Skip to content

Commit c092c02

Browse files
authored
[Auth] Refactor MultiFactor.swift (#14241)
1 parent ffe6cf2 commit c092c02

File tree

1 file changed

+77
-83
lines changed

1 file changed

+77
-83
lines changed

FirebaseAuth/Sources/Swift/MultiFactor/MultiFactor.swift

Lines changed: 77 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -67,104 +67,98 @@ import Foundation
6767
displayName: String?,
6868
completion: ((Error?) -> Void)?) {
6969
// TODO: Refactor classes so this duplicated code isn't necessary for phone and totp.
70+
71+
guard
72+
assertion.factorID == PhoneMultiFactorInfo.TOTPMultiFactorID ||
73+
assertion.factorID == PhoneMultiFactorInfo.PhoneMultiFactorID
74+
else {
75+
return
76+
}
77+
78+
guard let user, let auth = user.auth else {
79+
fatalError("Internal Auth error: failed to get user enrolling in MultiFactor")
80+
}
81+
82+
let request = Self.enrollmentFinalizationRequest(
83+
with: assertion,
84+
displayName: displayName,
85+
user: user,
86+
auth: auth
87+
)
88+
89+
Task {
90+
do {
91+
let response = try await auth.backend.call(with: request)
92+
let user = try await auth.completeSignIn(withAccessToken: response.idToken,
93+
accessTokenExpirationDate: nil,
94+
refreshToken: response.refreshToken,
95+
anonymous: false)
96+
try auth.updateCurrentUser(user, byForce: false, savingToDisk: true)
97+
if let completion {
98+
DispatchQueue.main.async {
99+
completion(nil)
100+
}
101+
}
102+
} catch {
103+
if let completion {
104+
DispatchQueue.main.async {
105+
completion(error)
106+
}
107+
}
108+
}
109+
}
110+
}
111+
112+
private static func enrollmentFinalizationRequest(with assertion: MultiFactorAssertion,
113+
displayName: String?,
114+
user: User,
115+
auth: Auth) -> FinalizeMFAEnrollmentRequest {
116+
var request: FinalizeMFAEnrollmentRequest? = nil
70117
if assertion.factorID == PhoneMultiFactorInfo.TOTPMultiFactorID {
71118
guard let totpAssertion = assertion as? TOTPMultiFactorAssertion else {
72119
fatalError("Auth Internal Error: Failed to find TOTPMultiFactorAssertion")
73120
}
74121
switch totpAssertion.secretOrID {
75122
case .enrollmentID: fatalError("Missing secret in totpAssertion")
76123
case let .secret(secret):
77-
guard let user = user, let auth = user.auth else {
78-
fatalError("Internal Auth error: failed to get user enrolling in MultiFactor")
79-
}
80124
let finalizeMFATOTPRequestInfo =
81125
AuthProtoFinalizeMFATOTPEnrollmentRequestInfo(sessionInfo: secret.sessionInfo,
82126
verificationCode: totpAssertion
83127
.oneTimePassword)
84-
let request = FinalizeMFAEnrollmentRequest(idToken: self.user?.rawAccessToken(),
85-
displayName: displayName,
86-
totpVerificationInfo: finalizeMFATOTPRequestInfo,
87-
requestConfiguration: user
88-
.requestConfiguration)
89-
Task {
90-
do {
91-
let response = try await auth.backend.call(with: request)
92-
do {
93-
let user = try await auth.completeSignIn(withAccessToken: response.idToken,
94-
accessTokenExpirationDate: nil,
95-
refreshToken: response.refreshToken,
96-
anonymous: false)
97-
try auth.updateCurrentUser(user, byForce: false, savingToDisk: true)
98-
if let completion {
99-
DispatchQueue.main.async {
100-
completion(nil)
101-
}
102-
}
103-
} catch {
104-
DispatchQueue.main.async {
105-
if let completion {
106-
completion(error)
107-
}
108-
}
109-
}
110-
} catch {
111-
if let completion {
112-
completion(error)
113-
}
114-
}
115-
}
128+
request = FinalizeMFAEnrollmentRequest(idToken: user.rawAccessToken(),
129+
displayName: displayName,
130+
totpVerificationInfo: finalizeMFATOTPRequestInfo,
131+
requestConfiguration: user
132+
.requestConfiguration)
116133
}
117-
return
118-
} else if assertion.factorID != PhoneMultiFactorInfo.PhoneMultiFactorID {
119-
return
120-
}
121-
let phoneAssertion = assertion as? PhoneMultiFactorAssertion
122-
guard let credential = phoneAssertion?.authCredential else {
123-
fatalError("Internal Error: Missing credential")
124-
}
125-
switch credential.credentialKind {
126-
case .phoneNumber: fatalError("Internal Error: Missing verificationCode")
127-
case let .verification(verificationID, code):
128-
let finalizeMFAPhoneRequestInfo =
129-
AuthProtoFinalizeMFAPhoneRequestInfo(sessionInfo: verificationID, verificationCode: code)
130-
guard let user = user, let auth = user.auth else {
131-
fatalError("Internal Auth error: failed to get user enrolling in MultiFactor")
134+
} else if assertion.factorID == PhoneMultiFactorInfo.PhoneMultiFactorID {
135+
let phoneAssertion = assertion as? PhoneMultiFactorAssertion
136+
guard let credential = phoneAssertion?.authCredential else {
137+
fatalError("Internal Error: Missing credential")
132138
}
133-
let request = FinalizeMFAEnrollmentRequest(
134-
idToken: self.user?.rawAccessToken(),
135-
displayName: displayName,
136-
phoneVerificationInfo: finalizeMFAPhoneRequestInfo,
137-
requestConfiguration: user.requestConfiguration
138-
)
139-
140-
Task {
141-
do {
142-
let response = try await auth.backend.call(with: request)
143-
do {
144-
let user = try await auth.completeSignIn(withAccessToken: response.idToken,
145-
accessTokenExpirationDate: nil,
146-
refreshToken: response.refreshToken,
147-
anonymous: false)
148-
try auth.updateCurrentUser(user, byForce: false, savingToDisk: true)
149-
if let completion {
150-
DispatchQueue.main.async {
151-
completion(nil)
152-
}
153-
}
154-
} catch {
155-
DispatchQueue.main.async {
156-
if let completion {
157-
completion(error)
158-
}
159-
}
160-
}
161-
} catch {
162-
if let completion {
163-
completion(error)
164-
}
165-
}
139+
switch credential.credentialKind {
140+
case .phoneNumber: fatalError("Internal Error: Missing verificationCode")
141+
case let .verification(verificationID, code):
142+
let finalizeMFAPhoneRequestInfo =
143+
AuthProtoFinalizeMFAPhoneRequestInfo(
144+
sessionInfo: verificationID,
145+
verificationCode: code
146+
)
147+
request = FinalizeMFAEnrollmentRequest(
148+
idToken: user.rawAccessToken(),
149+
displayName: displayName,
150+
phoneVerificationInfo: finalizeMFAPhoneRequestInfo,
151+
requestConfiguration: user.requestConfiguration
152+
)
166153
}
167154
}
155+
156+
guard let request else {
157+
// Assertion is not a phone assertion or TOTP assertion.
158+
fatalError("Internal Error: Unsupported assertion with factor ID: \(assertion.factorID).")
159+
}
160+
161+
return request
168162
}
169163

170164
/// Enrolls a second factor as identified by the `MultiFactorAssertion` parameter for the

0 commit comments

Comments
 (0)