forked from baron/baron-sso
fix(backend): improve LoginID synchronization from custom metadata fields
- Centralize LoginID sync logic in syncLoginID helper - Support namespaced metadata in CreateUser, UpdateUser, and BulkCreateUsers - Ensure UpdateUser and UpdateMe always sync LoginID from configured field even if not in update request - Add phone number normalization consistency for custom LoginIDs - Add unit tests for namespaced metadata LoginID sync
This commit is contained in:
@@ -5272,37 +5272,30 @@ func (h *AuthHandler) UpdateMe(c *fiber.Ctx) error {
|
||||
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
|
||||
// [Fix] Support merging namespaced metadata maps
|
||||
if incomingMap, ok := v.(map[string]any); ok {
|
||||
if existingMap, ok := traits[k].(map[string]interface{}); ok {
|
||||
for subK, subV := range incomingMap {
|
||||
existingMap[subK] = subV
|
||||
}
|
||||
traits[k] = existingMap
|
||||
} else {
|
||||
traits[k] = incomingMap
|
||||
}
|
||||
} else {
|
||||
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 != "" {
|
||||
slog.Debug("[UpdateMe] Login ID sync active", "field", loginIDField)
|
||||
// Search in Metadata (could be flat or namespaced)
|
||||
var newLoginID string
|
||||
if val, exists := req.Metadata[loginIDField]; exists {
|
||||
if s, ok := val.(string); ok {
|
||||
newLoginID = s
|
||||
}
|
||||
} else if namespaced, exists := req.Metadata[tenant.ID]; exists {
|
||||
if subMeta, ok := namespaced.(map[string]any); ok {
|
||||
if val, exists := subMeta[loginIDField]; exists {
|
||||
if s, ok := val.(string); ok {
|
||||
newLoginID = s
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if newLoginID != "" {
|
||||
slog.Info("[UpdateMe] Syncing custom field to LoginID", "field", loginIDField, "value", newLoginID)
|
||||
traits["id"] = newLoginID
|
||||
}
|
||||
// Perform sync AFTER metadata merge to ensure traits contains current values
|
||||
syncCompCode := extractTraitString(traits, "companyCode")
|
||||
if syncCompCode != "" && h.TenantService != nil {
|
||||
if tenant, err := h.TenantService.GetTenantBySlug(c.Context(), syncCompCode); err == nil && tenant != nil {
|
||||
if loginIdField, ok := tenant.Config["loginIdField"].(string); ok && loginIdField != "" {
|
||||
syncLoginID(traits, req.Metadata, tenant.ID, loginIdField)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user