Improve scan OTP token workflow
- scan, check OTP, save
This commit is contained in:
parent
dbfbd73d75
commit
a01e736b8a
3 changed files with 27 additions and 68 deletions
|
|
@ -640,7 +640,7 @@
|
||||||
</barButtonItem>
|
</barButtonItem>
|
||||||
</navigationItem>
|
</navigationItem>
|
||||||
<connections>
|
<connections>
|
||||||
<segue destination="lY3-ru-aoM" kind="show" identifier="showQRScannerSegue" id="mPU-tp-J0X"/>
|
<segue destination="A9p-Qb-WmU" kind="show" identifier="showQRScannerSegue" id="yyD-4H-pLE"/>
|
||||||
</connections>
|
</connections>
|
||||||
</tableViewController>
|
</tableViewController>
|
||||||
<placeholder placeholderIdentifier="IBFirstResponder" id="6R0-BP-wo8" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
<placeholder placeholderIdentifier="IBFirstResponder" id="6R0-BP-wo8" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||||
|
|
@ -684,11 +684,6 @@
|
||||||
<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"/>
|
||||||
</connections>
|
</connections>
|
||||||
</barButtonItem>
|
</barButtonItem>
|
||||||
<barButtonItem key="rightBarButtonItem" systemItem="save" id="4kF-IA-Obv">
|
|
||||||
<connections>
|
|
||||||
<segue destination="0gD-ix-2NF" kind="unwind" unwindAction="saveScannedOTPWithSegue:" id="CWK-sE-Ic4"/>
|
|
||||||
</connections>
|
|
||||||
</barButtonItem>
|
|
||||||
</navigationItem>
|
</navigationItem>
|
||||||
<connections>
|
<connections>
|
||||||
<outlet property="scannerOutput" destination="lOI-p4-BGb" id="LZa-eC-1Lc"/>
|
<outlet property="scannerOutput" destination="lOI-p4-BGb" id="LZa-eC-1Lc"/>
|
||||||
|
|
@ -697,7 +692,7 @@
|
||||||
<placeholder placeholderIdentifier="IBFirstResponder" id="rqh-SR-bIq" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
<placeholder placeholderIdentifier="IBFirstResponder" id="rqh-SR-bIq" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||||
<exit id="0gD-ix-2NF" userLabel="Exit" sceneMemberID="exit"/>
|
<exit id="0gD-ix-2NF" userLabel="Exit" sceneMemberID="exit"/>
|
||||||
</objects>
|
</objects>
|
||||||
<point key="canvasLocation" x="7994.202898550725" y="-1008.4239130434784"/>
|
<point key="canvasLocation" x="7059" y="-1012"/>
|
||||||
</scene>
|
</scene>
|
||||||
<!--Password Detail Table View Controller-->
|
<!--Password Detail Table View Controller-->
|
||||||
<scene sceneID="9wY-d0-fB1">
|
<scene sceneID="9wY-d0-fB1">
|
||||||
|
|
@ -807,7 +802,7 @@
|
||||||
</navigationItem>
|
</navigationItem>
|
||||||
<connections>
|
<connections>
|
||||||
<segue destination="HB6-Yu-Y3J" kind="unwind" identifier="deletePasswordSegue" unwindAction="deletePasswordWithSegue:" id="L1Z-64-EZh"/>
|
<segue destination="HB6-Yu-Y3J" kind="unwind" identifier="deletePasswordSegue" unwindAction="deletePasswordWithSegue:" id="L1Z-64-EZh"/>
|
||||||
<segue destination="lY3-ru-aoM" kind="show" identifier="showQRScannerSegue" id="Cpl-XA-cZ9"/>
|
<segue destination="A9p-Qb-WmU" kind="show" identifier="showQRScannerSegue" id="UfP-k3-XeR"/>
|
||||||
</connections>
|
</connections>
|
||||||
</tableViewController>
|
</tableViewController>
|
||||||
<placeholder placeholderIdentifier="IBFirstResponder" id="HlX-6r-eOU" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
<placeholder placeholderIdentifier="IBFirstResponder" id="HlX-6r-eOU" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||||
|
|
@ -1133,11 +1128,11 @@ Phone Support PIN #: 84719</string>
|
||||||
<rect key="frame" x="0.0" y="299" 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="44"/>
|
<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"/>
|
||||||
|
|
@ -1596,24 +1591,6 @@ Cgo
|
||||||
</objects>
|
</objects>
|
||||||
<point key="canvasLocation" x="6083" y="2895"/>
|
<point key="canvasLocation" x="6083" y="2895"/>
|
||||||
</scene>
|
</scene>
|
||||||
<!--Navigation Controller-->
|
|
||||||
<scene sceneID="E7j-qe-O6d">
|
|
||||||
<objects>
|
|
||||||
<navigationController automaticallyAdjustsScrollViewInsets="NO" id="lY3-ru-aoM" sceneMemberID="viewController">
|
|
||||||
<toolbarItems/>
|
|
||||||
<navigationBar key="navigationBar" contentMode="scaleToFill" id="6YB-px-rnU">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
</navigationBar>
|
|
||||||
<nil name="viewControllers"/>
|
|
||||||
<connections>
|
|
||||||
<segue destination="A9p-Qb-WmU" kind="relationship" relationship="rootViewController" id="und-S5-p1v"/>
|
|
||||||
</connections>
|
|
||||||
</navigationController>
|
|
||||||
<placeholder placeholderIdentifier="IBFirstResponder" id="D45-tZ-3fu" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
|
||||||
</objects>
|
|
||||||
<point key="canvasLocation" x="7086.9565217391309" y="-1008.4239130434784"/>
|
|
||||||
</scene>
|
|
||||||
<!--Git Signature-->
|
<!--Git Signature-->
|
||||||
<scene sceneID="eTh-B3-0rv">
|
<scene sceneID="eTh-B3-0rv">
|
||||||
<objects>
|
<objects>
|
||||||
|
|
@ -1745,6 +1722,6 @@ Cgo
|
||||||
<image name="Settings" width="25" height="25"/>
|
<image name="Settings" width="25" height="25"/>
|
||||||
</resources>
|
</resources>
|
||||||
<inferredMetricsTieBreakers>
|
<inferredMetricsTieBreakers>
|
||||||
<segue reference="mPU-tp-J0X"/>
|
<segue reference="UfP-k3-XeR"/>
|
||||||
</inferredMetricsTieBreakers>
|
</inferredMetricsTieBreakers>
|
||||||
</document>
|
</document>
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@ import AVFoundation
|
||||||
|
|
||||||
class OTPScannerController: QRScannerController {
|
class OTPScannerController: QRScannerController {
|
||||||
|
|
||||||
var tempPassword: Password?
|
|
||||||
var scannedOTP: String?
|
var scannedOTP: String?
|
||||||
|
|
||||||
// MARK: - AVCaptureMetadataOutputObjectsDelegate Methods
|
// MARK: - AVCaptureMetadataOutputObjectsDelegate Methods
|
||||||
|
|
@ -27,14 +26,11 @@ class OTPScannerController: QRScannerController {
|
||||||
// check whether it is a valid result
|
// check whether it is a valid result
|
||||||
if let scannedString = metadataObj.stringValue {
|
if let scannedString = metadataObj.stringValue {
|
||||||
if let (accept, message) = delegate?.checkScannedOutput(line: scannedString) {
|
if let (accept, message) = delegate?.checkScannedOutput(line: scannedString) {
|
||||||
|
scannerOutput.text = message
|
||||||
if accept == true {
|
if accept == true {
|
||||||
captureSession?.stopRunning()
|
captureSession?.stopRunning()
|
||||||
scannedOTP = scannedString
|
scannedOTP = scannedString
|
||||||
tempPassword = Password(name: "empty", plainText: scannedString)
|
presentSaveAlert()
|
||||||
// set scannerOutput
|
|
||||||
setupOneTimePasswordMessage()
|
|
||||||
} else {
|
|
||||||
scannerOutput.text = message
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// no delegate, show the scanned result
|
// no delegate, show the scanned result
|
||||||
|
|
@ -50,34 +46,28 @@ class OTPScannerController: QRScannerController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func setupOneTimePasswordMessage() {
|
private func presentSaveAlert() {
|
||||||
if let password = tempPassword {
|
// initialize alert
|
||||||
if password.otpType == .hotp {
|
let password = Password(name: "empty", plainText: scannedOTP!)
|
||||||
// hotp, no need to refresh
|
let (title, content) = password.getOtpStrings()!
|
||||||
let (title, content) = password.getOtpStrings()!
|
let alert = UIAlertController(title: "Success", message: "\(title): \(content)", preferredStyle: UIAlertControllerStyle.alert)
|
||||||
scannerOutput.text = "\(title):\(content)"
|
alert.addAction(UIAlertAction(title: "Save", style: UIAlertActionStyle.default, handler: {[unowned self] (action) -> Void in
|
||||||
} else if password.otpType == .totp {
|
self.delegate?.handleScannedOutput(line: self.scannedOTP!)
|
||||||
// totp, refresh
|
self.navigationController?.popViewController(animated: true)
|
||||||
Timer.scheduledTimer(withTimeInterval: 1, repeats: true) {
|
}))
|
||||||
[weak weakSelf = self] timer in
|
|
||||||
|
if password.otpType == .hotp {
|
||||||
|
// hotp, no need to refresh
|
||||||
|
self.present(alert, animated: true, completion: nil)
|
||||||
|
} else if password.otpType == .totp {
|
||||||
|
// totp, refresh otp
|
||||||
|
self.present(alert, animated: true) {
|
||||||
|
let alertController = self.presentedViewController as! UIAlertController
|
||||||
|
Timer.scheduledTimer(withTimeInterval: 1, repeats: true) {_ in
|
||||||
let (title, content) = password.getOtpStrings()!
|
let (title, content) = password.getOtpStrings()!
|
||||||
weakSelf?.scannerOutput.text = "\(title):\(content)"
|
alertController.message = "\(title): \(content)"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool {
|
|
||||||
if identifier == "saveAddScannedOTPSegue" {
|
|
||||||
return tempPassword != nil
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
|
|
||||||
// super.prepare(for: segue, sender: sender)
|
|
||||||
// if segue.identifier == "saveAddScannedOTPSegue" {
|
|
||||||
// delegate?.handleScannedOutput(line: scannedOTP)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -226,12 +226,4 @@ class PasswordEditorTableViewController: UITableViewController, FillPasswordTabl
|
||||||
@IBAction private func cancelOTPScanner(segue: UIStoryboardSegue) {
|
@IBAction private func cancelOTPScanner(segue: UIStoryboardSegue) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@IBAction func saveScannedOTP(segue: UIStoryboardSegue) {
|
|
||||||
if let controller = segue.source as? OTPScannerController {
|
|
||||||
if let scannedOTP = controller.scannedOTP {
|
|
||||||
insertScannedOTPFields(scannedOTP)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue