├── .github └── workflows │ └── swift.yml ├── .gitignore ├── Authenticator.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── xcshareddata │ └── xcschemes │ └── Authenticator.xcscheme ├── Authenticator ├── AddFromScanViewController.swift ├── Assets.xcassets │ ├── AccentColor.colorset │ │ └── Contents.json │ ├── AppIcon.appiconset │ │ ├── AppIcon-1024.png │ │ ├── AppIcon-20.png │ │ ├── AppIcon-20@2x.png │ │ ├── AppIcon-20@3x.png │ │ ├── AppIcon-29.png │ │ ├── AppIcon-29@2x.png │ │ ├── AppIcon-29@3x.png │ │ ├── AppIcon-40.png │ │ ├── AppIcon-40@2x.png │ │ ├── AppIcon-40@3x.png │ │ ├── AppIcon-60@2x.png │ │ ├── AppIcon-60@3x.png │ │ ├── AppIcon-76.png │ │ ├── AppIcon-76@2x.png │ │ ├── AppIcon-83.5@2x.png │ │ └── Contents.json │ ├── Contents.json │ ├── CustomColors │ │ ├── CodeBorder.colorset │ │ │ └── Contents.json │ │ ├── Contents.json │ │ ├── DetailsBackground.colorset │ │ │ └── Contents.json │ │ ├── DetailsCodeBackground.colorset │ │ │ └── Contents.json │ │ ├── Favorite.colorset │ │ │ └── Contents.json │ │ ├── ListSectionHeaderColor.colorset │ │ │ └── Contents.json │ │ ├── MenuBackground.colorset │ │ │ └── Contents.json │ │ ├── MenuDivider.colorset │ │ │ └── Contents.json │ │ ├── MenuSelectedBackground.colorset │ │ │ └── Contents.json │ │ ├── SearchBackground.colorset │ │ │ └── Contents.json │ │ ├── SearchBarBackground.colorset │ │ │ └── Contents.json │ │ ├── SheetBackgroundColor.colorset │ │ │ └── Contents.json │ │ ├── TableBackgroundColor.colorset │ │ │ └── Contents.json │ │ ├── TableSelection.colorset │ │ │ └── Contents.json │ │ ├── YubiBlue.colorset │ │ │ └── Contents.json │ │ └── YubiGreen.colorset │ │ │ └── Contents.json │ ├── CustomTableBackgroundColor.colorset │ │ └── Contents.json │ ├── Fre │ │ ├── Contents.json │ │ ├── auth-app-img-light.imageset │ │ │ ├── Contents.json │ │ │ ├── auth-app-img-dark.png │ │ │ ├── auth-app-img-dark@2x.png │ │ │ ├── auth-app-img-dark@3x.png │ │ │ ├── auth-app-img-light.png │ │ │ ├── auth-app-img-light@2x.png │ │ │ └── auth-app-img-light@3x.png │ │ ├── auth-app-intro-2-yk5ci.imageset │ │ │ ├── Contents.json │ │ │ ├── auth-app-intro-2-yk5ci-dark.png │ │ │ ├── auth-app-intro-2-yk5ci-dark@2x.png │ │ │ ├── auth-app-intro-2-yk5ci-dark@3x.png │ │ │ ├── auth-app-intro-2-yk5ci.png │ │ │ ├── auth-app-intro-2-yk5ci@2x.png │ │ │ └── auth-app-intro-2-yk5ci@3x.png │ │ ├── auth-app-intro-3-yk-nfc.imageset │ │ │ ├── Contents.json │ │ │ ├── auth-app-intro-3-yk-nfc-dark.png │ │ │ ├── auth-app-intro-3-yk-nfc-dark@2x.png │ │ │ ├── auth-app-intro-3-yk-nfc-dark@3x.png │ │ │ ├── auth-app-intro-3-yk-nfc.png │ │ │ ├── auth-app-intro-3-yk-nfc@2x.png │ │ │ └── auth-app-intro-3-yk-nfc@3x.png │ │ └── auth-app-intro-4-qr-code.imageset │ │ │ ├── Contents.json │ │ │ ├── auth-app-intro-4-qr-code-dark.png │ │ │ ├── auth-app-intro-4-qr-code-dark@2x.png │ │ │ ├── auth-app-intro-4-qr-code-dark@3x.png │ │ │ ├── auth-app-intro-4-qr-code.png │ │ │ ├── auth-app-intro-4-qr-code@2x.png │ │ │ └── auth-app-intro-4-qr-code@3x.png │ ├── Icons │ │ ├── Contents.json │ │ ├── person.fill.badge.plus.imageset │ │ │ ├── Contents.json │ │ │ ├── person.fill.badge.plus@1x.png │ │ │ ├── person.fill.badge.plus@2x.png │ │ │ └── person.fill.badge.plus@3x.png │ │ ├── plus.imageset │ │ │ ├── Contents.json │ │ │ ├── plus@1x.png │ │ │ ├── plus@2x.png │ │ │ └── plus@3x.png │ │ ├── square.and.pencil.imageset │ │ │ ├── Contents.json │ │ │ ├── square.and.pencil@1x.png │ │ │ ├── square.and.pencil@2x.png │ │ │ └── square.and.pencil@3x.png │ │ ├── star.filled.imageset │ │ │ ├── Contents.json │ │ │ ├── ic_star_white.png │ │ │ ├── ic_star_white_2x.png │ │ │ └── ic_star_white_3x.png │ │ ├── star.imageset │ │ │ ├── Contents.json │ │ │ ├── ic_star_border_white.png │ │ │ ├── ic_star_border_white_2x.png │ │ │ └── ic_star_border_white_3x.png │ │ ├── touch.imageset │ │ │ ├── Contents.json │ │ │ ├── baseline_touch_app_black_24dp-1.png │ │ │ └── baseline_touch_app_black_24dp.png │ │ └── trash.imageset │ │ │ ├── Contents.json │ │ │ ├── ic_delete_white.png │ │ │ ├── ic_delete_white_2x.png │ │ │ └── ic_delete_white_3x.png │ ├── IconsColorSet │ │ ├── Color1.colorset │ │ │ └── Contents.json │ │ ├── Color10.colorset │ │ │ └── Contents.json │ │ ├── Color11.colorset │ │ │ └── Contents.json │ │ ├── Color12.colorset │ │ │ └── Contents.json │ │ ├── Color13.colorset │ │ │ └── Contents.json │ │ ├── Color14.colorset │ │ │ └── Contents.json │ │ ├── Color15.colorset │ │ │ └── Contents.json │ │ ├── Color16.colorset │ │ │ └── Contents.json │ │ ├── Color2.colorset │ │ │ └── Contents.json │ │ ├── Color3.colorset │ │ │ └── Contents.json │ │ ├── Color4.colorset │ │ │ └── Contents.json │ │ ├── Color5.colorset │ │ │ └── Contents.json │ │ ├── Color6.colorset │ │ │ └── Contents.json │ │ ├── Color7.colorset │ │ │ └── Contents.json │ │ ├── Color8.colorset │ │ │ └── Contents.json │ │ ├── Color9.colorset │ │ │ └── Contents.json │ │ └── Contents.json │ ├── InsertKey.imageset │ │ ├── Contents.json │ │ ├── icon-yk5ci-dark-mode.png │ │ ├── icon-yk5ci-dark-mode@2x.png │ │ └── icon-yk5ci-dark-mode@3x.png │ ├── LogoText.imageset │ │ ├── Contents.json │ │ └── big_logo.png │ ├── NavbarLogo.imageset │ │ ├── Contents.json │ │ └── logo-white.svg │ ├── NavbarLogoColor.colorset │ │ └── Contents.json │ ├── SymbolColor.colorset │ │ └── Contents.json │ ├── Symbols │ │ ├── Contents.json │ │ ├── yubikey.circle.fill.symbolset │ │ │ ├── Contents.json │ │ │ └── yubikey.circle.fill.svg │ │ └── yubikey.symbolset │ │ │ ├── Contents.json │ │ │ └── yubikey.svg │ ├── SystemNavigationBar.colorset │ │ └── Contents.json │ ├── What's New │ │ ├── Contents.json │ │ ├── biometric.imageset │ │ │ ├── Contents.json │ │ │ ├── icon-biometric-blue.png │ │ │ ├── icon-biometric-blue@2x.png │ │ │ ├── icon-biometric-blue@3x.png │ │ │ ├── icon-biometric-green.png │ │ │ ├── icon-biometric-green@2x.png │ │ │ └── icon-biometric-green@3x.png │ │ ├── customize.imageset │ │ │ ├── Contents.json │ │ │ ├── icon-customize-blue.png │ │ │ ├── icon-customize-blue@2x.png │ │ │ ├── icon-customize-blue@3x.png │ │ │ ├── icon-customize-green.png │ │ │ ├── icon-customize-green@2x.png │ │ │ └── icon-customize-green@3x.png │ │ └── deviceInfo.imageset │ │ │ ├── Contents.json │ │ │ ├── icon-dev-info-blue.png │ │ │ ├── icon-dev-info-blue@2x.png │ │ │ ├── icon-dev-info-blue@3x.png │ │ │ ├── icon-dev-info-green.png │ │ │ ├── icon-dev-info-green@2x.png │ │ │ └── icon-dev-info-green@3x.png │ ├── YubiKeys │ │ ├── Contents.json │ │ ├── yk5ci.imageset │ │ │ ├── Contents.json │ │ │ └── yk5ci@2x.png │ │ ├── yk5cnfc.imageset │ │ │ ├── Contents.json │ │ │ └── yk5cnfc@2x.png │ │ ├── yk5nfc.imageset │ │ │ ├── Contents.json │ │ │ └── yk5nfc@2x.png │ │ ├── ykbioa.imageset │ │ │ ├── Contents.json │ │ │ └── ykbioa.png │ │ └── ykbioc.imageset │ │ │ ├── Contents.json │ │ │ └── ykbioc.png │ ├── gear.imageset │ │ ├── Contents.json │ │ ├── cogwheel-black-24.png │ │ ├── cogwheel-black-48.png │ │ └── cogwheel-black-72.png │ ├── icon.imageset │ │ ├── AppIcon-60@2x.png │ │ ├── AppIcon-60@3x.png │ │ └── Contents.json │ └── yubikey-nfc.imageset │ │ ├── Contents.json │ │ ├── yubikey-nfc@1x.png │ │ ├── yubikey-nfc@2x.png │ │ └── yubikey-nfc@3x.png ├── Authenticator-Bridging-Header.h ├── Authenticator.entitlements ├── AuthenticatorApp.swift ├── Info.plist ├── InfoPlist.xcstrings ├── Licensing.md ├── Localizable.xcstrings ├── Model │ ├── AccessKeyCache.swift │ ├── Account.swift │ ├── ApplicationSessionObserver.swift │ ├── ApplicationSettingsViewModel.swift │ ├── ConfigurationViewModel.swift │ ├── Connection.swift │ ├── CryptoTokenKit │ │ └── TokenCertificateStorage.swift │ ├── DisableOTPModel.swift │ ├── Extensions │ │ ├── Logger+Extensions.swift │ │ ├── YKFConnectionProtocol+Extensions.swift │ │ ├── YKFKeyVersion+Extensions.swift │ │ └── YKFOATHSession+Extensions.swift │ ├── FIDOPINViewModel.swift │ ├── FIDOResetViewModel.swift │ ├── FavoritesStorage.swift │ ├── KeySessionError.swift │ ├── MainViewModel.swift │ ├── ManagementViewModel.swift │ ├── NotificationsViewModel.swift │ ├── OATHPasswordViewModel.swift │ ├── OATHResetViewModel.swift │ ├── OATHSavedPasswordsViewModel.swift │ ├── OATHSession.swift │ ├── PasswordCache.swift │ ├── PasswordStatusViewModel.swift │ ├── SecureStore │ │ ├── PasswordPreferences.swift │ │ ├── SecureStore.swift │ │ ├── SecureStoreError.swift │ │ └── SecureStoreQueryable.swift │ ├── SettingsConfig.swift │ ├── SmartCardViewModel.swift │ ├── TokenRequestViewModel.swift │ └── YubiKeyInformationViewModel.swift ├── UI │ ├── About │ │ ├── AboutView.swift │ │ ├── LicensingView.swift │ │ ├── TutorialView.swift │ │ └── VersionHistoryView.swift │ ├── AccountDetailsView.swift │ ├── AccountRowView.swift │ ├── Authentication │ │ ├── AddCredential │ │ │ ├── AddAccountWrapper.swift │ │ │ ├── AddCredentialController.swift │ │ │ ├── AdvancedSettingsViewController.swift │ │ │ ├── Base.lproj │ │ │ │ └── AddCredential.storyboard │ │ │ ├── ScanAccountView.swift │ │ │ └── mul.lproj │ │ │ │ └── AddCredential.xcstrings │ │ └── EditCredential │ │ │ ├── Base.lproj │ │ │ └── EditCredential.storyboard │ │ │ ├── EditAccountWrapper.swift │ │ │ ├── EditCredentialController.swift │ │ │ ├── EditFieldController.swift │ │ │ ├── SettingsRowView.swift │ │ │ └── mul.lproj │ │ │ └── EditCredential.xcstrings │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── Constants.swift │ ├── DisableOTPView.swift │ ├── ErrorAlertView.swift │ ├── Helpers │ │ ├── Data+Extensions.swift │ │ ├── DetachedMenu.swift │ │ ├── MenuGestureRecognizer.swift │ │ ├── SecCertificate+Extensions.swift │ │ ├── SettingsButton.swift │ │ ├── SettingsView.swift │ │ ├── ShowTime.swift │ │ ├── ToastPresenter.swift │ │ ├── ToastView.swift │ │ ├── UIAlertController+Extensions.swift │ │ ├── UIApplicationExtension.swift │ │ ├── UIButton+Extensions.swift │ │ ├── UIColorAdditions.swift │ │ ├── UIControl+Extensions.swift │ │ ├── UIFont+Extensions.swift │ │ ├── UIGestureRecognizer+Extensions.swift │ │ ├── UIImageAdditions.swift │ │ ├── UIViewAdditions.swift │ │ ├── UIViewControllerAdditions.swift │ │ ├── View+Extensions.swift │ │ └── YubiMenu.swift │ ├── ListStatusView.swift │ ├── MainView.swift │ ├── TokenSession │ │ ├── TokenRequestViewController.swift │ │ ├── TokenRequestWrapper.swift │ │ └── TokenRequestYubiOTPViewController.swift │ ├── YubiKeyConfiguration │ │ ├── ConfigurationView.swift │ │ ├── FIDOPINView.swift │ │ ├── FIDOResetView.swift │ │ ├── NFCSettingsController.swift │ │ ├── OATHPasswordView.swift │ │ ├── OATHResetView.swift │ │ ├── OATHSavedPasswordsView.swift │ │ ├── OTPConfigurationController.swift │ │ └── SmartCardConfigurationController.swift │ ├── YubiOtpRowView.swift │ └── mul.lproj │ │ ├── LaunchScreen.xcstrings │ │ └── Main.xcstrings └── VersionHistory.plist ├── AuthenticatorTests ├── AuthenticatorTests.swift ├── Info.plist ├── SecureStoreTests.swift └── YKFKeyVersionExtensionsTests.swift ├── LICENSE ├── LocalizationScreenshots ├── 1-start.jpeg ├── 10-add-account-manual.jpeg ├── 11-add-account-missing-secret.jpeg ├── 12-add-account-missing-name.jpeg ├── 13-configuration.jpeg ├── 14-configuration-toggle-otp.jpeg ├── 15-configuration-passwords-and-reset-1.jpeg ├── 16-configuration-passwords-and-reset-2.jpeg ├── 17-configuration-set-password.jpeg ├── 18-configuration-clear-passwords.jpeg ├── 19-configuration-nfc-settings.jpeg ├── 2-start-ready-to-scan.jpeg ├── 20-configuration-reset.jpeg ├── 21-configuration-smarrtcard.jpeg ├── 22-configuration-smartcard-enabled.jpeg ├── 23-configuration-smartcard-help.jpeg ├── 24-about.jpeg ├── 25-about-tutorial-1.jpeg ├── 26-about-tutorial-2.jpeg ├── 27-about-tutorial-3.jpeg ├── 28-about-tutorial-4.jpeg ├── 29-about-version-history.jpeg ├── 3-start-successfully-read.jpeg ├── 30-disable-otp.png ├── 31-smartcard-extension-notification.png ├── 32-smartcard-extension-unlock.jpeg ├── 33-smartcard-extension-done.png ├── 4-start-list.jpeg ├── 5-details.jpeg ├── 6-rename.jpeg ├── 7-delete-alert.jpeg ├── 8-start-menu.jpeg └── 9-add-account-qr-code.jpeg ├── Localizations ├── en.xcloc │ ├── Localized Contents │ │ └── en.xliff │ ├── Source Contents │ │ ├── Authenticator │ │ │ ├── UI │ │ │ │ └── Base.lproj │ │ │ │ │ ├── LaunchScreen.storyboard │ │ │ │ │ └── Main.storyboard │ │ │ └── en.lproj │ │ │ │ ├── InfoPlist.strings │ │ │ │ └── Localizable.strings │ │ └── TokenExtension │ │ │ └── en.lproj │ │ │ └── InfoPlist.strings │ └── contents.json └── en │ └── en.xcloc │ ├── Localized Contents │ └── en.xliff │ ├── Source Contents │ ├── Authenticator │ │ ├── UI │ │ │ └── Base.lproj │ │ │ │ ├── LaunchScreen.storyboard │ │ │ │ └── Main.storyboard │ │ └── en.lproj │ │ │ ├── InfoPlist.strings │ │ │ └── Localizable.strings │ └── TokenExtension │ │ └── en.lproj │ │ └── InfoPlist.strings │ └── contents.json ├── README.md ├── TokenExtension ├── Info.plist ├── InfoPlist.xcstrings ├── Localizable.xcstrings ├── TKTokenAlgorithm+Extensions.swift ├── Token.swift ├── TokenDriver.swift ├── TokenExtension.entitlements └── TokenSession.swift └── crowdin.yml /.github/workflows/swift.yml: -------------------------------------------------------------------------------- 1 | name: AuthenticatorTests 2 | 3 | on: [push] 4 | 5 | jobs: 6 | build: 7 | runs-on: macos-latest 8 | steps: 9 | - uses: actions/checkout@v2 10 | - name: Test on emulator 11 | run: xcodebuild clean test -disablePackageRepositoryCache -sdk iphonesimulator -project Authenticator.xcodeproj -scheme Authenticator -destination "platform=iOS Simulator,OS=latest,name=iPhone 11" | xcpretty --test --color && exit ${PIPESTATUS[0]} 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | *.moved-aside 22 | *.xccheckout 23 | *.xcscmblueprint 24 | .DS_Store 25 | 26 | ## Obj-C/Swift specific 27 | *.hmap 28 | *.ipa 29 | *.dSYM.zip 30 | *.dSYM 31 | 32 | ## Playgrounds 33 | timeline.xctimeline 34 | playground.xcworkspace 35 | 36 | # Swift Package Manager 37 | # 38 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 39 | # Packages/ 40 | # Package.pins 41 | # Package.resolved 42 | .build/ 43 | 44 | # CocoaPods 45 | # 46 | # We recommend against adding the Pods directory to your .gitignore. However 47 | # you should judge for yourself, the pros and cons are mentioned at: 48 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 49 | # 50 | Pods/ 51 | Podfile.lock 52 | 53 | # 54 | # Add this line if you want to avoid checking in source code from the Xcode workspace 55 | # *.xcworkspace 56 | 57 | # Carthage 58 | # 59 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 60 | # Carthage/Checkouts 61 | 62 | Carthage/Build 63 | 64 | # fastlane 65 | # 66 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 67 | # screenshots whenever they are needed. 68 | # For more information about the recommended setup visit: 69 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 70 | 71 | fastlane/report.xml 72 | fastlane/Preview.html 73 | fastlane/screenshots/**/*.png 74 | fastlane/test_output 75 | 76 | # Code Injection 77 | # 78 | # After new code Injection tools there's a generated folder /iOSInjectionProject 79 | # https://github.com/johnno1962/injectionforxcode 80 | 81 | iOSInjectionProject/ 82 | -------------------------------------------------------------------------------- /Authenticator.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Authenticator.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Authenticator/AddFromScanViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AddFromScanViewController.swift 3 | // Authenticator 4 | // 5 | // Created by Irina Makhalova on 7/27/19. 6 | // Copyright © 2019 Irina Makhalova. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class AddFromScanViewController: UIViewController { 12 | 13 | @IBOutlet weak var addButton: UIButton! 14 | override func viewDidLoad() { 15 | super.viewDidLoad() 16 | 17 | // Do any additional setup after loading the view. 18 | } 19 | 20 | 21 | 22 | // MARK: - Navigation 23 | 24 | // In a storyboard-based application, you will often want to do a little preparation before navigation 25 | override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 26 | // Get the new view controller using segue.destination. 27 | // Pass the selected object to the new view controller. 28 | 29 | guard let button = sender as? UIButton, button === addButton else { 30 | print("The add button was not pressed, cancelling") 31 | return 32 | } 33 | 34 | // Set the credential to be passed to MainViewController after the unwind segue. 35 | let credential = YKFOATHCredential() 36 | credential.issuer = "issuer" 37 | credential.account = "name" 38 | 39 | self.credential = credential 40 | } 41 | 42 | 43 | } 44 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0", 9 | "green" : "0", 10 | "red" : "0" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "255", 27 | "green" : "255", 28 | "red" : "255" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/AppIcon.appiconset/AppIcon-1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/AppIcon.appiconset/AppIcon-1024.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/AppIcon.appiconset/AppIcon-20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/AppIcon.appiconset/AppIcon-20.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/AppIcon.appiconset/AppIcon-20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/AppIcon.appiconset/AppIcon-20@2x.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/AppIcon.appiconset/AppIcon-20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/AppIcon.appiconset/AppIcon-20@3x.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/AppIcon.appiconset/AppIcon-29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/AppIcon.appiconset/AppIcon-29.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/AppIcon.appiconset/AppIcon-29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/AppIcon.appiconset/AppIcon-29@2x.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/AppIcon.appiconset/AppIcon-29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/AppIcon.appiconset/AppIcon-29@3x.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/AppIcon.appiconset/AppIcon-40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/AppIcon.appiconset/AppIcon-40.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/AppIcon.appiconset/AppIcon-40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/AppIcon.appiconset/AppIcon-40@2x.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/AppIcon.appiconset/AppIcon-40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/AppIcon.appiconset/AppIcon-40@3x.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/AppIcon.appiconset/AppIcon-60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/AppIcon.appiconset/AppIcon-60@2x.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/AppIcon.appiconset/AppIcon-60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/AppIcon.appiconset/AppIcon-60@3x.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/AppIcon.appiconset/AppIcon-76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/AppIcon.appiconset/AppIcon-76.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/AppIcon.appiconset/AppIcon-76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/AppIcon.appiconset/AppIcon-76@2x.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/AppIcon.appiconset/AppIcon-83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/AppIcon.appiconset/AppIcon-83.5@2x.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "AppIcon-20@2x.png", 5 | "idiom" : "iphone", 6 | "scale" : "2x", 7 | "size" : "20x20" 8 | }, 9 | { 10 | "filename" : "AppIcon-20@3x.png", 11 | "idiom" : "iphone", 12 | "scale" : "3x", 13 | "size" : "20x20" 14 | }, 15 | { 16 | "filename" : "AppIcon-29@2x.png", 17 | "idiom" : "iphone", 18 | "scale" : "2x", 19 | "size" : "29x29" 20 | }, 21 | { 22 | "filename" : "AppIcon-29@3x.png", 23 | "idiom" : "iphone", 24 | "scale" : "3x", 25 | "size" : "29x29" 26 | }, 27 | { 28 | "filename" : "AppIcon-40@2x.png", 29 | "idiom" : "iphone", 30 | "scale" : "2x", 31 | "size" : "40x40" 32 | }, 33 | { 34 | "filename" : "AppIcon-40@3x.png", 35 | "idiom" : "iphone", 36 | "scale" : "3x", 37 | "size" : "40x40" 38 | }, 39 | { 40 | "filename" : "AppIcon-60@2x.png", 41 | "idiom" : "iphone", 42 | "scale" : "2x", 43 | "size" : "60x60" 44 | }, 45 | { 46 | "filename" : "AppIcon-60@3x.png", 47 | "idiom" : "iphone", 48 | "scale" : "3x", 49 | "size" : "60x60" 50 | }, 51 | { 52 | "filename" : "AppIcon-20.png", 53 | "idiom" : "ipad", 54 | "scale" : "1x", 55 | "size" : "20x20" 56 | }, 57 | { 58 | "filename" : "AppIcon-20@2x.png", 59 | "idiom" : "ipad", 60 | "scale" : "2x", 61 | "size" : "20x20" 62 | }, 63 | { 64 | "filename" : "AppIcon-29.png", 65 | "idiom" : "ipad", 66 | "scale" : "1x", 67 | "size" : "29x29" 68 | }, 69 | { 70 | "filename" : "AppIcon-29@2x.png", 71 | "idiom" : "ipad", 72 | "scale" : "2x", 73 | "size" : "29x29" 74 | }, 75 | { 76 | "filename" : "AppIcon-40.png", 77 | "idiom" : "ipad", 78 | "scale" : "1x", 79 | "size" : "40x40" 80 | }, 81 | { 82 | "filename" : "AppIcon-40@2x.png", 83 | "idiom" : "ipad", 84 | "scale" : "2x", 85 | "size" : "40x40" 86 | }, 87 | { 88 | "filename" : "AppIcon-76.png", 89 | "idiom" : "ipad", 90 | "scale" : "1x", 91 | "size" : "76x76" 92 | }, 93 | { 94 | "filename" : "AppIcon-76@2x.png", 95 | "idiom" : "ipad", 96 | "scale" : "2x", 97 | "size" : "76x76" 98 | }, 99 | { 100 | "filename" : "AppIcon-83.5@2x.png", 101 | "idiom" : "ipad", 102 | "scale" : "2x", 103 | "size" : "83.5x83.5" 104 | }, 105 | { 106 | "filename" : "AppIcon-1024.png", 107 | "idiom" : "ios-marketing", 108 | "scale" : "1x", 109 | "size" : "1024x1024" 110 | } 111 | ], 112 | "info" : { 113 | "author" : "xcode", 114 | "version" : 1 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/CustomColors/CodeBorder.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "display-p3", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.764", 9 | "green" : "0.764", 10 | "red" : "0.756" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "display-p3", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0.267", 27 | "green" : "0.267", 28 | "red" : "0.266" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/CustomColors/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/CustomColors/DetailsBackground.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "1.000", 9 | "green" : "1.000", 10 | "red" : "1.000" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "46", 27 | "green" : "44", 28 | "red" : "44" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/CustomColors/DetailsCodeBackground.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "display-p3", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0xF2", 9 | "green" : "0xEF", 10 | "red" : "0xEF" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "display-p3", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0.225", 27 | "green" : "0.215", 28 | "red" : "0.214" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/CustomColors/Favorite.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0x0A", 9 | "green" : "0xD6", 10 | "red" : "0xFF" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | } 15 | ], 16 | "info" : { 17 | "author" : "xcode", 18 | "version" : 1 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/CustomColors/ListSectionHeaderColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "extended-gray", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "white" : "0.000" 9 | } 10 | }, 11 | "idiom" : "universal" 12 | }, 13 | { 14 | "appearances" : [ 15 | { 16 | "appearance" : "luminosity", 17 | "value" : "dark" 18 | } 19 | ], 20 | "color" : { 21 | "color-space" : "extended-gray", 22 | "components" : { 23 | "alpha" : "1.000", 24 | "white" : "0.926" 25 | } 26 | }, 27 | "idiom" : "universal" 28 | } 29 | ], 30 | "info" : { 31 | "author" : "xcode", 32 | "version" : 1 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/CustomColors/MenuBackground.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.945", 9 | "green" : "0.937", 10 | "red" : "0.937" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0.173", 27 | "green" : "0.165", 28 | "red" : "0.165" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/CustomColors/MenuDivider.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "display-p3", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.827", 9 | "green" : "0.809", 10 | "red" : "0.810" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0.322", 27 | "green" : "0.314", 28 | "red" : "0.318" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/CustomColors/MenuSelectedBackground.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "display-p3", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.882", 9 | "green" : "0.882", 10 | "red" : "0.882" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "display-p3", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0.239", 27 | "green" : "0.239", 28 | "red" : "0.239" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/CustomColors/SearchBackground.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.937", 9 | "green" : "0.933", 10 | "red" : "0.933" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0.176", 27 | "green" : "0.169", 28 | "red" : "0.169" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/CustomColors/SearchBarBackground.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.996", 9 | "green" : "0.996", 10 | "red" : "0.996" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "30", 27 | "green" : "28", 28 | "red" : "28" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/CustomColors/SheetBackgroundColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.961", 9 | "green" : "0.945", 10 | "red" : "0.949" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "30", 27 | "green" : "28", 28 | "red" : "28" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/CustomColors/TableBackgroundColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.961", 9 | "green" : "0.945", 10 | "red" : "0.949" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0", 27 | "green" : "0", 28 | "red" : "0" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/CustomColors/TableSelection.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "display-p3", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.944", 9 | "green" : "0.935", 10 | "red" : "0.939" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "display-p3", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0.171", 27 | "green" : "0.169", 28 | "red" : "0.169" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/CustomColors/YubiBlue.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.455", 9 | "green" : "0.373", 10 | "red" : "0.196" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "display-p3", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0.416", 27 | "green" : "0.808", 28 | "red" : "0.643" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/CustomColors/YubiGreen.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "display-p3", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.416", 9 | "green" : "0.808", 10 | "red" : "0.643" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "idiom" : "universal" 23 | } 24 | ], 25 | "info" : { 26 | "author" : "xcode", 27 | "version" : 1 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/CustomTableBackgroundColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "1.000", 9 | "green" : "1.000", 10 | "red" : "1.000" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "display-p3", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0.114", 27 | "green" : "0.106", 28 | "red" : "0.110" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/Fre/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/Fre/auth-app-img-light.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "auth-app-img-light.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "auth-app-img-dark.png", 11 | "appearances" : [ 12 | { 13 | "appearance" : "luminosity", 14 | "value" : "dark" 15 | } 16 | ], 17 | "scale" : "1x" 18 | }, 19 | { 20 | "idiom" : "universal", 21 | "filename" : "auth-app-img-light@2x.png", 22 | "scale" : "2x" 23 | }, 24 | { 25 | "idiom" : "universal", 26 | "filename" : "auth-app-img-dark@2x.png", 27 | "appearances" : [ 28 | { 29 | "appearance" : "luminosity", 30 | "value" : "dark" 31 | } 32 | ], 33 | "scale" : "2x" 34 | }, 35 | { 36 | "idiom" : "universal", 37 | "filename" : "auth-app-img-light@3x.png", 38 | "scale" : "3x" 39 | }, 40 | { 41 | "idiom" : "universal", 42 | "filename" : "auth-app-img-dark@3x.png", 43 | "appearances" : [ 44 | { 45 | "appearance" : "luminosity", 46 | "value" : "dark" 47 | } 48 | ], 49 | "scale" : "3x" 50 | } 51 | ], 52 | "info" : { 53 | "version" : 1, 54 | "author" : "xcode" 55 | } 56 | } -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/Fre/auth-app-img-light.imageset/auth-app-img-dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/Fre/auth-app-img-light.imageset/auth-app-img-dark.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/Fre/auth-app-img-light.imageset/auth-app-img-dark@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/Fre/auth-app-img-light.imageset/auth-app-img-dark@2x.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/Fre/auth-app-img-light.imageset/auth-app-img-dark@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/Fre/auth-app-img-light.imageset/auth-app-img-dark@3x.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/Fre/auth-app-img-light.imageset/auth-app-img-light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/Fre/auth-app-img-light.imageset/auth-app-img-light.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/Fre/auth-app-img-light.imageset/auth-app-img-light@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/Fre/auth-app-img-light.imageset/auth-app-img-light@2x.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/Fre/auth-app-img-light.imageset/auth-app-img-light@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/Fre/auth-app-img-light.imageset/auth-app-img-light@3x.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/Fre/auth-app-intro-2-yk5ci.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "auth-app-intro-2-yk5ci.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "auth-app-intro-2-yk5ci-dark.png", 11 | "appearances" : [ 12 | { 13 | "appearance" : "luminosity", 14 | "value" : "dark" 15 | } 16 | ], 17 | "scale" : "1x" 18 | }, 19 | { 20 | "idiom" : "universal", 21 | "filename" : "auth-app-intro-2-yk5ci@2x.png", 22 | "scale" : "2x" 23 | }, 24 | { 25 | "idiom" : "universal", 26 | "filename" : "auth-app-intro-2-yk5ci-dark@2x.png", 27 | "appearances" : [ 28 | { 29 | "appearance" : "luminosity", 30 | "value" : "dark" 31 | } 32 | ], 33 | "scale" : "2x" 34 | }, 35 | { 36 | "idiom" : "universal", 37 | "filename" : "auth-app-intro-2-yk5ci@3x.png", 38 | "scale" : "3x" 39 | }, 40 | { 41 | "idiom" : "universal", 42 | "filename" : "auth-app-intro-2-yk5ci-dark@3x.png", 43 | "appearances" : [ 44 | { 45 | "appearance" : "luminosity", 46 | "value" : "dark" 47 | } 48 | ], 49 | "scale" : "3x" 50 | } 51 | ], 52 | "info" : { 53 | "version" : 1, 54 | "author" : "xcode" 55 | } 56 | } -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/Fre/auth-app-intro-2-yk5ci.imageset/auth-app-intro-2-yk5ci-dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/Fre/auth-app-intro-2-yk5ci.imageset/auth-app-intro-2-yk5ci-dark.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/Fre/auth-app-intro-2-yk5ci.imageset/auth-app-intro-2-yk5ci-dark@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/Fre/auth-app-intro-2-yk5ci.imageset/auth-app-intro-2-yk5ci-dark@2x.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/Fre/auth-app-intro-2-yk5ci.imageset/auth-app-intro-2-yk5ci-dark@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/Fre/auth-app-intro-2-yk5ci.imageset/auth-app-intro-2-yk5ci-dark@3x.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/Fre/auth-app-intro-2-yk5ci.imageset/auth-app-intro-2-yk5ci.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/Fre/auth-app-intro-2-yk5ci.imageset/auth-app-intro-2-yk5ci.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/Fre/auth-app-intro-2-yk5ci.imageset/auth-app-intro-2-yk5ci@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/Fre/auth-app-intro-2-yk5ci.imageset/auth-app-intro-2-yk5ci@2x.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/Fre/auth-app-intro-2-yk5ci.imageset/auth-app-intro-2-yk5ci@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/Fre/auth-app-intro-2-yk5ci.imageset/auth-app-intro-2-yk5ci@3x.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/Fre/auth-app-intro-3-yk-nfc.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "auth-app-intro-3-yk-nfc.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "auth-app-intro-3-yk-nfc-dark.png", 11 | "appearances" : [ 12 | { 13 | "appearance" : "luminosity", 14 | "value" : "dark" 15 | } 16 | ], 17 | "scale" : "1x" 18 | }, 19 | { 20 | "idiom" : "universal", 21 | "filename" : "auth-app-intro-3-yk-nfc@2x.png", 22 | "scale" : "2x" 23 | }, 24 | { 25 | "idiom" : "universal", 26 | "filename" : "auth-app-intro-3-yk-nfc-dark@2x.png", 27 | "appearances" : [ 28 | { 29 | "appearance" : "luminosity", 30 | "value" : "dark" 31 | } 32 | ], 33 | "scale" : "2x" 34 | }, 35 | { 36 | "idiom" : "universal", 37 | "filename" : "auth-app-intro-3-yk-nfc@3x.png", 38 | "scale" : "3x" 39 | }, 40 | { 41 | "idiom" : "universal", 42 | "filename" : "auth-app-intro-3-yk-nfc-dark@3x.png", 43 | "appearances" : [ 44 | { 45 | "appearance" : "luminosity", 46 | "value" : "dark" 47 | } 48 | ], 49 | "scale" : "3x" 50 | } 51 | ], 52 | "info" : { 53 | "version" : 1, 54 | "author" : "xcode" 55 | } 56 | } -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/Fre/auth-app-intro-3-yk-nfc.imageset/auth-app-intro-3-yk-nfc-dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/Fre/auth-app-intro-3-yk-nfc.imageset/auth-app-intro-3-yk-nfc-dark.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/Fre/auth-app-intro-3-yk-nfc.imageset/auth-app-intro-3-yk-nfc-dark@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/Fre/auth-app-intro-3-yk-nfc.imageset/auth-app-intro-3-yk-nfc-dark@2x.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/Fre/auth-app-intro-3-yk-nfc.imageset/auth-app-intro-3-yk-nfc-dark@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/Fre/auth-app-intro-3-yk-nfc.imageset/auth-app-intro-3-yk-nfc-dark@3x.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/Fre/auth-app-intro-3-yk-nfc.imageset/auth-app-intro-3-yk-nfc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/Fre/auth-app-intro-3-yk-nfc.imageset/auth-app-intro-3-yk-nfc.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/Fre/auth-app-intro-3-yk-nfc.imageset/auth-app-intro-3-yk-nfc@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/Fre/auth-app-intro-3-yk-nfc.imageset/auth-app-intro-3-yk-nfc@2x.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/Fre/auth-app-intro-3-yk-nfc.imageset/auth-app-intro-3-yk-nfc@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/Fre/auth-app-intro-3-yk-nfc.imageset/auth-app-intro-3-yk-nfc@3x.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/Fre/auth-app-intro-4-qr-code.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "auth-app-intro-4-qr-code.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "auth-app-intro-4-qr-code-dark.png", 11 | "appearances" : [ 12 | { 13 | "appearance" : "luminosity", 14 | "value" : "dark" 15 | } 16 | ], 17 | "scale" : "1x" 18 | }, 19 | { 20 | "idiom" : "universal", 21 | "filename" : "auth-app-intro-4-qr-code@2x.png", 22 | "scale" : "2x" 23 | }, 24 | { 25 | "idiom" : "universal", 26 | "filename" : "auth-app-intro-4-qr-code-dark@2x.png", 27 | "appearances" : [ 28 | { 29 | "appearance" : "luminosity", 30 | "value" : "dark" 31 | } 32 | ], 33 | "scale" : "2x" 34 | }, 35 | { 36 | "idiom" : "universal", 37 | "filename" : "auth-app-intro-4-qr-code@3x.png", 38 | "scale" : "3x" 39 | }, 40 | { 41 | "idiom" : "universal", 42 | "filename" : "auth-app-intro-4-qr-code-dark@3x.png", 43 | "appearances" : [ 44 | { 45 | "appearance" : "luminosity", 46 | "value" : "dark" 47 | } 48 | ], 49 | "scale" : "3x" 50 | } 51 | ], 52 | "info" : { 53 | "version" : 1, 54 | "author" : "xcode" 55 | } 56 | } -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/Fre/auth-app-intro-4-qr-code.imageset/auth-app-intro-4-qr-code-dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/Fre/auth-app-intro-4-qr-code.imageset/auth-app-intro-4-qr-code-dark.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/Fre/auth-app-intro-4-qr-code.imageset/auth-app-intro-4-qr-code-dark@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/Fre/auth-app-intro-4-qr-code.imageset/auth-app-intro-4-qr-code-dark@2x.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/Fre/auth-app-intro-4-qr-code.imageset/auth-app-intro-4-qr-code-dark@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/Fre/auth-app-intro-4-qr-code.imageset/auth-app-intro-4-qr-code-dark@3x.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/Fre/auth-app-intro-4-qr-code.imageset/auth-app-intro-4-qr-code.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/Fre/auth-app-intro-4-qr-code.imageset/auth-app-intro-4-qr-code.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/Fre/auth-app-intro-4-qr-code.imageset/auth-app-intro-4-qr-code@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/Fre/auth-app-intro-4-qr-code.imageset/auth-app-intro-4-qr-code@2x.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/Fre/auth-app-intro-4-qr-code.imageset/auth-app-intro-4-qr-code@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/Fre/auth-app-intro-4-qr-code.imageset/auth-app-intro-4-qr-code@3x.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/Icons/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/Icons/person.fill.badge.plus.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "person.fill.badge.plus@1x.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "person.fill.badge.plus@2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "person.fill.badge.plus@3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/Icons/person.fill.badge.plus.imageset/person.fill.badge.plus@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/Icons/person.fill.badge.plus.imageset/person.fill.badge.plus@1x.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/Icons/person.fill.badge.plus.imageset/person.fill.badge.plus@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/Icons/person.fill.badge.plus.imageset/person.fill.badge.plus@2x.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/Icons/person.fill.badge.plus.imageset/person.fill.badge.plus@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/Icons/person.fill.badge.plus.imageset/person.fill.badge.plus@3x.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/Icons/plus.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "plus@1x.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "plus@2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "plus@3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/Icons/plus.imageset/plus@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/Icons/plus.imageset/plus@1x.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/Icons/plus.imageset/plus@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/Icons/plus.imageset/plus@2x.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/Icons/plus.imageset/plus@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/Icons/plus.imageset/plus@3x.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/Icons/square.and.pencil.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "square.and.pencil@1x.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "square.and.pencil@2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "square.and.pencil@3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/Icons/square.and.pencil.imageset/square.and.pencil@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/Icons/square.and.pencil.imageset/square.and.pencil@1x.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/Icons/square.and.pencil.imageset/square.and.pencil@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/Icons/square.and.pencil.imageset/square.and.pencil@2x.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/Icons/square.and.pencil.imageset/square.and.pencil@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/Icons/square.and.pencil.imageset/square.and.pencil@3x.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/Icons/star.filled.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "ic_star_white.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "ic_star_white_2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "ic_star_white_3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/Icons/star.filled.imageset/ic_star_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/Icons/star.filled.imageset/ic_star_white.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/Icons/star.filled.imageset/ic_star_white_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/Icons/star.filled.imageset/ic_star_white_2x.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/Icons/star.filled.imageset/ic_star_white_3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/Icons/star.filled.imageset/ic_star_white_3x.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/Icons/star.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "ic_star_border_white.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "ic_star_border_white_2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "ic_star_border_white_3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | }, 23 | "properties" : { 24 | "template-rendering-intent" : "template" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/Icons/star.imageset/ic_star_border_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/Icons/star.imageset/ic_star_border_white.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/Icons/star.imageset/ic_star_border_white_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/Icons/star.imageset/ic_star_border_white_2x.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/Icons/star.imageset/ic_star_border_white_3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/Icons/star.imageset/ic_star_border_white_3x.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/Icons/touch.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "baseline_touch_app_black_24dp-1.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "baseline_touch_app_black_24dp.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "author" : "xcode", 20 | "version" : 1 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/Icons/touch.imageset/baseline_touch_app_black_24dp-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/Icons/touch.imageset/baseline_touch_app_black_24dp-1.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/Icons/touch.imageset/baseline_touch_app_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/Icons/touch.imageset/baseline_touch_app_black_24dp.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/Icons/trash.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "ic_delete_white.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "ic_delete_white_2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "ic_delete_white_3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/Icons/trash.imageset/ic_delete_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/Icons/trash.imageset/ic_delete_white.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/Icons/trash.imageset/ic_delete_white_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/Icons/trash.imageset/ic_delete_white_2x.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/Icons/trash.imageset/ic_delete_white_3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/Icons/trash.imageset/ic_delete_white_3x.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/IconsColorSet/Color1.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0x35", 9 | "green" : "0x39", 10 | "red" : "0xE5" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "display-p3", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0x45", 27 | "green" : "0x4F", 28 | "red" : "0xE4" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/IconsColorSet/Color10.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0x47", 9 | "green" : "0xA0", 10 | "red" : "0x43" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "display-p3", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0x5A", 27 | "green" : "0xB0", 28 | "red" : "0x65" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/IconsColorSet/Color11.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0x42", 9 | "green" : "0xB3", 10 | "red" : "0x7C" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "display-p3", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0x5D", 27 | "green" : "0xC3", 28 | "red" : "0x96" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/IconsColorSet/Color12.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0x33", 9 | "green" : "0xCA", 10 | "red" : "0xC0" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "display-p3", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0x58", 27 | "green" : "0xD6", 28 | "red" : "0xCD" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/IconsColorSet/Color13.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "display-p3", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0x4E", 9 | "green" : "0xE5", 10 | "red" : "0xE6" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "display-p3", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0x55", 27 | "green" : "0xF3", 28 | "red" : "0xF5" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/IconsColorSet/Color14.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0x00", 9 | "green" : "0xB3", 10 | "red" : "0xFF" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "display-p3", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0x41", 27 | "green" : "0xBA", 28 | "red" : "0xF8" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/IconsColorSet/Color15.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0x00", 9 | "green" : "0x8C", 10 | "red" : "0xFB" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "display-p3", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0x39", 27 | "green" : "0x97", 28 | "red" : "0xF6" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/IconsColorSet/Color16.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0x1E", 9 | "green" : "0x51", 10 | "red" : "0xF4" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "display-p3", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0x36", 27 | "green" : "0x61", 28 | "red" : "0xEC" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/IconsColorSet/Color2.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0x60", 9 | "green" : "0x1B", 10 | "red" : "0xD8" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "display-p3", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0x6F", 27 | "green" : "0x3A", 28 | "red" : "0xDE" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/IconsColorSet/Color3.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0xAA", 9 | "green" : "0x24", 10 | "red" : "0x8E" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "display-p3", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0xBB", 27 | "green" : "0x32", 28 | "red" : "0x93" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/IconsColorSet/Color4.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0xB1", 9 | "green" : "0x35", 10 | "red" : "0x5E" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "display-p3", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0xD0", 27 | "green" : "0x41", 28 | "red" : "0x69" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/IconsColorSet/Color5.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0xAB", 9 | "green" : "0x49", 10 | "red" : "0x39" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "display-p3", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0xBD", 27 | "green" : "0x50", 28 | "red" : "0x42" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/IconsColorSet/Color6.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0xE5", 9 | "green" : "0x88", 10 | "red" : "0x1E" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "display-p3", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0xEC", 27 | "green" : "0x8B", 28 | "red" : "0x43" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/IconsColorSet/Color7.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0xE5", 9 | "green" : "0x9B", 10 | "red" : "0x03" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "display-p3", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0xEE", 27 | "green" : "0xA2", 28 | "red" : "0x48" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/IconsColorSet/Color8.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0xC1", 9 | "green" : "0xAC", 10 | "red" : "0x00" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "display-p3", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0xCF", 27 | "green" : "0xB7", 28 | "red" : "0x50" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/IconsColorSet/Color9.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0x7B", 9 | "green" : "0x89", 10 | "red" : "0x00" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "display-p3", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0x8E", 27 | "green" : "0x9A", 28 | "red" : "0x43" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/IconsColorSet/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/InsertKey.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "icon-yk5ci-dark-mode.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "icon-yk5ci-dark-mode@2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "icon-yk5ci-dark-mode@3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | }, 23 | "properties" : { 24 | "template-rendering-intent" : "template" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/InsertKey.imageset/icon-yk5ci-dark-mode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/InsertKey.imageset/icon-yk5ci-dark-mode.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/InsertKey.imageset/icon-yk5ci-dark-mode@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/InsertKey.imageset/icon-yk5ci-dark-mode@2x.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/InsertKey.imageset/icon-yk5ci-dark-mode@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/InsertKey.imageset/icon-yk5ci-dark-mode@3x.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/LogoText.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "appearances" : [ 9 | { 10 | "appearance" : "luminosity", 11 | "value" : "dark" 12 | } 13 | ], 14 | "idiom" : "universal", 15 | "scale" : "1x" 16 | }, 17 | { 18 | "idiom" : "universal", 19 | "scale" : "2x" 20 | }, 21 | { 22 | "appearances" : [ 23 | { 24 | "appearance" : "luminosity", 25 | "value" : "dark" 26 | } 27 | ], 28 | "idiom" : "universal", 29 | "scale" : "2x" 30 | }, 31 | { 32 | "filename" : "big_logo.png", 33 | "idiom" : "universal", 34 | "scale" : "3x" 35 | }, 36 | { 37 | "appearances" : [ 38 | { 39 | "appearance" : "luminosity", 40 | "value" : "dark" 41 | } 42 | ], 43 | "idiom" : "universal", 44 | "scale" : "3x" 45 | } 46 | ], 47 | "info" : { 48 | "author" : "xcode", 49 | "version" : 1 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/LogoText.imageset/big_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/LogoText.imageset/big_logo.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/NavbarLogo.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "logo-white.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/NavbarLogoColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "display-p3", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.329", 9 | "green" : "0.787", 10 | "red" : "0.641" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "1.000", 27 | "green" : "1.000", 28 | "red" : "1.000" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/SymbolColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0x66", 9 | "green" : "0x66", 10 | "red" : "0x66" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0xCC", 27 | "green" : "0xCC", 28 | "red" : "0xCC" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/Symbols/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/Symbols/yubikey.circle.fill.symbolset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | }, 6 | "symbols" : [ 7 | { 8 | "filename" : "yubikey.circle.fill.svg", 9 | "idiom" : "universal" 10 | } 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/Symbols/yubikey.symbolset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | }, 6 | "symbols" : [ 7 | { 8 | "filename" : "yubikey.svg", 9 | "idiom" : "universal" 10 | } 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/SystemNavigationBar.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "247", 9 | "green" : "247", 10 | "red" : "247" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "display-p3", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "41", 27 | "green" : "39", 28 | "red" : "40" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/What's New/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/What's New/biometric.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "icon-biometric-blue.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "appearances" : [ 10 | { 11 | "appearance" : "luminosity", 12 | "value" : "dark" 13 | } 14 | ], 15 | "filename" : "icon-biometric-green.png", 16 | "idiom" : "universal", 17 | "scale" : "1x" 18 | }, 19 | { 20 | "filename" : "icon-biometric-blue@2x.png", 21 | "idiom" : "universal", 22 | "scale" : "2x" 23 | }, 24 | { 25 | "appearances" : [ 26 | { 27 | "appearance" : "luminosity", 28 | "value" : "dark" 29 | } 30 | ], 31 | "filename" : "icon-biometric-green@2x.png", 32 | "idiom" : "universal", 33 | "scale" : "2x" 34 | }, 35 | { 36 | "filename" : "icon-biometric-blue@3x.png", 37 | "idiom" : "universal", 38 | "scale" : "3x" 39 | }, 40 | { 41 | "appearances" : [ 42 | { 43 | "appearance" : "luminosity", 44 | "value" : "dark" 45 | } 46 | ], 47 | "filename" : "icon-biometric-green@3x.png", 48 | "idiom" : "universal", 49 | "scale" : "3x" 50 | } 51 | ], 52 | "info" : { 53 | "author" : "xcode", 54 | "version" : 1 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/What's New/biometric.imageset/icon-biometric-blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/What's New/biometric.imageset/icon-biometric-blue.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/What's New/biometric.imageset/icon-biometric-blue@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/What's New/biometric.imageset/icon-biometric-blue@2x.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/What's New/biometric.imageset/icon-biometric-blue@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/What's New/biometric.imageset/icon-biometric-blue@3x.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/What's New/biometric.imageset/icon-biometric-green.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/What's New/biometric.imageset/icon-biometric-green.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/What's New/biometric.imageset/icon-biometric-green@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/What's New/biometric.imageset/icon-biometric-green@2x.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/What's New/biometric.imageset/icon-biometric-green@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/What's New/biometric.imageset/icon-biometric-green@3x.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/What's New/customize.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "icon-customize-blue.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "appearances" : [ 10 | { 11 | "appearance" : "luminosity", 12 | "value" : "dark" 13 | } 14 | ], 15 | "filename" : "icon-customize-green.png", 16 | "idiom" : "universal", 17 | "scale" : "1x" 18 | }, 19 | { 20 | "filename" : "icon-customize-blue@2x.png", 21 | "idiom" : "universal", 22 | "scale" : "2x" 23 | }, 24 | { 25 | "appearances" : [ 26 | { 27 | "appearance" : "luminosity", 28 | "value" : "dark" 29 | } 30 | ], 31 | "filename" : "icon-customize-green@2x.png", 32 | "idiom" : "universal", 33 | "scale" : "2x" 34 | }, 35 | { 36 | "filename" : "icon-customize-blue@3x.png", 37 | "idiom" : "universal", 38 | "scale" : "3x" 39 | }, 40 | { 41 | "appearances" : [ 42 | { 43 | "appearance" : "luminosity", 44 | "value" : "dark" 45 | } 46 | ], 47 | "filename" : "icon-customize-green@3x.png", 48 | "idiom" : "universal", 49 | "scale" : "3x" 50 | } 51 | ], 52 | "info" : { 53 | "author" : "xcode", 54 | "version" : 1 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/What's New/customize.imageset/icon-customize-blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/What's New/customize.imageset/icon-customize-blue.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/What's New/customize.imageset/icon-customize-blue@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/What's New/customize.imageset/icon-customize-blue@2x.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/What's New/customize.imageset/icon-customize-blue@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/What's New/customize.imageset/icon-customize-blue@3x.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/What's New/customize.imageset/icon-customize-green.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/What's New/customize.imageset/icon-customize-green.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/What's New/customize.imageset/icon-customize-green@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/What's New/customize.imageset/icon-customize-green@2x.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/What's New/customize.imageset/icon-customize-green@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/What's New/customize.imageset/icon-customize-green@3x.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/What's New/deviceInfo.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "icon-dev-info-blue.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "appearances" : [ 10 | { 11 | "appearance" : "luminosity", 12 | "value" : "dark" 13 | } 14 | ], 15 | "filename" : "icon-dev-info-green.png", 16 | "idiom" : "universal", 17 | "scale" : "1x" 18 | }, 19 | { 20 | "filename" : "icon-dev-info-blue@2x.png", 21 | "idiom" : "universal", 22 | "scale" : "2x" 23 | }, 24 | { 25 | "appearances" : [ 26 | { 27 | "appearance" : "luminosity", 28 | "value" : "dark" 29 | } 30 | ], 31 | "filename" : "icon-dev-info-green@2x.png", 32 | "idiom" : "universal", 33 | "scale" : "2x" 34 | }, 35 | { 36 | "filename" : "icon-dev-info-blue@3x.png", 37 | "idiom" : "universal", 38 | "scale" : "3x" 39 | }, 40 | { 41 | "appearances" : [ 42 | { 43 | "appearance" : "luminosity", 44 | "value" : "dark" 45 | } 46 | ], 47 | "filename" : "icon-dev-info-green@3x.png", 48 | "idiom" : "universal", 49 | "scale" : "3x" 50 | } 51 | ], 52 | "info" : { 53 | "author" : "xcode", 54 | "version" : 1 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/What's New/deviceInfo.imageset/icon-dev-info-blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/What's New/deviceInfo.imageset/icon-dev-info-blue.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/What's New/deviceInfo.imageset/icon-dev-info-blue@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/What's New/deviceInfo.imageset/icon-dev-info-blue@2x.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/What's New/deviceInfo.imageset/icon-dev-info-blue@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/What's New/deviceInfo.imageset/icon-dev-info-blue@3x.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/What's New/deviceInfo.imageset/icon-dev-info-green.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/What's New/deviceInfo.imageset/icon-dev-info-green.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/What's New/deviceInfo.imageset/icon-dev-info-green@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/What's New/deviceInfo.imageset/icon-dev-info-green@2x.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/What's New/deviceInfo.imageset/icon-dev-info-green@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/What's New/deviceInfo.imageset/icon-dev-info-green@3x.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/YubiKeys/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/YubiKeys/yk5ci.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "yk5ci@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/YubiKeys/yk5ci.imageset/yk5ci@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/YubiKeys/yk5ci.imageset/yk5ci@2x.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/YubiKeys/yk5cnfc.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "yk5cnfc@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/YubiKeys/yk5cnfc.imageset/yk5cnfc@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/YubiKeys/yk5cnfc.imageset/yk5cnfc@2x.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/YubiKeys/yk5nfc.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "yk5nfc@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/YubiKeys/yk5nfc.imageset/yk5nfc@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/YubiKeys/yk5nfc.imageset/yk5nfc@2x.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/YubiKeys/ykbioa.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "ykbioa.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/YubiKeys/ykbioa.imageset/ykbioa.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/YubiKeys/ykbioa.imageset/ykbioa.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/YubiKeys/ykbioc.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "ykbioc.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/YubiKeys/ykbioc.imageset/ykbioc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/YubiKeys/ykbioc.imageset/ykbioc.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/gear.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "cogwheel-black-24.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "cogwheel-black-48.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "cogwheel-black-72.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/gear.imageset/cogwheel-black-24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/gear.imageset/cogwheel-black-24.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/gear.imageset/cogwheel-black-48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/gear.imageset/cogwheel-black-48.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/gear.imageset/cogwheel-black-72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/gear.imageset/cogwheel-black-72.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/icon.imageset/AppIcon-60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/icon.imageset/AppIcon-60@2x.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/icon.imageset/AppIcon-60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/icon.imageset/AppIcon-60@3x.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "AppIcon-60@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "filename" : "AppIcon-60@3x.png", 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "author" : "xcode", 20 | "version" : 1 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/yubikey-nfc.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "yubikey-nfc@1x.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "yubikey-nfc@2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "yubikey-nfc@3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | }, 23 | "properties" : { 24 | "template-rendering-intent" : "template" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/yubikey-nfc.imageset/yubikey-nfc@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/yubikey-nfc.imageset/yubikey-nfc@1x.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/yubikey-nfc.imageset/yubikey-nfc@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/yubikey-nfc.imageset/yubikey-nfc@2x.png -------------------------------------------------------------------------------- /Authenticator/Assets.xcassets/yubikey-nfc.imageset/yubikey-nfc@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Authenticator/Assets.xcassets/yubikey-nfc.imageset/yubikey-nfc@3x.png -------------------------------------------------------------------------------- /Authenticator/Authenticator-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #ifndef Authenticator_Bridging_Header_h 2 | #define Authenticator_Bridging_Header_h 3 | 4 | #import 5 | #import 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /Authenticator/Authenticator.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.developer.associated-domains 6 | 7 | applinks:my.yubico.com 8 | 9 | com.apple.developer.nfc.readersession.formats 10 | 11 | TAG 12 | 13 | com.apple.security.app-sandbox 14 | 15 | com.apple.security.application-groups 16 | 17 | group.com.yubico.Authenticator 18 | 19 | com.apple.security.device.camera 20 | 21 | keychain-access-groups 22 | 23 | $(AppIdentifierPrefix)com.yubico.Authenticator 24 | $(AppIdentifierPrefix)com.apple.token 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /Authenticator/AuthenticatorApp.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) Yubico. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import SwiftUI 18 | import YubiKit 19 | 20 | @main 21 | struct AuthenticatorApp: App { 22 | 23 | @Environment(\.scenePhase) var scenePhase 24 | @StateObject var toastPresenter = ToastPresenter() 25 | @StateObject var notificationsViewModel = NotificationsViewModel() 26 | 27 | var body: some Scene { 28 | WindowGroup { 29 | ZStack { 30 | MainView() 31 | .toast(isPresenting: $toastPresenter.isPresenting, message: toastPresenter.message) 32 | } 33 | .fullScreenCover(isPresented: $notificationsViewModel.showPIVTokenView) { 34 | TokenRequestView(userInfo: notificationsViewModel.userInfo) 35 | } 36 | .transaction { transaction in 37 | transaction.disablesAnimations = notificationsViewModel.showPIVTokenView 38 | } 39 | .navigationViewStyle(.stack) 40 | .environmentObject(toastPresenter) 41 | .environmentObject(notificationsViewModel) 42 | .onAppear { 43 | YubiKitExternalLocalization.nfcScanAlertMessage = String(localized: "Scan your YubiKey", comment: "iOS NFC alert scan") 44 | YubiKitExternalLocalization.nfcScanSuccessAlertMessage = String(localized: "Success", comment: "iOS NFC alert default success message") 45 | } 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Authenticator/Licensing.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Kane Cheshire 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, andor sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | 11 | https://github.com/KaneCheshire/ShowTime 12 | 13 | ______________________________________________ 14 | 15 | 16 | Copyright (c) 2018 Razeware LLC 17 | 18 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, andor sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 21 | 22 | Notwithstanding the foregoing, you may not use, copy, modify, merge, publish, distribute, sublicense, create a derivative work, andor sell copies of the Software in any work that is designed, intended, or marketed for pedagogical or instructional purposes related to programming, coding, application development, or information technology. Permission for such use, copying, modification, merger, publication, distribution, sublicensing, creation of derivative works, or sale is expressly withheld. 23 | 24 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 | 26 | https://www.raywenderlich.com/9240-keychain-services-api-tutorial-for-passwords-in-swift 27 | 28 | -------------------------------------------------------------------------------- /Authenticator/Model/AccessKeyCache.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 Yubico. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import Foundation 18 | 19 | struct AccessKeyCache { 20 | 21 | let timeToLive = TimeInterval(5*60) 22 | 23 | struct AccessKey { 24 | let timeStamp = Date() 25 | let accessKey: Data 26 | 27 | init(_ accessKey: Data) { 28 | self.accessKey = accessKey 29 | } 30 | } 31 | 32 | private var cache = [String: AccessKey]() 33 | 34 | mutating func accessKey(forKey index: String) -> Data? { 35 | guard let possibleAccessKey = cache[index] else { return nil } 36 | if Date() < Date(timeInterval: timeToLive, since: possibleAccessKey.timeStamp) { 37 | cache[index] = AccessKey(possibleAccessKey.accessKey) 38 | return possibleAccessKey.accessKey 39 | } else { 40 | cache.removeValue(forKey: index) 41 | return nil 42 | } 43 | } 44 | 45 | mutating func setAccessKey(_ accessKey: Data, forKey index: String) { 46 | let accessKey = AccessKey(accessKey) 47 | cache[index] = accessKey 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Authenticator/Model/ApplicationSessionObserver.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 Yubico. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import Foundation 18 | 19 | protocol ApplicationSessionObserverDelegate: NSObjectProtocol { 20 | func didEnterBackground() 21 | func willResignActive() 22 | func didBecomeActive() 23 | } 24 | 25 | // Default implementations making the methods optional when implementing ApplicationSessionObserverDelegate 26 | extension ApplicationSessionObserverDelegate { 27 | func didEnterBackground() { 28 | // do nothing 29 | } 30 | func willResignActive() { 31 | // do nothing 32 | } 33 | func didBecomeActive() { 34 | // do nothing 35 | } 36 | } 37 | 38 | @objc class ApplicationSessionObserver: NSObject { 39 | 40 | private weak var applicationDelegate: ApplicationSessionObserverDelegate? 41 | let notificationCenter = NotificationCenter.default 42 | 43 | init(delegate: ApplicationSessionObserverDelegate) { 44 | self.applicationDelegate = delegate 45 | super.init() 46 | notificationCenter.addObserver(self, selector: #selector(didEnterBackground), name: UIApplication.didEnterBackgroundNotification, object: nil) 47 | notificationCenter.addObserver(self, selector: #selector(willResignActive), name: UIApplication.willResignActiveNotification, object: nil) 48 | notificationCenter.addObserver(self, selector: #selector(didBecomeActive), name: UIApplication.didBecomeActiveNotification, object: nil) 49 | 50 | } 51 | 52 | deinit { 53 | notificationCenter.removeObserver(self) 54 | } 55 | 56 | @objc func didBecomeActive() { 57 | applicationDelegate?.didBecomeActive() 58 | } 59 | 60 | @objc func willResignActive() { 61 | applicationDelegate?.willResignActive() 62 | } 63 | 64 | @objc func didEnterBackground() { 65 | applicationDelegate?.didEnterBackground() 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /Authenticator/Model/ApplicationSettingsViewModel.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 Yubico. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import Foundation 18 | 19 | struct ApplicationSettingsViewModel { 20 | 21 | var isBypassTouchEnabled: Bool { 22 | get { 23 | return SettingsConfig.isBypassTouchEnabled 24 | } 25 | set { 26 | SettingsConfig.isBypassTouchEnabled = newValue 27 | } 28 | } 29 | 30 | var isNFCOnAppLaunchEnabled: Bool { 31 | get { 32 | return SettingsConfig.isNFCOnAppLaunchEnabled 33 | } 34 | set { 35 | SettingsConfig.isNFCOnAppLaunchEnabled = newValue 36 | } 37 | } 38 | 39 | var isNFCOnOTPLaunchEnabled: Bool { 40 | get { 41 | return SettingsConfig.isNFCOnOTPLaunchEnabled 42 | } 43 | set { 44 | SettingsConfig.isNFCOnOTPLaunchEnabled = newValue 45 | } 46 | } 47 | 48 | var isCopyOTPEnabled: Bool { 49 | get { 50 | return SettingsConfig.isCopyOTPEnabled 51 | } 52 | set { 53 | SettingsConfig.isCopyOTPEnabled = newValue 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Authenticator/Model/Extensions/Logger+Extensions.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 Yubico. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import OSLog 18 | 19 | public extension Logger { 20 | private static let subsystem = Bundle.main.bundleIdentifier! 21 | 22 | static let ui = Logger(subsystem: subsystem, category: "UI") 23 | static let allocation = Logger(subsystem: subsystem, category: "Allocation") 24 | static let connection = Logger(subsystem: subsystem, category: "Connection") 25 | static let ctk = Logger(subsystem: subsystem, category: "CTK") 26 | static let system = Logger(subsystem: subsystem, category: "System") 27 | } 28 | -------------------------------------------------------------------------------- /Authenticator/Model/Extensions/YKFKeyVersion+Extensions.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 Yubico. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | extension YKFVersion: Comparable { 18 | 19 | static public func ==(lhs: YKFVersion, rhs: YKFVersion) -> Bool { 20 | return lhs.major == lhs.major && lhs.minor == rhs.minor && lhs.micro == rhs.micro 21 | } 22 | 23 | static public func <(lhs: YKFVersion, rhs: YKFVersion) -> Bool { 24 | if (lhs.major != rhs.major) { 25 | return lhs.major < rhs.major 26 | } else if (lhs.minor != rhs.minor) { 27 | return lhs.minor < rhs.minor 28 | } else { 29 | return lhs.micro < rhs.micro 30 | } 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /Authenticator/Model/Extensions/YKFOATHSession+Extensions.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 Yubico. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | extension YKFOATHSession { 18 | func calculateSteamTOTP(credential: YKFOATHCredential, completion: @escaping ((String?, DateInterval?, Error?) -> Void)) { 19 | var challenge = Data() 20 | let timestamp = Date().addingTimeInterval(10) 21 | let value: UInt64 = UInt64(timestamp.timeIntervalSince1970 / TimeInterval(credential.period)) 22 | var bigEndianVal = value.bigEndian 23 | withUnsafePointer(to: &bigEndianVal) { 24 | challenge.append(UnsafeBufferPointer(start: $0, count: 1)) 25 | } 26 | 27 | self.calculateResponse(forCredentialID: Data(credential.id.utf8), challenge: challenge) { response, error in 28 | guard let response = response else { 29 | completion(nil, nil, error!) 30 | return 31 | } 32 | 33 | let offset = Int(response.last! & 0x0F) 34 | let subdata = response.subdata(in: offset.. 33 | }.compactMap { 34 | $0 35 | }.flatMap { 36 | $0 37 | } 38 | if !merged.isEmpty { 39 | saveFavorites(Set(merged)) 40 | // remove old favorites 41 | let keys = favorites.filter { dict in 42 | dict.key.starts(with: "Favorites-") 43 | }.map { dict in 44 | dict.key 45 | } 46 | keys.forEach { key in 47 | UserDefaults.standard.removeObject(forKey: key) 48 | } 49 | } 50 | } 51 | 52 | func saveFavorites(_ favorites: Set) { 53 | guard let encodedData = try? NSKeyedArchiver.archivedData(withRootObject: favorites, requiringSecureCoding: true) else { 54 | return 55 | } 56 | UserDefaults.standard.setValue(encodedData, forKey: "Favorites") 57 | } 58 | 59 | func readFavorites() -> Set { 60 | guard let encodedData = UserDefaults.standard.data(forKey: "Favorites"), 61 | let favorites = try? NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(encodedData) as? Set else { 62 | return Set() 63 | } 64 | return favorites 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /Authenticator/Model/KeySessionError.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 Yubico. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import Foundation 18 | 19 | enum KeySessionError : Error { 20 | case notSupported 21 | case noService 22 | case noResponse 23 | case timeout 24 | case invalidUri 25 | case invalidCredentialUri 26 | } 27 | 28 | 29 | extension KeySessionError: LocalizedError { 30 | public var errorDescription: String? { 31 | switch self { 32 | case .notSupported: 33 | return NSLocalizedString("This version of iOS does not support operations with the YubiKey for Lightning nor over NFC", comment: "Not supported") 34 | case .noService: 35 | return NSLocalizedString("Plug-in your YubiKey for that operation", comment: "No service found") 36 | case .noResponse: 37 | return NSLocalizedString("Something went wrong and key doesn't respond", comment: "No response") 38 | case .invalidUri: 39 | return NSLocalizedString("This QR code is not supported", comment: "Invalid Uri format, not OATH URL") 40 | case .timeout: 41 | return NSLocalizedString("The key doesn't respond", comment: "Timeout issue") 42 | case .invalidCredentialUri: 43 | return NSLocalizedString("Invalid URI format", comment: "Invalid Uri, wrong parameters") 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Authenticator/Model/NotificationsViewModel.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) Yubico. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import SwiftUI 18 | 19 | class NotificationsViewModel: NSObject, ObservableObject, UNUserNotificationCenterDelegate { 20 | 21 | @Published var showPIVTokenView: Bool = false 22 | var userInfo: [AnyHashable: Any]? 23 | 24 | override init() { 25 | super.init() 26 | UNUserNotificationCenter.current().delegate = self 27 | } 28 | 29 | func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { 30 | userInfo = response.notification.request.content.userInfo 31 | showPIVTokenView = true 32 | completionHandler() 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Authenticator/Model/OATHSavedPasswordsViewModel.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 Yubico. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | import OSLog 19 | 20 | class OATHSavedPasswordsViewModel: ObservableObject { 21 | 22 | @Published var state: ResetState = .ready 23 | 24 | enum ResetState: Equatable { 25 | case ready, success, error(String) 26 | } 27 | 28 | private let connection = Connection() 29 | 30 | func clearPasswords() { 31 | 32 | let passwordPreferences = PasswordPreferences() 33 | let secureStore = SecureStore(secureStoreQueryable: PasswordQueryable(service: "OATH")) 34 | passwordPreferences.resetPasswordPreferenceForAll() 35 | do { 36 | try secureStore.removeAllValues() 37 | self.state = .success 38 | } catch { 39 | self.state = .error(error.localizedDescription) 40 | } 41 | } 42 | 43 | init() { 44 | Logger.allocation.debug("OATHSavedPasswordsViewModel: init") 45 | } 46 | 47 | deinit { 48 | Logger.allocation.debug("OATHSavedPasswordsViewModel: deinit") 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Authenticator/Model/PasswordCache.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 Yubico. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import Foundation 18 | 19 | struct PasswordCache { 20 | 21 | let timeToLive = TimeInterval(5*60) 22 | 23 | struct Password { 24 | let timeStamp = Date() 25 | let password: String 26 | 27 | init(_ password: String) { 28 | self.password = password 29 | } 30 | } 31 | 32 | private var cache = [String: Password]() 33 | 34 | mutating func password(forKey index: String) -> String? { 35 | guard let possiblePassword = cache[index] else { return nil } 36 | if Date() < Date(timeInterval: timeToLive, since: possiblePassword.timeStamp) { 37 | cache[index] = Password(possiblePassword.password) 38 | return possiblePassword.password 39 | } else { 40 | cache.removeValue(forKey: index) 41 | return nil 42 | } 43 | } 44 | 45 | mutating func setPassword(_ password: String, forKey index: String) { 46 | let password = Password(password) 47 | cache[index] = password 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Authenticator/Model/SecureStore/SecureStoreError.swift: -------------------------------------------------------------------------------- 1 | /// Copyright (c) 2018 Razeware LLC 2 | /// 3 | /// Permission is hereby granted, free of charge, to any person obtaining a copy 4 | /// of this software and associated documentation files (the "Software"), to deal 5 | /// in the Software without restriction, including without limitation the rights 6 | /// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | /// copies of the Software, and to permit persons to whom the Software is 8 | /// furnished to do so, subject to the following conditions: 9 | /// 10 | /// The above copyright notice and this permission notice shall be included in 11 | /// all copies or substantial portions of the Software. 12 | /// 13 | /// Notwithstanding the foregoing, you may not use, copy, modify, merge, publish, 14 | /// distribute, sublicense, create a derivative work, and/or sell copies of the 15 | /// Software in any work that is designed, intended, or marketed for pedagogical or 16 | /// instructional purposes related to programming, coding, application development, 17 | /// or information technology. Permission for such use, copying, modification, 18 | /// merger, publication, distribution, sublicensing, creation of derivative works, 19 | /// or sale is expressly withheld. 20 | /// 21 | /// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | /// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | /// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | /// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | /// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | /// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | /// THE SOFTWARE. 28 | /// 29 | /// https://www.raywenderlich.com/9240-keychain-services-api-tutorial-for-passwords-in-swift 30 | 31 | import Foundation 32 | 33 | public enum SecureStoreError: Error { 34 | case string2DataConversionError 35 | case data2StringConversionError 36 | case dataCastError 37 | case unhandledError(message: String) 38 | case itemNotFound 39 | } 40 | 41 | /*! Represents type of errors that happen during communication with SecureStore 42 | */ 43 | extension SecureStoreError: LocalizedError { 44 | public var errorDescription: String? { 45 | switch self { 46 | case .string2DataConversionError: 47 | return NSLocalizedString("String to Data conversion error", comment: "") 48 | case .data2StringConversionError: 49 | return NSLocalizedString("Data to String conversion error", comment: "") 50 | case .dataCastError: 51 | return NSLocalizedString("Failed to cast object to Data error", comment: "") 52 | case .unhandledError(let message): 53 | return message 54 | case .itemNotFound: 55 | return NSLocalizedString("Item not found in secure storage", comment: "") 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Authenticator/UI/About/LicensingView.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) Yubico. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | import SwiftUI 19 | 20 | struct LicensingView: View { 21 | var body: some View { 22 | List { 23 | Text(self.licensingText()) 24 | .font(.footnote) 25 | } 26 | .navigationTitle("Licensing") 27 | } 28 | } 29 | 30 | extension LicensingView { 31 | private func licensingText() -> AttributedString { 32 | guard let filepath = Bundle.main.path(forResource: "Licensing", ofType: "md"), 33 | let licensingMarkdown = try? String(contentsOfFile: filepath) else { fatalError() } 34 | return try! AttributedString(markdown: licensingMarkdown, options: AttributedString.MarkdownParsingOptions(interpretedSyntax: .inlineOnlyPreservingWhitespace)) 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Authenticator/UI/Authentication/AddCredential/AddAccountWrapper.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) Yubico. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import SwiftUI 18 | import Combine 19 | 20 | struct AddAccountView: View { 21 | 22 | @Binding var showAddAccount: Bool 23 | var accountSubject: PassthroughSubject<(YKFOATHCredentialTemplate?, Bool), Never> 24 | var oathURL: URL? 25 | let navigationBarAppearance = UINavigationBarAppearance() 26 | 27 | init(showAddCredential: Binding, accountSubject: PassthroughSubject<(YKFOATHCredentialTemplate?, Bool), Never>, oathURL: URL?) { 28 | _showAddAccount = showAddCredential 29 | self.oathURL = oathURL 30 | self.accountSubject = accountSubject 31 | } 32 | 33 | var body: some View { 34 | AddCredentialWrapper(accountSubject: accountSubject, oathURL: oathURL) 35 | .navigationTitle(String(localized: "Add Credential", comment: "Add account navigation title")) 36 | .navigationBarItems(trailing: Button(String(localized: "Close", comment: "View close button")) { 37 | showAddAccount.toggle() 38 | }) 39 | .ignoresSafeArea(.all, edges: .bottom) 40 | } 41 | } 42 | 43 | struct AddCredentialWrapper: UIViewControllerRepresentable { 44 | 45 | var accountSubject: PassthroughSubject<(YKFOATHCredentialTemplate?, Bool), Never> 46 | var oathURL: URL? 47 | 48 | func makeUIViewController(context: Context) -> UINavigationController { 49 | let sb = UIStoryboard(name: "AddCredential", bundle: nil) 50 | let vc = sb.instantiateViewController(identifier: "AddCredentialController") as! UINavigationController 51 | 52 | guard let credentialController = vc.topViewController as? AddCredentialController else { fatalError() } 53 | if let oathURL { 54 | let template = YKFOATHCredentialTemplate(url: oathURL) 55 | credentialController.credential = template 56 | } 57 | 58 | credentialController.accountSubject = accountSubject 59 | 60 | return vc 61 | } 62 | 63 | func updateUIViewController(_ uiViewController: UINavigationController, context: Context) { 64 | } 65 | 66 | typealias UIViewControllerType = UINavigationController 67 | } 68 | -------------------------------------------------------------------------------- /Authenticator/UI/Authentication/AddCredential/AdvancedSettingsViewController.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 Yubico. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import UIKit 18 | 19 | class AdvancedSettingsViewController: UITableViewController { 20 | 21 | init(title: String, rows: [String], selected: Int, completion: @escaping (Int) -> Void) { 22 | self.rows = rows 23 | self.selectedRow = selected 24 | self.completion = completion 25 | super.init(style: .insetGrouped) 26 | self.accessibilityViewIsModal = true 27 | self.title = title 28 | } 29 | 30 | let rows: [String] 31 | var selectedRow: Int 32 | let completion: (Int) -> Void 33 | 34 | 35 | required init?(coder: NSCoder) { 36 | fatalError("init(coder:) has not been implemented") 37 | } 38 | 39 | override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 40 | let cell = UITableViewCell(style: .default, reuseIdentifier: "advancedSettings") 41 | cell.textLabel?.text = rows[indexPath.row] 42 | cell.accessoryType = indexPath.row == selectedRow ? .checkmark : .none 43 | return cell 44 | } 45 | 46 | override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 47 | return rows.count 48 | } 49 | 50 | override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 51 | selectedRow = indexPath.row 52 | self.tableView.reloadData() 53 | } 54 | 55 | override func viewWillDisappear(_ animated: Bool) { 56 | completion(selectedRow) 57 | super.viewWillDisappear(animated) 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /Authenticator/UI/Authentication/EditCredential/EditAccountWrapper.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) Yubico. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import SwiftUI 18 | 19 | 20 | struct EditView: View { 21 | 22 | @Binding var showEditing: Bool 23 | 24 | let viewModel: MainViewModel 25 | let account: Account 26 | 27 | let navigationBarAppearance = UINavigationBarAppearance() 28 | 29 | init(account: Account, viewModel: MainViewModel, showEditing: Binding ) { 30 | self.account = account 31 | self.viewModel = viewModel 32 | _showEditing = showEditing 33 | navigationBarAppearance.shadowColor = .secondarySystemBackground 34 | navigationBarAppearance.backgroundColor = .secondarySystemBackground 35 | UINavigationBar.appearance().scrollEdgeAppearance = navigationBarAppearance 36 | } 37 | 38 | var body: some View { 39 | EditAccountWrapper(account: account, viewModel: viewModel) 40 | .ignoresSafeArea(.all, edges: .bottom) 41 | } 42 | } 43 | 44 | struct EditAccountWrapper: UIViewControllerRepresentable { 45 | 46 | 47 | let account: Account 48 | let viewModel: MainViewModel 49 | 50 | func makeUIViewController(context: Context) -> UINavigationController { 51 | let sb = UIStoryboard(name: "EditCredential", bundle: nil) 52 | let vc = sb.instantiateViewController(identifier: "EditCredentialController") as! UINavigationController 53 | 54 | guard let editCredentialController = vc.topViewController as? EditCredentialController else { fatalError() } 55 | editCredentialController.account = account 56 | editCredentialController.viewModel = viewModel 57 | 58 | return vc 59 | } 60 | 61 | func updateUIViewController(_ uiViewController: UINavigationController, context: Context) { 62 | } 63 | 64 | typealias UIViewControllerType = UINavigationController 65 | } 66 | 67 | -------------------------------------------------------------------------------- /Authenticator/UI/Authentication/EditCredential/EditCredentialController.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 Yubico. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import UIKit 18 | 19 | class EditCredentialController: UITableViewController { 20 | public var account: Account? 21 | public var viewModel: MainViewModel? 22 | @IBOutlet weak var issuerRow: SettingsRowView! 23 | @IBOutlet weak var accountRow: SettingsRowView! 24 | 25 | override func viewDidLoad() { 26 | issuerRow.value = account?.credential.issuer 27 | accountRow.value = account?.credential.accountName 28 | super.viewDidLoad() 29 | } 30 | 31 | override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 32 | guard let settingsRow = (sender as? UITableViewCell)?.contentView.subviews.first as? SettingsRowView else { return } 33 | guard let editFieldController = segue.destination as? EditFieldController else { return } 34 | editFieldController.enablesReturnKeyAutomatically = settingsRow == accountRow 35 | editFieldController.settingsRow = settingsRow 36 | } 37 | 38 | @IBAction func save(_ sender: Any) { 39 | guard let account, let issuer = issuerRow.value, let accountName = accountRow.value, accountName.count > 0 else { 40 | showAlertDialog(title: String(localized: "Account not set", comment: "Rename credential alert"), message: String(localized: "Account name can not be empty", comment: "Rename credential alert")) 41 | return 42 | } 43 | viewModel?.renameAccount(account, issuer: issuer, accountName: accountName) { 44 | let credential = account.credential 45 | credential.issuer = issuer 46 | credential.accountName = accountName 47 | account.credential = credential 48 | } 49 | self.dismiss(animated: true) 50 | } 51 | 52 | @IBAction func cancel(_ sender: Any) { 53 | self.dismiss(animated: true) 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Authenticator/UI/Authentication/EditCredential/EditFieldController.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 Yubico. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import UIKit 18 | 19 | class EditFieldController: UITableViewController, UINavigationControllerDelegate, UITextFieldDelegate { 20 | 21 | @IBOutlet weak var field: UITextField! 22 | var settingsRow: SettingsRowView? 23 | var enablesReturnKeyAutomatically: Bool = false 24 | 25 | override func viewWillAppear(_ animated: Bool) { 26 | field.text = settingsRow?.value 27 | title = settingsRow?.title 28 | field.becomeFirstResponder() 29 | field.delegate = self 30 | field.enablesReturnKeyAutomatically = enablesReturnKeyAutomatically; 31 | } 32 | 33 | override func viewWillDisappear(_ animated: Bool) { 34 | super.viewWillDisappear(animated) 35 | settingsRow?.value = field.text 36 | } 37 | 38 | func textFieldShouldReturn(_ textField: UITextField) -> Bool { 39 | navigationController?.popViewController(animated: true) 40 | return true 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Authenticator/UI/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /Authenticator/UI/Constants.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 Yubico. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import Foundation 18 | 19 | extension Int { 20 | internal static let freVersion = 2 21 | internal static let whatsNewVersion = 1 22 | } 23 | 24 | extension String { 25 | internal static let unwindToMainViewController = "unwindToMain" 26 | internal static let addCredentialSequeID = "AddCredentialSequeID" 27 | internal static let startTutorial = "StartTutorial" 28 | internal static let editCredential = "EditCredential" 29 | internal static let showSettings = "ShowSettings" 30 | } 31 | -------------------------------------------------------------------------------- /Authenticator/UI/Helpers/Data+Extensions.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 Yubico. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import Foundation 18 | import CryptoKit 19 | 20 | extension Data { 21 | func sha256Hash() -> Data { 22 | let digest = SHA256.hash(data: self) 23 | let bytes = Array(digest.makeIterator()) 24 | return Data(bytes) 25 | } 26 | } 27 | 28 | extension Data { 29 | var uint32: UInt32? { 30 | guard self.count == MemoryLayout.size else { return nil } 31 | return withUnsafeBytes { $0.load(as: UInt32.self) } 32 | } 33 | 34 | var uint64: UInt64? { 35 | guard self.count == MemoryLayout.size else { return nil } 36 | return withUnsafeBytes { $0.load(as: UInt64.self) } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Authenticator/UI/Helpers/SecCertificate+Extensions.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 Yubico. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import Foundation 18 | import CommonCrypto 19 | 20 | extension SecCertificate: Equatable { 21 | 22 | var commonName: String? { 23 | var name: CFString? 24 | SecCertificateCopyCommonName(self, &name) 25 | return name as String? 26 | } 27 | 28 | func tokenObjectId() -> String { 29 | let data = SecCertificateCopyData(self) as Data 30 | return data.sha256Hash().map { String(format: "%02X", $0) }.joined() 31 | } 32 | 33 | func publicKey() -> SecKey? { 34 | return SecCertificateCopyKey(self) 35 | } 36 | 37 | public static func ==(lhs: SecCertificate, rhs: SecCertificate) -> Bool { 38 | return lhs.tokenObjectId() == rhs.tokenObjectId() 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Authenticator/UI/Helpers/SettingsButton.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) Yubico. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | import SwiftUI 19 | 20 | public struct SettingsButton: View { 21 | @Environment(\.isEnabled) var isEnabled 22 | @Environment(\.displayScale) var displayScale 23 | 24 | private let text: String 25 | private let action: () -> Void 26 | 27 | public init(_ text: String, action: @escaping () -> Void) { 28 | self.text = text 29 | self.action = action 30 | } 31 | 32 | public var body: some View { 33 | Button { 34 | action() 35 | } label: { 36 | VStack(alignment: .leading, spacing: 0) { 37 | Color(.separator) 38 | .frame(height: 1.0 / displayScale) 39 | .frame(maxWidth: .infinity) 40 | .padding(0) 41 | .padding(.leading, 20) 42 | Text(text) 43 | .font(.body) 44 | .padding(12) 45 | .padding(.leading, 7) 46 | } 47 | } 48 | .buttonStyle(SettingsButtonStyle(isEnabled: isEnabled)) 49 | } 50 | } 51 | 52 | private struct SettingsButtonStyle: ButtonStyle { 53 | let isEnabled: Bool 54 | 55 | @ViewBuilder 56 | func makeBody(configuration: Configuration) -> some View { 57 | configuration.label 58 | .background(configuration.isPressed ? Color(UIColor.systemGray4) : Color(.secondarySystemGroupedBackground)) 59 | .foregroundStyle(isEnabled ? .blue : Color(.secondaryText)) 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /Authenticator/UI/Helpers/SettingsView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SettingsView.swift 3 | // Authenticator 4 | // 5 | // Created by Jens Utbult on 2024-08-29. 6 | // Copyright © 2024 Yubico. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | 11 | struct SettingsView: View { 12 | 13 | var image: Image? = nil 14 | var imageColor: Color = .blue 15 | @ViewBuilder var content: () -> Content 16 | @ViewBuilder var buttons: () -> Buttons 17 | 18 | var body: some View { 19 | VStack { 20 | VStack(spacing: 0) { 21 | VStack(spacing: 10) { 22 | if let image { 23 | image 24 | .resizable() 25 | .scaledToFit() 26 | .font(Font.title.weight(.semibold)) 27 | .padding(10) 28 | .frame(width: 60, height: 60) 29 | .foregroundColor(.white) 30 | .background(imageColor) 31 | .cornerRadius(13) 32 | .padding(.top, 0) 33 | .padding(.bottom, 0) 34 | .accessibilityHidden(true) 35 | } 36 | content() 37 | } 38 | .padding(.horizontal, 30) 39 | .padding(.vertical, 25) 40 | buttons() 41 | } 42 | .frame(maxWidth: .infinity) 43 | .background(Color(.secondarySystemGroupedBackground)) 44 | .clipShape(RoundedRectangle(cornerRadius: 10, style: .continuous)) 45 | .padding(20) 46 | Spacer() 47 | } 48 | .background(Color(.systemGroupedBackground)) 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Authenticator/UI/Helpers/ToastPresenter.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) Yubico. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import SwiftUI 18 | 19 | 20 | class ToastPresenter: ObservableObject { 21 | @Published var isPresenting = false 22 | @Published var message = "No message" 23 | 24 | private var presentWorkItem: DispatchWorkItem? 25 | private var dismissWorkItem: DispatchWorkItem? 26 | 27 | func toast(message: String) { 28 | presentWorkItem?.cancel() 29 | dismissWorkItem?.cancel() 30 | 31 | if isPresenting { 32 | isPresenting = false 33 | let task = DispatchWorkItem { 34 | self.present(message) 35 | } 36 | DispatchQueue.main.asyncAfter(deadline: .now() + 0.3, execute: task) 37 | dismissWorkItem = task 38 | } else { 39 | present(message) 40 | } 41 | } 42 | 43 | private func present(_ message: String) { 44 | self.message = message 45 | isPresenting = true 46 | let task = DispatchWorkItem { 47 | self.isPresenting = false 48 | self.presentWorkItem = nil 49 | } 50 | presentWorkItem = task 51 | DispatchQueue.main.asyncAfter(deadline: .now() + 4, execute: task) 52 | } 53 | } 54 | 55 | extension ToastPresenter { 56 | 57 | func copyToClipboard(_ value: String) { 58 | UIPasteboard.general.string = value 59 | toast(message: String(localized: "Copied to clipboard", comment: "Toast copied to clipboard message")) 60 | let generator = UINotificationFeedbackGenerator() 61 | generator.notificationOccurred(.success) 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Authenticator/UI/Helpers/ToastView.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) Yubico. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import SwiftUI 18 | 19 | struct ToastView: View { 20 | 21 | let message: String 22 | 23 | @State var isVisible = true 24 | 25 | var body: some View { 26 | ZStack(alignment: .leading) { 27 | Text(message) 28 | .font(.body) 29 | .foregroundColor(Color(.white)) 30 | .fixedSize(horizontal: true, vertical: true) 31 | .padding(EdgeInsets(top: 5, leading: 15, bottom: 5, trailing: 15)) 32 | .background(Color(.yubiBlue)) 33 | .cornerRadius(20) 34 | .shadow(radius: 5) 35 | } 36 | } 37 | } 38 | 39 | struct ToastModifier: ViewModifier { 40 | 41 | @Binding var isPresenting: Bool 42 | var message: String 43 | 44 | @ViewBuilder public func main() -> some View { 45 | if isPresenting { 46 | ToastView(message: message) 47 | .onTapGesture { 48 | isPresenting = false 49 | } 50 | .transition(AnyTransition.scale(scale: 0.8).combined(with: .opacity)) 51 | } 52 | } 53 | 54 | @ViewBuilder public func body(content: Content) -> some View { 55 | content 56 | .overlay(main(), alignment: .top) 57 | .animation(.spring(), value: isPresenting) 58 | } 59 | } 60 | 61 | public extension View { 62 | 63 | func toast(isPresenting: Binding, message: String) -> some View { 64 | modifier(ToastModifier(isPresenting: isPresenting, message: message)) 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /Authenticator/UI/Helpers/UIApplicationExtension.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 Yubico. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import Foundation 18 | 19 | extension UIApplication { 20 | 21 | static var appVersion: String { 22 | return Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as! String 23 | } 24 | static var appBuildNumber: String { 25 | return Bundle.main.object(forInfoDictionaryKey: "CFBundleVersion") as! String 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Authenticator/UI/Helpers/UIButton+Extensions.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 Yubico. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import Foundation 18 | 19 | extension UIButton { 20 | convenience init(withSymbol symbol: String) { 21 | self.init() 22 | let config = UIImage.SymbolConfiguration(pointSize: 26, weight: .light, scale: .medium) 23 | let image = UIImage(systemName: symbol, withConfiguration: config) 24 | self.setImage(image, for: .normal) 25 | } 26 | 27 | func setSymbol(symbol: String) { 28 | let config = UIImage.SymbolConfiguration(pointSize: 26, weight: .light, scale: .medium) 29 | let image = UIImage(systemName: symbol, withConfiguration: config) 30 | self.setImage(image, for: .normal) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Authenticator/UI/Helpers/UIControl+Extensions.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 Yubico. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import Combine 18 | import UIKit 19 | 20 | extension UIControl { 21 | func addHandler(for event: UIControl.Event, block: @escaping () -> Void) -> Cancellable { 22 | let blockObject = BlockWrapper(block: block) 23 | addTarget(blockObject, action: #selector(BlockWrapper.execute), for: event) 24 | let cancellable = AnyCancellable { 25 | self.removeTarget(blockObject, action: #selector(BlockWrapper.execute), for: event) 26 | } 27 | return cancellable 28 | } 29 | } 30 | 31 | fileprivate class BlockWrapper: NSObject { 32 | let block: () -> Void 33 | 34 | init(block: @escaping () -> Void) { 35 | self.block = block 36 | } 37 | 38 | @objc dynamic func execute() { 39 | block() 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Authenticator/UI/Helpers/UIFont+Extensions.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) Yubico. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | extension UIFont { 18 | /// Returns a new font in the same family with the given symbolic traits, 19 | /// or `nil` if none found in the system. 20 | func withSymbolicTraits(_ traits: UIFontDescriptor.SymbolicTraits) -> UIFont? { 21 | guard let descriptorWithTraits = fontDescriptor.withSymbolicTraits(traits) 22 | else { return nil } 23 | return UIFont(descriptor: descriptorWithTraits, size: 0) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Authenticator/UI/Helpers/UIGestureRecognizer+Extensions.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 Yubico. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | extension UIGestureRecognizer { 18 | 19 | typealias Action = ((UIGestureRecognizer) -> ()) 20 | 21 | private struct Keys { 22 | static var actionKey = "ActionKey" 23 | } 24 | 25 | private var block: Action? { 26 | set { 27 | if let newValue = newValue { 28 | objc_setAssociatedObject(self, &Keys.actionKey, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN) 29 | } 30 | } 31 | 32 | get { 33 | objc_getAssociatedObject(self, &Keys.actionKey) as? Action 34 | } 35 | } 36 | 37 | @objc func handleAction(recognizer: UIGestureRecognizer) { 38 | block?(recognizer) 39 | } 40 | 41 | convenience public init(block: @escaping ((UIGestureRecognizer) -> ())) { 42 | self.init() 43 | self.block = block 44 | self.addTarget(self, action: #selector(handleAction(recognizer:))) 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Authenticator/UI/Helpers/UIImageAdditions.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 Yubico. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | extension UIImage { 18 | /// Returns a system image on iOS 13, otherwise returns an image from the Bundle provided. 19 | convenience init?(nameOrSystemName: String, in bundle: Bundle? = Bundle.main, compatibleWith traitCollection: UITraitCollection? = nil) { 20 | if #available(iOS 13, *) { 21 | self.init(systemName: nameOrSystemName, compatibleWith: traitCollection) 22 | } else { 23 | self.init(named: nameOrSystemName, in: bundle, compatibleWith: traitCollection) 24 | } 25 | } 26 | 27 | func rotate(degrees: Float) -> UIImage? { 28 | rotate(radians: degrees * .pi / 180.0) 29 | } 30 | 31 | func rotate(radians: Float) -> UIImage? { 32 | if radians == 0 { 33 | return self 34 | } 35 | var newSize = CGRect(origin: CGPoint.zero, size: self.size).applying(CGAffineTransform(rotationAngle: CGFloat(radians))).size 36 | newSize.width = floor(newSize.width) 37 | newSize.height = floor(newSize.height) 38 | UIGraphicsBeginImageContextWithOptions(newSize, false, self.scale) 39 | let context = UIGraphicsGetCurrentContext()! 40 | context.translateBy(x: newSize.width/2, y: newSize.height/2) 41 | context.rotate(by: CGFloat(radians)) 42 | self.draw(in: CGRect(x: -self.size.width/2, y: -self.size.height/2, width: self.size.width, height: self.size.height)) 43 | let newImage = UIGraphicsGetImageFromCurrentImageContext() 44 | UIGraphicsEndImageContext() 45 | return newImage 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Authenticator/UI/Helpers/UIViewAdditions.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 Yubico. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import UIKit 18 | 19 | @propertyWrapper 20 | public struct UsesAutoLayout { 21 | public var wrappedValue: T { 22 | didSet { 23 | wrappedValue.translatesAutoresizingMaskIntoConstraints = false 24 | } 25 | } 26 | 27 | public init(wrappedValue: T) { 28 | self.wrappedValue = wrappedValue 29 | wrappedValue.translatesAutoresizingMaskIntoConstraints = false 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Authenticator/UI/Helpers/UIViewControllerAdditions.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 Yubico. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import Foundation 18 | import LocalAuthentication 19 | 20 | extension UIViewController { 21 | static let PasswordUserDefaultsKey = "PasswordSaveType" 22 | 23 | /*! Show error dialog to notify if some operation couldn't be executed 24 | */ 25 | func showAlertDialog(title: String, message: String? = nil, nfcHandler: (() -> Void)? = nil, okHandler: (() -> Void)? = nil) { 26 | DispatchQueue.main.async { 27 | let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert) 28 | let cancel = UIAlertAction(title: String(localized: "OK"), style: .cancel) { (action) -> Void in 29 | okHandler?() 30 | } 31 | 32 | if YubiKitDeviceCapabilities.supportsISO7816NFCTags && nfcHandler != nil { 33 | let activate = UIAlertAction(title: String(localized: "Activate NFC", comment: "Password save type activate NFC"), style: .default) { (action) -> Void in 34 | nfcHandler?() 35 | } 36 | alertController.addAction(activate) 37 | } 38 | alertController.addAction(cancel) 39 | self.present(alertController, animated: false) 40 | } 41 | } 42 | 43 | /*! Shows warning with option to cancel operation 44 | */ 45 | func showWarning(title: String, message: String, okButtonTitle: String, style: UIAlertAction.Style = .destructive, okHandler: (() -> Void)? = nil) { 46 | DispatchQueue.main.async { 47 | let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert) 48 | 49 | let reset = UIAlertAction(title: okButtonTitle, style: style, handler: { (action) -> Void in 50 | okHandler?() 51 | }) 52 | let cancel = UIAlertAction(title: String(localized: "Cancel"), style: .cancel, handler: nil) 53 | alertController.addAction(reset) 54 | alertController.addAction(cancel) 55 | 56 | self.present(alertController, animated: false) 57 | } 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /Authenticator/UI/Helpers/View+Extensions.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) Yubico. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import SwiftUI 18 | 19 | 20 | extension View { 21 | func readFrame(_ frame: Binding) -> some View { 22 | self.modifier(FrameReaderModifier(frame: frame)) 23 | } 24 | } 25 | 26 | struct FrameReaderModifier: ViewModifier { 27 | @Binding var frame: CGRect 28 | 29 | func body(content: Content) -> some View { 30 | content.background( 31 | GeometryReader { geometry -> Color in 32 | DispatchQueue.main.async { 33 | frame = geometry.frame(in: CoordinateSpace.global) 34 | } 35 | return Color.clear 36 | } 37 | ) 38 | } 39 | } 40 | 41 | 42 | extension View { 43 | func readSize(_ size: Binding) -> some View { 44 | self.modifier(SizeReaderModifier(size: size)) 45 | } 46 | } 47 | 48 | struct SizeReaderModifier: ViewModifier { 49 | @Binding var size: CGSize 50 | 51 | func body(content: Content) -> some View { 52 | content.background( 53 | GeometryReader { geometry -> Color in 54 | DispatchQueue.main.async { 55 | size = geometry.size 56 | } 57 | return Color.clear 58 | } 59 | ) 60 | } 61 | } 62 | 63 | 64 | extension View { 65 | @ViewBuilder func refreshable(enabled: Bool, action: @escaping () async -> Void) -> some View { 66 | if enabled { 67 | self.refreshable { 68 | await action() 69 | } 70 | } else { 71 | self 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /Authenticator/UI/TokenSession/TokenRequestWrapper.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) Yubico. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import SwiftUI 18 | 19 | struct TokenRequestView: View { 20 | 21 | var userInfo: [AnyHashable: Any]? 22 | 23 | init(userInfo: [AnyHashable: Any]?) { 24 | self.userInfo = userInfo 25 | } 26 | 27 | var body: some View { 28 | TokenRequestWrapper(userInfo: userInfo) 29 | } 30 | } 31 | 32 | struct TokenRequestWrapper: UIViewControllerRepresentable { 33 | 34 | var userInfo: [AnyHashable: Any]? 35 | 36 | func makeUIViewController(context: Context) -> TokenRequestViewController { 37 | let sb = UIStoryboard(name: "Main", bundle: nil) 38 | let vc = sb.instantiateViewController(identifier: "TokenRequestViewController") as! TokenRequestViewController 39 | vc.userInfo = userInfo 40 | return vc 41 | } 42 | 43 | func updateUIViewController(_ uiViewController: TokenRequestViewController, context: Context) { 44 | } 45 | 46 | typealias UIViewControllerType = TokenRequestViewController 47 | } 48 | -------------------------------------------------------------------------------- /Authenticator/UI/TokenSession/TokenRequestYubiOTPViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TokenRequestYubiOTP.swift 3 | // Authenticator 4 | // 5 | // Created by Jens Utbult on 2023-12-11. 6 | // Copyright © 2023 Yubico. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | @available(iOS 14.0, *) 12 | class TokenRequestYubiOTPViewController: UIViewController { 13 | 14 | var viewModel: TokenRequestViewModel? 15 | 16 | @IBOutlet weak var optionsView: UIStackView! 17 | @IBOutlet weak var completedView: UIStackView! 18 | 19 | 20 | override func viewDidLoad() { 21 | self.viewModel?.waitForKeyRemoval { [weak self] in 22 | self?.dismiss(animated: true) 23 | } 24 | } 25 | 26 | @IBAction func disableOTP() { 27 | viewModel?.disableOTP { error in 28 | guard error == nil else { 29 | self.presentError(error) 30 | return 31 | } 32 | DispatchQueue.main.async { 33 | UIView.animate(withDuration: 0.5) { 34 | self.optionsView.alpha = 0 35 | self.completedView.alpha = 1 36 | } 37 | } 38 | } 39 | } 40 | 41 | @IBAction func ignoreThisKey() { 42 | viewModel?.ignoreThisKey { error in 43 | guard error == nil else { 44 | self.presentError(error) 45 | return 46 | } 47 | DispatchQueue.main.async { 48 | self.dismiss(animated: true) 49 | } 50 | } 51 | } 52 | 53 | private func presentError(_ error: Error?) { 54 | guard let error else { return } 55 | 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) } 56 | self.present(alert, animated: true, completion: nil) 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Authenticator/UI/YubiKeyConfiguration/NFCSettingsController.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 Yubico. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import UIKit 18 | import SwiftUI 19 | 20 | struct NFCSettingsView: UIViewControllerRepresentable { 21 | typealias UIViewControllerType = NFCSettingsController 22 | @Environment(\.dismiss) private var dismiss 23 | 24 | func makeUIViewController(context: Context) -> NFCSettingsController { 25 | let storyboard = UIStoryboard(name: "Main", bundle: nil) 26 | guard let vc = storyboard.instantiateViewController(withIdentifier: "YubiKeyApplicationSettings") as? NFCSettingsController else { fatalError() } 27 | return vc 28 | } 29 | 30 | func updateUIViewController(_ uiViewController: NFCSettingsController, context: Context) { } 31 | } 32 | 33 | class NFCSettingsController: UITableViewController { 34 | 35 | private var viewModel = ApplicationSettingsViewModel() 36 | 37 | @IBOutlet weak var bypassTouchSwitch: UISwitch! 38 | @IBOutlet weak var nfcOnAppLaunchSwitch: UISwitch! 39 | @IBOutlet weak var nfcOnOTPLaunchSwitch: UISwitch! 40 | @IBOutlet weak var copyOTPSwitch: UISwitch! 41 | 42 | @IBAction func changeBypassTouchSetting(_ sender: UISwitch) { 43 | viewModel.isBypassTouchEnabled = sender.isOn 44 | } 45 | 46 | @IBAction func changeNFCOnAppLaunchSetting(_ sender: UISwitch) { 47 | viewModel.isNFCOnAppLaunchEnabled = sender.isOn 48 | } 49 | 50 | @IBAction func changeNFCOnOTPLaunchSetting(_ sender: UISwitch) { 51 | viewModel.isNFCOnOTPLaunchEnabled = sender.isOn 52 | } 53 | 54 | @IBAction func changeCopyOTPSetting(_ sender: UISwitch) { 55 | viewModel.isCopyOTPEnabled = sender.isOn 56 | } 57 | 58 | override func viewDidLoad() { 59 | super.viewDidLoad() 60 | bypassTouchSwitch.isOn = viewModel.isBypassTouchEnabled 61 | nfcOnAppLaunchSwitch.isOn = viewModel.isNFCOnAppLaunchEnabled 62 | nfcOnOTPLaunchSwitch.isOn = viewModel.isNFCOnOTPLaunchEnabled 63 | copyOTPSwitch.isOn = viewModel.isCopyOTPEnabled 64 | } 65 | 66 | deinit { 67 | print("deinit NFCSettingsController") 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /Authenticator/UI/YubiOtpRowView.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) Yubico. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import SwiftUI 18 | 19 | 20 | struct YubiOtpRowView: View { 21 | 22 | @EnvironmentObject var toastPresenter: ToastPresenter 23 | var otp: String 24 | 25 | var body: some View { 26 | HStack { 27 | Image("yubikey") 28 | .frame(width:40, height: 40) 29 | .background(Color.accentColor) 30 | .cornerRadius(20) 31 | .padding(.trailing, 5) 32 | VStack(alignment: .leading) { 33 | Text(otp) 34 | .font(.subheadline.weight(.medium)) 35 | .lineLimit(1) 36 | .minimumScaleFactor(0.1) 37 | } 38 | } 39 | .listRowSeparator(.hidden) 40 | .background(Color(.systemBackground)) // without the background set, taps outside the Texts will be ignored 41 | .onTapGesture { 42 | toastPresenter.copyToClipboard(otp) 43 | } 44 | .onLongPressGesture { 45 | toastPresenter.copyToClipboard(otp) 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Authenticator/UI/mul.lproj/LaunchScreen.xcstrings: -------------------------------------------------------------------------------- 1 | { 2 | "sourceLanguage" : "en", 3 | "strings" : { 4 | 5 | }, 6 | "version" : "1.0" 7 | } -------------------------------------------------------------------------------- /AuthenticatorTests/AuthenticatorTests.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 Yubico. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import XCTest 18 | @testable import Authenticator 19 | 20 | class AuthenticatorTests: XCTestCase { 21 | 22 | override func setUp() { 23 | // Put setup code here. This method is called before the invocation of each test method in the class. 24 | } 25 | 26 | override func tearDown() { 27 | // Put teardown code here. This method is called after the invocation of each test method in the class. 28 | } 29 | 30 | func testExample() { 31 | // This is an example of a functional test case. 32 | // Use XCTAssert and related functions to verify your tests produce the correct results. 33 | } 34 | 35 | func testPerformanceExample() { 36 | // This is an example of a performance test case. 37 | self.measure { 38 | // Put the code you want to measure the time of here. 39 | } 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /AuthenticatorTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /AuthenticatorTests/YKFKeyVersionExtensionsTests.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 Yubico. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import XCTest 18 | import YubiKit 19 | @testable import Authenticator 20 | 21 | class YKFKeyVersionExtensionsTests: XCTestCase { 22 | 23 | func testMajor() throws { 24 | let lhs = YKFVersion(bytes: 4, minor: 1, micro: 1) 25 | let rhs = YKFVersion(bytes: 3, minor: 3, micro: 3) 26 | XCTAssert(lhs > rhs, "\(lhs) is not greater than \(rhs)!") 27 | } 28 | 29 | func testMinor() throws { 30 | let lhs = YKFVersion(bytes: 3, minor: 4, micro: 1) 31 | let rhs = YKFVersion(bytes: 3, minor: 1, micro: 4) 32 | XCTAssert(lhs > rhs, "\(lhs) is not greater than \(rhs)!") 33 | } 34 | 35 | func testMicro() throws { 36 | let lhs = YKFVersion(bytes: 3, minor: 1, micro: 4) 37 | let rhs = YKFVersion(bytes: 3, minor: 1, micro: 1) 38 | XCTAssert(lhs > rhs, "\(lhs) is not greater than \(rhs)!") 39 | } 40 | 41 | func testEqual() throws { 42 | let lhs = YKFVersion(bytes: 3, minor: 1, micro: 4) 43 | let rhs = YKFVersion(bytes: 3, minor: 1, micro: 4) 44 | XCTAssert(lhs == rhs, "\(lhs) is not equal to \(rhs)!") 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /LocalizationScreenshots/1-start.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/LocalizationScreenshots/1-start.jpeg -------------------------------------------------------------------------------- /LocalizationScreenshots/10-add-account-manual.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/LocalizationScreenshots/10-add-account-manual.jpeg -------------------------------------------------------------------------------- /LocalizationScreenshots/11-add-account-missing-secret.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/LocalizationScreenshots/11-add-account-missing-secret.jpeg -------------------------------------------------------------------------------- /LocalizationScreenshots/12-add-account-missing-name.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/LocalizationScreenshots/12-add-account-missing-name.jpeg -------------------------------------------------------------------------------- /LocalizationScreenshots/13-configuration.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/LocalizationScreenshots/13-configuration.jpeg -------------------------------------------------------------------------------- /LocalizationScreenshots/14-configuration-toggle-otp.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/LocalizationScreenshots/14-configuration-toggle-otp.jpeg -------------------------------------------------------------------------------- /LocalizationScreenshots/15-configuration-passwords-and-reset-1.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/LocalizationScreenshots/15-configuration-passwords-and-reset-1.jpeg -------------------------------------------------------------------------------- /LocalizationScreenshots/16-configuration-passwords-and-reset-2.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/LocalizationScreenshots/16-configuration-passwords-and-reset-2.jpeg -------------------------------------------------------------------------------- /LocalizationScreenshots/17-configuration-set-password.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/LocalizationScreenshots/17-configuration-set-password.jpeg -------------------------------------------------------------------------------- /LocalizationScreenshots/18-configuration-clear-passwords.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/LocalizationScreenshots/18-configuration-clear-passwords.jpeg -------------------------------------------------------------------------------- /LocalizationScreenshots/19-configuration-nfc-settings.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/LocalizationScreenshots/19-configuration-nfc-settings.jpeg -------------------------------------------------------------------------------- /LocalizationScreenshots/2-start-ready-to-scan.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/LocalizationScreenshots/2-start-ready-to-scan.jpeg -------------------------------------------------------------------------------- /LocalizationScreenshots/20-configuration-reset.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/LocalizationScreenshots/20-configuration-reset.jpeg -------------------------------------------------------------------------------- /LocalizationScreenshots/21-configuration-smarrtcard.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/LocalizationScreenshots/21-configuration-smarrtcard.jpeg -------------------------------------------------------------------------------- /LocalizationScreenshots/22-configuration-smartcard-enabled.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/LocalizationScreenshots/22-configuration-smartcard-enabled.jpeg -------------------------------------------------------------------------------- /LocalizationScreenshots/23-configuration-smartcard-help.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/LocalizationScreenshots/23-configuration-smartcard-help.jpeg -------------------------------------------------------------------------------- /LocalizationScreenshots/24-about.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/LocalizationScreenshots/24-about.jpeg -------------------------------------------------------------------------------- /LocalizationScreenshots/25-about-tutorial-1.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/LocalizationScreenshots/25-about-tutorial-1.jpeg -------------------------------------------------------------------------------- /LocalizationScreenshots/26-about-tutorial-2.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/LocalizationScreenshots/26-about-tutorial-2.jpeg -------------------------------------------------------------------------------- /LocalizationScreenshots/27-about-tutorial-3.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/LocalizationScreenshots/27-about-tutorial-3.jpeg -------------------------------------------------------------------------------- /LocalizationScreenshots/28-about-tutorial-4.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/LocalizationScreenshots/28-about-tutorial-4.jpeg -------------------------------------------------------------------------------- /LocalizationScreenshots/29-about-version-history.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/LocalizationScreenshots/29-about-version-history.jpeg -------------------------------------------------------------------------------- /LocalizationScreenshots/3-start-successfully-read.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/LocalizationScreenshots/3-start-successfully-read.jpeg -------------------------------------------------------------------------------- /LocalizationScreenshots/30-disable-otp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/LocalizationScreenshots/30-disable-otp.png -------------------------------------------------------------------------------- /LocalizationScreenshots/31-smartcard-extension-notification.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/LocalizationScreenshots/31-smartcard-extension-notification.png -------------------------------------------------------------------------------- /LocalizationScreenshots/32-smartcard-extension-unlock.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/LocalizationScreenshots/32-smartcard-extension-unlock.jpeg -------------------------------------------------------------------------------- /LocalizationScreenshots/33-smartcard-extension-done.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/LocalizationScreenshots/33-smartcard-extension-done.png -------------------------------------------------------------------------------- /LocalizationScreenshots/4-start-list.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/LocalizationScreenshots/4-start-list.jpeg -------------------------------------------------------------------------------- /LocalizationScreenshots/5-details.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/LocalizationScreenshots/5-details.jpeg -------------------------------------------------------------------------------- /LocalizationScreenshots/6-rename.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/LocalizationScreenshots/6-rename.jpeg -------------------------------------------------------------------------------- /LocalizationScreenshots/7-delete-alert.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/LocalizationScreenshots/7-delete-alert.jpeg -------------------------------------------------------------------------------- /LocalizationScreenshots/8-start-menu.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/LocalizationScreenshots/8-start-menu.jpeg -------------------------------------------------------------------------------- /LocalizationScreenshots/9-add-account-qr-code.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/LocalizationScreenshots/9-add-account-qr-code.jpeg -------------------------------------------------------------------------------- /Localizations/en.xcloc/Source Contents/Authenticator/UI/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /Localizations/en.xcloc/Source Contents/Authenticator/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle name */ 2 | "CFBundleName" = "Authenticator"; 3 | /* Privacy - NFC Scan Usage Description */ 4 | "NFCReaderUsageDescription" = "The application needs access to NFC reading to communicate with your Yubikey."; 5 | /* Privacy - Camera Usage Description */ 6 | "NSCameraUsageDescription" = "The application needs access to Camera to scan QR codes."; 7 | /* Privacy - Face ID Usage Description */ 8 | "NSFaceIDUsageDescription" = "The application needs access to Face ID to unlock your password vault."; 9 | -------------------------------------------------------------------------------- /Localizations/en.xcloc/Source Contents/Authenticator/en.lproj/Localizable.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Localizations/en.xcloc/Source Contents/Authenticator/en.lproj/Localizable.strings -------------------------------------------------------------------------------- /Localizations/en.xcloc/Source Contents/TokenExtension/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle display name */ 2 | "CFBundleDisplayName" = "TokenExtension"; 3 | /* Bundle name */ 4 | "CFBundleName" = "TokenExtension"; 5 | -------------------------------------------------------------------------------- /Localizations/en.xcloc/contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "developmentRegion" : "en", 3 | "project" : "Authenticator.xcodeproj", 4 | "targetLocale" : "en", 5 | "toolInfo" : { 6 | "toolBuildNumber" : "15C500b", 7 | "toolID" : "com.apple.dt.xcode", 8 | "toolName" : "Xcode", 9 | "toolVersion" : "15.2" 10 | }, 11 | "version" : "1.0" 12 | } -------------------------------------------------------------------------------- /Localizations/en/en.xcloc/Source Contents/Authenticator/UI/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /Localizations/en/en.xcloc/Source Contents/Authenticator/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle name */ 2 | "CFBundleName" = "Authenticator"; 3 | /* Privacy - NFC Scan Usage Description */ 4 | "NFCReaderUsageDescription" = "The application needs access to NFC reading to communicate with your Yubikey."; 5 | /* Privacy - Camera Usage Description */ 6 | "NSCameraUsageDescription" = "The application needs access to Camera to scan QR codes."; 7 | /* Privacy - Face ID Usage Description */ 8 | "NSFaceIDUsageDescription" = "The application needs access to Face ID to unlock your password vault."; 9 | -------------------------------------------------------------------------------- /Localizations/en/en.xcloc/Source Contents/Authenticator/en.lproj/Localizable.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yubico/yubioath-ios/598705fc483779c094db53c9f831f2ae6ed9abdb/Localizations/en/en.xcloc/Source Contents/Authenticator/en.lproj/Localizable.strings -------------------------------------------------------------------------------- /Localizations/en/en.xcloc/Source Contents/TokenExtension/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle display name */ 2 | "CFBundleDisplayName" = "TokenExtension"; 3 | /* Bundle name */ 4 | "CFBundleName" = "TokenExtension"; 5 | -------------------------------------------------------------------------------- /Localizations/en/en.xcloc/contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "developmentRegion" : "en", 3 | "project" : "Authenticator.xcodeproj", 4 | "targetLocale" : "en", 5 | "toolInfo" : { 6 | "toolBuildNumber" : "15C500b", 7 | "toolID" : "com.apple.dt.xcode", 8 | "toolName" : "Xcode", 9 | "toolVersion" : "15.2" 10 | }, 11 | "version" : "1.0" 12 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # iOS application for OATH with YubiKeys 2 | 3 | This app is hosted on the iOS App Store as 4 | [Yubico Authenticator](https://apps.apple.com/se/app/yubico-authenticator/id1476679808). 5 | 6 | See the file LICENSE for copyright and license information. 7 | 8 | ## OATH functionality 9 | 10 | This is an authenticator app compatible with the OATH standard for time and 11 | counter based numeric OTPs, as used by many online services. To store these 12 | credentials and generate the codes, it uses a compatible YubiKey, connected 13 | either via NFC or the Lightning port. 14 | 15 | Add credentials by tapping the menu icon, selecting `Add account` and then 16 | either add a credential by scanning a QR code, or by tapping the `Enter manually` 17 | button. 18 | 19 | Once credentials have been added, simply tap or connect your YubiKey to display 20 | codes. 21 | 22 | ## CryptTokenKit extension 23 | 24 | Besides the OATH functionality this app also support authetication using the CTK extension 25 | functionality provided by Apple. The authentication is handled using certificates stored 26 | in the Smart card application on the YubiKey. 27 | 28 | ## Development 29 | 30 | This app is developed in Xcode and the only external dependency is the 31 | [YubiKit iOS SDK](https://github.com/Yubico/yubikit-ios) which is added using 32 | the Swift Package Manager. To build the app simply open the project file and hit 33 | the build button. 34 | 35 | ## Issues 36 | 37 | Please report app issues in 38 | [the issue tracker on GitHub](https://github.com/Yubico/yubioath-ios). 39 | -------------------------------------------------------------------------------- /TokenExtension/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | TokenExtension 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 19 | CFBundleShortVersionString 20 | $(MARKETING_VERSION) 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | NSExtension 24 | 25 | NSExtensionAttributes 26 | 27 | com.apple.ctk.class-id 28 | com.yubico.Authenticator.TokenExtension 29 | com.apple.ctk.driver-class 30 | $(PRODUCT_MODULE_NAME).TokenDriver 31 | 32 | NSExtensionPointIdentifier 33 | com.apple.ctk-tokens 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /TokenExtension/InfoPlist.xcstrings: -------------------------------------------------------------------------------- 1 | { 2 | "sourceLanguage" : "en", 3 | "strings" : { 4 | "CFBundleDisplayName" : { 5 | "comment" : "Bundle display name", 6 | "extractionState" : "extracted_with_value", 7 | "localizations" : { 8 | "de" : { 9 | "stringUnit" : { 10 | "state" : "translated", 11 | "value" : "Token Extension" 12 | } 13 | }, 14 | "en" : { 15 | "stringUnit" : { 16 | "state" : "new", 17 | "value" : "TokenExtension" 18 | } 19 | }, 20 | "fr" : { 21 | "stringUnit" : { 22 | "state" : "translated", 23 | "value" : "TokenExtension" 24 | } 25 | }, 26 | "ja" : { 27 | "stringUnit" : { 28 | "state" : "translated", 29 | "value" : "TokenExtension" 30 | } 31 | }, 32 | "sk" : { 33 | "stringUnit" : { 34 | "state" : "translated", 35 | "value" : "TokenExtension" 36 | } 37 | } 38 | } 39 | }, 40 | "CFBundleName" : { 41 | "comment" : "Bundle name", 42 | "extractionState" : "extracted_with_value", 43 | "localizations" : { 44 | "de" : { 45 | "stringUnit" : { 46 | "state" : "translated", 47 | "value" : "Token Extension" 48 | } 49 | }, 50 | "en" : { 51 | "stringUnit" : { 52 | "state" : "new", 53 | "value" : "TokenExtension" 54 | } 55 | }, 56 | "fr" : { 57 | "stringUnit" : { 58 | "state" : "translated", 59 | "value" : "TokenExtension" 60 | } 61 | }, 62 | "ja" : { 63 | "stringUnit" : { 64 | "state" : "translated", 65 | "value" : "TokenExtension" 66 | } 67 | }, 68 | "sk" : { 69 | "stringUnit" : { 70 | "state" : "translated", 71 | "value" : "TokenExtension" 72 | } 73 | } 74 | } 75 | } 76 | }, 77 | "version" : "1.0" 78 | } -------------------------------------------------------------------------------- /TokenExtension/Localizable.xcstrings: -------------------------------------------------------------------------------- 1 | { 2 | "sourceLanguage" : "en", 3 | "strings" : { 4 | "Launch Yubico Authenticator" : { 5 | "localizations" : { 6 | "de" : { 7 | "stringUnit" : { 8 | "state" : "translated", 9 | "value" : "Yubico Authenticator starten" 10 | } 11 | }, 12 | "fr" : { 13 | "stringUnit" : { 14 | "state" : "translated", 15 | "value" : "Lancer Yubico Authenticator" 16 | } 17 | }, 18 | "ja" : { 19 | "stringUnit" : { 20 | "state" : "translated", 21 | "value" : "Yubico Authenticatorを起動" 22 | } 23 | }, 24 | "sk" : { 25 | "stringUnit" : { 26 | "state" : "translated", 27 | "value" : "Spustiť Yubico Authenticator" 28 | } 29 | } 30 | } 31 | }, 32 | "Tap here to complete the request using your YubiKey." : { 33 | "localizations" : { 34 | "de" : { 35 | "stringUnit" : { 36 | "state" : "translated", 37 | "value" : "Tippe hier, um die Anfrage mit Deinem YubiKey abzuschließen." 38 | } 39 | }, 40 | "fr" : { 41 | "stringUnit" : { 42 | "state" : "translated", 43 | "value" : "Appuyez ici pour finaliser la demande avec votre YubiKey." 44 | } 45 | }, 46 | "ja" : { 47 | "stringUnit" : { 48 | "state" : "translated", 49 | "value" : "ここをタップし、YubiKeyを使用してリクエストを完了します。" 50 | } 51 | }, 52 | "sk" : { 53 | "stringUnit" : { 54 | "state" : "translated", 55 | "value" : "Ťuknite sem a dokončite žiadosť pomocou svojho YubiKey." 56 | } 57 | } 58 | } 59 | }, 60 | "YubiKey required" : { 61 | "localizations" : { 62 | "de" : { 63 | "stringUnit" : { 64 | "state" : "translated", 65 | "value" : "YubiKey erforderlich" 66 | } 67 | }, 68 | "fr" : { 69 | "stringUnit" : { 70 | "state" : "translated", 71 | "value" : "YubiKey requise" 72 | } 73 | }, 74 | "ja" : { 75 | "stringUnit" : { 76 | "state" : "translated", 77 | "value" : "YubiKeyが必要です" 78 | } 79 | }, 80 | "sk" : { 81 | "stringUnit" : { 82 | "state" : "translated", 83 | "value" : "Vyžaduje sa YubiKey" 84 | } 85 | } 86 | } 87 | } 88 | }, 89 | "version" : "1.0" 90 | } -------------------------------------------------------------------------------- /TokenExtension/Token.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 Yubico. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import CryptoTokenKit 18 | 19 | class Token: TKToken, TKTokenDelegate { 20 | 21 | func createSession(_ token: TKToken) throws -> TKTokenSession { 22 | return TokenSession(token:self) 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /TokenExtension/TokenDriver.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 Yubico. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import CryptoTokenKit 18 | 19 | class TokenDriver: TKTokenDriver, TKTokenDriverDelegate { 20 | 21 | func tokenDriver(_ driver: TKTokenDriver, tokenFor configuration: TKToken.Configuration) throws -> TKToken { 22 | return Token(tokenDriver: self, instanceID: configuration.instanceID) 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /TokenExtension/TokenExtension.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.application-groups 6 | 7 | group.com.yubico.Authenticator 8 | 9 | keychain-access-groups 10 | 11 | $(AppIdentifierPrefix)com.yubico.Authenticator 12 | 13 | 14 | 15 | --------------------------------------------------------------------------------