package domain import ( "crypto/sha256" "encoding/hex" "fmt" "strings" ) // MongoDB BSON field names for auth module collections. const ( BSONFieldID = "_id" BSONFieldTenantID = "tenant_id" BSONFieldCodeHash = "code_hash" BSONFieldMaxUses = "max_uses" BSONFieldUsedCount = "used_count" BSONFieldExpiresAt = "expires_at" BSONFieldNewUsersOnly = "new_users_only" BSONFieldCreateAt = "create_at" BSONFieldUpdateAt = "update_at" BSONFieldUID = "uid" BSONFieldInviteCodeID = "invite_code_id" BSONFieldAcceptTermsVersion = "accept_terms_version" BSONFieldMarketingOptIn = "marketing_opt_in" BSONFieldRegistrationChannel = "registration_channel" BSONFieldClientIP = "client_ip" BSONFieldUserAgent = "user_agent" BSONFieldOccurredAt = "occurred_at" ) const inviteConsumeLockTTLSeconds = 30 const ( OAuthStatePrefixRegister = "reg:" OAuthStatePrefixLogin = "login:" ) // RegistrationSessionRedisKey returns the Redis key for a social registration session. func RegistrationSessionRedisKey(sessionID string) string { return fmt.Sprintf("auth:register:session:%s", sessionID) } // LoginSessionRedisKey returns the Redis key for a social login session. func LoginSessionRedisKey(sessionID string) string { return fmt.Sprintf("auth:login:session:%s", sessionID) } // LoginMFAChallengeRedisKey returns the Redis key for a password-login MFA challenge. func LoginMFAChallengeRedisKey(challengeID string) string { return fmt.Sprintf("auth:login:mfa:%s", challengeID) } // NormalizeInviteCode trims and uppercases user input before hashing. func NormalizeInviteCode(code string) string { return strings.ToUpper(strings.TrimSpace(code)) } // HashInviteCode returns a stable SHA-256 hex digest for storage and lookup. func HashInviteCode(code string) string { normalized := NormalizeInviteCode(code) sum := sha256.Sum256([]byte(normalized)) return hex.EncodeToString(sum[:]) } // InviteConsumeLockRedisKey returns the Redis key for serializing invite consumption. func InviteConsumeLockRedisKey(tenantID, codeHash string) string { return fmt.Sprintf("auth:invite:consume:%s:%s", tenantID, codeHash) } // InviteConsumeLockTTLSeconds is the Redis lock TTL for Consume. func InviteConsumeLockTTLSeconds() int { return inviteConsumeLockTTLSeconds } // JWTPairRedisKey maps an access or refresh jti to its paired jti. func JWTPairRedisKey(jti string) string { return fmt.Sprintf("auth:jwt:pair:%s", jti) } // JWTBlacklistRedisKey marks a revoked jti until natural expiry. func JWTBlacklistRedisKey(jti string) string { return fmt.Sprintf("auth:jwt:bl:%s", jti) }