Skip to content

Commit

Permalink
Merge pull request #3426 from safe-global/GH-3406/update-libs
Browse files Browse the repository at this point in the history
GH-3406, GH-3427 update libs
  • Loading branch information
DmitryBespalov authored Jun 14, 2024
2 parents 14b8c2b + 00c24a4 commit 76008f9
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 11 deletions.
2 changes: 1 addition & 1 deletion Multisig.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7506,7 +7506,7 @@
repositoryURL = "https://github.com/KeystoneHQ/ur-registry-ios";
requirement = {
kind = exactVersion;
version = 1.0.0;
version = 1.1.0;
};
};
0A259AB3287D83F9006770E7 /* XCRemoteSwiftPackageReference "resolution-swift" */ = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -384,8 +384,8 @@
"repositoryURL": "https://github.com/KeystoneHQ/ur-registry-ios",
"state": {
"branch": null,
"revision": "10511be95146e8dfa2063e3ea21cceb9e6536fa1",
"version": "1.0.0"
"revision": "cafed3d8d3f73417c148d4a0b00046a45ef1ed30",
"version": "1.1.0"
}
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class CreateExportPasswordViewController: UIViewController {
var prompt: String = ""
var placeholder: String = ""
var plainTextPassword: String?
var passwordMeterEnabled: Bool = false
var completion: (String) -> Void = { _ in }
var validateValue: (String) -> Error? = { _ in nil }

Expand All @@ -22,7 +23,8 @@ class CreateExportPasswordViewController: UIViewController {
@IBOutlet weak var continueButton: UIButton!
@IBOutlet weak var scrollView: UIScrollView!
@IBOutlet weak var buttonBottomConstraint: NSLayoutConstraint!

@IBOutlet weak var passwordMeter: UIProgressView!

private var debounceTimer: Timer!
private let debounceDuration: TimeInterval = 0.250
private var isValid: Bool = false
Expand Down Expand Up @@ -50,6 +52,8 @@ class CreateExportPasswordViewController: UIViewController {
descriptionLabel.setStyle(.body)

continueButton.setText("Continue", .filled)

passwordMeter.isHidden = !passwordMeterEnabled

validateText()

Expand Down Expand Up @@ -107,15 +111,39 @@ class CreateExportPasswordViewController: UIViewController {
}
}

private func validateText() {
func passwordScore(_ text: String) -> Double {
// We define score P as:
// P[ L >= 8 ] = 8 * L * (1 + 0.1 * N + 0.1 * S + 0.1 * C)
// P[ L < 8 ] = 8 * L
// where L = length of the password text string
// N = 1 if password contains numbers, 0 otherwise
// S = 1 if password contains symbols, 0 otherwise
// C = 1 if password contains capital letters, 0 otherwise
// Maximum P value equals 100, i.e.:
// P = min(P, 100)
let L = Double(text.count)
let N = text.rangeOfCharacter(from: .decimalDigits) == nil ? 0 : 1.0
let S = text.rangeOfCharacter(from: .symbols) == nil ? 0 : 1.0
let C = text.rangeOfCharacter(from: .capitalizedLetters) == nil ? 0 : 1.0
let P = min(100, (L < 8) ? (8 * L) : (8 * L * (1 + 0.1 * N + 0.1 * S + 0.1 * C)) )
return P
}

fileprivate func resetText() {
isValid = false
continueButton.isEnabled = false
textField.setError(nil)
passwordMeter.progress = 0
}

private func validateText() {
resetText()
guard let text = textField.textField.text?.trimmingCharacters(in: .whitespacesAndNewlines),
!text.isEmpty else {
self.plainTextPassword = nil
return
}
passwordMeter.progress = Float(passwordScore(text) / 100)
if let error = validateValue(text) {
textField.setError(error)
return
Expand All @@ -135,6 +163,11 @@ extension CreateExportPasswordViewController: UITextFieldDelegate {
func textFieldDidBeginEditing(_ textField: UITextField) {
keyboardBehavior.activeTextField = textField
}

func textFieldShouldClear(_ textField: UITextField) -> Bool {
self.resetText()
return true
}

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
debounceTimer?.invalidate()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
<outlet property="buttonBottomConstraint" destination="BLR-Ri-2c1" id="4Mc-DW-AHm"/>
<outlet property="continueButton" destination="gXy-yX-Ihv" id="syz-ft-J4k"/>
<outlet property="descriptionLabel" destination="qCR-Ls-3Sv" id="jfH-3z-Fne"/>
<outlet property="passwordMeter" destination="gcV-dU-WLK" id="r9h-fI-pzf"/>
<outlet property="scrollView" destination="HvJ-08-RJo" id="Tzi-uc-zzt"/>
<outlet property="textField" destination="YAC-g2-UKn" id="96R-Fu-Bt2"/>
<outlet property="view" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/>
Expand All @@ -32,10 +33,10 @@
<rect key="frame" x="0.0" y="0.0" width="414" height="814"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="32" translatesAutoresizingMaskIntoConstraints="NO" id="1Gx-rA-E0l">
<rect key="frame" x="16" y="16" width="382" height="105"/>
<rect key="frame" x="16" y="16" width="382" height="117"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="LsW-zt-ujG">
<rect key="frame" x="0.0" y="0.0" width="382" height="105"/>
<rect key="frame" x="0.0" y="0.0" width="382" height="117"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Choose a password for protecting the exported data." textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="qCR-Ls-3Sv">
<rect key="frame" x="0.0" y="0.0" width="382" height="41"/>
Expand All @@ -50,6 +51,9 @@
<constraint firstAttribute="height" constant="56" placeholder="YES" id="OVz-U6-IPi"/>
</constraints>
</view>
<progressView opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="750" progress="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="gcV-dU-WLK">
<rect key="frame" x="0.0" y="113" width="382" height="4"/>
</progressView>
</subviews>
<constraints>
<constraint firstItem="YAC-g2-UKn" firstAttribute="width" secondItem="LsW-zt-ujG" secondAttribute="width" id="Zri-CE-aSn"/>
Expand Down
14 changes: 11 additions & 3 deletions Multisig/Features/Data Export/ExportDataFlow.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class ExportDataFlow: UIFlow {
vc.steps = [
.header,
.step(number: "1", title: "Create a file password", description: "Enter a strong password for locking the export file."),
.step(number: "2", title: "Export the data", description: "Data includes the owner keys, safes and address book in an encrypted file format."),
.step(number: "2", title: "Export the data", description: "Data includes private keys, safes and address book in an encrypted file format."),
.step(number: "3", title: "Save the data file", description: "Store the export file in Files on your device or a secure location of your choice."),
.finalStep(title: "Export of data completed!")
]
Expand All @@ -43,8 +43,16 @@ class ExportDataFlow: UIFlow {
func createPassword() {
let vc = CreateExportPasswordViewController(nibName: nil, bundle: nil)
vc.title = "Create password"
vc.prompt = "Choose a password for protecting the exported data."
vc.prompt = "Your password protects the data, including private keys.\n• At least 8 characters long.\n• Use numbers, symbols, and capital letters.\n• Use a password manager like 1Password or iCloud Keychain."
vc.placeholder = "Enter password"
vc.passwordMeterEnabled = true
vc.validateValue = { [unowned vc] value in
let score = vc.passwordScore(value)
if score < 64 {
return "Password must be at least 8 characters long."
}
return nil
}
vc.completion = { [unowned self] plainTextPassword in
repeatPassword(plainTextPassword)
}
Expand Down Expand Up @@ -81,7 +89,7 @@ class ExportDataFlow: UIFlow {
if let url = tempFileURL {
let vc = SuccessViewController(
titleText: "Export completed",
bodyText: "Exported data is encrypted and includes owner keys, list of safes and address book",
bodyText: "Exported data is encrypted and includes private keys, list of safes and address book.\n\nSave it to Files - On My iPhone.",
primaryAction: "Save",
secondaryAction: "Done"
)
Expand Down
2 changes: 1 addition & 1 deletion Multisig/Features/Data Export/ImportDataFlow.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class ImportDataFlow: UIFlow {
.step(number: "2", title: "Enter file password",
description: "Enter the password to access the data from the file"),
.step(number: "3", title: "Import the data",
description: "The imported data includes owner keys, safes and address book. Duplicates will be skipped."),
description: "The imported data includes private keys, safes and address book. Duplicates will be skipped."),
.finalStep(title: "Import of data completed!")
]

Expand Down

0 comments on commit 76008f9

Please sign in to comment.