lms-backend/routers/router/api/v1/organization/settings.go

285 lines
7.1 KiB
Go

package organization
import (
"errors"
"strings"
"time"
"git.ex.umbach.dev/Alex/roese-utils/rsutils"
"git.ex.umbach.dev/LMS/libcore/models"
"github.com/gofiber/fiber/v2"
"github.com/google/uuid"
"gorm.io/gorm"
"lms.de/backend/modules/database"
"lms.de/backend/modules/structs"
"lms.de/backend/modules/utils"
"lms.de/backend/socketclients"
)
func GetOrganizationSettings(c *fiber.Ctx) error {
// swagger:operation GET /organization/settings organization getOrganizationSettings
// ---
// summary: Get settings
// consumes:
// - application/json
// produces:
// - application/json
// responses:
// '200':
// description: Settings fetched successfully
// schema:
// "$ref": "#/definitions/GetOrganizationSettingsResponse"
// '400':
// description: Invalid request body
// '500':
// description: Failed to fetch settings
var organizationSettings structs.GetOrganizationSettingsResponse
if err := database.DB.Model(&models.Organization{}).
Select("subdomain", "company_name", "primary_color", "logo_url", "banner_url").
Where("id = ?", c.Locals("organizationId").(string)).
First(&organizationSettings).Error; err != nil {
return c.SendStatus(fiber.StatusInternalServerError)
}
return c.JSON(organizationSettings)
}
func UpdateOrganizationSettings(c *fiber.Ctx) error {
// swagger:operation PATCH /organization/settings organization updateOrganizationSettings
// ---
// summary: Update settings
// consumes:
// - application/json
// produces:
// - application/json
// parameters:
// - name: body
// in: body
// schema:
// "$ref": "#/definitions/GetOrganizationSettingsResponse"
// responses:
// '200':
// description: Settings updated successfully
// '400':
// description: Invalid request body
// '500':
// description: Failed to update settings
var organizationSettings structs.UpdateOrganizationSettingsRequest
if err := c.BodyParser(&organizationSettings); err != nil {
return c.SendStatus(fiber.StatusBadRequest)
}
if err := database.DB.Model(&models.Organization{}).
Where("id = ?", c.Locals("organizationId").(string)).
Updates(organizationSettings).Error; err != nil {
return c.SendStatus(fiber.StatusInternalServerError)
}
socketclients.BroadcastMessageExceptBrowserTabSession(
c.Locals("organizationId").(string),
c.Locals("browserTabSession").(string),
structs.SendSocketMessage{
Cmd: utils.SendCmdSettingsUpdated,
Body: organizationSettings,
},
)
return c.JSON(fiber.Map{
"status": "success",
})
}
func UpdateOrganizationFile(c *fiber.Ctx) error {
// swagger:operation POST /organization/file/{type} organization updateOrganizationFiles
// ---
// summary: Update files
// consumes:
// - multipart/form-data
// produces:
// - application/json
// parameters:
// - name: logo
// in: formData
// type: file
// required: false
// - name: banner
// in: formData
// type: file
// required: false
// responses:
// '200':
// description: Files updated successfully
// '400':
// description: Invalid request body
// '500':
// description: Failed to update files
var params structs.UpdateOrganizationFileParam
if err := c.ParamsParser(&params); err != nil {
return c.SendStatus(fiber.StatusBadRequest)
}
fileHeader, err := c.FormFile("file")
if err != nil {
return c.SendStatus(fiber.StatusBadRequest)
}
if params.Type == "logo" || params.Type == "banner" {
if fileHeader.Size > utils.MaxImageSize {
return c.SendStatus(fiber.StatusBadRequest)
}
if !utils.IsFileTypeAllowed(fileHeader.Header.Get("Content-Type"), utils.AcceptedImageFileTypes) {
return c.SendStatus(fiber.StatusBadRequest)
}
} else {
return c.SendStatus(fiber.StatusBadRequest)
}
// get current file
organization := models.Organization{}
selectField := "logo_url"
if params.Type == "banner" {
selectField = "banner_url"
}
if err := database.DB.Model(&models.Organization{}).
Where("id = ?", c.Locals("organizationId").(string)).
Select(selectField).
First(&organization).Error; err != nil {
return c.SendStatus(fiber.StatusInternalServerError)
}
// delete current file
if organization.LogoUrl != "" {
utils.DeleteFile(organization.LogoUrl)
}
if organization.BannerUrl != "" {
utils.DeleteFile(organization.BannerUrl)
}
fileName := uuid.New().String() + "." + strings.Split(fileHeader.Header["Content-Type"][0], "/")[1]
databasePath, publicPath := utils.GetFullImagePath(c.Locals("organizationId").(string), "")
utils.CreateFolderStructureIfNotExists(publicPath)
update := models.Organization{}
if params.Type == "logo" {
update.LogoUrl = databasePath + fileName
} else {
update.BannerUrl = databasePath + fileName
}
if err := database.DB.Model(&models.Organization{}).
Where("id = ?", c.Locals("organizationId").(string)).
Updates(update).Error; err != nil {
return c.SendStatus(fiber.StatusInternalServerError)
}
if err := c.SaveFile(fileHeader, publicPath+fileName); err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"error": "Failed to save file",
})
}
cmdId := utils.SendCmdSettingsUpdatedLogo
if params.Type == "banner" {
cmdId = utils.SendCmdSettingsUpdatedBanner
}
newPath := databasePath + fileName
socketclients.BroadcastMessageExceptBrowserTabSession(
c.Locals("organizationId").(string),
c.Locals("browserTabSession").(string),
structs.SendSocketMessage{
Cmd: cmdId,
Body: newPath,
},
)
return c.JSON(fiber.Map{
"Data": newPath,
})
}
func UpdateSubdomain(c *fiber.Ctx) error {
// swagger:operation PATCH /organization/subdomain/{subdomain} organization updateSubdomain
// ---
// summary: Update organization subdomain
// consumes:
// - application/json
// produces:
// - application/json
// parameters:
// - name: subdomain
// in: path
// required: true
// type: string
// responses:
// '200':
// description: Subdomain updated successfully
// '400':
// description: Invalid request body
// '500':
// description: Failed to update subdomain
var params structs.SubdomainParam
if err := rsutils.ParamsParserHelper(c, &params); err != nil {
return c.SendStatus(fiber.StatusBadRequest)
}
var organization models.Organization
if err := database.DB.Select("subdomain").
Model(organization).
Where("id = ?", c.Locals("organizationId").(string)).
First(&organization).Error; err != nil {
if !errors.Is(err, gorm.ErrRecordNotFound) {
return c.SendStatus(fiber.StatusNotFound)
}
}
if organization.Subdomain == "" {
return c.SendStatus(fiber.StatusBadRequest)
}
if err := database.DB.Model(&organization).
Where("id = ?", c.Locals("organizationId")).
Update("subdomain", params.Subdomain).Error; err != nil {
return c.SendStatus(fiber.StatusInternalServerError)
}
orgId := c.Locals("organizationId").(string)
// send broadcast with delay
go func() {
time.Sleep(1 * time.Second)
socketclients.BroadcastMessage(orgId,
structs.SendSocketMessage{
Cmd: utils.SendCmdSettingsUpdatedSubdomain,
Body: params.Subdomain,
},
)
}()
return c.JSON(fiber.Map{
"status": "success",
})
}