@@ -171,48 +171,48 @@ extension Auth: AuthInterop {
171171 @objc public internal( set) weak var app : FirebaseApp ?
172172
173173 /// New R-GCIP v2 + BYO-CIAM initializer.
174- ///
175- /// This initializer allows to create an `Auth` instance with a specific `tenantConfig` for
176- /// R-GCIP.
177- /// - Parameters:
178- /// - app: The `FirebaseApp` for which to initialize the `Auth` instance.
179- /// - tenantConfig: The configuration for the tenant, including location and tenant ID.
180- /// - Returns: An `Auth` instance configured for the specified tenant.
181- public static func auth( app: FirebaseApp , tenantConfig: TenantConfig ) -> Auth {
182- // start from the legacy initializer so we get a fully-formed Auth object
183- let auth = auth ( app: app)
184- kAuthGlobalWorkQueue. sync {
185- auth. requestConfiguration. location = tenantConfig. location
186- auth. requestConfiguration. tenantId = tenantConfig. tenantId
187- }
188- return auth
174+ ///
175+ /// This initializer allows to create an `Auth` instance with a specific `tenantConfig` for
176+ /// R-GCIP.
177+ /// - Parameters:
178+ /// - app: The `FirebaseApp` for which to initialize the `Auth` instance.
179+ /// - tenantConfig: The configuration for the tenant, including location and tenant ID.
180+ /// - Returns: An `Auth` instance configured for the specified tenant.
181+ public static func auth( app: FirebaseApp , tenantConfig: TenantConfig ) -> Auth {
182+ // start from the legacy initializer so we get a fully-formed Auth object
183+ let auth = auth ( app: app)
184+ kAuthGlobalWorkQueue. sync {
185+ auth. requestConfiguration. location = tenantConfig. location
186+ auth. requestConfiguration. tenantId = tenantConfig. tenantId
189187 }
188+ return auth
189+ }
190190
191- /// Holds configuration for a R-GCIP tenant.
191+ /// Holds configuration for a R-GCIP tenant.
192192 public struct TenantConfig : Sendable {
193- public let tenantId : String /// The ID of the tenant.
194- public let location : String /// The location of the tenant.
193+ public let tenantId : String /// The ID of the tenant.
194+ public let location : String /// The location of the tenant.
195195
196- /// Initializes a `TenantConfig` instance.
197- /// - Parameters:
198- /// - location: The location of the tenant, defaults to "prod-global".
199- /// - tenantId: The ID of the tenant.
200- public init ( tenantId: String , location: String = " prod-global " ) {
201- self . location = location
202- self . tenantId = tenantId
203- }
196+ /// Initializes a `TenantConfig` instance.
197+ /// - Parameters:
198+ /// - location: The location of the tenant, defaults to "prod-global".
199+ /// - tenantId: The ID of the tenant.
200+ public init ( tenantId: String , location: String = " prod-global " ) {
201+ self . location = location
202+ self . tenantId = tenantId
204203 }
204+ }
205205
206- /// Holds a Firebase ID token and its expiration.
206+ /// Holds a Firebase ID token and its expiration.
207207 public struct AuthExchangeToken : Sendable {
208- public let token : String
209- public let expirationDate : Date ?
210- init ( token: String , expirationDate: Date ) {
211- self . token = token
212- self . expirationDate = expirationDate
213- }
208+ public let token : String
209+ public let expirationDate : Date ?
210+ init ( token: String , expirationDate: Date ) {
211+ self . token = token
212+ self . expirationDate = expirationDate
214213 }
215-
214+ }
215+
216216 /// Synchronously gets the cached current user, or null if there is none.
217217 @objc public var currentUser : User ? {
218218 kAuthGlobalWorkQueue. sync {
@@ -2471,7 +2471,6 @@ extension Auth: AuthInterop {
24712471
24722472@available ( iOS 13 , * )
24732473public extension Auth {
2474-
24752474 /// Exchanges a third-party OIDC token for a Firebase STS token using a completion handler.
24762475 ///
24772476 /// This method is used in R-GCIP (multi-tenant) environments where the `Auth` instance must
@@ -2481,81 +2480,80 @@ public extension Auth {
24812480 /// - idToken: The OIDC token received from the third-party Identity Provider (IdP).
24822481 /// - idpConfigId: The identifier of the OIDC provider configuration defined in Firebase.
24832482 /// - completion: A closure that gets called with either an `AuthTokenResult` or an `Error`.
2484- public func exchangeToken(
2485- idToken: String ,
2486- idpConfigId: String ,
2487- completion: @escaping ( AuthTokenResult ? , Error ? ) -> Void
2488- ) {
2489- // Ensure R-GCIP is configured with location and tenant ID
2490- guard let location = requestConfiguration. location,
2491- let tenantId = requestConfiguration. tenantId
2492- else {
2493- completion ( nil , AuthErrorCode . operationNotAllowed)
2494- return
2495- }
2483+ func exchangeToken( idToken: String ,
2484+ idpConfigId: String ,
2485+ completion: @escaping ( AuthTokenResult ? , Error ? ) -> Void ) {
2486+ // Ensure R-GCIP is configured with location and tenant ID
2487+ guard let location = requestConfiguration. location,
2488+ let tenantId = requestConfiguration. tenantId
2489+ else {
2490+ completion ( nil , AuthErrorCode . operationNotAllowed)
2491+ return
2492+ }
24962493
2497- // Build the exchange token request
2498- let request = ExchangeTokenRequest (
2499- idToken: idToken,
2500- idpConfigID: idpConfigId,
2501- config: requestConfiguration
2502- )
2494+ // Build the exchange token request
2495+ let request = ExchangeTokenRequest (
2496+ idToken: idToken,
2497+ idpConfigID: idpConfigId,
2498+ config: requestConfiguration
2499+ )
25032500
2504- // Perform the token exchange asynchronously
2505- Task {
2506- do {
2507- let response = try await backend. call ( with: request)
2508- do {
2509- // Try to parse the Firebase token response
2510- let authTokenResult = try AuthTokenResult . tokenResult ( token: response. firebaseToken)
2511- DispatchQueue . main. async {
2512- completion ( authTokenResult, nil )
2513- }
2514- } catch {
2515- // Failed to parse JWT
2516- DispatchQueue . main. async {
2517- completion ( nil , AuthErrorCode . malformedJWT)
2518- }
2519- }
2520- } catch {
2521- // Backend call failed
2522- DispatchQueue . main. async {
2523- completion ( nil , error)
2524- }
2501+ // Perform the token exchange asynchronously
2502+ Task {
2503+ do {
2504+ let response = try await backend. call ( with: request)
2505+ do {
2506+ // Try to parse the Firebase token response
2507+ let authTokenResult = try AuthTokenResult . tokenResult ( token: response. firebaseToken)
2508+ DispatchQueue . main. async {
2509+ completion ( authTokenResult, nil )
2510+ }
2511+ } catch {
2512+ // Failed to parse JWT
2513+ DispatchQueue . main. async {
2514+ completion ( nil , AuthErrorCode . malformedJWT)
25252515 }
2516+ }
2517+ } catch {
2518+ // Backend call failed
2519+ DispatchQueue . main. async {
2520+ completion ( nil , error)
2521+ }
25262522 }
2523+ }
25272524 }
2528-
2525+
25292526 /// Exchanges a third-party OIDC token for a Firebase STS token using Swift concurrency.
25302527 ///
25312528 /// This async variant performs the same operation as the completion-based method but returns
25322529 /// the result directly and throws on failure.
25332530 ///
2534- /// The `Auth` instance must be configured with `TenantConfig` containing `location` and `tenantId`.
2531+ /// The `Auth` instance must be configured with `TenantConfig` containing `location` and
2532+ /// `tenantId`.
25352533 ///
25362534 /// - Parameters:
25372535 /// - idToken: The OIDC token received from the third-party Identity Provider (IdP).
25382536 /// - idpConfigId: The identifier of the OIDC provider configuration defined in Firebase.
25392537 /// - Returns: An `AuthTokenResult` containing the Firebase ID token and its expiration details.
25402538 /// - Throws: An error if R-GCIP is not configured, if the network call fails,
25412539 /// or if the token parsing fails.
2542- public func exchangeToken( idToken: String , idpConfigId: String ) async throws -> AuthTokenResult {
2543- // Ensure R-GCIP is configured with location and tenant ID
2544- guard let location = requestConfiguration. location,
2545- let tenantId = requestConfiguration. tenantId
2546- else {
2547- throw AuthErrorCode . operationNotAllowed
2548- }
2549-
2550- // Build the exchange token request
2551- let request = ExchangeTokenRequest (
2552- idToken: idToken,
2553- idpConfigID: idpConfigId,
2554- config: requestConfiguration
2555- )
2540+ func exchangeToken( idToken: String , idpConfigId: String ) async throws -> AuthTokenResult {
2541+ // Ensure R-GCIP is configured with location and tenant ID
2542+ guard let location = requestConfiguration. location,
2543+ let tenantId = requestConfiguration. tenantId
2544+ else {
2545+ throw AuthErrorCode . operationNotAllowed
2546+ }
2547+
2548+ // Build the exchange token request
2549+ let request = ExchangeTokenRequest (
2550+ idToken: idToken,
2551+ idpConfigID: idpConfigId,
2552+ config: requestConfiguration
2553+ )
25562554
2557- // Perform the backend call and return parsed token
2558- let response = try await backend. call ( with: request)
2559- return try AuthTokenResult . tokenResult ( token: response. firebaseToken)
2555+ // Perform the backend call and return parsed token
2556+ let response = try await backend. call ( with: request)
2557+ return try AuthTokenResult . tokenResult ( token: response. firebaseToken)
25602558 }
25612559}
0 commit comments