1
0
forked from baron/baron-sso

chore: consolidate local integration changes

This commit is contained in:
2026-06-09 21:03:05 +09:00
parent aa2848c3b6
commit 1341f07ef9
158 changed files with 10995 additions and 1490 deletions

View File

@@ -776,13 +776,7 @@ func (h *AuthHandler) Signup(c *fiber.Ctx) error {
}
// Normalize Phone (E.164 형태로 보관)
normalizedPhone := strings.ReplaceAll(req.Phone, "-", "")
normalizedPhone = strings.ReplaceAll(normalizedPhone, " ", "")
if strings.HasPrefix(normalizedPhone, "010") {
normalizedPhone = "+82" + normalizedPhone[1:]
} else if strings.HasPrefix(normalizedPhone, "82") {
normalizedPhone = "+" + normalizedPhone
}
normalizedPhone := domain.NormalizePhoneNumber(req.Phone)
slog.Info("[Signup] Phone normalization", "raw", req.Phone, "normalized", normalizedPhone)
@@ -1092,15 +1086,7 @@ func (h *AuthHandler) GetTenantInfo(c *fiber.Ctx) error {
// normalizePhoneForLoginID는 전화번호를 IDP 조회에 적합한 형태(E.164)로 정규화합니다.
func normalizePhoneForLoginID(phone string) string {
normalized := strings.ReplaceAll(phone, "-", "")
normalized = strings.ReplaceAll(normalized, " ", "")
if strings.HasPrefix(normalized, "010") {
return "+82" + normalized[1:]
}
if strings.HasPrefix(normalized, "82") {
return "+" + normalized
}
return normalized
return domain.NormalizePhoneNumber(phone)
}
func buildOidcClaimsFromTraits(traits map[string]any, scopes []string, tenantID string) map[string]any {
@@ -1226,7 +1212,7 @@ func buildOidcClaimsFromTraits(traits map[string]any, scopes []string, tenantID
// Heuristic: if a trait value is a map, it's treated as namespaced metadata for a tenant
for k, v := range traits {
if k == "metadata" {
if k == "metadata" || k == "global_custom_claims" || k == "global_custom_claim_types" || k == "global_custom_claim_permissions" {
continue
}
if m, ok := v.(map[string]any); ok {
@@ -1242,7 +1228,7 @@ func buildOidcClaimsFromTraits(traits map[string]any, scopes []string, tenantID
claims["tenants"] = allTenants
}
return claims
return applyGlobalCustomClaims(claims, traits)
}
func withOidcSessionMetadata(claims map[string]any, sessionID string) map[string]any {
@@ -1263,6 +1249,39 @@ func composeOIDCSessionClaims(client domain.HydraClient, traits map[string]any,
return withOidcSessionMetadata(claims, sessionID)
}
func applyGlobalCustomClaims(baseClaims map[string]any, traits map[string]any) map[string]any {
if baseClaims == nil {
baseClaims = map[string]any{}
}
if traits == nil {
return baseClaims
}
rawClaims, ok := traits["global_custom_claims"]
if !ok || rawClaims == nil {
return baseClaims
}
customClaims, ok := rawClaims.(map[string]any)
if !ok {
return baseClaims
}
for key, value := range customClaims {
key = strings.TrimSpace(key)
if key == "" || value == nil {
continue
}
if key == "rp_claims" || key == "rp_profiles" {
continue
}
if _, exists := baseClaims[key]; exists {
continue
}
baseClaims[key] = value
}
return baseClaims
}
func (h *AuthHandler) withHanmacFamilyTenantClaims(ctx context.Context, claims map[string]any, traits map[string]any, scopes []string) map[string]any {
if claims == nil {
claims = map[string]any{}
@@ -4666,7 +4685,7 @@ func extractFirstString(data map[string]any, keys ...string) string {
}
func sanitizePhoneForSms(phone string) string {
sanitized := strings.TrimSpace(phone)
sanitized := domain.NormalizePhoneNumber(phone)
if strings.HasPrefix(sanitized, "+82") {
sanitized = "0" + sanitized[3:]
}
@@ -4685,11 +4704,7 @@ func (h *AuthHandler) formatPhoneForDisplay(phone string) string {
}
func (h *AuthHandler) formatPhoneForStorage(phone string) string {
phone = strings.ReplaceAll(phone, "-", "")
if strings.HasPrefix(phone, "010") && len(phone) == 11 {
return "+8210" + phone[3:]
}
return phone
return domain.NormalizePhoneNumber(phone)
}
// GetMe - Returns current user's profile with enriched data from local DB
@@ -5920,6 +5935,12 @@ func (h *AuthHandler) RevokeLinkedRp(c *fiber.Ctx) error {
slog.Error("failed to revoke hydra consent sessions", "error", err)
return fiber.NewError(fiber.StatusInternalServerError, "Failed to revoke link")
}
if h.ConsentRepo != nil {
if err := h.ConsentRepo.Delete(c.Context(), subject, clientID); err != nil {
slog.Error("failed to delete local consent after hydra revoke", "error", err, "subject", subject, "client_id", clientID)
return fiber.NewError(fiber.StatusInternalServerError, "Failed to revoke local consent")
}
}
if h.AuditRepo != nil {
detailsMap := map[string]any{
@@ -7611,35 +7632,6 @@ func (h *AuthHandler) getKratosSessionIDWithCookie(cookie string) (string, error
return result.ID, nil
}
func (h *AuthHandler) updateKratosIdentity(identityID string, traits map[string]any) error {
kratosAdminURL := strings.TrimRight(os.Getenv("KRATOS_ADMIN_URL"), "/")
if kratosAdminURL == "" {
kratosAdminURL = "http://kratos:4434"
}
payload := map[string]any{
"schema_id": "default",
"traits": traits,
}
body, _ := json.Marshal(payload)
req, err := http.NewRequestWithContext(context.Background(), http.MethodPut, fmt.Sprintf("%s/admin/identities/%s", kratosAdminURL, identityID), bytes.NewReader(body))
if err != nil {
return err
}
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode >= 300 {
respBody, _ := io.ReadAll(io.LimitReader(resp.Body, 2048))
return fmt.Errorf("kratos admin update failed status=%d body=%s", resp.StatusCode, string(respBody))
}
return nil
}
func (h *AuthHandler) getHydraProfile(ctx context.Context, token string) (*domain.UserProfileResponse, error) {
intro, err := h.Hydra.IntrospectToken(ctx, token)
if err != nil {
@@ -7952,10 +7944,17 @@ func (h *AuthHandler) UpdateMe(c *fiber.Ctx) error {
}
}
if err := h.updateKratosIdentity(identityID, traits); err != nil {
if h.KratosAdmin == nil {
return errorJSON(c, fiber.StatusServiceUnavailable, "identity provider not available")
}
updatedIdentity, err := h.KratosAdmin.UpdateIdentity(c.Context(), identityID, traits, "")
if err != nil {
slog.Error("Failed to update profile in Kratos", "error", err)
return errorJSON(c, fiber.StatusInternalServerError, "프로필 업데이트에 실패했습니다.")
}
if updatedIdentity != nil && updatedIdentity.Traits != nil {
traits = updatedIdentity.Traits
}
// [New] Local DB Sync - Sync synchronously to ensure immediate consistency
if h.UserRepo != nil {