Skip to content

Commit edb8b73

Browse files
fix: allow reauth on sensitive operations
1 parent a4c43be commit edb8b73

File tree

1 file changed

+27
-15
lines changed

1 file changed

+27
-15
lines changed

FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Services/AuthService.swift

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,13 @@ public final class AuthService {
188188
public func linkAccounts(credentials credentials: AuthCredential) async throws {
189189
authenticationState = .authenticating
190190
do {
191-
try await currentUser?.link(with: credentials)
191+
guard let user = currentUser else {
192+
throw AuthServiceError.noCurrentUser
193+
}
194+
195+
try await withReauthenticationIfNeeded(on: user) {
196+
try await user.link(with: credentials)
197+
}
192198
updateAuthenticationState()
193199
} catch {
194200
authenticationState = .unauthenticated
@@ -702,7 +708,9 @@ public extension AuthService {
702708
}
703709

704710
// Complete the enrollment
705-
try await user.multiFactor.enroll(with: assertion, displayName: displayName)
711+
try await withReauthenticationIfNeeded(on: user) {
712+
try await user.multiFactor.enroll(with: assertion, displayName: displayName)
713+
}
706714
currentUser = auth.currentUser
707715
} catch {
708716
updateError(message: string.localizedErrorMessage(for: error))
@@ -731,6 +739,22 @@ public extension AuthService {
731739
}
732740
}
733741

742+
private func withReauthenticationIfNeeded(on user: User,
743+
operation: () async throws -> Void) async throws {
744+
do {
745+
try await operation()
746+
} catch let error as NSError {
747+
if error.domain == AuthErrorDomain,
748+
error.code == AuthErrorCode.requiresRecentLogin.rawValue || error.code == AuthErrorCode
749+
.userTokenExpired.rawValue {
750+
try await reauthenticateCurrentUser(on: user)
751+
try await operation()
752+
} else {
753+
throw error
754+
}
755+
}
756+
}
757+
734758
func unenrollMFA(_ factorUid: String) async throws -> [MultiFactorInfo] {
735759
do {
736760
guard let user = auth.currentUser else {
@@ -739,20 +763,8 @@ public extension AuthService {
739763

740764
let multiFactorUser = user.multiFactor
741765

742-
do {
766+
try await withReauthenticationIfNeeded(on: user) {
743767
try await multiFactorUser.unenroll(withFactorUID: factorUid)
744-
} catch let error as NSError {
745-
if error.domain == AuthErrorDomain,
746-
error.code == AuthErrorCode.requiresRecentLogin.rawValue || error.code == AuthErrorCode
747-
.userTokenExpired.rawValue {
748-
try await reauthenticateCurrentUser(on: user)
749-
try await multiFactorUser.unenroll(withFactorUID: factorUid)
750-
} else {
751-
throw AuthServiceError
752-
.multiFactorAuth(
753-
"Invalid second factor: \(error.localizedDescription)"
754-
)
755-
}
756768
}
757769

758770
// This is the only we to get the actual latest enrolledFactors

0 commit comments

Comments
 (0)