From aad4ea84a17887540a7474244e373ac7e142200b Mon Sep 17 00:00:00 2001 From: chan Date: Wed, 25 Mar 2026 16:28:19 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20=EB=82=B4=20=EC=A0=95=EB=B3=B4(UpdateMe)?= =?UTF-8?q?=20=EC=88=98=EC=A0=95=20=EC=8B=9C=20=EC=BB=A4=EC=8A=A4=ED=85=80?= =?UTF-8?q?=20=ED=95=84=EB=93=9C=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20ID=20?= =?UTF-8?q?=EB=8F=99=EA=B8=B0=ED=99=94=20=EB=B0=8F=20Metadata=20=ED=95=84?= =?UTF-8?q?=EB=93=9C=20=EC=B6=94=EA=B0=80=20(#440)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/internal/domain/auth_models.go | 9 ++++--- backend/internal/handler/auth_handler.go | 33 ++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/backend/internal/domain/auth_models.go b/backend/internal/domain/auth_models.go index 8167ce35..5358c738 100644 --- a/backend/internal/domain/auth_models.go +++ b/backend/internal/domain/auth_models.go @@ -87,10 +87,11 @@ type UserProfileResponse struct { } type UpdateUserRequest struct { - Name string `json:"name"` - Phone string `json:"phone"` - Department string `json:"department"` - VerificationCode string `json:"verificationCode,omitempty"` // For phone change + Name string `json:"name"` + Phone string `json:"phone"` + Department string `json:"department"` + VerificationCode string `json:"verificationCode,omitempty"` // For phone change + Metadata map[string]any `json:"metadata,omitempty"` } // PasswordResetInitiateRequest is the request body for initiating a password reset. diff --git a/backend/internal/handler/auth_handler.go b/backend/internal/handler/auth_handler.go index dcae0d06..03faed40 100644 --- a/backend/internal/handler/auth_handler.go +++ b/backend/internal/handler/auth_handler.go @@ -5266,6 +5266,39 @@ func (h *AuthHandler) UpdateMe(c *fiber.Ctx) error { traits["department"] = req.Department } + // Merge custom metadata into traits + if len(req.Metadata) > 0 { + for k, v := range req.Metadata { + // Do not overwrite core fields + if _, isCore := map[string]bool{"email": true, "phone_number": true, "name": true, "department": true, "grade": true, "companyCode": true, "affiliationType": true, "id": true, "role": true, "tenant_id": true}[k]; !isCore { + traits[k] = v + } + } + } + + // [LoginID Sync based on Tenant Settings] + schemaCompCode := extractTraitString(traits, "companyCode") + if schemaCompCode != "" && h.TenantService != nil { + if tenant, err := h.TenantService.GetTenantBySlug(c.Context(), schemaCompCode); err == nil && tenant != nil { + if loginIDField, ok := tenant.Config["loginIdField"].(string); ok && loginIDField != "" { + // Search in Metadata (could be flat or namespaced) + if val, exists := req.Metadata[loginIDField]; exists { + if loginIDStr, ok := val.(string); ok && loginIDStr != "" { + traits["id"] = loginIDStr + } + } else if namespaced, exists := req.Metadata[tenant.ID]; exists { + if subMeta, ok := namespaced.(map[string]any); ok { + if val, exists := subMeta[loginIDField]; exists { + if loginIDStr, ok := val.(string); ok && loginIDStr != "" { + traits["id"] = loginIDStr + } + } + } + } + } + } + } + if err := h.updateKratosIdentity(identityID, traits); err != nil { slog.Error("Failed to update profile in Kratos", "error", err) return errorJSON(c, fiber.StatusInternalServerError, "프로필 업데이트에 실패했습니다.")