forked from baron/baron-sso
feat(user): support fixed UUID registration and enhance bulk import results
- Added support for fixed UUIDs during bulk registration (Search-first + ExternalID mapping) - Implemented idempotency and visibility restoration for soft-deleted users - Enhanced bulk upload UI to show 'New/Updated/Unchanged' status and modified fields - Added logic to reclaim identifiers (login_id) from colliding records - Added frontend E2E and backend unit tests for UUID integrity and conflict handling - Fixed i18n, formatting, and mock tests to satisfy code-check - Applied 'go fix' for 'omitzero' tags and general Go standards
This commit is contained in:
@@ -16,11 +16,13 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"log/slog"
|
||||
"maps"
|
||||
"math/rand"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"slices"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -601,7 +603,7 @@ func (h *AuthHandler) GetActiveTenants(c *fiber.Ctx) error {
|
||||
email := c.Query("email")
|
||||
if email == "" {
|
||||
// No email provided, return empty list (Security policy)
|
||||
return c.JSON([]interface{}{})
|
||||
return c.JSON([]any{})
|
||||
}
|
||||
|
||||
// 1. Verify Verification Status in Redis
|
||||
@@ -615,7 +617,7 @@ func (h *AuthHandler) GetActiveTenants(c *fiber.Ctx) error {
|
||||
// 2. Extract domain from verified email
|
||||
parts := strings.Split(email, "@")
|
||||
if len(parts) != 2 {
|
||||
return c.JSON([]interface{}{})
|
||||
return c.JSON([]any{})
|
||||
}
|
||||
domainName := parts[1]
|
||||
|
||||
@@ -623,7 +625,7 @@ func (h *AuthHandler) GetActiveTenants(c *fiber.Ctx) error {
|
||||
isInternal, _ := h.isAffiliateTenant(c.Context(), domainName)
|
||||
if !isInternal {
|
||||
// If not an affiliate email, do not show any tenants
|
||||
return c.JSON([]interface{}{})
|
||||
return c.JSON([]any{})
|
||||
}
|
||||
|
||||
// 3. List and Filter Tenants
|
||||
@@ -785,7 +787,7 @@ func (h *AuthHandler) Signup(c *fiber.Ctx) error {
|
||||
slog.Info("[Signup] Phone normalization", "raw", req.Phone, "normalized", normalizedPhone)
|
||||
|
||||
// IDP에 전달할 BrokerUser 스키마 구성
|
||||
attributes := map[string]interface{}{
|
||||
attributes := map[string]any{
|
||||
"department": req.Department,
|
||||
"affiliationType": req.AffiliationType,
|
||||
"grade": "",
|
||||
@@ -854,9 +856,7 @@ func (h *AuthHandler) Signup(c *fiber.Ctx) error {
|
||||
|
||||
// Merge metadata
|
||||
localUser.Metadata = make(domain.JSONMap)
|
||||
for k, v := range req.Metadata {
|
||||
localUser.Metadata[k] = v
|
||||
}
|
||||
maps.Copy(localUser.Metadata, req.Metadata)
|
||||
|
||||
if h.UserRepo != nil {
|
||||
go func(u *domain.User, ids []domain.UserLoginID) {
|
||||
@@ -915,7 +915,7 @@ func (h *AuthHandler) getBearerToken(c *fiber.Ctx) string {
|
||||
}
|
||||
|
||||
func firstForwardedValue(raw string) string {
|
||||
for _, part := range strings.Split(raw, ",") {
|
||||
for part := range strings.SplitSeq(raw, ",") {
|
||||
value := strings.TrimSpace(part)
|
||||
if value != "" {
|
||||
return value
|
||||
@@ -925,8 +925,8 @@ func firstForwardedValue(raw string) string {
|
||||
}
|
||||
|
||||
func forwardedDirective(raw, key string) string {
|
||||
for _, group := range strings.Split(raw, ",") {
|
||||
for _, directive := range strings.Split(group, ";") {
|
||||
for group := range strings.SplitSeq(raw, ",") {
|
||||
for directive := range strings.SplitSeq(group, ";") {
|
||||
pair := strings.SplitN(strings.TrimSpace(directive), "=", 2)
|
||||
if len(pair) != 2 {
|
||||
continue
|
||||
@@ -1075,9 +1075,9 @@ func (h *AuthHandler) GetTenantInfo(c *fiber.Ctx) error {
|
||||
if loginIdField, ok := tenant.Config["loginIdField"].(string); ok && loginIdField != "" {
|
||||
res["loginIdField"] = loginIdField
|
||||
// Find label in userSchema
|
||||
if schema, ok := tenant.Config["userSchema"].([]interface{}); ok {
|
||||
if schema, ok := tenant.Config["userSchema"].([]any); ok {
|
||||
for _, field := range schema {
|
||||
if f, ok := field.(map[string]interface{}); ok {
|
||||
if f, ok := field.(map[string]any); ok {
|
||||
if f["key"] == loginIdField {
|
||||
res["loginIdLabel"] = f["label"]
|
||||
break
|
||||
@@ -1215,9 +1215,7 @@ func buildOidcClaimsFromTraits(traits map[string]any, scopes []string, tenantID
|
||||
if includeTenantDetails {
|
||||
// tenant 스코프가 있을 때만 대표소속 namespace metadata를 top-level claim으로 펼칩니다.
|
||||
if namespaced, ok := traits[tenantID].(map[string]any); ok {
|
||||
for k, v := range namespaced {
|
||||
claims[k] = v
|
||||
}
|
||||
maps.Copy(claims, namespaced)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1570,7 +1568,7 @@ func tenantClaimAncestorSummaries(ancestors []*domain.Tenant) []map[string]any {
|
||||
return items
|
||||
}
|
||||
|
||||
func applyConfiguredIDTokenClaims(baseClaims map[string]any, metadata map[string]interface{}) map[string]any {
|
||||
func applyConfiguredIDTokenClaims(baseClaims map[string]any, metadata map[string]any) map[string]any {
|
||||
if baseClaims == nil {
|
||||
baseClaims = map[string]any{}
|
||||
}
|
||||
@@ -1670,7 +1668,7 @@ func (h *AuthHandler) withRPProfileClaims(ctx context.Context, claims map[string
|
||||
claims["rp_profiles"] = append(existing, profile)
|
||||
return claims
|
||||
}
|
||||
if existing, ok := claims["rp_profiles"].([]interface{}); ok {
|
||||
if existing, ok := claims["rp_profiles"].([]any); ok {
|
||||
claims["rp_profiles"] = append(existing, profile)
|
||||
return claims
|
||||
}
|
||||
@@ -1678,7 +1676,7 @@ func (h *AuthHandler) withRPProfileClaims(ctx context.Context, claims map[string
|
||||
return claims
|
||||
}
|
||||
|
||||
func extractClaimEnabledCustomUserSchemaKeys(metadata map[string]interface{}) []string {
|
||||
func extractClaimEnabledCustomUserSchemaKeys(metadata map[string]any) []string {
|
||||
if metadata == nil {
|
||||
return nil
|
||||
}
|
||||
@@ -1687,12 +1685,12 @@ func extractClaimEnabledCustomUserSchemaKeys(metadata map[string]interface{}) []
|
||||
return nil
|
||||
}
|
||||
|
||||
var items []interface{}
|
||||
var items []any
|
||||
switch schema := rawSchema.(type) {
|
||||
case []interface{}:
|
||||
case []any:
|
||||
items = schema
|
||||
case []map[string]interface{}:
|
||||
items = make([]interface{}, 0, len(schema))
|
||||
case []map[string]any:
|
||||
items = make([]any, 0, len(schema))
|
||||
for _, item := range schema {
|
||||
items = append(items, item)
|
||||
}
|
||||
@@ -1703,7 +1701,7 @@ func extractClaimEnabledCustomUserSchemaKeys(metadata map[string]interface{}) []
|
||||
keys := make([]string, 0, len(items))
|
||||
seen := make(map[string]struct{})
|
||||
for _, item := range items {
|
||||
field, ok := item.(map[string]interface{})
|
||||
field, ok := item.(map[string]any)
|
||||
if !ok {
|
||||
if typed, typedOK := item.(map[string]any); typedOK {
|
||||
field = typed
|
||||
@@ -4275,11 +4273,11 @@ func (h *AuthHandler) ScanQRLogin(c *fiber.Ctx) error {
|
||||
}
|
||||
|
||||
type kratosCourierRequest struct {
|
||||
Recipient string `json:"recipient"`
|
||||
TemplateType string `json:"template_type"`
|
||||
TemplateData map[string]interface{} `json:"template_data"`
|
||||
Subject string `json:"subject"`
|
||||
Body string `json:"body"`
|
||||
Recipient string `json:"recipient"`
|
||||
TemplateType string `json:"template_type"`
|
||||
TemplateData map[string]any `json:"template_data"`
|
||||
Subject string `json:"subject"`
|
||||
Body string `json:"body"`
|
||||
}
|
||||
|
||||
// HandleKratosCourierRelay - Kratos courier HTTP 요청을 받아 메일/SMS 발송으로 변환합니다.
|
||||
@@ -4604,7 +4602,7 @@ func (h *AuthHandler) isSmsCodeOnly(loginID string) bool {
|
||||
|
||||
func (h *AuthHandler) generateShortCode(code string) string {
|
||||
const letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
for i := 0; i < 10; i++ {
|
||||
for range 10 {
|
||||
b := make([]byte, 2)
|
||||
if _, err := crand.Read(b); err != nil {
|
||||
break
|
||||
@@ -4646,7 +4644,7 @@ func firstNonEmpty(values ...string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func extractFirstString(data map[string]interface{}, keys ...string) string {
|
||||
func extractFirstString(data map[string]any, keys ...string) string {
|
||||
if data == nil {
|
||||
return ""
|
||||
}
|
||||
@@ -5229,10 +5227,7 @@ func (h *AuthHandler) GetAuthTimeline(c *fiber.Ctx) error {
|
||||
}
|
||||
|
||||
candidates := buildLoginCandidates(profile)
|
||||
fetchLimit := limit * 10
|
||||
if fetchLimit < limit {
|
||||
fetchLimit = limit
|
||||
}
|
||||
fetchLimit := max(limit*10, limit)
|
||||
if fetchLimit > 500 {
|
||||
fetchLimit = 500
|
||||
}
|
||||
@@ -5805,9 +5800,9 @@ func (h *AuthHandler) ListLinkedRps(c *fiber.Ctx) error {
|
||||
}
|
||||
for _, log := range auditLogs {
|
||||
var details struct {
|
||||
ClientID string `json:"client_id"`
|
||||
ClientName string `json:"client_name"`
|
||||
Scopes interface{} `json:"scopes"`
|
||||
ClientID string `json:"client_id"`
|
||||
ClientName string `json:"client_name"`
|
||||
Scopes any `json:"scopes"`
|
||||
}
|
||||
// 로그 Details 파싱
|
||||
if err := json.Unmarshal([]byte(log.Details), &details); err != nil {
|
||||
@@ -5824,7 +5819,7 @@ func (h *AuthHandler) ListLinkedRps(c *fiber.Ctx) error {
|
||||
|
||||
// 스코프 추출 (consent.granted인 경우)
|
||||
scopes := []string{}
|
||||
if sList, ok := details.Scopes.([]interface{}); ok {
|
||||
if sList, ok := details.Scopes.([]any); ok {
|
||||
for _, s := range sList {
|
||||
if str, ok := s.(string); ok {
|
||||
scopes = append(scopes, str)
|
||||
@@ -5927,7 +5922,7 @@ func (h *AuthHandler) RevokeLinkedRp(c *fiber.Ctx) error {
|
||||
}
|
||||
|
||||
if h.AuditRepo != nil {
|
||||
detailsMap := map[string]interface{}{
|
||||
detailsMap := map[string]any{
|
||||
"client_id": clientID,
|
||||
}
|
||||
detailsBytes, _ := json.Marshal(detailsMap)
|
||||
@@ -6085,7 +6080,7 @@ func (h *AuthHandler) GetConsentRequest(c *fiber.Ctx) error {
|
||||
}
|
||||
|
||||
if h.AuditRepo != nil {
|
||||
detailsMap := map[string]interface{}{
|
||||
detailsMap := map[string]any{
|
||||
"client_id": consentRequest.Client.ClientID,
|
||||
"scopes": consentRequest.RequestedScope,
|
||||
"client_name": consentRequest.Client.ClientName,
|
||||
@@ -6135,12 +6130,12 @@ func (h *AuthHandler) GetConsentRequest(c *fiber.Ctx) error {
|
||||
// structured_scopes 파싱 및 scope_details 생성
|
||||
if metadata := consentRequest.Client.Metadata; metadata != nil {
|
||||
if rawScopes, ok := metadata["structured_scopes"]; ok {
|
||||
scopeDetails := make(map[string]map[string]interface{})
|
||||
scopeDetails := make(map[string]map[string]any)
|
||||
|
||||
// JSON 언마샬링 등을 통해 map[string]interface{} 또는 []interface{}로 들어옴
|
||||
// 안전하게 처리
|
||||
rawBytes, _ := json.Marshal(rawScopes)
|
||||
var scopesList []map[string]interface{}
|
||||
var scopesList []map[string]any
|
||||
if err := json.Unmarshal(rawBytes, &scopesList); err == nil {
|
||||
for _, item := range scopesList {
|
||||
name, _ := item["name"].(string)
|
||||
@@ -6150,7 +6145,7 @@ func (h *AuthHandler) GetConsentRequest(c *fiber.Ctx) error {
|
||||
desc, _ := item["description"].(string)
|
||||
mandatory, _ := item["mandatory"].(bool)
|
||||
|
||||
scopeDetails[name] = map[string]interface{}{
|
||||
scopeDetails[name] = map[string]any{
|
||||
"description": desc,
|
||||
"mandatory": mandatory,
|
||||
}
|
||||
@@ -6280,7 +6275,7 @@ func (h *AuthHandler) AcceptConsentRequest(c *fiber.Ctx) error {
|
||||
}
|
||||
|
||||
if h.AuditRepo != nil {
|
||||
detailsMap := map[string]interface{}{
|
||||
detailsMap := map[string]any{
|
||||
"client_id": consentRequest.Client.ClientID,
|
||||
"scopes": consentRequest.RequestedScope,
|
||||
"client_name": consentRequest.Client.ClientName,
|
||||
@@ -6618,7 +6613,7 @@ func appendLoginIDsFromValues(subjects []string, email string, phone string) []s
|
||||
return subjects
|
||||
}
|
||||
|
||||
func appendLoginIDsFromTraits(subjects []string, traits map[string]interface{}) []string {
|
||||
func appendLoginIDsFromTraits(subjects []string, traits map[string]any) []string {
|
||||
if traits == nil {
|
||||
return subjects
|
||||
}
|
||||
@@ -7235,7 +7230,7 @@ func (h *AuthHandler) resolveKratosLoginID(token string) (string, error) {
|
||||
return loginID, nil
|
||||
}
|
||||
|
||||
func pickLoginIDFromTraits(traits map[string]interface{}) string {
|
||||
func pickLoginIDFromTraits(traits map[string]any) string {
|
||||
if traits == nil {
|
||||
return ""
|
||||
}
|
||||
@@ -7409,12 +7404,12 @@ func extractLoginIDFromClaims(claims map[string]any) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (h *AuthHandler) getKratosIdentity(sessionToken string) (string, map[string]interface{}, string, error) {
|
||||
func (h *AuthHandler) getKratosIdentity(sessionToken string) (string, map[string]any, string, error) {
|
||||
identityID, traits, _, usedID, err := h.getKratosIdentityWithSession(sessionToken)
|
||||
return identityID, traits, usedID, err
|
||||
}
|
||||
|
||||
func (h *AuthHandler) getKratosIdentityWithSession(sessionToken string) (string, map[string]interface{}, string, string, error) {
|
||||
func (h *AuthHandler) getKratosIdentityWithSession(sessionToken string) (string, map[string]any, string, string, error) {
|
||||
kratosURL := strings.TrimRight(os.Getenv("KRATOS_PUBLIC_URL"), "/")
|
||||
if kratosURL == "" {
|
||||
kratosURL = "http://kratos:4433"
|
||||
@@ -7442,8 +7437,8 @@ func (h *AuthHandler) getKratosIdentityWithSession(sessionToken string) (string,
|
||||
Identifier string `json:"identifier"`
|
||||
} `json:"authentication_methods"`
|
||||
Identity struct {
|
||||
ID string `json:"id"`
|
||||
Traits map[string]interface{} `json:"traits"`
|
||||
ID string `json:"id"`
|
||||
Traits map[string]any `json:"traits"`
|
||||
} `json:"identity"`
|
||||
}
|
||||
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
|
||||
@@ -7501,7 +7496,7 @@ func (h *AuthHandler) issueKratosSession(ctx context.Context, identityID string)
|
||||
kratosAdminURL = "http://kratos:4434"
|
||||
}
|
||||
|
||||
payload := map[string]interface{}{
|
||||
payload := map[string]any{
|
||||
"identity_id": identityID,
|
||||
}
|
||||
body, _ := json.Marshal(payload)
|
||||
@@ -7534,12 +7529,12 @@ func (h *AuthHandler) issueKratosSession(ctx context.Context, identityID string)
|
||||
return parsed.SessionToken, nil
|
||||
}
|
||||
|
||||
func (h *AuthHandler) getKratosIdentityWithCookie(cookie string) (string, map[string]interface{}, string, error) {
|
||||
func (h *AuthHandler) getKratosIdentityWithCookie(cookie string) (string, map[string]any, string, error) {
|
||||
identityID, traits, _, usedID, err := h.getKratosIdentityWithCookieAndSession(cookie)
|
||||
return identityID, traits, usedID, err
|
||||
}
|
||||
|
||||
func (h *AuthHandler) getKratosIdentityWithCookieAndSession(cookie string) (string, map[string]interface{}, string, string, error) {
|
||||
func (h *AuthHandler) getKratosIdentityWithCookieAndSession(cookie string) (string, map[string]any, string, string, error) {
|
||||
kratosURL := strings.TrimRight(os.Getenv("KRATOS_PUBLIC_URL"), "/")
|
||||
if kratosURL == "" {
|
||||
kratosURL = "http://kratos:4433"
|
||||
@@ -7567,8 +7562,8 @@ func (h *AuthHandler) getKratosIdentityWithCookieAndSession(cookie string) (stri
|
||||
Identifier string `json:"identifier"`
|
||||
} `json:"authentication_methods"`
|
||||
Identity struct {
|
||||
ID string `json:"id"`
|
||||
Traits map[string]interface{} `json:"traits"`
|
||||
ID string `json:"id"`
|
||||
Traits map[string]any `json:"traits"`
|
||||
} `json:"identity"`
|
||||
}
|
||||
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
|
||||
@@ -7616,13 +7611,13 @@ func (h *AuthHandler) getKratosSessionIDWithCookie(cookie string) (string, error
|
||||
return result.ID, nil
|
||||
}
|
||||
|
||||
func (h *AuthHandler) updateKratosIdentity(identityID string, traits map[string]interface{}) error {
|
||||
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]interface{}{
|
||||
payload := map[string]any{
|
||||
"schema_id": "default",
|
||||
"traits": traits,
|
||||
}
|
||||
@@ -7681,7 +7676,7 @@ func (h *AuthHandler) getHydraProfile(ctx context.Context, token string) (*domai
|
||||
return h.mapKratosIdentityToProfile(identity.ID, identity.Traits), nil
|
||||
}
|
||||
|
||||
func (h *AuthHandler) mapKratosIdentityToProfile(identityID string, traits map[string]interface{}) *domain.UserProfileResponse {
|
||||
func (h *AuthHandler) mapKratosIdentityToProfile(identityID string, traits map[string]any) *domain.UserProfileResponse {
|
||||
email, _ := traits["email"].(string)
|
||||
name, _ := traits["name"].(string)
|
||||
phone, _ := traits["phone_number"].(string)
|
||||
@@ -7723,7 +7718,7 @@ func (h *AuthHandler) mapKratosIdentityToProfile(identityID string, traits map[s
|
||||
return profile
|
||||
}
|
||||
|
||||
func (h *AuthHandler) mapKratosTraitsToLocalUser(identityID string, traits map[string]interface{}, existing *domain.User) *domain.User {
|
||||
func (h *AuthHandler) mapKratosTraitsToLocalUser(identityID string, traits map[string]any, existing *domain.User) *domain.User {
|
||||
now := time.Now()
|
||||
localUser := &domain.User{
|
||||
ID: identityID,
|
||||
@@ -7810,7 +7805,7 @@ func (h *AuthHandler) mapKratosTraitsToLocalUser(identityID string, traits map[s
|
||||
return localUser
|
||||
}
|
||||
|
||||
func (h *AuthHandler) syncUpdatedKratosUserReadModel(ctx context.Context, identityID string, traits map[string]interface{}) error {
|
||||
func (h *AuthHandler) syncUpdatedKratosUserReadModel(ctx context.Context, identityID string, traits map[string]any) error {
|
||||
if h == nil || h.UserRepo == nil {
|
||||
return nil
|
||||
}
|
||||
@@ -7880,7 +7875,7 @@ func (h *AuthHandler) UpdateMe(c *fiber.Ctx) error {
|
||||
|
||||
var (
|
||||
identityID string
|
||||
traits map[string]interface{}
|
||||
traits map[string]any
|
||||
err error
|
||||
)
|
||||
if token != "" {
|
||||
@@ -7929,10 +7924,8 @@ func (h *AuthHandler) UpdateMe(c *fiber.Ctx) error {
|
||||
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 {
|
||||
// [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
|
||||
}
|
||||
if existingMap, ok := traits[k].(map[string]any); ok {
|
||||
maps.Copy(existingMap, incomingMap)
|
||||
traits[k] = existingMap
|
||||
} else {
|
||||
traits[k] = incomingMap
|
||||
@@ -8129,7 +8122,7 @@ func (h *AuthHandler) VerifyUpdateCode(c *fiber.Ctx) error {
|
||||
return c.JSON(fiber.Map{"success": true})
|
||||
}
|
||||
|
||||
func hydraClientStatus(metadata map[string]interface{}) string {
|
||||
func hydraClientStatus(metadata map[string]any) string {
|
||||
if metadata == nil {
|
||||
return "active"
|
||||
}
|
||||
@@ -8142,7 +8135,7 @@ func hydraClientStatus(metadata map[string]interface{}) string {
|
||||
return "active"
|
||||
}
|
||||
|
||||
func extractHydraClientLogo(metadata map[string]interface{}) string {
|
||||
func extractHydraClientLogo(metadata map[string]any) string {
|
||||
if metadata == nil {
|
||||
return ""
|
||||
}
|
||||
@@ -8198,7 +8191,7 @@ func resolveLinkedRPURL(clientID string, clientURI string, redirectURIs []string
|
||||
return ""
|
||||
}
|
||||
|
||||
func resolveLinkedRPAutoLoginSupported(clientID string, metadata map[string]interface{}) bool {
|
||||
func resolveLinkedRPAutoLoginSupported(clientID string, metadata map[string]any) bool {
|
||||
if readMetadataBoolValue(metadata, domain.MetadataAutoLoginSupported) {
|
||||
return true
|
||||
}
|
||||
@@ -8210,7 +8203,7 @@ func resolveLinkedRPAutoLoginSupported(clientID string, metadata map[string]inte
|
||||
}
|
||||
}
|
||||
|
||||
func resolveLinkedRPAutoLoginURL(clientID string, metadata map[string]interface{}) string {
|
||||
func resolveLinkedRPAutoLoginURL(clientID string, metadata map[string]any) string {
|
||||
clientID = strings.TrimSpace(clientID)
|
||||
if metadataURL := readMetadataStringValue(metadata, domain.MetadataAutoLoginURL); metadataURL != "" {
|
||||
if clientID == "orgfront" {
|
||||
@@ -8253,7 +8246,7 @@ func ensureOrgfrontAutoLoginURL(rawURL string) string {
|
||||
return parsed.String()
|
||||
}
|
||||
|
||||
func resolveLinkedRPInitURL(clientID string, metadata map[string]interface{}) string {
|
||||
func resolveLinkedRPInitURL(clientID string, metadata map[string]any) string {
|
||||
if !resolveLinkedRPAutoLoginSupported(clientID, metadata) {
|
||||
return ""
|
||||
}
|
||||
@@ -8548,7 +8541,7 @@ func (h *AuthHandler) ListRpHistory(c *fiber.Ctx) error {
|
||||
ts := log.Timestamp
|
||||
item.LastApprovedAt = &ts
|
||||
|
||||
if scopesRaw, ok := details["scopes"].([]interface{}); ok {
|
||||
if scopesRaw, ok := details["scopes"].([]any); ok {
|
||||
scopes := make([]string, 0, len(scopesRaw))
|
||||
for _, s := range scopesRaw {
|
||||
if str, ok := s.(string); ok {
|
||||
@@ -8811,7 +8804,7 @@ func extractStringLikeValue(raw any) string {
|
||||
}
|
||||
}
|
||||
|
||||
func extractHydraSessionID(ext map[string]interface{}) string {
|
||||
func extractHydraSessionID(ext map[string]any) string {
|
||||
if len(ext) == 0 {
|
||||
return ""
|
||||
}
|
||||
@@ -8886,13 +8879,7 @@ func (h *AuthHandler) loadSessionClientBindings(ctx context.Context, userID stri
|
||||
}
|
||||
|
||||
existing := bindings[sessionID]
|
||||
seen := false
|
||||
for _, candidate := range existing {
|
||||
if candidate == clientID {
|
||||
seen = true
|
||||
break
|
||||
}
|
||||
}
|
||||
seen := slices.Contains(existing, clientID)
|
||||
if !seen {
|
||||
bindings[sessionID] = append(existing, clientID)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user