diff --git a/AuthenticatorShared/Core/Platform/Utilities/ExternalLinksConstants.swift b/AuthenticatorShared/Core/Platform/Utilities/ExternalLinksConstants.swift index c4b7aa60..8f9106c5 100644 --- a/AuthenticatorShared/Core/Platform/Utilities/ExternalLinksConstants.swift +++ b/AuthenticatorShared/Core/Platform/Utilities/ExternalLinksConstants.swift @@ -13,6 +13,8 @@ enum ExternalLinksConstants { /// A link to the app review page within the app store. static let appReview = URL(string: "https://itunes.apple.com/us/app/id1137397744?action=write-review") + static let backupInformation = URL(string: "https://support.apple.com/guide/iphone/back-up-iphone-iph3ecf67d29/ios") + /// A link to Bitwarden's help page for learning more about the account fingerprint phrase. static let fingerprintPhrase = URL(string: "https://bitwarden.com/help/fingerprint-phrase/")! diff --git a/AuthenticatorShared/UI/Platform/Application/Support/Localizations/en.lproj/Localizable.strings b/AuthenticatorShared/UI/Platform/Application/Support/Localizations/en.lproj/Localizable.strings index be9dc242..8efde4a9 100644 --- a/AuthenticatorShared/UI/Platform/Application/Support/Localizations/en.lproj/Localizable.strings +++ b/AuthenticatorShared/UI/Platform/Application/Support/Localizations/en.lproj/Localizable.strings @@ -76,7 +76,6 @@ "Important" = "Important"; "YourMasterPasswordCannotBeRecoveredIfYouForgetItXCharactersMinimum" = "Your master password cannot be recovered if you forget it! %1$@ characters minimum."; "ThereAreNoItemsThatMatchTheSearch" = "There are no items that match the search"; -"Vault" = "Vault"; "Appearance" = "Appearance"; "BitwardenHelpCenter" = "Bitwarden Help Center"; "ContinueToWebApp" = "Continue to web app?"; @@ -119,3 +118,6 @@ "ItemsExported" = "Verification codes exported"; "ItemsImported" = "Vertification codes imported"; "VerificationCodeAdded" = "Verification code added"; +"Data" = "Data"; +"Backup" = "Backup"; +"BitwardenAuthenticatorDataIsBackedUpAndCanBeRestored" = "Bitwarden Authenticator data is backed up and can be restored with your regularly scheduled device backups."; diff --git a/AuthenticatorShared/UI/Platform/Settings/Extensions/Alert+Settings.swift b/AuthenticatorShared/UI/Platform/Settings/Extensions/Alert+Settings.swift index 46de5a21..0a8d61a3 100644 --- a/AuthenticatorShared/UI/Platform/Settings/Extensions/Alert+Settings.swift +++ b/AuthenticatorShared/UI/Platform/Settings/Extensions/Alert+Settings.swift @@ -3,6 +3,25 @@ extension Alert { // MARK: Methods + /// Provide information about data backup. + /// + /// - Parameters: + /// - action: The action to perform if the user selects Learn More. + /// - Returns: An alert for providing backup information. + /// + static func backupInformation(action: @escaping () -> Void) -> Alert { + Alert( + title: Localizations.bitwardenAuthenticatorDataIsBackedUpAndCanBeRestored, + message: nil, + alertActions: [ + AlertAction(title: Localizations.learnMore, style: .default) { _ in + action() + }, + AlertAction(title: Localizations.ok, style: .default), + ] + ) + } + /// Confirm deleting the folder. /// /// - Parameter action: The action to perform if the user selects yes. diff --git a/AuthenticatorShared/UI/Platform/Settings/Extensions/AlertSettingsTests.swift b/AuthenticatorShared/UI/Platform/Settings/Extensions/AlertSettingsTests.swift index 170e3da1..39a884aa 100644 --- a/AuthenticatorShared/UI/Platform/Settings/Extensions/AlertSettingsTests.swift +++ b/AuthenticatorShared/UI/Platform/Settings/Extensions/AlertSettingsTests.swift @@ -3,6 +3,21 @@ import XCTest @testable import AuthenticatorShared class AlertSettingsTests: AuthenticatorTestCase { + /// `backupInformation(action:)` constructs an `Alert` + /// with the correct title, message, and buttons. + func test_backupInformationAlert() { + let subject = Alert.backupInformation {} + + XCTAssertEqual(subject.preferredStyle, .alert) + XCTAssertEqual(subject.title, Localizations.bitwardenAuthenticatorDataIsBackedUpAndCanBeRestored) + XCTAssertNil(subject.message) + XCTAssertEqual(subject.alertActions.count, 2) + XCTAssertEqual(subject.alertActions.first?.title, Localizations.learnMore) + XCTAssertEqual(subject.alertActions.first?.style, .default) + XCTAssertEqual(subject.alertActions.last?.title, Localizations.ok) + XCTAssertEqual(subject.alertActions.last?.style, .default) + } + /// `confirmDeleteFolder(action:)` constructs an `Alert` with the title, /// message, yes, and cancel buttons to confirm deleting a folder. func test_confirmDeleteFolder() { @@ -37,7 +52,7 @@ class AlertSettingsTests: AuthenticatorTestCase { XCTAssertEqual(subject.alertActions.first?.style, .default) } - /// `privacyPolicyAlert(encrypted:action:)` constructs an `Alert` + /// `privacyPolicyAlert(action:)` constructs an `Alert` /// with the correct title, message, and Cancel and Continue buttons. func test_privacyPolicyAlert() { let subject = Alert.privacyPolicyAlert {} diff --git a/AuthenticatorShared/UI/Platform/Settings/Settings/SettingsAction.swift b/AuthenticatorShared/UI/Platform/Settings/Settings/SettingsAction.swift index 0c687691..2316a660 100644 --- a/AuthenticatorShared/UI/Platform/Settings/Settings/SettingsAction.swift +++ b/AuthenticatorShared/UI/Platform/Settings/Settings/SettingsAction.swift @@ -4,6 +4,9 @@ enum SettingsAction: Equatable { /// The default color theme was changed. case appThemeChanged(AppTheme) + /// The backup button was tapped. + case backupTapped + /// The url has been opened so clear the value in the state. case clearURL diff --git a/AuthenticatorShared/UI/Platform/Settings/Settings/SettingsProcessor.swift b/AuthenticatorShared/UI/Platform/Settings/Settings/SettingsProcessor.swift index c58295c1..a7fe8a30 100644 --- a/AuthenticatorShared/UI/Platform/Settings/Settings/SettingsProcessor.swift +++ b/AuthenticatorShared/UI/Platform/Settings/Settings/SettingsProcessor.swift @@ -58,6 +58,10 @@ final class SettingsProcessor: StateProcessor