Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .github/workflows/swiftui-auth.yml
Original file line number Diff line number Diff line change
Expand Up @@ -176,8 +176,7 @@ jobs:
xcodebuild test-without-building \
-scheme FirebaseSwiftUIExampleUITests \
-destination 'platform=iOS Simulator,name=iPhone 17' \
-parallel-testing-enabled YES \
-maximum-concurrent-test-simulator-destinations 2 \
-parallel-testing-enabled NO \
-enableCodeCoverage YES \
-resultBundlePath FirebaseSwiftUIExampleUITests.xcresult | tee FirebaseSwiftUIExampleUITests.log | xcpretty --test --color --simple

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ extension AuthPickerView: View {
VStack {
authService.renderButtons()
}
.padding(.horizontal, proxy.size.width * 0.18)
.padding(.horizontal, proxy.size.width * 0.14)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ extension EmailAuthView: View {
keyboardType: .emailAddress,
contentType: .emailAddress,
validations: [
FormValidators.email
FormValidators.email,
],
maintainsValidationMessage: authService.authenticationFlow == .signUp,
onSubmit: { _ in
Expand Down Expand Up @@ -161,7 +161,7 @@ extension EmailAuthView: View {
contentType: .password,
isSecureTextField: true,
validations: [
FormValidators.confirmPassword(password: password)
FormValidators.confirmPassword(password: password),
],
maintainsValidationMessage: true,
onSubmit: { _ in
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ extension EmailLinkView: View {
keyboardType: .emailAddress,
contentType: .emailAddress,
validations: [
FormValidators.email
FormValidators.email,
],
leading: {
Image(systemName: "at")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ struct EnterPhoneNumberView: View {
keyboardType: .phonePad,
contentType: .telephoneNumber,
validations: [
FormValidators.phoneNumber
FormValidators.phoneNumber,
],
onChange: { _ in }
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ struct EnterVerificationCodeView: View {
VerificationCodeInputField(
code: $verificationCode,
validations: [
FormValidators.verificationCode
FormValidators.verificationCode,
],
maintainsValidationMessage: true
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ private enum FocusableField: Hashable {
@MainActor
public struct MFAEnrolmentView {
@Environment(AuthService.self) private var authService
@Environment(\.reportError) private var reportError

@State private var selectedFactorType: SecondFactorType = .sms
@State private var phoneNumber = ""
Expand Down Expand Up @@ -81,12 +82,16 @@ public struct MFAEnrolmentView {
isLoading = true
defer { isLoading = false }

let session = try await authService.startMfaEnrollment(
type: selectedFactorType,
accountName: authService.currentUser?.email,
issuer: authService.configuration.mfaIssuer
)
currentSession = session
do {
let session = try await authService.startMfaEnrollment(
type: selectedFactorType,
accountName: authService.currentUser?.email,
issuer: authService.configuration.mfaIssuer
)
currentSession = session
} catch {
reportError?(error)
}
}
}

Expand All @@ -97,23 +102,27 @@ public struct MFAEnrolmentView {
isLoading = true
defer { isLoading = false }

let fullPhoneNumber = selectedCountry.dialCode + phoneNumber
let verificationId = try await authService.sendSmsVerificationForEnrollment(
session: session,
phoneNumber: fullPhoneNumber
)
// Update session status
currentSession = EnrollmentSession(
id: session.id,
type: session.type,
session: session.session,
totpInfo: session.totpInfo,
phoneNumber: fullPhoneNumber,
verificationId: verificationId,
status: .verificationSent,
createdAt: session.createdAt,
expiresAt: session.expiresAt
)
do {
let fullPhoneNumber = selectedCountry.dialCode + phoneNumber
let verificationId = try await authService.sendSmsVerificationForEnrollment(
session: session,
phoneNumber: fullPhoneNumber
)
// Update session status
currentSession = EnrollmentSession(
id: session.id,
type: session.type,
session: session.session,
totpInfo: session.totpInfo,
phoneNumber: fullPhoneNumber,
verificationId: verificationId,
status: .verificationSent,
createdAt: session.createdAt,
expiresAt: session.expiresAt
)
} catch {
reportError?(error)
}
}
}

Expand All @@ -124,18 +133,22 @@ public struct MFAEnrolmentView {
isLoading = true
defer { isLoading = false }

let code = session.type == .sms ? verificationCode : totpCode
try await authService.completeEnrollment(
session: session,
verificationId: session.verificationId,
verificationCode: code,
displayName: displayName
)

// Reset form state on success
resetForm()

authService.navigator.clear()
do {
let code = session.type == .sms ? verificationCode : totpCode
try await authService.completeEnrollment(
session: session,
verificationId: session.verificationId,
verificationCode: code,
displayName: displayName
)

// Reset form state on success
resetForm()

authService.navigator.clear()
} catch {
reportError?(error)
}
}
}

Expand Down Expand Up @@ -375,7 +388,7 @@ extension MFAEnrolmentView: View {
keyboardType: .phonePad,
contentType: .telephoneNumber,
validations: [
FormValidators.phoneNumber
FormValidators.phoneNumber,
],
maintainsValidationMessage: true,
onChange: { _ in }
Expand All @@ -393,7 +406,7 @@ extension MFAEnrolmentView: View {
label: authService.string.displayNameFieldLabel,
prompt: authService.string.enterDisplayNameForDevicePrompt,
validations: [
FormValidators.notEmpty(label: "Display name")
FormValidators.notEmpty(label: "Display name"),
],
maintainsValidationMessage: true,
leading: {
Expand Down Expand Up @@ -441,7 +454,7 @@ extension MFAEnrolmentView: View {
VerificationCodeInputField(
code: $verificationCode,
validations: [
FormValidators.verificationCode
FormValidators.verificationCode,
],
maintainsValidationMessage: true
)
Expand Down Expand Up @@ -584,7 +597,7 @@ extension MFAEnrolmentView: View {
label: authService.string.displayNameFieldLabel,
prompt: authService.string.enterDisplayNameForAuthenticatorPrompt,
validations: [
FormValidators.notEmpty(label: "Display name")
FormValidators.notEmpty(label: "Display name"),
],
maintainsValidationMessage: true,
leading: {
Expand All @@ -596,7 +609,7 @@ extension MFAEnrolmentView: View {
VerificationCodeInputField(
code: $totpCode,
validations: [
FormValidators.verificationCode
FormValidators.verificationCode,
],
maintainsValidationMessage: true
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ extension MultiFactorInfo: Identifiable {
@MainActor
public struct MFAManagementView {
@Environment(AuthService.self) private var authService
@Environment(\.reportError) private var reportError

@State private var enrolledFactors: [MultiFactorInfo] = []
@State private var isLoading = false
Expand All @@ -43,6 +44,7 @@ public struct MFAManagementView {
enrolledFactors = freshFactors
isLoading = false
} catch {
reportError?(error)
isLoading = false
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ private enum FocusableField: Hashable {
@MainActor
public struct MFAResolutionView {
@Environment(AuthService.self) private var authService
@Environment(\.reportError) private var reportError

@State private var verificationCode = ""
@State private var totpCode = ""
Expand Down Expand Up @@ -72,6 +73,7 @@ public struct MFAResolutionView {
self.verificationId = verificationId
isLoading = false
} catch {
reportError?(error)
isLoading = false
}
}
Expand All @@ -93,6 +95,7 @@ public struct MFAResolutionView {
authService.navigator.clear()
isLoading = false
} catch {
reportError?(error)
isLoading = false
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ extension PasswordRecoveryView: View {
keyboardType: .emailAddress,
contentType: .emailAddress,
validations: [
FormValidators.email
FormValidators.email,
],
leading: {
Image(systemName: "at")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,7 @@ public struct UpdatePasswordView {
do {
try await authService.updatePassword(to: confirmPassword)
showAlert = true
} catch {

}
} catch {}
}
}
}
Expand All @@ -64,7 +62,7 @@ extension UpdatePasswordView: View {
contentType: .password,
isSecureTextField: true,
validations: [
FormValidators.atLeast6Characters
FormValidators.atLeast6Characters,
],
maintainsValidationMessage: true,
leading: {
Expand All @@ -81,7 +79,7 @@ extension UpdatePasswordView: View {
contentType: .password,
isSecureTextField: true,
validations: [
FormValidators.confirmPassword(password: password)
FormValidators.confirmPassword(password: password),
],
maintainsValidationMessage: true,
leading: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public struct AuthTextField<Leading: View>: View {
@FocusState private var isFocused: Bool
@State var obscured: Bool = true
@State var hasInteracted: Bool = false

@Binding var text: String
let label: String
let prompt: String
Expand All @@ -32,7 +32,7 @@ public struct AuthTextField<Leading: View>: View {
var onSubmit: ((String) -> Void)? = nil
var onChange: ((String) -> Void)? = nil
private let leading: () -> Leading?

public init(text: Binding<String>,
label: String,
prompt: String,
Expand Down Expand Up @@ -60,11 +60,11 @@ public struct AuthTextField<Leading: View>: View {
self.onChange = onChange
self.leading = leading
}

var allRequirementsMet: Bool {
validations.allSatisfy { $0.isValid(input: text) }
}

public var body: some View {
VStack(alignment: .leading) {
Text(LocalizedStringResource(stringLiteral: label))
Expand Down Expand Up @@ -142,7 +142,8 @@ public struct AuthTextField<Leading: View>: View {
isFocused = true
}
}
if !validations.isEmpty && hasInteracted && (maintainsValidationMessage || !allRequirementsMet) {
if !validations
.isEmpty && hasInteracted && (maintainsValidationMessage || !allRequirementsMet) {
VStack(alignment: .leading, spacing: 4) {
ForEach(validations) { validator in
let isValid = validator.isValid(input: text)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@ public struct VerificationCodeInputField: View {
.frame(maxWidth: .infinity, alignment: .leading)
}

if !validations.isEmpty && hasInteracted && (maintainsValidationMessage || !allRequirementsMet) {
if !validations
.isEmpty && hasInteracted && (maintainsValidationMessage || !allRequirementsMet) {
VStack(alignment: .leading, spacing: 4) {
ForEach(validations) { validator in
let isValid = validator.isValid(input: code)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ public struct FormValidators {
}
)

public static func confirmPassword(password: @autoclosure @escaping () -> String) -> FormValidator {
public static func confirmPassword(password: @autoclosure @escaping () -> String)
-> FormValidator {
return FormValidator(
message: "Passwords must match",
validate: { input in
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ public class FacebookProviderSwift: CredentialAuthProviderSwift {
"`rawNonce` has not been generated for Facebook limited login"
)
}
let credential = OAuthProvider.credential(withProviderID: providerId,
let credential = OAuthProvider.credential(providerID: .facebook,
idToken: idToken.tokenString,
rawNonce: nonce)
return credential
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,25 @@
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
shouldAutocreateTestPlan = "YES">
shouldAutocreateTestPlan = "YES"
codeCoverageEnabled = "NO"
onlyGenerateCoverageForSpecifiedTargets = "NO">
<TestPlans>
</TestPlans>
<Testables>
<TestableReference
skipped = "NO"
parallelizable = "NO"
testExecutionOrdering = "random">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "46F89C412D64A86D000F8BC0"
BuildableName = "FirebaseSwiftUIExampleUITests.xctest"
BlueprintName = "FirebaseSwiftUIExampleUITests"
ReferencedContainer = "container:FirebaseSwiftUIExample.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
Expand Down
Loading