diff --git a/Authenticator.xcodeproj/project.pbxproj b/Authenticator.xcodeproj/project.pbxproj index fb588860..4cd50e87 100644 --- a/Authenticator.xcodeproj/project.pbxproj +++ b/Authenticator.xcodeproj/project.pbxproj @@ -15,7 +15,6 @@ 513D4DF52660EBA40022C53D /* ConfigurationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 513D4DF42660EBA40022C53D /* ConfigurationController.swift */; }; 513D4DF7266634280022C53D /* ShowTime.swift in Sources */ = {isa = PBXBuildFile; fileRef = 513D4DF6266634280022C53D /* ShowTime.swift */; }; 513D4DF9266A21250022C53D /* DelegateStack.swift in Sources */ = {isa = PBXBuildFile; fileRef = 513D4DF8266A21250022C53D /* DelegateStack.swift */; }; - 513F34BE24633A7900FCE030 /* EditCredential.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 513F34BD24633A7900FCE030 /* EditCredential.storyboard */; }; 513F34C02463F0C900FCE030 /* EditFieldController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 513F34BF2463F0C900FCE030 /* EditFieldController.swift */; }; 513F34C22463F44300FCE030 /* EditCredentialController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 513F34C12463F44300FCE030 /* EditCredentialController.swift */; }; 513F34C82464658F00FCE030 /* SettingsRowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 513F34C72464658F00FCE030 /* SettingsRowView.swift */; }; @@ -39,7 +38,6 @@ 5156D05F265D3CEF007A94F8 /* TokenRequestViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5156D05E265D3CEF007A94F8 /* TokenRequestViewModel.swift */; }; 5180974326DE185100A122C1 /* ResetOATHViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5180974226DE185100A122C1 /* ResetOATHViewModel.swift */; }; 51A162862678A1F100C3FA1E /* OATHConfigurationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51A162852678A1F100C3FA1E /* OATHConfigurationController.swift */; }; - 51AFD4D42716FC78008F2630 /* NFCSettingsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51AFD4D32716FC78008F2630 /* NFCSettingsController.swift */; }; 51AFD4D62716FCDB008F2630 /* ApplicationSettingsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51AFD4D52716FCDB008F2630 /* ApplicationSettingsViewModel.swift */; }; 51AFD4D827196AB6008F2630 /* VersionHistory.plist in Resources */ = {isa = PBXBuildFile; fileRef = 51AFD4D727196AB6008F2630 /* VersionHistory.plist */; }; 51AFD4DA271D4278008F2630 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 51AFD4D9271D4277008F2630 /* QuartzCore.framework */; }; @@ -69,8 +67,6 @@ A525965B23A45501006AA3C0 /* UIImageAdditions.swift in Sources */ = {isa = PBXBuildFile; fileRef = A525965A23A45501006AA3C0 /* UIImageAdditions.swift */; }; A544948E23CE546B003E1E07 /* TutorialViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A544948B23CE546B003E1E07 /* TutorialViewController.swift */; }; A544948F23CE546B003E1E07 /* TutorialPagesViewControllers.swift in Sources */ = {isa = PBXBuildFile; fileRef = A544948C23CE546B003E1E07 /* TutorialPagesViewControllers.swift */; }; - A544949023CE546B003E1E07 /* Tutorial.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A544948D23CE546B003E1E07 /* Tutorial.storyboard */; }; - A557BEE023AD97100097545D /* AddCredential.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A557BEDF23AD97100097545D /* AddCredential.storyboard */; }; A5588BF9239B0A7F003E4CA5 /* FavoritesStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5588BF8239B0A7F003E4CA5 /* FavoritesStorage.swift */; }; A591411D23830EB800CCCF67 /* UIApplicationExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A591411C23830EB800CCCF67 /* UIApplicationExtension.swift */; }; A591412123835F4600CCCF67 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = A591412023835F4600CCCF67 /* Constants.swift */; }; @@ -87,6 +83,7 @@ B452EC1F2A1E4F460045E5D9 /* YubiOtpRowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B452EC1E2A1E4F460045E5D9 /* YubiOtpRowView.swift */; }; B452EC3D2A264A620045E5D9 /* ToastView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B452EC3C2A264A620045E5D9 /* ToastView.swift */; }; B452EC442A2A06940045E5D9 /* ToastPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = B452EC432A2A06940045E5D9 /* ToastPresenter.swift */; }; + B45E0DA02C0768E0006FE88C /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = B45E0D9E2C0768E0006FE88C /* InfoPlist.strings */; }; B46E378729C348F100CA0B67 /* EditAccountWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = B46E378629C348F100CA0B67 /* EditAccountWrapper.swift */; }; B4712B7028DDB5F6009B270D /* AccessKeyCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4712B6F28DDB5F6009B270D /* AccessKeyCache.swift */; }; B4719B17298AA6E7006CDAEA /* MainView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4719B16298AA6E7006CDAEA /* MainView.swift */; }; @@ -94,6 +91,12 @@ B4719B1B298AB641006CDAEA /* MainViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4719B1A298AB641006CDAEA /* MainViewModel.swift */; }; B4719B2C29914051006CDAEA /* AccountRowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4719B2B29914051006CDAEA /* AccountRowView.swift */; }; B4719B322993EFEE006CDAEA /* AccountDetailsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4719B312993EFEE006CDAEA /* AccountDetailsView.swift */; }; + B4901AE42BD697620092E7A2 /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = B4901AE32BD697620092E7A2 /* Localizable.xcstrings */; }; + B4901AE92BD7DCC70092E7A2 /* Tutorial.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B4901AE82BD7DCC70092E7A2 /* Tutorial.storyboard */; }; + B4901AED2BD7DD160092E7A2 /* AddCredential.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B4901AEC2BD7DD160092E7A2 /* AddCredential.storyboard */; }; + B4901AF12BD7DD350092E7A2 /* EditCredential.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B4901AF02BD7DD350092E7A2 /* EditCredential.storyboard */; }; + B4901AF42BD7DF960092E7A2 /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = B4901AF32BD7DF960092E7A2 /* Localizable.xcstrings */; }; + B4901B082BD91DA60092E7A2 /* InfoPlist.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = B4901B072BD91DA60092E7A2 /* InfoPlist.xcstrings */; }; B4B1711827DF8C48002A62DE /* ScanAccountView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4B1711727DF8C48002A62DE /* ScanAccountView.swift */; }; B4C93E60299D156C00C2A8B8 /* ErrorAlertView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4C93E5F299D156C00C2A8B8 /* ErrorAlertView.swift */; }; B4C93E63299FB51A00C2A8B8 /* Account.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4C93E62299FB51A00C2A8B8 /* Account.swift */; }; @@ -149,7 +152,6 @@ 513D4DF42660EBA40022C53D /* ConfigurationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfigurationController.swift; sourceTree = ""; }; 513D4DF6266634280022C53D /* ShowTime.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShowTime.swift; sourceTree = ""; }; 513D4DF8266A21250022C53D /* DelegateStack.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DelegateStack.swift; sourceTree = ""; }; - 513F34BD24633A7900FCE030 /* EditCredential.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = EditCredential.storyboard; sourceTree = ""; }; 513F34BF2463F0C900FCE030 /* EditFieldController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditFieldController.swift; sourceTree = ""; }; 513F34C12463F44300FCE030 /* EditCredentialController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditCredentialController.swift; sourceTree = ""; }; 513F34C72464658F00FCE030 /* SettingsRowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsRowView.swift; sourceTree = ""; }; @@ -213,8 +215,6 @@ A525965A23A45501006AA3C0 /* UIImageAdditions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIImageAdditions.swift; sourceTree = ""; }; A544948B23CE546B003E1E07 /* TutorialViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TutorialViewController.swift; sourceTree = ""; }; A544948C23CE546B003E1E07 /* TutorialPagesViewControllers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TutorialPagesViewControllers.swift; sourceTree = ""; }; - A544948D23CE546B003E1E07 /* Tutorial.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Tutorial.storyboard; sourceTree = ""; }; - A557BEDF23AD97100097545D /* AddCredential.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = AddCredential.storyboard; sourceTree = ""; }; A5588BF8239B0A7F003E4CA5 /* FavoritesStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FavoritesStorage.swift; sourceTree = ""; }; A591411C23830EB800CCCF67 /* UIApplicationExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIApplicationExtension.swift; sourceTree = ""; }; A591412023835F4600CCCF67 /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = ""; }; @@ -230,6 +230,8 @@ B452EC1E2A1E4F460045E5D9 /* YubiOtpRowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YubiOtpRowView.swift; sourceTree = ""; }; B452EC3C2A264A620045E5D9 /* ToastView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToastView.swift; sourceTree = ""; }; B452EC432A2A06940045E5D9 /* ToastPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToastPresenter.swift; sourceTree = ""; }; + B45A980D2C2AE3D800AAAD78 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/InfoPlist.strings; sourceTree = ""; }; + B45E0D9F2C0768E0006FE88C /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/InfoPlist.strings; sourceTree = ""; }; B46E378629C348F100CA0B67 /* EditAccountWrapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditAccountWrapper.swift; sourceTree = ""; }; B4712B6F28DDB5F6009B270D /* AccessKeyCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccessKeyCache.swift; sourceTree = ""; }; B4719B16298AA6E7006CDAEA /* MainView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainView.swift; sourceTree = ""; }; @@ -237,6 +239,19 @@ B4719B1A298AB641006CDAEA /* MainViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainViewModel.swift; sourceTree = ""; }; B4719B2B29914051006CDAEA /* AccountRowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountRowView.swift; sourceTree = ""; }; B4719B312993EFEE006CDAEA /* AccountDetailsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountDetailsView.swift; sourceTree = ""; }; + B4901AE12BD696BE0092E7A2 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Main.strings; sourceTree = ""; }; + B4901AE22BD696BE0092E7A2 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/LaunchScreen.strings; sourceTree = ""; }; + B4901AE32BD697620092E7A2 /* Localizable.xcstrings */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; name = Localizable.xcstrings; path = Authenticator/Localizable.xcstrings; sourceTree = SOURCE_ROOT; }; + B4901AE52BD69A2B0092E7A2 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/Main.strings; sourceTree = ""; }; + B4901AE62BD69A2B0092E7A2 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/LaunchScreen.strings; sourceTree = ""; }; + B4901AE72BD7DCC70092E7A2 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Tutorial.storyboard; sourceTree = ""; }; + B4901AEA2BD7DCC70092E7A2 /* mul */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; name = mul; path = mul.lproj/Tutorial.xcstrings; sourceTree = ""; }; + B4901AEB2BD7DD160092E7A2 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/AddCredential.storyboard; sourceTree = ""; }; + B4901AEE2BD7DD160092E7A2 /* mul */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; name = mul; path = mul.lproj/AddCredential.xcstrings; sourceTree = ""; }; + B4901AEF2BD7DD350092E7A2 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/EditCredential.storyboard; sourceTree = ""; }; + B4901AF22BD7DD350092E7A2 /* mul */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; name = mul; path = mul.lproj/EditCredential.xcstrings; sourceTree = ""; }; + B4901AF32BD7DF960092E7A2 /* Localizable.xcstrings */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; path = Localizable.xcstrings; sourceTree = ""; }; + B4901B072BD91DA60092E7A2 /* InfoPlist.xcstrings */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; path = InfoPlist.xcstrings; sourceTree = ""; }; B4B1711727DF8C48002A62DE /* ScanAccountView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScanAccountView.swift; sourceTree = ""; }; B4C93E5F299D156C00C2A8B8 /* ErrorAlertView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorAlertView.swift; sourceTree = ""; }; B4C93E62299FB51A00C2A8B8 /* Account.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Account.swift; sourceTree = ""; }; @@ -321,7 +336,7 @@ 513F34C12463F44300FCE030 /* EditCredentialController.swift */, 513F34C72464658F00FCE030 /* SettingsRowView.swift */, 513F34BF2463F0C900FCE030 /* EditFieldController.swift */, - 513F34BD24633A7900FCE030 /* EditCredential.storyboard */, + B4901AF02BD7DD350092E7A2 /* EditCredential.storyboard */, ); path = EditCredential; sourceTree = ""; @@ -345,7 +360,9 @@ 515542762656707000B19C59 /* TokenDriver.swift */, 515542782656707000B19C59 /* TokenSession.swift */, 5155427A2656707000B19C59 /* Info.plist */, + B45E0D9E2C0768E0006FE88C /* InfoPlist.strings */, 5156D05A265D0538007A94F8 /* TKTokenAlgorithm+Extensions.swift */, + B4901AF32BD7DF960092E7A2 /* Localizable.xcstrings */, ); path = TokenExtension; sourceTree = ""; @@ -431,10 +448,12 @@ 818BE8DB22F3486500061026 /* Model */, 818BE8DA22F3485600061026 /* UI */, 818866F622E7A877006BC0A8 /* Authenticator.entitlements */, + B4901AE32BD697620092E7A2 /* Localizable.xcstrings */, 818866F122E18804006BC0A8 /* Authenticator-Bridging-Header.h */, B4719B18298AA757006CDAEA /* AuthenticatorApp.swift */, 818866BF22DFD72C006BC0A8 /* Assets.xcassets */, 818866C422DFD72C006BC0A8 /* Info.plist */, + B4901B072BD91DA60092E7A2 /* InfoPlist.xcstrings */, 51AFD4D727196AB6008F2630 /* VersionHistory.plist */, B40327752847AE0A00DF4DB0 /* Licensing.md */, ); @@ -513,7 +532,7 @@ 513D4DF12660D6570022C53D /* AddCredentialController.swift */, B4B1711727DF8C48002A62DE /* ScanAccountView.swift */, 81FA3C33231AF2D8009C22AB /* AdvancedSettingsViewController.swift */, - A557BEDF23AD97100097545D /* AddCredential.storyboard */, + B4901AEC2BD7DD160092E7A2 /* AddCredential.storyboard */, ); path = AddCredential; sourceTree = ""; @@ -535,7 +554,7 @@ children = ( A544948B23CE546B003E1E07 /* TutorialViewController.swift */, A544948C23CE546B003E1E07 /* TutorialPagesViewControllers.swift */, - A544948D23CE546B003E1E07 /* Tutorial.storyboard */, + B4901AE82BD7DCC70092E7A2 /* Tutorial.storyboard */, ); path = Tutorial; sourceTree = ""; @@ -642,6 +661,8 @@ knownRegions = ( en, Base, + fr, + ja, ); mainGroup = 818866AA22DFD729006BC0A8; packageReferences = ( @@ -663,6 +684,8 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + B4901AF42BD7DF960092E7A2 /* Localizable.xcstrings in Resources */, + B45E0DA02C0768E0006FE88C /* InfoPlist.strings in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -672,10 +695,12 @@ files = ( 818866C322DFD72C006BC0A8 /* LaunchScreen.storyboard in Resources */, 51AFD4D827196AB6008F2630 /* VersionHistory.plist in Resources */, - 513F34BE24633A7900FCE030 /* EditCredential.storyboard in Resources */, - A557BEE023AD97100097545D /* AddCredential.storyboard in Resources */, + B4901AF12BD7DD350092E7A2 /* EditCredential.storyboard in Resources */, + B4901AED2BD7DD160092E7A2 /* AddCredential.storyboard in Resources */, 818866C022DFD72C006BC0A8 /* Assets.xcassets in Resources */, - A544949023CE546B003E1E07 /* Tutorial.storyboard in Resources */, + B4901AE92BD7DCC70092E7A2 /* Tutorial.storyboard in Resources */, + B4901B082BD91DA60092E7A2 /* InfoPlist.xcstrings in Resources */, + B4901AE42BD697620092E7A2 /* Localizable.xcstrings in Resources */, 818866BE22DFD729006BC0A8 /* Main.storyboard in Resources */, B40327762847AE0A00DF4DB0 /* Licensing.md in Resources */, ); @@ -757,9 +782,7 @@ 5155428326569ADD00B19C59 /* UIControl+Extensions.swift in Sources */, B452EC1F2A1E4F460045E5D9 /* YubiOtpRowView.swift in Sources */, A544948F23CE546B003E1E07 /* TutorialPagesViewControllers.swift in Sources */, - 51AFD4D42716FC78008F2630 /* NFCSettingsController.swift in Sources */, B4719B19298AA757006CDAEA /* AuthenticatorApp.swift in Sources */, - 51AFD4D42716FC78008F2630 /* NFCSettingsController.swift in Sources */, 51394C5C26D4D460009F366D /* MenuGestureRecognizer.swift in Sources */, A5588BF9239B0A7F003E4CA5 /* FavoritesStorage.swift in Sources */, B4B1711827DF8C48002A62DE /* ScanAccountView.swift in Sources */, @@ -820,6 +843,8 @@ isa = PBXVariantGroup; children = ( 818866BD22DFD729006BC0A8 /* Base */, + B4901AE12BD696BE0092E7A2 /* fr */, + B4901AE52BD69A2B0092E7A2 /* ja */, ); name = Main.storyboard; sourceTree = ""; @@ -828,10 +853,48 @@ isa = PBXVariantGroup; children = ( 818866C222DFD72C006BC0A8 /* Base */, + B4901AE22BD696BE0092E7A2 /* fr */, + B4901AE62BD69A2B0092E7A2 /* ja */, ); name = LaunchScreen.storyboard; sourceTree = ""; }; + B45E0D9E2C0768E0006FE88C /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + B45E0D9F2C0768E0006FE88C /* ja */, + B45A980D2C2AE3D800AAAD78 /* fr */, + ); + name = InfoPlist.strings; + sourceTree = ""; + }; + B4901AE82BD7DCC70092E7A2 /* Tutorial.storyboard */ = { + isa = PBXVariantGroup; + children = ( + B4901AE72BD7DCC70092E7A2 /* Base */, + B4901AEA2BD7DCC70092E7A2 /* mul */, + ); + name = Tutorial.storyboard; + sourceTree = ""; + }; + B4901AEC2BD7DD160092E7A2 /* AddCredential.storyboard */ = { + isa = PBXVariantGroup; + children = ( + B4901AEB2BD7DD160092E7A2 /* Base */, + B4901AEE2BD7DD160092E7A2 /* mul */, + ); + name = AddCredential.storyboard; + sourceTree = ""; + }; + B4901AF02BD7DD350092E7A2 /* EditCredential.storyboard */ = { + isa = PBXVariantGroup; + children = ( + B4901AEF2BD7DD350092E7A2 /* Base */, + B4901AF22BD7DD350092E7A2 /* mul */, + ); + name = EditCredential.storyboard; + sourceTree = ""; + }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ @@ -843,7 +906,7 @@ CURRENT_PROJECT_VERSION = 115; DEVELOPMENT_TEAM = LQA3CS5MM7; INFOPLIST_FILE = TokenExtension/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 14.5; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -853,6 +916,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.yubico.Authenticator.TokenExtension; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; + SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; @@ -866,7 +930,7 @@ CURRENT_PROJECT_VERSION = 115; DEVELOPMENT_TEAM = LQA3CS5MM7; INFOPLIST_FILE = TokenExtension/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 14.5; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -876,6 +940,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.yubico.Authenticator.TokenExtension; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; + SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; @@ -885,6 +950,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; @@ -947,6 +1013,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; @@ -1006,7 +1073,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_ENTITLEMENTS = Authenticator/Authenticator.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 126; + CURRENT_PROJECT_VERSION = 129; DEVELOPMENT_TEAM = LQA3CS5MM7; HEADER_SEARCH_PATHS = "../Submodules/YubiKit/**"; INFOPLIST_FILE = Authenticator/Info.plist; @@ -1016,11 +1083,12 @@ "@executable_path/Frameworks", ); LIBRARY_SEARCH_PATHS = ""; - MARKETING_VERSION = 1.7.9; + MARKETING_VERSION = 1.7.10; OTHER_LDFLAGS = "-ObjC"; PRODUCT_BUNDLE_IDENTIFIER = com.yubico.Authenticator; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTS_MACCATALYST = NO; + SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_OBJC_BRIDGING_HEADER = "Authenticator/Authenticator-Bridging-Header.h"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; @@ -1034,7 +1102,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_ENTITLEMENTS = Authenticator/Authenticator.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 126; + CURRENT_PROJECT_VERSION = 129; DEVELOPMENT_TEAM = LQA3CS5MM7; HEADER_SEARCH_PATHS = "../Submodules/YubiKit/**"; INFOPLIST_FILE = Authenticator/Info.plist; @@ -1044,11 +1112,12 @@ "@executable_path/Frameworks", ); LIBRARY_SEARCH_PATHS = ""; - MARKETING_VERSION = 1.7.9; + MARKETING_VERSION = 1.7.10; OTHER_LDFLAGS = "-ObjC"; PRODUCT_BUNDLE_IDENTIFIER = com.yubico.Authenticator; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTS_MACCATALYST = NO; + SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_OBJC_BRIDGING_HEADER = "Authenticator/Authenticator-Bridging-Header.h"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; diff --git a/Authenticator/AuthenticatorApp.swift b/Authenticator/AuthenticatorApp.swift index 1b069350..c648e2f2 100644 --- a/Authenticator/AuthenticatorApp.swift +++ b/Authenticator/AuthenticatorApp.swift @@ -15,6 +15,7 @@ */ import SwiftUI +import YubiKit @main struct AuthenticatorApp: App { @@ -38,6 +39,10 @@ struct AuthenticatorApp: App { .navigationViewStyle(.stack) .environmentObject(toastPresenter) .environmentObject(notificationsViewModel) + .onAppear { + YubiKitExternalLocalization.nfcScanAlertMessage = String(localized: "Scan your YubiKey", comment: "iOS NFC alert scan") + YubiKitExternalLocalization.nfcScanSuccessAlertMessage = String(localized: "Success", comment: "iOS NFC alert default success message") + } } } } diff --git a/Authenticator/InfoPlist.xcstrings b/Authenticator/InfoPlist.xcstrings new file mode 100644 index 00000000..6e478714 --- /dev/null +++ b/Authenticator/InfoPlist.xcstrings @@ -0,0 +1,102 @@ +{ + "sourceLanguage" : "en", + "strings" : { + "CFBundleName" : { + "comment" : "Bundle name", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Authenticator" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Authenticator" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "Authenticator" + } + } + } + }, + "NFCReaderUsageDescription" : { + "comment" : "Privacy - NFC Scan Usage Description", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "The application needs access to NFC reading to communicate with your Yubikey." + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "L'appli doit accéder à la lecture NFC pour communiquer avec votre Yubikey." + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "Yubikeyと通信するには、アプリケーションがNFC読み取りにアクセスできる必要があります." + } + } + } + }, + "NSCameraUsageDescription" : { + "comment" : "Privacy - Camera Usage Description", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "The application needs access to Camera to scan QR codes." + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "L'appli doit accéder à l'appareil photo pour scanner les codes QR." + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "QRコードをスキャンするには、アプリケーションがカメラにアクセスできる必要があります." + } + } + } + }, + "NSFaceIDUsageDescription" : { + "comment" : "Privacy - Face ID Usage Description", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "The application needs access to Face ID to unlock your password vault." + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "L'appli doit accéder à Face ID pour débloquer votre coffre-fort de mots de passe." + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "パスワードボールトのロックを解除するには、アプリケーションがFace IDにアクセスできる必要があります." + } + } + } + } + }, + "version" : "1.0" +} \ No newline at end of file diff --git a/Authenticator/Localizable.xcstrings b/Authenticator/Localizable.xcstrings new file mode 100644 index 00000000..9cd286a9 --- /dev/null +++ b/Authenticator/Localizable.xcstrings @@ -0,0 +1,2661 @@ +{ + "sourceLanguage" : "en", + "strings" : { + " in this version" : { + "comment" : "Substring in \"See what's new in this version\"", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : " dans cette version" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : " このバージョンの" + } + } + } + }, + "*** *** " : { + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "*** *** " + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "*** *** " + } + } + } + }, + "888 888" : { + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "888 888" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "888 888" + } + } + } + }, + "About" : { + "comment" : "About view navigation title", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Infos" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "概要" + } + } + } + }, + "Account deleted" : { + "comment" : "OATH NFC account deleted", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Compte supprimé" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "アカウントが削除されました" + } + } + } + }, + "Account name can not be empty" : { + "comment" : "Rename credential alert", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Le nom du compte ne peut pas être vide" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "アカウント名は空白にできません" + } + } + } + }, + "Account not set" : { + "comment" : "Rename credential alert", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Compte non créé" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "アカウントが設定されていません" + } + } + } + }, + "Account renamed" : { + "comment" : "OATH NFC account renamed", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Compte renommé" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "アカウントの名前が変更されました" + } + } + } + }, + "Accounts" : { + "comment" : "Navigation title in main view.", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Comptes" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "アカウント" + } + } + } + }, + "Activate NFC" : { + "comment" : "Password save type activate NFC", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Activer NFC" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "NFCを有効化" + } + } + } + }, + "Add account" : { + "comment" : "Scan QR code add account label", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ajouter compte" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "アカウントを追加" + } + } + } + }, + "Add Credential" : { + "comment" : "Add account navigation title", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ajouter infos d'identification" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "資格情報を追加" + } + } + } + }, + "Algorithm" : { + "comment" : "Add account select algorithm", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Algorithme" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "アルゴリズム" + } + } + } + }, + "and can be used by other applications" : { + "comment" : "PIV extension substring in 'These certificates have been added to this [iPad/iPhone] and can be used by other applications'", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "et peut être utilisé par d'autres applications" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "他のアプリケーションで使用できます" + } + } + } + }, + "Authentication required" : { + "comment" : "Password Configuration auth required", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Authentification requise" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "認証が必要です" + } + } + } + }, + "Calculate" : { + "comment" : "Menu", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Calculer" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "計算" + } + } + } + }, + "Cancel" : { + "comment" : "Password alert", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Annuler" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "キャンセル" + } + } + } + }, + "Certificates on this YubiKey can be used to authenticate and sign requests from other applications if added to this" : { + "comment" : "PIV extension no certs on yubikey message", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Les certificats sur cette YubiKey peuvent être utilisés pour authentifier et signer des requêtes provenant d'autres applications s'ils sont ajoutés à celle-ci" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "このYubiKeyの証明書を使用して、他のアプリケーションからのリクエストが追加された場合に認証して署名することができます" + } + } + } + }, + "Certificates on YubiKey" : { + "comment" : "PIV extension table cell header", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Certificats sur YubiKey" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "YubiKeyの証明書" + } + } + } + }, + "Clear" : { + "comment" : "Clear password alert button", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Effacer" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "消去" + } + } + } + }, + "Clear passwords saved on" : { + "comment" : "Substring from 'Clear passwords saved on [iPad/iPhone]. This will prompt for a passowrd next time a password protected YubiKey is used.'.", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Effacez les mots de passe enregistrés sur" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "に保存されているパスワードを消去します" + } + } + } + }, + "Clear passwords saved on iPhone. This will prompt for a password next time a password protected YubiKey is used." : { + "comment" : "Clear password alert message", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Effacez les mots de passe enregistrés sur l'iPhone. Un mot de passe sera requis à la prochaine utilisation d'une YubiKey protégée par mot de passe." + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "iPhoneに保存されているパスワードを消去します。これにより、パスワードで保護されたYubiKeyの次回使用時にパスワードの入力を求められます." + } + } + } + }, + "Clear passwords?" : { + "comment" : "Clear password alert title", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Effacer les mots de passe ?" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "パスワードを消去しますか?" + } + } + } + }, + "Close" : { + "comment" : "View close button", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Fermer" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "閉じる" + } + } + } + }, + "Code calculated" : { + "comment" : "OATH NFC code calculated", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Code calculé" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "コードが計算されました" + } + } + } + }, + "Code expired" : { + "comment" : "Accessibility label", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Code expiré" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "コードが期限切れです" + } + } + } + }, + "Code not calculated" : { + "comment" : "Accessibility label", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Code non calculé" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "コードが計算されていません" + } + } + } + }, + "Configuration" : { + "comment" : "Configuration navigation title", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Configuration" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "設定" + } + } + } + }, + "Continue with limited usability" : { + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Continuer avec fonctionnalité limitée" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "使用制限ありで続行" + } + } + } + }, + "Copied to clipboard" : { + "comment" : "Toast copied to clipboard message", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Copié dans presse-papiers" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "クリップボードにコピーされました" + } + } + } + }, + "Copy" : { + "comment" : "Menu", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Copier" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "コピー" + } + } + } + }, + "Data to String conversion error" : { + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Erreur de conversion de données en chaîne" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "データから文字列への変換エラー" + } + } + } + }, + "Delete" : { + "comment" : "Menu", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Effacer" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "削除" + } + } + } + }, + "Delete account?" : { + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Effacer compte?" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "アカウントを削除しますか??" + } + } + } + }, + "Digits" : { + "comment" : "Add account select number of digits", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Chiffres" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "桁" + } + } + } + }, + "Disable Yubico OTP (recommended)" : { + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Désactiver Yubico OTP (recommandé)" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "Yubico OTPを無効にする(推奨)" + } + } + } + }, + "Disabling Yubico OTP will prevent the YubiKey from appearing as a keyboard. If you don’t use Yubico OTP this is the recommended solution. This can be re-enabled from the settings page." : { + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Désactiver Yubico OTP empêchera l'affichage de la YubiKey comme clavier. Si vous n'utilisez pas Yubico, c'est la solution recommandée. Cette fonction peut être réactivée via la page des paramètres." + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "Yubico OTPを無効にすると、YubiKeyがキーボードとして表示されなくなります。Yubico OTPを使用しない場合は、これが推奨される解決策です。Yubico OTPは、設定ページから再度有効にできます." + } + } + } + }, + "Dismiss details view" : { + "comment" : "Accessibility hint", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Fermer la vue détaillée" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "詳細ビューを閉じる" + } + } + } + }, + "Duplicate accounts!" : { + "comment" : "OATH add credential duplicate accounts error", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Comptes en double !" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "アカウントが重複しています" + } + } + } + }, + "Enabled" : { + "comment" : "PIV extension enabled message", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Activé" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "有効" + } + } + } + }, + "Enter manually" : { + "comment" : "Scan QR code add manually button", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Saisir manuellement" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "手動で入力" + } + } + } + }, + "Enter password" : { + "comment" : "Password alert", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Saisir le mot de passe" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "パスワードを入力" + } + } + } + }, + "Enter the PIN to access the certificate." : { + "comment" : "PIV extension enter PIN message", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Saisir le code PIN pour accéder au certificat." + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "証明書にアクセスするにはPINを入力してください。" + } + } + } + }, + "Error" : { + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Erreur" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "エラー" + } + } + } + }, + "Error reading YubiKey" : { + "comment" : "PIV extension error title", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Erreur lors de la lecture de la YubiKey" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "YubiKey読み取りエラー" + } + } + } + }, + "Error writing configuration" : { + "comment" : "OTP settings error alert title", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Erreur lors de l'écriture de la configuration" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "設定書き込みエラー" + } + } + } + }, + "Failed storing certificate" : { + "comment" : "PIV extension storing error alert title", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Échec du stockage du certificat" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "証明書の保存に失敗しました" + } + } + } + }, + "Failed to cast object to Data error" : { + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Impossible de convertir l'objet en données" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "データへのオブジェクトのキャスト失敗エラー" + } + } + } + }, + "Failed to clear passwords" : { + "comment" : "Clear passwords failure alert title", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Impossible d'effacer le mot de passe" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "パスワードの消去に失敗しました" + } + } + } + }, + "Failed to reset YubiKey" : { + "comment" : "Reset YubiKey failure alert title", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Échec de la réinitialisation de la YubiKey" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "YubiKeyのリセットに失敗しました" + } + } + } + }, + "Finished reading certificates" : { + "comment" : "PIV extension NFC finished reading certs", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Lecture des certificats terminée" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "証明書の読み取りが終了しました" + } + } + } + }, + "Incorrect password. Re-enter password." : { + "comment" : "OATH password entry retry", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Mot de passe incorrect. Saisissez à nouveau le mot de passe." + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "パスワードが正しくありません。パスワードを再入力してください。" + } + } + } + }, + "Insert YubiKey" : { + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Insérez YubiKey" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "YubiKeyを挿入" + } + } + } + }, + "Insert YubiKey or pull down to activate NFC" : { + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Insérez la YubiKey ou tirez vers le bas pour activer NFC" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "YubiKeyを挿入してください。またはプルダウンしてNFCを有効にしてください" + } + } + } + }, + "Invalid signature" : { + "comment" : "PIV extension NFC invalid signature", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Signature non valide" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "無効な署名" + } + } + } + }, + "Invalid URI format" : { + "comment" : "Invalid Uri, wrong parameters", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Format URI non valide" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "無効なURIフォーマット" + } + } + } + }, + "Item not found in secure storage" : { + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Élément introuvable dans le stockage sécurisé" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "アイテムが安全なストレージで見つかりません" + } + } + } + }, + "Key is password protected" : { + "comment" : "OATH NFC password protected key", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "La clé est protégée par mot de passe" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "キーはパスワードで保護されています" + } + } + } + }, + "Licensing" : { + "comment" : "Licensing view navigation title", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Licences" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "ライセンス" + } + } + } + }, + "Menu" : { + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Menu" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "メニュー" + } + } + } + }, + "Never for this YubiKey" : { + "comment" : "Save password alert.", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Jamais pour cette YubiKey" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "このYubiKeyには使用しないでください" + } + } + } + }, + "New OTP configuration saved" : { + "comment" : "Settings OTP configuration saved", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nouvelle configuration OTP enregistrée" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "新しいOTP設定が保存されました" + } + } + } + }, + "No account information found!" : { + "comment" : "Scan QR code no account error message", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Aucune information de compte trouvée !" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "アカウント情報が見つかりません" + } + } + } + }, + "No accounts on YubiKey" : { + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Aucun compte sur YubiKey" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "YubiKeyにアカウントがありません" + } + } + } + }, + "No camera permissions" : { + "comment" : "Scan QR code camera error title", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Aucune autorisation de caméra" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "カメラの権限がありません" + } + } + } + }, + "No certificates on YubiKey" : { + "comment" : "PIV extension no certificates message", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Aucun certificat sur YubiKey" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "YubiKeyに証明書がありません" + } + } + } + }, + "No matching accounts on YubiKey" : { + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Aucun compte correspondant sur YubiKey" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "YubiKeyに一致するアカウントがありません" + } + } + } + }, + "No name" : { + "comment" : "PIV extension certificate with no name", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Aucun nom" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "名前がありません" + } + } + } + }, + "No public key certificates in keychain" : { + "comment" : "PIV extension no certs in keychain", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Aucun certificat de clé publique dans le porte-clés" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "キーチェーンに公開鍵の証明書がありません" + } + } + } + }, + "No QR code?" : { + "comment" : "Scan QR code no QR code message", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pas de code QR ?" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "QRコードがありませんか?" + } + } + } + }, + "Not Enabled" : { + "comment" : "PIV extension not enabled message", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Non activé" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "有効化されていません" + } + } + } + }, + "Not now" : { + "comment" : "Save passsword alert", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pas maintenant" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "今はできません" + } + } + } + }, + "Not valid credential information" : { + "comment" : "Add account error message", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Informations d'identification non valides" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "有効な資格情報ではありません" + } + } + } + }, + "Notifications disabled" : { + "comment" : "PIV extension notifications alert title", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Notifications désactivées" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "通知が無効になっています" + } + } + } + }, + "OATH accounts deleted and OATH application reset to factory defaults." : { + "comment" : "OATH reset confirmation message", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Comptes OATH supprimés et application OATH réinitialisée aux paramètres par défaut." + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "OATHアカウントが削除され、OATHアプリケーションが工場出荷時のデフォルトにリセットされています。" + } + } + } + }, + "Ok" : { + "comment" : "Password alert", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "OK" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "OK" + } + } + } + }, + "OK" : { + "comment" : "OK button in error alert.", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "OK" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "OK" + } + } + } + }, + "on this YubiKey" : { + "comment" : "OATH substring in 'There's already an account named [issuer, name] on this YubiKey.", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "sur cette YubiKey" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "このYubiKeyで" + } + } + } + }, + "Open iOS Settings app" : { + "comment" : "Scan QR code settings button", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ouvrez l'application Réglages iOS" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "iOS設定アプリを開く" + } + } + } + }, + "or pull down to activate NFC" : { + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "ou tirez vers le bas pour activer NFC" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "またはプルダウンしてNFCを有効にします" + } + } + } + }, + "or scan a NFC YubiKey" : { + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "ou scannez une YubiKey NFC" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "またはNFC YubiKeyをスキャンします" + } + } + } + }, + "Other" : { + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Autre" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "その他" + } + } + } + }, + "Other applications can use client certificates on your YubiKey for authentication and signing purposes." : { + "comment" : "PIV extension info alert message", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "D'autres applications peuvent utiliser les certificats clients de votre YubiKey à des fins d'authentification et de signature." + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "他のアプリケーションが認証および署名の目的でYubiKeyのクライアント証明書を使用できます。" + } + } + } + }, + "Password" : { + "comment" : "Password alert", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Mot de passe" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "パスワード" + } + } + } + }, + "Password can not be an empty string" : { + "comment" : "Configuration set password empty password error alert message", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Le mot de passe ne peut pas être une chaîne vide" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "パスワードの文字列は空白にできません" + } + } + } + }, + "Password has been changed" : { + "comment" : "Password Configuration password changed", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Le mot de passe a été modifié" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "パスワードが変更されました" + } + } + } + }, + "Password has been removed" : { + "comment" : "Password Configuration password removed", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Le mot de passe a été supprimé" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "パスワードが削除されました" + } + } + } + }, + "Password has been set" : { + "comment" : "Password Configuration password set", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Le mot de passe a été créé" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "パスワードが設定されました" + } + } + } + }, + "Period" : { + "comment" : "Add account select period", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Période" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "期間" + } + } + } + }, + "Pin" : { + "comment" : "Menu", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Épingler" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "ピン" + } + } + } + }, + "Pinned" : { + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Épinglé" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "ピン留め" + } + } + } + }, + "Plug-in your YubiKey for that operation" : { + "comment" : "No service found", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Branchez votre YubiKey pour cette opération" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "YubiKeyをその操作のために接続してください" + } + } + } + }, + "Point your camera at a QR code to scan it" : { + "comment" : "Scan QR code message", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pointez votre caméra vers le code QR pour le scanner" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "スキャンするにはカメラをQRコードに向けてください" + } + } + } + }, + "Public key certificates on" : { + "comment" : "PIV extension no certs on device message", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Certificats de clé publique activés" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "公開鍵証明書の対象" + } + } + } + }, + "Read more..." : { + "comment" : "PIV extension read more alert title", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "En savoir plus..." + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "詳細を読む..." + } + } + } + }, + "Read YubiKey OTP configuration" : { + "comment" : "Settings OTP configuration read", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Lire la configuration OTP de la YubiKey" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "YubiKey OTP設定を読み取る" + } + } + } + }, + "Remove and re-insert your YubiKey" : { + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Retirez et réinsérez votre YubiKey" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "YubiKeyを取り外して再挿入してください" + } + } + } + }, + "Remove and reinsert your YubiKey" : { + "comment" : "PIV extension error reinsert key", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Retirez et réinsérez votre YubiKey" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "YubiKeyを取り外して再挿入してください" + } + } + } + }, + "Remove password" : { + "comment" : "Remove password alert title", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Supprimer mot de passe" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "パスワードを削除" + } + } + } + }, + "Remove password for this YubiKey?" : { + "comment" : "Remove password alert message", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Supprimer le mot de passe pour cette YubiKey ?" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "このYubiKeyのパスワードを削除しますか?" + } + } + } + }, + "Rename" : { + "comment" : "Menu", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Renommer" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "名前変更" + } + } + } + }, + "Reset" : { + "comment" : "Reset YubiKey alert button", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Réinitialiser" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "リセット" + } + } + } + }, + "Reset complete" : { + "comment" : "Reset YubiKey complete alert title", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Réinitialisation terminée" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "リセットが完了しました" + } + } + } + }, + "Reset YubiKey?" : { + "comment" : "Reset YubiKey alert title", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Réinitialiser la YubiKey ?" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "YubiKeyをリセットしますか?" + } + } + } + }, + "Save and protect with" : { + "comment" : "Password entry save substring in 'Save and protect with [save type]'", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Enregistrer et protéger avec" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "を使用して保存および保護" + } + } + } + }, + "Save and protect with %@" : { + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Enregistrer et protéger avec %@" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "%@を使用して保存および保護" + } + } + } + }, + "Save password" : { + "comment" : "Save password alert.", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Enregistrer mot de passe" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "パスワードを保存" + } + } + } + }, + "Save Password" : { + "comment" : "Password entry save password button", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Enregistrer mot de passe" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "パスワードを保存" + } + } + } + }, + "Save password?" : { + "comment" : "Save password alert", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Enregistrer mot de passe ?" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "パスワードを保存しますか?" + } + } + } + }, + "Scan NFC YubiKey" : { + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Scanner la YubiKey NFC" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "NFC YubiKeyをスキャン" + } + } + } + }, + "Scan your YubiKey" : { + "comment" : "iOS NFC alert scan", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Scannez votre YubiKey" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "YubiKeyをスキャン" + } + } + } + }, + "Search" : { + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Rechercher" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "検索" + } + } + } + }, + "See " : { + "comment" : "Substring in \"See what's new in this version\"", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Voir " + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "参照 " + } + } + } + }, + "Settings" : { + "comment" : "PIV extension settings alert title", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Réglages" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "設定" + } + } + } + }, + "Signing failed" : { + "comment" : "PIV extension signing failed error message", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Échec de la signature" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "署名に失敗しました" + } + } + } + }, + "Smart card extension" : { + "comment" : "PIV extension info alert title", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Extension carte à puce" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "スマートカード拡張機能" + } + } + } + }, + "Smart card extension is only available on iOS 14.5 and forward." : { + "comment" : "PIV extension version error", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "L'extension de carte à puce n'est disponible que sur iOS 14.5 et versions ultérieures." + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "スマートカード拡張機能は、iOS 14.5以降でのみ使用できます。" + } + } + } + }, + "Something went wrong" : { + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Une erreur s'est produite" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "問題が発生しました" + } + } + } + }, + "Something went wrong and key doesn't respond" : { + "comment" : "No response", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Erreur : la clé ne répond pas" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "問題が発生し、キーが応答しません" + } + } + } + }, + "Stored passwords have been cleared from this phone." : { + "comment" : "Clear passwords confirmation alert message", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Les mots de passe enregistrés ont été effacés de ce téléphone." + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "保存されたパスワードがこのスマートフォンから消去されました。" + } + } + } + }, + "String to Data conversion error" : { + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Erreur de conversion de chaîne en données" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "文字列からデータへの変換エラー" + } + } + } + }, + "Success" : { + "comment" : "Clear passwords confirmation alert title\niOS NFC alert default success message", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Succès" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "成功" + } + } + } + }, + "Success!\nHint: swipe down to dismiss" : { + "comment" : "iOS NFC alert success with hint", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Succès !\nAstuce : faites glisser vers le bas pour fermer" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "成功しました。\nヒント:下にスワイプして閉じます" + } + } + } + }, + "Successfully read" : { + "comment" : "iOS NFC alert successfully read", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Lecture effectuée" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "読み取りに成功しました" + } + } + } + }, + "Successfully signed data" : { + "comment" : "PIV extension NFC successfully signed data", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Données signées avec succès" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "データの署名に成功しました" + } + } + } + }, + "The key doesn't respond" : { + "comment" : "Timeout issue", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "La clé ne répond pas" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "キーが応答しません" + } + } + } + }, + "The passwords do not match" : { + "comment" : "Configuration set password not matching error alert message", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Les mots de passe ne correspondent pas" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "パスワードが一致しません" + } + } + } + }, + "The private key on the YubiKey does not match the certificate or there is no private key stored on the YubiKey." : { + "comment" : "PIV extension NFC invalid signature no private key", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "La clé privée sur la YubiKey ne correspond pas au certificat ou il n'y a pas de clé privée stockée sur la YubiKey." + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "YubiKeyの秘密鍵が証明書と一致しないか、YubiKeyに秘密鍵が保存されていません。" + } + } + } + }, + "The private key on the YubiKey does not match the certificate." : { + "comment" : "PIV extension invalid signature message", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "La clé privée sur la YubiKey ne correspond pas au certificat." + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "YubiKeyの秘密鍵が証明書と一致しません。" + } + } + } + }, + "The smart card extension requires notifications to be enabled for Yubico Authenticator. Enable it in the iOS Settings." : { + "comment" : "PIV extensions notifications alert message", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "L'extension de la carte à puce nécessite que les notifications soient activées pour Yubico Authenticator. Activez-les dans les paramètres iOS." + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "スマートカード拡張機能では、Yubico Authenticatorの通知を有効にする必要があります。iOS設定で有効にしてください。" + } + } + } + }, + "There's already an account named" : { + "comment" : "OATH substring in 'There's already an account named [issuer, name] on this YubiKey.", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Il existe déjà un compte portant le nom de" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "という名前のアカウントがすでに存在します" + } + } + } + }, + "These certificates have been added to this" : { + "comment" : "PIV extension substring in 'These certificates have been added to this [iPad/iPhone] and can be used by other applications'", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ces certificats ont été ajoutés à cette clé" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "これらの証明書はこれに追加されています" + } + } + } + }, + "This QR code is not supported" : { + "comment" : "Invalid Uri format, not OATH URL", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Code QR non pris en charge" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "このQRコードはサポートされていません" + } + } + } + }, + "This version of iOS does not support operations with the YubiKey for Lightning nor over NFC" : { + "comment" : "Not supported", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cette version d'iOS ne prend pas en charge les opérations avec YubiKey pour Lightning ni via NFC" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "このバージョンのiOSでは、LightningやNFCでのYubiKeyを使用した操作はサポートされていません" + } + } + } + }, + "This will delete all accounts and restore factory defaults of your YubiKey." : { + "comment" : "Reset YubiKey alert message", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cette action supprimera tous les comptes et restaurera les paramètres d'usine de votre YubiKey." + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "これにより、すべてのアカウントが削除され、YubiKeyの工場出荷時のデフォルトに戻ります。" + } + } + } + }, + "This will permanently delete the account from the YubiKey, and your ability to generate codes for it!" : { + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cela supprimera définitivement le compte de la YubiKey et vous ne pourrez plus générer de codes!" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "これにより、YubiKeyからアカウントが完全に削除され、コードを生成できなくなります!" + } + } + } + }, + "This will prompt for a password next time a password protected YubiKey is used" : { + "comment" : "Substring from 'Clear passwords saved on [iPad/iPhone]. This will prompt for a passowrd next time a password protected YubiKey is used.'.", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Un mot de passe sera requis à la prochaine utilisation d'une YubiKey protégée par mot de passe" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "これにより、パスワードで保護されたYubiKeyの次回使用時にパスワードの入力を求められます" + } + } + } + }, + "This YubiKey has Yubico OTP enabled which makes it appear as an external keyboard to the iPhone. Unfortunately this causes problem with the normal on-screen keyboard." : { + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Yubico OTP étant activé, cette YubiKey apparaît comme clavier externe pour l'iPhone. Cela pose problème avec le clavier à l'écran normal." + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "このYubiKeyはYubico OTPが有効になっているため、iPhoneへの外付けキーボードとして表示されます。これが原因で、標準のオンスクリーンキーボードで問題が発生します." + } + } + } + }, + "To prevent unauthorized access this YubiKey is protected with a password." : { + "comment" : "OATH password entry enter password", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pour empêcher tout accès non autorisé, cette YubiKey est protégée par un mot de passe." + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "不正アクセスを防止するため、このYubiKeyはパスワードで保護されます。" + } + } + } + }, + "To scan a QR code you need to enable camera permissions for the Authenticator app." : { + "comment" : "Scan QR code camera error message", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pour scanner un code QR, vous devez activer les autorisations de caméra pour l'application Authenticator." + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "QRコードをスキャンするには、Authenticatorアプリのカメラ権限を有効にする必要があります。" + } + } + } + }, + "Type" : { + "comment" : "Add account select type", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Type" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "タイプ" + } + } + } + }, + "Unhandled Error" : { + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Erreur non gérée" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "未処理エラー" + } + } + } + }, + "Unlock YubiKey" : { + "comment" : "Password entry unlock message", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Débloquer YubiKey" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "YubiKeyのロックを解除" + } + } + } + }, + "Unpin" : { + "comment" : "Menu", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Détacher" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "ピン解除" + } + } + } + }, + "Use your PUK code to reset PIN." : { + "comment" : "PIV extension pin blocked text", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Utilisez votre code PUK pour réinitialiser le code PIN." + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "PUKコードを使用してPINをリセットします。" + } + } + } + }, + "Version history" : { + "comment" : "Version history navigation title", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Historique des versions" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "バージョン履歴" + } + } + } + }, + "what's new" : { + "comment" : "Substring in \"See what's new in this version\"", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "nouveautés" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "新機能" + } + } + } + }, + "What's new in\nYubico Authenticator" : { + "comment" : "Version history title", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nouveautés de\nYubico Authenticator" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "Yubico Authenticator\nの新機能" + } + } + } + }, + "While the YubiKey is inserted the on-screen keyboard will not appear. To show the keyboard you will have to remove the YubiKey and then re-insert it." : { + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Lorsque vous insérez la YubiKey, le clavier à l'écran n'apparaît pas. Pour afficher le clavier, vous devez retirer la YubiKey, puis la réinsérer." + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "YubiKeyが挿入されている間は、オンスクリーンキーボードが表示されません。キーボードを表示するにはYubiKeyを取り外し、その後再挿入する必要があります." + } + } + } + }, + "Would you like to save this password for YubiKey for next usage in this application?" : { + "comment" : "Password entry save password title", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Souhaitez-vous enregistrer ce mot de passe pour la YubiKey afin de l'utiliser lors de la prochaine utilisation dans cette application ?" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "YubiKeyのこのパスワードを保存して、このアプリケーションで次回使用しますか?" + } + } + } + }, + "Wrong password" : { + "comment" : "Password Configuration wrong password", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Mot de passe incorrect" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "パスワードが正しくありません" + } + } + } + }, + "Wrong PIN code" : { + "comment" : "PIV extension wrong pin", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Code PIN incorrect" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "PINコードが正しくありません" + } + } + } + }, + "You can remove saved password in Settings." : { + "comment" : "Password entry save password message", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Vous pouvez supprimer le mot de passe enregistré dans les paramètres." + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "保存されたパスワードは設定で削除できます。" + } + } + } + }, + "Your PIN has ben blocked" : { + "comment" : "PIV extension pin blocked title", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Votre code PIN a été bloqué" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "PINがブロックされました" + } + } + } + }, + "Yubico OTP" : { + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Yubico OTP" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "Yubico OTP" + } + } + } + }, + "Yubico OTP enabled" : { + "comment" : "OATH otp enabled error message", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Yubico OTP activé" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "Yubico OTP有効" + } + } + } + }, + "Yubico OTP has been disabled" : { + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Yubico OTP désactivé" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "Yubico OTPが無効になっています" + } + } + } + }, + "YubiKey information read" : { + "comment" : "YubiKey info NFC read", + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Informations YubiKey lues" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "YubiKeyの情報が読み込まれました" + } + } + } + } + }, + "version" : "1.0" +} \ No newline at end of file diff --git a/Authenticator/Model/MainViewModel.swift b/Authenticator/Model/MainViewModel.swift index dc8c2051..5ba393a6 100644 --- a/Authenticator/Model/MainViewModel.swift +++ b/Authenticator/Model/MainViewModel.swift @@ -156,7 +156,7 @@ class MainViewModel: ObservableObject { account.update(otp: otp) } - session.endNFC(message: "Code calculated") + session.endNFC(message: String(localized: "Code calculated", comment: "OATH NFC code calculated")) } catch { handle(error: error, retry: { Task { await self.updateAccount(account) }}) } @@ -210,7 +210,7 @@ class MainViewModel: ObservableObject { } self.accountsLoaded = true - let message = SettingsConfig.showNFCSwipeHint ? "Success!\nHint: swipe down to dismiss" : "Successfully read" + let message = SettingsConfig.showNFCSwipeHint ? String(localized: "Success!\nHint: swipe down to dismiss", comment: "iOS NFC alert success with hint") : String(localized: "Successfully read", comment: "iOS NFC alert successfully read") useSession.endNFC(message: message) } catch { handle(error: error, retry: { Task { await self.updateAccounts() }}) @@ -233,7 +233,7 @@ class MainViewModel: ObservableObject { let session = try await OATHSessionHandler.shared.nfcSession() await updateAccounts(using: session) } catch { - YubiKitManager.shared.stopNFCConnection(withErrorMessage: "Something went wrong") + YubiKitManager.shared.stopNFCConnection(withErrorMessage: String(localized: "Something went wrong")) self.sessionError = error } } @@ -265,7 +265,7 @@ class MainViewModel: ObservableObject { account.updateTitles() account.isPinned = wasPinned await updateAccounts(using: session) - YubiKitManager.shared.stopNFCConnection(withMessage: "Account renamed") + YubiKitManager.shared.stopNFCConnection(withMessage: String(localized: "Account renamed", comment: "OATH NFC account renamed")) completion() } catch { handle(error: error, retry: { self.renameAccount(account, issuer: issuer, accountName: accountName, completion: completion) }) @@ -281,7 +281,7 @@ class MainViewModel: ObservableObject { accounts.removeAll { $0.accountId == account.accountId } pinnedAccounts.removeAll { $0.accountId == account.accountId } otherAccounts.removeAll { $0.accountId == account.accountId } - session.endNFC(message: "Account deleted") + session.endNFC(message: String(localized: "Account deleted", comment: "OATH NFC account deleted")) completion() } catch { handle(error: error, retry: { self.deleteAccount(account, completion: completion) }) @@ -291,8 +291,8 @@ class MainViewModel: ObservableObject { func collectPasswordAndUnlock(isRetry: Bool = false, completion: @escaping (Error?) -> Void) { DispatchQueue.main.async { - YubiKitManager.shared.stopNFCConnection(withErrorMessage: "Key is password protected") - self.passwordEntryMessage = isRetry ? "Incorrect password. Re-enter password." : "To prevent unauthorized access this YubiKey is protected with a password." + YubiKitManager.shared.stopNFCConnection(withErrorMessage: String(localized: "Key is password protected", comment: "OATH NFC password protected key")) + self.passwordEntryMessage = isRetry ? String(localized: "Incorrect password. Re-enter password.", comment: "OATH password entry retry") : String(localized: "To prevent unauthorized access this YubiKey is protected with a password.", comment: "OATH password entry enter password") self.presentPasswordEntry = true self.passwordCancellable = self.password.sink { password in if let password { @@ -324,7 +324,7 @@ class MainViewModel: ObservableObject { } catch { self.collectPasswordAndUnlock() { error in if let error { - YubiKitManager.shared.stopNFCConnection(withErrorMessage: "Something went wrong") + YubiKitManager.shared.stopNFCConnection(withErrorMessage: String(localized: "Something went wrong")) self.handle(error: error, retry: retry) } else { retry?() @@ -335,7 +335,7 @@ class MainViewModel: ObservableObject { } else { self.collectPasswordAndUnlock() { error in if let error { - YubiKitManager.shared.stopNFCConnection(withErrorMessage: "Something went wrong") + YubiKitManager.shared.stopNFCConnection(withErrorMessage: String(localized: "Something went wrong")) self.handle(error: error, retry: retry) } else { retry?() @@ -346,7 +346,7 @@ class MainViewModel: ObservableObject { } else if let oathError = error as? YKFOATHError, oathError.code == YKFOATHErrorCode.wrongPassword.rawValue { collectPasswordAndUnlock(isRetry: true) { error in if let error { - YubiKitManager.shared.stopNFCConnection(withErrorMessage: "Something went wrong") + YubiKitManager.shared.stopNFCConnection(withErrorMessage: String(localized: "Something went wrong")) self.handle(error: error, retry: retry) } else { retry?() diff --git a/Authenticator/Model/ManagementViewModel.swift b/Authenticator/Model/ManagementViewModel.swift index 0762ff28..e0477f32 100644 --- a/Authenticator/Model/ManagementViewModel.swift +++ b/Authenticator/Model/ManagementViewModel.swift @@ -55,7 +55,7 @@ class ManagementViewModel { return } session.getDeviceInfo { deviceInfo, error in - YubiKitManager.shared.stopNFCConnection(withMessage: "Read YubiKey OTP configuration") + YubiKitManager.shared.stopNFCConnection(withMessage: String(localized: "Read YubiKey OTP configuration", comment: "Settings OTP configuration read")) guard let deviceInfo = deviceInfo else { completion(.failure(error!)); return } guard let configuration = deviceInfo.configuration else { completion(.failure(ManagementViewModelError.unknownError)) @@ -103,7 +103,7 @@ class ManagementViewModel { completion(errorToPassOn) return } else { - YubiKitManager.shared.stopNFCConnection(withMessage: "New OTP configuration saved") + YubiKitManager.shared.stopNFCConnection(withMessage: String(localized: "New OTP configuration saved", comment: "Settings OTP configuration saved")) } completion(nil) } diff --git a/Authenticator/Model/OATHSession.swift b/Authenticator/Model/OATHSession.swift index 5061a3ba..6e5f0349 100644 --- a/Authenticator/Model/OATHSession.swift +++ b/Authenticator/Model/OATHSession.swift @@ -24,9 +24,9 @@ enum OATHSessionError: Error, LocalizedError, Equatable { public var errorDescription: String? { switch self { case .credentialAlreadyPresent(let credential): - return "There's already an account named \(credential.issuer.isEmpty == false ? "\(credential.issuer), \(credential.accountName)" : credential.accountName) on this YubiKey." + return "\(String(localized: "There's already an account named", comment: "OATH substring in 'There's already an account named [issuer, name] on this YubiKey.")) \(credential.issuer.isEmpty == false ? "\(credential.issuer), \(credential.accountName)" : credential.accountName) \(String(localized: "on this YubiKey", comment: "OATH substring in 'There's already an account named [issuer, name] on this YubiKey."))." case .otpEnabledError: - return "Yubico OTP enabled" + return String(localized: "Yubico OTP enabled", comment: "OATH otp enabled error message") } } } @@ -308,7 +308,7 @@ class OATHSession { let key = YKFOATHCredentialUtils.key(fromAccountName: template.accountName, issuer: template.issuer, period: template.period, type: template.type) let keys = credentials.map { YKFOATHCredentialUtils.key(fromAccountName: $0.accountName, issuer: $0.issuer, period: $0.period, type: $0.type) } guard !keys.contains(key) else { - YubiKitManager.shared.stopNFCConnection(withErrorMessage: "Duplicate accounts!") + YubiKitManager.shared.stopNFCConnection(withErrorMessage: String(localized: "Duplicate accounts!", comment: "OATH add credential duplicate accounts error")) throw OATHSessionError.credentialAlreadyPresent(template) } diff --git a/Authenticator/Model/PasswordConfigurationViewModel.swift b/Authenticator/Model/PasswordConfigurationViewModel.swift index 0e66dbf7..e5767369 100644 --- a/Authenticator/Model/PasswordConfigurationViewModel.swift +++ b/Authenticator/Model/PasswordConfigurationViewModel.swift @@ -44,7 +44,7 @@ class PasswordConfigurationViewModel { session.unlock(password: oldPassword) { error in if let error = error { if let oathError = error as? YKFOATHError, oathError.code == YKFOATHErrorCode.wrongPassword.rawValue { - YubiKitManager.shared.stopNFCConnection(withErrorMessage: "Wrong password") + YubiKitManager.shared.stopNFCConnection(withErrorMessage: String(localized: "Wrong password", comment: "Password Configuration wrong password")) completion(.wrongPassword) return } @@ -55,7 +55,7 @@ class PasswordConfigurationViewModel { session.setPassword(password) { error in if let error = error { if let oathError = error as? YKFOATHError, oathError.code == YKFOATHErrorCode.authenticationRequired.rawValue { - YubiKitManager.shared.stopNFCConnection(withErrorMessage: "Authentication required") + YubiKitManager.shared.stopNFCConnection(withErrorMessage: String(localized: "Authentication required", comment: "Password Configuration auth required")) completion(.authenticationRequired) return } @@ -65,11 +65,11 @@ class PasswordConfigurationViewModel { } let message: String if password == "" { - message = "Password has been removed" + message = String(localized: "Password has been removed", comment: "Password Configuration password removed") } else if oldPassword == nil { - message = "Password has been set" + message = String(localized: "Password has been set", comment: "Password Configuration password set") } else { - message = "Password has been changed" + message = String(localized: "Password has been changed", comment: "Password Configuration password changed") } YubiKitManager.shared.stopNFCConnection(withMessage: message) completion(.success((connection as? YKFAccessoryConnection != nil) ? message : nil)) diff --git a/Authenticator/Model/ResetOATHViewModel.swift b/Authenticator/Model/ResetOATHViewModel.swift index f52fc2f8..692cdf44 100644 --- a/Authenticator/Model/ResetOATHViewModel.swift +++ b/Authenticator/Model/ResetOATHViewModel.swift @@ -40,7 +40,7 @@ class ResetOATHViewModel { completion(.failure((connection as? YKFAccessoryConnection != nil) ? error.localizedDescription : nil)) return } else { - let message = "OATH accounts deleted and OATH application reset to factory defaults." + let message = String(localized: "OATH accounts deleted and OATH application reset to factory defaults.", comment: "OATH reset confirmation message") YubiKitManager.shared.stopNFCConnection(withMessage: message) completion(.success((connection as? YKFAccessoryConnection != nil) ? message: nil)) } diff --git a/Authenticator/Model/SecureStore/SecureStoreError.swift b/Authenticator/Model/SecureStore/SecureStoreError.swift index 4785ebac..fdefbf62 100644 --- a/Authenticator/Model/SecureStore/SecureStoreError.swift +++ b/Authenticator/Model/SecureStore/SecureStoreError.swift @@ -50,7 +50,7 @@ extension SecureStoreError: LocalizedError { case .dataCastError: return NSLocalizedString("Failed to cast object to Data error", comment: "") case .unhandledError(let message): - return NSLocalizedString(message, comment: "") + return message case .itemNotFound: return NSLocalizedString("Item not found in secure storage", comment: "") } diff --git a/Authenticator/Model/SmartCardViewModel.swift b/Authenticator/Model/SmartCardViewModel.swift index 5a1604ac..ca0b7963 100644 --- a/Authenticator/Model/SmartCardViewModel.swift +++ b/Authenticator/Model/SmartCardViewModel.swift @@ -81,7 +81,7 @@ class SmartCardViewModel: NSObject { session.getCertificateIn(slot: .cardAuth, callback: callback) { certificate in if let certificate = certificate { certificates.append(Certificate(certificate: certificate, slot: .cardAuth)) } callback(.success(certificates)) - YubiKitManager.shared.stopNFCConnection(withMessage: "Finished reading certificates") + YubiKitManager.shared.stopNFCConnection(withMessage: String(localized: "Finished reading certificates", comment: "PIV extension NFC finished reading certs")) return } } @@ -98,7 +98,7 @@ extension YKFPIVSession { completion: @escaping (_ certificate: SecCertificate?) -> Void) { getCertificateIn(slot) { certificate, error in guard let certificate = certificate else { - if (error! as NSError).code == 0x6A82 || (error! as NSError).code == YKFPIVFErrorCode.dataParseError.rawValue { + if (error! as NSError).code == 0x6A82 || (error! as NSError).code == YKFPIVErrorCode.dataParseError.rawValue { completion(nil) } else { callback(.failure(error!)) diff --git a/Authenticator/Model/TokenRequestViewModel.swift b/Authenticator/Model/TokenRequestViewModel.swift index 4d0aa867..f228b3a1 100644 --- a/Authenticator/Model/TokenRequestViewModel.swift +++ b/Authenticator/Model/TokenRequestViewModel.swift @@ -17,12 +17,13 @@ @available(iOS 14.0, *) extension Error { var tokenError: TokenRequestViewModel.TokenError { - let code = YKFPIVFErrorCode(rawValue: UInt((self as NSError).code)) + let code = YKFPIVErrorCode(rawValue: UInt((self as NSError).code)) switch code { case .pinLocked: - return .passwordLocked(TokenRequestViewModel.ErrorMessage(title: "Your PIN has ben blocked", text: "Use your PUK code to reset PIN.")) + return .passwordLocked(TokenRequestViewModel.ErrorMessage(title: String(localized: "Your PIN has ben blocked", comment: "PIV extension pin blocked title"), + text: String(localized: "Use your PUK code to reset PIN.", comment: "PIV extension pin blocked text"))) case .invalidPin: - return .wrongPassword(TokenRequestViewModel.ErrorMessage(title: "Wrong PIN code", text: nil)) + return .wrongPassword(TokenRequestViewModel.ErrorMessage(title: String(localized: "Wrong PIN code", comment: "PIV extension wrong pin"), text: nil)) default: return .notHandled(TokenRequestViewModel.ErrorMessage(title: self.localizedDescription, text: nil)) } @@ -125,24 +126,26 @@ class TokenRequestViewModel: NSObject { session.signWithKey(in: slot, type: type, algorithm: algorithm, message: message) { signature, error in // Handle any errors if let error = error, (error as NSError).code == 0x6a80 { - YubiKitManager.shared.stopNFCConnection(withErrorMessage: "Invalid signature") - completion(.communicationError(ErrorMessage(title: "Invalid signature", text: "The private key on the YubiKey does not match the certificate or there is no private key stored on the YubiKey."))) + YubiKitManager.shared.stopNFCConnection(withErrorMessage: String(localized: "Invalid signature", comment: "PIV extension NFC invalid signature")) + completion(.communicationError(ErrorMessage(title: String(localized: "Invalid signature", comment: "PIV extension NFC invalid signature"), + text: String(localized: "The private key on the YubiKey does not match the certificate or there is no private key stored on the YubiKey.", comment: "PIV extension NFC invalid signature no private key")))) return } if let error = error { - completion(.communicationError(ErrorMessage(title: "Signing failed", text: error.localizedDescription))) + completion(.communicationError(ErrorMessage(title: String(localized: "Signing failed", comment: "PIV extension signing failed error message"), text: error.localizedDescription))) return } guard let signature = signature else { fatalError() } // Verify signature let signatureError = self.verifySignature(signature, data: message, objectId: objectId, algorithm: algorithm) if signatureError != nil { - YubiKitManager.shared.stopNFCConnection(withErrorMessage: "Invalid signature") - completion(.communicationError(ErrorMessage(title: "Invalid signature", text: "The private key on the YubiKey does not match the certificate."))) + YubiKitManager.shared.stopNFCConnection(withErrorMessage: String(localized: "Invalid signature", comment: "PIV extension invalid signature")) + completion(.communicationError(ErrorMessage(title: String(localized: "Invalid signature", comment: "PIV extension invalid signature"), + text: String(localized: "The private key on the YubiKey does not match the certificate.", comment: "PIV extension invalid signature message")))) return } - YubiKitManager.shared.stopNFCConnection(withMessage: "Successfully signed data") + YubiKitManager.shared.stopNFCConnection(withMessage: String(localized: "Successfully signed data", comment: "PIV extension NFC successfully signed data")) print(signature.hex) diff --git a/Authenticator/Model/YubiKeyInformationViewModel.swift b/Authenticator/Model/YubiKeyInformationViewModel.swift index 7436173e..733e2e29 100644 --- a/Authenticator/Model/YubiKeyInformationViewModel.swift +++ b/Authenticator/Model/YubiKeyInformationViewModel.swift @@ -46,7 +46,7 @@ class YubiKeyInformationViewModel: NSObject { session.getDeviceInfo { info, error in guard let info = info else { self.handleError(error!, forConnection: connection); return } self.deviceInfo = info - YubiKitManager.shared.stopNFCConnection(withMessage: "YubiKey information read") + YubiKitManager.shared.stopNFCConnection(withMessage: String(localized: "YubiKey information read", comment: "YubiKey info NFC read")) self.handler?(.success(info)) } } diff --git a/Authenticator/UI/Authentication/AddCredential/AddAccountWrapper.swift b/Authenticator/UI/Authentication/AddCredential/AddAccountWrapper.swift index d58e0dcc..612809d6 100644 --- a/Authenticator/UI/Authentication/AddCredential/AddAccountWrapper.swift +++ b/Authenticator/UI/Authentication/AddCredential/AddAccountWrapper.swift @@ -35,8 +35,8 @@ struct AddAccountView: View { var body: some View { AddCredentialWrapper(accountSubject: accountSubject, oathURL: oathURL) - .navigationTitle("Add Credential") - .navigationBarItems(trailing: Button("Close") { + .navigationTitle(String(localized: "Add Credential", comment: "Add account navigation title")) + .navigationBarItems(trailing: Button(String(localized: "Close", comment: "View close button")) { showAddAccount.toggle() }) .ignoresSafeArea(.all, edges: .bottom) diff --git a/Authenticator/UI/Authentication/AddCredential/AddCredentialController.swift b/Authenticator/UI/Authentication/AddCredential/AddCredentialController.swift index c199f00c..b22a9a58 100644 --- a/Authenticator/UI/Authentication/AddCredential/AddCredentialController.swift +++ b/Authenticator/UI/Authentication/AddCredential/AddCredentialController.swift @@ -152,7 +152,7 @@ class AddCredentialController: UITableViewController { skip: []) } } catch { - showAlertDialog(title: "Not valid credential information", message: error.localizedDescription) + showAlertDialog(title: String(localized: "Not valid credential information", comment: "Add account error message"), message: error.localizedDescription) return } self.requiresTouch = requiresTouchSwitch.isOn @@ -217,28 +217,28 @@ class AddCredentialController: UITableViewController { guard indexPath.section == 1 else { return } switch indexPath.row { case 0: - let table = AdvancedSettingsViewController(title: "Type", + let table = AdvancedSettingsViewController(title: String(localized: "Type", comment: "Add account select type"), rows: advancedSettings[0], selected: typeIndex) { [weak self] result in self?.typeIndex = result } self.navigationController?.pushViewController(table, animated: true) case 1: - let table = AdvancedSettingsViewController(title: "Algorithm", + let table = AdvancedSettingsViewController(title: String(localized: "Algorithm", comment: "Add account select algorithm"), rows: advancedSettings[1], selected: algorithmIndex) { [weak self] result in self?.algorithmIndex = result } self.navigationController?.pushViewController(table, animated: true) case 2: - let table = AdvancedSettingsViewController(title: "Digits", + let table = AdvancedSettingsViewController(title: String(localized: "Digits", comment: "Add account select number of digits"), rows: advancedSettings[2], selected: digitsIndex) { [weak self] result in self?.digitsIndex = result } self.navigationController?.pushViewController(table, animated: true) case 3: - let table = AdvancedSettingsViewController(title: "Period", + let table = AdvancedSettingsViewController(title: String(localized: "Period", comment: "Add account select period"), rows: advancedSettings[3], selected: periodIndex) { [weak self] result in self?.periodIndex = result diff --git a/Authenticator/UI/Authentication/AddCredential/AddCredential.storyboard b/Authenticator/UI/Authentication/AddCredential/Base.lproj/AddCredential.storyboard similarity index 100% rename from Authenticator/UI/Authentication/AddCredential/AddCredential.storyboard rename to Authenticator/UI/Authentication/AddCredential/Base.lproj/AddCredential.storyboard diff --git a/Authenticator/UI/Authentication/AddCredential/ScanAccountView.swift b/Authenticator/UI/Authentication/AddCredential/ScanAccountView.swift index 8150555e..636f5e70 100644 --- a/Authenticator/UI/Authentication/AddCredential/ScanAccountView.swift +++ b/Authenticator/UI/Authentication/AddCredential/ScanAccountView.swift @@ -25,7 +25,7 @@ class ScanAccountView: UIView, AVCaptureMetadataOutputObjectsDelegate { case cancel, manuelEntry, account(YKFOATHCredentialTemplate) } - private static let scanMessage = "Point your camera at a QR code to scan it" + private static let scanMessage = String(localized: "Point your camera at a QR code to scan it", comment: "Scan QR code message") private let completionHandler: (ScanResult) -> () private let captureSession = AVCaptureSession() @@ -41,7 +41,7 @@ class ScanAccountView: UIView, AVCaptureMetadataOutputObjectsDelegate { private let closeButton: UIButton = { let button = UIButton() button.translatesAutoresizingMaskIntoConstraints = false - button.setTitle("Close", for: .normal) + button.setTitle(String(localized: "Close", comment: "View close button"), for: .normal) button.setTitleColor(.white, for: .normal) button.titleLabel?.font = .preferredFont(forTextStyle: .body) return button @@ -50,7 +50,7 @@ class ScanAccountView: UIView, AVCaptureMetadataOutputObjectsDelegate { private let addManuallyButton: UIButton = { let button = UIButton(type: .roundedRect) button.translatesAutoresizingMaskIntoConstraints = false - button.setTitle("Enter manually", for: .normal) + button.setTitle(String(localized: "Enter manually", comment: "Scan QR code add manually button"), for: .normal) button.setContentHuggingPriority(.required, for: .horizontal) button.setTitleColor(.white, for: .normal) button.titleLabel?.font = .preferredFont(forTextStyle: .body) @@ -65,7 +65,7 @@ class ScanAccountView: UIView, AVCaptureMetadataOutputObjectsDelegate { private let openSettingsButton: UIButton = { let button = UIButton(type: .roundedRect) button.translatesAutoresizingMaskIntoConstraints = false - button.setTitle("Open iOS Settings app", for: .normal) + button.setTitle(String(localized: "Open iOS Settings app", comment: "Scan QR code settings button"), for: .normal) button.setTitleColor(.white, for: .normal) button.titleLabel?.font = .preferredFont(forTextStyle: .body) button.layer.cornerRadius = 20 @@ -79,7 +79,7 @@ class ScanAccountView: UIView, AVCaptureMetadataOutputObjectsDelegate { private let addAccountLabel: UILabel = { let label = UILabel() label.translatesAutoresizingMaskIntoConstraints = false - label.text = "Add account" + label.text = String(localized: "Add account", comment: "Scan QR code add account label") label.textColor = .white label.font = .preferredFont(forTextStyle: .body).withSymbolicTraits(.traitBold) return label @@ -88,7 +88,7 @@ class ScanAccountView: UIView, AVCaptureMetadataOutputObjectsDelegate { private let noQRCodeLabel: UILabel = { let label = UILabel() label.translatesAutoresizingMaskIntoConstraints = false - label.text = "No QR code?" + label.text = String(localized: "No QR code?", comment: "Scan QR code no QR code message") label.textColor = .white label.font = .preferredFont(forTextStyle: .footnote).withSymbolicTraits(.traitBold) return label @@ -131,14 +131,14 @@ class ScanAccountView: UIView, AVCaptureMetadataOutputObjectsDelegate { title.numberOfLines = 0 title.font = .preferredFont(forTextStyle: .title2) title.textAlignment = .center - title.text = "No camera permissions" + title.text = String(localized: "No camera permissions", comment: "Scan QR code camera error title") title.textColor = .white view.addArrangedSubview(title) let text = UILabel() text.font = .preferredFont(forTextStyle: .body) text.translatesAutoresizingMaskIntoConstraints = false text.numberOfLines = 0 - text.text = "To scan a QR code you need to enable camera permissions for the Authenticator app." + text.text = String(localized: "To scan a QR code you need to enable camera permissions for the Authenticator app.", comment: "Scan QR code camera error message") text.textColor = .lightGray text.textAlignment = .center view.addArrangedSubview(text) @@ -289,7 +289,7 @@ class ScanAccountView: UIView, AVCaptureMetadataOutputObjectsDelegate { let readableObject = metadataObject as? AVMetadataMachineReadableCodeObject, let stringValue = readableObject.stringValue else { return } guard let url = URL(string: stringValue.trimmingCharacters(in: .whitespacesAndNewlines)) else { - showError("No account information found!") + showError(String(localized: "No account information found!", comment: "Scan QR code no account error message")) return } diff --git a/Authenticator/UI/Authentication/AddCredential/mul.lproj/AddCredential.xcstrings b/Authenticator/UI/Authentication/AddCredential/mul.lproj/AddCredential.xcstrings new file mode 100644 index 00000000..8c23c020 --- /dev/null +++ b/Authenticator/UI/Authentication/AddCredential/mul.lproj/AddCredential.xcstrings @@ -0,0 +1,462 @@ +{ + "sourceLanguage" : "en", + "strings" : { + "5qG-r3-8YC.text" : { + "comment" : "Class = \"UILabel\"; text = \"Digits\"; ObjectID = \"5qG-r3-8YC\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Digits" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Chiffres" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "桁" + } + } + } + }, + "7ff-AA-O0N.text" : { + "comment" : "Class = \"UILabel\"; text = \"Type\"; ObjectID = \"7ff-AA-O0N\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Type" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Type" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "タイプ" + } + } + } + }, + "9r9-ju-7hn.text" : { + "comment" : "Class = \"UILabel\"; text = \"Issuer\"; ObjectID = \"9r9-ju-7hn\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Issuer" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Émetteur" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "発行者" + } + } + } + }, + "23x-vE-GEf.text" : { + "comment" : "Class = \"UILabel\"; text = \"6\"; ObjectID = \"23x-vE-GEf\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "6" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "6" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "6" + } + } + } + }, + "b4T-vk-sxg.title" : { + "comment" : "Class = \"UINavigationItem\"; title = \"Add account\"; ObjectID = \"b4T-vk-sxg\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Add account" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ajouter compte" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "アカウントを追加" + } + } + } + }, + "Fgb-Ow-lzL.text" : { + "comment" : "Class = \"UILabel\"; text = \"Period\"; ObjectID = \"Fgb-Ow-lzL\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Period" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Période" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "期間" + } + } + } + }, + "gdf-yw-zNg.text" : { + "comment" : "Class = \"UILabel\"; text = \"Require touch\"; ObjectID = \"gdf-yw-zNg\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Require touch" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Touche requise" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "タッチが必要" + } + } + } + }, + "iKi-yO-dD3.text" : { + "comment" : "Class = \"UILabel\"; text = \"30\"; ObjectID = \"iKi-yO-dD3\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "30" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "30" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "30" + } + } + } + }, + "jjH-co-W9w.footerTitle" : { + "comment" : "Class = \"UITableViewSection\"; footerTitle = \"Normally these settings should not be changed, doing so may result in the code not working as expected\"; ObjectID = \"jjH-co-W9w\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Normally these settings should not be changed, doing so may result in the code not working as expected" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "En règle générale, ces paramètres ne devraient pas être modifiés, car cela pourrait entraîner un dysfonctionnement du code" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "通常、これらの設定は変更しないでください。変更すると、コードが想定どおりに動作しなくなる可能性があります" + } + } + } + }, + "jjH-co-W9w.headerTitle" : { + "comment" : "Class = \"UITableViewSection\"; headerTitle = \"Advanced settings\"; ObjectID = \"jjH-co-W9w\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Advanced settings" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Paramètres avancés" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "高度な設定" + } + } + } + }, + "Kyw-Tw-o0u.text" : { + "comment" : "Class = \"UILabel\"; text = \"TOTP\"; ObjectID = \"Kyw-Tw-o0u\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "TOTP" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "TOTP" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "TOTP" + } + } + } + }, + "Nc5-A6-Y2F.placeholder" : { + "comment" : "Class = \"UITextField\"; placeholder = \"Secret\"; ObjectID = \"Nc5-A6-Y2F\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Secret" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Secret" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "秘密鍵" + } + } + } + }, + "nc9-CL-5p4.placeholder" : { + "comment" : "Class = \"UITextField\"; placeholder = \"john@doe.com\"; ObjectID = \"nc9-CL-5p4\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "john@doe.com" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "john@doe.com" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "john@doe.com" + } + } + } + }, + "NVO-62-Xcp.text" : { + "comment" : "Class = \"UILabel\"; text = \"SHA1\"; ObjectID = \"NVO-62-Xcp\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "SHA1" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "SHA1" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "SHA1" + } + } + } + }, + "nyL-Vx-yTS.text" : { + "comment" : "Class = \"UILabel\"; text = \"Secret\"; ObjectID = \"nyL-Vx-yTS\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Secret" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Secret" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "秘密鍵" + } + } + } + }, + "OHS-sd-F7b.text" : { + "comment" : "Class = \"UILabel\"; text = \"Account name\"; ObjectID = \"OHS-sd-F7b\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Account name" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nom du compte" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "アカウント名" + } + } + } + }, + "t2b-3i-5P0.placeholder" : { + "comment" : "Class = \"UITextField\"; placeholder = \"Optional\"; ObjectID = \"t2b-3i-5P0\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Optional" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Optionnel" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "オプション" + } + } + } + }, + "t06-Ma-iHo.headerTitle" : { + "comment" : "Class = \"UITableViewSection\"; headerTitle = \"Account details\"; ObjectID = \"t06-Ma-iHo\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Account details" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Détails du compte" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "アカウント詳細" + } + } + } + }, + "xjs-s4-9fy.text" : { + "comment" : "Class = \"UILabel\"; text = \"Algorithm\"; ObjectID = \"xjs-s4-9fy\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Algorithm" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Algorithme" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "アルゴリズム" + } + } + } + } + }, + "version" : "1.0" +} \ No newline at end of file diff --git a/Authenticator/UI/Authentication/EditCredential/EditCredential.storyboard b/Authenticator/UI/Authentication/EditCredential/Base.lproj/EditCredential.storyboard similarity index 100% rename from Authenticator/UI/Authentication/EditCredential/EditCredential.storyboard rename to Authenticator/UI/Authentication/EditCredential/Base.lproj/EditCredential.storyboard diff --git a/Authenticator/UI/Authentication/EditCredential/EditAccountWrapper.swift b/Authenticator/UI/Authentication/EditCredential/EditAccountWrapper.swift index 33841382..408d404a 100644 --- a/Authenticator/UI/Authentication/EditCredential/EditAccountWrapper.swift +++ b/Authenticator/UI/Authentication/EditCredential/EditAccountWrapper.swift @@ -37,10 +37,6 @@ struct EditView: View { var body: some View { EditAccountWrapper(account: account, viewModel: viewModel) - .navigationTitle("Add Credential") - .navigationBarItems(trailing: Button("WAAAT") { - showEditing.toggle() - }) .ignoresSafeArea(.all, edges: .bottom) } } diff --git a/Authenticator/UI/Authentication/EditCredential/EditCredentialController.swift b/Authenticator/UI/Authentication/EditCredential/EditCredentialController.swift index 95085916..2b655d14 100644 --- a/Authenticator/UI/Authentication/EditCredential/EditCredentialController.swift +++ b/Authenticator/UI/Authentication/EditCredential/EditCredentialController.swift @@ -37,7 +37,7 @@ class EditCredentialController: UITableViewController { @IBAction func save(_ sender: Any) { guard let account, let issuer = issuerRow.value, let accountName = accountRow.value, accountName.count > 0 else { - showAlertDialog(title: "Account not set", message: "Account name can not be empty") + showAlertDialog(title: String(localized: "Account not set", comment: "Rename credential alert"), message: String(localized: "Account name can not be empty", comment: "Rename credential alert")) return } viewModel?.renameAccount(account, issuer: issuer, accountName: accountName) { diff --git a/Authenticator/UI/Authentication/EditCredential/mul.lproj/EditCredential.xcstrings b/Authenticator/UI/Authentication/EditCredential/mul.lproj/EditCredential.xcstrings new file mode 100644 index 00000000..d9404c76 --- /dev/null +++ b/Authenticator/UI/Authentication/EditCredential/mul.lproj/EditCredential.xcstrings @@ -0,0 +1,102 @@ +{ + "sourceLanguage" : "en", + "strings" : { + "1gZ-3p-mE7.text" : { + "comment" : "Class = \"UITextField\"; text = \"jens.utbult@yubico.com\"; ObjectID = \"1gZ-3p-mE7\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "jens.utbult@yubico.com" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "jens.utbult@yubico.com" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "jens.utbult@yubico.com" + } + } + } + }, + "3UQ-h0-0mc.title" : { + "comment" : "Class = \"UINavigationItem\"; title = \"Rename\"; ObjectID = \"3UQ-h0-0mc\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Rename" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Renommer" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "名前変更" + } + } + } + }, + "D9E-Hm-eAX.title" : { + "comment" : "Class = \"UIBarButtonItem\"; title = \"Cancel\"; ObjectID = \"D9E-Hm-eAX\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Cancel" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Annuler" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "キャンセル" + } + } + } + }, + "G5H-9k-oaS.title" : { + "comment" : "Class = \"UIBarButtonItem\"; title = \"Save\"; ObjectID = \"G5H-9k-oaS\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Save" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Enregistrer" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "保存" + } + } + } + } + }, + "version" : "1.0" +} \ No newline at end of file diff --git a/Authenticator/UI/Help/AboutWrapper.swift b/Authenticator/UI/Help/AboutWrapper.swift index d3e6b6b8..b3d30d45 100644 --- a/Authenticator/UI/Help/AboutWrapper.swift +++ b/Authenticator/UI/Help/AboutWrapper.swift @@ -32,8 +32,8 @@ struct AboutView: View { var body: some View { NavigationView { HelpWrapper() - .navigationTitle("About") - .navigationBarItems(trailing: Button("Close") { + .navigationTitle(String(localized: "About", comment: "About view navigation title")) + .navigationBarItems(trailing: Button(String(localized: "Close", comment: "View close button")) { showAbout.toggle() }) .ignoresSafeArea(.all, edges: .bottom) diff --git a/Authenticator/UI/Help/LicensingViewController.swift b/Authenticator/UI/Help/LicensingViewController.swift index 2e37200f..b6cda45d 100644 --- a/Authenticator/UI/Help/LicensingViewController.swift +++ b/Authenticator/UI/Help/LicensingViewController.swift @@ -22,7 +22,7 @@ class LicensingViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() - self.title = "Licensing" + self.title = String(localized: "Licensing", comment: "Licensing view navigation title") self.view = textView self.navigationItem.largeTitleDisplayMode = .never textView.textContainerInset = UIEdgeInsets(top: 15, left: 15, bottom: 15, right: 15) diff --git a/Authenticator/UI/Help/VersionHistoryViewController.swift b/Authenticator/UI/Help/VersionHistoryViewController.swift index 1f86df4b..c6870119 100644 --- a/Authenticator/UI/Help/VersionHistoryViewController.swift +++ b/Authenticator/UI/Help/VersionHistoryViewController.swift @@ -25,13 +25,13 @@ class VersionHistoryViewController: UIViewController { private var titleLabel = UILabel() var closeBlock: (() -> ())? - var closeButtonText: String = "Close" { + var closeButtonText: String = String(localized: "Close", comment: "View close button") { didSet { closeButton.setTitle(closeButtonText, for: .normal) } } - var titleText: String = "Version history" { + var titleText: String = String(localized: "Version history", comment: "Version history navigation title") { didSet { titleLabel.text = titleText } diff --git a/Authenticator/UI/Helpers/ToastPresenter.swift b/Authenticator/UI/Helpers/ToastPresenter.swift index 4d656e24..7ebb62c0 100644 --- a/Authenticator/UI/Helpers/ToastPresenter.swift +++ b/Authenticator/UI/Helpers/ToastPresenter.swift @@ -56,7 +56,7 @@ extension ToastPresenter { func copyToClipboard(_ value: String) { UIPasteboard.general.string = value - toast(message: "Copied to clipboard") + toast(message: String(localized: "Copied to clipboard", comment: "Toast copied to clipboard message")) let generator = UINotificationFeedbackGenerator() generator.notificationOccurred(.success) } diff --git a/Authenticator/UI/Helpers/ToastView.swift b/Authenticator/UI/Helpers/ToastView.swift index e399dfe5..7ed278db 100644 --- a/Authenticator/UI/Helpers/ToastView.swift +++ b/Authenticator/UI/Helpers/ToastView.swift @@ -36,16 +36,6 @@ struct ToastView: View { } } -struct ToastView_Previews: PreviewProvider { - static var previews: some View { - ZStack { - Color(.systemBackground).ignoresSafeArea() - Text("Some content...") - .overlay(ToastView(message: "Very toasty! Something has happened!"), alignment: .top) - } - } -} - struct ToastModifier: ViewModifier { @Binding var isPresenting: Bool diff --git a/Authenticator/UI/Helpers/UIAlertController+Extensions.swift b/Authenticator/UI/Helpers/UIAlertController+Extensions.swift index 8cb099a1..11448539 100644 --- a/Authenticator/UI/Helpers/UIAlertController+Extensions.swift +++ b/Authenticator/UI/Helpers/UIAlertController+Extensions.swift @@ -38,22 +38,22 @@ extension UIAlertController { let message: String switch type { case .password: - message = "To prevent unauthorized access this YubiKey is protected with a password." + message = String(localized: "To prevent unauthorized access this YubiKey is protected with a password.", comment: "OATH password entry enter password") case .retryPassword: - message = "Incorrect password. Re-enter password." + message = String(localized: "Incorrect password. Re-enter password.", comment: "OATH password entry retry") } - self.init(title: "Unlock YubiKey", message: message, preferredStyle: .alert) + self.init(title: String(localized: "Unlock YubiKey", comment: "Password entry unlock message"), message: message, preferredStyle: .alert) weak var inputTextField: UITextField? self.addTextField { textField in textField.isSecureTextEntry = true inputTextField = textField } - let ok = UIAlertAction(title: "OK", style: .default) { _ in + let ok = UIAlertAction(title: String(localized: "OK"), style: .default) { _ in completion(inputTextField?.text) } - let cancel = UIAlertAction(title: "Cancel", style: .cancel) { _ in + let cancel = UIAlertAction(title: String(localized: "Cancel"), style: .cancel) { _ in completion(nil) } self.addAction(ok) @@ -63,14 +63,14 @@ extension UIAlertController { convenience init(completion: @escaping (PasswordSaveType) -> Void) { let authenticationType = PasswordPreferences.evaluatedAuthenticationType() - self.init(title: "Would you like to save this password for YubiKey for next usage in this application?", - message: "You can remove saved password in Settings.", + self.init(title: String(localized: "Would you like to save this password for YubiKey for next usage in this application?", comment: "Password entry save password title"), + message: String(localized: "You can remove saved password in Settings.", comment: "Password entry save password message"), preferredStyle: UIDevice.current.userInterfaceIdiom == .pad ? .alert : .actionSheet) - let save = UIAlertAction(title: "Save Password", style: .default) { _ in completion(.save) } - let biometric = UIAlertAction(title: "Save and protect with \(authenticationType.title)", style: .default) { _ in completion(.lock) } - let never = UIAlertAction(title: "Never for this YubiKey", style: .default) { _ in completion(.never) } - let notNow = UIAlertAction(title: "Not now", style: .cancel) { _ in + let save = UIAlertAction(title: String(localized: "Save Password", comment: "Password entry save password button"), style: .default) { _ in completion(.save) } + let biometric = UIAlertAction(title: "\(String(localized: "Save and protect with", comment: "Password entry save substring in 'Save and protect with [save type]'")) \(authenticationType.title)", style: .default) { _ in completion(.lock) } + let never = UIAlertAction(title: String(localized: "Never for this YubiKey", comment: "Save password alert."), style: .default) { _ in completion(.never) } + let notNow = UIAlertAction(title: String(localized: "Not now", comment: "Save passsword alert"), style: .cancel) { _ in completion(.none) self.dismiss(animated: true, completion: nil) } diff --git a/Authenticator/UI/Helpers/UIViewControllerAdditions.swift b/Authenticator/UI/Helpers/UIViewControllerAdditions.swift index 215c712a..70ca1982 100644 --- a/Authenticator/UI/Helpers/UIViewControllerAdditions.swift +++ b/Authenticator/UI/Helpers/UIViewControllerAdditions.swift @@ -25,12 +25,12 @@ extension UIViewController { func showAlertDialog(title: String, message: String? = nil, nfcHandler: (() -> Void)? = nil, okHandler: (() -> Void)? = nil) { DispatchQueue.main.async { let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert) - let cancel = UIAlertAction(title: "OK", style: .cancel) { (action) -> Void in + let cancel = UIAlertAction(title: String(localized: "OK"), style: .cancel) { (action) -> Void in okHandler?() } if YubiKitDeviceCapabilities.supportsISO7816NFCTags && nfcHandler != nil { - let activate = UIAlertAction(title: "Activate NFC", style: .default) { (action) -> Void in + let activate = UIAlertAction(title: String(localized: "Activate NFC", comment: "Password save type activate NFC"), style: .default) { (action) -> Void in nfcHandler?() } alertController.addAction(activate) @@ -49,7 +49,7 @@ extension UIViewController { let reset = UIAlertAction(title: okButtonTitle, style: style, handler: { (action) -> Void in okHandler?() }) - let cancel = UIAlertAction(title: "Cancel", style: .cancel, handler: nil) + let cancel = UIAlertAction(title: String(localized: "Cancel"), style: .cancel, handler: nil) alertController.addAction(reset) alertController.addAction(cancel) diff --git a/Authenticator/UI/MainView.swift b/Authenticator/UI/MainView.swift index 2e708a3a..46a2e957 100644 --- a/Authenticator/UI/MainView.swift +++ b/Authenticator/UI/MainView.swift @@ -170,13 +170,13 @@ struct MainView: View { Text(model.passwordEntryMessage) } .alertOrConfirmationDialog(String(localized: "Save password?", comment: "Save password alert"), isPresented: $model.presentPasswordSaveType) { - Button("Save password", comment: "Save password alert.") { model.passwordSaveType.send(.some(.save)) } + Button(String(localized: "Save password", comment: "Save password alert.")) { model.passwordSaveType.send(.some(.save)) } let authenticationType = PasswordPreferences.evaluatedAuthenticationType() if authenticationType != .none { - Button("Save and protect with \(authenticationType.title)") { model.passwordSaveType.send(.some(.lock)) } + Button(String(localized: "Save and protect with \(authenticationType.title)")) { model.passwordSaveType.send(.some(.lock)) } } - Button("Never for this YubiKey", comment: "Save password alert.") { model.passwordSaveType.send(.some(.never)) } - Button("Not now", comment: "Save passsword alert" , role: .cancel) { model.passwordSaveType.send(nil) } + Button(String(localized: "Never for this YubiKey", comment: "Save password alert.")) { model.passwordSaveType.send(.some(.never)) } + Button(String(localized: "Not now", comment: "Save passsword alert"), role: .cancel) { model.passwordSaveType.send(nil) } } .errorAlert(error: $model.sessionError) .errorAlert(error: $model.connectionError) { model.start() } diff --git a/Authenticator/UI/TokenSession/TokenRequestViewController.swift b/Authenticator/UI/TokenSession/TokenRequestViewController.swift index 3f47c548..bc1d8e60 100644 --- a/Authenticator/UI/TokenSession/TokenRequestViewController.swift +++ b/Authenticator/UI/TokenSession/TokenRequestViewController.swift @@ -94,7 +94,7 @@ class TokenRequestViewController: UIViewController, UITextFieldDelegate { UIView.animate(withDuration: 0.2) { self?.accessoryLabel.alpha = 1 if connected { - self?.accessoryLabel.text = "Enter the PIN to access the certificate." + self?.accessoryLabel.text = String(localized: "Enter the PIN to access the certificate.", comment: "PIV extension enter PIN message") } else { self?.accessoryLabel.text = self?.defaultAccessoryTest if YubiKitDeviceCapabilities.supportsISO7816NFCTags { diff --git a/Authenticator/UI/TokenSession/TokenRequestYubiOTPViewController.swift b/Authenticator/UI/TokenSession/TokenRequestYubiOTPViewController.swift index f243fbd9..e032a9c7 100644 --- a/Authenticator/UI/TokenSession/TokenRequestYubiOTPViewController.swift +++ b/Authenticator/UI/TokenSession/TokenRequestYubiOTPViewController.swift @@ -52,7 +52,7 @@ class TokenRequestYubiOTPViewController: UIViewController { private func presentError(_ error: Error?) { guard let error else { return } - let alert = UIAlertController(title: "Error reading YubiKey", message: "\(error.localizedDescription)\n\nRemove and reinsert your YubiKey.") { self.dismiss(animated: true) } + let alert = UIAlertController(title: String(localized: "Error reading YubiKey", comment: "PIV extension error title"), message: "\(error.localizedDescription)\n\n\(String(localized: "Remove and reinsert your YubiKey", comment: "PIV extension error reinsert key")).") { self.dismiss(animated: true) } self.present(alert, animated: true, completion: nil) } } diff --git a/Authenticator/UI/Tutorial/Tutorial.storyboard b/Authenticator/UI/Tutorial/Base.lproj/Tutorial.storyboard similarity index 100% rename from Authenticator/UI/Tutorial/Tutorial.storyboard rename to Authenticator/UI/Tutorial/Base.lproj/Tutorial.storyboard diff --git a/Authenticator/UI/Tutorial/mul.lproj/Tutorial.xcstrings b/Authenticator/UI/Tutorial/mul.lproj/Tutorial.xcstrings new file mode 100644 index 00000000..55e5a2b3 --- /dev/null +++ b/Authenticator/UI/Tutorial/mul.lproj/Tutorial.xcstrings @@ -0,0 +1,390 @@ +{ + "sourceLanguage" : "en", + "strings" : { + "0Ew-5d-tth.text" : { + "comment" : "Class = \"UILabel\"; text = \"YubiKey 5 Series NFC authentication\"; ObjectID = \"0Ew-5d-tth\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "YubiKey 5 Series NFC authentication" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Authentification NFC YubiKey 5 Series" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "YubiKey 5シリーズのNFC認証" + } + } + } + }, + "4hs-uc-a5r.text" : { + "comment" : "Class = \"UITextView\"; text = \"If you have a YubiKey with NFC, pull down the main view to activate NFC.\"; ObjectID = \"4hs-uc-a5r\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "If you have a YubiKey with NFC, pull down the main view to activate NFC." + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Si vous possédez une YubiKey avec NFC, faites glisser la vue principale vers le bas pour activer le NFC." + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "NFC対応のYubiKeyをお持ちの場合は、メインビューをプルダウンしてNFCを有効にします。" + } + } + } + }, + "agV-vn-fpt.text" : { + "comment" : "Class = \"UITextView\"; text = \"You will need a YubiKey 5Ci or a compatible YubiKey with NFC to get started.\"; ObjectID = \"agV-vn-fpt\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "You will need a YubiKey 5Ci or a compatible YubiKey with NFC to get started." + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Vous aurez besoin d'une YubiKey 5Ci ou d'une YubiKey compatible avec NFC pour commencer." + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "開始するには、YubiKey 5CiまたはNFC対応のYubiKeyが必要です。" + } + } + } + }, + "bkN-Lk-jMY.text" : { + "comment" : "Class = \"UITextView\"; text = \"Touch the center of the key to the edge of the phone.\"; ObjectID = \"bkN-Lk-jMY\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Touch the center of the key to the edge of the phone." + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Appuyez le centre de la clé contre le bord du téléphone." + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "キーの中央をタッチして、スマートフォンの端に移動します。" + } + } + } + }, + "Bxy-Ot-GLA.text" : { + "comment" : "Class = \"UITextView\"; text = \"Hold the key horizontally and tilt the iPhone towards the key.\"; ObjectID = \"Bxy-Ot-GLA\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Hold the key horizontally and tilt the iPhone towards the key." + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tenez la clé horizontalement et inclinez l'iPhone vers la clé." + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "キーを水平に持ち、iPhoneをキーに向かって傾けます。" + } + } + } + }, + "bYg-TD-NqH.text" : { + "comment" : "Class = \"UITextView\"; text = \"Get a shared secret from any service you wish to secure, store it on the YubiKey and use it to generate your security codes.\"; ObjectID = \"bYg-TD-NqH\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Get a shared secret from any service you wish to secure, store it on the YubiKey and use it to generate your security codes." + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Obtenez un secret partagé du service que vous voulez sécuriser, stockez-le sur la YubiKey et générez vos codes de sécurité." + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "保護するサービスの共有秘密鍵を取得し、YubiKeyに保存して、YubiKeyを使用してセキュリティコードを生成します。" + } + } + } + }, + "cSo-Sg-vD2.text" : { + "comment" : "Class = \"UITextView\"; text = \"QR codes are available from the services you wish to secure.\"; ObjectID = \"cSo-Sg-vD2\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "QR codes are available from the services you wish to secure." + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Les codes QR sont disponibles auprès des services que vous souhaitez sécuriser." + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "QRコードは、保護するサービスから入手できます。" + } + } + } + }, + "IVf-FH-Iqr.title" : { + "comment" : "Class = \"UIBarButtonItem\"; title = \"Skip\"; ObjectID = \"IVf-FH-Iqr\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Skip" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Passer" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "スキップ" + } + } + } + }, + "jBh-MF-9Fk.text" : { + "comment" : "Class = \"UITextView\"; text = \"Simply scan the QR code when you add your YubiKey and generate your own security codes.\"; ObjectID = \"jBh-MF-9Fk\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Simply scan the QR code when you add your YubiKey and generate your own security codes." + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Il vous suffit de scanner le code QR lorsque vous ajoutez votre YubiKey pour générer vos propres codes de sécurité." + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "YubiKeyを追加して独自のセキュリティコードを生成する場合は、QRコードをスキャンしてください。" + } + } + } + }, + "KWb-g8-FRF.text" : { + "comment" : "Class = \"UITextView\"; text = \"If you have a YubiKey 5Ci, plug it in.\"; ObjectID = \"KWb-g8-FRF\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "If you have a YubiKey 5Ci, plug it in." + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Si vous avez une YubiKey 5Ci, insérez-la." + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "YubiKey 5Ciをお持ちの場合は接続します。" + } + } + } + }, + "mdG-o8-OXh.text" : { + "comment" : "Class = \"UILabel\"; text = \"YubiKey 5Ci authentication\"; ObjectID = \"mdG-o8-OXh\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "YubiKey 5Ci authentication" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Authentification YubiKey 5Ci" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "YubiKey 5Ci認証" + } + } + } + }, + "N2W-CE-fPm.title" : { + "comment" : "Class = \"UIBarButtonItem\"; title = \"Next\"; ObjectID = \"N2W-CE-fPm\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Next" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Suivant" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "次へ" + } + } + } + }, + "Paz-Es-tja.text" : { + "comment" : "Class = \"UITextView\"; text = \"Touch the contacts on the sides when prompted.\"; ObjectID = \"Paz-Es-tja\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Touch the contacts on the sides when prompted." + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Appuyez sur les contacts sur les côtés lorsque vous y êtes invité." + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "プロンプトが表示されたら、横にあるお問い合わせをタッチします。" + } + } + } + }, + "RUl-K8-lGO.text" : { + "comment" : "Class = \"UILabel\"; text = \"Where to get QR codes\"; ObjectID = \"RUl-K8-lGO\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Where to get QR codes" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Où obtenir les codes QR" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "QRコードの入手先" + } + } + } + }, + "ub0-A4-vpe.text" : { + "comment" : "Class = \"UILabel\"; text = \"How it works\"; ObjectID = \"ub0-A4-vpe\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "How it works" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Comment ça marche" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "動作方法" + } + } + } + }, + "XdE-m1-y3M.normalTitle" : { + "comment" : "Class = \"UIButton\"; normalTitle = \"Read more...\"; ObjectID = \"XdE-m1-y3M\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Read more..." + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "En savoir plus..." + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "詳細を読む..." + } + } + } + } + }, + "version" : "1.0" +} \ No newline at end of file diff --git a/Authenticator/UI/YubiKeyConfiguration/ConfigurationController.swift b/Authenticator/UI/YubiKeyConfiguration/ConfigurationController.swift index 29d4413e..dc984acd 100644 --- a/Authenticator/UI/YubiKeyConfiguration/ConfigurationController.swift +++ b/Authenticator/UI/YubiKeyConfiguration/ConfigurationController.swift @@ -35,7 +35,7 @@ class ConfigurationController: UITableViewController { if #available(iOS 14.5, *) { } else { switch (indexPath.section, indexPath.row) { case (3, 0): - let alert = UIAlertController(title: "Smart card extension is only available on iOS 14.5 and forward.", message: nil, completion: {}) + let alert = UIAlertController(title: String(localized: "Smart card extension is only available on iOS 14.5 and forward.", comment: "PIV extension version error"), message: nil, completion: {}) self.present(alert, animated: true, completion: nil) default: break } @@ -68,7 +68,7 @@ class ConfigurationController: UITableViewController { self.refreshControl = refreshControl } - insertYubiKeyLabel.text = YubiKitDeviceCapabilities.supportsISO7816NFCTags ? "Insert YubiKey or pull down to activate NFC" : "Insert YubiKey" + insertYubiKeyLabel.text = YubiKitDeviceCapabilities.supportsISO7816NFCTags ? String(localized: "Insert YubiKey or pull down to activate NFC") : String(localized: "Insert YubiKey") infoViewModel.deviceInfo { [weak self] result in DispatchQueue.main.async { @@ -85,7 +85,7 @@ class ConfigurationController: UITableViewController { self?.firmwareVersionLabel.text = info.version.description case .failure(let error): self?.reset() - let alert = UIAlertController(title: "Error reading YubiKey", message: error.localizedDescription) { } + let alert = UIAlertController(title: String(localized: "Error reading YubiKey"), message: error.localizedDescription) { } self?.present(alert, animated: true, completion: nil) } } diff --git a/Authenticator/UI/YubiKeyConfiguration/ConfigurationWrapper.swift b/Authenticator/UI/YubiKeyConfiguration/ConfigurationWrapper.swift index 8b8811cb..4589bfc0 100644 --- a/Authenticator/UI/YubiKeyConfiguration/ConfigurationWrapper.swift +++ b/Authenticator/UI/YubiKeyConfiguration/ConfigurationWrapper.swift @@ -24,8 +24,8 @@ struct ConfigurationView: View { var body: some View { NavigationView { ConfigurationWrapper() - .navigationTitle("Configuration") - .navigationBarItems(trailing: Button("Close") { + .navigationTitle(String(localized: "Configuration", comment: "Configuration navigation title")) + .navigationBarItems(trailing: Button(String(localized: "Close", comment: "View close button")) { showConfiguration.toggle() }) .ignoresSafeArea(.all, edges: .bottom) diff --git a/Authenticator/UI/YubiKeyConfiguration/OATHConfigurationController.swift b/Authenticator/UI/YubiKeyConfiguration/OATHConfigurationController.swift index 64733f11..41501b6a 100644 --- a/Authenticator/UI/YubiKeyConfiguration/OATHConfigurationController.swift +++ b/Authenticator/UI/YubiKeyConfiguration/OATHConfigurationController.swift @@ -54,7 +54,7 @@ class OATHConfigurationController: UITableViewController { override func viewDidLoad() { super.viewDidLoad() - clearPasswordsOnDeviceLabel.text = "Clear passwords saved on \(UIDevice.current.userInterfaceIdiom == .pad ? "iPad" : "iPhone"). This will prompt for a password next time a password protected YubiKey is used." + clearPasswordsOnDeviceLabel.text = "\(String(localized: "Clear passwords saved on", comment: "Substring from 'Clear passwords saved on [iPad/iPhone]. This will prompt for a passowrd next time a password protected YubiKey is used.'.")) \(UIDevice.current.userInterfaceIdiom == .pad ? "iPad" : "iPhone"). \(String(localized: "This will prompt for a password next time a password protected YubiKey is used", comment: "Substring from 'Clear passwords saved on [iPad/iPhone]. This will prompt for a passowrd next time a password protected YubiKey is used.'."))." } func pause() { @@ -83,15 +83,21 @@ class OATHConfigurationController: UITableViewController { override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { switch (indexPath.section, indexPath.row) { case (0, 2): - self.showWarning(title: "Remove password", message: "Remove password for this YubiKey?", okButtonTitle: "Remove password") { [weak self] () -> Void in + self.showWarning(title: String(localized: "Remove password", comment: "Remove password alert title"), + message: String(localized: "Remove password for this YubiKey?", comment: "Remove password alert message"), + okButtonTitle: String(localized: "Remove password", comment: "Remove password alert button")) { [weak self] () -> Void in self?.removeYubiKeyPassword(currentPassword: nil) } case (1, 1): - self.showWarning(title: "Clear passwords?", message: "Clear passwords saved on iPhone. This will prompt for a password next time a password protected YubiKey is used.", okButtonTitle: "Clear") { [weak self] () -> Void in + self.showWarning(title: String(localized: "Clear passwords?", comment: "Clear password alert title"), + message: String(localized: "Clear passwords saved on iPhone. This will prompt for a password next time a password protected YubiKey is used.", comment: "Clear password alert message"), + okButtonTitle: String(localized: "Clear", comment: "Clear password alert button")) { [weak self] () -> Void in self?.removeStoredPasswords() } case (2, 1): - self.showWarning(title: "Reset YubiKey?", message: "This will delete all accounts and restore factory defaults of your YubiKey.", okButtonTitle: "Reset") { [weak self] () -> Void in + self.showWarning(title: String(localized: "Reset YubiKey?", comment: "Reset YubiKey alert title"), + message: String(localized: "This will delete all accounts and restore factory defaults of your YubiKey.", comment: "Reset YubiKey alert message"), + okButtonTitle: String(localized: "Reset", comment: "Reset YubiKey alert button")) { [weak self] () -> Void in self?.resetOATH() } default: @@ -153,11 +159,15 @@ class OATHConfigurationController: UITableViewController { passwordPreferences.resetPasswordPreferenceForAll() do { try secureStore.removeAllValues() - self.showAlertDialog(title: "Success", message: "Stored passwords have been cleared from this phone.", okHandler: { [weak self] () -> Void in + self.showAlertDialog(title: String(localized: "Success", comment: "Clear passwords confirmation alert title"), + message: String(localized: "Stored passwords have been cleared from this phone.", comment: "Clear passwords confirmation alert message"), + okHandler: { [weak self] () -> Void in self?.dismiss(animated: true, completion: nil) }) } catch { - self.showAlertDialog(title: "Failed to clear passwords", message: error.localizedDescription, okHandler: { [weak self] () -> Void in + self.showAlertDialog(title: String(localized: "Failed to clear passwords", comment: "Clear passwords failure alert title"), + message: error.localizedDescription, + okHandler: { [weak self] () -> Void in self?.dismiss(animated: true, completion: nil) }) } @@ -173,11 +183,11 @@ class OATHConfigurationController: UITableViewController { switch result { case .success(let message): if let message = message { - self.showAlertDialog(title: "Reset complete", message: message) + self.showAlertDialog(title: String(localized: "Reset complete", comment: "Reset YubiKey complete alert title"), message: message) } case .failure(let error): if let message = error { - self.showAlertDialog(title: "Failed to reset YubiKey", message: message) + self.showAlertDialog(title: String(localized: "Failed to reset YubiKey", comment: "Reset YubiKey failure alert title"), message: message) } } } diff --git a/Authenticator/UI/YubiKeyConfiguration/OTPConfigurationController.swift b/Authenticator/UI/YubiKeyConfiguration/OTPConfigurationController.swift index 4cafd98b..e002afc5 100644 --- a/Authenticator/UI/YubiKeyConfiguration/OTPConfigurationController.swift +++ b/Authenticator/UI/YubiKeyConfiguration/OTPConfigurationController.swift @@ -37,8 +37,8 @@ class OTPConfigurationController: UITableViewController { viewModel.setOTPEnabled(enabled: sender.isOn) { error in DispatchQueue.main.async { guard error == nil else { - let alert = UIAlertController(title: "Error writing configuration", message: error?.localizedDescription, preferredStyle: .alert) - let action = UIAlertAction(title: "Ok", style: .default) { _ in + let alert = UIAlertController(title: String(localized: "Error writing configuration", comment: "OTP settings error alert title"), message: error?.localizedDescription, preferredStyle: .alert) + let action = UIAlertAction(title: String(localized: "Ok"), style: .default) { _ in self.dismiss() } alert.addAction(action) diff --git a/Authenticator/UI/YubiKeyConfiguration/SetPasswordViewController.swift b/Authenticator/UI/YubiKeyConfiguration/SetPasswordViewController.swift index dd4cbe9a..fd3d38dc 100644 --- a/Authenticator/UI/YubiKeyConfiguration/SetPasswordViewController.swift +++ b/Authenticator/UI/YubiKeyConfiguration/SetPasswordViewController.swift @@ -46,9 +46,9 @@ class SetPasswordViewController: UITableViewController { @IBAction func savePassword(_ sender: Any) { if !password.hasText && !confirmPassword.hasText { - self.showAlertDialog(title: "Error", message: "Password can not be an empty string") + self.showAlertDialog(title: String(localized: "Error"), message: String(localized: "Password can not be an empty string", comment: "Configuration set password empty password error alert message")) } else if password.text != confirmPassword.text { - self.showAlertDialog(title: "Error", message: "The passwords do not match") + self.showAlertDialog(title: String(localized: "Error"), message: String(localized: "The passwords do not match", comment: "Configuration set password not matching error alert message")) } else { self.changePassword(password: password.text ?? "", oldPassword: nil) } diff --git a/Authenticator/UI/YubiKeyConfiguration/SmartCardConfigurationController.swift b/Authenticator/UI/YubiKeyConfiguration/SmartCardConfigurationController.swift index 634dbf80..a82c532b 100644 --- a/Authenticator/UI/YubiKeyConfiguration/SmartCardConfigurationController.swift +++ b/Authenticator/UI/YubiKeyConfiguration/SmartCardConfigurationController.swift @@ -31,10 +31,12 @@ class SmartCardConfigurationController: UITableViewController { @IBAction func showHelp(sender: Any) { - let alert = UIAlertController(title: "Smart card extension", message: "Other applications can use client certificates on your YubiKey for authentication and signing purposes.", preferredStyle: .alert) - let closeAction = UIAlertAction(title: "Close", style: .cancel) + let alert = UIAlertController(title: String(localized: "Smart card extension", comment: "PIV extension info alert title"), + message: String(localized: "Other applications can use client certificates on your YubiKey for authentication and signing purposes.", comment: "PIV extension info alert message"), + preferredStyle: .alert) + let closeAction = UIAlertAction(title: String(localized: "Close"), style: .cancel) alert.addAction(closeAction) - let readMoreAction = UIAlertAction(title: "Read more...", style: .default) {_ in + let readMoreAction = UIAlertAction(title: String(localized: "Read more...", comment: "PIV extension read more alert title"), style: .default) {_ in if let url = URL(string: "https://www.yubico.com/blog/yubico-pioneers-the-simplification-of-smartcard-support-on-mobile-for-ios/") { UIApplication.shared.open(url) } @@ -75,14 +77,16 @@ class SmartCardConfigurationController: UITableViewController { center.requestAuthorization(options: [.alert, .badge, .sound]) { (granted, error) in if !granted { DispatchQueue.main.async { - let alertController = UIAlertController (title: "Notifications disabled", message: "The smart card extension requires notifications to be enabled for Yubico Authenticator. Enable it in the iOS Settings.", preferredStyle: .alert) + let alertController = UIAlertController (title: String(localized: "Notifications disabled", comment: "PIV extension notifications alert title"), + message: String(localized: "The smart card extension requires notifications to be enabled for Yubico Authenticator. Enable it in the iOS Settings.", comment: "PIV extensions notifications alert message"), + preferredStyle: .alert) - let cancelAction = UIAlertAction(title: "Cancel", style: .default) {_ in + let cancelAction = UIAlertAction(title: String(localized: "Cancel"), style: .default) {_ in self.dismiss(animated: true) } alertController.addAction(cancelAction) - let settingsAction = UIAlertAction(title: "Settings", style: .default) { (_) -> Void in + let settingsAction = UIAlertAction(title: String(localized: "Settings", comment: "PIV extension settings alert title"), style: .default) { (_) -> Void in guard let settingsUrl = URL(string: UIApplication.openSettingsURLString) else { return } @@ -139,7 +143,7 @@ class SmartCardConfigurationController: UITableViewController { func storeTokenCertificate(certificate: SecCertificate) { let error = viewModel.storeTokenCertificate(certificate: certificate) if let error = error { - let alert = UIAlertController(title: "Failed storing certificate", message: "Error: \(error)", completion:{}) + let alert = UIAlertController(title: String(localized: "Failed storing certificate", comment: "PIV extension storing error alert title"), message: "Error: \(error)", completion:{}) self.present(alert, animated: true, completion: nil) } } @@ -162,18 +166,18 @@ class SmartCardConfigurationController: UITableViewController { guard let certificates = certificates else { let cell = tableView.dequeueReusableCell(withIdentifier: "MessageCell", for: indexPath) as! MessageCell - cell.message = "Insert YubiKey or pull down to activate NFC" + cell.message = String(localized: "Insert YubiKey or pull down to activate NFC") return cell } if certificates.count == 0 { let cell = tableView.dequeueReusableCell(withIdentifier: "MessageCell", for: indexPath) as! MessageCell - cell.message = "No certificates on YubiKey" + cell.message = String(localized: "No certificates on YubiKey", comment: "PIV extension no certificates message") return cell } else { let cell = tableView.dequeueReusableCell(withIdentifier: "CertificateCell", for: indexPath) as! CertificateCell let certificate = certificates[indexPath.row - 1] - cell.name = "\(certificate.certificate.commonName ?? "No name") (slot \(String(format: "%02X", certificate.slot.rawValue)))" + cell.name = "\(certificate.certificate.commonName ?? String(localized: "No name", comment: "PIV extension certificate with no name")) (slot \(String(format: "%02X", certificate.slot.rawValue)))" if !tokens.contains(certificate.certificate) { cell.action = { [weak self] in self?.storeTokenCertificate(certificate: certificate.certificate) @@ -193,7 +197,7 @@ class SmartCardConfigurationController: UITableViewController { if tokens.count == 0 { let cell = tableView.dequeueReusableCell(withIdentifier: "MessageCell", for: indexPath) as! MessageCell - cell.message = "No public key certificates in keychain" + cell.message = String(localized: "No public key certificates in keychain", comment: "PIV extension no certs in keychain") return cell } else { let cell = tableView.dequeueReusableCell(withIdentifier: "CertificateCell", for: indexPath) as! CertificateCell @@ -228,12 +232,12 @@ private class HeaderCell: UITableViewCell { switch newValue { case .onYubiKey: icon.image = UIImage(named: "yubikey")?.withConfiguration(configuration) - title.text = "Certificates on YubiKey".uppercased() - text.text = "Certificates on this YubiKey can be used to authenticate and sign requests from other applications if added to this \(device)." + title.text = String(localized: "Certificates on YubiKey", comment: "PIV extension table cell header").uppercased() + text.text = "\(String(localized: "Certificates on this YubiKey can be used to authenticate and sign requests from other applications if added to this", comment: "PIV extension no certs on yubikey message")) \(device)." case .onDevice: icon.image = UIImage(systemName: "iphone", withConfiguration: configuration) - title.text = "Public key certificates on \(device)".uppercased() - text.text = "These certificates have been added to this \(device) and can be used by other applications." + title.text = "\(String(localized: "Public key certificates on", comment: "PIV extension no certs on device message")) \(device)".uppercased() + text.text = "\(String(localized: "These certificates have been added to this", comment: "PIV extension substring in 'These certificates have been added to this [iPad/iPhone] and can be used by other applications'")) \(device) \(String(localized: "and can be used by other applications", comment: "PIV extension substring in 'These certificates have been added to this [iPad/iPhone] and can be used by other applications'"))." } } } @@ -457,11 +461,11 @@ class TableHeaderView: UIView { case .notEnabled: imageView.image = UIImage(systemName: "minus.circle.fill", withConfiguration: configuration) imageView.tintColor = .secondaryLabel - label.text = "Not Enabled".uppercased() + label.text = String(localized: "Not Enabled", comment: "PIV extension not enabled message").uppercased() case .enabled: imageView.image = UIImage(systemName: "checkmark.circle.fill", withConfiguration: configuration) imageView.tintColor = .systemGreen - label.text = "Enabled".uppercased() + label.text = String(localized: "Enabled", comment: "PIV extension enabled message").uppercased() } } } diff --git a/Authenticator/UI/fr.lproj/LaunchScreen.strings b/Authenticator/UI/fr.lproj/LaunchScreen.strings new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/Authenticator/UI/fr.lproj/LaunchScreen.strings @@ -0,0 +1 @@ + diff --git a/Authenticator/UI/fr.lproj/Main.strings b/Authenticator/UI/fr.lproj/Main.strings new file mode 100644 index 00000000..8867efc9 --- /dev/null +++ b/Authenticator/UI/fr.lproj/Main.strings @@ -0,0 +1,243 @@ +/* Class = "UILabel"; text = "One-Time Password"; ObjectID = "1mC-4P-2g3"; */ +"1mC-4P-2g3.text" = "Mot de passe à usage unique"; + +/* Class = "UILabel"; text = "Tap the back button to continue"; ObjectID = "2pK-HU-1WC"; */ +"2pK-HU-1WC.text" = "Appuyer sur Retour pour continuer"; + +/* Class = "UILabel"; text = "Passwords and reset"; ObjectID = "03k-jY-TEC"; */ +"03k-jY-TEC.text" = "Mots de passe et réinitialisation"; + +/* Class = "UILabel"; text = "PASSWORD PROTECTION"; ObjectID = "5iZ-OS-CfM"; */ +"5iZ-OS-CfM.text" = "PROTECTION PAR MOT DE PASSE"; + +/* Class = "UILabel"; text = "1.0"; ObjectID = "6TW-2t-mYb"; */ +"6TW-2t-mYb.text" = "1.0"; + +/* Class = "UITableViewController"; title = "YubiKey configuration"; ObjectID = "09D-Aw-j1I"; */ +"09D-Aw-j1I.title" = "Configuration YubiKey"; + +/* Class = "UILabel"; text = "Privacy policy"; ObjectID = "9lG-2A-fbz"; */ +"9lG-2A-fbz.text" = "Confidentialité"; + +/* Class = "UILabel"; text = "Enabled"; ObjectID = "9lL-ZS-odE"; */ +"9lL-ZS-odE.text" = "Activé"; + +/* Class = "UINavigationItem"; title = "Passwords and reset"; ObjectID = "9NQ-7X-HqZ"; */ +"9NQ-7X-HqZ.title" = "Mots de passe et réinitialisation"; + +/* Class = "UILabel"; text = "Yubico OTP enabled"; ObjectID = "26R-OJ-dML"; */ +"26R-OJ-dML.text" = "Yubico OTP activé"; + +/* Class = "UILabel"; text = "For additional security and to prevent unauthorized access the YubiKey can be password protected."; ObjectID = "46N-qq-yo2"; */ +"46N-qq-yo2.text" = "Pour plus de sécurité et pour empêcher tout accès non autorisé, la YubiKey peut être protégée par mot de passe."; + +/* Class = "UITextField"; placeholder = "Password"; ObjectID = "857-GD-96Q"; */ +"857-GD-96Q.placeholder" = "Mot de passe"; + +/* Class = "UILabel"; text = "Firmware"; ObjectID = "aFH-4H-WRy"; */ +"aFH-4H-WRy.text" = "Firmware"; + +/* Class = "UILabel"; text = "Remove and re-insert your YubiKey"; ObjectID = "AGQ-n1-pV3"; */ +"AGQ-n1-pV3.text" = "Retirez et réinsérez votre YubiKey"; + +/* Class = "UILabel"; text = "Confirm password"; ObjectID = "al9-tv-dIv"; */ +"al9-tv-dIv.text" = "Confirmer mot de passe"; + +/* Class = "UILabel"; text = "ONE-TIME PASSWORD"; ObjectID = "b6z-Ri-5bh"; */ +"b6z-Ri-5bh.text" = "MOT DE PASSE À USAGE UNIQUE"; + +/* Class = "UITableViewController"; title = "YubiKey configuration"; ObjectID = "Bxb-bg-K32"; */ +"Bxb-bg-K32.title" = "Configuration YubiKey"; + +/* Class = "UILabel"; text = "Activate NFC on OTP tag read"; ObjectID = "Byl-RD-bpD"; */ +"Byl-RD-bpD.text" = "Activer NFC lors de la lecture de tags OTP"; + +/* Class = "UITableViewSection"; headerTitle = "Configuration"; ObjectID = "C5n-jq-Mk9"; */ +"C5n-jq-Mk9.headerTitle" = "Configuration"; + +/* Class = "UILabel"; text = "Password"; ObjectID = "Ced-DN-oqW"; */ +"Ced-DN-oqW.text" = "Mot de passe"; + +/* Class = "UILabel"; text = "Disabling Yubico OTP will prevent the YubiKey from appearing as a keyboard. If you don’t use Yubico OTP this is the recommended solution. This can be re-enabled from the settings page."; ObjectID = "cou-Cr-QYP"; */ +"cou-Cr-QYP.text" = "Désactiver Yubico OTP empêchera l'affichage de la YubiKey comme clavier. Si vous n'utilisez pas Yubico OTP, c'est la solution recommandée. Cette fonction peut être réactivée via la page des paramètres."; + +/* Class = "UILabel"; text = "NFC settings"; ObjectID = "D3g-ds-RCu"; */ +"D3g-ds-RCu.text" = "Paramètres NFC"; + +/* Class = "UIBarButtonItem"; title = "Close"; ObjectID = "D6R-wW-EtA"; */ +"D6R-wW-EtA.title" = "Fermer"; + +/* Class = "UILabel"; text = "Remove password"; ObjectID = "dAR-My-Mmm"; */ +"dAR-My-Mmm.text" = "Supprimer mot de passe"; + +/* Class = "UINavigationItem"; title = "Configuration"; ObjectID = "e3s-bq-xAt"; */ +"e3s-bq-xAt.title" = "Configuration"; + +/* Class = "UILabel"; text = "Copyright © 2021 Yubico.\nAll rights reserved."; ObjectID = "Ecy-Pw-sM0"; */ +"Ecy-Pw-sM0.text" = "Copyright© 2021 Yubico.\nTous droits réservés."; + +/* Class = "UILabel"; text = "Initiate NFC at application start"; ObjectID = "Efl-xJ-qER"; */ +"Efl-xJ-qER.text" = "Lancer NFC au démarrage de l'application"; + +/* Class = "UINavigationItem"; title = "Set password"; ObjectID = "eiF-JR-TAC"; */ +"eiF-JR-TAC.title" = "Créer le mot de passe"; + +/* Class = "UINavigationItem"; title = "Smart card extension"; ObjectID = "fl4-8d-lD9"; */ +"fl4-8d-lD9.title" = "Extension carte à puce"; + +/* Class = "UILabel"; text = "SAVED PASSWORDS"; ObjectID = "FMw-TB-KRk"; */ +"FMw-TB-KRk.text" = "MOTS DE PASSE ENREGISTRÉS"; + +/* Class = "UILabel"; text = "Bypass touch requirement"; ObjectID = "frN-Of-d1s"; */ +"frN-Of-d1s.text" = "Contourner les exigences tactiles"; + +/* Class = "UILabel"; text = "RESET YUBIKEY"; ObjectID = "gAN-p5-fcQ"; */ +"gAN-p5-fcQ.text" = "RÉINITIALISER YUBIKEY"; + +/* Class = "UILabel"; text = "Version history"; ObjectID = "ghF-dC-3d6"; */ +"ghF-dC-3d6.text" = "Historique des versions"; + +/* Class = "UITableViewSection"; footerTitle = "Initiate NFC at application start will automatically read your YubiKey as soon as the app becomes active."; ObjectID = "gQR-ie-6Y0"; */ +"gQR-ie-6Y0.footerTitle" = "L'activation NFC au démarrage de l'application permet de lire automatiquement votre YubiKey."; + +/* Class = "UILabel"; text = "Clear passwords saved on iPhone. This will prompt for a password next time a password protected YubiKey is used."; ObjectID = "gYP-vW-fFN"; */ +"gYP-vW-fFN.text" = "Effacez les mots de passe enregistrés sur l'iPhone. Un mot de passe sera requis lors de la prochaine utilisation d'une YubiKey protégée par mot de passe."; + +/* Class = "UIBarButtonItem"; title = "Item"; ObjectID = "hBA-XE-Ib1"; */ +"hBA-XE-Ib1.title" = "Élément"; + +/* Class = "UINavigationItem"; title = "About"; ObjectID = "Hbq-O7-HqW"; */ +"Hbq-O7-HqW.title" = "Infos"; + +/* Class = "UITableViewSection"; footerTitle = "For additional security and to prevent unauthorized access the YubiKey can be protected with a password"; ObjectID = "hOr-gJ-fIa"; */ +"hOr-gJ-fIa.footerTitle" = "Pour plus de sécurité et empêcher tout accès non autorisé, la YubiKey peut être protégée par un mot de passe"; + +/* Class = "UILabel"; text = "Copy OTP to clipboard"; ObjectID = "hsz-tV-DPW"; */ +"hsz-tV-DPW.text" = "Copier OTP dans presse-papiers"; + +/* Class = "UILabel"; text = "Yubico OTP has been disabled"; ObjectID = "Icc-EW-Cgh"; */ +"Icc-EW-Cgh.text" = "Yubico OTP désactivé"; + +/* Class = "UILabel"; text = "Smart card extension"; ObjectID = "iH3-4d-Rv5"; */ +"iH3-4d-Rv5.text" = "Extension carte à puce"; + +/* Class = "UINavigationItem"; title = "Toggle One-Time Password"; ObjectID = "Inc-aD-fdW"; */ +"Inc-aD-fdW.title" = "Activer OTP"; + +/* Class = "UILabel"; text = "This YubiKey has Yubico OTP enabled which makes it appear as an external keyboard to the iPhone. Unfortunately this causes problem with the normal on-screen keyboard."; ObjectID = "JN3-vC-kaK"; */ +"JN3-vC-kaK.text" = "Yubico OTP étant activé, cette YubiKey apparaît comme clavier externe pour iPhone. Cela pose problème avec le clavier à l'écran normal."; + +/* Class = "UIBarButtonItem"; title = "Close"; ObjectID = "jNG-Du-Ghz"; */ +"jNG-Du-Ghz.title" = "Fermer"; + +/* Class = "UITextField"; placeholder = "Smart card (PIV) PIN"; ObjectID = "JON-gB-7WG"; */ +"JON-gB-7WG.placeholder" = "PIN carte à puce (PIV)"; + +/* Class = "UILabel"; text = "While the YubiKey is inserted the on-screen keyboard will not appear. To show the keyboard you will have to remove the YubiKey and then re-insert it."; ObjectID = "JQM-z3-Kvc"; */ +"JQM-z3-Kvc.text" = "Lorsque vous insérez la YubiKey, le clavier à l'écran n'apparaît pas. Pour afficher le clavier, vous devez retirer la YubiKey, puis la réinsérer."; + +/* Class = "UITableViewSection"; footerTitle = "Start NFC and read OATH accounts when the application has been opened by reading the OTP tag on a YubiKey."; ObjectID = "JSq-rh-zB3"; */ +"JSq-rh-zB3.footerTitle" = "Lancez NFC et lisez les comptes OATH lorsque l'application a été ouverte en lisant le tag OTP sur une YubiKey."; + +/* Class = "UILabel"; text = "Clear saved passwords"; ObjectID = "jx7-Be-qMk"; */ +"jx7-Be-qMk.text" = "Effacer les mots de passe enregistrés"; + +/* Class = "UIButton"; configuration.title = "Continue with limited usability"; ObjectID = "kAX-Sn-d4r"; */ +"kAX-Sn-d4r.configuration.title" = "Continuer avec fonctionnalité limitée"; + +/* Class = "UIButton"; normalTitle = "Button"; ObjectID = "kAX-Sn-d4r"; */ +"kAX-Sn-d4r.normalTitle" = "Bouton"; + +/* Class = "UILabel"; text = "or"; ObjectID = "L2j-ZW-Jbf"; */ +"L2j-ZW-Jbf.text" = "ou"; + +/* Class = "UILabel"; text = "Device type"; ObjectID = "llv-60-0FB"; */ +"llv-60-0FB.text" = "Type d'appareil"; + +/* Class = "UILabel"; text = "Serial number"; ObjectID = "Lzm-p7-Lmb"; */ +"Lzm-p7-Lmb.text" = "Numéro de série"; + +/* Class = "UILabel"; text = "N/A"; ObjectID = "MBv-4M-eos"; */ +"MBv-4M-eos.text" = "S/O"; + +/* Class = "UILabel"; text = "Help with YubiKey"; ObjectID = "NnL-eZ-nHd"; */ +"NnL-eZ-nHd.text" = "Aide YubiKey"; + +/* Class = "UILabel"; text = "Insert a YubiKey and enter its PIN to access the certificate."; ObjectID = "noy-hK-f0E"; */ +"noy-hK-f0E.text" = "Insérez une YubiKey et saisissez son PIN pour accéder au certificat."; + +/* Class = "UILabel"; text = "Unlock YubiKey"; ObjectID = "O2N-dk-eMF"; */ +"O2N-dk-eMF.text" = "Débloquer YubiKey"; + +/* Class = "UILabel"; text = "Set password"; ObjectID = "Oba-Qw-cTB"; */ +"Oba-Qw-cTB.text" = "Créer le mot de passe"; + +/* Class = "UITableViewSection"; footerTitle = "Copy OTP automatically to clipboard when a YubiKey has been scanned using the NFC tag functionality."; ObjectID = "oy6-QK-Bgw"; */ +"oy6-QK-Bgw.footerTitle" = "Copiez l'OTP automatiquement dans le presse-papiers lorsqu'une YubiKey est scannée à l'aide de la fonctionnalité de tags NFC."; + +/* Class = "UINavigationItem"; title = "NFC settings"; ObjectID = "PCq-PC-KyX"; */ +"PCq-PC-KyX.title" = "Paramètres NFC"; + +/* Class = "UILabel"; text = "N/A"; ObjectID = "QGj-16-s0W"; */ +"QGj-16-s0W.text" = "S/O"; + +/* Class = "UILabel"; text = "Terms of use"; ObjectID = "QHB-fS-VBc"; */ +"QHB-fS-VBc.text" = "Conditions d'utilisation"; + +/* Class = "UITableViewSection"; headerTitle = "Application"; ObjectID = "raA-qu-ETm"; */ +"raA-qu-ETm.headerTitle" = "Application"; + +/* Class = "UILabel"; text = "Insert YubiKey or pull down to activate NFC"; ObjectID = "Re8-TR-xIr"; */ +"Re8-TR-xIr.text" = "Insérez la YubiKey ou tirez vers le bas pour activer NFC"; + +/* Class = "UIButton"; normalTitle = "UnwindButton"; ObjectID = "Szl-yL-4ir"; */ +"Szl-yL-4ir.normalTitle" = "Bouton déroulement"; + +/* Class = "UILabel"; text = "Contact support"; ObjectID = "tMr-aW-Doe"; */ +"tMr-aW-Doe.text" = "Contacter l'assistance"; + +/* Class = "UILabel"; text = "Toggle One-Time Password"; ObjectID = "uP5-O2-d0d"; */ +"uP5-O2-d0d.text" = "Activer OTP"; + +/* Class = "UITableViewSection"; footerTitle = "Accounts that require touch will need an extra NFC tap to calculate its code. Bypassing it minimizes the number of NFC taps needed."; ObjectID = "Uvq-Ba-xiH"; */ +"Uvq-Ba-xiH.footerTitle" = "Les comptes tactiles nécessitent un rapprochement de la clef en NFC de plus pour calculer leur code. Le contournement réduit le nombre de rapprochements en NFC requis."; + +/* Class = "UILabel"; text = "N/A"; ObjectID = "VAw-dv-zeA"; */ +"VAw-dv-zeA.text" = "S/O"; + +/* Class = "UILabel"; text = "Reset YubiKey"; ObjectID = "Vb7-1M-PWz"; */ +"Vb7-1M-PWz.text" = "Réinitialiser la YubiKey"; + +/* Class = "UILabel"; text = "Yubico Authenticator"; ObjectID = "VHQ-4i-YEj"; */ +"VHQ-4i-YEj.text" = "Yubico Authenticator"; + +/* Class = "UILabel"; text = "Turn on/off opening Safari to copy your OTP when scanning the NFC YubiKey."; ObjectID = "vjs-4B-RzZ"; */ +"vjs-4B-RzZ.text" = "Activez/désactivez l'ouverture de Safari pour copier votre OTP lors du scan de la YubiKey NFC."; + +/* Class = "UITableViewSection"; headerTitle = "Support"; ObjectID = "vn9-zq-1Ri"; */ +"vn9-zq-1Ri.headerTitle" = "Assistance"; + +/* Class = "UILabel"; text = "Enter the PIN, then tap a NFC enabled YubiKey against the iPhone to access the certificate."; ObjectID = "WGy-0e-K7w"; */ +"WGy-0e-K7w.text" = "Saisissez le PIN, puis apposez une YubiKey NFC sur l'iPhone pour accéder au certificat."; + +/* Class = "UITextField"; placeholder = "Password"; ObjectID = "wH4-5g-AV5"; */ +"wH4-5g-AV5.placeholder" = "Mot de passe"; + +/* Class = "UILabel"; text = "Licensing"; ObjectID = "wvt-LS-lIS"; */ +"wvt-LS-lIS.text" = "Licences"; + +/* Class = "UILabel"; text = "How does it work"; ObjectID = "y0i-iX-KLv"; */ +"y0i-iX-KLv.text" = "Fonctionnement"; + +/* Class = "UITableViewSection"; headerTitle = "INFORMATION"; ObjectID = "yed-kd-amP"; */ +"yed-kd-amP.headerTitle" = "INFORMATIONS"; + +/* Class = "UIButton"; configuration.title = "Disable Yubico OTP (recommended)"; ObjectID = "Yo4-ef-tkZ"; */ +"Yo4-ef-tkZ.configuration.title" = "Désactiver Yubico OTP (recommandé)"; + +/* Class = "UIButton"; normalTitle = "Button"; ObjectID = "Yo4-ef-tkZ"; */ +"Yo4-ef-tkZ.normalTitle" = "Bouton"; + +/* Class = "UILabel"; text = "Reset all accounts stored on YubiKey, make sure they are not in use anywhere before doing this."; ObjectID = "zcT-oY-vKq"; */ +"zcT-oY-vKq.text" = "Réinitialisez tous les comptes de la YubiKey. Ils ne doivent pas être utilisés avant cette opération."; + diff --git a/Authenticator/UI/ja.lproj/LaunchScreen.strings b/Authenticator/UI/ja.lproj/LaunchScreen.strings new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/Authenticator/UI/ja.lproj/LaunchScreen.strings @@ -0,0 +1 @@ + diff --git a/Authenticator/UI/ja.lproj/Main.strings b/Authenticator/UI/ja.lproj/Main.strings new file mode 100644 index 00000000..25f95f05 --- /dev/null +++ b/Authenticator/UI/ja.lproj/Main.strings @@ -0,0 +1,243 @@ +/* Class = "UILabel"; text = "One-Time Password"; ObjectID = "1mC-4P-2g3"; */ +"1mC-4P-2g3.text" = "ワンタイムパスワード"; + +/* Class = "UILabel"; text = "Tap the back button to continue"; ObjectID = "2pK-HU-1WC"; */ +"2pK-HU-1WC.text" = "戻るボタンをタップして続行します"; + +/* Class = "UILabel"; text = "Passwords and reset"; ObjectID = "03k-jY-TEC"; */ +"03k-jY-TEC.text" = "パスワードとリセット"; + +/* Class = "UILabel"; text = "PASSWORD PROTECTION"; ObjectID = "5iZ-OS-CfM"; */ +"5iZ-OS-CfM.text" = "パスワード保護"; + +/* Class = "UILabel"; text = "1.0"; ObjectID = "6TW-2t-mYb"; */ +"6TW-2t-mYb.text" = "1.0"; + +/* Class = "UITableViewController"; title = "YubiKey configuration"; ObjectID = "09D-Aw-j1I"; */ +"09D-Aw-j1I.title" = "YubiKey設定"; + +/* Class = "UILabel"; text = "Privacy policy"; ObjectID = "9lG-2A-fbz"; */ +"9lG-2A-fbz.text" = "プライバシーポリシー"; + +/* Class = "UILabel"; text = "Enabled"; ObjectID = "9lL-ZS-odE"; */ +"9lL-ZS-odE.text" = "有効"; + +/* Class = "UINavigationItem"; title = "Passwords and reset"; ObjectID = "9NQ-7X-HqZ"; */ +"9NQ-7X-HqZ.title" = "パスワードとリセット"; + +/* Class = "UILabel"; text = "Yubico OTP enabled"; ObjectID = "26R-OJ-dML"; */ +"26R-OJ-dML.text" = "Yubico OTP有効"; + +/* Class = "UILabel"; text = "For additional security and to prevent unauthorized access the YubiKey can be password protected."; ObjectID = "46N-qq-yo2"; */ +"46N-qq-yo2.text" = "セキュリティを強化し、不正アクセスを防止するために、YubiKeyをパスワードで保護できます。"; + +/* Class = "UITextField"; placeholder = "Password"; ObjectID = "857-GD-96Q"; */ +"857-GD-96Q.placeholder" = "パスワード"; + +/* Class = "UILabel"; text = "Firmware"; ObjectID = "aFH-4H-WRy"; */ +"aFH-4H-WRy.text" = "ファームウェア"; + +/* Class = "UILabel"; text = "Remove and re-insert your YubiKey"; ObjectID = "AGQ-n1-pV3"; */ +"AGQ-n1-pV3.text" = "YubiKeyを取り外して再挿入してください"; + +/* Class = "UILabel"; text = "Confirm password"; ObjectID = "al9-tv-dIv"; */ +"al9-tv-dIv.text" = "パスワードを確認"; + +/* Class = "UILabel"; text = "ONE-TIME PASSWORD"; ObjectID = "b6z-Ri-5bh"; */ +"b6z-Ri-5bh.text" = "ワンタイムパスワード"; + +/* Class = "UITableViewController"; title = "YubiKey configuration"; ObjectID = "Bxb-bg-K32"; */ +"Bxb-bg-K32.title" = "YubiKey設定"; + +/* Class = "UILabel"; text = "Activate NFC on OTP tag read"; ObjectID = "Byl-RD-bpD"; */ +"Byl-RD-bpD.text" = "OTPタグ読み取りでNFCをアクティブにする"; + +/* Class = "UITableViewSection"; headerTitle = "Configuration"; ObjectID = "C5n-jq-Mk9"; */ +"C5n-jq-Mk9.headerTitle" = "設定"; + +/* Class = "UILabel"; text = "Password"; ObjectID = "Ced-DN-oqW"; */ +"Ced-DN-oqW.text" = "パスワード"; + +/* Class = "UILabel"; text = "Disabling Yubico OTP will prevent the YubiKey from appearing as a keyboard. If you don’t use Yubico OTP this is the recommended solution. This can be re-enabled from the settings page."; ObjectID = "cou-Cr-QYP"; */ +"cou-Cr-QYP.text" = "Yubico OTPを無効にすると、YubiKeyがキーボードとして表示されなくなります。Yubico OTPを使用しない場合は、これが推奨される解決策です。Yubico OTPは、設定ページから再度有効にできます。"; + +/* Class = "UILabel"; text = "NFC settings"; ObjectID = "D3g-ds-RCu"; */ +"D3g-ds-RCu.text" = "NFC設定"; + +/* Class = "UIBarButtonItem"; title = "Close"; ObjectID = "D6R-wW-EtA"; */ +"D6R-wW-EtA.title" = "閉じる"; + +/* Class = "UILabel"; text = "Remove password"; ObjectID = "dAR-My-Mmm"; */ +"dAR-My-Mmm.text" = "パスワードを削除"; + +/* Class = "UINavigationItem"; title = "Configuration"; ObjectID = "e3s-bq-xAt"; */ +"e3s-bq-xAt.title" = "設定"; + +/* Class = "UILabel"; text = "Copyright © 2021 Yubico.\nAll rights reserved."; ObjectID = "Ecy-Pw-sM0"; */ +"Ecy-Pw-sM0.text" = "Copyright © 2021 Yubico.\n無断複写・転載を禁じます。"; + +/* Class = "UILabel"; text = "Initiate NFC at application start"; ObjectID = "Efl-xJ-qER"; */ +"Efl-xJ-qER.text" = "アプリケーションの起動時にNFCを開始"; + +/* Class = "UINavigationItem"; title = "Set password"; ObjectID = "eiF-JR-TAC"; */ +"eiF-JR-TAC.title" = "パスワードを設定"; + +/* Class = "UINavigationItem"; title = "Smart card extension"; ObjectID = "fl4-8d-lD9"; */ +"fl4-8d-lD9.title" = "スマートカード拡張機能"; + +/* Class = "UILabel"; text = "SAVED PASSWORDS"; ObjectID = "FMw-TB-KRk"; */ +"FMw-TB-KRk.text" = "保存されたパスワード"; + +/* Class = "UILabel"; text = "Bypass touch requirement"; ObjectID = "frN-Of-d1s"; */ +"frN-Of-d1s.text" = "タッチ要件をスキップ"; + +/* Class = "UILabel"; text = "RESET YUBIKEY"; ObjectID = "gAN-p5-fcQ"; */ +"gAN-p5-fcQ.text" = "YubiKeyをリセット"; + +/* Class = "UILabel"; text = "Version history"; ObjectID = "ghF-dC-3d6"; */ +"ghF-dC-3d6.text" = "バージョン履歴"; + +/* Class = "UITableViewSection"; footerTitle = "Initiate NFC at application start will automatically read your YubiKey as soon as the app becomes active."; ObjectID = "gQR-ie-6Y0"; */ +"gQR-ie-6Y0.footerTitle" = "アプリケーションの起動時にNFCを開始すると、アプリがアクティブになると同時にYubiKeyが自動で読み込まれます。"; + +/* Class = "UILabel"; text = "Clear passwords saved on iPhone. This will prompt for a password next time a password protected YubiKey is used."; ObjectID = "gYP-vW-fFN"; */ +"gYP-vW-fFN.text" = "iPhoneに保存されているパスワードを消去します。これにより、パスワードで保護されたYubiKeyの次回使用時にパスワードの入力を求められます。"; + +/* Class = "UIBarButtonItem"; title = "Item"; ObjectID = "hBA-XE-Ib1"; */ +"hBA-XE-Ib1.title" = "アイテム"; + +/* Class = "UINavigationItem"; title = "About"; ObjectID = "Hbq-O7-HqW"; */ +"Hbq-O7-HqW.title" = "概要"; + +/* Class = "UITableViewSection"; footerTitle = "For additional security and to prevent unauthorized access the YubiKey can be protected with a password"; ObjectID = "hOr-gJ-fIa"; */ +"hOr-gJ-fIa.footerTitle" = "セキュリティを強化し、不正アクセスを防止するために、YubiKeyをパスワードで保護できます"; + +/* Class = "UILabel"; text = "Copy OTP to clipboard"; ObjectID = "hsz-tV-DPW"; */ +"hsz-tV-DPW.text" = "OTPをクリップボードにコピー"; + +/* Class = "UILabel"; text = "Yubico OTP has been disabled"; ObjectID = "Icc-EW-Cgh"; */ +"Icc-EW-Cgh.text" = "Yubico OTPが無効になっています"; + +/* Class = "UILabel"; text = "Smart card extension"; ObjectID = "iH3-4d-Rv5"; */ +"iH3-4d-Rv5.text" = "スマートカード拡張機能"; + +/* Class = "UINavigationItem"; title = "Toggle One-Time Password"; ObjectID = "Inc-aD-fdW"; */ +"Inc-aD-fdW.title" = "ワンタイムパスワードを切り替える"; + +/* Class = "UILabel"; text = "This YubiKey has Yubico OTP enabled which makes it appear as an external keyboard to the iPhone. Unfortunately this causes problem with the normal on-screen keyboard."; ObjectID = "JN3-vC-kaK"; */ +"JN3-vC-kaK.text" = "このYubiKeyはYubico OTPが有効になっているため、iPhoneへの外付けキーボードとして表示されます。これが原因で、標準のオンスクリーンキーボードで問題が発生します。"; + +/* Class = "UIBarButtonItem"; title = "Close"; ObjectID = "jNG-Du-Ghz"; */ +"jNG-Du-Ghz.title" = "閉じる"; + +/* Class = "UITextField"; placeholder = "Smart card (PIV) PIN"; ObjectID = "JON-gB-7WG"; */ +"JON-gB-7WG.placeholder" = "スマートカード(PIV)PIN"; + +/* Class = "UILabel"; text = "While the YubiKey is inserted the on-screen keyboard will not appear. To show the keyboard you will have to remove the YubiKey and then re-insert it."; ObjectID = "JQM-z3-Kvc"; */ +"JQM-z3-Kvc.text" = "YubiKeyが挿入されている間は、オンスクリーンキーボードが表示されません。キーボードを表示するにはYubiKeyを取り外し、その後再挿入する必要があります。"; + +/* Class = "UITableViewSection"; footerTitle = "Start NFC and read OATH accounts when the application has been opened by reading the OTP tag on a YubiKey."; ObjectID = "JSq-rh-zB3"; */ +"JSq-rh-zB3.footerTitle" = "YubiKeyのOTPタグを読み取ってアプリケーションを開いた際にNFCを開始し、OATHアカウントを読み取ります。"; + +/* Class = "UILabel"; text = "Clear saved passwords"; ObjectID = "jx7-Be-qMk"; */ +"jx7-Be-qMk.text" = "保存したパスワードを消去"; + +/* Class = "UIButton"; configuration.title = "Continue with limited usability"; ObjectID = "kAX-Sn-d4r"; */ +"kAX-Sn-d4r.configuration.title" = "使用制限ありで続行"; + +/* Class = "UIButton"; normalTitle = "Button"; ObjectID = "kAX-Sn-d4r"; */ +"kAX-Sn-d4r.normalTitle" = "ボタン"; + +/* Class = "UILabel"; text = "or"; ObjectID = "L2j-ZW-Jbf"; */ +"L2j-ZW-Jbf.text" = "または"; + +/* Class = "UILabel"; text = "Device type"; ObjectID = "llv-60-0FB"; */ +"llv-60-0FB.text" = "デバイスタイプ"; + +/* Class = "UILabel"; text = "Serial number"; ObjectID = "Lzm-p7-Lmb"; */ +"Lzm-p7-Lmb.text" = "シリアル番号"; + +/* Class = "UILabel"; text = "N/A"; ObjectID = "MBv-4M-eos"; */ +"MBv-4M-eos.text" = "N/A"; + +/* Class = "UILabel"; text = "Help with YubiKey"; ObjectID = "NnL-eZ-nHd"; */ +"NnL-eZ-nHd.text" = "YubiKeyのヘルプ"; + +/* Class = "UILabel"; text = "Insert a YubiKey and enter its PIN to access the certificate."; ObjectID = "noy-hK-f0E"; */ +"noy-hK-f0E.text" = "証明書にアクセスするには、YubiKeyを挿入し、そのPINを入力してください。"; + +/* Class = "UILabel"; text = "Unlock YubiKey"; ObjectID = "O2N-dk-eMF"; */ +"O2N-dk-eMF.text" = "YubiKeyのロックを解除"; + +/* Class = "UILabel"; text = "Set password"; ObjectID = "Oba-Qw-cTB"; */ +"Oba-Qw-cTB.text" = "パスワードを設定"; + +/* Class = "UITableViewSection"; footerTitle = "Copy OTP automatically to clipboard when a YubiKey has been scanned using the NFC tag functionality."; ObjectID = "oy6-QK-Bgw"; */ +"oy6-QK-Bgw.footerTitle" = "YubiKeyがNFCタグ機能を使用してスキャンされた場合に、OTPをクリップボードに自動でコピーします。"; + +/* Class = "UINavigationItem"; title = "NFC settings"; ObjectID = "PCq-PC-KyX"; */ +"PCq-PC-KyX.title" = "NFC設定"; + +/* Class = "UILabel"; text = "N/A"; ObjectID = "QGj-16-s0W"; */ +"QGj-16-s0W.text" = "N/A"; + +/* Class = "UILabel"; text = "Terms of use"; ObjectID = "QHB-fS-VBc"; */ +"QHB-fS-VBc.text" = "利用規約"; + +/* Class = "UITableViewSection"; headerTitle = "Application"; ObjectID = "raA-qu-ETm"; */ +"raA-qu-ETm.headerTitle" = "アプリケーション"; + +/* Class = "UILabel"; text = "Insert YubiKey or pull down to activate NFC"; ObjectID = "Re8-TR-xIr"; */ +"Re8-TR-xIr.text" = "YubiKeyを挿入してください。またはプルダウンしてNFCを有効にしてください。"; + +/* Class = "UIButton"; normalTitle = "UnwindButton"; ObjectID = "Szl-yL-4ir"; */ +"Szl-yL-4ir.normalTitle" = "UnwindButton"; + +/* Class = "UILabel"; text = "Contact support"; ObjectID = "tMr-aW-Doe"; */ +"tMr-aW-Doe.text" = "サポートへのお問い合わせ"; + +/* Class = "UILabel"; text = "Toggle One-Time Password"; ObjectID = "uP5-O2-d0d"; */ +"uP5-O2-d0d.text" = "ワンタイムパスワードを切り替える"; + +/* Class = "UITableViewSection"; footerTitle = "Accounts that require touch will need an extra NFC tap to calculate its code. Bypassing it minimizes the number of NFC taps needed."; ObjectID = "Uvq-Ba-xiH"; */ +"Uvq-Ba-xiH.footerTitle" = "タッチが必要なアカウントでは、コードを計算するために追加のNFCタップが必要です。これをスキップすることで、必要なNFCタップの数が最小限に抑えられます。"; + +/* Class = "UILabel"; text = "N/A"; ObjectID = "VAw-dv-zeA"; */ +"VAw-dv-zeA.text" = "N/A"; + +/* Class = "UILabel"; text = "Reset YubiKey"; ObjectID = "Vb7-1M-PWz"; */ +"Vb7-1M-PWz.text" = "YubiKeyをリセット"; + +/* Class = "UILabel"; text = "Yubico Authenticator"; ObjectID = "VHQ-4i-YEj"; */ +"VHQ-4i-YEj.text" = "Yubico Authenticator"; + +/* Class = "UILabel"; text = "Turn on/off opening Safari to copy your OTP when scanning the NFC YubiKey."; ObjectID = "vjs-4B-RzZ"; */ +"vjs-4B-RzZ.text" = "NFC YubiKeyのスキャン時にOTPをコピーするには、Safariを開く操作のオン/オフを切り替えてください。"; + +/* Class = "UITableViewSection"; headerTitle = "Support"; ObjectID = "vn9-zq-1Ri"; */ +"vn9-zq-1Ri.headerTitle" = "サポート"; + +/* Class = "UILabel"; text = "Enter the PIN, then tap a NFC enabled YubiKey against the iPhone to access the certificate."; ObjectID = "WGy-0e-K7w"; */ +"WGy-0e-K7w.text" = "証明書にアクセスするには、PINを入力してから、iPhoneに対してNFC対応のYubiKeyをタップしてください。"; + +/* Class = "UITextField"; placeholder = "Password"; ObjectID = "wH4-5g-AV5"; */ +"wH4-5g-AV5.placeholder" = "パスワード"; + +/* Class = "UILabel"; text = "Licensing"; ObjectID = "wvt-LS-lIS"; */ +"wvt-LS-lIS.text" = "ライセンス"; + +/* Class = "UILabel"; text = "How does it work"; ObjectID = "y0i-iX-KLv"; */ +"y0i-iX-KLv.text" = "動作の仕組み"; + +/* Class = "UITableViewSection"; headerTitle = "INFORMATION"; ObjectID = "yed-kd-amP"; */ +"yed-kd-amP.headerTitle" = "情報"; + +/* Class = "UIButton"; configuration.title = "Disable Yubico OTP (recommended)"; ObjectID = "Yo4-ef-tkZ"; */ +"Yo4-ef-tkZ.configuration.title" = "Yubico OTPを無効にする(推奨)"; + +/* Class = "UIButton"; normalTitle = "Button"; ObjectID = "Yo4-ef-tkZ"; */ +"Yo4-ef-tkZ.normalTitle" = "ボタン"; + +/* Class = "UILabel"; text = "Reset all accounts stored on YubiKey, make sure they are not in use anywhere before doing this."; ObjectID = "zcT-oY-vKq"; */ +"zcT-oY-vKq.text" = "YubiKeyに保存されているすべてのアカウントをリセットします。この操作を行う前に、アカウントが一切使用されていないことを確認してください。"; + diff --git a/Authenticator/VersionHistory.plist b/Authenticator/VersionHistory.plist index fe10859e..c0015a17 100644 --- a/Authenticator/VersionHistory.plist +++ b/Authenticator/VersionHistory.plist @@ -2,6 +2,18 @@ + + version + 1.7.10 + date + 2024-09-01T09:41:00Z + shouldPromptUser + + changes + + Support for French and Japanese added to this version of the Yubico Authenticator. + + version 1.7.9 diff --git a/Localizations/en.xcloc/Localized Contents/en.xliff b/Localizations/en.xcloc/Localized Contents/en.xliff new file mode 100644 index 00000000..df4c0ace --- /dev/null +++ b/Localizations/en.xcloc/Localized Contents/en.xliff @@ -0,0 +1,623 @@ + + + +
+ +
+ + + Authenticator + Authenticator + Bundle name + + + The application needs access to NFC reading to communicate with your Yubikey. + The application needs access to NFC reading to communicate with your Yubikey. + Privacy - NFC Scan Usage Description + + + The application needs access to Camera to scan QR codes. + The application needs access to Camera to scan QR codes. + Privacy - Camera Usage Description + + + The application needs access to Face ID to unlock your password vault. + The application needs access to Face ID to unlock your password vault. + Privacy - Face ID Usage Description + + +
+ +
+ +
+ + + *** *** + *** *** + No comment provided by engineer. + + + 888 888 + 888 888 + No comment provided by engineer. + + + ? + ? + No comment provided by engineer. + + + Accounts + Accounts + No comment provided by engineer. + + + Cancel + Cancel + No comment provided by engineer. + + + Continue with limited usability + Continue with limited usability + No comment provided by engineer. + + + Data to String conversion error + Data to String conversion error + No comment provided by engineer. + + + Delete + Delete + No comment provided by engineer. + + + Delete account? + Delete account? + No comment provided by engineer. + + + Disable Yubico OTP (recommended) + Disable Yubico OTP (recommended) + No comment provided by engineer. + + + Disabling Yubico OTP will prevent the YubiKey from appearing as a keyboard. If you don’t use Yubico OTP this is the recommended solution. This can be re-enabled from the settings page. + Disabling Yubico OTP will prevent the YubiKey from appearing as a keyboard. If you don’t use Yubico OTP this is the recommended solution. This can be re-enabled from the settings page. + No comment provided by engineer. + + + Failed to cast object to Data error + Failed to cast object to Data error + No comment provided by engineer. + + + Invalid URI format + Invalid URI format + Invalid Uri, wrong parameters + + + Item not found in secure storage + Item not found in secure storage + No comment provided by engineer. + + + Other + Other + No comment provided by engineer. + + + Pinned + Pinned + No comment provided by engineer. + + + Plug-in your YubiKey for that operation + Plug-in your YubiKey for that operation + No service found + + + Remove and re-insert your YubiKey + Remove and re-insert your YubiKey + No comment provided by engineer. + + + Some content... + Some content... + No comment provided by engineer. + + + Something went wrong and key doesn't respond + Something went wrong and key doesn't respond + No response + + + String to Data conversion error + String to Data conversion error + No comment provided by engineer. + + + The key doesn't respond + The key doesn't respond + Timeout issue + + + This QR code is not supported + This QR code is not supported + Invalid Uri format, not OATH URL + + + This YubiKey has Yubico OTP enabled which makes it appear as an external keyboard to the iPhone. Unfortunately this causes problem with the normal on-screen keyboard. + This YubiKey has Yubico OTP enabled which makes it appear as an external keyboard to the iPhone. Unfortunately this causes problem with the normal on-screen keyboard. + No comment provided by engineer. + + + This version of iOS does not support operations with the YubiKey for Lightning nor over NFC + This version of iOS does not support operations with the YubiKey for Lightning nor over NFC + Not supported + + + This will permanently delete the account from the YubiKey, and your ability to generate codes for it! + This will permanently delete the account from the YubiKey, and your ability to generate codes for it! + No comment provided by engineer. + + + Unhandled Error + Unhandled Error + No comment provided by engineer. + + + While the YubiKey is inserted the on-screen keyboard will not appear. To show the keyboard you will have to remove the YubiKey and then re-insert it. + While the YubiKey is inserted the on-screen keyboard will not appear. To show the keyboard you will have to remove the YubiKey and then re-insert it. + No comment provided by engineer. + + + Yubico OTP + Yubico OTP + No comment provided by engineer. + + + Yubico OTP enabled + Yubico OTP enabled + No comment provided by engineer. + + + Yubico OTP has been disabled + Yubico OTP has been disabled + No comment provided by engineer. + + +
+ +
+ +
+ + + One-Time Password + One-Time Password + Class = "UILabel"; text = "One-Time Password"; ObjectID = "1mC-4P-2g3"; + + + Tap the back button to continue + Tap the back button to continue + Class = "UILabel"; text = "Tap the back button to continue"; ObjectID = "2pK-HU-1WC"; + + + Passwords and reset + Passwords and reset + Class = "UILabel"; text = "Passwords and reset"; ObjectID = "03k-jY-TEC"; + + + PASSWORD PROTECTION + PASSWORD PROTECTION + Class = "UILabel"; text = "PASSWORD PROTECTION"; ObjectID = "5iZ-OS-CfM"; + + + 1.0 + 1.0 + Class = "UILabel"; text = "1.0"; ObjectID = "6TW-2t-mYb"; + + + YubiKey configuration + YubiKey configuration + Class = "UITableViewController"; title = "YubiKey configuration"; ObjectID = "09D-Aw-j1I"; + + + Passwords and reset + Passwords and reset + Class = "UINavigationItem"; title = "Passwords and reset"; ObjectID = "9NQ-7X-HqZ"; + + + Privacy policy + Privacy policy + Class = "UILabel"; text = "Privacy policy"; ObjectID = "9lG-2A-fbz"; + + + Enabled + Enabled + Class = "UILabel"; text = "Enabled"; ObjectID = "9lL-ZS-odE"; + + + Yubico OTP enabled + Yubico OTP enabled + Class = "UILabel"; text = "Yubico OTP enabled"; ObjectID = "26R-OJ-dML"; + + + For additional security and to prevent unauthorized access the YubiKey can be password protected. + For additional security and to prevent unauthorized access the YubiKey can be password protected. + Class = "UILabel"; text = "For additional security and to prevent unauthorized access the YubiKey can be password protected."; ObjectID = "46N-qq-yo2"; + + + Password + Password + Class = "UITextField"; placeholder = "Password"; ObjectID = "857-GD-96Q"; + + + Remove and re-insert your YubiKey + Remove and re-insert your YubiKey + Class = "UILabel"; text = "Remove and re-insert your YubiKey"; ObjectID = "AGQ-n1-pV3"; + + + YubiKey configuration + YubiKey configuration + Class = "UITableViewController"; title = "YubiKey configuration"; ObjectID = "Bxb-bg-K32"; + + + Activate NFC on OTP tag read + Activate NFC on OTP tag read + Class = "UILabel"; text = "Activate NFC on OTP tag read"; ObjectID = "Byl-RD-bpD"; + + + Configuration + Configuration + Class = "UITableViewSection"; headerTitle = "Configuration"; ObjectID = "C5n-jq-Mk9"; + + + Password + Password + Class = "UILabel"; text = "Password"; ObjectID = "Ced-DN-oqW"; + + + NFC settings + NFC settings + Class = "UILabel"; text = "NFC settings"; ObjectID = "D3g-ds-RCu"; + + + Close + Close + Class = "UIBarButtonItem"; title = "Close"; ObjectID = "D6R-wW-EtA"; + + + Copyright © 2021 Yubico. +All rights reserved. + Copyright © 2021 Yubico. +All rights reserved. + Class = "UILabel"; text = "Copyright © 2021 Yubico.\nAll rights reserved."; ObjectID = "Ecy-Pw-sM0"; + + + Initiate NFC at application start + Initiate NFC at application start + Class = "UILabel"; text = "Initiate NFC at application start"; ObjectID = "Efl-xJ-qER"; + + + SAVED PASSWORDS + SAVED PASSWORDS + Class = "UILabel"; text = "SAVED PASSWORDS"; ObjectID = "FMw-TB-KRk"; + + + About + About + Class = "UINavigationItem"; title = "About"; ObjectID = "Hbq-O7-HqW"; + + + Yubico OTP has been disabled + Yubico OTP has been disabled + Class = "UILabel"; text = "Yubico OTP has been disabled"; ObjectID = "Icc-EW-Cgh"; + + + Toggle One-Time Password + Toggle One-Time Password + Class = "UINavigationItem"; title = "Toggle One-Time Password"; ObjectID = "Inc-aD-fdW"; + + + This YubiKey has Yubico OTP enabled which makes it appear as an external keyboard to the iPhone. Unfortunately this causes problem with the normal on-screen keyboard. + This YubiKey has Yubico OTP enabled which makes it appear as an external keyboard to the iPhone. Unfortunately this causes problem with the normal on-screen keyboard. + Class = "UILabel"; text = "This YubiKey has Yubico OTP enabled which makes it appear as an external keyboard to the iPhone. Unfortunately this causes problem with the normal on-screen keyboard."; ObjectID = "JN3-vC-kaK"; + + + Smart card (PIV) PIN + Smart card (PIV) PIN + Class = "UITextField"; placeholder = "Smart card (PIV) PIN"; ObjectID = "JON-gB-7WG"; + + + While the YubiKey is inserted the on-screen keyboard will not appear. To show the keyboard you will have to remove the YubiKey and then re-insert it. + While the YubiKey is inserted the on-screen keyboard will not appear. To show the keyboard you will have to remove the YubiKey and then re-insert it. + Class = "UILabel"; text = "While the YubiKey is inserted the on-screen keyboard will not appear. To show the keyboard you will have to remove the YubiKey and then re-insert it."; ObjectID = "JQM-z3-Kvc"; + + + Start NFC and read OATH accounts when the application has been opened by reading the OTP tag on a YubiKey. + Start NFC and read OATH accounts when the application has been opened by reading the OTP tag on a YubiKey. + Class = "UITableViewSection"; footerTitle = "Start NFC and read OATH accounts when the application has been opened by reading the OTP tag on a YubiKey."; ObjectID = "JSq-rh-zB3"; + + + or + or + Class = "UILabel"; text = "or"; ObjectID = "L2j-ZW-Jbf"; + + + Serial number + Serial number + Class = "UILabel"; text = "Serial number"; ObjectID = "Lzm-p7-Lmb"; + + + N/A + N/A + Class = "UILabel"; text = "N/A"; ObjectID = "MBv-4M-eos"; + + + Help with YubiKey + Help with YubiKey + Class = "UILabel"; text = "Help with YubiKey"; ObjectID = "NnL-eZ-nHd"; + + + Unlock YubiKey + Unlock YubiKey + Class = "UILabel"; text = "Unlock YubiKey"; ObjectID = "O2N-dk-eMF"; + + + Set password + Set password + Class = "UILabel"; text = "Set password"; ObjectID = "Oba-Qw-cTB"; + + + NFC settings + NFC settings + Class = "UINavigationItem"; title = "NFC settings"; ObjectID = "PCq-PC-KyX"; + + + N/A + N/A + Class = "UILabel"; text = "N/A"; ObjectID = "QGj-16-s0W"; + + + Terms of use + Terms of use + Class = "UILabel"; text = "Terms of use"; ObjectID = "QHB-fS-VBc"; + + + Insert YubiKey or pull down to activate NFC + Insert YubiKey or pull down to activate NFC + Class = "UILabel"; text = "Insert YubiKey or pull down to activate NFC"; ObjectID = "Re8-TR-xIr"; + + + UnwindButton + UnwindButton + Class = "UIButton"; normalTitle = "UnwindButton"; ObjectID = "Szl-yL-4ir"; + + + Accounts that require touch will need an extra NFC tap to calculate its code. Bypassing it minimizes the number of NFC taps needed. + Accounts that require touch will need an extra NFC tap to calculate its code. Bypassing it minimizes the number of NFC taps needed. + Class = "UITableViewSection"; footerTitle = "Accounts that require touch will need an extra NFC tap to calculate its code. Bypassing it minimizes the number of NFC taps needed."; ObjectID = "Uvq-Ba-xiH"; + + + N/A + N/A + Class = "UILabel"; text = "N/A"; ObjectID = "VAw-dv-zeA"; + + + Yubico Authenticator + Yubico Authenticator + Class = "UILabel"; text = "Yubico Authenticator"; ObjectID = "VHQ-4i-YEj"; + + + Reset YubiKey + Reset YubiKey + Class = "UILabel"; text = "Reset YubiKey"; ObjectID = "Vb7-1M-PWz"; + + + Enter the PIN, then tap a NFC enabled YubiKey against the iPhone to access the certificate. + Enter the PIN, then tap a NFC enabled YubiKey against the iPhone to access the certificate. + Class = "UILabel"; text = "Enter the PIN, then tap a NFC enabled YubiKey against the iPhone to access the certificate."; ObjectID = "WGy-0e-K7w"; + + + Disable Yubico OTP (recommended) + Disable Yubico OTP (recommended) + Class = "UIButton"; configuration.title = "Disable Yubico OTP (recommended)"; ObjectID = "Yo4-ef-tkZ"; + + + Button + Button + Class = "UIButton"; normalTitle = "Button"; ObjectID = "Yo4-ef-tkZ"; + + + Firmware + Firmware + Class = "UILabel"; text = "Firmware"; ObjectID = "aFH-4H-WRy"; + + + Confirm password + Confirm password + Class = "UILabel"; text = "Confirm password"; ObjectID = "al9-tv-dIv"; + + + ONE-TIME PASSWORD + ONE-TIME PASSWORD + Class = "UILabel"; text = "ONE-TIME PASSWORD"; ObjectID = "b6z-Ri-5bh"; + + + Disabling Yubico OTP will prevent the YubiKey from appearing as a keyboard. If you don’t use Yubico OTP this is the recommended solution. This can be re-enabled from the settings page. + Disabling Yubico OTP will prevent the YubiKey from appearing as a keyboard. If you don’t use Yubico OTP this is the recommended solution. This can be re-enabled from the settings page. + Class = "UILabel"; text = "Disabling Yubico OTP will prevent the YubiKey from appearing as a keyboard. If you don’t use Yubico OTP this is the recommended solution. This can be re-enabled from the settings page."; ObjectID = "cou-Cr-QYP"; + + + Remove password + Remove password + Class = "UILabel"; text = "Remove password"; ObjectID = "dAR-My-Mmm"; + + + Configuration + Configuration + Class = "UINavigationItem"; title = "Configuration"; ObjectID = "e3s-bq-xAt"; + + + Set password + Set password + Class = "UINavigationItem"; title = "Set password"; ObjectID = "eiF-JR-TAC"; + + + Smart card extension + Smart card extension + Class = "UINavigationItem"; title = "Smart card extension"; ObjectID = "fl4-8d-lD9"; + + + Bypass touch requirement + Bypass touch requirement + Class = "UILabel"; text = "Bypass touch requirement"; ObjectID = "frN-Of-d1s"; + + + RESET YUBIKEY + RESET YUBIKEY + Class = "UILabel"; text = "RESET YUBIKEY"; ObjectID = "gAN-p5-fcQ"; + + + Initiate NFC at application start will automatically read your YubiKey as soon as the app becomes active. + Initiate NFC at application start will automatically read your YubiKey as soon as the app becomes active. + Class = "UITableViewSection"; footerTitle = "Initiate NFC at application start will automatically read your YubiKey as soon as the app becomes active."; ObjectID = "gQR-ie-6Y0"; + + + Clear passwords saved on iPhone. This will prompt for a password next time a password protected YubiKey is used. + Clear passwords saved on iPhone. This will prompt for a password next time a password protected YubiKey is used. + Class = "UILabel"; text = "Clear passwords saved on iPhone. This will prompt for a password next time a password protected YubiKey is used."; ObjectID = "gYP-vW-fFN"; + + + Version history + Version history + Class = "UILabel"; text = "Version history"; ObjectID = "ghF-dC-3d6"; + + + Item + Item + Class = "UIBarButtonItem"; title = "Item"; ObjectID = "hBA-XE-Ib1"; + + + For additional security and to prevent unauthorized access the YubiKey can be protected with a password + For additional security and to prevent unauthorized access the YubiKey can be protected with a password + Class = "UITableViewSection"; footerTitle = "For additional security and to prevent unauthorized access the YubiKey can be protected with a password"; ObjectID = "hOr-gJ-fIa"; + + + Copy OTP to clipboard + Copy OTP to clipboard + Class = "UILabel"; text = "Copy OTP to clipboard"; ObjectID = "hsz-tV-DPW"; + + + Smart card extension + Smart card extension + Class = "UILabel"; text = "Smart card extension"; ObjectID = "iH3-4d-Rv5"; + + + Close + Close + Class = "UIBarButtonItem"; title = "Close"; ObjectID = "jNG-Du-Ghz"; + + + Clear saved passwords + Clear saved passwords + Class = "UILabel"; text = "Clear saved passwords"; ObjectID = "jx7-Be-qMk"; + + + Continue with limited usability + Continue with limited usability + Class = "UIButton"; configuration.title = "Continue with limited usability"; ObjectID = "kAX-Sn-d4r"; + + + Button + Button + Class = "UIButton"; normalTitle = "Button"; ObjectID = "kAX-Sn-d4r"; + + + Device type + Device type + Class = "UILabel"; text = "Device type"; ObjectID = "llv-60-0FB"; + + + Insert a YubiKey and enter its PIN to access the certificate. + Insert a YubiKey and enter its PIN to access the certificate. + Class = "UILabel"; text = "Insert a YubiKey and enter its PIN to access the certificate."; ObjectID = "noy-hK-f0E"; + + + Copy OTP automatically to clipboard when a YubiKey has been scanned using the NFC tag functionality. + Copy OTP automatically to clipboard when a YubiKey has been scanned using the NFC tag functionality. + Class = "UITableViewSection"; footerTitle = "Copy OTP automatically to clipboard when a YubiKey has been scanned using the NFC tag functionality."; ObjectID = "oy6-QK-Bgw"; + + + Application + Application + Class = "UITableViewSection"; headerTitle = "Application"; ObjectID = "raA-qu-ETm"; + + + Contact support + Contact support + Class = "UILabel"; text = "Contact support"; ObjectID = "tMr-aW-Doe"; + + + Toggle One-Time Password + Toggle One-Time Password + Class = "UILabel"; text = "Toggle One-Time Password"; ObjectID = "uP5-O2-d0d"; + + + Turn on/off opening Safari to copy your OTP when scanning the NFC YubiKey. + Turn on/off opening Safari to copy your OTP when scanning the NFC YubiKey. + Class = "UILabel"; text = "Turn on/off opening Safari to copy your OTP when scanning the NFC YubiKey."; ObjectID = "vjs-4B-RzZ"; + + + Support + Support + Class = "UITableViewSection"; headerTitle = "Support"; ObjectID = "vn9-zq-1Ri"; + + + Password + Password + Class = "UITextField"; placeholder = "Password"; ObjectID = "wH4-5g-AV5"; + + + Licensing + Licensing + Class = "UILabel"; text = "Licensing"; ObjectID = "wvt-LS-lIS"; + + + How does it work + How does it work + Class = "UILabel"; text = "How does it work"; ObjectID = "y0i-iX-KLv"; + + + INFORMATION + INFORMATION + Class = "UITableViewSection"; headerTitle = "INFORMATION"; ObjectID = "yed-kd-amP"; + + + Reset all accounts stored on YubiKey, make sure they are not in use anywhere before doing this. + Reset all accounts stored on YubiKey, make sure they are not in use anywhere before doing this. + Class = "UILabel"; text = "Reset all accounts stored on YubiKey, make sure they are not in use anywhere before doing this."; ObjectID = "zcT-oY-vKq"; + + +
+ +
+ +
+ + + TokenExtension + TokenExtension + Bundle display name + + + TokenExtension + TokenExtension + Bundle name + + +
+
diff --git a/Localizations/en.xcloc/Source Contents/Authenticator/UI/Base.lproj/LaunchScreen.storyboard b/Localizations/en.xcloc/Source Contents/Authenticator/UI/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 00000000..2825ba1a --- /dev/null +++ b/Localizations/en.xcloc/Source Contents/Authenticator/UI/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Localizations/en.xcloc/Source Contents/Authenticator/UI/Base.lproj/Main.storyboard b/Localizations/en.xcloc/Source Contents/Authenticator/UI/Base.lproj/Main.storyboard new file mode 100644 index 00000000..72bd3467 --- /dev/null +++ b/Localizations/en.xcloc/Source Contents/Authenticator/UI/Base.lproj/Main.storyboard @@ -0,0 +1,1673 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Accounts that require touch will need an extra NFC tap to calculate its code. Bypassing it minimizes the number of NFC taps needed. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Localizations/en.xcloc/Source Contents/Authenticator/en.lproj/InfoPlist.strings b/Localizations/en.xcloc/Source Contents/Authenticator/en.lproj/InfoPlist.strings new file mode 100644 index 00000000..49238f28 --- /dev/null +++ b/Localizations/en.xcloc/Source Contents/Authenticator/en.lproj/InfoPlist.strings @@ -0,0 +1,8 @@ +/* Bundle name */ +"CFBundleName" = "Authenticator"; +/* Privacy - NFC Scan Usage Description */ +"NFCReaderUsageDescription" = "The application needs access to NFC reading to communicate with your Yubikey."; +/* Privacy - Camera Usage Description */ +"NSCameraUsageDescription" = "The application needs access to Camera to scan QR codes."; +/* Privacy - Face ID Usage Description */ +"NSFaceIDUsageDescription" = "The application needs access to Face ID to unlock your password vault."; diff --git a/Localizations/en.xcloc/Source Contents/Authenticator/en.lproj/Localizable.strings b/Localizations/en.xcloc/Source Contents/Authenticator/en.lproj/Localizable.strings new file mode 100644 index 00000000..bad7b929 Binary files /dev/null and b/Localizations/en.xcloc/Source Contents/Authenticator/en.lproj/Localizable.strings differ diff --git a/Localizations/en.xcloc/Source Contents/TokenExtension/en.lproj/InfoPlist.strings b/Localizations/en.xcloc/Source Contents/TokenExtension/en.lproj/InfoPlist.strings new file mode 100644 index 00000000..7162b4da --- /dev/null +++ b/Localizations/en.xcloc/Source Contents/TokenExtension/en.lproj/InfoPlist.strings @@ -0,0 +1,4 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "TokenExtension"; +/* Bundle name */ +"CFBundleName" = "TokenExtension"; diff --git a/Localizations/en.xcloc/contents.json b/Localizations/en.xcloc/contents.json new file mode 100644 index 00000000..946b5513 --- /dev/null +++ b/Localizations/en.xcloc/contents.json @@ -0,0 +1,12 @@ +{ + "developmentRegion" : "en", + "project" : "Authenticator.xcodeproj", + "targetLocale" : "en", + "toolInfo" : { + "toolBuildNumber" : "15C500b", + "toolID" : "com.apple.dt.xcode", + "toolName" : "Xcode", + "toolVersion" : "15.2" + }, + "version" : "1.0" +} \ No newline at end of file diff --git a/Localizations/en/en.xcloc/Localized Contents/en.xliff b/Localizations/en/en.xcloc/Localized Contents/en.xliff new file mode 100644 index 00000000..df4c0ace --- /dev/null +++ b/Localizations/en/en.xcloc/Localized Contents/en.xliff @@ -0,0 +1,623 @@ + + + +
+ +
+ + + Authenticator + Authenticator + Bundle name + + + The application needs access to NFC reading to communicate with your Yubikey. + The application needs access to NFC reading to communicate with your Yubikey. + Privacy - NFC Scan Usage Description + + + The application needs access to Camera to scan QR codes. + The application needs access to Camera to scan QR codes. + Privacy - Camera Usage Description + + + The application needs access to Face ID to unlock your password vault. + The application needs access to Face ID to unlock your password vault. + Privacy - Face ID Usage Description + + +
+ +
+ +
+ + + *** *** + *** *** + No comment provided by engineer. + + + 888 888 + 888 888 + No comment provided by engineer. + + + ? + ? + No comment provided by engineer. + + + Accounts + Accounts + No comment provided by engineer. + + + Cancel + Cancel + No comment provided by engineer. + + + Continue with limited usability + Continue with limited usability + No comment provided by engineer. + + + Data to String conversion error + Data to String conversion error + No comment provided by engineer. + + + Delete + Delete + No comment provided by engineer. + + + Delete account? + Delete account? + No comment provided by engineer. + + + Disable Yubico OTP (recommended) + Disable Yubico OTP (recommended) + No comment provided by engineer. + + + Disabling Yubico OTP will prevent the YubiKey from appearing as a keyboard. If you don’t use Yubico OTP this is the recommended solution. This can be re-enabled from the settings page. + Disabling Yubico OTP will prevent the YubiKey from appearing as a keyboard. If you don’t use Yubico OTP this is the recommended solution. This can be re-enabled from the settings page. + No comment provided by engineer. + + + Failed to cast object to Data error + Failed to cast object to Data error + No comment provided by engineer. + + + Invalid URI format + Invalid URI format + Invalid Uri, wrong parameters + + + Item not found in secure storage + Item not found in secure storage + No comment provided by engineer. + + + Other + Other + No comment provided by engineer. + + + Pinned + Pinned + No comment provided by engineer. + + + Plug-in your YubiKey for that operation + Plug-in your YubiKey for that operation + No service found + + + Remove and re-insert your YubiKey + Remove and re-insert your YubiKey + No comment provided by engineer. + + + Some content... + Some content... + No comment provided by engineer. + + + Something went wrong and key doesn't respond + Something went wrong and key doesn't respond + No response + + + String to Data conversion error + String to Data conversion error + No comment provided by engineer. + + + The key doesn't respond + The key doesn't respond + Timeout issue + + + This QR code is not supported + This QR code is not supported + Invalid Uri format, not OATH URL + + + This YubiKey has Yubico OTP enabled which makes it appear as an external keyboard to the iPhone. Unfortunately this causes problem with the normal on-screen keyboard. + This YubiKey has Yubico OTP enabled which makes it appear as an external keyboard to the iPhone. Unfortunately this causes problem with the normal on-screen keyboard. + No comment provided by engineer. + + + This version of iOS does not support operations with the YubiKey for Lightning nor over NFC + This version of iOS does not support operations with the YubiKey for Lightning nor over NFC + Not supported + + + This will permanently delete the account from the YubiKey, and your ability to generate codes for it! + This will permanently delete the account from the YubiKey, and your ability to generate codes for it! + No comment provided by engineer. + + + Unhandled Error + Unhandled Error + No comment provided by engineer. + + + While the YubiKey is inserted the on-screen keyboard will not appear. To show the keyboard you will have to remove the YubiKey and then re-insert it. + While the YubiKey is inserted the on-screen keyboard will not appear. To show the keyboard you will have to remove the YubiKey and then re-insert it. + No comment provided by engineer. + + + Yubico OTP + Yubico OTP + No comment provided by engineer. + + + Yubico OTP enabled + Yubico OTP enabled + No comment provided by engineer. + + + Yubico OTP has been disabled + Yubico OTP has been disabled + No comment provided by engineer. + + +
+ +
+ +
+ + + One-Time Password + One-Time Password + Class = "UILabel"; text = "One-Time Password"; ObjectID = "1mC-4P-2g3"; + + + Tap the back button to continue + Tap the back button to continue + Class = "UILabel"; text = "Tap the back button to continue"; ObjectID = "2pK-HU-1WC"; + + + Passwords and reset + Passwords and reset + Class = "UILabel"; text = "Passwords and reset"; ObjectID = "03k-jY-TEC"; + + + PASSWORD PROTECTION + PASSWORD PROTECTION + Class = "UILabel"; text = "PASSWORD PROTECTION"; ObjectID = "5iZ-OS-CfM"; + + + 1.0 + 1.0 + Class = "UILabel"; text = "1.0"; ObjectID = "6TW-2t-mYb"; + + + YubiKey configuration + YubiKey configuration + Class = "UITableViewController"; title = "YubiKey configuration"; ObjectID = "09D-Aw-j1I"; + + + Passwords and reset + Passwords and reset + Class = "UINavigationItem"; title = "Passwords and reset"; ObjectID = "9NQ-7X-HqZ"; + + + Privacy policy + Privacy policy + Class = "UILabel"; text = "Privacy policy"; ObjectID = "9lG-2A-fbz"; + + + Enabled + Enabled + Class = "UILabel"; text = "Enabled"; ObjectID = "9lL-ZS-odE"; + + + Yubico OTP enabled + Yubico OTP enabled + Class = "UILabel"; text = "Yubico OTP enabled"; ObjectID = "26R-OJ-dML"; + + + For additional security and to prevent unauthorized access the YubiKey can be password protected. + For additional security and to prevent unauthorized access the YubiKey can be password protected. + Class = "UILabel"; text = "For additional security and to prevent unauthorized access the YubiKey can be password protected."; ObjectID = "46N-qq-yo2"; + + + Password + Password + Class = "UITextField"; placeholder = "Password"; ObjectID = "857-GD-96Q"; + + + Remove and re-insert your YubiKey + Remove and re-insert your YubiKey + Class = "UILabel"; text = "Remove and re-insert your YubiKey"; ObjectID = "AGQ-n1-pV3"; + + + YubiKey configuration + YubiKey configuration + Class = "UITableViewController"; title = "YubiKey configuration"; ObjectID = "Bxb-bg-K32"; + + + Activate NFC on OTP tag read + Activate NFC on OTP tag read + Class = "UILabel"; text = "Activate NFC on OTP tag read"; ObjectID = "Byl-RD-bpD"; + + + Configuration + Configuration + Class = "UITableViewSection"; headerTitle = "Configuration"; ObjectID = "C5n-jq-Mk9"; + + + Password + Password + Class = "UILabel"; text = "Password"; ObjectID = "Ced-DN-oqW"; + + + NFC settings + NFC settings + Class = "UILabel"; text = "NFC settings"; ObjectID = "D3g-ds-RCu"; + + + Close + Close + Class = "UIBarButtonItem"; title = "Close"; ObjectID = "D6R-wW-EtA"; + + + Copyright © 2021 Yubico. +All rights reserved. + Copyright © 2021 Yubico. +All rights reserved. + Class = "UILabel"; text = "Copyright © 2021 Yubico.\nAll rights reserved."; ObjectID = "Ecy-Pw-sM0"; + + + Initiate NFC at application start + Initiate NFC at application start + Class = "UILabel"; text = "Initiate NFC at application start"; ObjectID = "Efl-xJ-qER"; + + + SAVED PASSWORDS + SAVED PASSWORDS + Class = "UILabel"; text = "SAVED PASSWORDS"; ObjectID = "FMw-TB-KRk"; + + + About + About + Class = "UINavigationItem"; title = "About"; ObjectID = "Hbq-O7-HqW"; + + + Yubico OTP has been disabled + Yubico OTP has been disabled + Class = "UILabel"; text = "Yubico OTP has been disabled"; ObjectID = "Icc-EW-Cgh"; + + + Toggle One-Time Password + Toggle One-Time Password + Class = "UINavigationItem"; title = "Toggle One-Time Password"; ObjectID = "Inc-aD-fdW"; + + + This YubiKey has Yubico OTP enabled which makes it appear as an external keyboard to the iPhone. Unfortunately this causes problem with the normal on-screen keyboard. + This YubiKey has Yubico OTP enabled which makes it appear as an external keyboard to the iPhone. Unfortunately this causes problem with the normal on-screen keyboard. + Class = "UILabel"; text = "This YubiKey has Yubico OTP enabled which makes it appear as an external keyboard to the iPhone. Unfortunately this causes problem with the normal on-screen keyboard."; ObjectID = "JN3-vC-kaK"; + + + Smart card (PIV) PIN + Smart card (PIV) PIN + Class = "UITextField"; placeholder = "Smart card (PIV) PIN"; ObjectID = "JON-gB-7WG"; + + + While the YubiKey is inserted the on-screen keyboard will not appear. To show the keyboard you will have to remove the YubiKey and then re-insert it. + While the YubiKey is inserted the on-screen keyboard will not appear. To show the keyboard you will have to remove the YubiKey and then re-insert it. + Class = "UILabel"; text = "While the YubiKey is inserted the on-screen keyboard will not appear. To show the keyboard you will have to remove the YubiKey and then re-insert it."; ObjectID = "JQM-z3-Kvc"; + + + Start NFC and read OATH accounts when the application has been opened by reading the OTP tag on a YubiKey. + Start NFC and read OATH accounts when the application has been opened by reading the OTP tag on a YubiKey. + Class = "UITableViewSection"; footerTitle = "Start NFC and read OATH accounts when the application has been opened by reading the OTP tag on a YubiKey."; ObjectID = "JSq-rh-zB3"; + + + or + or + Class = "UILabel"; text = "or"; ObjectID = "L2j-ZW-Jbf"; + + + Serial number + Serial number + Class = "UILabel"; text = "Serial number"; ObjectID = "Lzm-p7-Lmb"; + + + N/A + N/A + Class = "UILabel"; text = "N/A"; ObjectID = "MBv-4M-eos"; + + + Help with YubiKey + Help with YubiKey + Class = "UILabel"; text = "Help with YubiKey"; ObjectID = "NnL-eZ-nHd"; + + + Unlock YubiKey + Unlock YubiKey + Class = "UILabel"; text = "Unlock YubiKey"; ObjectID = "O2N-dk-eMF"; + + + Set password + Set password + Class = "UILabel"; text = "Set password"; ObjectID = "Oba-Qw-cTB"; + + + NFC settings + NFC settings + Class = "UINavigationItem"; title = "NFC settings"; ObjectID = "PCq-PC-KyX"; + + + N/A + N/A + Class = "UILabel"; text = "N/A"; ObjectID = "QGj-16-s0W"; + + + Terms of use + Terms of use + Class = "UILabel"; text = "Terms of use"; ObjectID = "QHB-fS-VBc"; + + + Insert YubiKey or pull down to activate NFC + Insert YubiKey or pull down to activate NFC + Class = "UILabel"; text = "Insert YubiKey or pull down to activate NFC"; ObjectID = "Re8-TR-xIr"; + + + UnwindButton + UnwindButton + Class = "UIButton"; normalTitle = "UnwindButton"; ObjectID = "Szl-yL-4ir"; + + + Accounts that require touch will need an extra NFC tap to calculate its code. Bypassing it minimizes the number of NFC taps needed. + Accounts that require touch will need an extra NFC tap to calculate its code. Bypassing it minimizes the number of NFC taps needed. + Class = "UITableViewSection"; footerTitle = "Accounts that require touch will need an extra NFC tap to calculate its code. Bypassing it minimizes the number of NFC taps needed."; ObjectID = "Uvq-Ba-xiH"; + + + N/A + N/A + Class = "UILabel"; text = "N/A"; ObjectID = "VAw-dv-zeA"; + + + Yubico Authenticator + Yubico Authenticator + Class = "UILabel"; text = "Yubico Authenticator"; ObjectID = "VHQ-4i-YEj"; + + + Reset YubiKey + Reset YubiKey + Class = "UILabel"; text = "Reset YubiKey"; ObjectID = "Vb7-1M-PWz"; + + + Enter the PIN, then tap a NFC enabled YubiKey against the iPhone to access the certificate. + Enter the PIN, then tap a NFC enabled YubiKey against the iPhone to access the certificate. + Class = "UILabel"; text = "Enter the PIN, then tap a NFC enabled YubiKey against the iPhone to access the certificate."; ObjectID = "WGy-0e-K7w"; + + + Disable Yubico OTP (recommended) + Disable Yubico OTP (recommended) + Class = "UIButton"; configuration.title = "Disable Yubico OTP (recommended)"; ObjectID = "Yo4-ef-tkZ"; + + + Button + Button + Class = "UIButton"; normalTitle = "Button"; ObjectID = "Yo4-ef-tkZ"; + + + Firmware + Firmware + Class = "UILabel"; text = "Firmware"; ObjectID = "aFH-4H-WRy"; + + + Confirm password + Confirm password + Class = "UILabel"; text = "Confirm password"; ObjectID = "al9-tv-dIv"; + + + ONE-TIME PASSWORD + ONE-TIME PASSWORD + Class = "UILabel"; text = "ONE-TIME PASSWORD"; ObjectID = "b6z-Ri-5bh"; + + + Disabling Yubico OTP will prevent the YubiKey from appearing as a keyboard. If you don’t use Yubico OTP this is the recommended solution. This can be re-enabled from the settings page. + Disabling Yubico OTP will prevent the YubiKey from appearing as a keyboard. If you don’t use Yubico OTP this is the recommended solution. This can be re-enabled from the settings page. + Class = "UILabel"; text = "Disabling Yubico OTP will prevent the YubiKey from appearing as a keyboard. If you don’t use Yubico OTP this is the recommended solution. This can be re-enabled from the settings page."; ObjectID = "cou-Cr-QYP"; + + + Remove password + Remove password + Class = "UILabel"; text = "Remove password"; ObjectID = "dAR-My-Mmm"; + + + Configuration + Configuration + Class = "UINavigationItem"; title = "Configuration"; ObjectID = "e3s-bq-xAt"; + + + Set password + Set password + Class = "UINavigationItem"; title = "Set password"; ObjectID = "eiF-JR-TAC"; + + + Smart card extension + Smart card extension + Class = "UINavigationItem"; title = "Smart card extension"; ObjectID = "fl4-8d-lD9"; + + + Bypass touch requirement + Bypass touch requirement + Class = "UILabel"; text = "Bypass touch requirement"; ObjectID = "frN-Of-d1s"; + + + RESET YUBIKEY + RESET YUBIKEY + Class = "UILabel"; text = "RESET YUBIKEY"; ObjectID = "gAN-p5-fcQ"; + + + Initiate NFC at application start will automatically read your YubiKey as soon as the app becomes active. + Initiate NFC at application start will automatically read your YubiKey as soon as the app becomes active. + Class = "UITableViewSection"; footerTitle = "Initiate NFC at application start will automatically read your YubiKey as soon as the app becomes active."; ObjectID = "gQR-ie-6Y0"; + + + Clear passwords saved on iPhone. This will prompt for a password next time a password protected YubiKey is used. + Clear passwords saved on iPhone. This will prompt for a password next time a password protected YubiKey is used. + Class = "UILabel"; text = "Clear passwords saved on iPhone. This will prompt for a password next time a password protected YubiKey is used."; ObjectID = "gYP-vW-fFN"; + + + Version history + Version history + Class = "UILabel"; text = "Version history"; ObjectID = "ghF-dC-3d6"; + + + Item + Item + Class = "UIBarButtonItem"; title = "Item"; ObjectID = "hBA-XE-Ib1"; + + + For additional security and to prevent unauthorized access the YubiKey can be protected with a password + For additional security and to prevent unauthorized access the YubiKey can be protected with a password + Class = "UITableViewSection"; footerTitle = "For additional security and to prevent unauthorized access the YubiKey can be protected with a password"; ObjectID = "hOr-gJ-fIa"; + + + Copy OTP to clipboard + Copy OTP to clipboard + Class = "UILabel"; text = "Copy OTP to clipboard"; ObjectID = "hsz-tV-DPW"; + + + Smart card extension + Smart card extension + Class = "UILabel"; text = "Smart card extension"; ObjectID = "iH3-4d-Rv5"; + + + Close + Close + Class = "UIBarButtonItem"; title = "Close"; ObjectID = "jNG-Du-Ghz"; + + + Clear saved passwords + Clear saved passwords + Class = "UILabel"; text = "Clear saved passwords"; ObjectID = "jx7-Be-qMk"; + + + Continue with limited usability + Continue with limited usability + Class = "UIButton"; configuration.title = "Continue with limited usability"; ObjectID = "kAX-Sn-d4r"; + + + Button + Button + Class = "UIButton"; normalTitle = "Button"; ObjectID = "kAX-Sn-d4r"; + + + Device type + Device type + Class = "UILabel"; text = "Device type"; ObjectID = "llv-60-0FB"; + + + Insert a YubiKey and enter its PIN to access the certificate. + Insert a YubiKey and enter its PIN to access the certificate. + Class = "UILabel"; text = "Insert a YubiKey and enter its PIN to access the certificate."; ObjectID = "noy-hK-f0E"; + + + Copy OTP automatically to clipboard when a YubiKey has been scanned using the NFC tag functionality. + Copy OTP automatically to clipboard when a YubiKey has been scanned using the NFC tag functionality. + Class = "UITableViewSection"; footerTitle = "Copy OTP automatically to clipboard when a YubiKey has been scanned using the NFC tag functionality."; ObjectID = "oy6-QK-Bgw"; + + + Application + Application + Class = "UITableViewSection"; headerTitle = "Application"; ObjectID = "raA-qu-ETm"; + + + Contact support + Contact support + Class = "UILabel"; text = "Contact support"; ObjectID = "tMr-aW-Doe"; + + + Toggle One-Time Password + Toggle One-Time Password + Class = "UILabel"; text = "Toggle One-Time Password"; ObjectID = "uP5-O2-d0d"; + + + Turn on/off opening Safari to copy your OTP when scanning the NFC YubiKey. + Turn on/off opening Safari to copy your OTP when scanning the NFC YubiKey. + Class = "UILabel"; text = "Turn on/off opening Safari to copy your OTP when scanning the NFC YubiKey."; ObjectID = "vjs-4B-RzZ"; + + + Support + Support + Class = "UITableViewSection"; headerTitle = "Support"; ObjectID = "vn9-zq-1Ri"; + + + Password + Password + Class = "UITextField"; placeholder = "Password"; ObjectID = "wH4-5g-AV5"; + + + Licensing + Licensing + Class = "UILabel"; text = "Licensing"; ObjectID = "wvt-LS-lIS"; + + + How does it work + How does it work + Class = "UILabel"; text = "How does it work"; ObjectID = "y0i-iX-KLv"; + + + INFORMATION + INFORMATION + Class = "UITableViewSection"; headerTitle = "INFORMATION"; ObjectID = "yed-kd-amP"; + + + Reset all accounts stored on YubiKey, make sure they are not in use anywhere before doing this. + Reset all accounts stored on YubiKey, make sure they are not in use anywhere before doing this. + Class = "UILabel"; text = "Reset all accounts stored on YubiKey, make sure they are not in use anywhere before doing this."; ObjectID = "zcT-oY-vKq"; + + +
+ +
+ +
+ + + TokenExtension + TokenExtension + Bundle display name + + + TokenExtension + TokenExtension + Bundle name + + +
+
diff --git a/Localizations/en/en.xcloc/Source Contents/Authenticator/UI/Base.lproj/LaunchScreen.storyboard b/Localizations/en/en.xcloc/Source Contents/Authenticator/UI/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 00000000..2825ba1a --- /dev/null +++ b/Localizations/en/en.xcloc/Source Contents/Authenticator/UI/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Localizations/en/en.xcloc/Source Contents/Authenticator/UI/Base.lproj/Main.storyboard b/Localizations/en/en.xcloc/Source Contents/Authenticator/UI/Base.lproj/Main.storyboard new file mode 100644 index 00000000..72bd3467 --- /dev/null +++ b/Localizations/en/en.xcloc/Source Contents/Authenticator/UI/Base.lproj/Main.storyboard @@ -0,0 +1,1673 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Accounts that require touch will need an extra NFC tap to calculate its code. Bypassing it minimizes the number of NFC taps needed. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Localizations/en/en.xcloc/Source Contents/Authenticator/en.lproj/InfoPlist.strings b/Localizations/en/en.xcloc/Source Contents/Authenticator/en.lproj/InfoPlist.strings new file mode 100644 index 00000000..49238f28 --- /dev/null +++ b/Localizations/en/en.xcloc/Source Contents/Authenticator/en.lproj/InfoPlist.strings @@ -0,0 +1,8 @@ +/* Bundle name */ +"CFBundleName" = "Authenticator"; +/* Privacy - NFC Scan Usage Description */ +"NFCReaderUsageDescription" = "The application needs access to NFC reading to communicate with your Yubikey."; +/* Privacy - Camera Usage Description */ +"NSCameraUsageDescription" = "The application needs access to Camera to scan QR codes."; +/* Privacy - Face ID Usage Description */ +"NSFaceIDUsageDescription" = "The application needs access to Face ID to unlock your password vault."; diff --git a/Localizations/en/en.xcloc/Source Contents/Authenticator/en.lproj/Localizable.strings b/Localizations/en/en.xcloc/Source Contents/Authenticator/en.lproj/Localizable.strings new file mode 100644 index 00000000..bad7b929 Binary files /dev/null and b/Localizations/en/en.xcloc/Source Contents/Authenticator/en.lproj/Localizable.strings differ diff --git a/Localizations/en/en.xcloc/Source Contents/TokenExtension/en.lproj/InfoPlist.strings b/Localizations/en/en.xcloc/Source Contents/TokenExtension/en.lproj/InfoPlist.strings new file mode 100644 index 00000000..7162b4da --- /dev/null +++ b/Localizations/en/en.xcloc/Source Contents/TokenExtension/en.lproj/InfoPlist.strings @@ -0,0 +1,4 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "TokenExtension"; +/* Bundle name */ +"CFBundleName" = "TokenExtension"; diff --git a/Localizations/en/en.xcloc/contents.json b/Localizations/en/en.xcloc/contents.json new file mode 100644 index 00000000..946b5513 --- /dev/null +++ b/Localizations/en/en.xcloc/contents.json @@ -0,0 +1,12 @@ +{ + "developmentRegion" : "en", + "project" : "Authenticator.xcodeproj", + "targetLocale" : "en", + "toolInfo" : { + "toolBuildNumber" : "15C500b", + "toolID" : "com.apple.dt.xcode", + "toolName" : "Xcode", + "toolVersion" : "15.2" + }, + "version" : "1.0" +} \ No newline at end of file diff --git a/TokenExtension/Localizable.xcstrings b/TokenExtension/Localizable.xcstrings new file mode 100644 index 00000000..2c6a5bad --- /dev/null +++ b/TokenExtension/Localizable.xcstrings @@ -0,0 +1,54 @@ +{ + "sourceLanguage" : "en", + "strings" : { + "Launch Yubico Authenticator" : { + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Lancer Yubico Authenticator" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "Yubico Authenticatorを起動" + } + } + } + }, + "Tap here to complete the request using your YubiKey." : { + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Appuyez ici pour finaliser la demande avec votre YubiKey." + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "ここをタップし、YubiKeyを使用してリクエストを完了します。" + } + } + } + }, + "YubiKey required" : { + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "YubiKey requise" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "YubiKeyが必要です" + } + } + } + } + }, + "version" : "1.0" +} \ No newline at end of file diff --git a/TokenExtension/TokenSession.swift b/TokenExtension/TokenSession.swift index 58d346f1..0d967e6e 100644 --- a/TokenExtension/TokenSession.swift +++ b/TokenExtension/TokenSession.swift @@ -151,14 +151,14 @@ class TokenSession: TKTokenSession, TKTokenSessionDelegate { cancelAllNotifications() let categoryID = "SignData" let content = UNMutableNotificationContent() - content.title = "YubiKey required" - content.body = "Tap here to complete the request using your YubiKey." + content.title = String(localized: "YubiKey required") + content.body = String(localized: "Tap here to complete the request using your YubiKey.") content.categoryIdentifier = categoryID content.userInfo = ["data": data, "keyObjectID": keyObjectID, "algorithm": algorithm.rawValue, "keyType": keyType.rawValue]; content.sound = UNNotificationSound.default let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 0.1, repeats: false) - let show = UNNotificationAction(identifier: categoryID, title: "Launch Yubico Authenticator", options: .foreground) + let show = UNNotificationAction(identifier: categoryID, title: String(localized: "Launch Yubico Authenticator"), options: .foreground) let category = UNNotificationCategory(identifier: categoryID, actions: [show], intentIdentifiers: []) let center = UNUserNotificationCenter.current() diff --git a/TokenExtension/fr.lproj/InfoPlist.strings b/TokenExtension/fr.lproj/InfoPlist.strings new file mode 100644 index 00000000..51156d23 --- /dev/null +++ b/TokenExtension/fr.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "Extension jeton"; + +/* Bundle name */ +"CFBundleName" = "Extension jeton"; + diff --git a/TokenExtension/ja.lproj/InfoPlist.strings b/TokenExtension/ja.lproj/InfoPlist.strings new file mode 100644 index 00000000..3fc77307 --- /dev/null +++ b/TokenExtension/ja.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "TokenExtension"; + +/* Bundle name */ +"CFBundleName" = "TokenExtension"; +