stack/sdks/implementations/swift/Sources/StackAuth/Models/User.swift
Konstantin Wohlwend c8b516833e
Some checks failed
all-good: Did all the other checks pass? / all-good (push) Has been cancelled
Ensure Prisma migrations are in sync with the schema / check_prisma_migrations (22.x) (push) Has been cancelled
Docker Server Build and Push / Docker Build and Push Server (push) Has been cancelled
Docker Server Build and Run / docker (push) Has been cancelled
Runs E2E API Tests / E2E Tests (Node ${{ matrix.node-version }}, Freestyle ${{ matrix.freestyle-mode }}) (mock, 22.x) (push) Has been cancelled
Runs E2E API Tests / E2E Tests (Node ${{ matrix.node-version }}, Freestyle ${{ matrix.freestyle-mode }}) (prod, 22.x) (push) Has been cancelled
Runs E2E API Tests with custom port prefix / build (22.x) (push) Has been cancelled
Lint & build / lint_and_build (latest) (push) Has been cancelled
Mirror main branch to main-mirror-for-wdb / lint_and_build (push) Has been cancelled
Publish npm packages / publish (push) Has been cancelled
Dev Environment Test With Custom Base Port / restart-dev-and-test-with-custom-base-port (push) Has been cancelled
Dev Environment Test / restart-dev-and-test (push) Has been cancelled
Run setup tests with custom base port / setup-tests-with-custom-base-port (push) Has been cancelled
Run setup tests / setup-tests (push) Has been cancelled
Publish Swift SDK to prerelease repo / publish (push) Has been cancelled
Sync Main to Dev / sync-commits (push) Has been cancelled
TOC Generator / TOC Generator (push) Has been cancelled
Add requires_totp_mfa to JWT
2026-03-02 10:09:47 -08:00

83 lines
3.2 KiB
Swift

import Foundation
/// Base user properties visible to clients
/// Note: [String: Any] is not Sendable but we accept this for JSON data
public struct User: @unchecked Sendable {
public let id: String
public let displayName: String?
public let primaryEmail: String?
public let primaryEmailVerified: Bool
public let profileImageUrl: String?
public let signedUpAt: Date
public let clientMetadata: [String: Any]
public let clientReadOnlyMetadata: [String: Any]
public let hasPassword: Bool
public let emailAuthEnabled: Bool
public let otpAuthEnabled: Bool
public let passkeyAuthEnabled: Bool
public let isMultiFactorRequired: Bool
public let isAnonymous: Bool
public let isRestricted: Bool
public let restrictedReason: RestrictedReason?
public let oauthProviders: [OAuthProviderInfo]
public struct RestrictedReason: Sendable {
public let type: String
}
public struct OAuthProviderInfo: Sendable {
public let id: String
}
}
// Make User Sendable by using a wrapper for the metadata
extension User {
init(from json: [String: Any]) {
self.id = json["id"] as? String ?? ""
self.displayName = json["display_name"] as? String
self.primaryEmail = json["primary_email"] as? String
self.primaryEmailVerified = json["primary_email_verified"] as? Bool ?? false
self.profileImageUrl = json["profile_image_url"] as? String
let millis = json["signed_up_at_millis"] as? Int64 ?? 0
self.signedUpAt = Date(timeIntervalSince1970: Double(millis) / 1000.0)
// Note: These are not truly Sendable but we accept the risk for JSON data
self.clientMetadata = json["client_metadata"] as? [String: Any] ?? [:]
self.clientReadOnlyMetadata = json["client_read_only_metadata"] as? [String: Any] ?? [:]
self.hasPassword = json["has_password"] as? Bool ?? false
self.emailAuthEnabled = json["auth_with_email"] as? Bool ?? false
self.otpAuthEnabled = json["otp_auth_enabled"] as? Bool ?? false
self.passkeyAuthEnabled = json["passkey_auth_enabled"] as? Bool ?? false
self.isMultiFactorRequired = json["requires_totp_mfa"] as? Bool ?? false
self.isAnonymous = json["is_anonymous"] as? Bool ?? false
self.isRestricted = json["is_restricted"] as? Bool ?? false
if let reason = json["restricted_reason"] as? [String: Any],
let type = reason["type"] as? String {
self.restrictedReason = RestrictedReason(type: type)
} else {
self.restrictedReason = nil
}
if let providers = json["oauth_providers"] as? [[String: Any]] {
self.oauthProviders = providers.map { OAuthProviderInfo(id: $0["id"] as? String ?? "") }
} else {
self.oauthProviders = []
}
}
}
/// Partial user info extracted from JWT token
public struct TokenPartialUser: Sendable {
public let id: String
public let displayName: String?
public let primaryEmail: String?
public let primaryEmailVerified: Bool
public let isAnonymous: Bool
public let isMultiFactorRequired: Bool
public let isRestricted: Bool
public let restrictedReason: User.RestrictedReason?
}