Introduce KeyImporter protocol to reduce code duplications in SSH key importers
This commit is contained in:
parent
6aa39db657
commit
94a5f8c501
14 changed files with 189 additions and 144 deletions
|
|
@ -1031,9 +1031,11 @@ Secret Question 1: What is your childhood best friend's most bizarre superhero f
|
|||
</navigationItem>
|
||||
<connections>
|
||||
<outlet property="privateKeyURLTextField" destination="4iJ-oB-R1f" id="scx-lz-dUW"/>
|
||||
<segue destination="bXG-pY-DH6" kind="unwind" identifier="importSSHKeySegue" unwindAction="importSSHKeyWithSegue:" id="vGk-Xa-meP"/>
|
||||
</connections>
|
||||
</tableViewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="eY3-aM-BJB" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
<exit id="bXG-pY-DH6" userLabel="Exit" sceneMemberID="exit"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="6990" y="2239"/>
|
||||
</scene>
|
||||
|
|
@ -1558,9 +1560,11 @@ Secret Question 1: What is your childhood best friend's most bizarre superhero f
|
|||
<outlet property="armorPrivateKeyTextView" destination="23o-MP-wQY" id="ybK-Ba-vJt"/>
|
||||
<outlet property="scanPrivateKeyCell" destination="jXO-n0-Mvx" id="Zdb-wm-7Ls"/>
|
||||
<segue destination="LZE-gF-IcM" kind="show" identifier="showSSHScannerSegue" id="oxP-I1-Mke"/>
|
||||
<segue destination="Vrv-hO-eSS" kind="unwind" identifier="importSSHKeySegue" unwindAction="importSSHKeyWithSegue:" id="zgs-se-tr3"/>
|
||||
</connections>
|
||||
</tableViewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="qJO-AN-K9p" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
<exit id="Vrv-hO-eSS" userLabel="Exit" sceneMemberID="exit"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="6083" y="3668"/>
|
||||
</scene>
|
||||
|
|
|
|||
|
|
@ -213,78 +213,65 @@ class GitRepositorySettingsTableViewController: UITableViewController {
|
|||
}
|
||||
}
|
||||
|
||||
@IBAction func importSSHKey(segue: UIStoryboardSegue) {
|
||||
guard let sourceController = segue.source as? KeyImporter, sourceController.isReadyToUse() else {
|
||||
return
|
||||
}
|
||||
importSSHKey(using: sourceController)
|
||||
}
|
||||
|
||||
private func importSSHKey(using keyImporter: KeyImporter) {
|
||||
DispatchQueue.global(qos: .userInitiated).async { [unowned self] in
|
||||
do {
|
||||
try keyImporter.importKeys()
|
||||
DispatchQueue.main.async {
|
||||
SVProgressHUD.showSuccess(withStatus: "Imported".localize())
|
||||
SVProgressHUD.dismiss(withDelay: 1)
|
||||
}
|
||||
Defaults.gitSSHKeySource = type(of: keyImporter).keySource
|
||||
self.gitAuthenticationMethod = .key
|
||||
self.sshLabel?.isEnabled = true
|
||||
} catch {
|
||||
Utils.alert(title: "Error".localize(), message: error.localizedDescription, controller: self)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Helper Functions
|
||||
|
||||
private func showSSHKeyActionSheet() {
|
||||
let optionMenu = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
|
||||
var urlActionTitle = "DownloadFromUrl".localize()
|
||||
var armorActionTitle = "AsciiArmorEncryptedKey".localize()
|
||||
var fileActionTitle = "ITunesFileSharing".localize()
|
||||
|
||||
switch Defaults.gitSSHKeySource {
|
||||
case .url: urlActionTitle = "✓ \(urlActionTitle)"
|
||||
case .armor: armorActionTitle = "✓ \(armorActionTitle)"
|
||||
case .file: fileActionTitle = "✓ \(fileActionTitle)"
|
||||
case .none: break
|
||||
}
|
||||
|
||||
let urlAction = UIAlertAction(title: urlActionTitle, style: .default) { _ in
|
||||
optionMenu.addAction(UIAlertAction(title: SSHKeyUrlImportTableViewController.menuLabel, style: .default) { _ in
|
||||
self.performSegue(withIdentifier: "setGitSSHKeyByURLSegue", sender: self)
|
||||
}
|
||||
optionMenu.addAction(urlAction)
|
||||
|
||||
let armorAction = UIAlertAction(title: armorActionTitle, style: .default) { _ in
|
||||
})
|
||||
optionMenu.addAction(UIAlertAction(title: SSHKeyArmorImportTableViewController.menuLabel, style: .default) { _ in
|
||||
self.performSegue(withIdentifier: "setGitSSHKeyByArmorSegue", sender: self)
|
||||
})
|
||||
|
||||
if isReadyToUse() {
|
||||
optionMenu.addAction(UIAlertAction(title: "\(Self.menuLabel) (\("Import".localize()))", style: .default) { _ in
|
||||
self.importSSHKey(using: self)
|
||||
})
|
||||
} else {
|
||||
optionMenu.addAction(UIAlertAction(title: "\(Self.menuLabel) (\("Tips".localize()))", style: .default) { _ in
|
||||
let title = "Tips".localize()
|
||||
let message = "SshCopyPrivateKeyToPass.".localize()
|
||||
Utils.alert(title: title, message: message, controller: self)
|
||||
})
|
||||
}
|
||||
optionMenu.addAction(armorAction)
|
||||
|
||||
let fileAction: UIAlertAction = {
|
||||
if KeyFileManager.PrivateSsh.doesKeyFileExist() {
|
||||
fileActionTitle.append(" (\("Import".localize()))")
|
||||
let action = UIAlertAction(title: fileActionTitle, style: .default) { _ in
|
||||
do {
|
||||
try self.passwordStore.gitSSHKeyImportFromFileSharing()
|
||||
Defaults.gitSSHKeySource = .file
|
||||
SVProgressHUD.showSuccess(withStatus: "Imported".localize())
|
||||
SVProgressHUD.dismiss(withDelay: 1)
|
||||
self.sshLabel?.isEnabled = true
|
||||
self.gitAuthenticationMethod = .key
|
||||
self.updateAuthenticationMethodCheckView(for: self.gitAuthenticationMethod)
|
||||
} catch {
|
||||
Utils.alert(title: "Error".localize(), message: error.localizedDescription, controller: self)
|
||||
}
|
||||
}
|
||||
return action
|
||||
} else {
|
||||
fileActionTitle.append(" (\("Tips".localize()))")
|
||||
let action = UIAlertAction(title: fileActionTitle, style: .default) { _ in
|
||||
let title = "Tips".localize()
|
||||
let message = "SshCopyPrivateKeyToPass.".localize()
|
||||
Utils.alert(title: title, message: message, controller: self)
|
||||
}
|
||||
return action
|
||||
}
|
||||
|
||||
}()
|
||||
optionMenu.addAction(fileAction)
|
||||
|
||||
if Defaults.gitSSHKeySource != nil {
|
||||
let deleteAction = UIAlertAction(title: "RemoveSShKeys".localize(), style: .destructive) { _ in
|
||||
optionMenu.addAction(UIAlertAction(title: "RemoveSShKeys".localize(), style: .destructive) { _ in
|
||||
self.passwordStore.removeGitSSHKeys()
|
||||
Defaults.gitSSHKeySource = nil
|
||||
self.sshLabel?.isEnabled = false
|
||||
self.updateAuthenticationMethodCheckView(for: .password)
|
||||
}
|
||||
optionMenu.addAction(deleteAction)
|
||||
self.gitAuthenticationMethod = .password
|
||||
})
|
||||
}
|
||||
|
||||
let cancelAction = UIAlertAction(title: "Cancel".localize(), style: .cancel, handler: nil)
|
||||
optionMenu.addAction(cancelAction)
|
||||
|
||||
optionMenu.addAction(UIAlertAction(title: "Cancel".localize(), style: .cancel, handler: nil))
|
||||
optionMenu.popoverPresentationController?.sourceView = authSSHKeyCell
|
||||
optionMenu.popoverPresentationController?.sourceRect = authSSHKeyCell.bounds
|
||||
|
||||
self.present(optionMenu, animated: true)
|
||||
present(optionMenu, animated: true)
|
||||
}
|
||||
|
||||
private func requestCredentialPassword(credential: GitCredential.Credential, lastPassword: String?) -> String? {
|
||||
|
|
@ -313,5 +300,18 @@ class GitRepositorySettingsTableViewController: UITableViewController {
|
|||
"""
|
||||
Utils.alert(title: "Git URL Format", message: message, controller: self)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension GitRepositorySettingsTableViewController: KeyImporter {
|
||||
|
||||
static let keySource = KeySource.itunes
|
||||
static let label = "ITunesFileSharing".localize()
|
||||
|
||||
func isReadyToUse() -> Bool {
|
||||
return KeyFileManager.PrivateSsh.doesKeyFileExist()
|
||||
}
|
||||
|
||||
func importKeys() throws {
|
||||
try KeyFileManager.PrivateSsh.importKeyFromFileSharing()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
36
pass/Controllers/KeyImporter.swift
Normal file
36
pass/Controllers/KeyImporter.swift
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
//
|
||||
// KeyImporter.swift
|
||||
// pass
|
||||
//
|
||||
// Created by Danny Moesch on 15.02.20.
|
||||
// Copyright © 2020 Bob Sun. All rights reserved.
|
||||
//
|
||||
|
||||
import passKit
|
||||
|
||||
protocol KeyImporter {
|
||||
|
||||
static var keySource: KeySource { get }
|
||||
|
||||
static var label: String { get }
|
||||
|
||||
static var menuLabel: String { get }
|
||||
|
||||
func isReadyToUse() -> Bool
|
||||
|
||||
func importKeys() throws
|
||||
}
|
||||
|
||||
extension KeyImporter {
|
||||
|
||||
static var isCurrentKeySource: Bool {
|
||||
return Defaults.gitSSHKeySource == Self.keySource
|
||||
}
|
||||
|
||||
static var menuLabel: String {
|
||||
if isCurrentKeySource {
|
||||
return "✓ \(Self.label)"
|
||||
}
|
||||
return Self.label
|
||||
}
|
||||
}
|
||||
|
|
@ -10,13 +10,11 @@ import UIKit
|
|||
import passKit
|
||||
|
||||
class PGPKeyArmorImportTableViewController: AutoCellHeightUITableViewController, UITextViewDelegate, QRScannerControllerDelegate {
|
||||
|
||||
@IBOutlet weak var armorPublicKeyTextView: UITextView!
|
||||
@IBOutlet weak var armorPrivateKeyTextView: UITextView!
|
||||
@IBOutlet weak var scanPublicKeyCell: UITableViewCell!
|
||||
@IBOutlet weak var scanPrivateKeyCell: UITableViewCell!
|
||||
|
||||
let passwordStore = PasswordStore.shared
|
||||
let keychain = AppKeychain.shared
|
||||
|
||||
class ScannedPGPKey {
|
||||
enum KeyType {
|
||||
|
|
@ -132,7 +130,7 @@ class PGPKeyArmorImportTableViewController: AutoCellHeightUITableViewController,
|
|||
|
||||
extension PGPKeyArmorImportTableViewController: PGPKeyImporter {
|
||||
|
||||
static let keySource = PGPKeySource.armor
|
||||
static let keySource = KeySource.armor
|
||||
static let label = "AsciiArmorEncryptedKey".localize()
|
||||
|
||||
func isReadyToUse() -> Bool {
|
||||
|
|
@ -152,10 +150,6 @@ extension PGPKeyArmorImportTableViewController: PGPKeyImporter {
|
|||
try KeyFileManager.PrivatePgp.importKey(from: armorPrivateKeyTextView.text ?? "")
|
||||
}
|
||||
|
||||
func doAfterImport() {
|
||||
|
||||
}
|
||||
|
||||
func saveImportedKeys() {
|
||||
performSegue(withIdentifier: "savePGPKeySegue", sender: self)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,9 +13,6 @@ class PGPKeyFileImportTableViewController: AutoCellHeightUITableViewController {
|
|||
@IBOutlet weak var pgpPublicKeyFile: UITableViewCell!
|
||||
@IBOutlet weak var pgpPrivateKeyFile: UITableViewCell!
|
||||
|
||||
private let passwordStore = PasswordStore.shared
|
||||
private let keychain = AppKeychain.shared
|
||||
|
||||
private var publicKey: String? = nil
|
||||
private var privateKey: String? = nil
|
||||
|
||||
|
|
@ -72,7 +69,7 @@ extension PGPKeyFileImportTableViewController: UIDocumentPickerDelegate {
|
|||
|
||||
extension PGPKeyFileImportTableViewController: PGPKeyImporter {
|
||||
|
||||
static let keySource = PGPKeySource.files
|
||||
static let keySource = KeySource.file
|
||||
static let label = "LoadFromFiles".localize()
|
||||
|
||||
func isReadyToUse() -> Bool {
|
||||
|
|
|
|||
|
|
@ -8,17 +8,7 @@
|
|||
|
||||
import passKit
|
||||
|
||||
protocol PGPKeyImporter {
|
||||
|
||||
static var keySource: PGPKeySource { get }
|
||||
|
||||
static var label: String { get }
|
||||
|
||||
static var menuLabel: String { get }
|
||||
|
||||
func isReadyToUse() -> Bool
|
||||
|
||||
func importKeys() throws
|
||||
protocol PGPKeyImporter: KeyImporter {
|
||||
|
||||
func doAfterImport()
|
||||
|
||||
|
|
@ -26,12 +16,13 @@ protocol PGPKeyImporter {
|
|||
}
|
||||
|
||||
extension PGPKeyImporter {
|
||||
|
||||
static var menuLabel: String {
|
||||
if Defaults.pgpKeySource == Self.keySource {
|
||||
return "✓ \(Self.label)"
|
||||
}
|
||||
return Self.label
|
||||
|
||||
static var isCurrentKeySource: Bool {
|
||||
return Defaults.pgpKeySource == Self.keySource
|
||||
}
|
||||
|
||||
func doAfterImport() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,9 +14,6 @@ class PGPKeyUrlImportTableViewController: AutoCellHeightUITableViewController {
|
|||
@IBOutlet weak var pgpPublicKeyURLTextField: UITextField!
|
||||
@IBOutlet weak var pgpPrivateKeyURLTextField: UITextField!
|
||||
|
||||
let passwordStore = PasswordStore.shared
|
||||
let keychain = AppKeychain.shared
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
pgpPublicKeyURLTextField.text = Defaults.pgpPublicKeyURL?.absoluteString
|
||||
|
|
@ -46,7 +43,7 @@ class PGPKeyUrlImportTableViewController: AutoCellHeightUITableViewController {
|
|||
|
||||
extension PGPKeyUrlImportTableViewController: PGPKeyImporter {
|
||||
|
||||
static let keySource = PGPKeySource.url
|
||||
static let keySource = KeySource.url
|
||||
static let label = "DownloadFromUrl".localize()
|
||||
|
||||
func isReadyToUse() -> Bool {
|
||||
|
|
|
|||
|
|
@ -10,11 +10,11 @@ import UIKit
|
|||
import passKit
|
||||
|
||||
class SSHKeyArmorImportTableViewController: AutoCellHeightUITableViewController, UITextViewDelegate, QRScannerControllerDelegate {
|
||||
|
||||
@IBOutlet weak var armorPrivateKeyTextView: UITextView!
|
||||
@IBOutlet weak var scanPrivateKeyCell: UITableViewCell!
|
||||
|
||||
var gitSSHPrivateKeyPassphrase: String?
|
||||
let passwordStore = PasswordStore.shared
|
||||
|
||||
class ScannedSSHKey {
|
||||
var segments = [String]()
|
||||
|
|
@ -60,10 +60,7 @@ class SSHKeyArmorImportTableViewController: AutoCellHeightUITableViewController,
|
|||
}
|
||||
|
||||
@IBAction func doneButtonTapped(_ sender: Any) {
|
||||
AppKeychain.shared.add(string: armorPrivateKeyTextView.text, for: SshKey.PRIVATE.getKeychainKey())
|
||||
Defaults.gitSSHKeySource = .armor
|
||||
Defaults.gitAuthenticationMethod = .key
|
||||
self.navigationController!.popViewController(animated: true)
|
||||
performSegue(withIdentifier: "importSSHKeySegue", sender: self)
|
||||
}
|
||||
|
||||
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
|
||||
|
|
@ -109,5 +106,22 @@ class SSHKeyArmorImportTableViewController: AutoCellHeightUITableViewController,
|
|||
@IBAction private func cancelSSHScanner(segue: UIStoryboardSegue) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension SSHKeyArmorImportTableViewController: KeyImporter {
|
||||
|
||||
static let keySource = KeySource.armor
|
||||
static let label = "AsciiArmorEncryptedKey".localize()
|
||||
|
||||
func isReadyToUse() -> Bool {
|
||||
guard !armorPrivateKeyTextView.text.isEmpty else {
|
||||
Utils.alert(title: "CannotSave".localize(), message: "SetPrivateKey.".localize(), controller: self)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func importKeys() throws {
|
||||
try KeyFileManager.PrivateSsh.importKey(from: armorPrivateKeyTextView.text ?? "")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,34 +6,55 @@
|
|||
// Copyright © 2017 Bob Sun. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import SVProgressHUD
|
||||
import passKit
|
||||
|
||||
class SSHKeyUrlImportTableViewController: AutoCellHeightUITableViewController {
|
||||
|
||||
@IBOutlet weak var privateKeyURLTextField: UITextField!
|
||||
|
||||
let passwordStore = PasswordStore.shared
|
||||
|
||||
@IBAction func doneButtonTapped(_ sender: UIButton) {
|
||||
guard let privateKeyURL = URL(string: privateKeyURLTextField.text!.trimmed) else {
|
||||
Utils.alert(title: "CannotSave".localize(), message: "SetPrivateKeyUrl.".localize(), controller: self, completion: nil)
|
||||
return
|
||||
}
|
||||
|
||||
do {
|
||||
try Data(contentsOf: privateKeyURL).write(to: URL(fileURLWithPath: SshKey.PRIVATE.getFileSharingPath()), options: .atomic)
|
||||
try self.passwordStore.gitSSHKeyImportFromFileSharing()
|
||||
Defaults.gitSSHKeySource = .file
|
||||
Defaults.gitAuthenticationMethod = .key
|
||||
SVProgressHUD.showSuccess(withStatus: "Imported".localize())
|
||||
SVProgressHUD.dismiss(withDelay: 1)
|
||||
} catch {
|
||||
Utils.alert(title: "Error".localize(), message: error.localizedDescription, controller: self, completion: nil)
|
||||
}
|
||||
Defaults.gitSSHKeySource = .url
|
||||
self.navigationController!.popViewController(animated: true)
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
privateKeyURLTextField.text = Defaults.gitSSHPrivateKeyURL?.absoluteString
|
||||
}
|
||||
|
||||
@IBAction func doneButtonTapped(_ sender: UIButton) {
|
||||
if getScheme(from: privateKeyURLTextField.text?.trimmed) == "http" {
|
||||
let savePassphraseAlert = UIAlertController(title: "HttpNotSecure".localize(), message: "ReallyUseHttp?".localize(), preferredStyle: .alert)
|
||||
savePassphraseAlert.addAction(UIAlertAction(title: "No".localize(), style: .default) { _ in })
|
||||
savePassphraseAlert.addAction(UIAlertAction(title: "Yes".localize(), style: .destructive) { _ in
|
||||
self.performSegue(withIdentifier: "importSSHKeySegue", sender: self)
|
||||
})
|
||||
return present(savePassphraseAlert, animated: true)
|
||||
}
|
||||
performSegue(withIdentifier: "importSSHKeySegue", sender: self)
|
||||
}
|
||||
|
||||
private func getScheme(from url: String?) -> String? {
|
||||
return url.flatMap(URL.init(string:))?.scheme
|
||||
}
|
||||
}
|
||||
|
||||
extension SSHKeyUrlImportTableViewController: KeyImporter {
|
||||
|
||||
static let keySource = KeySource.url
|
||||
static let label = "DownloadFromUrl".localize()
|
||||
|
||||
func isReadyToUse() -> Bool {
|
||||
guard let scheme = getScheme(from: privateKeyURLTextField.text?.trimmed) else {
|
||||
Utils.alert(title: "CannotSave".localize(), message: "SetPrivateKeyUrl.".localize(), controller: self)
|
||||
return false
|
||||
}
|
||||
guard scheme == "https" || scheme == "http" else {
|
||||
Utils.alert(title: "CannotSave".localize(), message: "UseEitherHttpsOrHttp.".localize(), controller: self)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func importKeys() throws {
|
||||
Defaults.gitSSHPrivateKeyURL = URL(string: privateKeyURLTextField.text!.trimmed)
|
||||
|
||||
try KeyFileManager.PrivateSsh.importKey(from: Defaults.gitSSHPrivateKeyURL!)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -153,19 +153,18 @@ class SettingsTableViewController: UITableViewController, UITabBarControllerDele
|
|||
}
|
||||
|
||||
if Defaults.pgpKeySource != nil {
|
||||
let deleteAction = UIAlertAction(title: "RemovePgpKeys".localize(), style: .destructive) { _ in
|
||||
optionMenu.addAction(UIAlertAction(title: "RemovePgpKeys".localize(), style: .destructive) { _ in
|
||||
self.keychain.removeContent(for: PgpKey.PUBLIC.getKeychainKey())
|
||||
self.keychain.removeContent(for: PgpKey.PRIVATE.getKeychainKey())
|
||||
PGPAgent.shared.uninitKeys()
|
||||
self.pgpKeyTableViewCell.detailTextLabel?.text = "NotSet".localize()
|
||||
Defaults.pgpKeySource = nil
|
||||
}
|
||||
optionMenu.addAction(deleteAction)
|
||||
})
|
||||
}
|
||||
optionMenu.addAction(UIAlertAction(title: "Cancel".localize(), style: .cancel, handler: nil))
|
||||
optionMenu.popoverPresentationController?.sourceView = pgpKeyTableViewCell
|
||||
optionMenu.popoverPresentationController?.sourceRect = pgpKeyTableViewCell.bounds
|
||||
self.present(optionMenu, animated: true, completion: nil)
|
||||
present(optionMenu, animated: true)
|
||||
}
|
||||
|
||||
func showPasscodeActionSheet() {
|
||||
|
|
@ -243,7 +242,7 @@ class SettingsTableViewController: UITableViewController, UITabBarControllerDele
|
|||
|
||||
extension SettingsTableViewController: PGPKeyImporter {
|
||||
|
||||
static let keySource = PGPKeySource.itunes
|
||||
static let keySource = KeySource.itunes
|
||||
static let label = "ITunesFileSharing".localize()
|
||||
|
||||
func isReadyToUse() -> Bool {
|
||||
|
|
@ -255,11 +254,7 @@ extension SettingsTableViewController: PGPKeyImporter {
|
|||
try KeyFileManager.PrivatePgp.importKeyFromFileSharing()
|
||||
}
|
||||
|
||||
func doAfterImport() {
|
||||
|
||||
}
|
||||
|
||||
func saveImportedKeys() {
|
||||
self.savePGPKey(using: self)
|
||||
savePGPKey(using: self)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@
|
|||
"CannotSelectSshKey" = "Cannot Select SSH Key";
|
||||
"PleaseSetupSshKeyFirst." = "Please setup SSH key first.";
|
||||
"RemoveSShKeys" = "Remove Git SSH Keys";
|
||||
"SetPrivateKeyUrl." = "Please set private key URL first.";
|
||||
"SetPrivateKeyUrl." = "Please set a valid private key URL first.";
|
||||
"SshCopyPrivateKeyToPass." = "Copy your ASCII-armored private key to Pass with the name \"ssh_key\" (without quotes) via iTunes. Then come back and click \"iTunes File Sharing\" to finish.";
|
||||
|
||||
// QR code scanning
|
||||
|
|
@ -113,8 +113,8 @@
|
|||
"ScanPrivateKey." = "Please scan private key.";
|
||||
"ScanPrivateKeyQrCodes" = "Scan Private Key QR codes";
|
||||
"ScanPublicKeyQrCodes" = "Scan Public Key QR codes";
|
||||
"SetPrivateKey." = "Please set private key first.";
|
||||
"SetPublicKey." = "Please set public key first.";
|
||||
"SetPrivateKey." = "Please set the private key first.";
|
||||
"SetPublicKey." = "Please set the public key first.";
|
||||
"NoQrCodeDetected." = "No QR code detected.";
|
||||
"NoStringValue" = "No string value";
|
||||
"CameraAccessDenied." = "Camera access denied.";
|
||||
|
|
@ -126,7 +126,7 @@
|
|||
"FillInPgpPassphrase." = "Please fill in the passphrase of your PGP secret key.";
|
||||
"WantToSavePassphrase?" = "Do you want to save the passphrase for later decryption?";
|
||||
"CannotSavePgpKey" = "Cannot Save PGP Key";
|
||||
"SetPgpKeyUrlsFirst." = "Please set PGP key URLs first.";
|
||||
"SetPgpKeyUrlsFirst." = "Please set valid PGP key URLs first.";
|
||||
"FetchingPgpKey" = "Fetching PGP Key";
|
||||
"RememberToRemoveKey" = "Remember to Remove the Keys";
|
||||
"RememberToRemoveKeyFromServer." = "Remember to remove the keys from the server.";
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue