Merge branch 'release/0.2.7'
This commit is contained in:
commit
d635eea136
24 changed files with 609 additions and 472 deletions
|
|
@ -29,7 +29,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||||
SVProgressHUD.setMinimumSize(CGSize(width: 150, height: 100))
|
SVProgressHUD.setMinimumSize(CGSize(width: 150, height: 100))
|
||||||
passcodeLockPresenter.present()
|
passcodeLockPresenter.present()
|
||||||
if let shortcutItem = launchOptions?[UIApplicationLaunchOptionsKey.shortcutItem] as? UIApplicationShortcutItem {
|
if let shortcutItem = launchOptions?[UIApplicationLaunchOptionsKey.shortcutItem] as? UIApplicationShortcutItem {
|
||||||
if shortcutItem.type == "me.mssun.passforios.search" {
|
var searchType = Bundle.main.bundleIdentifier!
|
||||||
|
searchType.append("search")
|
||||||
|
if shortcutItem.type == searchType {
|
||||||
self.perform(#selector(postSearchNotification), with: nil, afterDelay: 0.4)
|
self.perform(#selector(postSearchNotification), with: nil, afterDelay: 0.4)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -42,7 +44,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||||
}
|
}
|
||||||
|
|
||||||
func application(_ application: UIApplication, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler: @escaping (Bool) -> Void) {
|
func application(_ application: UIApplication, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler: @escaping (Bool) -> Void) {
|
||||||
if shortcutItem.type == "me.mssun.passforios.search" {
|
var searchType = Bundle.main.bundleIdentifier!
|
||||||
|
searchType.append("search")
|
||||||
|
if shortcutItem.type == searchType {
|
||||||
let tabBarController = self.window!.rootViewController as! UITabBarController
|
let tabBarController = self.window!.rootViewController as! UITabBarController
|
||||||
tabBarController.selectedIndex = 0
|
tabBarController.selectedIndex = 0
|
||||||
let navigationController = tabBarController.selectedViewController as! UINavigationController
|
let navigationController = tabBarController.selectedViewController as! UINavigationController
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12120" systemVersion="16E195" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="YoR-iB-XAd">
|
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12120" systemVersion="16F73" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="YoR-iB-XAd">
|
||||||
<device id="retina5_5" orientation="portrait">
|
<device id="retina5_5" orientation="portrait">
|
||||||
<adaptation id="fullscreen"/>
|
<adaptation id="fullscreen"/>
|
||||||
</device>
|
</device>
|
||||||
|
|
@ -31,18 +31,18 @@
|
||||||
<rect key="frame" x="0.0" y="28" width="414" height="44"/>
|
<rect key="frame" x="0.0" y="28" width="414" height="44"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="bEm-K1-de5" id="kV8-N2-jWc">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="bEm-K1-de5" id="kV8-N2-jWc">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="381" height="43"/>
|
<rect key="frame" x="0.0" y="0.0" width="381" height="43.666666666666664"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Title" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Eu3-i0-M5v">
|
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Title" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Eu3-i0-M5v">
|
||||||
<rect key="frame" x="15" y="11" width="34" height="21"/>
|
<rect key="frame" x="15" y="11.999999999999998" width="33.333333333333336" height="20.333333333333332"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||||
<nil key="textColor"/>
|
<nil key="textColor"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="jms-aX-6FT">
|
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="jms-aX-6FT">
|
||||||
<rect key="frame" x="335" y="11" width="44" height="21"/>
|
<rect key="frame" x="335" y="11.999999999999998" width="44" height="20.333333333333332"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||||
<color key="textColor" white="0.66666666666666663" alpha="1" colorSpace="calibratedWhite"/>
|
<color key="textColor" white="0.66666666666666663" alpha="1" colorSpace="calibratedWhite"/>
|
||||||
|
|
@ -89,11 +89,11 @@
|
||||||
<rect key="frame" x="0.0" y="35" width="414" height="44"/>
|
<rect key="frame" x="0.0" y="35" width="414" height="44"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="55g-T3-9ak" id="dKn-cO-EJa">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="55g-T3-9ak" id="dKn-cO-EJa">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="381" height="43"/>
|
<rect key="frame" x="0.0" y="0.0" width="381" height="43.666666666666664"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="General" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="dOt-Rj-vWD">
|
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="General" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="dOt-Rj-vWD">
|
||||||
<rect key="frame" x="15" y="0.0" width="364" height="43"/>
|
<rect key="frame" x="15" y="0.0" width="364" height="43.666666666666664"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||||
<nil key="textColor"/>
|
<nil key="textColor"/>
|
||||||
|
|
@ -109,18 +109,18 @@
|
||||||
<rect key="frame" x="0.0" y="79" width="414" height="44"/>
|
<rect key="frame" x="0.0" y="79" width="414" height="44"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="2rc-ZW-XKd" id="CpT-zb-QEP">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="2rc-ZW-XKd" id="CpT-zb-QEP">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="381" height="43"/>
|
<rect key="frame" x="0.0" y="0.0" width="381" height="43.666666666666664"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Password Repository" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="gWn-ib-STb">
|
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Password Repository" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="gWn-ib-STb">
|
||||||
<rect key="frame" x="15" y="11" width="161" height="21"/>
|
<rect key="frame" x="15" y="11.999999999999998" width="160.33333333333334" height="20.333333333333332"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||||
<nil key="textColor"/>
|
<nil key="textColor"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Not Set" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Myq-fV-riz">
|
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Not Set" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Myq-fV-riz">
|
||||||
<rect key="frame" x="321" y="11" width="58" height="21"/>
|
<rect key="frame" x="321.33333333333331" y="11.999999999999998" width="57.666666666666664" height="20.333333333333332"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||||
<color key="textColor" red="0.5568627451" green="0.5568627451" blue="0.57647058819999997" alpha="1" colorSpace="calibratedRGB"/>
|
<color key="textColor" red="0.5568627451" green="0.5568627451" blue="0.57647058819999997" alpha="1" colorSpace="calibratedRGB"/>
|
||||||
|
|
@ -136,18 +136,18 @@
|
||||||
<rect key="frame" x="0.0" y="123" width="414" height="44"/>
|
<rect key="frame" x="0.0" y="123" width="414" height="44"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="1ze-MS-Xbj" id="W7U-oL-hOh">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="1ze-MS-Xbj" id="W7U-oL-hOh">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="381" height="43"/>
|
<rect key="frame" x="0.0" y="0.0" width="381" height="43.666666666666664"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="PGP Key" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="RR9-xr-9ko">
|
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="PGP Key" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="RR9-xr-9ko">
|
||||||
<rect key="frame" x="15" y="11" width="66" height="21"/>
|
<rect key="frame" x="15" y="11.999999999999998" width="66" height="20.333333333333332"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||||
<nil key="textColor"/>
|
<nil key="textColor"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Not Set" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="7lc-Vh-G9W">
|
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Not Set" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="7lc-Vh-G9W">
|
||||||
<rect key="frame" x="321" y="11" width="58" height="21"/>
|
<rect key="frame" x="321.33333333333331" y="11.999999999999998" width="57.666666666666664" height="20.333333333333332"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||||
<color key="textColor" red="0.55686274509803924" green="0.55686274509803924" blue="0.57647058823529407" alpha="1" colorSpace="calibratedRGB"/>
|
<color key="textColor" red="0.55686274509803924" green="0.55686274509803924" blue="0.57647058823529407" alpha="1" colorSpace="calibratedRGB"/>
|
||||||
|
|
@ -161,21 +161,21 @@
|
||||||
<tableViewSection headerTitle="SECURITY" id="Cx7-e4-wCO">
|
<tableViewSection headerTitle="SECURITY" id="Cx7-e4-wCO">
|
||||||
<cells>
|
<cells>
|
||||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="passcodeTableViewCell" textLabel="RaZ-6t-0CU" detailTextLabel="HXb-ZX-HUv" style="IBUITableViewCellStyleValue1" id="6Y0-mj-qhA">
|
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="passcodeTableViewCell" textLabel="RaZ-6t-0CU" detailTextLabel="HXb-ZX-HUv" style="IBUITableViewCellStyleValue1" id="6Y0-mj-qhA">
|
||||||
<rect key="frame" x="0.0" y="224" width="414" height="44"/>
|
<rect key="frame" x="0.0" y="223" width="414" height="44"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="6Y0-mj-qhA" id="qlv-tQ-Xmc">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="6Y0-mj-qhA" id="qlv-tQ-Xmc">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="381" height="43"/>
|
<rect key="frame" x="0.0" y="0.0" width="381" height="43.666666666666664"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Passcode Lock" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="RaZ-6t-0CU">
|
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Passcode Lock" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="RaZ-6t-0CU">
|
||||||
<rect key="frame" x="15" y="11" width="115" height="21"/>
|
<rect key="frame" x="15" y="11.999999999999998" width="115" height="20.333333333333332"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||||
<nil key="textColor"/>
|
<nil key="textColor"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Off" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="HXb-ZX-HUv">
|
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Off" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="HXb-ZX-HUv">
|
||||||
<rect key="frame" x="354" y="11" width="25" height="21"/>
|
<rect key="frame" x="354.66666666666669" y="11.999999999999998" width="24.333333333333332" height="20.333333333333332"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||||
<color key="textColor" red="0.5568627451" green="0.5568627451" blue="0.57647058819999997" alpha="1" colorSpace="calibratedRGB"/>
|
<color key="textColor" red="0.5568627451" green="0.5568627451" blue="0.57647058819999997" alpha="1" colorSpace="calibratedRGB"/>
|
||||||
|
|
@ -185,14 +185,14 @@
|
||||||
</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">
|
<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="268" width="414" height="44"/>
|
<rect key="frame" x="0.0" y="267" width="414" height="44"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="wB7-Km-Oel" id="m90-X7-DbI">
|
<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"/>
|
<rect key="frame" x="0.0" y="0.0" width="414" height="43.666666666666664"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Touch ID" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="H2E-hP-Gyf">
|
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Touch ID" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="H2E-hP-Gyf">
|
||||||
<rect key="frame" x="15" y="0.0" width="384" height="43"/>
|
<rect key="frame" x="15" y="0.0" width="384" height="43.666666666666664"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||||
<nil key="textColor"/>
|
<nil key="textColor"/>
|
||||||
|
|
@ -206,14 +206,14 @@
|
||||||
<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="348" width="414" height="44"/>
|
<rect key="frame" x="0.0" y="347" 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="381" height="43"/>
|
<rect key="frame" x="0.0" y="0.0" width="381" height="43.666666666666664"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Advanced" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="MKj-d0-8q3">
|
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Advanced" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="MKj-d0-8q3">
|
||||||
<rect key="frame" x="15" y="0.0" width="364" height="43"/>
|
<rect key="frame" x="15" y="0.0" width="364" height="43.666666666666664"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||||
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
|
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
|
||||||
|
|
@ -230,14 +230,14 @@
|
||||||
<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" imageView="Fgk-EG-6cx" style="IBUITableViewCellStyleDefault" id="osS-xk-WRP">
|
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="aboutTableViewCell" textLabel="oqz-Hr-RAl" imageView="Fgk-EG-6cx" style="IBUITableViewCellStyleDefault" id="osS-xk-WRP">
|
||||||
<rect key="frame" x="0.0" y="428" width="414" height="44"/>
|
<rect key="frame" x="0.0" y="427" 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="381" height="43"/>
|
<rect key="frame" x="0.0" y="0.0" width="381" height="43.666666666666664"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="About" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="oqz-Hr-RAl">
|
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="About" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="oqz-Hr-RAl">
|
||||||
<rect key="frame" x="15" y="0.0" width="364" height="43"/>
|
<rect key="frame" x="15" y="0.0" width="364" height="43.666666666666664"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||||
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
|
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
|
||||||
|
|
@ -288,7 +288,7 @@
|
||||||
<rect key="frame" x="0.0" y="28" width="414" height="54"/>
|
<rect key="frame" x="0.0" y="28" width="414" height="54"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" tableViewCell="OfB-1N-1Am" id="fh0-au-C6q">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" tableViewCell="OfB-1N-1Am" id="fh0-au-C6q">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="414" height="53"/>
|
<rect key="frame" x="0.0" y="0.0" width="414" height="54"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<label opaque="NO" userInteractionEnabled="NO" tag="201" contentMode="left" verticalHuggingPriority="251" preservesSuperviewLayoutMargins="YES" text="2017/04/04" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="GLC-qL-55P">
|
<label opaque="NO" userInteractionEnabled="NO" tag="201" contentMode="left" verticalHuggingPriority="251" preservesSuperviewLayoutMargins="YES" text="2017/04/04" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="GLC-qL-55P">
|
||||||
|
|
@ -348,7 +348,7 @@
|
||||||
<tableViewSection headerTitle="Git Repository URL" id="pbe-W6-w4V">
|
<tableViewSection headerTitle="Git Repository URL" id="pbe-W6-w4V">
|
||||||
<cells>
|
<cells>
|
||||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" indentationWidth="10" reuseIdentifier="gitRepositoryURLTabelViewCell" rowHeight="52" id="FRr-pf-aPO">
|
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" indentationWidth="10" reuseIdentifier="gitRepositoryURLTabelViewCell" rowHeight="52" id="FRr-pf-aPO">
|
||||||
<rect key="frame" x="0.0" y="56" width="414" height="52"/>
|
<rect key="frame" x="0.0" y="55" width="414" height="52"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" tableViewCell="FRr-pf-aPO" id="60A-PS-qGe">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" tableViewCell="FRr-pf-aPO" id="60A-PS-qGe">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="414" height="51"/>
|
<rect key="frame" x="0.0" y="0.0" width="414" height="51"/>
|
||||||
|
|
@ -378,7 +378,7 @@
|
||||||
<tableViewSection headerTitle="Username" id="fRu-A2-SCk">
|
<tableViewSection headerTitle="Username" id="fRu-A2-SCk">
|
||||||
<cells>
|
<cells>
|
||||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" indentationWidth="10" reuseIdentifier="usernameTableVIewCell" rowHeight="52" id="tnj-5U-kMB">
|
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" indentationWidth="10" reuseIdentifier="usernameTableVIewCell" rowHeight="52" id="tnj-5U-kMB">
|
||||||
<rect key="frame" x="0.0" y="165" width="414" height="52"/>
|
<rect key="frame" x="0.0" y="163" width="414" height="52"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" tableViewCell="tnj-5U-kMB" id="f0c-pI-MSJ">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" tableViewCell="tnj-5U-kMB" id="f0c-pI-MSJ">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="414" height="51"/>
|
<rect key="frame" x="0.0" y="0.0" width="414" height="51"/>
|
||||||
|
|
@ -407,7 +407,7 @@
|
||||||
<tableViewSection headerTitle="Authentication Method" id="h0N-tI-shZ">
|
<tableViewSection headerTitle="Authentication Method" id="h0N-tI-shZ">
|
||||||
<cells>
|
<cells>
|
||||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="2" indentationWidth="0.0" shouldIndentWhileEditing="NO" id="KrP-nb-haa">
|
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="2" indentationWidth="0.0" shouldIndentWhileEditing="NO" id="KrP-nb-haa">
|
||||||
<rect key="frame" x="0.0" y="274" width="414" height="44"/>
|
<rect key="frame" x="0.0" y="271" width="414" height="44"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="KrP-nb-haa" id="1uB-oE-kfI">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="KrP-nb-haa" id="1uB-oE-kfI">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="414" height="43"/>
|
<rect key="frame" x="0.0" y="0.0" width="414" height="43"/>
|
||||||
|
|
@ -438,7 +438,7 @@
|
||||||
<inset key="separatorInset" minX="62" minY="0.0" maxX="0.0" maxY="0.0"/>
|
<inset key="separatorInset" minX="62" minY="0.0" maxX="0.0" maxY="0.0"/>
|
||||||
</tableViewCell>
|
</tableViewCell>
|
||||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="blue" accessoryType="detailButton" hidesAccessoryWhenEditing="NO" indentationLevel="2" indentationWidth="0.0" shouldIndentWhileEditing="NO" id="Qmt-bo-CuJ">
|
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="blue" accessoryType="detailButton" hidesAccessoryWhenEditing="NO" indentationLevel="2" indentationWidth="0.0" shouldIndentWhileEditing="NO" id="Qmt-bo-CuJ">
|
||||||
<rect key="frame" x="0.0" y="318" width="414" height="44"/>
|
<rect key="frame" x="0.0" y="315" width="414" height="44"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="Qmt-bo-CuJ" id="p3u-8b-h3U">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="Qmt-bo-CuJ" id="p3u-8b-h3U">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="367" height="43"/>
|
<rect key="frame" x="0.0" y="0.0" width="367" height="43"/>
|
||||||
|
|
@ -519,7 +519,7 @@
|
||||||
<rect key="frame" x="0.0" y="35" width="414" height="52"/>
|
<rect key="frame" x="0.0" y="35" width="414" height="52"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="BYZ-9g-xZy" id="Zfn-rK-sN1">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="BYZ-9g-xZy" id="Zfn-rK-sN1">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="414" height="51"/>
|
<rect key="frame" x="0.0" y="0.0" width="414" height="52"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Public Key URL" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="dWi-eh-7Eq">
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Public Key URL" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="dWi-eh-7Eq">
|
||||||
|
|
@ -553,7 +553,7 @@
|
||||||
<rect key="frame" x="0.0" y="87" width="414" height="52"/>
|
<rect key="frame" x="0.0" y="87" width="414" height="52"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="vpk-J8-j7t" id="1td-qT-6ts">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="vpk-J8-j7t" id="1td-qT-6ts">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="414" height="51"/>
|
<rect key="frame" x="0.0" y="0.0" width="414" height="52"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Private Key URL" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Qht-RC-Yeg">
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Private Key URL" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Qht-RC-Yeg">
|
||||||
|
|
@ -648,7 +648,7 @@
|
||||||
</objects>
|
</objects>
|
||||||
<point key="canvasLocation" x="4954" y="-1027"/>
|
<point key="canvasLocation" x="4954" y="-1027"/>
|
||||||
</scene>
|
</scene>
|
||||||
<!--Scanner-->
|
<!--Scan OTP QR Codes-->
|
||||||
<scene sceneID="AuR-rQ-G3V">
|
<scene sceneID="AuR-rQ-G3V">
|
||||||
<objects>
|
<objects>
|
||||||
<viewController id="A9p-Qb-WmU" customClass="OTPScannerController" customModule="pass" customModuleProvider="target" sceneMemberID="viewController">
|
<viewController id="A9p-Qb-WmU" customClass="OTPScannerController" customModule="pass" customModuleProvider="target" sceneMemberID="viewController">
|
||||||
|
|
@ -678,7 +678,7 @@
|
||||||
<constraint firstAttribute="trailingMargin" secondItem="lOI-p4-BGb" secondAttribute="trailing" constant="30" id="qNb-4K-GGl"/>
|
<constraint firstAttribute="trailingMargin" secondItem="lOI-p4-BGb" secondAttribute="trailing" constant="30" id="qNb-4K-GGl"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
</view>
|
</view>
|
||||||
<navigationItem key="navigationItem" title="Scanner" id="Hlb-5I-bfE">
|
<navigationItem key="navigationItem" title="Scan OTP QR Codes" id="Hlb-5I-bfE">
|
||||||
<barButtonItem key="leftBarButtonItem" systemItem="cancel" id="KBZ-N2-OGE">
|
<barButtonItem key="leftBarButtonItem" systemItem="cancel" id="KBZ-N2-OGE">
|
||||||
<connections>
|
<connections>
|
||||||
<segue destination="0gD-ix-2NF" kind="unwind" unwindAction="cancelOTPScannerWithSegue:" id="nZe-B6-MNt"/>
|
<segue destination="0gD-ix-2NF" kind="unwind" unwindAction="cancelOTPScannerWithSegue:" id="nZe-B6-MNt"/>
|
||||||
|
|
@ -912,45 +912,11 @@ Phone Support PIN #: 84719</string>
|
||||||
<sections>
|
<sections>
|
||||||
<tableViewSection id="7c6-yg-Aab">
|
<tableViewSection id="7c6-yg-Aab">
|
||||||
<cells>
|
<cells>
|
||||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" reuseIdentifier="publicKeyURLTableViewCell" rowHeight="52" id="Jy1-4S-Lvf">
|
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" reuseIdentifier="privateKeyURLTableViewCell" rowHeight="52" id="MA5-lE-8dT">
|
||||||
<rect key="frame" x="0.0" y="35" width="414" height="52"/>
|
<rect key="frame" x="0.0" y="35" width="414" height="52"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="Jy1-4S-Lvf" id="tJE-ww-okf">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="414" height="51"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<subviews>
|
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Public Key URL" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Oys-xP-ZrB">
|
|
||||||
<rect key="frame" x="15" y="8" width="391" height="15"/>
|
|
||||||
<fontDescription key="fontDescription" style="UICTFontTextStyleCaption1"/>
|
|
||||||
<color key="textColor" white="0.33333333333333331" alpha="1" colorSpace="calibratedWhite"/>
|
|
||||||
<nil key="highlightedColor"/>
|
|
||||||
</label>
|
|
||||||
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="Public Key URL" textAlignment="natural" minimumFontSize="17" clearButtonMode="whileEditing" translatesAutoresizingMaskIntoConstraints="NO" id="Q1j-Z4-Ae8">
|
|
||||||
<rect key="frame" x="15" y="23" width="391" height="21"/>
|
|
||||||
<nil key="textColor"/>
|
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
|
||||||
<textInputTraits key="textInputTraits" autocorrectionType="no" spellCheckingType="no" keyboardType="URL" returnKeyType="next"/>
|
|
||||||
<connections>
|
|
||||||
<outlet property="delegate" destination="hqC-Ic-NMi" id="grO-WT-wLU"/>
|
|
||||||
<outlet property="nextField" destination="4iJ-oB-R1f" id="4oy-bE-Mh5"/>
|
|
||||||
</connections>
|
|
||||||
</textField>
|
|
||||||
</subviews>
|
|
||||||
<constraints>
|
|
||||||
<constraint firstItem="Q1j-Z4-Ae8" firstAttribute="leading" secondItem="Oys-xP-ZrB" secondAttribute="leading" id="1dT-YN-mgp"/>
|
|
||||||
<constraint firstItem="Q1j-Z4-Ae8" firstAttribute="top" secondItem="Oys-xP-ZrB" secondAttribute="bottom" id="28u-dV-vgj"/>
|
|
||||||
<constraint firstAttribute="trailingMargin" secondItem="Oys-xP-ZrB" secondAttribute="trailing" id="EAa-jy-gKh"/>
|
|
||||||
<constraint firstItem="Oys-xP-ZrB" firstAttribute="leading" secondItem="tJE-ww-okf" secondAttribute="leadingMargin" constant="7" id="Ivp-CN-Uv6"/>
|
|
||||||
<constraint firstAttribute="topMargin" secondItem="Oys-xP-ZrB" secondAttribute="top" id="auJ-Xy-l2r"/>
|
|
||||||
<constraint firstAttribute="trailingMargin" secondItem="Q1j-Z4-Ae8" secondAttribute="trailing" id="dHQ-mx-Xuw"/>
|
|
||||||
</constraints>
|
|
||||||
</tableViewCellContentView>
|
|
||||||
</tableViewCell>
|
|
||||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" reuseIdentifier="privateKeyURLTableViewCell" rowHeight="52" id="MA5-lE-8dT">
|
|
||||||
<rect key="frame" x="0.0" y="87" width="414" height="52"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="MA5-lE-8dT" id="pTv-Wj-psC">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="MA5-lE-8dT" id="pTv-Wj-psC">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="414" height="51"/>
|
<rect key="frame" x="0.0" y="0.0" width="414" height="52"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Private Key URL" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="C2w-dd-roS">
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Private Key URL" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="C2w-dd-roS">
|
||||||
|
|
@ -996,7 +962,6 @@ Phone Support PIN #: 84719</string>
|
||||||
</navigationItem>
|
</navigationItem>
|
||||||
<connections>
|
<connections>
|
||||||
<outlet property="privateKeyURLTextField" destination="4iJ-oB-R1f" id="scx-lz-dUW"/>
|
<outlet property="privateKeyURLTextField" destination="4iJ-oB-R1f" id="scx-lz-dUW"/>
|
||||||
<outlet property="publicKeyURLTextField" destination="Q1j-Z4-Ae8" id="nfA-W3-kJ2"/>
|
|
||||||
</connections>
|
</connections>
|
||||||
</tableViewController>
|
</tableViewController>
|
||||||
<placeholder placeholderIdentifier="IBFirstResponder" id="eY3-aM-BJB" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
<placeholder placeholderIdentifier="IBFirstResponder" id="eY3-aM-BJB" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||||
|
|
@ -1056,14 +1021,14 @@ Phone Support PIN #: 84719</string>
|
||||||
<tableViewSection headerTitle="GPG Configuration" id="ugP-R2-9M7">
|
<tableViewSection headerTitle="GPG Configuration" id="ugP-R2-9M7">
|
||||||
<cells>
|
<cells>
|
||||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" textLabel="Jwg-mt-woS" style="IBUITableViewCellStyleDefault" id="tHt-Ro-0HF" userLabel="Encrypt in ASCII-Armored">
|
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" textLabel="Jwg-mt-woS" style="IBUITableViewCellStyleDefault" id="tHt-Ro-0HF" userLabel="Encrypt in ASCII-Armored">
|
||||||
<rect key="frame" x="0.0" y="56" width="414" height="44"/>
|
<rect key="frame" x="0.0" y="55" width="414" height="44"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="tHt-Ro-0HF" id="Epj-ei-NtS">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="tHt-Ro-0HF" id="Epj-ei-NtS">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="414" height="43"/>
|
<rect key="frame" x="0.0" y="0.0" width="414" height="43.666666666666664"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Encrypt in ASCII-Armored" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Jwg-mt-woS">
|
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Encrypt in ASCII-Armored" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Jwg-mt-woS">
|
||||||
<rect key="frame" x="15" y="0.0" width="384" height="43"/>
|
<rect key="frame" x="15" y="0.0" width="384" height="43.666666666666664"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||||
<nil key="textColor"/>
|
<nil key="textColor"/>
|
||||||
|
|
@ -1077,21 +1042,21 @@ Phone Support PIN #: 84719</string>
|
||||||
<tableViewSection headerTitle="Git Configuration" id="ihT-OG-HTv">
|
<tableViewSection headerTitle="Git Configuration" id="ihT-OG-HTv">
|
||||||
<cells>
|
<cells>
|
||||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" textLabel="87a-xY-AbR" detailTextLabel="2qr-d7-0SK" style="IBUITableViewCellStyleValue1" id="SVj-jD-qPT" userLabel="Git Signature">
|
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" textLabel="87a-xY-AbR" detailTextLabel="2qr-d7-0SK" style="IBUITableViewCellStyleValue1" id="SVj-jD-qPT" userLabel="Git Signature">
|
||||||
<rect key="frame" x="0.0" y="157" width="414" height="44"/>
|
<rect key="frame" x="0.0" y="155" width="414" height="44"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="SVj-jD-qPT" id="HaO-5w-qZt">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="SVj-jD-qPT" id="HaO-5w-qZt">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="381" height="43"/>
|
<rect key="frame" x="0.0" y="0.0" width="381" height="43.666666666666664"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Git Signature" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="87a-xY-AbR">
|
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Git Signature" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="87a-xY-AbR">
|
||||||
<rect key="frame" x="15" y="11" width="100" height="21"/>
|
<rect key="frame" x="15.000000000000007" y="11.999999999999998" width="99.666666666666671" height="20.333333333333332"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||||
<nil key="textColor"/>
|
<nil key="textColor"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Not Set" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="2qr-d7-0SK">
|
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Not Set" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="2qr-d7-0SK">
|
||||||
<rect key="frame" x="321" y="11" width="58" height="21"/>
|
<rect key="frame" x="321.33333333333331" y="11.999999999999998" width="57.666666666666664" height="20.333333333333332"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||||
<color key="textColor" red="0.5568627451" green="0.5568627451" blue="0.57647058819999997" alpha="1" colorSpace="calibratedRGB"/>
|
<color key="textColor" red="0.5568627451" green="0.5568627451" blue="0.57647058819999997" alpha="1" colorSpace="calibratedRGB"/>
|
||||||
|
|
@ -1108,14 +1073,14 @@ Phone Support PIN #: 84719</string>
|
||||||
<tableViewSection headerTitle="PasswordStore Data" id="aVR-FE-jMg">
|
<tableViewSection headerTitle="PasswordStore Data" id="aVR-FE-jMg">
|
||||||
<cells>
|
<cells>
|
||||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" textLabel="zrl-v3-fxg" style="IBUITableViewCellStyleDefault" id="Jm8-B5-wKx" userLabel="Discard Changes Table View Cell">
|
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" textLabel="zrl-v3-fxg" style="IBUITableViewCellStyleDefault" id="Jm8-B5-wKx" userLabel="Discard Changes Table View Cell">
|
||||||
<rect key="frame" x="0.0" y="258" width="414" height="44"/>
|
<rect key="frame" x="0.0" y="255" width="414" height="44"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="Jm8-B5-wKx" id="tjS-Q6-y2M">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="Jm8-B5-wKx" id="tjS-Q6-y2M">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="414" height="43"/>
|
<rect key="frame" x="0.0" y="0.0" width="414" height="43.666666666666664"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Discard All Local Changes" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="zrl-v3-fxg">
|
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Discard All Local Changes" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="zrl-v3-fxg">
|
||||||
<rect key="frame" x="15" y="0.0" width="384" height="43"/>
|
<rect key="frame" x="15" y="0.0" width="384" height="43.666666666666664"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||||
<color key="textColor" red="0.50196081400000003" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
|
<color key="textColor" red="0.50196081400000003" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
|
||||||
|
|
@ -1125,14 +1090,14 @@ Phone Support PIN #: 84719</string>
|
||||||
</tableViewCellContentView>
|
</tableViewCellContentView>
|
||||||
</tableViewCell>
|
</tableViewCell>
|
||||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" textLabel="K2K-Bx-g7Z" style="IBUITableViewCellStyleDefault" id="NI1-Kd-hyH">
|
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" textLabel="K2K-Bx-g7Z" style="IBUITableViewCellStyleDefault" id="NI1-Kd-hyH">
|
||||||
<rect key="frame" x="0.0" y="302" width="414" height="44"/>
|
<rect key="frame" x="0.0" y="299" width="414" height="44"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="NI1-Kd-hyH" id="yLe-T2-TWF">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="NI1-Kd-hyH" id="yLe-T2-TWF">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="414" height="43"/>
|
<rect key="frame" x="0.0" y="0.0" width="414" height="43.666666666666664"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Erase All Password Store Data" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="K2K-Bx-g7Z">
|
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Erase All Password Store Data" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="K2K-Bx-g7Z">
|
||||||
<rect key="frame" x="15" y="0.0" width="384" height="43"/>
|
<rect key="frame" x="15" y="0.0" width="384" height="43.666666666666664"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||||
<color key="textColor" red="0.50196081400000003" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
|
<color key="textColor" red="0.50196081400000003" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
|
||||||
|
|
@ -1276,11 +1241,11 @@ Phone Support PIN #: 84719</string>
|
||||||
<rect key="frame" x="0.0" y="35" width="414" height="170"/>
|
<rect key="frame" x="0.0" y="35" width="414" height="170"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="Pv0-ev-stj" id="ywz-II-W1g">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="Pv0-ev-stj" id="ywz-II-W1g">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="414" height="169"/>
|
<rect key="frame" x="0.0" y="0.0" width="414" height="169.66666666666666"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="ASCII-Armor Keys" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="M32-yr-IfE">
|
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="ASCII-Armor Keys" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="M32-yr-IfE">
|
||||||
<rect key="frame" x="15" y="17" width="122" height="17"/>
|
<rect key="frame" x="15.000000000000007" y="17" width="121.66666666666667" height="17"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<fontDescription key="fontDescription" name="HelveticaNeue-Bold" family="Helvetica Neue" pointSize="14"/>
|
<fontDescription key="fontDescription" name="HelveticaNeue-Bold" family="Helvetica Neue" pointSize="14"/>
|
||||||
<nil key="textColor"/>
|
<nil key="textColor"/>
|
||||||
|
|
@ -1337,10 +1302,10 @@ Cgo
|
||||||
<tableViewSection headerTitle="ASCII-Armor Encrypted Public Key" id="MZz-mp-v5N">
|
<tableViewSection headerTitle="ASCII-Armor Encrypted Public Key" id="MZz-mp-v5N">
|
||||||
<cells>
|
<cells>
|
||||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" reuseIdentifier="pgpKeyURLTableViewCell" rowHeight="160" id="Lom-iT-l16">
|
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" reuseIdentifier="pgpKeyURLTableViewCell" rowHeight="160" id="Lom-iT-l16">
|
||||||
<rect key="frame" x="0.0" y="245" width="414" height="160"/>
|
<rect key="frame" x="0.0" y="244" width="414" height="160"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="Lom-iT-l16" id="eya-Tv-r0q">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="Lom-iT-l16" id="eya-Tv-r0q">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="414" height="159"/>
|
<rect key="frame" x="0.0" y="0.0" width="414" height="160"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="oyB-oI-1fS">
|
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="oyB-oI-1fS">
|
||||||
|
|
@ -1363,10 +1328,10 @@ Cgo
|
||||||
</tableViewCellContentView>
|
</tableViewCellContentView>
|
||||||
</tableViewCell>
|
</tableViewCell>
|
||||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" id="F0i-XE-PGt" userLabel="scanQRCodeCell">
|
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" id="F0i-XE-PGt" userLabel="scanQRCodeCell">
|
||||||
<rect key="frame" x="0.0" y="405" width="414" height="44"/>
|
<rect key="frame" x="0.0" y="404" width="414" height="44"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="F0i-XE-PGt" id="xO8-yL-W9a">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="F0i-XE-PGt" id="xO8-yL-W9a">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="414" height="43"/>
|
<rect key="frame" x="0.0" y="0.0" width="414" height="44"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
</tableViewCellContentView>
|
</tableViewCellContentView>
|
||||||
</tableViewCell>
|
</tableViewCell>
|
||||||
|
|
@ -1375,10 +1340,10 @@ Cgo
|
||||||
<tableViewSection headerTitle="ASCII-ARMOR ENCRYPTED PRIVATE KEY" id="0RP-Jn-j5G">
|
<tableViewSection headerTitle="ASCII-ARMOR ENCRYPTED PRIVATE KEY" id="0RP-Jn-j5G">
|
||||||
<cells>
|
<cells>
|
||||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" reuseIdentifier="pgpKeyURLTableViewCell" rowHeight="160" id="J8U-ev-FRQ">
|
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" reuseIdentifier="pgpKeyURLTableViewCell" rowHeight="160" id="J8U-ev-FRQ">
|
||||||
<rect key="frame" x="0.0" y="489" width="414" height="160"/>
|
<rect key="frame" x="0.0" y="487" width="414" height="160"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="J8U-ev-FRQ" id="eb0-vb-Fcc">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="J8U-ev-FRQ" id="eb0-vb-Fcc">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="414" height="159"/>
|
<rect key="frame" x="0.0" y="0.0" width="414" height="160"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="lrQ-Ln-ZOv">
|
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="lrQ-Ln-ZOv">
|
||||||
|
|
@ -1401,10 +1366,10 @@ Cgo
|
||||||
</tableViewCellContentView>
|
</tableViewCellContentView>
|
||||||
</tableViewCell>
|
</tableViewCell>
|
||||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" id="b0Z-rW-sAE" userLabel="scanQRCodeCell">
|
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" id="b0Z-rW-sAE" userLabel="scanQRCodeCell">
|
||||||
<rect key="frame" x="0.0" y="649" width="414" height="44"/>
|
<rect key="frame" x="0.0" y="647" width="414" height="44"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="b0Z-rW-sAE" id="UZX-pP-UWB">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="b0Z-rW-sAE" id="UZX-pP-UWB">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="414" height="43"/>
|
<rect key="frame" x="0.0" y="0.0" width="414" height="44"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
</tableViewCellContentView>
|
</tableViewCellContentView>
|
||||||
</tableViewCell>
|
</tableViewCell>
|
||||||
|
|
@ -1482,7 +1447,7 @@ Cgo
|
||||||
<scene sceneID="zWR-BT-dXv">
|
<scene sceneID="zWR-BT-dXv">
|
||||||
<objects>
|
<objects>
|
||||||
<tableViewController id="WgM-cY-mig" customClass="GitSSHKeyArmorSettingTableViewController" customModule="pass" customModuleProvider="target" sceneMemberID="viewController">
|
<tableViewController id="WgM-cY-mig" customClass="GitSSHKeyArmorSettingTableViewController" customModule="pass" customModuleProvider="target" sceneMemberID="viewController">
|
||||||
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="static" style="grouped" separatorStyle="default" allowsSelection="NO" rowHeight="44" sectionHeaderHeight="18" sectionFooterHeight="1" id="e2Q-qC-LUk">
|
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="static" style="grouped" separatorStyle="default" rowHeight="44" sectionHeaderHeight="18" sectionFooterHeight="1" id="e2Q-qC-LUk">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="414" height="736"/>
|
<rect key="frame" x="0.0" y="0.0" width="414" height="736"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<color key="backgroundColor" cocoaTouchSystemColor="groupTableViewBackgroundColor"/>
|
<color key="backgroundColor" cocoaTouchSystemColor="groupTableViewBackgroundColor"/>
|
||||||
|
|
@ -1493,18 +1458,18 @@ Cgo
|
||||||
<rect key="frame" x="0.0" y="35" width="414" height="170"/>
|
<rect key="frame" x="0.0" y="35" width="414" height="170"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="EMz-nP-2Om" id="XW5-mL-PRC">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="EMz-nP-2Om" id="XW5-mL-PRC">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="414" height="169"/>
|
<rect key="frame" x="0.0" y="0.0" width="414" height="169.66666666666666"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="ASCII-Armor Keys" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="i78-t7-fP9">
|
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="ASCII-Armor Keys" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="i78-t7-fP9">
|
||||||
<rect key="frame" x="15" y="36" width="122" height="17"/>
|
<rect key="frame" x="15.000000000000007" y="45" width="121.66666666666667" height="17"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<fontDescription key="fontDescription" name="HelveticaNeue-Bold" family="Helvetica Neue" pointSize="14"/>
|
<fontDescription key="fontDescription" name="HelveticaNeue-Bold" family="Helvetica Neue" pointSize="14"/>
|
||||||
<nil key="textColor"/>
|
<nil key="textColor"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" usesAttributedText="YES" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Oit-sd-wa5">
|
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" usesAttributedText="YES" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Oit-sd-wa5">
|
||||||
<rect key="frame" x="15" y="53" width="344" height="80"/>
|
<rect key="frame" x="15" y="61.999999999999993" width="344" height="64.333333333333329"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<attributedString key="attributedText">
|
<attributedString key="attributedText">
|
||||||
<fragment>
|
<fragment>
|
||||||
|
|
@ -1517,9 +1482,7 @@ Cgo
|
||||||
<paragraphStyle key="NSParagraphStyle" alignment="left" lineBreakMode="wordWrapping" baseWritingDirection="natural" tighteningFactorForTruncation="0.0" allowsDefaultTighteningForTruncation="NO"/>
|
<paragraphStyle key="NSParagraphStyle" alignment="left" lineBreakMode="wordWrapping" baseWritingDirection="natural" tighteningFactorForTruncation="0.0" allowsDefaultTighteningForTruncation="NO"/>
|
||||||
</attributes>
|
</attributes>
|
||||||
</fragment>
|
</fragment>
|
||||||
<fragment>
|
<fragment content=" $ cat ~/.ssh/id_rsa">
|
||||||
<string key="content"> $ cat ~/.ssh/id_rsa.pub
|
|
||||||
$ cat ~/.ssh/id_rsa</string>
|
|
||||||
<attributes>
|
<attributes>
|
||||||
<color key="NSColor" white="0.40782000000000002" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
<color key="NSColor" white="0.40782000000000002" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||||
<font key="NSFont" size="13" name="Menlo-Regular"/>
|
<font key="NSFont" size="13" name="Menlo-Regular"/>
|
||||||
|
|
@ -1534,40 +1497,13 @@ Cgo
|
||||||
</tableViewCell>
|
</tableViewCell>
|
||||||
</cells>
|
</cells>
|
||||||
</tableViewSection>
|
</tableViewSection>
|
||||||
<tableViewSection headerTitle="ASCII-Armor Encrypted Public Key" id="w4D-Mh-0pP">
|
|
||||||
<cells>
|
|
||||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" reuseIdentifier="pgpKeyURLTableViewCell" rowHeight="160" id="3po-uS-Nch">
|
|
||||||
<rect key="frame" x="0.0" y="245" width="414" height="160"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="3po-uS-Nch" id="pet-if-EHU">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="414" height="159"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<subviews>
|
|
||||||
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Y9t-DD-6uH">
|
|
||||||
<rect key="frame" x="15" y="8" width="391" height="144"/>
|
|
||||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
|
||||||
<color key="textColor" white="0.33333333333333331" alpha="1" colorSpace="calibratedWhite"/>
|
|
||||||
<fontDescription key="fontDescription" name="Menlo-Regular" family="Menlo" pointSize="8.5"/>
|
|
||||||
<textInputTraits key="textInputTraits" autocorrectionType="no" spellCheckingType="no"/>
|
|
||||||
</textView>
|
|
||||||
</subviews>
|
|
||||||
<constraints>
|
|
||||||
<constraint firstAttribute="bottomMargin" secondItem="Y9t-DD-6uH" secondAttribute="bottom" id="EAK-Wn-RP8"/>
|
|
||||||
<constraint firstItem="Y9t-DD-6uH" firstAttribute="top" secondItem="pet-if-EHU" secondAttribute="topMargin" id="LW7-SZ-CP3"/>
|
|
||||||
<constraint firstItem="Y9t-DD-6uH" firstAttribute="leading" secondItem="pet-if-EHU" secondAttribute="leadingMargin" constant="7" id="bw3-EI-8oh"/>
|
|
||||||
<constraint firstAttribute="trailingMargin" secondItem="Y9t-DD-6uH" secondAttribute="trailing" id="fCY-XN-Wtz"/>
|
|
||||||
</constraints>
|
|
||||||
</tableViewCellContentView>
|
|
||||||
</tableViewCell>
|
|
||||||
</cells>
|
|
||||||
</tableViewSection>
|
|
||||||
<tableViewSection headerTitle="ASCII-ARMOR ENCRYPTED PRIVATE KEY" id="sxk-Yb-Y3x">
|
<tableViewSection headerTitle="ASCII-ARMOR ENCRYPTED PRIVATE KEY" id="sxk-Yb-Y3x">
|
||||||
<cells>
|
<cells>
|
||||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" reuseIdentifier="pgpKeyURLTableViewCell" rowHeight="160" id="nmc-vy-Ab5">
|
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" reuseIdentifier="pgpKeyURLTableViewCell" rowHeight="160" id="nmc-vy-Ab5">
|
||||||
<rect key="frame" x="0.0" y="445" width="414" height="160"/>
|
<rect key="frame" x="0.0" y="244" width="414" height="160"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="nmc-vy-Ab5" id="TQD-GC-YOY">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="nmc-vy-Ab5" id="TQD-GC-YOY">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="414" height="159"/>
|
<rect key="frame" x="0.0" y="0.0" width="414" height="160"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="23o-MP-wQY">
|
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="23o-MP-wQY">
|
||||||
|
|
@ -1586,6 +1522,14 @@ Cgo
|
||||||
</constraints>
|
</constraints>
|
||||||
</tableViewCellContentView>
|
</tableViewCellContentView>
|
||||||
</tableViewCell>
|
</tableViewCell>
|
||||||
|
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" id="jXO-n0-Mvx">
|
||||||
|
<rect key="frame" x="0.0" y="404" width="414" height="44"/>
|
||||||
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="jXO-n0-Mvx" id="AIL-mq-u7n">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="414" height="44"/>
|
||||||
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
|
</tableViewCellContentView>
|
||||||
|
</tableViewCell>
|
||||||
</cells>
|
</cells>
|
||||||
</tableViewSection>
|
</tableViewSection>
|
||||||
</sections>
|
</sections>
|
||||||
|
|
@ -1603,7 +1547,8 @@ Cgo
|
||||||
</navigationItem>
|
</navigationItem>
|
||||||
<connections>
|
<connections>
|
||||||
<outlet property="armorPrivateKeyTextView" destination="23o-MP-wQY" id="ybK-Ba-vJt"/>
|
<outlet property="armorPrivateKeyTextView" destination="23o-MP-wQY" id="ybK-Ba-vJt"/>
|
||||||
<outlet property="armorPublicKeyTextView" destination="Y9t-DD-6uH" id="307-xN-QZ9"/>
|
<outlet property="scanPrivateKeyCell" destination="jXO-n0-Mvx" id="Zdb-wm-7Ls"/>
|
||||||
|
<segue destination="lLV-kB-JkG" kind="show" identifier="showSSHScannerSegue" id="orz-gu-cTp"/>
|
||||||
</connections>
|
</connections>
|
||||||
</tableViewController>
|
</tableViewController>
|
||||||
<placeholder placeholderIdentifier="IBFirstResponder" id="qJO-AN-K9p" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
<placeholder placeholderIdentifier="IBFirstResponder" id="qJO-AN-K9p" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||||
|
|
@ -1625,7 +1570,7 @@ Cgo
|
||||||
<rect key="frame" x="0.0" y="35" width="414" height="52"/>
|
<rect key="frame" x="0.0" y="35" width="414" height="52"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="4Bh-1D-w5T" id="mIL-ig-tbp">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="4Bh-1D-w5T" id="mIL-ig-tbp">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="414" height="51"/>
|
<rect key="frame" x="0.0" y="0.0" width="414" height="52"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Name" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Hlb-Zh-ega">
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Name" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Hlb-Zh-ega">
|
||||||
|
|
@ -1658,7 +1603,7 @@ Cgo
|
||||||
<rect key="frame" x="0.0" y="87" width="414" height="52"/>
|
<rect key="frame" x="0.0" y="87" width="414" height="52"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="JRY-pY-XtS" id="KrQ-Ih-dk8">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="JRY-pY-XtS" id="KrQ-Ih-dk8">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="414" height="51"/>
|
<rect key="frame" x="0.0" y="0.0" width="414" height="52"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Email" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="m25-Qy-XwU">
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Email" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="m25-Qy-XwU">
|
||||||
|
|
@ -1735,7 +1680,7 @@ Cgo
|
||||||
</objects>
|
</objects>
|
||||||
<point key="canvasLocation" x="4967" y="5333"/>
|
<point key="canvasLocation" x="4967" y="5333"/>
|
||||||
</scene>
|
</scene>
|
||||||
<!--Scanner-->
|
<!--Scan PGP Keys-->
|
||||||
<scene sceneID="7j1-Qg-pUZ">
|
<scene sceneID="7j1-Qg-pUZ">
|
||||||
<objects>
|
<objects>
|
||||||
<viewController id="LZE-gF-IcM" customClass="QRScannerController" customModule="pass" customModuleProvider="target" sceneMemberID="viewController">
|
<viewController id="LZE-gF-IcM" customClass="QRScannerController" customModule="pass" customModuleProvider="target" sceneMemberID="viewController">
|
||||||
|
|
@ -1765,7 +1710,7 @@ Cgo
|
||||||
<constraint firstItem="53A-gx-tky" firstAttribute="top" secondItem="U8O-Md-w8e" secondAttribute="bottom" constant="80" id="tzL-K0-lE7"/>
|
<constraint firstItem="53A-gx-tky" firstAttribute="top" secondItem="U8O-Md-w8e" secondAttribute="bottom" constant="80" id="tzL-K0-lE7"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
</view>
|
</view>
|
||||||
<navigationItem key="navigationItem" title="Scanner" id="JIs-3z-Tmr">
|
<navigationItem key="navigationItem" title="Scan PGP Keys" id="JIs-3z-Tmr">
|
||||||
<barButtonItem key="leftBarButtonItem" systemItem="cancel" id="yma-o8-xRu">
|
<barButtonItem key="leftBarButtonItem" systemItem="cancel" id="yma-o8-xRu">
|
||||||
<connections>
|
<connections>
|
||||||
<segue destination="0F8-Zv-c2C" kind="unwind" unwindAction="cancelPGPScannerWithSegue:" id="q14-fu-3N4"/>
|
<segue destination="0F8-Zv-c2C" kind="unwind" unwindAction="cancelPGPScannerWithSegue:" id="q14-fu-3N4"/>
|
||||||
|
|
@ -1781,6 +1726,52 @@ Cgo
|
||||||
</objects>
|
</objects>
|
||||||
<point key="canvasLocation" x="6122" y="4302"/>
|
<point key="canvasLocation" x="6122" y="4302"/>
|
||||||
</scene>
|
</scene>
|
||||||
|
<!--Scan SSH Keys-->
|
||||||
|
<scene sceneID="kmR-CX-Yi7">
|
||||||
|
<objects>
|
||||||
|
<viewController id="lLV-kB-JkG" customClass="QRScannerController" customModule="pass" customModuleProvider="target" sceneMemberID="viewController">
|
||||||
|
<layoutGuides>
|
||||||
|
<viewControllerLayoutGuide type="top" id="NSI-Fp-tX4"/>
|
||||||
|
<viewControllerLayoutGuide type="bottom" id="QZv-Im-xZk"/>
|
||||||
|
</layoutGuides>
|
||||||
|
<view key="view" contentMode="scaleToFill" id="GYE-sh-yvu">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="414" height="736"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
|
<subviews>
|
||||||
|
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="scanner output" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="fsL-pq-A5q">
|
||||||
|
<rect key="frame" x="50" y="567" width="314" height="45"/>
|
||||||
|
<color key="backgroundColor" red="1" green="1" blue="1" alpha="0.5" colorSpace="calibratedRGB"/>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstAttribute="height" constant="45" id="IPT-kM-arz"/>
|
||||||
|
</constraints>
|
||||||
|
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||||
|
<nil key="textColor"/>
|
||||||
|
<nil key="highlightedColor"/>
|
||||||
|
</label>
|
||||||
|
</subviews>
|
||||||
|
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstItem="QZv-Im-xZk" firstAttribute="top" secondItem="fsL-pq-A5q" secondAttribute="bottom" constant="80" id="76J-7g-eVO"/>
|
||||||
|
<constraint firstItem="fsL-pq-A5q" firstAttribute="leading" secondItem="GYE-sh-yvu" secondAttribute="leadingMargin" constant="30" id="IOo-JD-FMG"/>
|
||||||
|
<constraint firstAttribute="trailingMargin" secondItem="fsL-pq-A5q" secondAttribute="trailing" constant="30" id="ymC-G4-bdA"/>
|
||||||
|
</constraints>
|
||||||
|
</view>
|
||||||
|
<navigationItem key="navigationItem" title="Scan SSH Keys" id="bov-FI-Hkg">
|
||||||
|
<barButtonItem key="leftBarButtonItem" systemItem="cancel" id="JhH-TO-YkO">
|
||||||
|
<connections>
|
||||||
|
<segue destination="J2S-Mr-s10" kind="unwind" unwindAction="cancelSSHScannerWithSegue:" id="Thj-zj-TEX"/>
|
||||||
|
</connections>
|
||||||
|
</barButtonItem>
|
||||||
|
</navigationItem>
|
||||||
|
<connections>
|
||||||
|
<outlet property="scannerOutput" destination="fsL-pq-A5q" id="lSv-2S-qVd"/>
|
||||||
|
</connections>
|
||||||
|
</viewController>
|
||||||
|
<placeholder placeholderIdentifier="IBFirstResponder" id="s1p-jn-4PV" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||||
|
<exit id="J2S-Mr-s10" userLabel="Exit" sceneMemberID="exit"/>
|
||||||
|
</objects>
|
||||||
|
<point key="canvasLocation" x="7133" y="2895"/>
|
||||||
|
</scene>
|
||||||
</scenes>
|
</scenes>
|
||||||
<resources>
|
<resources>
|
||||||
<image name="Lock" width="25" height="25"/>
|
<image name="Lock" width="25" height="25"/>
|
||||||
|
|
|
||||||
|
|
@ -51,8 +51,15 @@ class AboutRepositoryTableViewController: BasicStaticTableViewController {
|
||||||
|
|
||||||
let numberOfPasswordsString = numberFormatter.string(from: NSNumber(value: self.passwordStore.numberOfPasswords))!
|
let numberOfPasswordsString = numberFormatter.string(from: NSNumber(value: self.passwordStore.numberOfPasswords))!
|
||||||
let sizeOfRepositoryString = ByteCountFormatter.string(fromByteCount: Int64(self.passwordStore.sizeOfRepositoryByteCount), countStyle: ByteCountFormatter.CountStyle.file)
|
let sizeOfRepositoryString = ByteCountFormatter.string(fromByteCount: Int64(self.passwordStore.sizeOfRepositoryByteCount), countStyle: ByteCountFormatter.CountStyle.file)
|
||||||
|
var numberOfCommits: UInt = 0
|
||||||
|
|
||||||
let numberOfCommits = self.passwordStore.storeRepository?.numberOfCommits(inCurrentBranch: NSErrorPointer(nilLiteral: ())) ?? 0
|
do {
|
||||||
|
if let _ = try self.passwordStore.storeRepository?.currentBranch().oid {
|
||||||
|
numberOfCommits = self.passwordStore.storeRepository?.numberOfCommits(inCurrentBranch: NSErrorPointer(nilLiteral: ())) ?? 0
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
print(error)
|
||||||
|
}
|
||||||
let numberOfCommitsString = numberFormatter.string(from: NSNumber(value: numberOfCommits))!
|
let numberOfCommitsString = numberFormatter.string(from: NSNumber(value: numberOfCommits))!
|
||||||
|
|
||||||
DispatchQueue.main.async { [weak self] in
|
DispatchQueue.main.async { [weak self] in
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ class AboutTableViewController: BasicStaticTableViewController {
|
||||||
// section 0
|
// section 0
|
||||||
[[.title: "Website", .action: "link", .link: "https://github.com/mssun/pass-ios.git"],
|
[[.title: "Website", .action: "link", .link: "https://github.com/mssun/pass-ios.git"],
|
||||||
[.title: "Help", .action: "link", .link: "https://github.com/mssun/passforios/wiki"],
|
[.title: "Help", .action: "link", .link: "https://github.com/mssun/passforios/wiki"],
|
||||||
[.title: "Contact Developer", .action: "link", .link: "mailto:bob@mssun.me?subject=passforiOS"],],
|
[.title: "Contact Developer", .action: "link", .link: "mailto:developer@passforios.mssun.me?subject=Pass%20for%20iOS"],],
|
||||||
|
|
||||||
// section 1,
|
// section 1,
|
||||||
[[.title: "Open Source Components", .action: "segue", .link: "showOpenSourceComponentsSegue"],
|
[[.title: "Open Source Components", .action: "segue", .link: "showOpenSourceComponentsSegue"],
|
||||||
|
|
|
||||||
|
|
@ -16,11 +16,14 @@ class AddPasswordTableViewController: PasswordEditorTableViewController {
|
||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
tableData = [
|
tableData = [
|
||||||
[[.type: PasswordEditorCellType.nameCell, .title: "name"]],
|
[[.type: PasswordEditorCellType.nameCell, .title: "name"]],
|
||||||
[[.type: PasswordEditorCellType.fillPasswordCell, .title: "password"],
|
[[.type: PasswordEditorCellType.fillPasswordCell, .title: "password"]],
|
||||||
[.type: PasswordEditorCellType.passwordLengthCell, .title: "passwordlength"]],
|
|
||||||
[[.type: PasswordEditorCellType.additionsCell, .title: "additions"]],
|
[[.type: PasswordEditorCellType.additionsCell, .title: "additions"]],
|
||||||
[[.type: PasswordEditorCellType.scanQRCodeCell]]
|
[[.type: PasswordEditorCellType.scanQRCodeCell]]
|
||||||
]
|
]
|
||||||
|
if let lengthSetting = Globals.passwordDefaultLength[Defaults[.passwordGeneratorFlavor]],
|
||||||
|
lengthSetting.max > lengthSetting.min {
|
||||||
|
tableData[1].append([.type: PasswordEditorCellType.passwordLengthCell, .title: "passwordlength"])
|
||||||
|
}
|
||||||
super.viewDidLoad()
|
super.viewDidLoad()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,17 +7,21 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
import SwiftyUserDefaults
|
||||||
|
|
||||||
class EditPasswordTableViewController: PasswordEditorTableViewController {
|
class EditPasswordTableViewController: PasswordEditorTableViewController {
|
||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
tableData = [
|
tableData = [
|
||||||
[[.type: PasswordEditorCellType.nameCell, .title: "name", .content: password!.namePath]],
|
[[.type: PasswordEditorCellType.nameCell, .title: "name", .content: password!.namePath]],
|
||||||
[[.type: PasswordEditorCellType.fillPasswordCell, .title: "password", .content: password!.password],
|
[[.type: PasswordEditorCellType.fillPasswordCell, .title: "password", .content: password!.password]],
|
||||||
[.type: PasswordEditorCellType.passwordLengthCell, .title: "passwordlength"]],
|
|
||||||
[[.type: PasswordEditorCellType.additionsCell, .title: "additions", .content: password!.getAdditionsPlainText()]],
|
[[.type: PasswordEditorCellType.additionsCell, .title: "additions", .content: password!.getAdditionsPlainText()]],
|
||||||
[[.type: PasswordEditorCellType.scanQRCodeCell],
|
[[.type: PasswordEditorCellType.scanQRCodeCell],
|
||||||
[.type: PasswordEditorCellType.deletePasswordCell]]
|
[.type: PasswordEditorCellType.deletePasswordCell]]
|
||||||
]
|
]
|
||||||
|
if let lengthSetting = Globals.passwordDefaultLength[Defaults[.passwordGeneratorFlavor]],
|
||||||
|
lengthSetting.max > lengthSetting.min {
|
||||||
|
tableData[1].append([.type: PasswordEditorCellType.passwordLengthCell, .title: "passwordlength"])
|
||||||
|
}
|
||||||
super.viewDidLoad()
|
super.viewDidLoad()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ struct GitCredential {
|
||||||
|
|
||||||
enum Credential {
|
enum Credential {
|
||||||
case http(userName: String, controller: UIViewController)
|
case http(userName: String, controller: UIViewController)
|
||||||
case ssh(userName: String, publicKeyFile: URL, privateKeyFile: URL, controller: UIViewController)
|
case ssh(userName: String, privateKeyFile: URL, controller: UIViewController)
|
||||||
}
|
}
|
||||||
|
|
||||||
init(credential: Credential) {
|
init(credential: Credential) {
|
||||||
|
|
@ -44,7 +44,7 @@ struct GitCredential {
|
||||||
attempts += 1
|
attempts += 1
|
||||||
lastPassword = newPassword
|
lastPassword = newPassword
|
||||||
credential = try? GTCredential(userName: userName, password: newPassword!)
|
credential = try? GTCredential(userName: userName, password: newPassword!)
|
||||||
case let .ssh(userName, publicKeyFile, privateKeyFile, controller):
|
case let .ssh(userName, privateKeyFile, controller):
|
||||||
var newPassword = Utils.getPasswordFromKeychain(name: "gitSSHKeyPassphrase")
|
var newPassword = Utils.getPasswordFromKeychain(name: "gitSSHKeyPassphrase")
|
||||||
if newPassword == nil || attempts != 0 {
|
if newPassword == nil || attempts != 0 {
|
||||||
if let requestedPassword = self.requestGitPassword(controller, lastPassword) {
|
if let requestedPassword = self.requestGitPassword(controller, lastPassword) {
|
||||||
|
|
@ -56,7 +56,8 @@ struct GitCredential {
|
||||||
}
|
}
|
||||||
attempts += 1
|
attempts += 1
|
||||||
lastPassword = newPassword
|
lastPassword = newPassword
|
||||||
credential = try? GTCredential(userName: userName, publicKeyURL: publicKeyFile, privateKeyURL: privateKeyFile, passphrase: newPassword!)
|
credential = try? GTCredential(userName: userName, publicKeyURL: nil, privateKeyURL: privateKeyFile, passphrase: newPassword!)
|
||||||
|
print(privateKeyFile)
|
||||||
}
|
}
|
||||||
return credential
|
return credential
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,27 +9,82 @@
|
||||||
import UIKit
|
import UIKit
|
||||||
import SwiftyUserDefaults
|
import SwiftyUserDefaults
|
||||||
|
|
||||||
class GitSSHKeyArmorSettingTableViewController: UITableViewController, UITextViewDelegate {
|
class GitSSHKeyArmorSettingTableViewController: UITableViewController, UITextViewDelegate, QRScannerControllerDelegate {
|
||||||
@IBOutlet weak var armorPublicKeyTextView: UITextView!
|
|
||||||
@IBOutlet weak var armorPrivateKeyTextView: UITextView!
|
@IBOutlet weak var armorPrivateKeyTextView: UITextView!
|
||||||
|
@IBOutlet weak var scanPrivateKeyCell: UITableViewCell!
|
||||||
|
|
||||||
var gitSSHPrivateKeyPassphrase: String?
|
var gitSSHPrivateKeyPassphrase: String?
|
||||||
let passwordStore = PasswordStore.shared
|
let passwordStore = PasswordStore.shared
|
||||||
|
|
||||||
private var recentPastedText = ""
|
private var recentPastedText = ""
|
||||||
|
|
||||||
|
class ScannedSSHKey {
|
||||||
|
static let maxNumberOfGif = 100
|
||||||
|
var numberOfSegments = 0
|
||||||
|
var previousSegment = ""
|
||||||
|
var key = ""
|
||||||
|
var message = ""
|
||||||
|
var hasStarted = false
|
||||||
|
var isDone = false
|
||||||
|
|
||||||
|
func reset() {
|
||||||
|
numberOfSegments = 0
|
||||||
|
previousSegment = ""
|
||||||
|
key = ""
|
||||||
|
message = "Looking for the starting frame."
|
||||||
|
hasStarted = false
|
||||||
|
isDone = false
|
||||||
|
}
|
||||||
|
|
||||||
|
func addSegment(segment: String) {
|
||||||
|
// skip duplicated segments
|
||||||
|
guard segment != previousSegment else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
previousSegment = segment
|
||||||
|
|
||||||
|
// check whether we have found the first block
|
||||||
|
if hasStarted == false {
|
||||||
|
hasStarted = segment.contains("-----BEGIN")
|
||||||
|
}
|
||||||
|
guard hasStarted == true else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// check the number of segments
|
||||||
|
numberOfSegments = numberOfSegments + 1
|
||||||
|
guard numberOfSegments <= ScannedSSHKey.maxNumberOfGif else {
|
||||||
|
key = "Too many QR codes"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// update full text and check whether we are done
|
||||||
|
key.append(segment)
|
||||||
|
if let index1 = key.range(of: "-----END")?.lowerBound,
|
||||||
|
let _ = key.substring(from: index1).range(of: "KEY-----")?.lowerBound {
|
||||||
|
isDone = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// update message
|
||||||
|
message = "\(numberOfSegments) scanned QR codes."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var scanned = ScannedSSHKey()
|
||||||
|
|
||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
super.viewDidLoad()
|
super.viewDidLoad()
|
||||||
armorPublicKeyTextView.text = Defaults[.gitSSHPublicKeyArmor]
|
|
||||||
armorPrivateKeyTextView.text = Defaults[.gitSSHPrivateKeyArmor]
|
armorPrivateKeyTextView.text = Defaults[.gitSSHPrivateKeyArmor]
|
||||||
armorPublicKeyTextView.delegate = self
|
|
||||||
armorPrivateKeyTextView.delegate = self
|
armorPrivateKeyTextView.delegate = self
|
||||||
|
|
||||||
|
scanPrivateKeyCell?.textLabel?.text = "Scan Private Key QR Codes"
|
||||||
|
scanPrivateKeyCell?.textLabel?.textColor = Globals.blue
|
||||||
|
scanPrivateKeyCell?.selectionStyle = .default
|
||||||
|
scanPrivateKeyCell?.accessoryType = .disclosureIndicator
|
||||||
}
|
}
|
||||||
|
|
||||||
@IBAction func doneButtonTapped(_ sender: Any) {
|
@IBAction func doneButtonTapped(_ sender: Any) {
|
||||||
Defaults[.gitSSHPublicKeyArmor] = armorPublicKeyTextView.text
|
|
||||||
Defaults[.gitSSHPrivateKeyArmor] = armorPrivateKeyTextView.text
|
Defaults[.gitSSHPrivateKeyArmor] = armorPrivateKeyTextView.text
|
||||||
do {
|
do {
|
||||||
try passwordStore.initGitSSHKey(with: armorPublicKeyTextView.text, .public)
|
|
||||||
try passwordStore.initGitSSHKey(with: armorPrivateKeyTextView.text, .secret)
|
try passwordStore.initGitSSHKey(with: armorPrivateKeyTextView.text, .secret)
|
||||||
} catch {
|
} catch {
|
||||||
Utils.alert(title: "Cannot Save", message: "Cannot Save SSH Key", controller: self, completion: nil)
|
Utils.alert(title: "Cannot Save", message: "Cannot Save SSH Key", controller: self, completion: nil)
|
||||||
|
|
@ -51,4 +106,46 @@ class GitSSHKeyArmorSettingTableViewController: UITableViewController, UITextVie
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||||
|
let selectedCell = tableView.cellForRow(at: indexPath)
|
||||||
|
if selectedCell == scanPrivateKeyCell {
|
||||||
|
scanned.reset()
|
||||||
|
self.performSegue(withIdentifier: "showSSHScannerSegue", sender: self)
|
||||||
|
}
|
||||||
|
tableView.deselectRow(at: indexPath, animated: true)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: - QRScannerControllerDelegate Methods
|
||||||
|
func checkScannedOutput(line: String) -> (accept: Bool, message: String) {
|
||||||
|
scanned.addSegment(segment: line)
|
||||||
|
if scanned.isDone {
|
||||||
|
return (accept: true, message: "Done")
|
||||||
|
} else {
|
||||||
|
return (accept: false, message: scanned.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - QRScannerControllerDelegate Methods
|
||||||
|
func handleScannedOutput(line: String) {
|
||||||
|
armorPrivateKeyTextView.text = scanned.key
|
||||||
|
}
|
||||||
|
|
||||||
|
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
|
||||||
|
if segue.identifier == "showSSHScannerSegue" {
|
||||||
|
if let navController = segue.destination as? UINavigationController {
|
||||||
|
if let viewController = navController.topViewController as? QRScannerController {
|
||||||
|
viewController.delegate = self
|
||||||
|
}
|
||||||
|
} else if let viewController = segue.destination as? QRScannerController {
|
||||||
|
viewController.delegate = self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@IBAction private func cancelSSHScanner(segue: UIStoryboardSegue) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,9 +40,9 @@ class GitServerSettingTableViewController: UITableViewController {
|
||||||
|
|
||||||
override func viewWillAppear(_ animated: Bool) {
|
override func viewWillAppear(_ animated: Bool) {
|
||||||
super.viewWillAppear(animated)
|
super.viewWillAppear(animated)
|
||||||
// Grey out ssh option if ssh_key and ssh_key.pub are not present
|
// Grey out ssh option if ssh_key is not present
|
||||||
if let sshLabel = sshLabel {
|
if let sshLabel = sshLabel {
|
||||||
sshLabel.isEnabled = gitSSHKeyExists()
|
sshLabel.isEnabled = passwordStore.gitSSHKeyExists()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
|
|
@ -73,15 +73,56 @@ class GitServerSettingTableViewController: UITableViewController {
|
||||||
view.endEditing(true)
|
view.endEditing(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool {
|
private func cloneAndSegueIfSuccess() {
|
||||||
if identifier == "saveGitServerSettingSegue" {
|
// try to clone
|
||||||
guard let _ = URL(string: gitURLTextField.text!) else {
|
let gitRepostiroyURL = gitURLTextField.text!
|
||||||
Utils.alert(title: "Cannot Save", message: "Git Server is not set.", controller: self, completion: nil)
|
let username = usernameTextField.text!
|
||||||
return false
|
let auth = authenticationMethod
|
||||||
|
|
||||||
|
SVProgressHUD.setDefaultMaskType(.black)
|
||||||
|
SVProgressHUD.setDefaultStyle(.light)
|
||||||
|
SVProgressHUD.show(withStatus: "Prepare Repository")
|
||||||
|
var gitCredential: GitCredential
|
||||||
|
if auth == "Password" {
|
||||||
|
gitCredential = GitCredential(credential: GitCredential.Credential.http(userName: username, controller: self))
|
||||||
|
} else {
|
||||||
|
gitCredential = GitCredential(
|
||||||
|
credential: GitCredential.Credential.ssh(
|
||||||
|
userName: username,
|
||||||
|
privateKeyFile: Globals.gitSSHPrivateKeyURL,
|
||||||
|
controller: self
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
let dispatchQueue = DispatchQueue.global(qos: .userInitiated)
|
||||||
|
dispatchQueue.async {
|
||||||
|
do {
|
||||||
|
try self.passwordStore.cloneRepository(remoteRepoURL: URL(string: gitRepostiroyURL)!,
|
||||||
|
credential: gitCredential,
|
||||||
|
transferProgressBlock: { (git_transfer_progress, stop) in
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
SVProgressHUD.showProgress(Float(git_transfer_progress.pointee.received_objects)/Float(git_transfer_progress.pointee.total_objects), status: "Clone Remote Repository")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
checkoutProgressBlock: { (path, completedSteps, totalSteps) in
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
SVProgressHUD.showProgress(Float(completedSteps)/Float(totalSteps), status: "Checkout Master Branch")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
Defaults[.gitURL] = URL(string: gitRepostiroyURL)
|
||||||
|
Defaults[.gitUsername] = username
|
||||||
|
Defaults[.gitAuthenticationMethod] = auth
|
||||||
|
SVProgressHUD.showSuccess(withStatus: "Done")
|
||||||
|
SVProgressHUD.dismiss(withDelay: 1)
|
||||||
|
self.performSegue(withIdentifier: "saveGitServerSettingSegue", sender: self)
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
Utils.alert(title: "Error", message: error.localizedDescription, controller: self, completion: nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true
|
} }
|
||||||
}
|
|
||||||
|
|
||||||
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||||
let cell = tableView.cellForRow(at: indexPath)
|
let cell = tableView.cellForRow(at: indexPath)
|
||||||
|
|
@ -89,7 +130,7 @@ class GitServerSettingTableViewController: UITableViewController {
|
||||||
authenticationMethod = "Password"
|
authenticationMethod = "Password"
|
||||||
} else if cell == authSSHKeyCell {
|
} else if cell == authSSHKeyCell {
|
||||||
|
|
||||||
if !gitSSHKeyExists() {
|
if !passwordStore.gitSSHKeyExists() {
|
||||||
Utils.alert(title: "Cannot Select SSH Key", message: "Please setup SSH key first.", controller: self, completion: nil)
|
Utils.alert(title: "Cannot Select SSH Key", message: "Please setup SSH key first.", controller: self, completion: nil)
|
||||||
authenticationMethod = "Password"
|
authenticationMethod = "Password"
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -100,35 +141,31 @@ class GitServerSettingTableViewController: UITableViewController {
|
||||||
tableView.deselectRow(at: indexPath, animated: true)
|
tableView.deselectRow(at: indexPath, animated: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func doClone() {
|
@IBAction func save(_ sender: Any) {
|
||||||
if self.shouldPerformSegue(withIdentifier: "saveGitServerSettingSegue", sender: self) {
|
guard let _ = URL(string: gitURLTextField.text!) else {
|
||||||
self.performSegue(withIdentifier: "saveGitServerSettingSegue", sender: self)
|
Utils.alert(title: "Cannot Save", message: "Git Server is not set.", controller: self, completion: nil)
|
||||||
}
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@IBAction func save(_ sender: Any) {
|
|
||||||
if passwordStore.repositoryExisted() {
|
if passwordStore.repositoryExisted() {
|
||||||
let alert = UIAlertController(title: "Erase Current Password Store Data?", message: "A cloned password store exists. This operation will erase all local data. Data on your remote server will not be affected.", preferredStyle: UIAlertControllerStyle.alert)
|
let alert = UIAlertController(title: "Erase Current Password Store Data?", message: "A cloned password store exists. This operation will erase all local data. Data on your remote server will not be affected.", preferredStyle: UIAlertControllerStyle.alert)
|
||||||
alert.addAction(UIAlertAction(title: "Erase", style: UIAlertActionStyle.destructive, handler: { _ in
|
alert.addAction(UIAlertAction(title: "Erase", style: UIAlertActionStyle.destructive, handler: { _ in
|
||||||
self.doClone()
|
// perform segue only after a successful clone
|
||||||
|
self.cloneAndSegueIfSuccess()
|
||||||
}))
|
}))
|
||||||
alert.addAction(UIAlertAction(title: "Cancel", style: UIAlertActionStyle.cancel, handler: nil))
|
alert.addAction(UIAlertAction(title: "Cancel", style: UIAlertActionStyle.cancel, handler: nil))
|
||||||
self.present(alert, animated: true, completion: nil)
|
self.present(alert, animated: true, completion: nil)
|
||||||
} else {
|
} else {
|
||||||
doClone()
|
// perform segue only after a successful clone
|
||||||
|
cloneAndSegueIfSuccess()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func gitSSHKeyExists() -> Bool {
|
|
||||||
return FileManager.default.fileExists(atPath: Globals.gitSSHPublicKeyPath) &&
|
|
||||||
FileManager.default.fileExists(atPath: Globals.gitSSHPrivateKeyPath)
|
|
||||||
}
|
|
||||||
|
|
||||||
func showSSHKeyActionSheet() {
|
func showSSHKeyActionSheet() {
|
||||||
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"
|
||||||
var armorActionTitle = "ASCII-Armor Encrypted Key"
|
var armorActionTitle = "ASCII-Armor Encrypted Key"
|
||||||
var fileActionTitle = "Use Uploaded Keys"
|
var fileActionTitle = "Use Imported Keys"
|
||||||
|
|
||||||
if Defaults[.gitSSHKeySource] == "url" {
|
if Defaults[.gitSSHKeySource] == "url" {
|
||||||
urlActionTitle = "✓ \(urlActionTitle)"
|
urlActionTitle = "✓ \(urlActionTitle)"
|
||||||
|
|
@ -147,16 +184,24 @@ class GitServerSettingTableViewController: UITableViewController {
|
||||||
optionMenu.addAction(urlAction)
|
optionMenu.addAction(urlAction)
|
||||||
optionMenu.addAction(armorAction)
|
optionMenu.addAction(armorAction)
|
||||||
|
|
||||||
if (gitSSHKeyExists()) {
|
if passwordStore.gitSSHKeyExists() {
|
||||||
|
// might keys updated via iTunes, or downloaded/pasted inside the app
|
||||||
let fileAction = UIAlertAction(title: fileActionTitle, style: .default) { _ in
|
let fileAction = UIAlertAction(title: fileActionTitle, style: .default) { _ in
|
||||||
Defaults[.gitSSHKeySource] = "file"
|
Defaults[.gitSSHKeySource] = "file"
|
||||||
}
|
}
|
||||||
optionMenu.addAction(fileAction)
|
optionMenu.addAction(fileAction)
|
||||||
|
} else {
|
||||||
|
let fileAction = UIAlertAction(title: "iTunes File Sharing", style: .default) { _ in
|
||||||
|
let title = "Import via iTunes File Sharing"
|
||||||
|
let message = "Copy your private key from your computer to Pass for iOS with the name \"ssh_key\" (without quotes)."
|
||||||
|
Utils.alert(title: title, message: message, controller: self)
|
||||||
|
}
|
||||||
|
optionMenu.addAction(fileAction)
|
||||||
}
|
}
|
||||||
|
|
||||||
if Defaults[.gitSSHKeySource] != nil {
|
if Defaults[.gitSSHKeySource] != nil {
|
||||||
let deleteAction = UIAlertAction(title: "Remove Git SSH Keys", style: .destructive) { _ in
|
let deleteAction = UIAlertAction(title: "Remove Git SSH Keys", style: .destructive) { _ in
|
||||||
Utils.removeGitSSHKeys()
|
self.passwordStore.removeGitSSHKeys()
|
||||||
Defaults[.gitSSHKeySource] = nil
|
Defaults[.gitSSHKeySource] = nil
|
||||||
if let sshLabel = self.sshLabel {
|
if let sshLabel = self.sshLabel {
|
||||||
sshLabel.isEnabled = false
|
sshLabel.isEnabled = false
|
||||||
|
|
|
||||||
|
|
@ -107,20 +107,6 @@ class PGPKeyArmorSettingTableViewController: UITableViewController, UITextViewDe
|
||||||
scanPrivateKeyCell?.accessoryType = .disclosureIndicator
|
scanPrivateKeyCell?.accessoryType = .disclosureIndicator
|
||||||
}
|
}
|
||||||
|
|
||||||
private func createSavePassphraseAndSegueAlert() -> UIAlertController {
|
|
||||||
let savePassphraseAlert = UIAlertController(title: "Passphrase", message: "Do you want to save the passphrase for later decryption?", preferredStyle: UIAlertControllerStyle.alert)
|
|
||||||
savePassphraseAlert.addAction(UIAlertAction(title: "No", style: UIAlertActionStyle.default) { _ in
|
|
||||||
Defaults[.isRememberPassphraseOn] = false
|
|
||||||
self.pgpPassphrase = nil
|
|
||||||
self.performSegue(withIdentifier: "savePGPKeySegue", sender: self)
|
|
||||||
})
|
|
||||||
savePassphraseAlert.addAction(UIAlertAction(title: "Save", style: UIAlertActionStyle.destructive) {_ in
|
|
||||||
Defaults[.isRememberPassphraseOn] = true
|
|
||||||
self.performSegue(withIdentifier: "savePGPKeySegue", sender: self)
|
|
||||||
})
|
|
||||||
return savePassphraseAlert
|
|
||||||
}
|
|
||||||
|
|
||||||
override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool {
|
override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool {
|
||||||
if identifier == "savePGPKeySegue" {
|
if identifier == "savePGPKeySegue" {
|
||||||
if armorPublicKeyTextView.text.isEmpty {
|
if armorPublicKeyTextView.text.isEmpty {
|
||||||
|
|
@ -136,17 +122,29 @@ class PGPKeyArmorSettingTableViewController: UITableViewController, UITextViewDe
|
||||||
}
|
}
|
||||||
|
|
||||||
@IBAction func save(_ sender: Any) {
|
@IBAction func save(_ sender: Any) {
|
||||||
|
let savePassphraseAlert = UIAlertController(title: "Passphrase", message: "Do you want to save the passphrase for later decryption?", preferredStyle: UIAlertControllerStyle.alert)
|
||||||
|
// no
|
||||||
|
savePassphraseAlert.addAction(UIAlertAction(title: "No", style: UIAlertActionStyle.default) { _ in
|
||||||
|
self.pgpPassphrase = nil
|
||||||
|
Defaults[.isRememberPassphraseOn] = false
|
||||||
|
self.performSegue(withIdentifier: "savePGPKeySegue", sender: self)
|
||||||
|
})
|
||||||
|
// yes
|
||||||
|
savePassphraseAlert.addAction(UIAlertAction(title: "Yes", style: UIAlertActionStyle.destructive) {_ in
|
||||||
|
// ask for the passphrase
|
||||||
let alert = UIAlertController(title: "Passphrase", message: "Please fill in the passphrase of your PGP secret key.", preferredStyle: UIAlertControllerStyle.alert)
|
let alert = UIAlertController(title: "Passphrase", message: "Please fill in the passphrase of your PGP secret key.", preferredStyle: UIAlertControllerStyle.alert)
|
||||||
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: {_ in
|
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: {_ in
|
||||||
self.pgpPassphrase = alert.textFields?.first?.text
|
self.pgpPassphrase = alert.textFields?.first?.text
|
||||||
let savePassphraseAndSegueAlert = self.createSavePassphraseAndSegueAlert()
|
Defaults[.isRememberPassphraseOn] = true
|
||||||
self.present(savePassphraseAndSegueAlert, animated: true, completion: nil)
|
self.performSegue(withIdentifier: "savePGPKeySegue", sender: self)
|
||||||
}))
|
}))
|
||||||
alert.addTextField(configurationHandler: {(textField: UITextField!) in
|
alert.addTextField(configurationHandler: {(textField: UITextField!) in
|
||||||
textField.text = self.pgpPassphrase
|
textField.text = self.pgpPassphrase
|
||||||
textField.isSecureTextEntry = true
|
textField.isSecureTextEntry = true
|
||||||
})
|
})
|
||||||
self.present(alert, animated: true, completion: nil)
|
self.present(alert, animated: true, completion: nil)
|
||||||
|
})
|
||||||
|
self.present(savePassphraseAlert, animated: true, completion: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
|
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
|
||||||
|
|
|
||||||
|
|
@ -24,19 +24,6 @@ class PGPKeySettingTableViewController: UITableViewController {
|
||||||
pgpPassphrase = passwordStore.pgpKeyPassphrase
|
pgpPassphrase = passwordStore.pgpKeyPassphrase
|
||||||
}
|
}
|
||||||
|
|
||||||
private func createSavePassphraseAndSegueAlert() -> UIAlertController {
|
|
||||||
let savePassphraseAlert = UIAlertController(title: "Passphrase", message: "Do you want to save the passphrase for later decryption?", preferredStyle: UIAlertControllerStyle.alert)
|
|
||||||
savePassphraseAlert.addAction(UIAlertAction(title: "No", style: UIAlertActionStyle.default) { _ in
|
|
||||||
Defaults[.isRememberPassphraseOn] = false
|
|
||||||
self.performSegue(withIdentifier: "savePGPKeySegue", sender: self)
|
|
||||||
})
|
|
||||||
savePassphraseAlert.addAction(UIAlertAction(title: "Save", style: UIAlertActionStyle.destructive) {_ in
|
|
||||||
Defaults[.isRememberPassphraseOn] = true
|
|
||||||
self.performSegue(withIdentifier: "savePGPKeySegue", sender: self)
|
|
||||||
})
|
|
||||||
return savePassphraseAlert
|
|
||||||
}
|
|
||||||
|
|
||||||
override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool {
|
override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool {
|
||||||
if identifier == "savePGPKeySegue" {
|
if identifier == "savePGPKeySegue" {
|
||||||
guard validatePGPKeyURL(input: pgpPublicKeyURLTextField.text) == true,
|
guard validatePGPKeyURL(input: pgpPublicKeyURLTextField.text) == true,
|
||||||
|
|
@ -60,16 +47,28 @@ class PGPKeySettingTableViewController: UITableViewController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@IBAction func save(_ sender: Any) {
|
@IBAction func save(_ sender: Any) {
|
||||||
|
let savePassphraseAlert = UIAlertController(title: "Passphrase", message: "Do you want to save the passphrase for later decryption?", preferredStyle: UIAlertControllerStyle.alert)
|
||||||
|
// no
|
||||||
|
savePassphraseAlert.addAction(UIAlertAction(title: "No", style: UIAlertActionStyle.default) { _ in
|
||||||
|
self.pgpPassphrase = nil
|
||||||
|
Defaults[.isRememberPassphraseOn] = false
|
||||||
|
self.performSegue(withIdentifier: "savePGPKeySegue", sender: self)
|
||||||
|
})
|
||||||
|
// yes
|
||||||
|
savePassphraseAlert.addAction(UIAlertAction(title: "Yes", style: UIAlertActionStyle.destructive) {_ in
|
||||||
|
// ask for the passphrase
|
||||||
let alert = UIAlertController(title: "Passphrase", message: "Please fill in the passphrase of your PGP secret key.", preferredStyle: UIAlertControllerStyle.alert)
|
let alert = UIAlertController(title: "Passphrase", message: "Please fill in the passphrase of your PGP secret key.", preferredStyle: UIAlertControllerStyle.alert)
|
||||||
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: {_ in
|
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: {_ in
|
||||||
self.pgpPassphrase = alert.textFields?.first?.text
|
self.pgpPassphrase = alert.textFields?.first?.text
|
||||||
let savePassphraseAndSegueAlert = self.createSavePassphraseAndSegueAlert()
|
Defaults[.isRememberPassphraseOn] = true
|
||||||
self.present(savePassphraseAndSegueAlert, animated: true, completion: nil)
|
self.performSegue(withIdentifier: "savePGPKeySegue", sender: self)
|
||||||
}))
|
}))
|
||||||
alert.addTextField(configurationHandler: {(textField: UITextField!) in
|
alert.addTextField(configurationHandler: {(textField: UITextField!) in
|
||||||
textField.text = self.pgpPassphrase
|
textField.text = self.pgpPassphrase
|
||||||
textField.isSecureTextEntry = true
|
textField.isSecureTextEntry = true
|
||||||
})
|
})
|
||||||
self.present(alert, animated: true, completion: nil)
|
self.present(alert, animated: true, completion: nil)
|
||||||
|
})
|
||||||
|
self.present(savePassphraseAlert, animated: true, completion: nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -101,10 +101,10 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni
|
||||||
NotificationCenter.default.addObserver(self, selector: #selector(setShouldPopCurrentView), name: .passwordStoreChangeDiscarded, object: nil)
|
NotificationCenter.default.addObserver(self, selector: #selector(setShouldPopCurrentView), name: .passwordStoreChangeDiscarded, object: nil)
|
||||||
|
|
||||||
// reset the data table if some password (maybe another one) has been updated
|
// reset the data table if some password (maybe another one) has been updated
|
||||||
NotificationCenter.default.addObserver(self, selector: #selector(showPassword), name: .passwordStoreUpdated, object: nil)
|
NotificationCenter.default.addObserver(self, selector: #selector(decryptThenShowPassword), name: .passwordStoreUpdated, object: nil)
|
||||||
|
|
||||||
// reset the data table if the disaply settings have been changed
|
// reset the data table if the disaply settings have been changed
|
||||||
NotificationCenter.default.addObserver(self, selector: #selector(showPassword), name: .passwordDetailDisplaySettingChanged, object: nil)
|
NotificationCenter.default.addObserver(self, selector: #selector(decryptThenShowPassword), name: .passwordDetailDisplaySettingChanged, object: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
override func viewDidAppear(_ animated: Bool) {
|
override func viewDidAppear(_ animated: Bool) {
|
||||||
|
|
@ -140,19 +140,29 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni
|
||||||
return passphrase
|
return passphrase
|
||||||
}
|
}
|
||||||
|
|
||||||
private func decryptThenShowPassword() {
|
@objc private func decryptThenShowPassword() {
|
||||||
|
guard let passwordEntity = passwordEntity, passwordEntity.path != nil else {
|
||||||
|
Utils.alert(title: "Cannot Show Password", message: "The password does not exist.", controller: self, handler: {(UIAlertAction) -> Void in
|
||||||
|
self.navigationController!.popViewController(animated: true)
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
DispatchQueue.global(qos: .userInitiated).async {
|
DispatchQueue.global(qos: .userInitiated).async {
|
||||||
// decrypt password
|
// decrypt password
|
||||||
do {
|
do {
|
||||||
self.password = try self.passwordStore.decrypt(passwordEntity: self.passwordEntity!, requestPGPKeyPassphrase: self.requestPGPKeyPassphrase)
|
self.password = try self.passwordStore.decrypt(passwordEntity: passwordEntity, requestPGPKeyPassphrase: self.requestPGPKeyPassphrase)
|
||||||
} catch {
|
} catch {
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
// remove the wrong passphrase so that users could enter it next time
|
// remove the wrong passphrase so that users could enter it next time
|
||||||
self.passwordStore.pgpKeyPassphrase = nil
|
self.passwordStore.pgpKeyPassphrase = nil
|
||||||
|
// alert: cancel or try again
|
||||||
let alert = UIAlertController(title: "Cannot Show Password", message: error.localizedDescription, preferredStyle: UIAlertControllerStyle.alert)
|
let alert = UIAlertController(title: "Cannot Show Password", message: error.localizedDescription, preferredStyle: UIAlertControllerStyle.alert)
|
||||||
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: {(UIAlertAction) -> Void in
|
alert.addAction(UIAlertAction(title: "Cancel", style: UIAlertActionStyle.default) { _ in
|
||||||
self.navigationController!.popViewController(animated: true)
|
self.navigationController!.popViewController(animated: true)
|
||||||
}))
|
})
|
||||||
|
alert.addAction(UIAlertAction(title: "Try again", style: UIAlertActionStyle.destructive) {_ in
|
||||||
|
self.decryptThenShowPassword()
|
||||||
|
})
|
||||||
self.present(alert, animated: true, completion: nil)
|
self.present(alert, animated: true, completion: nil)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
|
@ -162,7 +172,7 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc private func showPassword() {
|
private func showPassword() {
|
||||||
DispatchQueue.main.async { [weak self] in
|
DispatchQueue.main.async { [weak self] in
|
||||||
self?.indicator.stopAnimating()
|
self?.indicator.stopAnimating()
|
||||||
self?.setTableData()
|
self?.setTableData()
|
||||||
|
|
|
||||||
|
|
@ -89,6 +89,9 @@ class PasswordEditorTableViewController: UITableViewController, FillPasswordTabl
|
||||||
fillPasswordCell = tableView.dequeueReusableCell(withIdentifier: "fillPasswordCell", for: indexPath) as? FillPasswordTableViewCell
|
fillPasswordCell = tableView.dequeueReusableCell(withIdentifier: "fillPasswordCell", for: indexPath) as? FillPasswordTableViewCell
|
||||||
fillPasswordCell?.delegate = self
|
fillPasswordCell?.delegate = self
|
||||||
fillPasswordCell?.setContent(content: cellData[PasswordEditorCellKey.content] as? String)
|
fillPasswordCell?.setContent(content: cellData[PasswordEditorCellKey.content] as? String)
|
||||||
|
if tableData[passwordSection].count == 1 {
|
||||||
|
fillPasswordCell?.settingButton.isHidden = true
|
||||||
|
}
|
||||||
return fillPasswordCell!
|
return fillPasswordCell!
|
||||||
case .passwordLengthCell:
|
case .passwordLengthCell:
|
||||||
passwordLengthCell = tableView.dequeueReusableCell(withIdentifier: "passwordLengthCell", for: indexPath) as? SliderTableViewCell
|
passwordLengthCell = tableView.dequeueReusableCell(withIdentifier: "passwordLengthCell", for: indexPath) as? SliderTableViewCell
|
||||||
|
|
|
||||||
|
|
@ -145,7 +145,6 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV
|
||||||
gitCredential = GitCredential(
|
gitCredential = GitCredential(
|
||||||
credential: GitCredential.Credential.ssh(
|
credential: GitCredential.Credential.ssh(
|
||||||
userName: Defaults[.gitUsername]!,
|
userName: Defaults[.gitUsername]!,
|
||||||
publicKeyFile: Globals.gitSSHPublicKeyURL,
|
|
||||||
privateKeyFile: Globals.gitSSHPrivateKeyURL,
|
privateKeyFile: Globals.gitSSHPrivateKeyURL,
|
||||||
controller: self
|
controller: self
|
||||||
)
|
)
|
||||||
|
|
@ -535,7 +534,9 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV
|
||||||
self.tapTabBarTime = currentTime
|
self.tapTabBarTime = currentTime
|
||||||
if duration < 0.35 {
|
if duration < 0.35 {
|
||||||
let topIndexPath = IndexPath(row: 0, section: 0)
|
let topIndexPath = IndexPath(row: 0, section: 0)
|
||||||
|
if let _ = tableView.cellForRow(at: topIndexPath) {
|
||||||
tableView.scrollToRow(at: topIndexPath, at: .bottom, animated: true)
|
tableView.scrollToRow(at: topIndexPath, at: .bottom, animated: true)
|
||||||
|
}
|
||||||
self.tapTabBarTime = 0
|
self.tapTabBarTime = 0
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,31 +13,23 @@ import SVProgressHUD
|
||||||
class SSHKeySettingTableViewController: UITableViewController {
|
class SSHKeySettingTableViewController: UITableViewController {
|
||||||
|
|
||||||
@IBOutlet weak var privateKeyURLTextField: UITextField!
|
@IBOutlet weak var privateKeyURLTextField: UITextField!
|
||||||
@IBOutlet weak var publicKeyURLTextField: UITextField!
|
|
||||||
let passwordStore = PasswordStore.shared
|
let passwordStore = PasswordStore.shared
|
||||||
|
|
||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
super.viewDidLoad()
|
super.viewDidLoad()
|
||||||
privateKeyURLTextField.text = Defaults[.gitSSHPrivateKeyURL]?.absoluteString
|
privateKeyURLTextField.text = Defaults[.gitSSHPrivateKeyURL]?.absoluteString
|
||||||
publicKeyURLTextField.text = Defaults[.gitSSHPublicKeyURL]?.absoluteString
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@IBAction func doneButtonTapped(_ sender: UIButton) {
|
@IBAction func doneButtonTapped(_ sender: UIButton) {
|
||||||
guard let publicKeyURL = URL(string: publicKeyURLTextField.text!) else {
|
|
||||||
Utils.alert(title: "Cannot Save", message: "Please set Public Key URL first.", controller: self, completion: nil)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
guard let privateKeyURL = URL(string: privateKeyURLTextField.text!) else {
|
guard let privateKeyURL = URL(string: privateKeyURLTextField.text!) else {
|
||||||
Utils.alert(title: "Cannot Save", message: "Please set Private Key URL first.", controller: self, completion: nil)
|
Utils.alert(title: "Cannot Save", message: "Please set Private Key URL first.", controller: self, completion: nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
Defaults[.gitSSHPublicKeyURL] = publicKeyURL
|
|
||||||
Defaults[.gitSSHPrivateKeyURL] = privateKeyURL
|
Defaults[.gitSSHPrivateKeyURL] = privateKeyURL
|
||||||
|
|
||||||
do {
|
do {
|
||||||
try Data(contentsOf: publicKeyURL).write(to: URL(fileURLWithPath: Globals.gitSSHPublicKeyPath), options: .atomic)
|
|
||||||
try Data(contentsOf: privateKeyURL).write(to: URL(fileURLWithPath: Globals.gitSSHPrivateKeyPath), options: .atomic)
|
try Data(contentsOf: privateKeyURL).write(to: URL(fileURLWithPath: Globals.gitSSHPrivateKeyPath), options: .atomic)
|
||||||
} catch {
|
} catch {
|
||||||
Utils.alert(title: "Error", message: error.localizedDescription, controller: self, completion: nil)
|
Utils.alert(title: "Error", message: error.localizedDescription, controller: self, completion: nil)
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ import SVProgressHUD
|
||||||
import CoreData
|
import CoreData
|
||||||
import SwiftyUserDefaults
|
import SwiftyUserDefaults
|
||||||
import PasscodeLock
|
import PasscodeLock
|
||||||
|
import LocalAuthentication
|
||||||
|
|
||||||
class SettingsTableViewController: UITableViewController {
|
class SettingsTableViewController: UITableViewController {
|
||||||
|
|
||||||
|
|
@ -91,62 +92,47 @@ class SettingsTableViewController: UITableViewController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@IBAction func cancelGitServerSetting(segue: UIStoryboardSegue) {
|
private func saveImportedPGPKey() {
|
||||||
}
|
// load keys
|
||||||
|
Defaults[.pgpKeySource] = "file"
|
||||||
@IBAction func saveGitServerSetting(segue: UIStoryboardSegue) {
|
|
||||||
if let controller = segue.source as? GitServerSettingTableViewController {
|
|
||||||
let gitRepostiroyURL = controller.gitURLTextField.text!
|
|
||||||
let username = controller.usernameTextField.text!
|
|
||||||
let auth = controller.authenticationMethod
|
|
||||||
|
|
||||||
SVProgressHUD.setDefaultMaskType(.black)
|
SVProgressHUD.setDefaultMaskType(.black)
|
||||||
SVProgressHUD.setDefaultStyle(.light)
|
SVProgressHUD.setDefaultStyle(.light)
|
||||||
SVProgressHUD.show(withStatus: "Prepare Repository")
|
SVProgressHUD.show(withStatus: "Fetching PGP Key")
|
||||||
var gitCredential: GitCredential
|
DispatchQueue.global(qos: .userInitiated).async { [unowned self] in
|
||||||
if auth == "Password" {
|
|
||||||
gitCredential = GitCredential(credential: GitCredential.Credential.http(userName: username, controller: self))
|
|
||||||
} else {
|
|
||||||
gitCredential = GitCredential(
|
|
||||||
credential: GitCredential.Credential.ssh(
|
|
||||||
userName: username,
|
|
||||||
publicKeyFile: Globals.gitSSHPublicKeyURL,
|
|
||||||
privateKeyFile: Globals.gitSSHPrivateKeyURL,
|
|
||||||
controller: self
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
let dispatchQueue = DispatchQueue.global(qos: .userInitiated)
|
|
||||||
dispatchQueue.async {
|
|
||||||
do {
|
do {
|
||||||
try self.passwordStore.cloneRepository(remoteRepoURL: URL(string: gitRepostiroyURL)!,
|
try self.passwordStore.initPGPKeys()
|
||||||
credential: gitCredential,
|
|
||||||
transferProgressBlock:{ (git_transfer_progress, stop) in
|
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
SVProgressHUD.showProgress(Float(git_transfer_progress.pointee.received_objects)/Float(git_transfer_progress.pointee.total_objects), status: "Clone Remote Repository")
|
self.pgpKeyTableViewCell.detailTextLabel?.text = self.passwordStore.pgpKeyID
|
||||||
}
|
SVProgressHUD.showSuccess(withStatus: "Success")
|
||||||
},
|
|
||||||
checkoutProgressBlock: { (path, completedSteps, totalSteps) in
|
|
||||||
DispatchQueue.main.async {
|
|
||||||
SVProgressHUD.showProgress(Float(completedSteps)/Float(totalSteps), status: "Checkout Master Branch")
|
|
||||||
}
|
|
||||||
})
|
|
||||||
DispatchQueue.main.async {
|
|
||||||
Defaults[.gitURL] = URL(string: gitRepostiroyURL)
|
|
||||||
Defaults[.gitUsername] = username
|
|
||||||
Defaults[.gitAuthenticationMethod] = auth
|
|
||||||
self.passwordRepositoryTableViewCell.detailTextLabel?.text = Defaults[.gitURL]?.host
|
|
||||||
SVProgressHUD.showSuccess(withStatus: "Done")
|
|
||||||
SVProgressHUD.dismiss(withDelay: 1)
|
SVProgressHUD.dismiss(withDelay: 1)
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
|
self.pgpKeyTableViewCell.detailTextLabel?.text = "Not Set"
|
||||||
Utils.alert(title: "Error", message: error.localizedDescription, controller: self, completion: nil)
|
Utils.alert(title: "Error", message: error.localizedDescription, controller: self, completion: nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@IBAction func cancelGitServerSetting(segue: UIStoryboardSegue) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@IBAction func saveGitServerSetting(segue: UIStoryboardSegue) {
|
||||||
|
self.passwordRepositoryTableViewCell.detailTextLabel?.text = Defaults[.gitURL]?.host
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
|
|
@ -159,6 +145,28 @@ class SettingsTableViewController: UITableViewController {
|
||||||
setPasscodeLockTouchIDCells()
|
setPasscodeLockTouchIDCells()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func hasTouchID() -> Bool {
|
||||||
|
let context = LAContext()
|
||||||
|
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() {
|
private func setPasscodeLockTouchIDCells() {
|
||||||
if PasscodeLockRepository().hasPasscode {
|
if PasscodeLockRepository().hasPasscode {
|
||||||
self.passcodeTableViewCell.detailTextLabel?.text = "On"
|
self.passcodeTableViewCell.detailTextLabel?.text = "On"
|
||||||
|
|
@ -210,15 +218,13 @@ class SettingsTableViewController: UITableViewController {
|
||||||
tableView.deselectRow(at: indexPath, animated: true)
|
tableView.deselectRow(at: indexPath, animated: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
override func viewWillAppear(_ animated: Bool) {
|
|
||||||
super.viewWillAppear(animated)
|
|
||||||
}
|
|
||||||
|
|
||||||
func touchIDSwitchAction(uiSwitch: UISwitch) {
|
func touchIDSwitchAction(uiSwitch: UISwitch) {
|
||||||
if !Globals.passcodeConfiguration.isTouchIDAllowed {
|
if !Globals.passcodeConfiguration.isTouchIDAllowed || !isTouchIDEnabled() {
|
||||||
// switch off
|
// switch off
|
||||||
|
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(500)) {
|
||||||
uiSwitch.isOn = Defaults[.isTouchIDOn] // false
|
uiSwitch.isOn = Defaults[.isTouchIDOn] // false
|
||||||
Utils.alert(title: "Notice", message: "Please set the passcode lock first.", controller: self, completion: nil)
|
Utils.alert(title: "Notice", message: "Please enable Touch ID and set the passcode lock first.", controller: self, completion: nil)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Defaults[.isTouchIDOn] = uiSwitch.isOn
|
Defaults[.isTouchIDOn] = uiSwitch.isOn
|
||||||
}
|
}
|
||||||
|
|
@ -226,16 +232,11 @@ class SettingsTableViewController: UITableViewController {
|
||||||
appDelegate.passcodeLockPresenter = PasscodeLockPresenter(mainWindow: appDelegate.window, configuration: Globals.passcodeConfiguration)
|
appDelegate.passcodeLockPresenter = PasscodeLockPresenter(mainWindow: appDelegate.window, configuration: Globals.passcodeConfiguration)
|
||||||
}
|
}
|
||||||
|
|
||||||
func pgpKeyExists() -> Bool {
|
|
||||||
return FileManager.default.fileExists(atPath: Globals.pgpPublicKeyPath) &&
|
|
||||||
FileManager.default.fileExists(atPath: Globals.pgpPrivateKeyPath)
|
|
||||||
}
|
|
||||||
|
|
||||||
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"
|
||||||
var armorActionTitle = "ASCII-Armor Encrypted Key"
|
var armorActionTitle = "ASCII-Armor Encrypted Key"
|
||||||
var fileActionTitle = "Use Uploaded Keys"
|
var fileActionTitle = "Use Imported Keys"
|
||||||
|
|
||||||
if Defaults[.pgpKeySource] == "url" {
|
if Defaults[.pgpKeySource] == "url" {
|
||||||
urlActionTitle = "✓ \(urlActionTitle)"
|
urlActionTitle = "✓ \(urlActionTitle)"
|
||||||
|
|
@ -254,63 +255,47 @@ class SettingsTableViewController: UITableViewController {
|
||||||
optionMenu.addAction(urlAction)
|
optionMenu.addAction(urlAction)
|
||||||
optionMenu.addAction(armorAction)
|
optionMenu.addAction(armorAction)
|
||||||
|
|
||||||
if (pgpKeyExists()) {
|
if passwordStore.pgpKeyExists() {
|
||||||
let fileAction = UIAlertAction(title: fileActionTitle, style: .default) { _ in
|
let fileAction = UIAlertAction(title: fileActionTitle, style: .default) { _ in
|
||||||
|
// passphrase related
|
||||||
SVProgressHUD.setDefaultMaskType(.black)
|
let savePassphraseAlert = UIAlertController(title: "Passphrase", message: "Do you want to save the passphrase for later decryption?", preferredStyle: UIAlertControllerStyle.alert)
|
||||||
SVProgressHUD.setDefaultStyle(.light)
|
// no
|
||||||
SVProgressHUD.show(withStatus: "Reading PGP key")
|
savePassphraseAlert.addAction(UIAlertAction(title: "No", style: UIAlertActionStyle.default) { _ in
|
||||||
|
self.passwordStore.pgpKeyPassphrase = nil
|
||||||
let alert = UIAlertController(
|
Defaults[.isRememberPassphraseOn] = false
|
||||||
title: "PGP Passphrase",
|
self.saveImportedPGPKey()
|
||||||
message: "Please fill in the passphrase for your PGP key.",
|
})
|
||||||
preferredStyle: UIAlertControllerStyle.alert
|
// yes
|
||||||
)
|
savePassphraseAlert.addAction(UIAlertAction(title: "Yes", style: UIAlertActionStyle.destructive) {_ in
|
||||||
|
// ask for the passphrase
|
||||||
alert.addAction(
|
let alert = UIAlertController(title: "Passphrase", message: "Please fill in the passphrase of your PGP secret key.", preferredStyle: UIAlertControllerStyle.alert)
|
||||||
UIAlertAction(
|
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: {_ in
|
||||||
title: "OK",
|
self.passwordStore.pgpKeyPassphrase = alert.textFields?.first?.text
|
||||||
style: UIAlertActionStyle.default,
|
Defaults[.isRememberPassphraseOn] = true
|
||||||
handler: {_ in
|
self.saveImportedPGPKey()
|
||||||
Utils.addPasswordToKeychain(
|
}))
|
||||||
name: "pgpKeyPassphrase",
|
alert.addTextField(configurationHandler: {(textField: UITextField!) in
|
||||||
password: alert.textFields!.first!.text!
|
textField.text = ""
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
alert.addTextField(
|
|
||||||
configurationHandler: {(textField: UITextField!) in
|
|
||||||
textField.text = Utils.getPasswordFromKeychain(name: "pgpKeyPassphrase") ?? ""
|
|
||||||
textField.isSecureTextEntry = true
|
textField.isSecureTextEntry = true
|
||||||
}
|
})
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
DispatchQueue.main.async {
|
|
||||||
self.passwordStore.initPGPKeys()
|
|
||||||
|
|
||||||
let key: PGPKey = self.passwordStore.getPgpPrivateKey()
|
|
||||||
Defaults[.pgpKeySource] = "file"
|
|
||||||
|
|
||||||
if (key.isEncrypted) {
|
|
||||||
SVProgressHUD.dismiss()
|
|
||||||
self.present(alert, animated: true, completion: nil)
|
self.present(alert, animated: true, completion: nil)
|
||||||
|
})
|
||||||
|
self.present(savePassphraseAlert, animated: true, completion: nil)
|
||||||
}
|
}
|
||||||
|
optionMenu.addAction(fileAction)
|
||||||
SVProgressHUD.dismiss()
|
} else {
|
||||||
self.pgpKeyTableViewCell.detailTextLabel?.text = self.passwordStore.pgpKeyID
|
let fileAction = UIAlertAction(title: "iTunes File Sharing", style: .default) { _ in
|
||||||
|
let title = "Import via iTunes File Sharing"
|
||||||
|
let message = "Copy your public and private key from your computer to Pass for iOS with the name \"gpg_key.pub\" and \"gpg_key\" (without quotes)."
|
||||||
|
Utils.alert(title: title, message: message, controller: self)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
optionMenu.addAction(fileAction)
|
optionMenu.addAction(fileAction)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if Defaults[.pgpKeySource] != nil {
|
if Defaults[.pgpKeySource] != nil {
|
||||||
let deleteAction = UIAlertAction(title: "Remove PGP Keys", style: .destructive) { _ in
|
let deleteAction = UIAlertAction(title: "Remove PGP Keys", style: .destructive) { _ in
|
||||||
Utils.removePGPKeys()
|
self.passwordStore.removePGPKeys()
|
||||||
self.pgpKeyTableViewCell.detailTextLabel?.text = "Not Set"
|
self.pgpKeyTableViewCell.detailTextLabel?.text = "Not Set"
|
||||||
}
|
}
|
||||||
optionMenu.addAction(deleteAction)
|
optionMenu.addAction(deleteAction)
|
||||||
|
|
|
||||||
|
|
@ -20,10 +20,8 @@ extension DefaultsKeys {
|
||||||
static let gitURL = DefaultsKey<URL?>("gitURL")
|
static let gitURL = DefaultsKey<URL?>("gitURL")
|
||||||
static let gitAuthenticationMethod = DefaultsKey<String?>("gitAuthenticationMethod")
|
static let gitAuthenticationMethod = DefaultsKey<String?>("gitAuthenticationMethod")
|
||||||
static let gitUsername = DefaultsKey<String?>("gitUsername")
|
static let gitUsername = DefaultsKey<String?>("gitUsername")
|
||||||
static let gitSSHPublicKeyURL = DefaultsKey<URL?>("gitSSHPublicKeyURL")
|
|
||||||
static let gitSSHPrivateKeyURL = DefaultsKey<URL?>("gitSSHPrivateKeyURL")
|
static let gitSSHPrivateKeyURL = DefaultsKey<URL?>("gitSSHPrivateKeyURL")
|
||||||
static let gitSSHKeySource = DefaultsKey<String?>("gitSSHKeySource")
|
static let gitSSHKeySource = DefaultsKey<String?>("gitSSHKeySource")
|
||||||
static let gitSSHPublicKeyArmor = DefaultsKey<String?>("gitSSHPublicKeyArmor")
|
|
||||||
static let gitSSHPrivateKeyArmor = DefaultsKey<String?>("gitSSHPrivateKeyArmor")
|
static let gitSSHPrivateKeyArmor = DefaultsKey<String?>("gitSSHPrivateKeyArmor")
|
||||||
static let gitSignatureName = DefaultsKey<String?>("gitSignatureName")
|
static let gitSignatureName = DefaultsKey<String?>("gitSignatureName")
|
||||||
static let gitSignatureEmail = DefaultsKey<String?>("gitSignatureEmail")
|
static let gitSignatureEmail = DefaultsKey<String?>("gitSignatureEmail")
|
||||||
|
|
|
||||||
|
|
@ -15,15 +15,13 @@ class Globals {
|
||||||
static let pgpPublicKeyPath = "\(documentPath)/gpg_key.pub"
|
static let pgpPublicKeyPath = "\(documentPath)/gpg_key.pub"
|
||||||
static let pgpPrivateKeyPath = "\(documentPath)/gpg_key"
|
static let pgpPrivateKeyPath = "\(documentPath)/gpg_key"
|
||||||
|
|
||||||
static let gitSSHPublicKeyPath = "\(documentPath)/ssh_key.pub"
|
|
||||||
static let gitSSHPrivateKeyPath = "\(documentPath)/ssh_key"
|
static let gitSSHPrivateKeyPath = "\(documentPath)/ssh_key"
|
||||||
static let gitSSHPublicKeyURL = URL(fileURLWithPath: gitSSHPublicKeyPath)
|
|
||||||
static let gitSSHPrivateKeyURL = URL(fileURLWithPath: gitSSHPrivateKeyPath)
|
static let gitSSHPrivateKeyURL = URL(fileURLWithPath: gitSSHPrivateKeyPath)
|
||||||
|
|
||||||
static let repositoryPath = "\(libraryPath)/password-store"
|
static let repositoryPath = "\(libraryPath)/password-store"
|
||||||
static var passcodeConfiguration = PasscodeLockConfiguration()
|
static var passcodeConfiguration = PasscodeLockConfiguration()
|
||||||
|
|
||||||
static let passwordDefaultLength = ["Random": (min: 6, max: 24, def: 16),
|
static let passwordDefaultLength = ["Random": (min: 4, max: 64, def: 16),
|
||||||
"Apple": (min: 15, max: 15, def: 15)]
|
"Apple": (min: 15, max: 15, def: 15)]
|
||||||
|
|
||||||
static let gitSignatureDefaultName = "Pass for iOS"
|
static let gitSignatureDefaultName = "Pass for iOS"
|
||||||
|
|
|
||||||
|
|
@ -64,37 +64,15 @@ class Utils {
|
||||||
return randomString
|
return randomString
|
||||||
}
|
}
|
||||||
|
|
||||||
static func alert(title: String, message: String, controller: UIViewController, completion: (() -> Void)?) {
|
static func alert(title: String, message: String, controller: UIViewController, handler: ((UIAlertAction) -> Void)? = nil, completion: (() -> Void)? = nil) {
|
||||||
SVProgressHUD.dismiss()
|
SVProgressHUD.dismiss()
|
||||||
let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.alert)
|
let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.alert)
|
||||||
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil))
|
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: handler))
|
||||||
controller.present(alert, animated: true, completion: completion)
|
controller.present(alert, animated: true, completion: completion)
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static func removePGPKeys() {
|
|
||||||
removeFileIfExists(atPath: Globals.pgpPublicKeyPath)
|
|
||||||
removeFileIfExists(atPath: Globals.pgpPrivateKeyPath)
|
|
||||||
Defaults.remove(.pgpKeySource)
|
|
||||||
Defaults.remove(.pgpPublicKeyArmor)
|
|
||||||
Defaults.remove(.pgpPrivateKeyArmor)
|
|
||||||
Defaults.remove(.pgpPrivateKeyURL)
|
|
||||||
Defaults.remove(.pgpPublicKeyURL)
|
|
||||||
Utils.removeKeychain(name: ".pgpKeyPassphrase")
|
|
||||||
}
|
|
||||||
|
|
||||||
static func removeGitSSHKeys() {
|
|
||||||
removeFileIfExists(atPath: Globals.gitSSHPublicKeyPath)
|
|
||||||
removeFileIfExists(atPath: Globals.gitSSHPrivateKeyPath)
|
|
||||||
Defaults.remove(.gitSSHPublicKeyArmor)
|
|
||||||
Defaults.remove(.gitSSHPrivateKeyArmor)
|
|
||||||
Defaults.remove(.gitSSHPublicKeyURL)
|
|
||||||
Defaults.remove(.gitSSHPrivateKeyURL)
|
|
||||||
Utils.removeKeychain(name: ".gitSSHPrivateKeyPassphrase")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static func getPasswordFromKeychain(name: String) -> String? {
|
static func getPasswordFromKeychain(name: String) -> String? {
|
||||||
let keychain = Keychain(service: "me.mssun.passforios")
|
let keychain = Keychain(service: Bundle.main.bundleIdentifier!)
|
||||||
do {
|
do {
|
||||||
return try keychain.getString(name)
|
return try keychain.getString(name)
|
||||||
} catch {
|
} catch {
|
||||||
|
|
@ -104,11 +82,11 @@ class Utils {
|
||||||
}
|
}
|
||||||
|
|
||||||
static func addPasswordToKeychain(name: String, password: String?) {
|
static func addPasswordToKeychain(name: String, password: String?) {
|
||||||
let keychain = Keychain(service: "me.mssun.passforios")
|
let keychain = Keychain(service: Bundle.main.bundleIdentifier!)
|
||||||
keychain[name] = password
|
keychain[name] = password
|
||||||
}
|
}
|
||||||
static func removeKeychain(name: String) {
|
static func removeKeychain(name: String) {
|
||||||
let keychain = Keychain(service: "me.mssun.passforios")
|
let keychain = Keychain(service: Bundle.main.bundleIdentifier!)
|
||||||
do {
|
do {
|
||||||
try keychain.remove(name)
|
try keychain.remove(name)
|
||||||
} catch {
|
} catch {
|
||||||
|
|
@ -116,7 +94,7 @@ class Utils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static func removeAllKeychain() {
|
static func removeAllKeychain() {
|
||||||
let keychain = Keychain(service: "me.mssun.passforios")
|
let keychain = Keychain(service: Bundle.main.bundleIdentifier!)
|
||||||
do {
|
do {
|
||||||
try keychain.removeAll()
|
try keychain.removeAll()
|
||||||
} catch {
|
} catch {
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>APPL</string>
|
<string>APPL</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>0.2.6</string>
|
<string>0.2.7</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>1</string>
|
<string>1</string>
|
||||||
<key>ITSAppUsesNonExemptEncryption</key>
|
<key>ITSAppUsesNonExemptEncryption</key>
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ class PasswordStore {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let pgp: ObjectivePGP = ObjectivePGP()
|
var pgp: ObjectivePGP = ObjectivePGP()
|
||||||
|
|
||||||
var pgpKeyPassphrase: String? {
|
var pgpKeyPassphrase: String? {
|
||||||
set {
|
set {
|
||||||
|
|
@ -93,10 +93,10 @@ class PasswordStore {
|
||||||
if FileManager.default.fileExists(atPath: storeURL.path) {
|
if FileManager.default.fileExists(atPath: storeURL.path) {
|
||||||
try storeRepository = GTRepository.init(url: storeURL)
|
try storeRepository = GTRepository.init(url: storeURL)
|
||||||
}
|
}
|
||||||
|
try initPGPKeys()
|
||||||
} catch {
|
} catch {
|
||||||
print(error)
|
print(error)
|
||||||
}
|
}
|
||||||
initPGPKeys()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum SSHKeyType {
|
enum SSHKeyType {
|
||||||
|
|
@ -104,24 +104,16 @@ class PasswordStore {
|
||||||
}
|
}
|
||||||
|
|
||||||
public func initGitSSHKey(with armorKey: String, _ keyType: SSHKeyType) throws {
|
public func initGitSSHKey(with armorKey: String, _ keyType: SSHKeyType) throws {
|
||||||
var keyPath = ""
|
guard keyType == .secret else {
|
||||||
switch keyType {
|
return
|
||||||
case .public:
|
|
||||||
keyPath = Globals.gitSSHPublicKeyPath
|
|
||||||
case .secret:
|
|
||||||
keyPath = Globals.gitSSHPrivateKeyPath
|
|
||||||
}
|
}
|
||||||
|
let keyPath = Globals.gitSSHPrivateKeyPath
|
||||||
try armorKey.write(toFile: keyPath, atomically: true, encoding: .ascii)
|
try armorKey.write(toFile: keyPath, atomically: true, encoding: .ascii)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func initPGPKeys() {
|
public func initPGPKeys() throws {
|
||||||
do {
|
|
||||||
try initPGPKey(.public)
|
try initPGPKey(.public)
|
||||||
try initPGPKey(.secret)
|
try initPGPKey(.secret)
|
||||||
} catch {
|
|
||||||
print(error)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public func initPGPKey(_ keyType: PGPKeyType) throws {
|
public func initPGPKey(_ keyType: PGPKeyType) throws {
|
||||||
|
|
@ -143,7 +135,7 @@ class PasswordStore {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func initPGPKey(from url: URL, keyType: PGPKeyType) throws{
|
public func initPGPKey(from url: URL, keyType: PGPKeyType) throws {
|
||||||
var pgpKeyLocalPath = ""
|
var pgpKeyLocalPath = ""
|
||||||
if keyType == .public {
|
if keyType == .public {
|
||||||
pgpKeyLocalPath = Globals.pgpPublicKeyPath
|
pgpKeyLocalPath = Globals.pgpPublicKeyPath
|
||||||
|
|
@ -692,7 +684,6 @@ class PasswordStore {
|
||||||
|
|
||||||
Utils.removeFileIfExists(atPath: Globals.pgpPublicKeyPath)
|
Utils.removeFileIfExists(atPath: Globals.pgpPublicKeyPath)
|
||||||
Utils.removeFileIfExists(atPath: Globals.pgpPrivateKeyPath)
|
Utils.removeFileIfExists(atPath: Globals.pgpPrivateKeyPath)
|
||||||
Utils.removeFileIfExists(atPath: Globals.gitSSHPublicKeyPath)
|
|
||||||
Utils.removeFileIfExists(atPath: Globals.gitSSHPrivateKeyPath)
|
Utils.removeFileIfExists(atPath: Globals.gitSSHPrivateKeyPath)
|
||||||
|
|
||||||
Utils.removeAllKeychain()
|
Utils.removeAllKeychain()
|
||||||
|
|
@ -787,4 +778,37 @@ class PasswordStore {
|
||||||
let encryptedData = try pgp.encryptData(plainData, usingPublicKey: publicKey, armored: Defaults[.encryptInArmored])
|
let encryptedData = try pgp.encryptData(plainData, usingPublicKey: publicKey, armored: Defaults[.encryptInArmored])
|
||||||
return encryptedData
|
return encryptedData
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func removePGPKeys() {
|
||||||
|
Utils.removeFileIfExists(atPath: Globals.pgpPublicKeyPath)
|
||||||
|
Utils.removeFileIfExists(atPath: Globals.pgpPrivateKeyPath)
|
||||||
|
Defaults.remove(.pgpKeySource)
|
||||||
|
Defaults.remove(.pgpPublicKeyArmor)
|
||||||
|
Defaults.remove(.pgpPrivateKeyArmor)
|
||||||
|
Defaults.remove(.pgpPrivateKeyURL)
|
||||||
|
Defaults.remove(.pgpPublicKeyURL)
|
||||||
|
Utils.removeKeychain(name: ".pgpKeyPassphrase")
|
||||||
|
pgp = ObjectivePGP()
|
||||||
|
publicKey = nil
|
||||||
|
privateKey = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func removeGitSSHKeys() {
|
||||||
|
Utils.removeFileIfExists(atPath: Globals.gitSSHPrivateKeyPath)
|
||||||
|
Defaults.remove(.gitSSHPrivateKeyArmor)
|
||||||
|
Defaults.remove(.gitSSHPrivateKeyURL)
|
||||||
|
Utils.removeKeychain(name: ".gitSSHPrivateKeyPassphrase")
|
||||||
|
}
|
||||||
|
|
||||||
|
func gitSSHKeyExists() -> Bool {
|
||||||
|
let fm = FileManager.default
|
||||||
|
return fm.fileExists(atPath: Globals.gitSSHPrivateKeyPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
func pgpKeyExists() -> Bool {
|
||||||
|
let fm = FileManager.default
|
||||||
|
return fm.fileExists(atPath: Globals.pgpPublicKeyPath) && fm.fileExists(atPath: Globals.pgpPrivateKeyPath)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12118" systemVersion="16F43c" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12120" systemVersion="16F73" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
||||||
<device id="retina4_7" orientation="portrait">
|
<device id="retina4_7" orientation="portrait">
|
||||||
<adaptation id="fullscreen"/>
|
<adaptation id="fullscreen"/>
|
||||||
</device>
|
</device>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<deployment identifier="iOS"/>
|
<deployment identifier="iOS"/>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12086"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12088"/>
|
||||||
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
|
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
|
||||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
@ -16,11 +16,14 @@
|
||||||
<rect key="frame" x="0.0" y="0.0" width="320" height="90"/>
|
<rect key="frame" x="0.0" y="0.0" width="320" height="90"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" tableViewCell="KGk-i7-Jjw" id="H2p-sc-9uM">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" tableViewCell="KGk-i7-Jjw" id="H2p-sc-9uM">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="320" height="89.5"/>
|
<rect key="frame" x="0.0" y="0.0" width="320" height="90"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
|
<subviews>
|
||||||
|
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="19l-R0-gP1">
|
||||||
|
<rect key="frame" x="15" y="11" width="290" height="68"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" horizontalHuggingPriority="249" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="password" textAlignment="natural" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="k0U-2N-YaX" userLabel="Password">
|
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" horizontalHuggingPriority="249" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="password" textAlignment="natural" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="k0U-2N-YaX" userLabel="Password">
|
||||||
<rect key="frame" x="15" y="11" width="225" height="68"/>
|
<rect key="frame" x="0.0" y="0.0" width="230" height="68"/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="38" id="9gX-VT-F9P"/>
|
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="38" id="9gX-VT-F9P"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
|
|
@ -31,19 +34,8 @@
|
||||||
<action selector="textFieldDidChange:" destination="KGk-i7-Jjw" eventType="editingChanged" id="U0t-2B-JxY"/>
|
<action selector="textFieldDidChange:" destination="KGk-i7-Jjw" eventType="editingChanged" id="U0t-2B-JxY"/>
|
||||||
</connections>
|
</connections>
|
||||||
</textField>
|
</textField>
|
||||||
<button opaque="NO" contentMode="scaleAspectFit" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="SZJ-aY-45Y" userLabel="Setting">
|
|
||||||
<rect key="frame" x="275" y="11" width="30" height="68"/>
|
|
||||||
<constraints>
|
|
||||||
<constraint firstAttribute="width" constant="30" id="D9D-FC-ANz"/>
|
|
||||||
</constraints>
|
|
||||||
<inset key="contentEdgeInsets" minX="5" minY="10" maxX="5" maxY="10"/>
|
|
||||||
<state key="normal" image="HorizontalSettings"/>
|
|
||||||
<connections>
|
|
||||||
<action selector="showHidePasswordSettings" destination="KGk-i7-Jjw" eventType="touchUpInside" id="3I8-S0-qlo"/>
|
|
||||||
</connections>
|
|
||||||
</button>
|
|
||||||
<button opaque="NO" contentMode="scaleAspectFit" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="hTh-ek-Xam" userLabel="Generate">
|
<button opaque="NO" contentMode="scaleAspectFit" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="hTh-ek-Xam" userLabel="Generate">
|
||||||
<rect key="frame" x="245" y="11" width="30" height="68"/>
|
<rect key="frame" x="230" y="0.0" width="30" height="68"/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstAttribute="width" constant="30" id="l0l-7B-Tws"/>
|
<constraint firstAttribute="width" constant="30" id="l0l-7B-Tws"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
|
|
@ -53,18 +45,25 @@
|
||||||
<action selector="generatePassword:" destination="KGk-i7-Jjw" eventType="touchUpInside" id="M61-hs-PCP"/>
|
<action selector="generatePassword:" destination="KGk-i7-Jjw" eventType="touchUpInside" id="M61-hs-PCP"/>
|
||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
|
<button opaque="NO" contentMode="scaleAspectFit" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="SZJ-aY-45Y" userLabel="Setting">
|
||||||
|
<rect key="frame" x="260" y="0.0" width="30" height="68"/>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstAttribute="width" constant="30" id="D9D-FC-ANz"/>
|
||||||
|
</constraints>
|
||||||
|
<inset key="contentEdgeInsets" minX="5" minY="10" maxX="5" maxY="10"/>
|
||||||
|
<state key="normal" image="HorizontalSettings"/>
|
||||||
|
<connections>
|
||||||
|
<action selector="showHidePasswordSettings" destination="KGk-i7-Jjw" eventType="touchUpInside" id="3I8-S0-qlo"/>
|
||||||
|
</connections>
|
||||||
|
</button>
|
||||||
|
</subviews>
|
||||||
|
</stackView>
|
||||||
</subviews>
|
</subviews>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstItem="SZJ-aY-45Y" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="topMargin" id="5XP-xZ-YWY"/>
|
<constraint firstAttribute="bottomMargin" secondItem="19l-R0-gP1" secondAttribute="bottom" id="ZtI-tq-wfu"/>
|
||||||
<constraint firstAttribute="trailingMargin" secondItem="SZJ-aY-45Y" secondAttribute="trailing" id="5bp-bm-9vv"/>
|
<constraint firstItem="19l-R0-gP1" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leadingMargin" id="cad-hD-m5H"/>
|
||||||
<constraint firstAttribute="bottomMargin" secondItem="SZJ-aY-45Y" secondAttribute="bottom" id="CMF-1f-MdG"/>
|
<constraint firstItem="19l-R0-gP1" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="topMargin" id="ig6-lH-djx"/>
|
||||||
<constraint firstItem="hTh-ek-Xam" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="topMargin" id="OjQ-mD-CWV"/>
|
<constraint firstAttribute="trailingMargin" secondItem="19l-R0-gP1" secondAttribute="trailing" id="k4R-Fi-Hue"/>
|
||||||
<constraint firstItem="SZJ-aY-45Y" firstAttribute="leading" secondItem="hTh-ek-Xam" secondAttribute="trailing" id="UlR-NB-9So"/>
|
|
||||||
<constraint firstAttribute="bottomMargin" secondItem="hTh-ek-Xam" secondAttribute="bottom" id="bvu-Q0-QAG"/>
|
|
||||||
<constraint firstAttribute="trailingMargin" secondItem="k0U-2N-YaX" secondAttribute="trailing" constant="65" id="fz0-HW-sCe"/>
|
|
||||||
<constraint firstAttribute="bottomMargin" secondItem="k0U-2N-YaX" secondAttribute="bottom" id="lRv-MC-Cru"/>
|
|
||||||
<constraint firstItem="k0U-2N-YaX" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="topMargin" id="sUk-sk-JLT"/>
|
|
||||||
<constraint firstItem="k0U-2N-YaX" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leadingMargin" id="zGn-an-SlK"/>
|
|
||||||
</constraints>
|
</constraints>
|
||||||
</tableViewCellContentView>
|
</tableViewCellContentView>
|
||||||
<connections>
|
<connections>
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12118" systemVersion="16F43c" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12120" systemVersion="16F73" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
||||||
<device id="retina4_7" orientation="portrait">
|
<device id="retina4_7" orientation="portrait">
|
||||||
<adaptation id="fullscreen"/>
|
<adaptation id="fullscreen"/>
|
||||||
</device>
|
</device>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<deployment identifier="iOS"/>
|
<deployment identifier="iOS"/>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12086"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12088"/>
|
||||||
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
|
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
|
||||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
<rect key="frame" x="0.0" y="0.0" width="333" height="59"/>
|
<rect key="frame" x="0.0" y="0.0" width="333" height="59"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" tableViewCell="KGk-i7-Jjw" id="H2p-sc-9uM">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" tableViewCell="KGk-i7-Jjw" id="H2p-sc-9uM">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="333" height="58.5"/>
|
<rect key="frame" x="0.0" y="0.0" width="333" height="59"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" verticalHuggingPriority="251" text="content" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="yyr-cF-QN0">
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" verticalHuggingPriority="251" text="content" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="yyr-cF-QN0">
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12118" systemVersion="16F43c" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12120" systemVersion="16G8c" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
||||||
<device id="retina4_7" orientation="portrait">
|
<device id="retina4_7" orientation="portrait">
|
||||||
<adaptation id="fullscreen"/>
|
<adaptation id="fullscreen"/>
|
||||||
</device>
|
</device>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<deployment identifier="iOS"/>
|
<deployment identifier="iOS"/>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12086"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12088"/>
|
||||||
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
|
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
|
||||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
@ -20,37 +20,37 @@
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="0.5" minValue="0.0" maxValue="1" translatesAutoresizingMaskIntoConstraints="NO" id="MwT-Jl-hhE">
|
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="0.5" minValue="0.0" maxValue="1" translatesAutoresizingMaskIntoConstraints="NO" id="MwT-Jl-hhE">
|
||||||
<rect key="frame" x="60.5" y="22.5" width="198.5" height="31"/>
|
<rect key="frame" x="53.5" y="22.5" width="212.5" height="31"/>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="handleSliderValueChange:" destination="KGk-i7-Jjw" eventType="valueChanged" id="WwM-ZE-yIB"/>
|
<action selector="handleSliderValueChange:" destination="KGk-i7-Jjw" eventType="valueChanged" id="WwM-ZE-yIB"/>
|
||||||
</connections>
|
</connections>
|
||||||
</slider>
|
</slider>
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="88" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="GJP-Fj-VZt" userLabel="Value">
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="88" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="GJP-Fj-VZt" userLabel="Value">
|
||||||
<rect key="frame" x="274" y="11" width="24" height="52"/>
|
<rect key="frame" x="278" y="11" width="20" height="52"/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstAttribute="width" constant="24" id="tOG-yp-eFw"/>
|
<constraint firstAttribute="width" constant="20" id="tOG-yp-eFw"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="15"/>
|
<fontDescription key="fontDescription" type="system" pointSize="13"/>
|
||||||
<nil key="textColor"/>
|
<nil key="textColor"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Title" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="t7T-HC-hUd" userLabel="Title">
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Title" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="t7T-HC-hUd" userLabel="Title">
|
||||||
<rect key="frame" x="15" y="11" width="30" height="52"/>
|
<rect key="frame" x="15" y="11" width="26.5" height="52"/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="38" id="8Tz-Qo-Mkg"/>
|
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="38" id="8Tz-Qo-Mkg"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="15"/>
|
<fontDescription key="fontDescription" type="system" pointSize="13"/>
|
||||||
<nil key="textColor"/>
|
<nil key="textColor"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
</subviews>
|
</subviews>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstItem="MwT-Jl-hhE" firstAttribute="leading" secondItem="t7T-HC-hUd" secondAttribute="trailing" constant="17" id="Cc9-kV-nZf"/>
|
<constraint firstItem="MwT-Jl-hhE" firstAttribute="leading" secondItem="t7T-HC-hUd" secondAttribute="trailing" constant="14" id="Cc9-kV-nZf"/>
|
||||||
<constraint firstItem="t7T-HC-hUd" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leadingMargin" id="Kje-Zj-RaX"/>
|
<constraint firstItem="t7T-HC-hUd" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leadingMargin" id="Kje-Zj-RaX"/>
|
||||||
<constraint firstAttribute="trailingMargin" secondItem="GJP-Fj-VZt" secondAttribute="trailing" constant="7" id="LjD-JH-dRT"/>
|
<constraint firstAttribute="trailingMargin" secondItem="GJP-Fj-VZt" secondAttribute="trailing" constant="7" id="LjD-JH-dRT"/>
|
||||||
<constraint firstItem="MwT-Jl-hhE" firstAttribute="centerY" secondItem="t7T-HC-hUd" secondAttribute="centerY" id="MHN-Vl-1le"/>
|
<constraint firstItem="MwT-Jl-hhE" firstAttribute="centerY" secondItem="t7T-HC-hUd" secondAttribute="centerY" id="MHN-Vl-1le"/>
|
||||||
<constraint firstAttribute="bottomMargin" secondItem="GJP-Fj-VZt" secondAttribute="bottom" id="NmC-sS-9Yt"/>
|
<constraint firstAttribute="bottomMargin" secondItem="GJP-Fj-VZt" secondAttribute="bottom" id="NmC-sS-9Yt"/>
|
||||||
<constraint firstItem="GJP-Fj-VZt" firstAttribute="leading" secondItem="MwT-Jl-hhE" secondAttribute="trailing" constant="17" id="VAG-Y2-0Lu"/>
|
<constraint firstItem="GJP-Fj-VZt" firstAttribute="leading" secondItem="MwT-Jl-hhE" secondAttribute="trailing" constant="14" id="VAG-Y2-0Lu"/>
|
||||||
<constraint firstAttribute="bottomMargin" secondItem="t7T-HC-hUd" secondAttribute="bottom" id="mng-Ic-Ciy"/>
|
<constraint firstAttribute="bottomMargin" secondItem="t7T-HC-hUd" secondAttribute="bottom" id="mng-Ic-Ciy"/>
|
||||||
<constraint firstItem="GJP-Fj-VZt" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="topMargin" id="oYC-wl-Lyg"/>
|
<constraint firstItem="GJP-Fj-VZt" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="topMargin" id="oYC-wl-Lyg"/>
|
||||||
<constraint firstItem="t7T-HC-hUd" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="topMargin" id="vhu-L7-r5I"/>
|
<constraint firstItem="t7T-HC-hUd" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="topMargin" id="vhu-L7-r5I"/>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue