Self-maintained passcode lock
- No cancel button anywhere in the passcode lock yet - Poor UI
This commit is contained in:
parent
30ae08bed5
commit
da3c4f0bc0
10 changed files with 298 additions and 210 deletions
2
Cartfile
2
Cartfile
|
|
@ -1,8 +1,6 @@
|
||||||
github "SVProgressHUD/SVProgressHUD"
|
github "SVProgressHUD/SVProgressHUD"
|
||||||
github "radex/SwiftyUserDefaults"
|
github "radex/SwiftyUserDefaults"
|
||||||
github "libgit2/objective-git"
|
github "libgit2/objective-git"
|
||||||
# github "zahlz/SwiftPasscodeLock" "master"
|
|
||||||
github "yishilin14/SwiftPasscodeLock" "app-extension-support"
|
|
||||||
github "bitserf/FavIcon"
|
github "bitserf/FavIcon"
|
||||||
github "kishikawakatsumi/KeychainAccess"
|
github "kishikawakatsumi/KeychainAccess"
|
||||||
github "mattrubin/OneTimePassword"
|
github "mattrubin/OneTimePassword"
|
||||||
|
|
|
||||||
|
|
@ -29,8 +29,6 @@
|
||||||
A26700371EEC475600176B8A /* passProcessor.js in Resources */ = {isa = PBXBuildFile; fileRef = A26700351EEC475600176B8A /* passProcessor.js */; };
|
A26700371EEC475600176B8A /* passProcessor.js in Resources */ = {isa = PBXBuildFile; fileRef = A26700351EEC475600176B8A /* passProcessor.js */; };
|
||||||
A2802BF91E70813A00879216 /* SliderTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2802BF71E70813A00879216 /* SliderTableViewCell.swift */; };
|
A2802BF91E70813A00879216 /* SliderTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2802BF71E70813A00879216 /* SliderTableViewCell.swift */; };
|
||||||
A2802BFA1E70813A00879216 /* SliderTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = A2802BF81E70813A00879216 /* SliderTableViewCell.xib */; };
|
A2802BFA1E70813A00879216 /* SliderTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = A2802BF81E70813A00879216 /* SliderTableViewCell.xib */; };
|
||||||
A28C66651EF109D600A398A1 /* PasscodeLockConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = A28C66631EF109D600A398A1 /* PasscodeLockConfiguration.swift */; };
|
|
||||||
A28C66661EF109D600A398A1 /* PasscodeLockRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = A28C66641EF109D600A398A1 /* PasscodeLockRepository.swift */; };
|
|
||||||
A28C66681EF10EC900A398A1 /* PasscodeExtensionDisplay.swift in Sources */ = {isa = PBXBuildFile; fileRef = A28C66671EF10EC900A398A1 /* PasscodeExtensionDisplay.swift */; };
|
A28C66681EF10EC900A398A1 /* PasscodeExtensionDisplay.swift in Sources */ = {isa = PBXBuildFile; fileRef = A28C66671EF10EC900A398A1 /* PasscodeExtensionDisplay.swift */; };
|
||||||
A2A61C131EEF90CB00CFE063 /* Base32.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A262A58C1E68749C006B0890 /* Base32.framework */; };
|
A2A61C131EEF90CB00CFE063 /* Base32.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A262A58C1E68749C006B0890 /* Base32.framework */; };
|
||||||
A2A61C151EEF90CB00CFE063 /* KeychainAccess.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCA742D91E599ED400D54E16 /* KeychainAccess.framework */; };
|
A2A61C151EEF90CB00CFE063 /* KeychainAccess.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCA742D91E599ED400D54E16 /* KeychainAccess.framework */; };
|
||||||
|
|
@ -39,6 +37,9 @@
|
||||||
A2A61C201EEFABAD00CFE063 /* UtilsExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2A61C1F1EEFABAD00CFE063 /* UtilsExtension.swift */; };
|
A2A61C201EEFABAD00CFE063 /* UtilsExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2A61C1F1EEFABAD00CFE063 /* UtilsExtension.swift */; };
|
||||||
A2A61C2C1EEFDF3300CFE063 /* ExtensionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2A61C2B1EEFDF3300CFE063 /* ExtensionViewController.swift */; };
|
A2A61C2C1EEFDF3300CFE063 /* ExtensionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2A61C2B1EEFDF3300CFE063 /* ExtensionViewController.swift */; };
|
||||||
A2A7813F1E97DBD9001311F5 /* QRScannerController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2A7813E1E97DBD9001311F5 /* QRScannerController.swift */; };
|
A2A7813F1E97DBD9001311F5 /* QRScannerController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2A7813E1E97DBD9001311F5 /* QRScannerController.swift */; };
|
||||||
|
A2C532BB201E5A9600DB9F53 /* PasscodeLock.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2C532BA201E5A9600DB9F53 /* PasscodeLock.swift */; };
|
||||||
|
A2C532BE201E5AA100DB9F53 /* PasscodeLockViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2C532BC201E5AA000DB9F53 /* PasscodeLockViewController.swift */; };
|
||||||
|
A2C532BF201E5AA100DB9F53 /* PasscodeLockPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2C532BD201E5AA100DB9F53 /* PasscodeLockPresenter.swift */; };
|
||||||
A2F4E2141EED800F0011986E /* GitCredential.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2F4E2101EED800F0011986E /* GitCredential.swift */; };
|
A2F4E2141EED800F0011986E /* GitCredential.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2F4E2101EED800F0011986E /* GitCredential.swift */; };
|
||||||
A2F4E2151EED800F0011986E /* Password.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2F4E2111EED800F0011986E /* Password.swift */; };
|
A2F4E2151EED800F0011986E /* Password.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2F4E2111EED800F0011986E /* Password.swift */; };
|
||||||
A2F4E2161EED800F0011986E /* PasswordEntity.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2F4E2121EED800F0011986E /* PasswordEntity.swift */; };
|
A2F4E2161EED800F0011986E /* PasswordEntity.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2F4E2121EED800F0011986E /* PasswordEntity.swift */; };
|
||||||
|
|
@ -61,7 +62,6 @@
|
||||||
DC037CC01E4ED4E100609409 /* TextViewTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = DC037CBE1E4ED4E100609409 /* TextViewTableViewCell.xib */; };
|
DC037CC01E4ED4E100609409 /* TextViewTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = DC037CBE1E4ED4E100609409 /* TextViewTableViewCell.xib */; };
|
||||||
DC13B1511E8640810097803F /* passTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC13B1501E8640810097803F /* passTests.swift */; };
|
DC13B1511E8640810097803F /* passTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC13B1501E8640810097803F /* passTests.swift */; };
|
||||||
DC193FFA1E49B4430077E0A3 /* AdvancedSettingsTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC193FF91E49B4430077E0A3 /* AdvancedSettingsTableViewController.swift */; };
|
DC193FFA1E49B4430077E0A3 /* AdvancedSettingsTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC193FF91E49B4430077E0A3 /* AdvancedSettingsTableViewController.swift */; };
|
||||||
DC193FFC1E49E0340077E0A3 /* PasscodeLock.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC193FFB1E49E0340077E0A3 /* PasscodeLock.framework */; };
|
|
||||||
DC3E64E61E656F11009A83DE /* CommitLogsTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC3E64E51E656F11009A83DE /* CommitLogsTableViewController.swift */; };
|
DC3E64E61E656F11009A83DE /* CommitLogsTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC3E64E51E656F11009A83DE /* CommitLogsTableViewController.swift */; };
|
||||||
DC4914961E434301007FF592 /* LabelTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC4914941E434301007FF592 /* LabelTableViewCell.swift */; };
|
DC4914961E434301007FF592 /* LabelTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC4914941E434301007FF592 /* LabelTableViewCell.swift */; };
|
||||||
DC4914991E434600007FF592 /* PasswordDetailTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC4914981E434600007FF592 /* PasswordDetailTableViewController.swift */; };
|
DC4914991E434600007FF592 /* PasswordDetailTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC4914981E434600007FF592 /* PasswordDetailTableViewController.swift */; };
|
||||||
|
|
@ -191,8 +191,6 @@
|
||||||
A26700351EEC475600176B8A /* passProcessor.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = passProcessor.js; sourceTree = "<group>"; };
|
A26700351EEC475600176B8A /* passProcessor.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = passProcessor.js; sourceTree = "<group>"; };
|
||||||
A2802BF71E70813A00879216 /* SliderTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SliderTableViewCell.swift; sourceTree = "<group>"; };
|
A2802BF71E70813A00879216 /* SliderTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SliderTableViewCell.swift; sourceTree = "<group>"; };
|
||||||
A2802BF81E70813A00879216 /* SliderTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = SliderTableViewCell.xib; sourceTree = "<group>"; };
|
A2802BF81E70813A00879216 /* SliderTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = SliderTableViewCell.xib; sourceTree = "<group>"; };
|
||||||
A28C66631EF109D600A398A1 /* PasscodeLockConfiguration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = PasscodeLockConfiguration.swift; path = Models/PasscodeLockConfiguration.swift; sourceTree = "<group>"; };
|
|
||||||
A28C66641EF109D600A398A1 /* PasscodeLockRepository.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = PasscodeLockRepository.swift; path = Models/PasscodeLockRepository.swift; sourceTree = "<group>"; };
|
|
||||||
A28C66671EF10EC900A398A1 /* PasscodeExtensionDisplay.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PasscodeExtensionDisplay.swift; sourceTree = "<group>"; };
|
A28C66671EF10EC900A398A1 /* PasscodeExtensionDisplay.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PasscodeExtensionDisplay.swift; sourceTree = "<group>"; };
|
||||||
A2A61C0C1EEF8DFE00CFE063 /* libPods-passExtension.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libPods-passExtension.a"; path = "../../Library/Developer/Xcode/DerivedData/pass-fwlmfsjroyvbfhdyqmglrwfhvjli/Build/Products/Debug-iphonesimulator/libPods-passExtension.a"; sourceTree = "<group>"; };
|
A2A61C0C1EEF8DFE00CFE063 /* libPods-passExtension.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libPods-passExtension.a"; path = "../../Library/Developer/Xcode/DerivedData/pass-fwlmfsjroyvbfhdyqmglrwfhvjli/Build/Products/Debug-iphonesimulator/libPods-passExtension.a"; sourceTree = "<group>"; };
|
||||||
A2A61C101EEF8E3500CFE063 /* libPods-passKit.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libPods-passKit.a"; path = "Pods/../build/Debug-iphoneos/libPods-passKit.a"; sourceTree = "<group>"; };
|
A2A61C101EEF8E3500CFE063 /* libPods-passKit.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libPods-passKit.a"; path = "Pods/../build/Debug-iphoneos/libPods-passKit.a"; sourceTree = "<group>"; };
|
||||||
|
|
@ -200,6 +198,9 @@
|
||||||
A2A61C2B1EEFDF3300CFE063 /* ExtensionViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExtensionViewController.swift; sourceTree = "<group>"; };
|
A2A61C2B1EEFDF3300CFE063 /* ExtensionViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExtensionViewController.swift; sourceTree = "<group>"; };
|
||||||
A2A7813E1E97DBD9001311F5 /* QRScannerController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QRScannerController.swift; sourceTree = "<group>"; };
|
A2A7813E1E97DBD9001311F5 /* QRScannerController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QRScannerController.swift; sourceTree = "<group>"; };
|
||||||
A2BC54C71EEE5669001FAFBD /* Objective-CBridgingHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Objective-CBridgingHeader.h"; sourceTree = "<group>"; };
|
A2BC54C71EEE5669001FAFBD /* Objective-CBridgingHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Objective-CBridgingHeader.h"; sourceTree = "<group>"; };
|
||||||
|
A2C532BA201E5A9600DB9F53 /* PasscodeLock.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = PasscodeLock.swift; path = Models/PasscodeLock.swift; sourceTree = "<group>"; };
|
||||||
|
A2C532BC201E5AA000DB9F53 /* PasscodeLockViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = PasscodeLockViewController.swift; path = Controllers/PasscodeLockViewController.swift; sourceTree = "<group>"; };
|
||||||
|
A2C532BD201E5AA100DB9F53 /* PasscodeLockPresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = PasscodeLockPresenter.swift; path = Controllers/PasscodeLockPresenter.swift; sourceTree = "<group>"; };
|
||||||
A2F4E2101EED800F0011986E /* GitCredential.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = GitCredential.swift; path = Models/GitCredential.swift; sourceTree = "<group>"; };
|
A2F4E2101EED800F0011986E /* GitCredential.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = GitCredential.swift; path = Models/GitCredential.swift; sourceTree = "<group>"; };
|
||||||
A2F4E2111EED800F0011986E /* Password.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Password.swift; path = Models/Password.swift; sourceTree = "<group>"; };
|
A2F4E2111EED800F0011986E /* Password.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Password.swift; path = Models/Password.swift; sourceTree = "<group>"; };
|
||||||
A2F4E2121EED800F0011986E /* PasswordEntity.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = PasswordEntity.swift; path = Models/PasswordEntity.swift; sourceTree = "<group>"; };
|
A2F4E2121EED800F0011986E /* PasswordEntity.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = PasswordEntity.swift; path = Models/PasswordEntity.swift; sourceTree = "<group>"; };
|
||||||
|
|
@ -315,7 +316,6 @@
|
||||||
files = (
|
files = (
|
||||||
A260758D1EEC6F34005DB03E /* passKit.framework in Frameworks */,
|
A260758D1EEC6F34005DB03E /* passKit.framework in Frameworks */,
|
||||||
DCC408C71E307DBB00F29B0E /* SVProgressHUD.framework in Frameworks */,
|
DCC408C71E307DBB00F29B0E /* SVProgressHUD.framework in Frameworks */,
|
||||||
DC193FFC1E49E0340077E0A3 /* PasscodeLock.framework in Frameworks */,
|
|
||||||
18F19A67B0C07F13C17169E0 /* Pods_pass.framework in Frameworks */,
|
18F19A67B0C07F13C17169E0 /* Pods_pass.framework in Frameworks */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
|
@ -344,11 +344,12 @@
|
||||||
A26075791EEC6F34005DB03E /* passKit */ = {
|
A26075791EEC6F34005DB03E /* passKit */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
A2C532B9201DD07500DB9F53 /* Controllers */,
|
||||||
|
A2F4E20F1EED7F0A0011986E /* Helpers */,
|
||||||
|
A260757B1EEC6F34005DB03E /* Info.plist */,
|
||||||
A2F4E20E1EED7F040011986E /* Models */,
|
A2F4E20E1EED7F040011986E /* Models */,
|
||||||
A26075A51EEC7125005DB03E /* pass.xcdatamodeld */,
|
A26075A51EEC7125005DB03E /* pass.xcdatamodeld */,
|
||||||
A2F4E20F1EED7F0A0011986E /* Helpers */,
|
|
||||||
A260757A1EEC6F34005DB03E /* passKit.h */,
|
A260757A1EEC6F34005DB03E /* passKit.h */,
|
||||||
A260757B1EEC6F34005DB03E /* Info.plist */,
|
|
||||||
);
|
);
|
||||||
path = passKit;
|
path = passKit;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
|
@ -376,11 +377,19 @@
|
||||||
path = passExtension;
|
path = passExtension;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
A2C532B9201DD07500DB9F53 /* Controllers */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
A2C532BD201E5AA100DB9F53 /* PasscodeLockPresenter.swift */,
|
||||||
|
A2C532BC201E5AA000DB9F53 /* PasscodeLockViewController.swift */,
|
||||||
|
);
|
||||||
|
name = Controllers;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
A2F4E20E1EED7F040011986E /* Models */ = {
|
A2F4E20E1EED7F040011986E /* Models */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
A28C66631EF109D600A398A1 /* PasscodeLockConfiguration.swift */,
|
A2C532BA201E5A9600DB9F53 /* PasscodeLock.swift */,
|
||||||
A28C66641EF109D600A398A1 /* PasscodeLockRepository.swift */,
|
|
||||||
A2F4E2101EED800F0011986E /* GitCredential.swift */,
|
A2F4E2101EED800F0011986E /* GitCredential.swift */,
|
||||||
A2F4E2111EED800F0011986E /* Password.swift */,
|
A2F4E2111EED800F0011986E /* Password.swift */,
|
||||||
A2F4E2121EED800F0011986E /* PasswordEntity.swift */,
|
A2F4E2121EED800F0011986E /* PasswordEntity.swift */,
|
||||||
|
|
@ -429,30 +438,30 @@
|
||||||
DC19400C1E4B39400077E0A3 /* Controllers */ = {
|
DC19400C1E4B39400077E0A3 /* Controllers */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
DCD3C65D1EFB9BB400CBE842 /* SettingsSplitViewController.swift */,
|
|
||||||
DC3E64E51E656F11009A83DE /* CommitLogsTableViewController.swift */,
|
|
||||||
DC5F385A1E56AADB00C69ACA /* PGPKeyArmorSettingTableViewController.swift */,
|
|
||||||
DC037CB11E4CAB1700609409 /* AboutRepositoryTableViewController.swift */,
|
DC037CB11E4CAB1700609409 /* AboutRepositoryTableViewController.swift */,
|
||||||
DC962CDE1E4B62C10033B5D8 /* AboutTableViewController.swift */,
|
DC962CDE1E4B62C10033B5D8 /* AboutTableViewController.swift */,
|
||||||
DC037CB71E4DD1A500609409 /* AddPasswordTableViewController.swift */,
|
DC037CB71E4DD1A500609409 /* AddPasswordTableViewController.swift */,
|
||||||
DC193FF91E49B4430077E0A3 /* AdvancedSettingsTableViewController.swift */,
|
DC193FF91E49B4430077E0A3 /* AdvancedSettingsTableViewController.swift */,
|
||||||
DC037CA71E4B898100609409 /* BasicStaticTableViewController.swift */,
|
DC037CA71E4B898100609409 /* BasicStaticTableViewController.swift */,
|
||||||
|
DC3E64E51E656F11009A83DE /* CommitLogsTableViewController.swift */,
|
||||||
DCFB77A61E502DF9008DE471 /* EditPasswordTableViewController.swift */,
|
DCFB77A61E502DF9008DE471 /* EditPasswordTableViewController.swift */,
|
||||||
DC037CAF1E4CA51F00609409 /* GeneralSettingsTableViewController.swift */,
|
DC037CAF1E4CA51F00609409 /* GeneralSettingsTableViewController.swift */,
|
||||||
|
A217ACE31E9BBBBD00A1A6CF /* GitConfigSettingTableViewController.swift */,
|
||||||
DCA049991E335CC800522E8F /* GitServerSettingTableViewController.swift */,
|
DCA049991E335CC800522E8F /* GitServerSettingTableViewController.swift */,
|
||||||
|
DCC441531E916382008A90C4 /* GitSSHKeyArmorSettingTableViewController.swift */,
|
||||||
DC037CA51E4B883900609409 /* OpenSourceComponentsTableViewController.swift */,
|
DC037CA51E4B883900609409 /* OpenSourceComponentsTableViewController.swift */,
|
||||||
|
A217ACE11E9AB17C00A1A6CF /* OTPScannerController.swift */,
|
||||||
DC4914981E434600007FF592 /* PasswordDetailTableViewController.swift */,
|
DC4914981E434600007FF592 /* PasswordDetailTableViewController.swift */,
|
||||||
DCC441511E8F6C06008A90C4 /* RawPasswordViewController.swift */,
|
|
||||||
DCFB77A81E502FF6008DE471 /* PasswordEditorTableViewController.swift */,
|
DCFB77A81E502FF6008DE471 /* PasswordEditorTableViewController.swift */,
|
||||||
DC5734AD1E439AD400D09270 /* PasswordsViewController.swift */,
|
DC5734AD1E439AD400D09270 /* PasswordsViewController.swift */,
|
||||||
|
DC5F385A1E56AADB00C69ACA /* PGPKeyArmorSettingTableViewController.swift */,
|
||||||
DCA0499B1E3362F400522E8F /* PGPKeySettingTableViewController.swift */,
|
DCA0499B1E3362F400522E8F /* PGPKeySettingTableViewController.swift */,
|
||||||
|
A2A7813E1E97DBD9001311F5 /* QRScannerController.swift */,
|
||||||
|
DCC441511E8F6C06008A90C4 /* RawPasswordViewController.swift */,
|
||||||
|
DCD3C65D1EFB9BB400CBE842 /* SettingsSplitViewController.swift */,
|
||||||
DCAAF7441E2FA66800AB94BC /* SettingsTableViewController.swift */,
|
DCAAF7441E2FA66800AB94BC /* SettingsTableViewController.swift */,
|
||||||
DC037CA91E4B8EAE00609409 /* SpecialThanksTableViewController.swift */,
|
DC037CA91E4B8EAE00609409 /* SpecialThanksTableViewController.swift */,
|
||||||
DC8963BF1E38EEB900828B09 /* SSHKeySettingTableViewController.swift */,
|
DC8963BF1E38EEB900828B09 /* SSHKeySettingTableViewController.swift */,
|
||||||
DCC441531E916382008A90C4 /* GitSSHKeyArmorSettingTableViewController.swift */,
|
|
||||||
A2A7813E1E97DBD9001311F5 /* QRScannerController.swift */,
|
|
||||||
A217ACE11E9AB17C00A1A6CF /* OTPScannerController.swift */,
|
|
||||||
A217ACE31E9BBBBD00A1A6CF /* GitConfigSettingTableViewController.swift */,
|
|
||||||
);
|
);
|
||||||
path = Controllers;
|
path = Controllers;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
|
@ -477,21 +486,21 @@
|
||||||
DC19400F1E4B3A9E0077E0A3 /* Views */ = {
|
DC19400F1E4B3A9E0077E0A3 /* Views */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
A2802BF71E70813A00879216 /* SliderTableViewCell.swift */,
|
DCFB77AA1E503729008DE471 /* ContentTableViewCell.swift */,
|
||||||
A2802BF81E70813A00879216 /* SliderTableViewCell.xib */,
|
|
||||||
DCFB779C1E4F40C7008DE471 /* FillPasswordTableViewCell.swift */,
|
DCFB779C1E4F40C7008DE471 /* FillPasswordTableViewCell.swift */,
|
||||||
DCFB779D1E4F40C7008DE471 /* FillPasswordTableViewCell.xib */,
|
DCFB779D1E4F40C7008DE471 /* FillPasswordTableViewCell.xib */,
|
||||||
DCFB77981E4F3BCF008DE471 /* TitleTextFieldTableViewCell.swift */,
|
|
||||||
DCFB77991E4F3BCF008DE471 /* TitleTextFieldTableViewCell.xib */,
|
|
||||||
DC4914941E434301007FF592 /* LabelTableViewCell.swift */,
|
DC4914941E434301007FF592 /* LabelTableViewCell.swift */,
|
||||||
DCDDEAAF1E4639F300F68193 /* LabelTableViewCell.xib */,
|
DCDDEAAF1E4639F300F68193 /* LabelTableViewCell.xib */,
|
||||||
DC037CB91E4DD47B00609409 /* TextFieldTableViewCell.swift */,
|
|
||||||
DC037CBA1E4DD47B00609409 /* TextFieldTableViewCell.xib */,
|
|
||||||
DCDDEAB11E4896BF00F68193 /* PasswordDetailTitleTableViewCell.swift */,
|
DCDDEAB11E4896BF00F68193 /* PasswordDetailTitleTableViewCell.swift */,
|
||||||
DCFB77A21E500D9C008DE471 /* PasswordDetailTitleTableViewCell.xib */,
|
DCFB77A21E500D9C008DE471 /* PasswordDetailTitleTableViewCell.xib */,
|
||||||
|
A2802BF71E70813A00879216 /* SliderTableViewCell.swift */,
|
||||||
|
A2802BF81E70813A00879216 /* SliderTableViewCell.xib */,
|
||||||
|
DC037CB91E4DD47B00609409 /* TextFieldTableViewCell.swift */,
|
||||||
|
DC037CBA1E4DD47B00609409 /* TextFieldTableViewCell.xib */,
|
||||||
DC037CBD1E4ED4E100609409 /* TextViewTableViewCell.swift */,
|
DC037CBD1E4ED4E100609409 /* TextViewTableViewCell.swift */,
|
||||||
DC037CBE1E4ED4E100609409 /* TextViewTableViewCell.xib */,
|
DC037CBE1E4ED4E100609409 /* TextViewTableViewCell.xib */,
|
||||||
DCFB77AA1E503729008DE471 /* ContentTableViewCell.swift */,
|
DCFB77981E4F3BCF008DE471 /* TitleTextFieldTableViewCell.swift */,
|
||||||
|
DCFB77991E4F3BCF008DE471 /* TitleTextFieldTableViewCell.xib */,
|
||||||
);
|
);
|
||||||
path = Views;
|
path = Views;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
|
@ -984,7 +993,6 @@
|
||||||
"$(SRCROOT)/Carthage/Build/iOS/SVProgressHUD.framework",
|
"$(SRCROOT)/Carthage/Build/iOS/SVProgressHUD.framework",
|
||||||
"$(SRCROOT)/Carthage/Build/iOS/SwiftyUserDefaults.framework",
|
"$(SRCROOT)/Carthage/Build/iOS/SwiftyUserDefaults.framework",
|
||||||
"$(SRCROOT)/Carthage/Build/iOS/ObjectiveGit.framework",
|
"$(SRCROOT)/Carthage/Build/iOS/ObjectiveGit.framework",
|
||||||
"$(SRCROOT)/Carthage/Build/iOS/PasscodeLock.framework",
|
|
||||||
"$(SRCROOT)/Carthage/Build/iOS/FavIcon.framework",
|
"$(SRCROOT)/Carthage/Build/iOS/FavIcon.framework",
|
||||||
"$(SRCROOT)/Carthage/Build/iOS/KeychainAccess.framework",
|
"$(SRCROOT)/Carthage/Build/iOS/KeychainAccess.framework",
|
||||||
"$(SRCROOT)/Carthage/Build/iOS/OneTimePassword.framework",
|
"$(SRCROOT)/Carthage/Build/iOS/OneTimePassword.framework",
|
||||||
|
|
@ -1019,14 +1027,15 @@
|
||||||
isa = PBXSourcesBuildPhase;
|
isa = PBXSourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
A28C66661EF109D600A398A1 /* PasscodeLockRepository.swift in Sources */,
|
A2C532BB201E5A9600DB9F53 /* PasscodeLock.swift in Sources */,
|
||||||
A2F4E2151EED800F0011986E /* Password.swift in Sources */,
|
A2F4E2151EED800F0011986E /* Password.swift in Sources */,
|
||||||
A28C66651EF109D600A398A1 /* PasscodeLockConfiguration.swift in Sources */,
|
|
||||||
A26075AD1EEC7125005DB03E /* pass.xcdatamodeld in Sources */,
|
A26075AD1EEC7125005DB03E /* pass.xcdatamodeld in Sources */,
|
||||||
A2F4E21E1EED80160011986E /* AppError.swift in Sources */,
|
A2F4E21E1EED80160011986E /* AppError.swift in Sources */,
|
||||||
A2F4E2171EED800F0011986E /* PasswordStore.swift in Sources */,
|
A2F4E2171EED800F0011986E /* PasswordStore.swift in Sources */,
|
||||||
A2F4E2211EED80160011986E /* NotificationNames.swift in Sources */,
|
A2F4E2211EED80160011986E /* NotificationNames.swift in Sources */,
|
||||||
A2F4E2221EED80160011986E /* UITextFieldExtension.swift in Sources */,
|
A2F4E2221EED80160011986E /* UITextFieldExtension.swift in Sources */,
|
||||||
|
A2C532BF201E5AA100DB9F53 /* PasscodeLockPresenter.swift in Sources */,
|
||||||
|
A2C532BE201E5AA100DB9F53 /* PasscodeLockViewController.swift in Sources */,
|
||||||
A2F4E2201EED80160011986E /* Globals.swift in Sources */,
|
A2F4E2201EED80160011986E /* Globals.swift in Sources */,
|
||||||
A2F4E2231EED80160011986E /* Utils.swift in Sources */,
|
A2F4E2231EED80160011986E /* Utils.swift in Sources */,
|
||||||
A2F4E21F1EED80160011986E /* DefaultsKeys.swift in Sources */,
|
A2F4E21F1EED80160011986E /* DefaultsKeys.swift in Sources */,
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@
|
||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
import CoreData
|
import CoreData
|
||||||
import PasscodeLock
|
|
||||||
import SVProgressHUD
|
import SVProgressHUD
|
||||||
import passKit
|
import passKit
|
||||||
|
|
||||||
|
|
@ -21,7 +20,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||||
}
|
}
|
||||||
|
|
||||||
lazy var passcodeLockPresenter: PasscodeLockPresenter = {
|
lazy var passcodeLockPresenter: PasscodeLockPresenter = {
|
||||||
let presenter = PasscodeLockPresenter(mainWindow: self.window, configuration: PasscodeLockConfiguration.shared)
|
let presenter = PasscodeLockPresenter(mainWindow: self.window)
|
||||||
return presenter
|
return presenter
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
|
@ -92,7 +91,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||||
|
|
||||||
func applicationWillEnterForeground(_ application: UIApplication) {
|
func applicationWillEnterForeground(_ application: UIApplication) {
|
||||||
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
|
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
|
||||||
passcodeLockPresenter = PasscodeLockPresenter(mainWindow: self.window, configuration: PasscodeLockConfiguration.shared)
|
|
||||||
passcodeLockPresenter.present(windowLevel: UIApplication.shared.windows.last?.windowLevel)
|
passcodeLockPresenter.present(windowLevel: UIApplication.shared.windows.last?.windowLevel)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -195,29 +195,12 @@
|
||||||
</subviews>
|
</subviews>
|
||||||
</tableViewCellContentView>
|
</tableViewCellContentView>
|
||||||
</tableViewCell>
|
</tableViewCell>
|
||||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" reuseIdentifier="touchIDTableViewCell" textLabel="H2E-hP-Gyf" style="IBUITableViewCellStyleDefault" id="wB7-Km-Oel">
|
|
||||||
<rect key="frame" x="0.0" y="267" width="414" height="44"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="wB7-Km-Oel" id="m90-X7-DbI">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="414" height="43.666666666666664"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<subviews>
|
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Touch ID" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" id="H2E-hP-Gyf">
|
|
||||||
<rect key="frame" x="20" y="0.0" width="374" height="43.666666666666664"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
|
||||||
<nil key="textColor"/>
|
|
||||||
<nil key="highlightedColor"/>
|
|
||||||
</label>
|
|
||||||
</subviews>
|
|
||||||
</tableViewCellContentView>
|
|
||||||
</tableViewCell>
|
|
||||||
</cells>
|
</cells>
|
||||||
</tableViewSection>
|
</tableViewSection>
|
||||||
<tableViewSection id="6U8-ue-MhL">
|
<tableViewSection id="6U8-ue-MhL">
|
||||||
<cells>
|
<cells>
|
||||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="advancedTableViewCell" textLabel="MKj-d0-8q3" style="IBUITableViewCellStyleDefault" id="tQN-gu-iRe">
|
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="advancedTableViewCell" textLabel="MKj-d0-8q3" style="IBUITableViewCellStyleDefault" id="tQN-gu-iRe">
|
||||||
<rect key="frame" x="0.0" y="347" width="414" height="44"/>
|
<rect key="frame" x="0.0" y="303" width="414" height="44"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="tQN-gu-iRe" id="Xs0-LN-r43">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="tQN-gu-iRe" id="Xs0-LN-r43">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="376" height="43.666666666666664"/>
|
<rect key="frame" x="0.0" y="0.0" width="376" height="43.666666666666664"/>
|
||||||
|
|
@ -241,7 +224,7 @@
|
||||||
<tableViewSection id="T7L-rR-R9W">
|
<tableViewSection id="T7L-rR-R9W">
|
||||||
<cells>
|
<cells>
|
||||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="aboutTableViewCell" textLabel="oqz-Hr-RAl" style="IBUITableViewCellStyleDefault" id="osS-xk-WRP">
|
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="aboutTableViewCell" textLabel="oqz-Hr-RAl" style="IBUITableViewCellStyleDefault" id="osS-xk-WRP">
|
||||||
<rect key="frame" x="0.0" y="427" width="414" height="44"/>
|
<rect key="frame" x="0.0" y="383" width="414" height="44"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="osS-xk-WRP" id="G6j-ij-rNr">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="osS-xk-WRP" id="G6j-ij-rNr">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="376" height="43.666666666666664"/>
|
<rect key="frame" x="0.0" y="0.0" width="376" height="43.666666666666664"/>
|
||||||
|
|
@ -273,7 +256,6 @@
|
||||||
<outlet property="passcodeTableViewCell" destination="6Y0-mj-qhA" id="vkI-h5-GRo"/>
|
<outlet property="passcodeTableViewCell" destination="6Y0-mj-qhA" id="vkI-h5-GRo"/>
|
||||||
<outlet property="passwordRepositoryTableViewCell" destination="2rc-ZW-XKd" id="aFq-K7-eIj"/>
|
<outlet property="passwordRepositoryTableViewCell" destination="2rc-ZW-XKd" id="aFq-K7-eIj"/>
|
||||||
<outlet property="pgpKeyTableViewCell" destination="1ze-MS-Xbj" id="hXe-eD-0R4"/>
|
<outlet property="pgpKeyTableViewCell" destination="1ze-MS-Xbj" id="hXe-eD-0R4"/>
|
||||||
<outlet property="touchIDTableViewCell" destination="wB7-Km-Oel" id="0fi-Sb-qMa"/>
|
|
||||||
<segue destination="ZUt-x1-TJu" kind="showDetail" identifier="setPGPKeyByURLSegue" id="qRF-S1-bqF"/>
|
<segue destination="ZUt-x1-TJu" kind="showDetail" identifier="setPGPKeyByURLSegue" id="qRF-S1-bqF"/>
|
||||||
<segue destination="ffY-rC-jhq" kind="showDetail" identifier="setPGPKeyByASCIISegue" id="mgi-Oe-i2X"/>
|
<segue destination="ffY-rC-jhq" kind="showDetail" identifier="setPGPKeyByASCIISegue" id="mgi-Oe-i2X"/>
|
||||||
</connections>
|
</connections>
|
||||||
|
|
|
||||||
|
|
@ -9,25 +9,16 @@
|
||||||
import UIKit
|
import UIKit
|
||||||
import SVProgressHUD
|
import SVProgressHUD
|
||||||
import CoreData
|
import CoreData
|
||||||
import PasscodeLock
|
|
||||||
import LocalAuthentication
|
|
||||||
import passKit
|
import passKit
|
||||||
|
|
||||||
class SettingsTableViewController: UITableViewController, UITabBarControllerDelegate {
|
class SettingsTableViewController: UITableViewController, UITabBarControllerDelegate {
|
||||||
|
|
||||||
lazy var touchIDSwitch: UISwitch = {
|
|
||||||
let uiSwitch = UISwitch(frame: CGRect.zero)
|
|
||||||
uiSwitch.onTintColor = Globals.blue
|
|
||||||
uiSwitch.addTarget(self, action: #selector(touchIDSwitchAction), for: UIControlEvents.valueChanged)
|
|
||||||
return uiSwitch
|
|
||||||
}()
|
|
||||||
|
|
||||||
@IBOutlet weak var pgpKeyTableViewCell: UITableViewCell!
|
@IBOutlet weak var pgpKeyTableViewCell: UITableViewCell!
|
||||||
@IBOutlet weak var touchIDTableViewCell: UITableViewCell!
|
|
||||||
@IBOutlet weak var passcodeTableViewCell: UITableViewCell!
|
@IBOutlet weak var passcodeTableViewCell: UITableViewCell!
|
||||||
@IBOutlet weak var passwordRepositoryTableViewCell: UITableViewCell!
|
@IBOutlet weak var passwordRepositoryTableViewCell: UITableViewCell!
|
||||||
|
var setPasscodeLockAlert: UIAlertController?
|
||||||
|
|
||||||
let passwordStore = PasswordStore.shared
|
let passwordStore = PasswordStore.shared
|
||||||
var passcodeLockConfig = PasscodeLockConfiguration.shared
|
var passcodeLock = PasscodeLock.shared
|
||||||
|
|
||||||
func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
|
func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
|
||||||
navigationController?.popViewController(animated: true)
|
navigationController?.popViewController(animated: true)
|
||||||
|
|
@ -123,14 +114,6 @@ class SettingsTableViewController: UITableViewController, UITabBarControllerDele
|
||||||
}
|
}
|
||||||
|
|
||||||
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||||
// Security section, hide TouchID if the device doesn't support
|
|
||||||
if section == 1 {
|
|
||||||
if hasTouchID() {
|
|
||||||
return 2
|
|
||||||
} else {
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return super.tableView(tableView, numberOfRowsInSection: section)
|
return super.tableView(tableView, numberOfRowsInSection: section)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -138,10 +121,9 @@ class SettingsTableViewController: UITableViewController, UITabBarControllerDele
|
||||||
super.viewDidLoad()
|
super.viewDidLoad()
|
||||||
NotificationCenter.default.addObserver(self, selector: #selector(SettingsTableViewController.actOnPasswordStoreErasedNotification), name: .passwordStoreErased, object: nil)
|
NotificationCenter.default.addObserver(self, selector: #selector(SettingsTableViewController.actOnPasswordStoreErasedNotification), name: .passwordStoreErased, object: nil)
|
||||||
self.passwordRepositoryTableViewCell.detailTextLabel?.text = SharedDefaults[.gitURL]?.host
|
self.passwordRepositoryTableViewCell.detailTextLabel?.text = SharedDefaults[.gitURL]?.host
|
||||||
touchIDTableViewCell.accessoryView = touchIDSwitch
|
|
||||||
setPGPKeyTableViewCellDetailText()
|
setPGPKeyTableViewCellDetailText()
|
||||||
setPasswordRepositoryTableViewCellDetailText()
|
setPasswordRepositoryTableViewCellDetailText()
|
||||||
setPasscodeLockTouchIDCells()
|
setPasscodeLockCell()
|
||||||
}
|
}
|
||||||
|
|
||||||
override func viewWillAppear(_ animated: Bool) {
|
override func viewWillAppear(_ animated: Bool) {
|
||||||
|
|
@ -149,38 +131,11 @@ class SettingsTableViewController: UITableViewController, UITabBarControllerDele
|
||||||
tabBarController!.delegate = self
|
tabBarController!.delegate = self
|
||||||
}
|
}
|
||||||
|
|
||||||
private func hasTouchID() -> Bool {
|
private func setPasscodeLockCell() {
|
||||||
let context = LAContext()
|
if passcodeLock.hasPasscode {
|
||||||
var error: NSError?
|
|
||||||
if context.canEvaluatePolicy(LAPolicy.deviceOwnerAuthenticationWithBiometrics, error: &error) {
|
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
switch error!.code {
|
|
||||||
case LAError.Code.touchIDNotEnrolled.rawValue:
|
|
||||||
return true
|
|
||||||
case LAError.Code.passcodeNotSet.rawValue:
|
|
||||||
return true
|
|
||||||
default:
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private func isTouchIDEnabled() -> Bool {
|
|
||||||
let context = LAContext()
|
|
||||||
return context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
private func setPasscodeLockTouchIDCells() {
|
|
||||||
if passcodeLockConfig.repository.hasPasscode {
|
|
||||||
self.passcodeTableViewCell.detailTextLabel?.text = "On"
|
self.passcodeTableViewCell.detailTextLabel?.text = "On"
|
||||||
passcodeLockConfig.isTouchIDAllowed = SharedDefaults[.isTouchIDOn]
|
|
||||||
touchIDSwitch.isOn = SharedDefaults[.isTouchIDOn]
|
|
||||||
} else {
|
} else {
|
||||||
self.passcodeTableViewCell.detailTextLabel?.text = "Off"
|
self.passcodeTableViewCell.detailTextLabel?.text = "Off"
|
||||||
SharedDefaults[.isTouchIDOn] = false
|
|
||||||
passcodeLockConfig.isTouchIDAllowed = SharedDefaults[.isTouchIDOn]
|
|
||||||
touchIDSwitch.isOn = SharedDefaults[.isTouchIDOn]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -203,10 +158,10 @@ class SettingsTableViewController: UITableViewController, UITabBarControllerDele
|
||||||
@objc func actOnPasswordStoreErasedNotification() {
|
@objc func actOnPasswordStoreErasedNotification() {
|
||||||
setPGPKeyTableViewCellDetailText()
|
setPGPKeyTableViewCellDetailText()
|
||||||
setPasswordRepositoryTableViewCellDetailText()
|
setPasswordRepositoryTableViewCellDetailText()
|
||||||
setPasscodeLockTouchIDCells()
|
setPasscodeLockCell()
|
||||||
|
|
||||||
let appDelegate = UIApplication.shared.delegate as! AppDelegate
|
let appDelegate = UIApplication.shared.delegate as! AppDelegate
|
||||||
appDelegate.passcodeLockPresenter = PasscodeLockPresenter(mainWindow: appDelegate.window, configuration: passcodeLockConfig)
|
appDelegate.passcodeLockPresenter = PasscodeLockPresenter(mainWindow: appDelegate.window)
|
||||||
}
|
}
|
||||||
|
|
||||||
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||||
|
|
@ -222,21 +177,6 @@ class SettingsTableViewController: UITableViewController, UITabBarControllerDele
|
||||||
tableView.deselectRow(at: indexPath, animated: true)
|
tableView.deselectRow(at: indexPath, animated: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc func touchIDSwitchAction(uiSwitch: UISwitch) {
|
|
||||||
if !passcodeLockConfig.repository.hasPasscode || !isTouchIDEnabled() {
|
|
||||||
// switch off
|
|
||||||
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(500)) {
|
|
||||||
uiSwitch.isOn = SharedDefaults[.isTouchIDOn] // SharedDefaults[.isTouchIDOn] should be false
|
|
||||||
Utils.alert(title: "Notice", message: "Please enable Touch ID of your phone and setup the passcode lock for Pass.", controller: self, completion: nil)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
SharedDefaults[.isTouchIDOn] = uiSwitch.isOn
|
|
||||||
passcodeLockConfig.isTouchIDAllowed = SharedDefaults[.isTouchIDOn]
|
|
||||||
}
|
|
||||||
let appDelegate = UIApplication.shared.delegate as! AppDelegate
|
|
||||||
appDelegate.passcodeLockPresenter = PasscodeLockPresenter(mainWindow: appDelegate.window, configuration: passcodeLockConfig)
|
|
||||||
}
|
|
||||||
|
|
||||||
func showPGPKeyActionSheet() {
|
func showPGPKeyActionSheet() {
|
||||||
let optionMenu = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
|
let optionMenu = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
|
||||||
var urlActionTitle = "Download from URL"
|
var urlActionTitle = "Download from URL"
|
||||||
|
|
@ -314,21 +254,22 @@ class SettingsTableViewController: UITableViewController, UITabBarControllerDele
|
||||||
}
|
}
|
||||||
|
|
||||||
func showPasscodeActionSheet() {
|
func showPasscodeActionSheet() {
|
||||||
let passcodeChangeViewController = PasscodeLockViewController(state: .change, configuration: passcodeLockConfig)
|
|
||||||
let passcodeRemoveViewController = PasscodeLockViewController(state: .remove, configuration: passcodeLockConfig)
|
|
||||||
|
|
||||||
let optionMenu = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
|
let optionMenu = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
|
||||||
|
let passcodeRemoveViewController = PasscodeLockViewController()
|
||||||
|
|
||||||
|
|
||||||
let removePasscodeAction = UIAlertAction(title: "Remove Passcode", style: .destructive) { [weak self] _ in
|
let removePasscodeAction = UIAlertAction(title: "Remove Passcode", style: .destructive) { [weak self] _ in
|
||||||
passcodeRemoveViewController.successCallback = { _ in
|
passcodeRemoveViewController.successCallback = {
|
||||||
self?.setPasscodeLockTouchIDCells()
|
self?.passcodeLock.delete()
|
||||||
|
self?.setPasscodeLockCell()
|
||||||
let appDelegate = UIApplication.shared.delegate as! AppDelegate
|
let appDelegate = UIApplication.shared.delegate as! AppDelegate
|
||||||
appDelegate.passcodeLockPresenter = PasscodeLockPresenter(mainWindow: appDelegate.window, configuration: (self?.passcodeLockConfig)!)
|
appDelegate.passcodeLockPresenter = PasscodeLockPresenter(mainWindow: appDelegate.window)
|
||||||
}
|
}
|
||||||
self?.present(passcodeRemoveViewController, animated: true, completion: nil)
|
self?.present(passcodeRemoveViewController, animated: true, completion: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
let changePasscodeAction = UIAlertAction(title: "Change Passcode", style: .default) { [weak self] _ in
|
let changePasscodeAction = UIAlertAction(title: "Change Passcode", style: .default) { [weak self] _ in
|
||||||
self?.present(passcodeChangeViewController, animated: true, completion: nil)
|
self?.setPasscodeLock()
|
||||||
}
|
}
|
||||||
|
|
||||||
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
|
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
|
||||||
|
|
@ -340,11 +281,49 @@ class SettingsTableViewController: UITableViewController, UITabBarControllerDele
|
||||||
self.present(optionMenu, animated: true, completion: nil)
|
self.present(optionMenu, animated: true, completion: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func setPasscodeLock() {
|
@objc func alertTextFieldDidChange(_ sender: UITextField) {
|
||||||
let passcodeSetViewController = PasscodeLockViewController(state: .set, configuration: passcodeLockConfig)
|
// check whether we should enable the Save button in setPasscodeLockAlert
|
||||||
passcodeSetViewController.successCallback = { _ in
|
if let setPasscodeLockAlert = self.setPasscodeLockAlert,
|
||||||
self.setPasscodeLockTouchIDCells()
|
let setPasscodeLockAlertTextFields0 = setPasscodeLockAlert.textFields?[0],
|
||||||
|
let setPasscodeLockAlertTextFields1 = setPasscodeLockAlert.textFields?[1] {
|
||||||
|
if sender == setPasscodeLockAlertTextFields0 || sender == setPasscodeLockAlertTextFields1 {
|
||||||
|
// two passwords should be the same, and length >= 4
|
||||||
|
let passcodeText = setPasscodeLockAlertTextFields0.text!
|
||||||
|
let passcodeConfirmationText = setPasscodeLockAlertTextFields1.text!
|
||||||
|
setPasscodeLockAlert.actions[0].isEnabled = passcodeText == passcodeConfirmationText && passcodeText.count >= 4
|
||||||
|
}
|
||||||
}
|
}
|
||||||
present(passcodeSetViewController, animated: true, completion: nil)
|
}
|
||||||
|
|
||||||
|
func setPasscodeLock() {
|
||||||
|
// prepare the alert for setting the passcode
|
||||||
|
setPasscodeLockAlert = UIAlertController(title: "Set passcode", message: "Fill in your passcode for Pass (at least 4 characters)", preferredStyle: .alert)
|
||||||
|
setPasscodeLockAlert?.addTextField(configurationHandler: {(_ textField: UITextField) -> Void in
|
||||||
|
textField.placeholder = "Password"
|
||||||
|
textField.isSecureTextEntry = true
|
||||||
|
textField.addTarget(self, action: #selector(self.alertTextFieldDidChange(_:)), for: UIControlEvents.editingChanged)
|
||||||
|
})
|
||||||
|
setPasscodeLockAlert?.addTextField(configurationHandler: {(_ textField: UITextField) -> Void in
|
||||||
|
textField.placeholder = "Password Confirmation"
|
||||||
|
textField.isSecureTextEntry = true
|
||||||
|
textField.addTarget(self, action: #selector(self.alertTextFieldDidChange(_:)), for: UIControlEvents.editingChanged)
|
||||||
|
})
|
||||||
|
|
||||||
|
// save action
|
||||||
|
let saveAction = UIAlertAction(title: "Save", style: .default) { (action:UIAlertAction) -> Void in
|
||||||
|
let passcode: String = self.setPasscodeLockAlert!.textFields![0].text!
|
||||||
|
self.passcodeLock.save(passcode: passcode)
|
||||||
|
// refresh the passcode lock cell ("On")
|
||||||
|
self.setPasscodeLockCell()
|
||||||
|
}
|
||||||
|
saveAction.isEnabled = false // disable the Save button by default
|
||||||
|
|
||||||
|
// cancel action
|
||||||
|
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
|
||||||
|
|
||||||
|
// present
|
||||||
|
setPasscodeLockAlert?.addAction(saveAction)
|
||||||
|
setPasscodeLockAlert?.addAction(cancelAction)
|
||||||
|
self.present(setPasscodeLockAlert!, animated: true, completion: nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,46 +7,14 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
import PasscodeLock
|
|
||||||
import passKit
|
import passKit
|
||||||
|
|
||||||
// add a cancel button in the passcode lock view
|
|
||||||
struct CancelableEnterPasscodeState: PasscodeLockStateType {
|
|
||||||
let title: String = "Enter passcode"
|
|
||||||
let description: String = "Enter passcode"
|
|
||||||
let isCancellableAction = true
|
|
||||||
var isTouchIDAllowed = true
|
|
||||||
mutating func accept(passcode: String, from lock: PasscodeLockType) {
|
|
||||||
if lock.repository.check(passcode: passcode) {
|
|
||||||
lock.delegate?.passcodeLockDidSucceed(lock)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// cancel means cancel the extension
|
|
||||||
class PasscodeLockViewControllerForExtension: PasscodeLockViewController {
|
|
||||||
var originalExtensionContest: NSExtensionContext?
|
|
||||||
public convenience init(extensionContext: NSExtensionContext?, state: PasscodeLockStateType, configuration: PasscodeLockConfigurationType, animateOnDismiss: Bool = true) {
|
|
||||||
self.init(state: state, configuration: configuration, animateOnDismiss: animateOnDismiss)
|
|
||||||
originalExtensionContest = extensionContext
|
|
||||||
}
|
|
||||||
override func viewDidLoad() {
|
|
||||||
super.viewDidLoad()
|
|
||||||
cancelButton?.removeTarget(nil, action: nil, for: .allEvents)
|
|
||||||
cancelButton?.addTarget(self, action: #selector(cancelExtension), for: .touchUpInside)
|
|
||||||
}
|
|
||||||
@objc func cancelExtension() {
|
|
||||||
originalExtensionContest?.completeRequest(returningItems: [], completionHandler: nil)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class PasscodeExtensionDisplay {
|
class PasscodeExtensionDisplay {
|
||||||
private var isPasscodePresented = false
|
private var isPasscodePresented = false
|
||||||
private let passcodeLockVC: PasscodeLockViewControllerForExtension
|
private let passcodeLockVC: PasscodeLockViewController
|
||||||
|
|
||||||
init(extensionContext: NSExtensionContext?) {
|
init(extensionContext: NSExtensionContext?) {
|
||||||
let cancelableEnter = CancelableEnterPasscodeState()
|
passcodeLockVC = PasscodeLockViewController()
|
||||||
passcodeLockVC = PasscodeLockViewControllerForExtension(extensionContext: extensionContext, state: cancelableEnter, configuration: PasscodeLockConfiguration.shared)
|
|
||||||
passcodeLockVC.dismissCompletionCallback = { [weak self] in
|
passcodeLockVC.dismissCompletionCallback = { [weak self] in
|
||||||
self?.dismiss()
|
self?.dismiss()
|
||||||
}
|
}
|
||||||
|
|
@ -54,7 +22,7 @@ class PasscodeExtensionDisplay {
|
||||||
|
|
||||||
// present the passcode lock view if passcode is set and the view controller is not presented
|
// present the passcode lock view if passcode is set and the view controller is not presented
|
||||||
func presentPasscodeLockIfNeeded(_ extensionVC: ExtensionViewController) {
|
func presentPasscodeLockIfNeeded(_ extensionVC: ExtensionViewController) {
|
||||||
guard PasscodeLockConfiguration.shared.repository.hasPasscode && !isPasscodePresented == true else {
|
guard PasscodeLock.shared.hasPasscode && !isPasscodePresented == true else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
isPasscodePresented = true
|
isPasscodePresented = true
|
||||||
|
|
|
||||||
59
passKit/Controllers/PasscodeLockPresenter.swift
Normal file
59
passKit/Controllers/PasscodeLockPresenter.swift
Normal file
|
|
@ -0,0 +1,59 @@
|
||||||
|
//
|
||||||
|
// PasscodeLockPresenter.swift
|
||||||
|
// PasscodeLock
|
||||||
|
//
|
||||||
|
// Created by Yanko Dimitrov on 8/29/15.
|
||||||
|
// Copyright © 2015 Yanko Dimitrov. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
open class PasscodeLockPresenter {
|
||||||
|
|
||||||
|
fileprivate var mainWindow: UIWindow?
|
||||||
|
|
||||||
|
fileprivate lazy var passcodeLockWindow = UIWindow(frame: UIScreen.main.bounds)
|
||||||
|
|
||||||
|
open var isPasscodePresented = false
|
||||||
|
open let passcodeLockVC: PasscodeLockViewController
|
||||||
|
|
||||||
|
public init(mainWindow window: UIWindow?, viewController: PasscodeLockViewController) {
|
||||||
|
mainWindow = window
|
||||||
|
passcodeLockVC = viewController
|
||||||
|
}
|
||||||
|
|
||||||
|
public convenience init(mainWindow window: UIWindow?) {
|
||||||
|
let passcodeLockVC = PasscodeLockViewController()
|
||||||
|
self.init(mainWindow: window, viewController: passcodeLockVC)
|
||||||
|
}
|
||||||
|
|
||||||
|
open func present(windowLevel: CGFloat?) {
|
||||||
|
guard PasscodeLock.shared.hasPasscode else { return }
|
||||||
|
guard !isPasscodePresented else { return }
|
||||||
|
|
||||||
|
isPasscodePresented = true
|
||||||
|
|
||||||
|
mainWindow?.endEditing(true)
|
||||||
|
moveWindowsToFront(windowLevel: windowLevel)
|
||||||
|
passcodeLockWindow.isHidden = false
|
||||||
|
|
||||||
|
let userDismissCompletionCallback = passcodeLockVC.dismissCompletionCallback
|
||||||
|
passcodeLockVC.dismissCompletionCallback = { [weak self] in
|
||||||
|
userDismissCompletionCallback?()
|
||||||
|
self?.dismiss()
|
||||||
|
}
|
||||||
|
passcodeLockWindow.rootViewController = passcodeLockVC
|
||||||
|
}
|
||||||
|
|
||||||
|
open func dismiss() {
|
||||||
|
isPasscodePresented = false
|
||||||
|
passcodeLockWindow.isHidden = true
|
||||||
|
passcodeLockWindow.rootViewController = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
fileprivate func moveWindowsToFront(windowLevel: CGFloat?) {
|
||||||
|
let windowLevel = windowLevel ?? UIWindowLevelNormal
|
||||||
|
let maxWinLevel = max(windowLevel, UIWindowLevelNormal)
|
||||||
|
passcodeLockWindow.windowLevel = maxWinLevel + 1
|
||||||
|
}
|
||||||
|
}
|
||||||
125
passKit/Controllers/PasscodeLockViewController.swift
Normal file
125
passKit/Controllers/PasscodeLockViewController.swift
Normal file
|
|
@ -0,0 +1,125 @@
|
||||||
|
//
|
||||||
|
// PasscodeLockViewController.swift
|
||||||
|
// PasscodeLock
|
||||||
|
//
|
||||||
|
// Created by Yanko Dimitrov on 8/28/15.
|
||||||
|
// Copyright © 2015 Yanko Dimitrov. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
import LocalAuthentication
|
||||||
|
|
||||||
|
open class PasscodeLockViewController: UIViewController {
|
||||||
|
|
||||||
|
open var dismissCompletionCallback: (()->Void)?
|
||||||
|
open var successCallback: (()->Void)?
|
||||||
|
open var cancelCallback: (()->Void)?
|
||||||
|
lazy var enterPasscodeAlert: UIAlertController = {
|
||||||
|
let enterPasscodeAlert = UIAlertController(title: "Authenticate Pass", message: "Unlock with passcode for Pass", preferredStyle: .alert)
|
||||||
|
|
||||||
|
enterPasscodeAlert.addTextField(configurationHandler: {(_ textField: UITextField) -> Void in
|
||||||
|
textField.placeholder = "passcode"
|
||||||
|
textField.isSecureTextEntry = true
|
||||||
|
textField.addTarget(self, action: #selector(self.passcodeTextFieldDidChange(_:)), for: UIControlEvents.editingChanged)
|
||||||
|
textField.clearButtonMode = UITextFieldViewMode.whileEditing
|
||||||
|
textField.becomeFirstResponder()
|
||||||
|
})
|
||||||
|
|
||||||
|
let myContext = LAContext()
|
||||||
|
var authError: NSError?
|
||||||
|
if #available(iOS 8.0, macOS 10.12.1, *) {
|
||||||
|
if myContext.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &authError) {
|
||||||
|
var biometryType = "Touch ID"
|
||||||
|
if #available(iOS 11.0, *) {
|
||||||
|
if myContext.biometryType == LABiometryType.faceID {
|
||||||
|
biometryType = "Face ID"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let bioAction = UIAlertAction(title: "Use " + biometryType, style: .default) { (action:UIAlertAction) -> Void in
|
||||||
|
self.authenticate()
|
||||||
|
}
|
||||||
|
enterPasscodeAlert.addAction(bioAction)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return enterPasscodeAlert
|
||||||
|
}()
|
||||||
|
|
||||||
|
open override func viewDidLoad() {
|
||||||
|
super.viewDidLoad()
|
||||||
|
self.view.backgroundColor = UIColor.white
|
||||||
|
}
|
||||||
|
|
||||||
|
open override func viewDidAppear(_ animated: Bool) {
|
||||||
|
super.viewDidAppear(animated)
|
||||||
|
authenticate()
|
||||||
|
}
|
||||||
|
|
||||||
|
internal func dismissPasscodeLock(completionHandler: (() -> Void)? = nil) {
|
||||||
|
// clean up the textfield
|
||||||
|
enterPasscodeAlert.textFields?[0].text = ""
|
||||||
|
if presentingViewController?.presentedViewController == self {
|
||||||
|
// if presented as modal
|
||||||
|
dismiss(animated: true, completion: { [weak self] in
|
||||||
|
self?.dismissCompletionCallback?()
|
||||||
|
completionHandler?()
|
||||||
|
})
|
||||||
|
// if pushed in a navigation controller
|
||||||
|
} else {
|
||||||
|
_ = navigationController?.popViewController(animated: true)
|
||||||
|
dismissCompletionCallback?()
|
||||||
|
completionHandler?()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - PasscodeLockDelegate
|
||||||
|
|
||||||
|
open func passcodeLockDidSucceed() {
|
||||||
|
dismissPasscodeLock(completionHandler: successCallback)
|
||||||
|
}
|
||||||
|
|
||||||
|
open func passcodeLockDidCancel() {
|
||||||
|
dismissPasscodeLock(completionHandler: cancelCallback)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func authenticate() {
|
||||||
|
print(enterPasscodeAlert.isBeingPresented)
|
||||||
|
|
||||||
|
let myContext = LAContext()
|
||||||
|
let myLocalizedReasonString = "Authentication is needed to access Pass."
|
||||||
|
var authError: NSError?
|
||||||
|
|
||||||
|
if #available(iOS 8.0, *) {
|
||||||
|
if myContext.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &authError) {
|
||||||
|
myContext.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: myLocalizedReasonString) { success, evaluateError in
|
||||||
|
if success {
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
// user authenticated successfully, take appropriate action
|
||||||
|
self.passcodeLockDidSucceed()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// User did not authenticate successfully
|
||||||
|
self.showPasswordAlert()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// could not evaluate policy; look at authError and present an appropriate message to user
|
||||||
|
self.showPasswordAlert()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// fallback on earlier versions
|
||||||
|
self.showPasswordAlert()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc func passcodeTextFieldDidChange(_ sender: UITextField) {
|
||||||
|
// check whether the passcode is correct
|
||||||
|
if PasscodeLock.shared.check(passcode: sender.text ?? "") {
|
||||||
|
self.passcodeLockDidSucceed()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func showPasswordAlert() {
|
||||||
|
self.present(enterPasscodeAlert, animated: true, completion: nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,28 +1,24 @@
|
||||||
//
|
//
|
||||||
// PasscodeRepository.swift
|
// PasscodeLock.swift
|
||||||
// pass
|
// PassKit
|
||||||
//
|
//
|
||||||
// Created by Mingshen Sun on 7/2/2017.
|
// Created by Yishi Lin on 28/1/2018.
|
||||||
// Copyright © 2017 Bob Sun. All rights reserved.
|
// Copyright © 2017 Yishi Lin. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
import PasscodeLock
|
import LocalAuthentication
|
||||||
|
|
||||||
public class PasscodeLockRepository: PasscodeRepositoryType {
|
open class PasscodeLock {
|
||||||
private let passcodeKey = "passcode.lock.passcode"
|
public static let shared = PasscodeLock()
|
||||||
|
|
||||||
public var hasPasscode: Bool {
|
fileprivate let passcodeKey = "passcode.lock.passcode"
|
||||||
|
fileprivate var passcode: String? {
|
||||||
if passcode != nil {
|
return SharedDefaults[.passcodeKey]
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private var passcode: String? {
|
public var hasPasscode: Bool {
|
||||||
return SharedDefaults[.passcodeKey]
|
return passcode != nil
|
||||||
}
|
}
|
||||||
|
|
||||||
public func save(passcode: String) {
|
public func save(passcode: String) {
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
//
|
|
||||||
// PasscodeLockConfiguration.swift
|
|
||||||
// pass
|
|
||||||
//
|
|
||||||
// Created by Mingshen Sun on 7/2/2017.
|
|
||||||
// Copyright © 2017 Bob Sun. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
import PasscodeLock
|
|
||||||
|
|
||||||
public class PasscodeLockConfiguration: PasscodeLockConfigurationType {
|
|
||||||
|
|
||||||
public static let shared = PasscodeLockConfiguration()
|
|
||||||
|
|
||||||
public let repository: PasscodeRepositoryType
|
|
||||||
public let passcodeLength = 4
|
|
||||||
public var isTouchIDAllowed = SharedDefaults[.isTouchIDOn]
|
|
||||||
|
|
||||||
public let shouldRequestTouchIDImmediately = true
|
|
||||||
public let maximumInccorectPasscodeAttempts = 3
|
|
||||||
|
|
||||||
init() {
|
|
||||||
self.repository = PasscodeLockRepository()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue