Scan QR Code to import SSH private key
This commit is contained in:
parent
a31f5b797d
commit
3cde0d954c
6 changed files with 175 additions and 25 deletions
|
|
@ -648,7 +648,7 @@
|
||||||
</objects>
|
</objects>
|
||||||
<point key="canvasLocation" x="4954" y="-1027"/>
|
<point key="canvasLocation" x="4954" y="-1027"/>
|
||||||
</scene>
|
</scene>
|
||||||
<!--Scan QR Codes-->
|
<!--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="Scan QR Codes" 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"/>
|
||||||
|
|
@ -1028,7 +1028,7 @@ Phone Support PIN #: 84719</string>
|
||||||
<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="20" y="0.0" width="379" height="43.666666666666664"/>
|
<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"/>
|
||||||
|
|
@ -1045,18 +1045,18 @@ Phone Support PIN #: 84719</string>
|
||||||
<rect key="frame" x="0.0" y="155" 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="376" height="43.666666666666664"/>
|
<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="20.000000000000007" y="11.999999999999998" width="99.666666666666671" height="20.333333333333332"/>
|
<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="318.33333333333331" y="11.999999999999998" width="57.666666666666664" height="20.333333333333332"/>
|
<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"/>
|
||||||
|
|
@ -1080,7 +1080,7 @@ Phone Support PIN #: 84719</string>
|
||||||
<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="20" y="0.0" width="379" height="43.666666666666664"/>
|
<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"/>
|
||||||
|
|
@ -1097,7 +1097,7 @@ Phone Support PIN #: 84719</string>
|
||||||
<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="20" y="0.0" width="379" height="43.666666666666664"/>
|
<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"/>
|
||||||
|
|
@ -1447,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"/>
|
||||||
|
|
@ -1522,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>
|
||||||
|
|
@ -1539,6 +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="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"/>
|
||||||
|
|
@ -1670,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">
|
||||||
|
|
@ -1700,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"/>
|
||||||
|
|
@ -1716,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"/>
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,7 @@ struct GitCredential {
|
||||||
attempts += 1
|
attempts += 1
|
||||||
lastPassword = newPassword
|
lastPassword = newPassword
|
||||||
credential = try? GTCredential(userName: userName, publicKeyURL: nil, privateKeyURL: privateKeyFile, passphrase: newPassword!)
|
credential = try? GTCredential(userName: userName, publicKeyURL: nil, privateKeyURL: privateKeyFile, passphrase: newPassword!)
|
||||||
|
print(privateKeyFile)
|
||||||
}
|
}
|
||||||
return credential
|
return credential
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,17 +9,77 @@
|
||||||
import UIKit
|
import UIKit
|
||||||
import SwiftyUserDefaults
|
import SwiftyUserDefaults
|
||||||
|
|
||||||
class GitSSHKeyArmorSettingTableViewController: UITableViewController, UITextViewDelegate {
|
class GitSSHKeyArmorSettingTableViewController: UITableViewController, UITextViewDelegate, QRScannerControllerDelegate {
|
||||||
@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()
|
||||||
armorPrivateKeyTextView.text = Defaults[.gitSSHPrivateKeyArmor]
|
armorPrivateKeyTextView.text = Defaults[.gitSSHPrivateKeyArmor]
|
||||||
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) {
|
||||||
|
|
@ -46,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) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -120,8 +120,7 @@ class GitServerSettingTableViewController: UITableViewController {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func gitSSHKeyExists() -> Bool {
|
private func gitSSHKeyExists() -> Bool {
|
||||||
return FileManager.default.fileExists(atPath: Globals.gitSSHPublicKeyPath) &&
|
return FileManager.default.fileExists(atPath: Globals.gitSSHPrivateKeyPath)
|
||||||
FileManager.default.fileExists(atPath: Globals.gitSSHPrivateKeyPath)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func showSSHKeyActionSheet() {
|
func showSSHKeyActionSheet() {
|
||||||
|
|
|
||||||
|
|
@ -15,9 +15,7 @@ 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"
|
||||||
|
|
|
||||||
|
|
@ -104,14 +104,10 @@ 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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -692,7 +688,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()
|
||||||
|
|
@ -805,7 +800,6 @@ class PasswordStore {
|
||||||
}
|
}
|
||||||
|
|
||||||
func removeGitSSHKeys() {
|
func removeGitSSHKeys() {
|
||||||
Utils.removeFileIfExists(atPath: Globals.gitSSHPublicKeyPath)
|
|
||||||
Utils.removeFileIfExists(atPath: Globals.gitSSHPrivateKeyPath)
|
Utils.removeFileIfExists(atPath: Globals.gitSSHPrivateKeyPath)
|
||||||
Defaults.remove(.gitSSHPrivateKeyArmor)
|
Defaults.remove(.gitSSHPrivateKeyArmor)
|
||||||
Defaults.remove(.gitSSHPrivateKeyURL)
|
Defaults.remove(.gitSSHPrivateKeyURL)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue