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
Original file line number Diff line number Diff line change
Expand Up @@ -3053,6 +3053,10 @@
}
}
},
"Please tap on the link in your email to complete verification." : {
"comment" : "A message displayed in a sheet that appears after a user requests email verification. It instructs the user to tap on the link in their email to complete the verification process.",
"isCommentAutoGenerated" : true
},
"PrivacyPolicy" : {
"comment" : "Text linked to a web page with the Privacy Policy content.",
"extractionState" : "manual",
Expand Down Expand Up @@ -4963,5 +4967,5 @@

}
},
"version" : "1.0"
"version" : "1.1"
}
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,13 @@ public class StringUtils {
return localizedString(for: "EnterYourPassword")
}

/// Update password title
/// found in:
/// - UpdatePasswordView
public var updatePasswordTitle: String {
return localizedString(for: "UpdatePasswordTitle")
}

/// Password recovery title
/// found in:
/// - PasswordRecoveryView
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,6 @@ extension MFAManagementView: View {
.onAppear {
loadEnrolledFactors()
}
// Password prompt sheet now centralized in AuthPickerView
}

@ViewBuilder
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,25 +143,15 @@ extension SignedInView: View {
)
.presentationDetents([.medium])
}
// Password prompt sheet now centralized in AuthPickerView
.sheet(isPresented: $showEmailVerificationSent) {
VStack(spacing: 24) {
Text(authService.string.verifyEmailSheetMessage)
.font(.headline)
Button {
showEmailVerificationSent = false
} label: {
Text(authService.string.okButtonLabel)
.padding(.vertical, 8)
.frame(maxWidth: .infinity)
}
.buttonStyle(.borderedProminent)
.padding([.top, .bottom], 8)
.frame(maxWidth: .infinity)
.alert(
authService.string.verifyEmailSheetMessage,
isPresented: $showEmailVerificationSent
) {
Button(authService.string.okButtonLabel) {
showEmailVerificationSent = false
}
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top)
.safeAreaPadding()
.presentationDetents([.medium])
} message: {
Text("Please tap on the link in your email to complete verification.")
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ extension UpdatePasswordView: View {
}
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top)
.safeAreaPadding()
.navigationTitle(authService.string.passwordRecoveryTitle)
.navigationTitle(authService.string.updatePasswordTitle)
.alert(
"Password Updated",
isPresented: $showAlert
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,21 @@ import XCTest

final class MFAEnrollmentUITests: XCTestCase {
var app: XCUIApplication!

override func setUpWithError() throws {
continueAfterFailure = false
}

override func tearDownWithError() throws {
// Clean up: Terminate app
if let app = app {
app.terminate()
}
app = nil

// Small delay between tests to allow emulator to settle
Thread.sleep(forTimeInterval: 0.5)

try super.tearDownWithError()
}

Expand Down Expand Up @@ -226,7 +226,7 @@ final class MFAEnrollmentUITests: XCTestCase {
let phoneField = app.textFields["phone-number-field"]
XCTAssertTrue(phoneField.waitForExistence(timeout: 10))
// Generate unique phone number using timestamp to avoid conflicts between tests
let uniqueId = Int(Date().timeIntervalSince1970 * 1000) % 1000000
let uniqueId = Int(Date().timeIntervalSince1970 * 1000) % 1_000_000
let phoneNumberWithoutDialCode = "7\(String(format: "%09d", uniqueId))"
UIPasteboard.general.string = phoneNumberWithoutDialCode
phoneField.tap()
Expand Down Expand Up @@ -258,9 +258,9 @@ final class MFAEnrollmentUITests: XCTestCase {

// Paste each digit into the corresponding text field
let codeDigits = Array(code)
let fields = [verificationCodeField1, verificationCodeField2, verificationCodeField3,
let fields = [verificationCodeField1, verificationCodeField2, verificationCodeField3,
verificationCodeField4, verificationCodeField5, verificationCodeField6]

for (index, digit) in codeDigits.enumerated() where index < fields.count {
let field = fields[index]
UIPasteboard.general.string = String(digit)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,9 @@ func createEmail() -> String {
guard let http = sendResp as? HTTPURLResponse, http.statusCode == 200 else {
let errorBody = String(data: sendData, encoding: .utf8) ?? "Unknown error"
throw NSError(domain: "EmulatorError", code: 1,
userInfo: [NSLocalizedDescriptionKey: "Failed to send verification email: \(errorBody)"])
userInfo: [
NSLocalizedDescriptionKey: "Failed to send verification email: \(errorBody)",
])
}

// Add a small delay to ensure the OOB code is registered in the emulator
Expand All @@ -156,12 +158,12 @@ func createEmail() -> String {

// Step 2: Fetch OOB codes from emulator with retry logic
let oobURL = URL(string: "\(base)/emulator/v1/projects/\(projectID)/oobCodes")!

var codeItem: OobItem?
var attempts = 0
let maxAttempts = 5
while codeItem == nil && attempts < maxAttempts {

while codeItem == nil, attempts < maxAttempts {
let (oobData, oobResp) = try await URLSession.shared.data(from: oobURL)
guard (oobResp as? HTTPURLResponse)?.statusCode == 200 else {
throw NSError(domain: "EmulatorError", code: 2,
Expand All @@ -182,15 +184,16 @@ func createEmail() -> String {
return d0 > d1
}
.first

if codeItem == nil {
attempts += 1
if attempts < maxAttempts {
// Wait before retrying
try await Task.sleep(nanoseconds: 500_000_000) // 0.5 seconds
} else {
// Log available codes for debugging
let availableCodes = envelope.oobCodes.map { "Email: \($0.email), Type: \($0.requestType)" }.joined(separator: "; ")
let availableCodes = envelope.oobCodes.map { "Email: \($0.email), Type: \($0.requestType)" }
.joined(separator: "; ")
throw NSError(domain: "EmulatorError", code: 3,
userInfo: [
NSLocalizedDescriptionKey: "No VERIFY_EMAIL OOB code found for \(email) after \(maxAttempts) attempts. Available codes: \(availableCodes)",
Expand Down
Loading