Browse Source

Initial commit

David Walter 2 years ago
commit
e064dc8101
88 changed files with 5666 additions and 0 deletions
  1. 69
    0
      .gitignore
  2. 17
    0
      .swiftlint.yml
  3. 14
    0
      .travis.yml
  4. 604
    0
      Authenticator.xcodeproj/project.pbxproj
  5. 96
    0
      Authenticator/AppConfig.swift
  6. 59
    0
      Authenticator/AppDelegate.swift
  7. 62
    0
      Authenticator/Assets.xcassets/AppIcon.appiconset/Contents.json
  8. BIN
      Authenticator/Assets.xcassets/AppIcon.appiconset/Icon-20@2x.png
  9. BIN
      Authenticator/Assets.xcassets/AppIcon.appiconset/Icon-20@3x.png
  10. BIN
      Authenticator/Assets.xcassets/AppIcon.appiconset/Icon-29@2x.png
  11. BIN
      Authenticator/Assets.xcassets/AppIcon.appiconset/Icon-29@3x.png
  12. BIN
      Authenticator/Assets.xcassets/AppIcon.appiconset/Icon-40@2x.png
  13. BIN
      Authenticator/Assets.xcassets/AppIcon.appiconset/Icon-40@3x.png
  14. BIN
      Authenticator/Assets.xcassets/AppIcon.appiconset/Icon-App-iTunes.png
  15. BIN
      Authenticator/Assets.xcassets/AppIcon.appiconset/iPhone-60@2x.png
  16. BIN
      Authenticator/Assets.xcassets/AppIcon.appiconset/iPhone-60@3x.png
  17. 6
    0
      Authenticator/Assets.xcassets/Contents.json
  18. 23
    0
      Authenticator/Assets.xcassets/Icon.imageset/Contents.json
  19. BIN
      Authenticator/Assets.xcassets/Icon.imageset/Icon.png
  20. BIN
      Authenticator/Assets.xcassets/Icon.imageset/Icon@2x.png
  21. BIN
      Authenticator/Assets.xcassets/Icon.imageset/Icon@3x.png
  22. 26
    0
      Authenticator/Assets.xcassets/Template.imageset/Contents.json
  23. BIN
      Authenticator/Assets.xcassets/Template.imageset/Icon.png
  24. BIN
      Authenticator/Assets.xcassets/Template.imageset/Icon@2x.png
  25. BIN
      Authenticator/Assets.xcassets/Template.imageset/Icon@3x.png
  26. 20
    0
      Authenticator/Assets.xcassets/mainColor.colorset/Contents.json
  27. 15
    0
      Authenticator/Assets.xcassets/scanWindow.imageset/Contents.json
  28. BIN
      Authenticator/Assets.xcassets/scanWindow.imageset/scanWindow.pdf
  29. 23
    0
      Authenticator/Assets.xcassets/settings.imageset/Contents.json
  30. BIN
      Authenticator/Assets.xcassets/settings.imageset/settings-1.png
  31. BIN
      Authenticator/Assets.xcassets/settings.imageset/settings@2x.png
  32. BIN
      Authenticator/Assets.xcassets/settings.imageset/settings@3x.png
  33. 60
    0
      Authenticator/Info.plist
  34. 73
    0
      Authenticator/Models/OTPAuthParser.swift
  35. 141
    0
      Authenticator/Models/Token.swift
  36. 18
    0
      Authenticator/Settings.bundle/Acknowledgement-AcknowledgementGenerator.plist
  37. 38
    0
      Authenticator/Settings.bundle/Acknowledgement-ColorPickerRow.plist
  38. 39
    0
      Authenticator/Settings.bundle/Acknowledgement-Eureka.plist
  39. 39
    0
      Authenticator/Settings.bundle/Acknowledgement-Hue.plist
  40. 37
    0
      Authenticator/Settings.bundle/Acknowledgement-KeyChainSwift.plist
  41. 30
    0
      Authenticator/Settings.bundle/Acknowledgement-LTMorphingLabe.plist
  42. 30
    0
      Authenticator/Settings.bundle/Acknowledgement-LTMorphingLabel.plist
  43. 30
    0
      Authenticator/Settings.bundle/Acknowledgement-OTPGenerator.plist
  44. 89
    0
      Authenticator/Settings.bundle/Acknowledgement-Passcode.plist
  45. 265
    0
      Authenticator/Settings.bundle/Acknowledgement-Realm.plist
  46. 38
    0
      Authenticator/Settings.bundle/Acknowledgement-UserDefaults.plist
  47. 91
    0
      Authenticator/Settings.bundle/Acknowledgements.plist
  48. 19
    0
      Authenticator/Settings.bundle/Root.plist
  49. BIN
      Authenticator/Settings.bundle/en.lproj/Root.strings
  50. 38
    0
      Authenticator/SettingsViewController.swift
  51. 16
    0
      Authenticator/Themes/dark.json
  52. 16
    0
      Authenticator/Themes/light.json
  53. 91
    0
      Authenticator/ViewModels/TokenViewModel.swift
  54. 454
    0
      Authenticator/Views/Base.lproj/Authenticator~.storyboard
  55. 44
    0
      Authenticator/Views/Base.lproj/LaunchScreen.storyboard
  56. 306
    0
      Authenticator/Views/Base.lproj/Main.storyboard
  57. 230
    0
      Authenticator/Views/Cells & Xibs/ColorRow/ColorPalettes.swift
  58. 304
    0
      Authenticator/Views/Cells & Xibs/ColorRow/ColorPickerRow.swift
  59. 78
    0
      Authenticator/Views/Cells & Xibs/ColorRow/ColorRow.swift
  60. 38
    0
      Authenticator/Views/Cells & Xibs/ColorRow/ColorSwatchCell.swift
  61. 95
    0
      Authenticator/Views/Cells & Xibs/ColorRow/ColorSwatchView.swift
  62. 124
    0
      Authenticator/Views/Cells & Xibs/ColorRow/InlineColorPickerRow.swift
  63. 45
    0
      Authenticator/Views/Cells & Xibs/EmptyView.swift
  64. 53
    0
      Authenticator/Views/Cells & Xibs/EmptyView.xib
  65. 166
    0
      Authenticator/Views/Cells & Xibs/TokenTableViewCell.swift
  66. 192
    0
      Authenticator/Views/MainTableViewController.swift
  67. 76
    0
      Authenticator/Views/PasscodeSettingsViewController.swift
  68. 154
    0
      Authenticator/Views/ScannerViewController.swift
  69. 182
    0
      Authenticator/Views/SettingsViewController.swift
  70. 146
    0
      Authenticator/Views/TokenViewController.swift
  71. 70
    0
      Authenticator/de.lproj/Localizable.strings
  72. 71
    0
      Authenticator/en.lproj/Localizable.strings
  73. 9
    0
      Cartfile
  74. 9
    0
      Cartfile.resolved
  75. 8
    0
      Carthage/Cartfile.resolved
  76. 21
    0
      Carthage/Licenses/ColorPickerRow.license
  77. 22
    0
      Carthage/Licenses/Eureka.license
  78. 22
    0
      Carthage/Licenses/Hue.license
  79. 21
    0
      Carthage/Licenses/KeyChainSwift.license
  80. 13
    0
      Carthage/Licenses/LTMorphingLabel.license
  81. 13
    0
      Carthage/Licenses/OTPGenerator.license
  82. 72
    0
      Carthage/Licenses/Passcode.license
  83. 248
    0
      Carthage/Licenses/Realm.license
  84. 21
    0
      Carthage/Licenses/UserDefaults.license
  85. 72
    0
      LICENSE
  86. 33
    0
      README.md
  87. 2
    0
      script/bootstrap
  88. 20
    0
      script/intelligent-bootstrap

+ 69
- 0
.gitignore View File

@@ -0,0 +1,69 @@
1
+# Created by https://www.gitignore.io/api/macos,xcode,carthage
2
+
3
+### Carthage ###
4
+# Carthage
5
+#
6
+# Add this line if you want to avoid checking in source code from Carthage dependencies.
7
+Carthage/Checkouts
8
+Carthage/Build
9
+
10
+### macOS ###
11
+*.DS_Store
12
+.AppleDouble
13
+.LSOverride
14
+
15
+# Icon must end with two \r
16
+Icon
17
+
18
+# Thumbnails
19
+._*
20
+
21
+# Files that might appear in the root of a volume
22
+.DocumentRevisions-V100
23
+.fseventsd
24
+.Spotlight-V100
25
+.TemporaryItems
26
+.Trashes
27
+.VolumeIcon.icns
28
+.com.apple.timemachine.donotpresent
29
+
30
+# Directories potentially created on remote AFP share
31
+.AppleDB
32
+.AppleDesktop
33
+Network Trash Folder
34
+Temporary Items
35
+.apdisk
36
+
37
+### Xcode ###
38
+# Xcode
39
+#
40
+# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
41
+
42
+## Build generated
43
+build/
44
+DerivedData/
45
+
46
+## Various settings
47
+*.pbxuser
48
+!default.pbxuser
49
+*.mode1v3
50
+!default.mode1v3
51
+*.mode2v3
52
+!default.mode2v3
53
+*.perspectivev3
54
+!default.perspectivev3
55
+xcuserdata/
56
+
57
+## Other
58
+*.moved-aside
59
+*.xccheckout
60
+*.xcscmblueprint
61
+
62
+### Xcode Patch ###
63
+*.xcodeproj/*
64
+!*.xcodeproj/project.pbxproj
65
+!*.xcodeproj/xcshareddata/
66
+!*.xcworkspace/contents.xcworkspacedata
67
+/*.gcno
68
+
69
+# End of https://www.gitignore.io/api/macos,xcode,carthage

+ 17
- 0
.swiftlint.yml View File

@@ -0,0 +1,17 @@
1
+disabled_rules:
2
+  - trailing_whitespace
3
+  - line_length
4
+  - unused_optional_binding
5
+  - function_body_length
6
+opt_in_rules:
7
+  - empty_count
8
+  - no_grouping_extension
9
+included:
10
+  - Authenticator
11
+excluded:
12
+  - Carthage
13
+  - Authenticator/Views/Cells & Xibs/ColorRow
14
+identifier_name:
15
+  excluded:
16
+    - id
17
+    - to

+ 14
- 0
.travis.yml View File

@@ -0,0 +1,14 @@
1
+language: objective-c
2
+
3
+xcode_project: Authenticator.xcodeproj
4
+xcode_scheme: Authenticator
5
+osx_image: xcode9.2
6
+      
7
+before_install:
8
+  - brew update
9
+  - brew upgrade carthage || true
10
+install:
11
+  - travis_wait 30 script/intelligent-bootstrap
12
+
13
+script:
14
+  - xcodebuild clean build -sdk iphonesimulator -project Authenticator.xcodeproj -scheme Authenticator

+ 604
- 0
Authenticator.xcodeproj/project.pbxproj View File

@@ -0,0 +1,604 @@
1
+// !$*UTF8*$!
2
+{
3
+	archiveVersion = 1;
4
+	classes = {
5
+	};
6
+	objectVersion = 48;
7
+	objects = {
8
+
9
+/* Begin PBXBuildFile section */
10
+		6318DCB0200D1A3900F40A63 /* LTMorphingLabel.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D0F0EB200559E7001EC8EC /* LTMorphingLabel.framework */; };
11
+		6318DCB1200D1A3900F40A63 /* LTMorphingLabel.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 63D0F0EB200559E7001EC8EC /* LTMorphingLabel.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
12
+		6318DCB6200D1A3900F40A63 /* Eureka.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6367EA971FF91E3600753CDC /* Eureka.framework */; };
13
+		6318DCB7200D1A3900F40A63 /* Eureka.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 6367EA971FF91E3600753CDC /* Eureka.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
14
+		6318DCB8200D1A3900F40A63 /* OTPGenerator.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6367EA861FF915BC00753CDC /* OTPGenerator.framework */; };
15
+		6318DCB9200D1A3900F40A63 /* OTPGenerator.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 6367EA861FF915BC00753CDC /* OTPGenerator.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
16
+		6318DCBA200D1A3900F40A63 /* Realm.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6367EA871FF915BC00753CDC /* Realm.framework */; };
17
+		6318DCBB200D1A3900F40A63 /* Realm.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 6367EA871FF915BC00753CDC /* Realm.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
18
+		6318DCBC200D1A3900F40A63 /* RealmSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6367EA8A1FF915BC00753CDC /* RealmSwift.framework */; };
19
+		6318DCBD200D1A3900F40A63 /* RealmSwift.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 6367EA8A1FF915BC00753CDC /* RealmSwift.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
20
+		6318DCBF200D1A3E00F40A63 /* Vision.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6354F7F51FF9155200FFCE99 /* Vision.framework */; };
21
+		631B55DC200E64D900D6C15F /* PasscodeSettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 631B55DB200E64D900D6C15F /* PasscodeSettingsViewController.swift */; };
22
+		632656712021295E00695B49 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 633D866A201266DB00FC305C /* AVFoundation.framework */; };
23
+		633D866F2012B27900FC305C /* KeychainSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 633D866E2012B27300FC305C /* KeychainSwift.framework */; };
24
+		633D86702012B27900FC305C /* KeychainSwift.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 633D866E2012B27300FC305C /* KeychainSwift.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
25
+		634795D72013503C001D334F /* Settings.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 634795D62013503C001D334F /* Settings.bundle */; };
26
+		634F54A3201D572600B85422 /* dark.json in Resources */ = {isa = PBXBuildFile; fileRef = 634F54A1201D572600B85422 /* dark.json */; };
27
+		634F54A4201D572600B85422 /* light.json in Resources */ = {isa = PBXBuildFile; fileRef = 634F54A2201D572600B85422 /* light.json */; };
28
+		6354F7F31FF910D600FFCE99 /* ScannerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6354F7F21FF910D600FFCE99 /* ScannerViewController.swift */; };
29
+		6367EA961FF91C4200753CDC /* TokenViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6367EA951FF91C4200753CDC /* TokenViewController.swift */; };
30
+		6367EAB81FF941EC00753CDC /* TokenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6367EAB71FF941EC00753CDC /* TokenViewModel.swift */; };
31
+		63957D0F200417A700305625 /* SettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63957D0E200417A700305625 /* SettingsViewController.swift */; };
32
+		639696B620122F2400887ACC /* Hue.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 639696B220122F0500887ACC /* Hue.framework */; };
33
+		639696B720122F2400887ACC /* Hue.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 639696B220122F0500887ACC /* Hue.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
34
+		639696B820122F2400887ACC /* UserDefaults.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 639696B320122F0500887ACC /* UserDefaults.framework */; };
35
+		639696B920122F2400887ACC /* UserDefaults.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 639696B320122F0500887ACC /* UserDefaults.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
36
+		639696BB201230AB00887ACC /* AppConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 639696BA201230AB00887ACC /* AppConfig.swift */; };
37
+		63AA62DB1FF8221F00A76E77 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63AA62DA1FF8221F00A76E77 /* AppDelegate.swift */; };
38
+		63AA62E01FF8221F00A76E77 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 63AA62DE1FF8221F00A76E77 /* Main.storyboard */; };
39
+		63AA62E21FF8221F00A76E77 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 63AA62E11FF8221F00A76E77 /* Assets.xcassets */; };
40
+		63AA62E51FF8221F00A76E77 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 63AA62E31FF8221F00A76E77 /* LaunchScreen.storyboard */; };
41
+		63AA630A1FF8275800A76E77 /* MainTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63AA63091FF8275800A76E77 /* MainTableViewController.swift */; };
42
+		63AA63311FF82A2E00A76E77 /* Token.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63AA63301FF82A2E00A76E77 /* Token.swift */; };
43
+		63B119832024E2F70059A369 /* Passcode.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 63B119822024E2F70059A369 /* Passcode.framework */; };
44
+		63B119842024E3040059A369 /* Passcode.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 63B119822024E2F70059A369 /* Passcode.framework */; };
45
+		63B119852024E3040059A369 /* Passcode.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 63B119822024E2F70059A369 /* Passcode.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
46
+		63C74AF8202A2BCA00713DAA /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 63C74AF5202A2ACF00713DAA /* Localizable.strings */; };
47
+		63C74AFA202A2CCC00713DAA /* Localizable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63C74AF9202A2CCC00713DAA /* Localizable.swift */; };
48
+		63C896C81FFBCD0B00081DD3 /* TokenTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63C896C71FFBCD0B00081DD3 /* TokenTableViewCell.swift */; };
49
+		63C9C69C2027883100012934 /* Themeable.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 63C9C69B2027883100012934 /* Themeable.framework */; };
50
+		63C9C69D2027883600012934 /* Themeable.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 63C9C69B2027883100012934 /* Themeable.framework */; };
51
+		63C9C69E2027883600012934 /* Themeable.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 63C9C69B2027883100012934 /* Themeable.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
52
+		63C9C6A62027895600012934 /* ColorSwatchView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63C9C6A02027895500012934 /* ColorSwatchView.swift */; };
53
+		63C9C6A72027895600012934 /* ColorSwatchCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63C9C6A12027895500012934 /* ColorSwatchCell.swift */; };
54
+		63C9C6A82027895600012934 /* ColorPalettes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63C9C6A22027895500012934 /* ColorPalettes.swift */; };
55
+		63C9C6A92027895600012934 /* ColorPickerRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63C9C6A32027895500012934 /* ColorPickerRow.swift */; };
56
+		63C9C6AA2027895600012934 /* InlineColorPickerRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63C9C6A42027895500012934 /* InlineColorPickerRow.swift */; };
57
+		63C9C6AB2027895600012934 /* ColorRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63C9C6A52027895500012934 /* ColorRow.swift */; };
58
+		63D0F0E02005371F001EC8EC /* OTPAuthParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63D0F0DF2005371F001EC8EC /* OTPAuthParser.swift */; };
59
+		63EDBD2F201BDB0400FE52DB /* EmptyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63EDBD2D201BDB0400FE52DB /* EmptyView.swift */; };
60
+		63EDBD30201BDB0400FE52DB /* EmptyView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 63EDBD2E201BDB0400FE52DB /* EmptyView.xib */; };
61
+/* End PBXBuildFile section */
62
+
63
+/* Begin PBXCopyFilesBuildPhase section */
64
+		6318DCBE200D1A3900F40A63 /* Embed Frameworks */ = {
65
+			isa = PBXCopyFilesBuildPhase;
66
+			buildActionMask = 2147483647;
67
+			dstPath = "";
68
+			dstSubfolderSpec = 10;
69
+			files = (
70
+				63C9C69E2027883600012934 /* Themeable.framework in Embed Frameworks */,
71
+				6318DCBB200D1A3900F40A63 /* Realm.framework in Embed Frameworks */,
72
+				639696B720122F2400887ACC /* Hue.framework in Embed Frameworks */,
73
+				63B119852024E3040059A369 /* Passcode.framework in Embed Frameworks */,
74
+				6318DCB1200D1A3900F40A63 /* LTMorphingLabel.framework in Embed Frameworks */,
75
+				6318DCBD200D1A3900F40A63 /* RealmSwift.framework in Embed Frameworks */,
76
+				633D86702012B27900FC305C /* KeychainSwift.framework in Embed Frameworks */,
77
+				6318DCB7200D1A3900F40A63 /* Eureka.framework in Embed Frameworks */,
78
+				6318DCB9200D1A3900F40A63 /* OTPGenerator.framework in Embed Frameworks */,
79
+				639696B920122F2400887ACC /* UserDefaults.framework in Embed Frameworks */,
80
+			);
81
+			name = "Embed Frameworks";
82
+			runOnlyForDeploymentPostprocessing = 0;
83
+		};
84
+/* End PBXCopyFilesBuildPhase section */
85
+
86
+/* Begin PBXFileReference section */
87
+		631B55DB200E64D900D6C15F /* PasscodeSettingsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PasscodeSettingsViewController.swift; sourceTree = "<group>"; };
88
+		6326566F2021293400695B49 /* AVKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVKit.framework; path = System/Library/Frameworks/AVKit.framework; sourceTree = SDKROOT; };
89
+		633D866A201266DB00FC305C /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; };
90
+		633D866E2012B27300FC305C /* KeychainSwift.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = KeychainSwift.framework; path = Carthage/Build/iOS/KeychainSwift.framework; sourceTree = "<group>"; };
91
+		634795D62013503C001D334F /* Settings.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Settings.bundle; sourceTree = "<group>"; };
92
+		634F54A1201D572600B85422 /* dark.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = dark.json; sourceTree = "<group>"; };
93
+		634F54A2201D572600B85422 /* light.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = light.json; sourceTree = "<group>"; };
94
+		6354F7F21FF910D600FFCE99 /* ScannerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScannerViewController.swift; sourceTree = "<group>"; };
95
+		6354F7F51FF9155200FFCE99 /* Vision.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Vision.framework; path = System/Library/Frameworks/Vision.framework; sourceTree = SDKROOT; };
96
+		6367EA861FF915BC00753CDC /* OTPGenerator.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OTPGenerator.framework; path = Carthage/Build/iOS/OTPGenerator.framework; sourceTree = "<group>"; };
97
+		6367EA871FF915BC00753CDC /* Realm.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Realm.framework; path = Carthage/Build/iOS/Realm.framework; sourceTree = "<group>"; };
98
+		6367EA8A1FF915BC00753CDC /* RealmSwift.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RealmSwift.framework; path = Carthage/Build/iOS/RealmSwift.framework; sourceTree = "<group>"; };
99
+		6367EA951FF91C4200753CDC /* TokenViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TokenViewController.swift; sourceTree = "<group>"; };
100
+		6367EA971FF91E3600753CDC /* Eureka.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Eureka.framework; path = Carthage/Build/iOS/Eureka.framework; sourceTree = "<group>"; };
101
+		6367EAB71FF941EC00753CDC /* TokenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TokenViewModel.swift; sourceTree = "<group>"; };
102
+		63957D0E200417A700305625 /* SettingsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewController.swift; sourceTree = "<group>"; };
103
+		639696B220122F0500887ACC /* Hue.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Hue.framework; path = Carthage/Build/iOS/Hue.framework; sourceTree = "<group>"; };
104
+		639696B320122F0500887ACC /* UserDefaults.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UserDefaults.framework; path = Carthage/Build/iOS/UserDefaults.framework; sourceTree = "<group>"; };
105
+		639696BA201230AB00887ACC /* AppConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppConfig.swift; sourceTree = "<group>"; };
106
+		63AA62D71FF8221F00A76E77 /* Authenticator.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Authenticator.app; sourceTree = BUILT_PRODUCTS_DIR; };
107
+		63AA62DA1FF8221F00A76E77 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
108
+		63AA62DF1FF8221F00A76E77 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
109
+		63AA62E11FF8221F00A76E77 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
110
+		63AA62E41FF8221F00A76E77 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
111
+		63AA62E61FF8221F00A76E77 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
112
+		63AA63091FF8275800A76E77 /* MainTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainTableViewController.swift; sourceTree = "<group>"; };
113
+		63AA63301FF82A2E00A76E77 /* Token.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Token.swift; sourceTree = "<group>"; };
114
+		63B119822024E2F70059A369 /* Passcode.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Passcode.framework; path = Carthage/Build/iOS/Passcode.framework; sourceTree = "<group>"; };
115
+		63C74AF4202A2ACF00713DAA /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; };
116
+		63C74AF6202A2AD900713DAA /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Localizable.strings; sourceTree = "<group>"; };
117
+		63C74AF9202A2CCC00713DAA /* Localizable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Localizable.swift; path = Carthage/Checkouts/Passcode/Passcode/Localizable.swift; sourceTree = SOURCE_ROOT; };
118
+		63C896C71FFBCD0B00081DD3 /* TokenTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TokenTableViewCell.swift; sourceTree = "<group>"; };
119
+		63C9C69B2027883100012934 /* Themeable.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Themeable.framework; path = Carthage/Build/iOS/Themeable.framework; sourceTree = "<group>"; };
120
+		63C9C6A02027895500012934 /* ColorSwatchView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ColorSwatchView.swift; sourceTree = "<group>"; };
121
+		63C9C6A12027895500012934 /* ColorSwatchCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ColorSwatchCell.swift; sourceTree = "<group>"; };
122
+		63C9C6A22027895500012934 /* ColorPalettes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ColorPalettes.swift; sourceTree = "<group>"; };
123
+		63C9C6A32027895500012934 /* ColorPickerRow.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ColorPickerRow.swift; sourceTree = "<group>"; };
124
+		63C9C6A42027895500012934 /* InlineColorPickerRow.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InlineColorPickerRow.swift; sourceTree = "<group>"; };
125
+		63C9C6A52027895500012934 /* ColorRow.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ColorRow.swift; sourceTree = "<group>"; };
126
+		63D0F0DF2005371F001EC8EC /* OTPAuthParser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OTPAuthParser.swift; sourceTree = "<group>"; };
127
+		63D0F0EB200559E7001EC8EC /* LTMorphingLabel.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = LTMorphingLabel.framework; path = Carthage/Build/iOS/LTMorphingLabel.framework; sourceTree = "<group>"; };
128
+		63EDBD2D201BDB0400FE52DB /* EmptyView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EmptyView.swift; sourceTree = "<group>"; };
129
+		63EDBD2E201BDB0400FE52DB /* EmptyView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = EmptyView.xib; sourceTree = "<group>"; };
130
+/* End PBXFileReference section */
131
+
132
+/* Begin PBXFrameworksBuildPhase section */
133
+		63AA62D41FF8221F00A76E77 /* Frameworks */ = {
134
+			isa = PBXFrameworksBuildPhase;
135
+			buildActionMask = 2147483647;
136
+			files = (
137
+				633D866F2012B27900FC305C /* KeychainSwift.framework in Frameworks */,
138
+				63B119832024E2F70059A369 /* Passcode.framework in Frameworks */,
139
+				6318DCBA200D1A3900F40A63 /* Realm.framework in Frameworks */,
140
+				639696B820122F2400887ACC /* UserDefaults.framework in Frameworks */,
141
+				63C9C69D2027883600012934 /* Themeable.framework in Frameworks */,
142
+				6318DCB0200D1A3900F40A63 /* LTMorphingLabel.framework in Frameworks */,
143
+				6318DCBC200D1A3900F40A63 /* RealmSwift.framework in Frameworks */,
144
+				639696B620122F2400887ACC /* Hue.framework in Frameworks */,
145
+				6318DCB6200D1A3900F40A63 /* Eureka.framework in Frameworks */,
146
+				63B119842024E3040059A369 /* Passcode.framework in Frameworks */,
147
+				6318DCB8200D1A3900F40A63 /* OTPGenerator.framework in Frameworks */,
148
+				632656712021295E00695B49 /* AVFoundation.framework in Frameworks */,
149
+				63C9C69C2027883100012934 /* Themeable.framework in Frameworks */,
150
+				6318DCBF200D1A3E00F40A63 /* Vision.framework in Frameworks */,
151
+			);
152
+			runOnlyForDeploymentPostprocessing = 0;
153
+		};
154
+/* End PBXFrameworksBuildPhase section */
155
+
156
+/* Begin PBXGroup section */
157
+		634F54A0201D56FF00B85422 /* Themes */ = {
158
+			isa = PBXGroup;
159
+			children = (
160
+				634F54A1201D572600B85422 /* dark.json */,
161
+				634F54A2201D572600B85422 /* light.json */,
162
+			);
163
+			path = Themes;
164
+			sourceTree = "<group>";
165
+		};
166
+		6354F7F41FF9155200FFCE99 /* Frameworks */ = {
167
+			isa = PBXGroup;
168
+			children = (
169
+				63C9C69B2027883100012934 /* Themeable.framework */,
170
+				63B119822024E2F70059A369 /* Passcode.framework */,
171
+				6326566F2021293400695B49 /* AVKit.framework */,
172
+				633D866E2012B27300FC305C /* KeychainSwift.framework */,
173
+				633D866A201266DB00FC305C /* AVFoundation.framework */,
174
+				639696B220122F0500887ACC /* Hue.framework */,
175
+				639696B320122F0500887ACC /* UserDefaults.framework */,
176
+				63D0F0EB200559E7001EC8EC /* LTMorphingLabel.framework */,
177
+				6367EA971FF91E3600753CDC /* Eureka.framework */,
178
+				6367EA861FF915BC00753CDC /* OTPGenerator.framework */,
179
+				6367EA871FF915BC00753CDC /* Realm.framework */,
180
+				6367EA8A1FF915BC00753CDC /* RealmSwift.framework */,
181
+				6354F7F51FF9155200FFCE99 /* Vision.framework */,
182
+			);
183
+			name = Frameworks;
184
+			sourceTree = "<group>";
185
+		};
186
+		63AA62CE1FF8221F00A76E77 = {
187
+			isa = PBXGroup;
188
+			children = (
189
+				63AA62D91FF8221F00A76E77 /* Authenticator */,
190
+				63AA62D81FF8221F00A76E77 /* Products */,
191
+				6354F7F41FF9155200FFCE99 /* Frameworks */,
192
+			);
193
+			sourceTree = "<group>";
194
+		};
195
+		63AA62D81FF8221F00A76E77 /* Products */ = {
196
+			isa = PBXGroup;
197
+			children = (
198
+				63AA62D71FF8221F00A76E77 /* Authenticator.app */,
199
+			);
200
+			name = Products;
201
+			sourceTree = "<group>";
202
+		};
203
+		63AA62D91FF8221F00A76E77 /* Authenticator */ = {
204
+			isa = PBXGroup;
205
+			children = (
206
+				639696BA201230AB00887ACC /* AppConfig.swift */,
207
+				63AA62DA1FF8221F00A76E77 /* AppDelegate.swift */,
208
+				63D0F0E520054CCB001EC8EC /* Models */,
209
+				63D0F0E620054CD9001EC8EC /* ViewModels */,
210
+				63D0F0E320054CAC001EC8EC /* Views */,
211
+				63AA62E11FF8221F00A76E77 /* Assets.xcassets */,
212
+				634F54A0201D56FF00B85422 /* Themes */,
213
+				634795D62013503C001D334F /* Settings.bundle */,
214
+				63AA62E61FF8221F00A76E77 /* Info.plist */,
215
+				63C74AF9202A2CCC00713DAA /* Localizable.swift */,
216
+				63C74AF5202A2ACF00713DAA /* Localizable.strings */,
217
+			);
218
+			path = Authenticator;
219
+			sourceTree = "<group>";
220
+		};
221
+		63C9C69F2027895500012934 /* ColorRow */ = {
222
+			isa = PBXGroup;
223
+			children = (
224
+				63C9C6A02027895500012934 /* ColorSwatchView.swift */,
225
+				63C9C6A12027895500012934 /* ColorSwatchCell.swift */,
226
+				63C9C6A22027895500012934 /* ColorPalettes.swift */,
227
+				63C9C6A32027895500012934 /* ColorPickerRow.swift */,
228
+				63C9C6A42027895500012934 /* InlineColorPickerRow.swift */,
229
+				63C9C6A52027895500012934 /* ColorRow.swift */,
230
+			);
231
+			path = ColorRow;
232
+			sourceTree = "<group>";
233
+		};
234
+		63D0F0E320054CAC001EC8EC /* Views */ = {
235
+			isa = PBXGroup;
236
+			children = (
237
+				63AA62E31FF8221F00A76E77 /* LaunchScreen.storyboard */,
238
+				63AA62DE1FF8221F00A76E77 /* Main.storyboard */,
239
+				63D0F0E720054CF3001EC8EC /* Cells & Xibs */,
240
+				63AA63091FF8275800A76E77 /* MainTableViewController.swift */,
241
+				6354F7F21FF910D600FFCE99 /* ScannerViewController.swift */,
242
+				6367EA951FF91C4200753CDC /* TokenViewController.swift */,
243
+				63957D0E200417A700305625 /* SettingsViewController.swift */,
244
+				631B55DB200E64D900D6C15F /* PasscodeSettingsViewController.swift */,
245
+			);
246
+			path = Views;
247
+			sourceTree = "<group>";
248
+		};
249
+		63D0F0E520054CCB001EC8EC /* Models */ = {
250
+			isa = PBXGroup;
251
+			children = (
252
+				63AA63301FF82A2E00A76E77 /* Token.swift */,
253
+				63D0F0DF2005371F001EC8EC /* OTPAuthParser.swift */,
254
+			);
255
+			path = Models;
256
+			sourceTree = "<group>";
257
+		};
258
+		63D0F0E620054CD9001EC8EC /* ViewModels */ = {
259
+			isa = PBXGroup;
260
+			children = (
261
+				6367EAB71FF941EC00753CDC /* TokenViewModel.swift */,
262
+			);
263
+			path = ViewModels;
264
+			sourceTree = "<group>";
265
+		};
266
+		63D0F0E720054CF3001EC8EC /* Cells & Xibs */ = {
267
+			isa = PBXGroup;
268
+			children = (
269
+				63C9C69F2027895500012934 /* ColorRow */,
270
+				63EDBD2D201BDB0400FE52DB /* EmptyView.swift */,
271
+				63EDBD2E201BDB0400FE52DB /* EmptyView.xib */,
272
+				63C896C71FFBCD0B00081DD3 /* TokenTableViewCell.swift */,
273
+			);
274
+			path = "Cells & Xibs";
275
+			sourceTree = "<group>";
276
+		};
277
+/* End PBXGroup section */
278
+
279
+/* Begin PBXNativeTarget section */
280
+		63AA62D61FF8221F00A76E77 /* Authenticator */ = {
281
+			isa = PBXNativeTarget;
282
+			buildConfigurationList = 63AA62E91FF8221F00A76E77 /* Build configuration list for PBXNativeTarget "Authenticator" */;
283
+			buildPhases = (
284
+				63AA62D31FF8221F00A76E77 /* Sources */,
285
+				63AA62D41FF8221F00A76E77 /* Frameworks */,
286
+				63AA62D51FF8221F00A76E77 /* Resources */,
287
+				6318DCBE200D1A3900F40A63 /* Embed Frameworks */,
288
+				6323C4592021BD91004BE10A /* SwiftLint */,
289
+			);
290
+			buildRules = (
291
+			);
292
+			dependencies = (
293
+			);
294
+			name = Authenticator;
295
+			productName = Authenticator;
296
+			productReference = 63AA62D71FF8221F00A76E77 /* Authenticator.app */;
297
+			productType = "com.apple.product-type.application";
298
+		};
299
+/* End PBXNativeTarget section */
300
+
301
+/* Begin PBXProject section */
302
+		63AA62CF1FF8221F00A76E77 /* Project object */ = {
303
+			isa = PBXProject;
304
+			attributes = {
305
+				LastSwiftUpdateCheck = 0920;
306
+				LastUpgradeCheck = 0920;
307
+				ORGANIZATIONNAME = "David Walter";
308
+				TargetAttributes = {
309
+					63AA62D61FF8221F00A76E77 = {
310
+						CreatedOnToolsVersion = 9.2;
311
+						ProvisioningStyle = Automatic;
312
+					};
313
+				};
314
+			};
315
+			buildConfigurationList = 63AA62D21FF8221F00A76E77 /* Build configuration list for PBXProject "Authenticator" */;
316
+			compatibilityVersion = "Xcode 8.0";
317
+			developmentRegion = en;
318
+			hasScannedForEncodings = 0;
319
+			knownRegions = (
320
+				en,
321
+				Base,
322
+				de,
323
+			);
324
+			mainGroup = 63AA62CE1FF8221F00A76E77;
325
+			productRefGroup = 63AA62D81FF8221F00A76E77 /* Products */;
326
+			projectDirPath = "";
327
+			projectRoot = "";
328
+			targets = (
329
+				63AA62D61FF8221F00A76E77 /* Authenticator */,
330
+			);
331
+		};
332
+/* End PBXProject section */
333
+
334
+/* Begin PBXResourcesBuildPhase section */
335
+		63AA62D51FF8221F00A76E77 /* Resources */ = {
336
+			isa = PBXResourcesBuildPhase;
337
+			buildActionMask = 2147483647;
338
+			files = (
339
+				634795D72013503C001D334F /* Settings.bundle in Resources */,
340
+				634F54A3201D572600B85422 /* dark.json in Resources */,
341
+				634F54A4201D572600B85422 /* light.json in Resources */,
342
+				63AA62E51FF8221F00A76E77 /* LaunchScreen.storyboard in Resources */,
343
+				63AA62E21FF8221F00A76E77 /* Assets.xcassets in Resources */,
344
+				63C74AF8202A2BCA00713DAA /* Localizable.strings in Resources */,
345
+				63AA62E01FF8221F00A76E77 /* Main.storyboard in Resources */,
346
+				63EDBD30201BDB0400FE52DB /* EmptyView.xib in Resources */,
347
+			);
348
+			runOnlyForDeploymentPostprocessing = 0;
349
+		};
350
+/* End PBXResourcesBuildPhase section */
351
+
352
+/* Begin PBXShellScriptBuildPhase section */
353
+		6323C4592021BD91004BE10A /* SwiftLint */ = {
354
+			isa = PBXShellScriptBuildPhase;
355
+			buildActionMask = 2147483647;
356
+			files = (
357
+			);
358
+			inputPaths = (
359
+			);
360
+			name = SwiftLint;
361
+			outputPaths = (
362
+			);
363
+			runOnlyForDeploymentPostprocessing = 0;
364
+			shellPath = /bin/sh;
365
+			shellScript = "if which swiftlint >/dev/null; then\n    swiftlint\nelse\n    echo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi";
366
+		};
367
+/* End PBXShellScriptBuildPhase section */
368
+
369
+/* Begin PBXSourcesBuildPhase section */
370
+		63AA62D31FF8221F00A76E77 /* Sources */ = {
371
+			isa = PBXSourcesBuildPhase;
372
+			buildActionMask = 2147483647;
373
+			files = (
374
+				63D0F0E02005371F001EC8EC /* OTPAuthParser.swift in Sources */,
375
+				63C9C6A72027895600012934 /* ColorSwatchCell.swift in Sources */,
376
+				639696BB201230AB00887ACC /* AppConfig.swift in Sources */,
377
+				631B55DC200E64D900D6C15F /* PasscodeSettingsViewController.swift in Sources */,
378
+				63C9C6A92027895600012934 /* ColorPickerRow.swift in Sources */,
379
+				6367EAB81FF941EC00753CDC /* TokenViewModel.swift in Sources */,
380
+				63C9C6AB2027895600012934 /* ColorRow.swift in Sources */,
381
+				63AA63311FF82A2E00A76E77 /* Token.swift in Sources */,
382
+				63AA630A1FF8275800A76E77 /* MainTableViewController.swift in Sources */,
383
+				63957D0F200417A700305625 /* SettingsViewController.swift in Sources */,
384
+				63C9C6AA2027895600012934 /* InlineColorPickerRow.swift in Sources */,
385
+				63C9C6A82027895600012934 /* ColorPalettes.swift in Sources */,
386
+				63C9C6A62027895600012934 /* ColorSwatchView.swift in Sources */,
387
+				63C74AFA202A2CCC00713DAA /* Localizable.swift in Sources */,
388
+				6367EA961FF91C4200753CDC /* TokenViewController.swift in Sources */,
389
+				6354F7F31FF910D600FFCE99 /* ScannerViewController.swift in Sources */,
390
+				63AA62DB1FF8221F00A76E77 /* AppDelegate.swift in Sources */,
391
+				63C896C81FFBCD0B00081DD3 /* TokenTableViewCell.swift in Sources */,
392
+				63EDBD2F201BDB0400FE52DB /* EmptyView.swift in Sources */,
393
+			);
394
+			runOnlyForDeploymentPostprocessing = 0;
395
+		};
396
+/* End PBXSourcesBuildPhase section */
397
+
398
+/* Begin PBXVariantGroup section */
399
+		63AA62DE1FF8221F00A76E77 /* Main.storyboard */ = {
400
+			isa = PBXVariantGroup;
401
+			children = (
402
+				63AA62DF1FF8221F00A76E77 /* Base */,
403
+			);
404
+			name = Main.storyboard;
405
+			sourceTree = "<group>";
406
+		};
407
+		63AA62E31FF8221F00A76E77 /* LaunchScreen.storyboard */ = {
408
+			isa = PBXVariantGroup;
409
+			children = (
410
+				63AA62E41FF8221F00A76E77 /* Base */,
411
+			);
412
+			name = LaunchScreen.storyboard;
413
+			sourceTree = "<group>";
414
+		};
415
+		63C74AF5202A2ACF00713DAA /* Localizable.strings */ = {
416
+			isa = PBXVariantGroup;
417
+			children = (
418
+				63C74AF4202A2ACF00713DAA /* en */,
419
+				63C74AF6202A2AD900713DAA /* de */,
420
+			);
421
+			name = Localizable.strings;
422
+			sourceTree = "<group>";
423
+		};
424
+/* End PBXVariantGroup section */
425
+
426
+/* Begin XCBuildConfiguration section */
427
+		63AA62E71FF8221F00A76E77 /* Debug */ = {
428
+			isa = XCBuildConfiguration;
429
+			buildSettings = {
430
+				ALWAYS_SEARCH_USER_PATHS = NO;
431
+				CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
432
+				CLANG_ANALYZER_NONNULL = YES;
433
+				CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
434
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
435
+				CLANG_CXX_LIBRARY = "libc++";
436
+				CLANG_ENABLE_MODULES = YES;
437
+				CLANG_ENABLE_OBJC_ARC = YES;
438
+				CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
439
+				CLANG_WARN_BOOL_CONVERSION = YES;
440
+				CLANG_WARN_COMMA = YES;
441
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
442
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
443
+				CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
444
+				CLANG_WARN_EMPTY_BODY = YES;
445
+				CLANG_WARN_ENUM_CONVERSION = YES;
446
+				CLANG_WARN_INFINITE_RECURSION = YES;
447
+				CLANG_WARN_INT_CONVERSION = YES;
448
+				CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
449
+				CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
450
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
451
+				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
452
+				CLANG_WARN_STRICT_PROTOTYPES = YES;
453
+				CLANG_WARN_SUSPICIOUS_MOVE = YES;
454
+				CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
455
+				CLANG_WARN_UNREACHABLE_CODE = YES;
456
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
457
+				CODE_SIGN_IDENTITY = "iPhone Developer";
458
+				COPY_PHASE_STRIP = NO;
459
+				DEBUG_INFORMATION_FORMAT = dwarf;
460
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
461
+				ENABLE_TESTABILITY = YES;
462
+				GCC_C_LANGUAGE_STANDARD = gnu11;
463
+				GCC_DYNAMIC_NO_PIC = NO;
464
+				GCC_NO_COMMON_BLOCKS = YES;
465
+				GCC_OPTIMIZATION_LEVEL = 0;
466
+				GCC_PREPROCESSOR_DEFINITIONS = (
467
+					"DEBUG=1",
468
+					"$(inherited)",
469
+				);
470
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
471
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
472
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
473
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
474
+				GCC_WARN_UNUSED_FUNCTION = YES;
475
+				GCC_WARN_UNUSED_VARIABLE = YES;
476
+				IPHONEOS_DEPLOYMENT_TARGET = 11.2;
477
+				MTL_ENABLE_DEBUG_INFO = YES;
478
+				ONLY_ACTIVE_ARCH = YES;
479
+				SDKROOT = iphoneos;
480
+				SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
481
+				SWIFT_OPTIMIZATION_LEVEL = "-Onone";
482
+			};
483
+			name = Debug;
484
+		};
485
+		63AA62E81FF8221F00A76E77 /* Release */ = {
486
+			isa = XCBuildConfiguration;
487
+			buildSettings = {
488
+				ALWAYS_SEARCH_USER_PATHS = NO;
489
+				CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
490
+				CLANG_ANALYZER_NONNULL = YES;
491
+				CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
492
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
493
+				CLANG_CXX_LIBRARY = "libc++";
494
+				CLANG_ENABLE_MODULES = YES;
495
+				CLANG_ENABLE_OBJC_ARC = YES;
496
+				CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
497
+				CLANG_WARN_BOOL_CONVERSION = YES;
498
+				CLANG_WARN_COMMA = YES;
499
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
500
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
501
+				CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
502
+				CLANG_WARN_EMPTY_BODY = YES;
503
+				CLANG_WARN_ENUM_CONVERSION = YES;
504
+				CLANG_WARN_INFINITE_RECURSION = YES;
505
+				CLANG_WARN_INT_CONVERSION = YES;
506
+				CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
507
+				CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
508
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
509
+				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
510
+				CLANG_WARN_STRICT_PROTOTYPES = YES;
511
+				CLANG_WARN_SUSPICIOUS_MOVE = YES;
512
+				CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
513
+				CLANG_WARN_UNREACHABLE_CODE = YES;
514
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
515
+				CODE_SIGN_IDENTITY = "iPhone Developer";
516
+				COPY_PHASE_STRIP = NO;
517
+				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
518
+				ENABLE_NS_ASSERTIONS = NO;
519
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
520
+				GCC_C_LANGUAGE_STANDARD = gnu11;
521
+				GCC_NO_COMMON_BLOCKS = YES;
522
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
523
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
524
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
525
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
526
+				GCC_WARN_UNUSED_FUNCTION = YES;
527
+				GCC_WARN_UNUSED_VARIABLE = YES;
528
+				IPHONEOS_DEPLOYMENT_TARGET = 11.2;
529
+				MTL_ENABLE_DEBUG_INFO = NO;
530
+				SDKROOT = iphoneos;
531
+				SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
532
+				VALIDATE_PRODUCT = YES;
533
+			};
534
+			name = Release;
535
+		};
536
+		63AA62EA1FF8221F00A76E77 /* Debug */ = {
537
+			isa = XCBuildConfiguration;
538
+			buildSettings = {
539
+				ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
540
+				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
541
+				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
542
+				CODE_SIGN_STYLE = Automatic;
543
+				DEVELOPMENT_TEAM = 7MLF4U25UX;
544
+				FRAMEWORK_SEARCH_PATHS = (
545
+					"$(inherited)",
546
+					"$(PROJECT_DIR)/Carthage/Build/iOS",
547
+				);
548
+				INFOPLIST_FILE = Authenticator/Info.plist;
549
+				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
550
+				PRODUCT_BUNDLE_IDENTIFIER = at.davidwalter.Authenticator;
551
+				PRODUCT_NAME = "$(TARGET_NAME)";
552
+				PROVISIONING_PROFILE_SPECIFIER = "";
553
+				SWIFT_VERSION = 4.0;
554
+				TARGETED_DEVICE_FAMILY = 1;
555
+			};
556
+			name = Debug;
557
+		};
558
+		63AA62EB1FF8221F00A76E77 /* Release */ = {
559
+			isa = XCBuildConfiguration;
560
+			buildSettings = {
561
+				ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
562
+				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
563
+				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
564
+				CODE_SIGN_STYLE = Automatic;
565
+				DEVELOPMENT_TEAM = 7MLF4U25UX;
566
+				FRAMEWORK_SEARCH_PATHS = (
567
+					"$(inherited)",
568
+					"$(PROJECT_DIR)/Carthage/Build/iOS",
569
+				);
570
+				INFOPLIST_FILE = Authenticator/Info.plist;
571
+				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
572
+				PRODUCT_BUNDLE_IDENTIFIER = at.davidwalter.Authenticator;
573
+				PRODUCT_NAME = "$(TARGET_NAME)";
574
+				PROVISIONING_PROFILE_SPECIFIER = "";
575
+				SWIFT_VERSION = 4.0;
576
+				TARGETED_DEVICE_FAMILY = 1;
577
+			};
578
+			name = Release;
579
+		};
580
+/* End XCBuildConfiguration section */
581
+
582
+/* Begin XCConfigurationList section */
583
+		63AA62D21FF8221F00A76E77 /* Build configuration list for PBXProject "Authenticator" */ = {
584
+			isa = XCConfigurationList;
585
+			buildConfigurations = (
586
+				63AA62E71FF8221F00A76E77 /* Debug */,
587
+				63AA62E81FF8221F00A76E77 /* Release */,
588
+			);
589
+			defaultConfigurationIsVisible = 0;
590
+			defaultConfigurationName = Release;
591
+		};
592
+		63AA62E91FF8221F00A76E77 /* Build configuration list for PBXNativeTarget "Authenticator" */ = {
593
+			isa = XCConfigurationList;
594
+			buildConfigurations = (
595
+				63AA62EA1FF8221F00A76E77 /* Debug */,
596
+				63AA62EB1FF8221F00A76E77 /* Release */,
597
+			);
598
+			defaultConfigurationIsVisible = 0;
599
+			defaultConfigurationName = Release;
600
+		};
601
+/* End XCConfigurationList section */
602
+	};
603
+	rootObject = 63AA62CF1FF8221F00A76E77 /* Project object */;
604
+}

+ 96
- 0
Authenticator/AppConfig.swift View File

@@ -0,0 +1,96 @@
1
+//
2
+//  AppConfig.swift
3
+//  Authenticator
4
+//
5
+//  Created by David Walter on 19.01.18.
6
+//  Copyright © 2018 David Walter. All rights reserved.
7
+//
8
+
9
+import UIKit
10
+import UserDefaults
11
+import KeychainSwift
12
+import Passcode
13
+import Hue
14
+import Eureka
15
+import Themeable
16
+
17
+struct AppConfig {
18
+    
19
+    static var window: UIWindow?
20
+    
21
+    static var passcode: Passcode = {
22
+        var config = PasscodeConfig(passcodeGetter: {
23
+            return AppConfig.keychain.get("Authentication-code") ?? ""
24
+        }, passcodeSetter: { code in
25
+            AppConfig.keychain.set(code, forKey: "Authentication-code")
26
+        }, biometricsGetter: {
27
+            return UserDefaults.standard[.biometrics]
28
+        })
29
+        config.autoBiometrics = UserDefaults.standard[.biometrics]
30
+        
31
+        return Passcode(window: AppDelegate.window, config: config)
32
+    }()
33
+    
34
+    static let keychain = KeychainSwift()
35
+    
36
+    static func load() {
37
+        if !UserDefaults.standard[.initialized] {
38
+            UserDefaults.standard[.initialized] = true
39
+            
40
+            AppConfig.keychain.delete("Authentication-enabled")
41
+            AppConfig.keychain.delete("Authentication-code")
42
+            UserDefaults.standard[.biometrics] = false
43
+            
44
+            UserDefaults.standard[.mainTint] = "#6543E9"
45
+            UserDefaults.standard[.dark] = false
46
+            
47
+            UserDefaults.standard[.animateToken] = true
48
+            UserDefaults.standard[.animateTimer] = true
49
+            
50
+            Theme.shared.colors = .light
51
+        } else {
52
+            Theme.shared.colors = UserDefaults.standard[.dark] ? .dark : .light
53
+        }
54
+        
55
+        Theme.shared.eureka = true
56
+        
57
+        Theme.shared.customColor = {
58
+            let textOnMainTint = Theme.shared.colors.tint.isDark ? Theme.shared.colors.textLight : Theme.shared.colors.textDark
59
+            AppConfig.passcode.config.colors = PasscodeColors(dark: Theme.shared.colors.isDark, mainTint: Theme.shared.colors.tint, buttonTint: Theme.shared.colors.text, biometrics: (textOnMainTint, Theme.shared.colors.tint), text: Theme.shared.colors.text)
60
+            
61
+            if let hex = UserDefaults.standard[.mainTint] {
62
+                Theme.shared.colors.tint = UIColor(hex: hex)
63
+            }
64
+        }
65
+        
66
+        Theme.shared.customAppearance = {
67
+            // Empty View
68
+            
69
+            UIImageView.appearance(whenContainedInInstancesOf: [EmptyView.self]).tintColor = Theme.shared.colors.dampened
70
+            UILabel.appearance(whenContainedInInstancesOf: [EmptyView.self]).textColor = Theme.shared.colors.dampened
71
+        }
72
+        
73
+        Theme.shared.apply(force: false)
74
+        
75
+        if AppConfig.keychain.getBool("Authentication-enabled") ?? false {
76
+            AppConfig.passcode.authenticateWindow()
77
+        }
78
+    }
79
+}
80
+
81
+extension ThemeColors {
82
+    static let light = ThemeColors.from(bundle: "light")
83
+    static let dark = ThemeColors.from(bundle: "dark")
84
+}
85
+
86
+extension DefaultsKeys {
87
+    static let initialized = DefaultsKey<Bool>("initialized")
88
+    
89
+    static let biometrics = DefaultsKey<Bool>("biometrics")
90
+    
91
+    static let mainTint = DefaultsKey<String>("mainTint")
92
+    static let dark = DefaultsKey<Bool>("dark")
93
+    
94
+    static let animateToken = DefaultsKey<Bool>("animateToken")
95
+    static let animateTimer = DefaultsKey<Bool>("animateTimer")
96
+}

+ 59
- 0
Authenticator/AppDelegate.swift View File

@@ -0,0 +1,59 @@
1
+//
2
+//  AppDelegate.swift
3
+//  Authenticator
4
+//
5
+//  Created by David Walter on 30.12.17.
6
+//  Copyright © 2017 David Walter. All rights reserved.
7
+//
8
+
9
+import UIKit
10
+import UserDefaults
11
+import KeychainSwift
12
+
13
+@UIApplicationMain
14
+class AppDelegate: UIResponder, UIApplicationDelegate {
15
+
16
+    static var window: UIWindow?
17
+    var window: UIWindow?
18
+
19
+    public static let reloadData = NSNotification.Name(rawValue: "reloadData")
20
+
21
+    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
22
+        AppDelegate.window = self.window
23
+        AppConfig.load()
24
+        return true
25
+    }
26
+
27
+    func applicationWillResignActive(_ application: UIApplication) {
28
+
29
+    }
30
+    
31
+    func applicationDidEnterBackground(_ application: UIApplication) {
32
+        UserDefaults.standard.synchronize()
33
+        
34
+        if AppConfig.keychain.getBool("Authentication-enabled") ?? false {
35
+            AppConfig.passcode.authenticateWindow()
36
+        }
37
+    }
38
+
39
+    func applicationWillEnterForeground(_ application: UIApplication) {
40
+        
41
+    }
42
+
43
+    func applicationDidBecomeActive(_ application: UIApplication) {
44
+        
45
+    }
46
+
47
+    func applicationWillTerminate(_ application: UIApplication) {
48
+        UserDefaults.standard.synchronize()
49
+    }
50
+
51
+    func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey: Any] = [:]) -> Bool {
52
+        guard let data = OTPAuthParser.parse(url: url) else { return false }
53
+        
54
+        TokenViewModel.shared.add(token: Token(data: data))
55
+        NotificationCenter.default.post(name: AppDelegate.reloadData, object: nil)
56
+        
57
+        return true
58
+    }
59
+}

+ 62
- 0
Authenticator/Assets.xcassets/AppIcon.appiconset/Contents.json View File

@@ -0,0 +1,62 @@
1
+{
2
+  "images" : [
3
+    {
4
+      "size" : "20x20",
5
+      "idiom" : "iphone",
6
+      "filename" : "Icon-20@2x.png",
7
+      "scale" : "2x"
8
+    },
9
+    {
10
+      "size" : "20x20",
11
+      "idiom" : "iphone",
12
+      "filename" : "Icon-20@3x.png",
13
+      "scale" : "3x"
14
+    },
15
+    {
16
+      "size" : "29x29",
17
+      "idiom" : "iphone",
18
+      "filename" : "Icon-29@2x.png",
19
+      "scale" : "2x"
20
+    },
21
+    {
22
+      "size" : "29x29",
23
+      "idiom" : "iphone",
24
+      "filename" : "Icon-29@3x.png",
25
+      "scale" : "3x"
26
+    },
27
+    {
28
+      "size" : "40x40",
29
+      "idiom" : "iphone",
30
+      "filename" : "Icon-40@2x.png",
31
+      "scale" : "2x"
32
+    },
33
+    {
34
+      "size" : "40x40",
35
+      "idiom" : "iphone",
36
+      "filename" : "Icon-40@3x.png",
37
+      "scale" : "3x"
38
+    },
39
+    {
40
+      "size" : "60x60",
41
+      "idiom" : "iphone",
42
+      "filename" : "iPhone-60@2x.png",
43
+      "scale" : "2x"
44
+    },
45
+    {
46
+      "size" : "60x60",
47
+      "idiom" : "iphone",
48
+      "filename" : "iPhone-60@3x.png",
49
+      "scale" : "3x"
50
+    },
51
+    {
52
+      "size" : "1024x1024",
53
+      "idiom" : "ios-marketing",
54
+      "filename" : "Icon-App-iTunes.png",
55
+      "scale" : "1x"
56
+    }
57
+  ],
58
+  "info" : {
59
+    "version" : 1,
60
+    "author" : "xcode"
61
+  }
62
+}

BIN
Authenticator/Assets.xcassets/AppIcon.appiconset/Icon-20@2x.png View File


BIN
Authenticator/Assets.xcassets/AppIcon.appiconset/Icon-20@3x.png View File


BIN
Authenticator/Assets.xcassets/AppIcon.appiconset/Icon-29@2x.png View File


BIN
Authenticator/Assets.xcassets/AppIcon.appiconset/Icon-29@3x.png View File


BIN
Authenticator/Assets.xcassets/AppIcon.appiconset/Icon-40@2x.png View File


BIN
Authenticator/Assets.xcassets/AppIcon.appiconset/Icon-40@3x.png View File


BIN
Authenticator/Assets.xcassets/AppIcon.appiconset/Icon-App-iTunes.png View File


BIN
Authenticator/Assets.xcassets/AppIcon.appiconset/iPhone-60@2x.png View File


BIN
Authenticator/Assets.xcassets/AppIcon.appiconset/iPhone-60@3x.png View File


+ 6
- 0
Authenticator/Assets.xcassets/Contents.json View File

@@ -0,0 +1,6 @@
1
+{
2
+  "info" : {
3
+    "version" : 1,
4
+    "author" : "xcode"
5
+  }
6
+}

+ 23
- 0
Authenticator/Assets.xcassets/Icon.imageset/Contents.json View File

@@ -0,0 +1,23 @@
1
+{
2
+  "images" : [
3
+    {
4
+      "idiom" : "universal",
5
+      "filename" : "Icon.png",
6
+      "scale" : "1x"
7
+    },
8
+    {
9
+      "idiom" : "universal",
10
+      "filename" : "Icon@2x.png",
11
+      "scale" : "2x"
12
+    },
13
+    {
14
+      "idiom" : "universal",
15
+      "filename" : "Icon@3x.png",
16
+      "scale" : "3x"
17
+    }
18
+  ],
19
+  "info" : {
20
+    "version" : 1,
21
+    "author" : "xcode"
22
+  }
23
+}

BIN
Authenticator/Assets.xcassets/Icon.imageset/Icon.png View File


BIN
Authenticator/Assets.xcassets/Icon.imageset/Icon@2x.png View File


BIN
Authenticator/Assets.xcassets/Icon.imageset/Icon@3x.png View File


+ 26
- 0
Authenticator/Assets.xcassets/Template.imageset/Contents.json View File

@@ -0,0 +1,26 @@
1
+{
2
+  "images" : [
3
+    {
4
+      "idiom" : "universal",
5
+      "filename" : "Icon.png",
6
+      "scale" : "1x"
7
+    },
8
+    {
9
+      "idiom" : "universal",
10
+      "filename" : "Icon@2x.png",
11
+      "scale" : "2x"
12
+    },
13
+    {
14
+      "idiom" : "universal",
15
+      "filename" : "Icon@3x.png",
16
+      "scale" : "3x"
17
+    }
18
+  ],
19
+  "info" : {
20
+    "version" : 1,
21
+    "author" : "xcode"
22
+  },
23
+  "properties" : {
24
+    "template-rendering-intent" : "template"
25
+  }
26
+}

BIN
Authenticator/Assets.xcassets/Template.imageset/Icon.png View File


BIN
Authenticator/Assets.xcassets/Template.imageset/Icon@2x.png View File


BIN
Authenticator/Assets.xcassets/Template.imageset/Icon@3x.png View File


+ 20
- 0
Authenticator/Assets.xcassets/mainColor.colorset/Contents.json View File

@@ -0,0 +1,20 @@
1
+{
2
+  "info" : {
3
+    "version" : 1,
4
+    "author" : "xcode"
5
+  },
6
+  "colors" : [
7
+    {
8
+      "idiom" : "universal",
9
+      "color" : {
10
+        "color-space" : "srgb",
11
+        "components" : {
12
+          "red" : "0x65",
13
+          "alpha" : "1.000",
14
+          "blue" : "0xE9",
15
+          "green" : "0x43"
16
+        }
17
+      }
18
+    }
19
+  ]
20
+}

+ 15
- 0
Authenticator/Assets.xcassets/scanWindow.imageset/Contents.json View File

@@ -0,0 +1,15 @@
1
+{
2
+  "images" : [
3
+    {
4
+      "idiom" : "universal",
5
+      "filename" : "scanWindow.pdf"
6
+    }
7
+  ],
8
+  "info" : {
9
+    "version" : 1,
10
+    "author" : "xcode"
11
+  },
12
+  "properties" : {
13
+    "template-rendering-intent" : "template"
14
+  }
15
+}

BIN
Authenticator/Assets.xcassets/scanWindow.imageset/scanWindow.pdf View File


+ 23
- 0
Authenticator/Assets.xcassets/settings.imageset/Contents.json View File

@@ -0,0 +1,23 @@
1
+{
2
+  "images" : [
3
+    {
4
+      "idiom" : "universal",
5
+      "filename" : "settings-1.png",
6
+      "scale" : "1x"
7
+    },
8
+    {
9
+      "idiom" : "universal",
10
+      "filename" : "settings@2x.png",
11
+      "scale" : "2x"
12
+    },
13
+    {
14
+      "idiom" : "universal",
15
+      "filename" : "settings@3x.png",
16
+      "scale" : "3x"
17
+    }
18
+  ],
19
+  "info" : {
20
+    "version" : 1,
21
+    "author" : "xcode"
22
+  }
23
+}

BIN
Authenticator/Assets.xcassets/settings.imageset/settings-1.png View File


BIN
Authenticator/Assets.xcassets/settings.imageset/settings@2x.png View File


BIN
Authenticator/Assets.xcassets/settings.imageset/settings@3x.png View File


+ 60
- 0
Authenticator/Info.plist View File

@@ -0,0 +1,60 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+<plist version="1.0">
4
+<dict>
5
+	<key>NSFaceIDUsageDescription</key>
6
+	<string>Authenticator uses Face ID as a secure alternative to typing your passcode</string>
7
+	<key>CFBundleDevelopmentRegion</key>
8
+	<string>$(DEVELOPMENT_LANGUAGE)</string>
9
+	<key>CFBundleExecutable</key>
10
+	<string>$(EXECUTABLE_NAME)</string>
11
+	<key>CFBundleIdentifier</key>
12
+	<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
13
+	<key>CFBundleInfoDictionaryVersion</key>
14
+	<string>6.0</string>
15
+	<key>CFBundleName</key>
16
+	<string>$(PRODUCT_NAME)</string>
17
+	<key>CFBundlePackageType</key>
18
+	<string>APPL</string>
19
+	<key>CFBundleShortVersionString</key>
20
+	<string>1.0</string>
21
+	<key>CFBundleURLTypes</key>
22
+	<array>
23
+		<dict>
24
+			<key>CFBundleTypeRole</key>
25
+			<string>Viewer</string>
26
+			<key>CFBundleURLName</key>
27
+			<string>at.davidwalter.otpauth</string>
28
+			<key>CFBundleURLSchemes</key>
29
+			<array>
30
+				<string>otpauth</string>
31
+			</array>
32
+		</dict>
33
+	</array>
34
+	<key>CFBundleVersion</key>
35
+	<string>1</string>
36
+	<key>LSRequiresIPhoneOS</key>
37
+	<true/>
38
+	<key>NSCameraUsageDescription</key>
39
+	<string>Authenticator needs the camera to scan QR codes for easy account configuration</string>
40
+	<key>UILaunchStoryboardName</key>
41
+	<string>LaunchScreen</string>
42
+	<key>UIMainStoryboardFile</key>
43
+	<string>Main</string>
44
+	<key>UIRequiredDeviceCapabilities</key>
45
+	<array>
46
+		<string>armv7</string>
47
+	</array>
48
+	<key>UISupportedInterfaceOrientations</key>
49
+	<array>
50
+		<string>UIInterfaceOrientationPortrait</string>
51
+	</array>
52
+	<key>UISupportedInterfaceOrientations~ipad</key>
53
+	<array>
54
+		<string>UIInterfaceOrientationPortrait</string>
55
+		<string>UIInterfaceOrientationPortraitUpsideDown</string>
56
+		<string>UIInterfaceOrientationLandscapeLeft</string>
57
+		<string>UIInterfaceOrientationLandscapeRight</string>
58
+	</array>
59
+</dict>
60
+</plist>

+ 73
- 0
Authenticator/Models/OTPAuthParser.swift View File

@@ -0,0 +1,73 @@
1
+//
2
+//  OTPAuthParser.swift
3
+//  Authenticator
4
+//
5
+//  Created by David Walter on 09.01.18.
6
+//  Copyright © 2018 David Walter. All rights reserved.
7
+//
8
+
9
+import Foundation
10
+import OTPGenerator
11
+
12
+extension URL {
13
+    subscript(queryParam: String) -> String? {
14
+        guard let url = URLComponents(string: self.absoluteString) else { return nil }
15
+        return url.queryItems?.first(where: { $0.name == queryParam })?.value
16
+    }
17
+}
18
+
19
+class OTPAuthParser {
20
+    
21
+    static func parse(string: String?) -> [String: Any?]? {
22
+        guard let string = string, string.hasPrefix("otpauth://"), let url = URL(string: string), url.scheme == "otpauth" else {
23
+            return nil
24
+        }
25
+        
26
+        return OTPAuthParser.parse(url: url)
27
+    }
28
+    
29
+    static func parse(url: URL) -> [String: Any?]? {
30
+        let label = url.lastPathComponent.split(separator: ":")
31
+        guard url.scheme == "otpauth",
32
+            !label.isEmpty,
33
+            label.count <= 2,
34
+            let secret = url["secret"]
35
+            else { return nil }
36
+        
37
+        var dict: [String: Any?] = [:]
38
+        dict["key"] = secret
39
+        dict["counterBased"] = url.host?.lowercased() == "hotp"
40
+        dict["issuer"] = String(label[0])
41
+        
42
+        if label.count == 2 {
43
+            dict["account"] = String(label[1])
44
+        }
45
+        
46
+        if let issuer = url["issuer"] {
47
+            dict["provider"] = issuer
48
+        }
49
+        
50
+        if let algorithm = url["algorithm"] {
51
+            switch algorithm.uppercased() {
52
+            case "SHA256":
53
+                dict["algorithm"] = OTPAlgorithm.sha256
54
+            case "SHA512":
55
+                dict["algorithm"] = OTPAlgorithm.sha512
56
+            case "MD5":
57
+                dict["algorithm"] = OTPAlgorithm.md5
58
+            default:
59
+                dict["algorithm"] = OTPAlgorithm.sha1
60
+            }
61
+        }
62
+        
63
+        if let digits = url["digits"] {
64
+            dict["digits"] = Double(digits)
65
+        }
66
+        
67
+        if let counter = url["counter"] {
68
+            dict["counter"] = Double(counter)
69
+        }
70
+        
71
+        return dict
72
+    }
73
+}

+ 141
- 0
Authenticator/Models/Token.swift View File

@@ -0,0 +1,141 @@
1
+//
2
+//  Code.swift
3
+//  Authenticator
4
+//
5
+//  Created by David Walter on 30.12.17.
6
+//  Copyright © 2017 David Walter. All rights reserved.
7
+//
8
+
9
+import UIKit
10
+import RealmSwift
11
+import OTPGenerator
12
+
13
+class Tokens: Object {
14
+    let tokens = List<Token>()
15
+}
16
+
17
+class Token: Object {
18
+    @objc dynamic var provider = ""
19
+    @objc dynamic var account = ""
20
+    @objc dynamic var key = ""
21
+    @objc dynamic var color = "#2CB6B1"
22
+    
23
+    @objc dynamic var counterBased = false
24
+    @objc dynamic var counter = 0
25
+    @objc dynamic var digits = 6
26
+    @objc dynamic var algorithm = 0
27
+
28
+    convenience init(data: [String: Any?]) {
29
+        self.init()
30
+        self.update(data: data)
31
+    }
32
+    
33
+    private var otpGenerator: OTPGenerator?
34
+    
35
+    private func getGenerator() -> OTPGenerator? {
36
+        guard let algorithm = OTPAlgorithm(rawValue: algorithm) else {
37
+            return nil
38
+        }
39
+        
40
+        if counterBased {
41
+            self.otpGenerator = HOTPGenerator(secret: self.key, counter: uint_fast64_t(self.counter), pinLength: self.digits, algorithm: algorithm)
42
+        } else {
43
+            self.otpGenerator = TOTPGenerator(secret: self.key, period: 30, pinLength: self.digits, algorithm: algorithm)
44
+        }
45
+        
46
+        return self.otpGenerator
47
+    }
48
+    
49
+    private var generator: OTPGenerator? {
50
+        guard let generator = otpGenerator else {
51
+            return self.getGenerator()
52
+        }
53
+        
54
+        return generator
55
+    }
56
+    
57
+    var time: Int {
58
+        guard let generator = generator as? TOTPGenerator else {
59
+            return -1
60
+        }
61
+        
62
+        return Int(generator.period)
63
+    }
64
+    
65
+    var code: String? {
66
+        if let generator = self.generator as? HOTPGenerator {
67
+            let code = generator.generateOTP()
68
+            self.counter += 1
69
+            return code
70
+        }
71
+        
72
+        if let generator = self.generator as? TOTPGenerator {
73
+            let code = generator.generateOTP()
74
+            return code
75
+        }
76
+        
77
+        return nil
78
+    }
79
+    
80
+    // MARK: - Equatable
81
+    
82
+    public static func == (lhs: Token, rhs: Token) -> Bool {
83
+        let code = lhs.key == rhs.key
84
+        let provider = lhs.provider == rhs.provider
85
+        
86
+        return code && provider
87
+    }
88
+    
89
+    override func isEqual(_ object: Any?) -> Bool {
90
+        guard let other = object as? Token else { return false }
91
+        
92
+        let code = self.key == other.key
93
+        let provider = self.provider == other.provider
94
+        
95
+        return code && provider
96
+    }
97
+    
98
+    // MARK: - Hashable
99
+    
100
+    public override var hash: Int {
101
+        return key.hash + provider.hash
102
+    }
103
+    
104
+    public override var hashValue: Int {
105
+        return key.hashValue + provider.hashValue
106
+    }
107
+    
108
+    // MARK: - Update
109
+
110
+    public func update(data: [String: Any?]) {
111
+        // Essential
112
+        if let key = data["key"] as? String {
113
+            self.key = key
114
+        }
115
+        if let provider = data["provider"] as? String {
116
+            self.provider = provider
117
+        }
118
+        
119
+        // Advanced
120
+        if let counterBased = data["type"] as? Bool {
121
+            self.counterBased = counterBased
122
+        }
123
+        if let counter = data["counter"] as? Double {
124
+            self.counter = Int(counter)
125
+        }
126
+        if let algorithm = data["algorithm"] as? OTPAlgorithm {
127
+            self.algorithm = algorithm.rawValue
128
+        }
129
+        if let digits = data["digits"] as? Double {
130
+            self.digits = Int(digits)
131
+        }
132
+        
133
+        // Custom
134
+        if let account = data["account"] as? String {
135
+            self.account = account
136
+        }
137
+        if let color = data["color"] as? UIColor {
138
+            self.color = color.hex()
139
+        }
140
+    }
141
+}

+ 18
- 0
Authenticator/Settings.bundle/Acknowledgement-AcknowledgementGenerator.plist View File

@@ -0,0 +1,18 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+<plist version="1.0">
4
+  <dict>
5
+    <key>StringsTable</key>
6
+    <string>ThirdPartyLicenses</string>
7
+    <key>PreferenceSpecifiers</key>
8
+    <array>
9
+      <dict>
10
+        <key>Type</key>
11
+        <string>PSGroupSpecifier</string>
12
+        <key>FooterText</key>
13
+        <string>"THE BEER-WARE LICENSE" (Revision 42):
14
+&lt;http://www.knage.net&gt; wrote this file. As long as you retain this notice you can do whatever you want with this stuff. If we meet some day, and you think this stuff is worth it, you can buy me a beer in return Christophe Vallinas Knage.</string>
15
+      </dict>
16
+    </array>
17
+  </dict>
18
+</plist>

+ 38
- 0
Authenticator/Settings.bundle/Acknowledgement-ColorPickerRow.plist View File

@@ -0,0 +1,38 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+<plist version="1.0">
4
+  <dict>
5
+    <key>StringsTable</key>
6
+    <string>ThirdPartyLicenses</string>
7
+    <key>PreferenceSpecifiers</key>
8
+    <array>
9
+      <dict>
10
+        <key>Type</key>
11
+        <string>PSGroupSpecifier</string>
12
+        <key>FooterText</key>
13
+        <string>The MIT License (MIT)
14
+
15
+Copyright (c) 2017 Mark Alldritt and Late Night Software Ltd.
16
+
17
+Permission is hereby granted, free of charge, to any person obtaining a copy
18
+of this software and associated documentation files (the "Software"), to deal
19
+in the Software without restriction, including without limitation the rights
20
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
21
+copies of the Software, and to permit persons to whom the Software is
22
+furnished to do so, subject to the following conditions:
23
+
24
+The above copyright notice and this permission notice shall be included in all
25
+copies or substantial portions of the Software.
26
+
27
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
30
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
31
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
32
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
33
+SOFTWARE.
34
+</string>
35
+      </dict>
36
+    </array>
37
+  </dict>
38
+</plist>

+ 39
- 0
Authenticator/Settings.bundle/Acknowledgement-Eureka.plist View File

@@ -0,0 +1,39 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+<plist version="1.0">
4
+  <dict>
5
+    <key>StringsTable</key>
6
+    <string>ThirdPartyLicenses</string>
7
+    <key>PreferenceSpecifiers</key>
8
+    <array>
9
+      <dict>
10
+        <key>Type</key>
11
+        <string>PSGroupSpecifier</string>
12
+        <key>FooterText</key>
13
+        <string>The MIT License (MIT)
14
+
15
+Copyright (c) 2015 XMARTLABS
16
+
17
+Permission is hereby granted, free of charge, to any person obtaining a copy
18
+of this software and associated documentation files (the "Software"), to deal
19
+in the Software without restriction, including without limitation the rights
20
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
21
+copies of the Software, and to permit persons to whom the Software is
22
+furnished to do so, subject to the following conditions:
23
+
24
+The above copyright notice and this permission notice shall be included in all
25
+copies or substantial portions of the Software.
26
+
27
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
30
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
31
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
32
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
33
+SOFTWARE.
34
+
35
+</string>
36
+      </dict>
37
+    </array>
38
+  </dict>
39
+</plist>

+ 39
- 0
Authenticator/Settings.bundle/Acknowledgement-Hue.plist View File

@@ -0,0 +1,39 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+<plist version="1.0">
4
+  <dict>
5
+    <key>StringsTable</key>
6
+    <string>ThirdPartyLicenses</string>
7
+    <key>PreferenceSpecifiers</key>
8
+    <array>
9
+      <dict>
10
+        <key>Type</key>
11
+        <string>PSGroupSpecifier</string>
12
+        <key>FooterText</key>
13
+        <string>Licensed under the **MIT** license
14
+
15
+&gt; Copyright (c) 2015 Hyper Interaktiv AS
16
+&gt;
17
+&gt; Permission is hereby granted, free of charge, to any person obtaining
18
+&gt; a copy of this software and associated documentation files (the
19
+&gt; "Software"), to deal in the Software without restriction, including
20
+&gt; without limitation the rights to use, copy, modify, merge, publish,
21
+&gt; distribute, sublicense, and/or sell copies of the Software, and to
22
+&gt; permit persons to whom the Software is furnished to do so, subject to
23
+&gt; the following conditions:
24
+&gt;
25
+&gt; The above copyright notice and this permission notice shall be
26
+&gt; included in all copies or substantial portions of the Software.
27
+&gt;
28
+&gt; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
29
+&gt; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
30
+&gt; MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
31
+&gt; IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
32
+&gt; CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
33
+&gt; TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
34
+&gt; SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35
+</string>
36
+      </dict>
37
+    </array>
38
+  </dict>
39
+</plist>

+ 37
- 0
Authenticator/Settings.bundle/Acknowledgement-KeyChainSwift.plist View File

@@ -0,0 +1,37 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+<plist version="1.0">
4
+  <dict>
5
+    <key>StringsTable</key>
6
+    <string>ThirdPartyLicenses</string>
7
+    <key>PreferenceSpecifiers</key>
8
+    <array>
9
+      <dict>
10
+        <key>Type</key>
11
+        <string>PSGroupSpecifier</string>
12
+        <key>FooterText</key>
13
+        <string>The MIT License
14
+
15
+Copyright (c) 2015 Marketplacer
16
+
17
+Permission is hereby granted, free of charge, to any person obtaining a copy
18
+of this software and associated documentation files (the "Software"), to deal
19
+in the Software without restriction, including without limitation the rights
20
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
21
+copies of the Software, and to permit persons to whom the Software is
22
+furnished to do so, subject to the following conditions:
23
+
24
+The above copyright notice and this permission notice shall be included in
25
+all copies or substantial portions of the Software.
26
+
27
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
30
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
31
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
32
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
33
+THE SOFTWARE.</string>
34
+      </dict>
35
+    </array>
36
+  </dict>
37
+</plist>

+ 30
- 0
Authenticator/Settings.bundle/Acknowledgement-LTMorphingLabe.plist View File

@@ -0,0 +1,30 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+<plist version="1.0">
4
+  <dict>
5
+    <key>StringsTable</key>
6
+    <string>ThirdPartyLicenses</string>
7
+    <key>PreferenceSpecifiers</key>
8
+    <array>
9
+      <dict>
10
+        <key>Type</key>
11
+        <string>PSGroupSpecifier</string>
12
+        <key>FooterText</key>
13
+        <string>Copyright 2015 Codewise sp. z o.o. Sp. K.
14
+
15
+Licensed under the Apache License, Version 2.0 (the "License");
16
+you may not use this file except in compliance with the License.
17
+You may obtain a copy of the License at
18
+
19
+  http://www.apache.org/licenses/LICENSE-2.0
20
+
21
+Unless required by applicable law or agreed to in writing, software
22
+distributed under the License is distributed on an "AS IS" BASIS,
23
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
24
+See the License for the specific language governing permissions and
25
+limitations under the License.
26
+</string>
27
+      </dict>
28
+    </array>
29
+  </dict>
30
+</plist>

+ 30
- 0
Authenticator/Settings.bundle/Acknowledgement-LTMorphingLabel.plist View File

@@ -0,0 +1,30 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+<plist version="1.0">
4
+  <dict>
5
+    <key>StringsTable</key>
6
+    <string>ThirdPartyLicenses</string>
7
+    <key>PreferenceSpecifiers</key>
8
+    <array>
9
+      <dict>
10
+        <key>Type</key>
11
+        <string>PSGroupSpecifier</string>
12
+        <key>FooterText</key>
13
+        <string>Copyright 2015 Codewise sp. z o.o. Sp. K.
14
+
15
+Licensed under the Apache License, Version 2.0 (the "License");
16
+you may not use this file except in compliance with the License.
17
+You may obtain a copy of the License at
18
+
19
+  http://www.apache.org/licenses/LICENSE-2.0
20
+
21
+Unless required by applicable law or agreed to in writing, software
22
+distributed under the License is distributed on an "AS IS" BASIS,
23
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
24
+See the License for the specific language governing permissions and
25
+limitations under the License.
26
+</string>
27
+      </dict>
28
+    </array>
29
+  </dict>
30
+</plist>

+ 30
- 0
Authenticator/Settings.bundle/Acknowledgement-OTPGenerator.plist View File

@@ -0,0 +1,30 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+<plist version="1.0">
4
+  <dict>
5
+    <key>StringsTable</key>
6
+    <string>ThirdPartyLicenses</string>
7
+    <key>PreferenceSpecifiers</key>
8
+    <array>
9
+      <dict>
10
+        <key>Type</key>
11
+        <string>PSGroupSpecifier</string>
12
+        <key>FooterText</key>
13
+        <string>Copyright 2015 Codewise sp. z o.o. Sp. K.
14
+
15
+Licensed under the Apache License, Version 2.0 (the "License");
16
+you may not use this file except in compliance with the License.
17
+You may obtain a copy of the License at
18
+
19
+  http://www.apache.org/licenses/LICENSE-2.0
20
+
21
+Unless required by applicable law or agreed to in writing, software
22
+distributed under the License is distributed on an "AS IS" BASIS,
23
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
24
+See the License for the specific language governing permissions and
25
+limitations under the License.
26
+</string>
27
+      </dict>
28
+    </array>
29
+  </dict>
30
+</plist>

+ 89
- 0
Authenticator/Settings.bundle/Acknowledgement-Passcode.plist View File

@@ -0,0 +1,89 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+<plist version="1.0">
4
+  <dict>
5
+    <key>StringsTable</key>
6
+    <string>ThirdPartyLicenses</string>
7
+    <key>PreferenceSpecifiers</key>
8
+    <array>
9
+      <dict>
10
+        <key>Type</key>
11
+        <string>PSGroupSpecifier</string>
12
+        <key>FooterText</key>
13
+        <string>Apache License 
14
+Version 2.0, January 2004 
15
+http://www.apache.org/licenses/
16
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
17
+
18
+1. Definitions.
19
+
20
+"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
21
+
22
+"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
23
+
24
+"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
25
+
26
+"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
27
+
28
+"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
29
+
30
+"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
31
+
32
+"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
33
+
34
+"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
35
+
36
+"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
37
+
38
+"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
39
+
40
+2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
41
+
42
+3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
43
+
44
+4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
45
+
46
+(a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
47
+
48
+(b) You must cause any modified files to carry prominent notices stating that You changed the files; and
49
+
50
+(c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
51
+
52
+(d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
53
+
54
+You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
55
+
56
+5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
57
+
58
+6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
59
+
60
+7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
61
+
62
+8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
63
+
64
+9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
65
+
66
+END OF TERMS AND CONDITIONS
67
+
68
+APPENDIX: How to apply the Apache License to your work.
69
+
70
+To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
71
+
72
+Copyright 2018 David Walter (www.davidwalter.at)
73
+
74
+Licensed under the Apache License, Version 2.0 (the "License"); 
75
+you may not use this file except in compliance with the License. 
76
+You may obtain a copy of the License at
77
+
78
+http://www.apache.org/licenses/LICENSE-2.0
79
+
80
+Unless required by applicable law or agreed to in writing, software 
81
+distributed under the License is distributed on an "AS IS" BASIS, 
82
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
83
+See the License for the specific language governing permissions and 
84
+limitations under the License.
85
+</string>
86
+      </dict>
87
+    </array>
88
+  </dict>
89
+</plist>

+ 265
- 0
Authenticator/Settings.bundle/Acknowledgement-Realm.plist View File

@@ -0,0 +1,265 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+<plist version="1.0">
4
+  <dict>
5
+    <key>StringsTable</key>
6
+    <string>ThirdPartyLicenses</string>
7
+    <key>PreferenceSpecifiers</key>
8
+    <array>
9
+      <dict>
10
+        <key>Type</key>
11
+        <string>PSGroupSpecifier</string>
12
+        <key>FooterText</key>
13
+        <string>TABLE OF CONTENTS
14
+
15
+1. Apache License version 2.0
16
+2. Realm Components
17
+3. Export Compliance
18
+
19
+1. -------------------------------------------------------------------------------
20
+
21
+                                 Apache License
22
+                           Version 2.0, January 2004
23
+                        http://www.apache.org/licenses/
24
+
25
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
26
+
27
+   1. Definitions.
28
+
29
+      "License" shall mean the terms and conditions for use, reproduction,
30
+      and distribution as defined by Sections 1 through 9 of this document.
31
+
32
+      "Licensor" shall mean the copyright owner or entity authorized by
33
+      the copyright owner that is granting the License.
34
+
35
+      "Legal Entity" shall mean the union of the acting entity and all
36
+      other entities that control, are controlled by, or are under common
37
+      control with that entity. For the purposes of this definition,
38
+      "control" means (i) the power, direct or indirect, to cause the
39
+      direction or management of such entity, whether by contract or
40
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
41
+      outstanding shares, or (iii) beneficial ownership of such entity.
42
+
43
+      "You" (or "Your") shall mean an individual or Legal Entity
44
+      exercising permissions granted by this License.
45
+
46
+      "Source" form shall mean the preferred form for making modifications,
47
+      including but not limited to software source code, documentation
48
+      source, and configuration files.
49
+
50
+      "Object" form shall mean any form resulting from mechanical
51
+      transformation or translation of a Source form, including but
52
+      not limited to compiled object code, generated documentation,
53
+      and conversions to other media types.
54
+
55
+      "Work" shall mean the work of authorship, whether in Source or
56
+      Object form, made available under the License, as indicated by a
57
+      copyright notice that is included in or attached to the work
58
+      (an example is provided in the Appendix below).
59
+
60
+      "Derivative Works" shall mean any work, whether in Source or Object
61
+      form, that is based on (or derived from) the Work and for which the
62
+      editorial revisions, annotations, elaborations, or other modifications
63
+      represent, as a whole, an original work of authorship. For the purposes
64
+      of this License, Derivative Works shall not include works that remain
65
+      separable from, or merely link (or bind by name) to the interfaces of,
66
+      the Work and Derivative Works thereof.
67
+
68
+      "Contribution" shall mean any work of authorship, including
69
+      the original version of the Work and any modifications or additions
70
+      to that Work or Derivative Works thereof, that is intentionally
71
+      submitted to Licensor for inclusion in the Work by the copyright owner
72
+      or by an individual or Legal Entity authorized to submit on behalf of
73
+      the copyright owner. For the purposes of this definition, "submitted"
74
+      means any form of electronic, verbal, or written communication sent
75
+      to the Licensor or its representatives, including but not limited to
76
+      communication on electronic mailing lists, source code control systems,
77
+      and issue tracking systems that are managed by, or on behalf of, the
78
+      Licensor for the purpose of discussing and improving the Work, but
79
+      excluding communication that is conspicuously marked or otherwise
80
+      designated in writing by the copyright owner as "Not a Contribution."
81
+
82
+      "Contributor" shall mean Licensor and any individual or Legal Entity
83
+      on behalf of whom a Contribution has been received by Licensor and
84
+      subsequently incorporated within the Work.
85
+
86
+   2. Grant of Copyright License. Subject to the terms and conditions of
87
+      this License, each Contributor hereby grants to You a perpetual,
88
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
89
+      copyright license to reproduce, prepare Derivative Works of,
90
+      publicly display, publicly perform, sublicense, and distribute the
91
+      Work and such Derivative Works in Source or Object form.
92
+
93
+   3. Grant of Patent License. Subject to the terms and conditions of
94
+      this License, each Contributor hereby grants to You a perpetual,
95
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
96
+      (except as stated in this section) patent license to make, have made,
97
+      use, offer to sell, sell, import, and otherwise transfer the Work,
98
+      where such license applies only to those patent claims licensable
99
+      by such Contributor that are necessarily infringed by their
100
+      Contribution(s) alone or by combination of their Contribution(s)
101
+      with the Work to which such Contribution(s) was submitted. If You
102
+      institute patent litigation against any entity (including a
103
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
104
+      or a Contribution incorporated within the Work constitutes direct
105
+      or contributory patent infringement, then any patent licenses
106
+      granted to You under this License for that Work shall terminate
107
+      as of the date such litigation is filed.
108
+
109
+   4. Redistribution. You may reproduce and distribute copies of the
110
+      Work or Derivative Works thereof in any medium, with or without
111
+      modifications, and in Source or Object form, provided that You
112
+      meet the following conditions:
113
+
114
+      (a) You must give any other recipients of the Work or
115
+          Derivative Works a copy of this License; and
116
+
117
+      (b) You must cause any modified files to carry prominent notices
118
+          stating that You changed the files; and
119
+
120
+      (c) You must retain, in the Source form of any Derivative Works
121
+          that You distribute, all copyright, patent, trademark, and
122
+          attribution notices from the Source form of the Work,
123
+          excluding those notices that do not pertain to any part of
124
+          the Derivative Works; and
125
+
126
+      (d) If the Work includes a "NOTICE" text file as part of its
127
+          distribution, then any Derivative Works that You distribute must
128
+          include a readable copy of the attribution notices contained
129
+          within such NOTICE file, excluding those notices that do not
130
+          pertain to any part of the Derivative Works, in at least one
131
+          of the following places: within a NOTICE text file distributed
132
+          as part of the Derivative Works; within the Source form or
133
+          documentation, if provided along with the Derivative Works; or,
134
+          within a display generated by the Derivative Works, if and
135
+          wherever such third-party notices normally appear. The contents
136
+          of the NOTICE file are for informational purposes only and
137
+          do not modify the License. You may add Your own attribution
138
+          notices within Derivative Works that You distribute, alongside
139
+          or as an addendum to the NOTICE text from the Work, provided
140
+          that such additional attribution notices cannot be construed
141
+          as modifying the License.
142
+
143
+      You may add Your own copyright statement to Your modifications and
144
+      may provide additional or different license terms and conditions
145
+      for use, reproduction, or distribution of Your modifications, or
146
+      for any such Derivative Works as a whole, provided Your use,
147
+      reproduction, and distribution of the Work otherwise complies with
148
+      the conditions stated in this License.
149
+
150
+   5. Submission of Contributions. Unless You explicitly state otherwise,
151
+      any Contribution intentionally submitted for inclusion in the Work
152
+      by You to the Licensor shall be under the terms and conditions of
153
+      this License, without any additional terms or conditions.
154
+      Notwithstanding the above, nothing herein shall supersede or modify
155
+      the terms of any separate license agreement you may have executed
156
+      with Licensor regarding such Contributions.
157
+
158
+   6. Trademarks. This License does not grant permission to use the trade
159
+      names, trademarks, service marks, or product names of the Licensor,
160
+      except as required for reasonable and customary use in describing the
161
+      origin of the Work and reproducing the content of the NOTICE file.
162
+
163
+   7. Disclaimer of Warranty. Unless required by applicable law or
164
+      agreed to in writing, Licensor provides the Work (and each
165
+      Contributor provides its Contributions) on an "AS IS" BASIS,
166
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
167
+      implied, including, without limitation, any warranties or conditions
168
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
169
+      PARTICULAR PURPOSE. You are solely responsible for determining the
170
+      appropriateness of using or redistributing the Work and assume any
171
+      risks associated with Your exercise of permissions under this License.
172
+
173
+   8. Limitation of Liability. In no event and under no legal theory,
174
+      whether in tort (including negligence), contract, or otherwise,
175
+      unless required by applicable law (such as deliberate and grossly
176
+      negligent acts) or agreed to in writing, shall any Contributor be
177
+      liable to You for damages, including any direct, indirect, special,
178
+      incidental, or consequential damages of any character arising as a
179
+      result of this License or out of the use or inability to use the
180
+      Work (including but not limited to damages for loss of goodwill,
181
+      work stoppage, computer failure or malfunction, or any and all
182
+      other commercial damages or losses), even if such Contributor
183
+      has been advised of the possibility of such damages.
184
+
185
+   9. Accepting Warranty or Additional Liability. While redistributing
186
+      the Work or Derivative Works thereof, You may choose to offer,
187
+      and charge a fee for, acceptance of support, warranty, indemnity,
188
+      or other liability obligations and/or rights consistent with this
189
+      License. However, in accepting such obligations, You may act only
190
+      on Your own behalf and on Your sole responsibility, not on behalf
191
+      of any other Contributor, and only if You agree to indemnify,
192
+      defend, and hold each Contributor harmless for any liability
193
+      incurred by, or claims asserted against, such Contributor by reason
194
+      of your accepting any such warranty or additional liability.
195
+
196
+2. -------------------------------------------------------------------------------
197
+
198
+REALM COMPONENTS
199
+
200
+This software contains components with separate copyright and license terms.
201
+Your use of these components is subject to the terms and conditions of the
202
+following licenses.
203
+
204
+For the Realm Platform Extensions component
205
+
206
+  Realm Platform Extensions License
207
+
208
+  Copyright (c) 2011-2017 Realm Inc All rights reserved
209
+
210
+  Redistribution and use in binary form, with or without modification, is
211
+  permitted provided that the following conditions are met:
212
+
213
+  1. You agree not to attempt to decompile, disassemble, reverse engineer or
214
+  otherwise discover the source code from which the binary code was derived.
215
+  You may, however, access and obtain a separate license for most of the
216
+  source code from which this Software was created, at
217
+  http://realm.io/pricing/.
218
+
219
+  2. Redistributions in binary form must reproduce the above copyright notice,
220
+  this list of conditions and the following disclaimer in the documentation
221
+  and/or other materials provided with the distribution.
222
+
223
+  3. Neither the name of the copyright holder nor the names of its
224
+  contributors may be used to endorse or promote products derived from this
225
+  software without specific prior written permission.
226
+
227
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
228
+  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
229
+  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
230
+  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
231
+  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
232
+  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
233
+  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
234
+  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
235
+  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
236
+  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
237
+  POSSIBILITY OF SUCH DAMAGE.
238
+
239
+3. -------------------------------------------------------------------------------
240
+
241
+EXPORT COMPLIANCE
242
+
243
+You understand that the Software may contain cryptographic functions that may be
244
+subject to export restrictions, and you represent and warrant that you are not
245
+(i) located in a jurisdiction that is subject to United States economic
246
+sanctions (“Prohibited Jurisdiction”), including Cuba, Iran, North Korea,
247
+Sudan, Syria or the Crimea region, (ii) a person listed on any U.S. government
248
+blacklist (to include the List of Specially Designated Nationals and Blocked
249
+Persons or the Consolidated Sanctions List administered by the U.S. Department
250
+of the Treasury’s Office of Foreign Assets Control, or the Denied Persons List
251
+or Entity List administered by the U.S. Department of Commerce)
252
+(“Sanctioned Person”), or (iii) controlled or 50% or more owned by a Sanctioned
253
+Person.
254
+
255
+You agree to comply with all export, re-export and import restrictions and
256
+regulations of the U.S. Department of Commerce or other agency or authority of
257
+the United States or other applicable countries. You also agree not to transfer,
258
+or authorize the transfer of, directly or indirectly, of the Software to any
259
+Prohibited Jurisdiction, or otherwise in violation of any such restrictions or
260
+regulations.
261
+</string>
262
+      </dict>
263
+    </array>
264
+  </dict>
265
+</plist>

+ 38
- 0
Authenticator/Settings.bundle/Acknowledgement-UserDefaults.plist View File

@@ -0,0 +1,38 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+<plist version="1.0">
4
+  <dict>
5
+    <key>StringsTable</key>
6
+    <string>ThirdPartyLicenses</string>
7
+    <key>PreferenceSpecifiers</key>
8
+    <array>
9
+      <dict>
10
+        <key>Type</key>
11
+        <string>PSGroupSpecifier</string>
12
+        <key>FooterText</key>
13
+        <string>MIT License
14
+
15
+Copyright (c) 2018 David Walter
16
+
17
+Permission is hereby granted, free of charge, to any person obtaining a copy
18
+of this software and associated documentation files (the "Software"), to deal
19
+in the Software without restriction, including without limitation the rights
20
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
21
+copies of the Software, and to permit persons to whom the Software is
22
+furnished to do so, subject to the following conditions:
23
+
24
+The above copyright notice and this permission notice shall be included in all
25
+copies or substantial portions of the Software.
26
+
27
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
30
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
31
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
32
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
33
+SOFTWARE.
34
+</string>
35
+      </dict>
36
+    </array>
37
+  </dict>
38
+</plist>

+ 91
- 0
Authenticator/Settings.bundle/Acknowledgements.plist View File

@@ -0,0 +1,91 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+<plist version="1.0">
4
+  <dict>
5
+    <key>StringsTable</key>
6
+    <string>ThirdPartyLicenses</string>
7
+    <key>PreferenceSpecifiers</key>
8
+    <array>
9
+      <dict>
10
+        <key>Type</key>
11
+        <string>PSChildPaneSpecifier</string>
12
+        <key>Title</key>
13
+        <string>AcknowledgementGenerator</string>
14
+        <key>File</key>
15
+        <string>Acknowledgement-AcknowledgementGenerator</string>
16
+      </dict>
17
+      <dict>
18
+        <key>Type</key>
19
+        <string>PSChildPaneSpecifier</string>
20
+        <key>Title</key>
21
+        <string>ColorPickerRow</string>
22
+        <key>File</key>
23
+        <string>Acknowledgement-ColorPickerRow</string>
24
+      </dict>
25
+      <dict>
26
+        <key>Type</key>
27
+        <string>PSChildPaneSpecifier</string>
28
+        <key>Title</key>
29
+        <string>Eureka</string>
30
+        <key>File</key>
31
+        <string>Acknowledgement-Eureka</string>
32
+      </dict>
33
+      <dict>
34
+        <key>Type</key>
35
+        <string>PSChildPaneSpecifier</string>
36
+        <key>Title</key>
37
+        <string>Hue</string>
38
+        <key>File</key>
39
+        <string>Acknowledgement-Hue</string>
40
+      </dict>
41
+      <dict>
42
+        <key>Type</key>
43
+        <string>PSChildPaneSpecifier</string>
44
+        <key>Title</key>
45
+        <string>KeyChainSwift</string>
46
+        <key>File</key>
47
+        <string>Acknowledgement-KeyChainSwift</string>
48
+      </dict>
49
+      <dict>
50
+        <key>Type</key>
51
+        <string>PSChildPaneSpecifier</string>
52
+        <key>Title</key>
53
+        <string>LTMorphingLabel</string>
54
+        <key>File</key>
55
+        <string>Acknowledgement-LTMorphingLabel</string>
56
+      </dict>
57
+      <dict>
58
+        <key>Type</key>
59
+        <string>PSChildPaneSpecifier</string>
60
+        <key>Title</key>
61
+        <string>OTPGenerator</string>
62
+        <key>File</key>
63
+        <string>Acknowledgement-OTPGenerator</string>
64
+      </dict>
65
+      <dict>
66
+        <key>Type</key>
67
+        <string>PSChildPaneSpecifier</string>
68
+        <key>Title</key>
69
+        <string>Passcode</string>
70
+        <key>File</key>
71
+        <string>Acknowledgement-Passcode</string>
72
+      </dict>
73
+      <dict>
74
+        <key>Type</key>
75
+        <string>PSChildPaneSpecifier</string>
76
+        <key>Title</key>
77
+        <string>Realm</string>
78
+        <key>File</key>
79
+        <string>Acknowledgement-Realm</string>
80
+      </dict>
81
+      <dict>
82
+        <key>Type</key>
83
+        <string>PSChildPaneSpecifier</string>
84
+        <key>Title</key>
85
+        <string>UserDefaults</string>
86
+        <key>File</key>
87
+        <string>Acknowledgement-UserDefaults</string>
88
+      </dict>
89
+    </array>
90
+  </dict>
91
+</plist>

+ 19
- 0
Authenticator/Settings.bundle/Root.plist View File

@@ -0,0 +1,19 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+<plist version="1.0">
4
+    <dict>
5
+        <key>PreferenceSpecifiers</key>
6
+        <array>
7
+            <dict>
8
+                <key>Type</key>
9
+                <string>PSChildPaneSpecifier</string>
10
+                <key>Title</key>
11
+                <string>Acknowledgements</string>
12
+                <key>File</key>
13
+                <string>Acknowledgements</string>
14
+            </dict>
15
+        </array>
16
+        <key>StringsTable</key>
17
+        <string>Root</string>
18
+    </dict>
19
+</plist>

BIN
Authenticator/Settings.bundle/en.lproj/Root.strings View File


+ 38
- 0
Authenticator/SettingsViewController.swift View File

@@ -0,0 +1,38 @@
1
+//
2
+//  SettingsViewController.swift
3
+//  Authenticator
4
+//
5
+//  Created by David Walter on 08.01.18.
6
+//  Copyright © 2018 David Walter. All rights reserved.
7
+//
8
+
9
+import UIKit
10
+import Eureka
11
+
12
+class SettingsTableViewController: FormViewController {
13
+    
14
+    override func viewDidLoad() {
15
+        super.viewDidLoad()
16
+        
17
+        self.form
18
+            +++ Section("Sync")
19
+            <<< ButtonRow("") { row in
20
+                row.title = "iCloud Sync"
21
+            }
22
+            +++ Section("Security")
23
+            <<< ButtonRow("security") { row in
24
+                row.title = "Passcode & Touch ID"
25
+            }
26
+            +++ Section("Options")
27
+            <<< ButtonRow("style") { row in
28
+                row.title = "Code grouping style"
29
+            }
30
+            +++ Section("Support")
31
+            <<< ButtonRow("support") { row in
32
+                row.title = "Authenticator Support Website"
33
+            }
34
+            <<< ButtonRow("email") { row in
35
+                row.title = "Email Developer"
36
+            }
37
+    }
38
+}

+ 16
- 0
Authenticator/Themes/dark.json View File

@@ -0,0 +1,16 @@
1
+{
2
+	"isDark": true,
3
+    "tint": "#6543E9",
4
+	"dampened": "#505162",
5
+	
6
+	"text": "#FFFFFF",
7
+    "textInverse": "#000000",
8
+	"textDark": "#292B35",
9
+    "textLight": "#E7E8EB",
10
+  
11
+    "background": "#292B35",
12
+	"backgroundDark": "#E7E8EB",
13
+	"backgroundForm": "#292B35",
14
+    "cell": "#E7E8EB",
15
+	"separator": "#363748"
16
+}

+ 16
- 0
Authenticator/Themes/light.json View File

@@ -0,0 +1,16 @@
1
+{
2
+    "isDark": false,
3
+    "tint": "#6543E9",
4
+	"dampened": "#B2B2B2",
5
+	
6
+	"text": "#000000",
7
+    "textInverse": "#FFFFFF",
8
+	"textDark": "#292B35",
9
+    "textLight": "#E7E8EB",
10
+  
11
+    "background": "#FFFFFF",
12
+	"backgroundDark": "#292B35",
13
+	"backgroundForm": "#E7E8EB",
14
+    "cell": "#FFFFFF",
15
+	"separator": "#CAC9CD"
16
+}

+ 91
- 0
Authenticator/ViewModels/TokenViewModel.swift View File

@@ -0,0 +1,91 @@
1
+//
2
+//  TokenViewModel.swift
3
+//  Authenticator
4
+//
5
+//  Created by David Walter on 31.12.17.
6
+//  Copyright © 2017 David Walter. All rights reserved.
7
+//
8
+
9
+import UIKit
10
+import RealmSwift
11
+import OTPGenerator
12
+
13
+class TokenViewModel {
14
+    
15
+    public static let shared = TokenViewModel { model in
16
+        guard let tokens = model.realm?.objects(Tokens.self).first else { return }
17
+        model.tokens = tokens.tokens
18
+    }
19
+    
20
+    let realm: Realm?
21
+    var tokens: List<Token>?
22
+    let reference = Token()
23
+    
24
+    fileprivate init() {
25
+        do {
26
+            realm = try Realm()
27
+        } catch {
28
+            realm = nil
29
+        }
30
+        
31
+        guard let realm = self.realm else { return }
32
+        
33
+        realm.autorefresh = true
34
+        
35
+        if realm.objects(Tokens.self).isEmpty {
36
+            try? realm.write {
37
+                realm.add(Tokens())
38
+            }
39
+        }
40
+    }
41
+    
42
+    fileprivate convenience init(_ completion: (TokenViewModel) -> Void) {
43
+        self.init()
44
+        completion(self)
45
+    }
46
+    
47
+    var isEmpty: Bool {
48
+        return tokens?.isEmpty ?? true
49
+    }
50
+    
51
+    var count: Int {
52
+        return tokens?.count ?? 0
53
+    }
54
+    
55
+    func contains(token: Token?) -> Bool {
56
+        guard let token = token else { return false }
57
+        
58
+        return tokens?.contains(token) ?? false
59
+    }
60
+    
61
+    func add(token: Token?) {
62
+        guard let token = token else { return }
63
+        
64
+        try? realm?.write { tokens?.append(token) }
65
+    }
66
+    
67
+    func update(token: Token?, data: [String: Any?]) {
68
+        guard let token = token else { return }
69
+        
70
+        try? realm?.write { token.update(data: data) }
71
+    }
72
+    
73
+    func delete(token: Token) {
74
+        guard let index = self.tokens?.index(of: token) else { return }
75
+        self.delete(at: index)
76
+    }
77
+    
78
+    func delete(at index: Int) {
79
+        try? realm?.write { tokens?.remove(at: index) }
80
+    }
81
+    
82
+    func move(from: Int, to: Int) {
83
+        try? realm?.write { tokens?.move(from: from, to: to) }
84
+    }
85
+    
86
+    func reset() {
87
+        try? realm?.write {
88
+            self.tokens?.removeAll()
89
+        }
90
+    }
91
+}

+ 454
- 0
Authenticator/Views/Base.lproj/Authenticator~.storyboard View File

@@ -0,0 +1,454 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13771" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="xXX-nL-hYA">
3
+    <device id="retina4_7" orientation="portrait">
4
+        <adaptation id="fullscreen"/>
5
+    </device>
6
+    <dependencies>
7
+        <deployment identifier="iOS"/>
8
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13772"/>
9
+        <capability name="Aspect ratio constraints" minToolsVersion="5.1"/>
10
+        <capability name="Constraints to layout margins" minToolsVersion="6.0"/>
11
+        <capability name="Named colors" minToolsVersion="9.0"/>
12
+        <capability name="Navigation items with more than one left or right bar item" minToolsVersion="7.0"/>
13
+        <capability name="Safe area layout guides" minToolsVersion="9.0"/>
14
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
15
+    </dependencies>
16
+    <customFonts key="customFonts">
17
+        <array key="Menlo.ttc">
18
+            <string>Menlo-Regular</string>
19
+        </array>
20
+    </customFonts>
21
+    <scenes>
22
+        <!--Settings-->
23
+        <scene sceneID="3nB-o0-RvR">
24
+            <objects>
25
+                <viewController title="Settings" id="sZZ-2F-jyh" customClass="SettingsViewController" customModule="Authenticator" customModuleProvider="target" sceneMemberID="viewController">
26
+                    <view key="view" contentMode="scaleToFill" id="gcj-R6-NaC">
27
+                        <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
28
+                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
29
+                        <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
30
+                        <viewLayoutGuide key="safeArea" id="0Cc-Xq-J0v"/>
31
+                    </view>
32
+                    <navigationItem key="navigationItem" title="Settings" id="3f7-j3-XEa">
33
+                        <barButtonItem key="rightBarButtonItem" style="done" systemItem="done" id="Hqx-mh-mmS">
34
+                            <connections>
35
+                                <segue destination="wIl-KW-H5Q" kind="unwind" unwindAction="unwindTokenViewWithSegue:" id="TZX-Qz-4Gt"/>
36
+                            </connections>
37
+                        </barButtonItem>
38
+                    </navigationItem>
39
+                    <connections>
40
+                        <segue destination="ENV-jR-IzX" kind="show" identifier="passcodeSegue" id="xbv-1M-4gV"/>
41
+                        <segue destination="pYf-FM-pAQ" kind="show" identifier="icloudSegue" id="h2w-mc-MYj"/>
42
+                        <segue destination="a1A-iG-iQj" kind="presentation" identifier="checkPasscodeSegue" id="FUv-uA-grK"/>
43
+                    </connections>
44
+                </viewController>
45
+                <placeholder placeholderIdentifier="IBFirstResponder" id="UO2-Mi-vZX" userLabel="First Responder" sceneMemberID="firstResponder"/>
46
+                <exit id="wIl-KW-H5Q" userLabel="Exit" sceneMemberID="exit"/>
47
+            </objects>
48
+            <point key="canvasLocation" x="3636" y="-637"/>
49
+        </scene>
50
+        <!--iCloud-->
51
+        <scene sceneID="6Qc-7Y-DAt">
52
+            <objects>
53
+                <viewController title="iCloud" id="pYf-FM-pAQ" sceneMemberID="viewController">
54
+                    <view key="view" contentMode="scaleToFill" id="fKX-Rg-Wyj">
55
+                        <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
56
+                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
57
+                        <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
58
+                        <viewLayoutGuide key="safeArea" id="sB0-SV-VxI"/>
59
+                    </view>
60
+                </viewController>
61
+                <placeholder placeholderIdentifier="IBFirstResponder" id="1bG-4f-7mn" userLabel="First Responder" sceneMemberID="firstResponder"/>
62
+            </objects>
63
+            <point key="canvasLocation" x="4628" y="-1030"/>
64
+        </scene>
65
+        <!--Passcode-->
66
+        <scene sceneID="mbP-1k-pII">
67
+            <objects>
68
+                <viewController title="Passcode" id="ENV-jR-IzX" customClass="PasscodeSettingsViewController" customModule="Authenticator" customModuleProvider="target" sceneMemberID="viewController">
69
+                    <view key="view" contentMode="scaleToFill" id="nt9-zX-dTj">
70
+                        <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
71
+                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
72
+                        <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
73
+                        <viewLayoutGuide key="safeArea" id="DQZ-wL-7DA"/>
74
+                    </view>
75
+                    <connections>
76
+                        <segue destination="a1A-iG-iQj" kind="presentation" identifier="passcodeSegue" modalPresentationStyle="overFullScreen" modalTransitionStyle="crossDissolve" id="waz-LM-6pG"/>
77
+                    </connections>
78
+                </viewController>
79
+                <placeholder placeholderIdentifier="IBFirstResponder" id="Kis-hM-Pqq" userLabel="First Responder" sceneMemberID="firstResponder"/>
80
+            </objects>
81
+            <point key="canvasLocation" x="4628" y="-268"/>
82
+        </scene>
83
+        <!--Navigation Controller-->
84
+        <scene sceneID="Gff-BG-Twa">
85
+            <objects>
86
+                <navigationController id="8eF-jb-LfR" sceneMemberID="viewController">
87
+                    <navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" largeTitles="YES" id="jxL-yQ-Kq1">
88
+                        <rect key="frame" x="0.0" y="20" width="375" height="96"/>
89
+                        <autoresizingMask key="autoresizingMask"/>
90
+                    </navigationBar>
91
+                    <connections>
92
+                        <segue destination="sZZ-2F-jyh" kind="relationship" relationship="rootViewController" id="7SK-sB-KmO"/>
93
+                    </connections>
94
+                </navigationController>
95
+                <placeholder placeholderIdentifier="IBFirstResponder" id="DoV-BU-4mq" userLabel="First Responder" sceneMemberID="firstResponder"/>
96
+            </objects>
97
+            <point key="canvasLocation" x="2796" y="-637"/>
98
+        </scene>
99
+        <!--Authenticator-->
100
+        <scene sceneID="O4b-zH-aep">
101
+            <objects>
102
+                <tableViewController id="OCe-kP-HpL" customClass="MainTableViewController" customModule="Authenticator" customModuleProvider="target" sceneMemberID="viewController">
103
+                    <tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" allowsSelectionDuringEditing="YES" rowHeight="64" estimatedRowHeight="64" sectionHeaderHeight="1" estimatedSectionHeaderHeight="1" sectionFooterHeight="28" id="Q9X-Gw-cs6">
104
+                        <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
105
+                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
106
+                        <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
107
+                        <prototypes>
108
+                            <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" showsReorderControl="YES" indentationWidth="10" reuseIdentifier="TokenCell" editingAccessoryType="disclosureIndicator" rowHeight="64" id="tde-TY-5Cy" customClass="TokenTableViewCell" customModule="Authenticator" customModuleProvider="target">
109
+                                <rect key="frame" x="0.0" y="1" width="375" height="64"/>
110
+                                <autoresizingMask key="autoresizingMask"/>
111
+                                <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="tde-TY-5Cy" id="QT6-6Z-JrG">
112
+                                    <rect key="frame" x="0.0" y="0.0" width="375" height="63.5"/>
113
+                                    <autoresizingMask key="autoresizingMask"/>
114
+                                    <subviews>
115
+                                        <view clearsContextBeforeDrawing="NO" userInteractionEnabled="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="tk3-PM-uqg">
116
+                                            <rect key="frame" x="0.0" y="0.0" width="8" height="64.5"/>
117
+                                            <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
118
+                                            <constraints>
119
+                                                <constraint firstAttribute="width" constant="8" id="XNL-6N-7w7"/>
120
+                                            </constraints>
121
+                                        </view>
122
+                                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="iHi-ds-EuZ">
123
+                                            <rect key="frame" x="16" y="11" width="172" height="23"/>
124
+                                            <fontDescription key="fontDescription" type="system" pointSize="19"/>
125
+                                            <nil key="textColor"/>
126
+                                            <nil key="highlightedColor"/>
127
+                                        </label>
128
+                                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" verticalCompressionResistancePriority="250" placeholderIntrinsicWidth="46.5" placeholderIntrinsicHeight="18" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="qRp-vM-STf" customClass="LTMorphingLabel" customModule="LTMorphingLabel">
129
+                                            <rect key="frame" x="16" y="35" width="172" height="18"/>
130
+                                            <fontDescription key="fontDescription" type="system" pointSize="15"/>
131
+                                            <nil key="textColor"/>
132
+                                            <nil key="highlightedColor"/>
133
+                                        </label>
134
+                                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="1000" verticalHuggingPriority="1000" horizontalCompressionResistancePriority="1000" verticalCompressionResistancePriority="1000" text="1234-5678" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" adjustsLetterSpacingToFitWidth="YES" translatesAutoresizingMaskIntoConstraints="NO" id="290-kf-446" customClass="LTMorphingLabel" customModule="LTMorphingLabel">
135
+                                            <rect key="frame" x="196" y="13" width="163" height="38"/>
136
+                                            <fontDescription key="fontDescription" name="Menlo-Regular" family="Menlo" pointSize="30"/>
137
+                                            <nil key="textColor"/>
138
+                                            <nil key="highlightedColor"/>
139
+                                        </label>