change subdomain
parent
7fda97d09e
commit
0538e8b3ea
|
@ -27,6 +27,7 @@ type CreateOrganizationResponse struct {
|
||||||
Session string
|
Session string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// swagger:model GetOrganizationSettingsResponse
|
||||||
type GetOrganizationSettingsResponse struct {
|
type GetOrganizationSettingsResponse struct {
|
||||||
Subdomain string
|
Subdomain string
|
||||||
CompanyName string
|
CompanyName string
|
||||||
|
@ -35,7 +36,23 @@ type GetOrganizationSettingsResponse struct {
|
||||||
BannerUrl string
|
BannerUrl string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// swagger:model UpdateOrganizationSettingsRequest
|
||||||
type UpdateOrganizationSettingsRequest struct {
|
type UpdateOrganizationSettingsRequest struct {
|
||||||
CompanyName string
|
CompanyName string
|
||||||
PrimaryColor string
|
PrimaryColor string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// swagger:model UpdateOrganizationFileParam
|
||||||
|
type UpdateOrganizationFileParam struct {
|
||||||
|
Type string
|
||||||
|
}
|
||||||
|
|
||||||
|
// swagger:model IsSubdomainAvailableResponse
|
||||||
|
type IsSubdomainAvailableResponse struct {
|
||||||
|
Available bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// swagger:model SubdomainParam
|
||||||
|
type SubdomainParam struct {
|
||||||
|
Subdomain string
|
||||||
|
}
|
||||||
|
|
|
@ -110,7 +110,11 @@ func IsFileTypeAllowed(contentType string, allowedContentTypes []string) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func DeleteFile(filePath string) {
|
func DeleteFile(filePath string) {
|
||||||
os.Remove(filePath)
|
err := os.Remove(config.Cfg.FolderPaths.PublicStatic + filePath)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Msgf("Failed to delete file: %v", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateFolderStructureIfNotExists(folderPath string) {
|
func CreateFolderStructureIfNotExists(folderPath string) {
|
||||||
|
@ -123,6 +127,13 @@ func CreateFolderStructureIfNotExists(folderPath string) {
|
||||||
|
|
||||||
// GetFullImagePath returns the database path and the public path for the image
|
// GetFullImagePath returns the database path and the public path for the image
|
||||||
func GetFullImagePath(organizationId string, lessonId string) (databasePath string, publicPath string) {
|
func GetFullImagePath(organizationId string, lessonId string) (databasePath string, publicPath string) {
|
||||||
|
if lessonId == "" {
|
||||||
|
return fmt.Sprintf(
|
||||||
|
"o/%s/", organizationId),
|
||||||
|
fmt.Sprintf(
|
||||||
|
"%s/o/%s/", config.Cfg.FolderPaths.PublicStatic, organizationId)
|
||||||
|
}
|
||||||
|
|
||||||
return fmt.Sprintf(
|
return fmt.Sprintf(
|
||||||
"o/%s/l/%s/", organizationId, lessonId),
|
"o/%s/l/%s/", organizationId, lessonId),
|
||||||
fmt.Sprintf(
|
fmt.Sprintf(
|
||||||
|
|
|
@ -197,7 +197,7 @@ func UpdateLessonPreviewThumbnail(c *fiber.Ctx) error {
|
||||||
// ---
|
// ---
|
||||||
// summary: Update lesson preview thumbnail.
|
// summary: Update lesson preview thumbnail.
|
||||||
// consumes:
|
// consumes:
|
||||||
// - application/json
|
// - multipart/form-data
|
||||||
// produces:
|
// produces:
|
||||||
// - application/json
|
// - application/json
|
||||||
// parameters:
|
// parameters:
|
||||||
|
|
|
@ -103,3 +103,89 @@ func CreateOrganization(c *fiber.Ctx) error {
|
||||||
Session: session,
|
Session: session,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func IsSubdomainAvailable(c *fiber.Ctx) error {
|
||||||
|
// swagger:operation GET /organization/subdomain/{subdomain} organization isSubdomainAvailable
|
||||||
|
// ---
|
||||||
|
// summary: Check if subdomain is available
|
||||||
|
// produces:
|
||||||
|
// - application/json
|
||||||
|
// parameters:
|
||||||
|
// - name: subdomain
|
||||||
|
// in: path
|
||||||
|
// required: true
|
||||||
|
// type: string
|
||||||
|
// responses:
|
||||||
|
// '200':
|
||||||
|
// description: Subdomain is available
|
||||||
|
// schema:
|
||||||
|
// "$ref": "#/definitions/IsSubdomainAvailableResponse"
|
||||||
|
// '400':
|
||||||
|
// description: Invalid subdomain
|
||||||
|
// '500':
|
||||||
|
// description: Failed to check subdomain
|
||||||
|
|
||||||
|
var params structs.SubdomainParam
|
||||||
|
|
||||||
|
if err := rsutils.ParamsParserHelper(c, ¶ms); err != nil {
|
||||||
|
return c.SendStatus(fiber.StatusBadRequest)
|
||||||
|
}
|
||||||
|
|
||||||
|
var organization structs.Organization
|
||||||
|
|
||||||
|
database.DB.Select("Id").Where("subdomain = ?", params.Subdomain).First(&organization)
|
||||||
|
|
||||||
|
if organization.Id != "" {
|
||||||
|
return c.JSON(structs.IsSubdomainAvailableResponse{
|
||||||
|
Available: false,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(structs.IsSubdomainAvailableResponse{
|
||||||
|
Available: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
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, ¶ms); err != nil {
|
||||||
|
return c.SendStatus(fiber.StatusBadRequest)
|
||||||
|
}
|
||||||
|
|
||||||
|
organization := structs.Organization{
|
||||||
|
Id: c.Locals("organizationId").(string),
|
||||||
|
}
|
||||||
|
|
||||||
|
database.DB.Select("subdomain").Model(organization).First(&organization)
|
||||||
|
|
||||||
|
if organization.Subdomain == "" {
|
||||||
|
return c.SendStatus(fiber.StatusBadRequest)
|
||||||
|
}
|
||||||
|
|
||||||
|
database.DB.Model(&organization).Update("subdomain", params.Subdomain)
|
||||||
|
|
||||||
|
return c.JSON(fiber.Map{
|
||||||
|
"status": "success",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
package organization
|
package organization
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
|
"github.com/google/uuid"
|
||||||
"lms.de/backend/modules/database"
|
"lms.de/backend/modules/database"
|
||||||
"lms.de/backend/modules/structs"
|
"lms.de/backend/modules/structs"
|
||||||
|
"lms.de/backend/modules/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetOrganizationSettings(c *fiber.Ctx) error {
|
func GetOrganizationSettings(c *fiber.Ctx) error {
|
||||||
|
@ -64,3 +68,105 @@ func UpdateOrganizationSettings(c *fiber.Ctx) error {
|
||||||
|
|
||||||
return c.SendStatus(fiber.StatusOK)
|
return c.SendStatus(fiber.StatusOK)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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(¶ms); 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 := structs.Organization{}
|
||||||
|
|
||||||
|
selectField := "logo_url"
|
||||||
|
|
||||||
|
if params.Type == "banner" {
|
||||||
|
selectField = "banner_url"
|
||||||
|
}
|
||||||
|
|
||||||
|
database.DB.Model(&structs.Organization{
|
||||||
|
Id: c.Locals("organizationId").(string),
|
||||||
|
}).Select(selectField).First(&organization)
|
||||||
|
|
||||||
|
// 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 := structs.Organization{}
|
||||||
|
|
||||||
|
if params.Type == "logo" {
|
||||||
|
update.LogoUrl = databasePath + fileName
|
||||||
|
} else {
|
||||||
|
update.BannerUrl = databasePath + fileName
|
||||||
|
}
|
||||||
|
|
||||||
|
database.DB.Model(&structs.Organization{
|
||||||
|
Id: c.Locals("organizationId").(string),
|
||||||
|
}).Updates(update)
|
||||||
|
|
||||||
|
if err := c.SaveFile(fileHeader, publicPath+fileName); err != nil {
|
||||||
|
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
|
||||||
|
"error": "Failed to save file",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(fiber.Map{
|
||||||
|
"Data": databasePath + fileName,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -24,6 +24,9 @@ func SetupRoutes(app *fiber.App) {
|
||||||
o.Get("/team/members", handleOrganizationSubdomain, requestAccessValidation, organization.GetTeamMembers)
|
o.Get("/team/members", handleOrganizationSubdomain, requestAccessValidation, organization.GetTeamMembers)
|
||||||
o.Get("/settings", handleOrganizationSubdomain, requestAccessValidation, organization.GetOrganizationSettings)
|
o.Get("/settings", handleOrganizationSubdomain, requestAccessValidation, organization.GetOrganizationSettings)
|
||||||
o.Patch("/settings", handleOrganizationSubdomain, requestAccessValidation, organization.UpdateOrganizationSettings)
|
o.Patch("/settings", handleOrganizationSubdomain, requestAccessValidation, organization.UpdateOrganizationSettings)
|
||||||
|
o.Post("/file/:type", handleOrganizationSubdomain, requestAccessValidation, organization.UpdateOrganizationFile)
|
||||||
|
o.Get("/subdomain/:subdomain", organization.IsSubdomainAvailable)
|
||||||
|
o.Patch("/subdomain/:subdomain", handleOrganizationSubdomain, requestAccessValidation, organization.UpdateSubdomain)
|
||||||
|
|
||||||
u := v1.Group("/user")
|
u := v1.Group("/user")
|
||||||
u.Post("/auth/login", handleOrganizationSubdomain, user.UserLogin)
|
u.Post("/auth/login", handleOrganizationSubdomain, user.UserLogin)
|
||||||
|
|
Loading…
Reference in New Issue