Skip to content

Commit

Permalink
Merge pull request #3353 from safe-global/GH-3337/various-fixes
Browse files Browse the repository at this point in the history
Gh 3337/various fixes
  • Loading branch information
DmitryBespalov authored Oct 5, 2023
2 parents 12f8f1f + 61ca62f commit 0997c58
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 26 deletions.
2 changes: 1 addition & 1 deletion Multisig/App/SceneDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
// - 'connect' link to establish new connection
// - 'open' link to move the app to foreground so that it is able to process WalletConnect request or response.
// - Request To Add Owner
// - <web app url>/addOwner?safe=<safe_address>&address=<owner_address>
// - <web app url>/settings/setup?safe=<safe_address>&address=<owner_address>
// - Web3auth
// - handled by CustomAuth.handle()
private func handleUserActivity(_ userActivity: NSUserActivity) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,13 +177,23 @@ class WebConnectionsViewController: UITableViewController, ExternalURLSource, We
// MARK: - Table view delegate

override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
// we want the header view to appear at the top of the table, so we show it not in the data section but
// in the warning section
guard section == warningSection else { return nil }
let view = tableView.dequeueHeaderFooterView(DesktopPairingHeaderView.self)
view.onScan = { [unowned self] in
self.scan()
}
return view
}

override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
if section == warningSection {
return UITableView.automaticDimension
} else {
return 0
}
}

override func tableView(_ tableView: UITableView,
trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
Expand Down
2 changes: 1 addition & 1 deletion Multisig/UI/App/NavigationRouter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ extension NavigationRoute {

// MARK: Onboarding

static let requestToAddOwnerPath = "/addOwner"
static let requestToAddOwnerPath = "/settings/setup"

static func requestToAddOwner(_ params: AddOwnerRequestParameters) -> NavigationRoute {
var route = NavigationRoute(path: requestToAddOwnerPath)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ class BalancesViewController: LoadableViewController, UITableViewDelegate, UITab
}

@objc private func doReloadData() {
guard (try? Safe.getSelected())?.safeStatus == .deployed else { return }
reloadData()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ struct AddOwnerRequestParameters {

func link(base: URL = App.configuration.services.webAppURL) -> String {
var url = base
.appendingPathComponent("addOwner")
.appendingPathComponent("settings")
.appendingPathComponent("setup")

let result: String

Expand Down Expand Up @@ -46,10 +47,10 @@ struct AddOwnerRequestValidator {
}
set {
_webAppURL = newValue
pattern = "^\(newValue)addOwner\\?safe=([-a-zA-Z0-9]{1,20}):(0x[a-fA-F0-9]{40})&address=(0x[a-fA-F0-9]{40})$"
pattern = "^\(newValue)settings/setup\\?safe=([-a-zA-Z0-9]{1,20}):(0x[a-fA-F0-9]{40})&address=(0x[a-fA-F0-9]{40})$"
}
}
private static var pattern = "^\(webAppURL)addOwner\\?safe=([-a-zA-Z0-9]{1,20}):(0x[a-fA-F0-9]{40})&address=(0x[a-fA-F0-9]{40})$"
private static var pattern = "^\(webAppURL)settings/setup\\?safe=([-a-zA-Z0-9]{1,20}):(0x[a-fA-F0-9]{40})&address=(0x[a-fA-F0-9]{40})$"

static func isValid(url: URL) -> Bool {
guard url.absoluteString.matches(pattern: pattern) else { return false }
Expand Down
42 changes: 21 additions & 21 deletions MultisigTests/Logic/AddOwnerRequestValidatorTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,42 +22,42 @@ class AddOwnerRequestValidatorTests: XCTestCase {
assertInvalid("https://\(domain)", "missing path and query")
assertInvalid("ftp://url?query=https://\(domain)/", "must start with the correct link")
assertInvalid("https://\(domain)/", "missing rest of the path and query")
assertInvalid("https://\(domain)/addOwner?safe=something&address=else", "wrong format of path and query parameters")
assertInvalid("https://\(domain)/eth:0x71592E6Cbe7779D480C1D029e70904041F8f602A/addOwner", "missing owner address query parameter")
assertInvalid("https://\(domain)/settings/setup?safe=something&address=else", "wrong format of path and query parameters")
assertInvalid("https://\(domain)/eth:0x71592E6Cbe7779D480C1D029e70904041F8f602A/settings/setup", "missing owner address query parameter")

// shortname with dash
assertValid("https://\(domain)/addOwner?safe=eth-weth:0x71592E6Cbe7779D480C1D029e70904041F8f602A&address=0x8e6A5aDb2B88257A3DAc7A76A7B4EcaCdA090b66", "must support dash in shortname")
assertValid("https://\(domain)/settings/setup?safe=eth-weth:0x71592E6Cbe7779D480C1D029e70904041F8f602A&address=0x8e6A5aDb2B88257A3DAc7A76A7B4EcaCdA090b66", "must support dash in shortname")

// shortname empty, 1, 20, 21
assertValid("https://\(domain)/addOwner?safe=a:0x71592E6Cbe7779D480C1D029e70904041F8f602A&address=0x8e6A5aDb2B88257A3DAc7A76A7B4EcaCdA090b66", "must support one-char shortname")
assertValid("https://\(domain)/addOwner?safe=abcde12345abcde12345:0x71592E6Cbe7779D480C1D029e70904041F8f602A&address=0x8e6A5aDb2B88257A3DAc7A76A7B4EcaCdA090b66", "must support 20-char shortname")
assertInvalid("https://\(domain)/addOwner?safe=abcde12345abcde12345e:0x71592E6Cbe7779D480C1D029e70904041F8f602A&address=0x8e6A5aDb2B88257A3DAc7A76A7B4EcaCdA090b66", "shortname too long")
assertInvalid("https://\(domain)/addOwner?safe=:0x71592E6Cbe7779D480C1D029e70904041F8f602A&address=0x8e6A5aDb2B88257A3DAc7A76A7B4EcaCdA090b66", "shortname empty")
assertValid("https://\(domain)/settings/setup?safe=a:0x71592E6Cbe7779D480C1D029e70904041F8f602A&address=0x8e6A5aDb2B88257A3DAc7A76A7B4EcaCdA090b66", "must support one-char shortname")
assertValid("https://\(domain)/settings/setup?safe=abcde12345abcde12345:0x71592E6Cbe7779D480C1D029e70904041F8f602A&address=0x8e6A5aDb2B88257A3DAc7A76A7B4EcaCdA090b66", "must support 20-char shortname")
assertInvalid("https://\(domain)/settings/setup?safe=abcde12345abcde12345e:0x71592E6Cbe7779D480C1D029e70904041F8f602A&address=0x8e6A5aDb2B88257A3DAc7A76A7B4EcaCdA090b66", "shortname too long")
assertInvalid("https://\(domain)/settings/setup?safe=:0x71592E6Cbe7779D480C1D029e70904041F8f602A&address=0x8e6A5aDb2B88257A3DAc7A76A7B4EcaCdA090b66", "shortname empty")

// safe address: empty, 39, 40, 41, hex, checksum wrong
assertInvalid("https://\(domain)/addOwner?safe=eth:&address=0x8e6A5aDb2B88257A3DAc7A76A7B4EcaCdA090b66", "safe address empty")
assertInvalid("https://\(domain)/addOwner?safe=eth:0x71592E6Cbe7779D480C1D029e70904041F8f602&address=0x8e6A5aDb2B88257A3DAc7A76A7B4EcaCdA090b66", "safe address too short")
assertInvalid("https://\(domain)/addOwner?safe=eth:0x71592E6Cbe7779D480C1D029e70904041F8f602A1&address=0x8e6A5aDb2B88257A3DAc7A76A7B4EcaCdA090b66", "safe address too long")
assertValid("https://\(domain)/addOwner?safe=eth:0x71592E6Cbe7779D480C1D029e70904041F8f602A&address=0x8e6A5aDb2B88257A3DAc7A76A7B4EcaCdA090b66", "must support hex safe address")
assertInvalid("https://\(domain)/addOwner?safe=eth:0x71592E6Cbe7779D480C1D029e70904041f8f602A&address=0x8e6A5aDb2B88257A3DAc7A76A7B4EcaCdA090b66", "must detect wrong checksum in safe address")
assertInvalid("https://\(domain)/settings/setup?safe=eth:&address=0x8e6A5aDb2B88257A3DAc7A76A7B4EcaCdA090b66", "safe address empty")
assertInvalid("https://\(domain)/settings/setup?safe=eth:0x71592E6Cbe7779D480C1D029e70904041F8f602&address=0x8e6A5aDb2B88257A3DAc7A76A7B4EcaCdA090b66", "safe address too short")
assertInvalid("https://\(domain)/settings/setup?safe=eth:0x71592E6Cbe7779D480C1D029e70904041F8f602A1&address=0x8e6A5aDb2B88257A3DAc7A76A7B4EcaCdA090b66", "safe address too long")
assertValid("https://\(domain)/settings/setup?safe=eth:0x71592E6Cbe7779D480C1D029e70904041F8f602A&address=0x8e6A5aDb2B88257A3DAc7A76A7B4EcaCdA090b66", "must support hex safe address")
assertInvalid("https://\(domain)/settings/setup?safe=eth:0x71592E6Cbe7779D480C1D029e70904041f8f602A&address=0x8e6A5aDb2B88257A3DAc7A76A7B4EcaCdA090b66", "must detect wrong checksum in safe address")

// owner address: empty, 39, 40, 41, hex, checksum wrong
assertInvalid("https://\(domain)/addOwner?safe=eth:0x71592E6Cbe7779D480C1D029e70904041F8f602A&address=", "owner address empty")
assertInvalid("https://\(domain)/addOwner?safe=eth:0x71592E6Cbe7779D480C1D029e70904041F8f602A&address=0x8e6A5aDb2B88257A3DAc7A76A7B4EcaCdA090b6", "owner address too short")
assertInvalid("https://\(domain)/addOwner?safe=eth:0x71592E6Cbe7779D480C1D029e70904041F8f602A&address=0x8e6A5aDb2B88257A3DAc7A76A7B4EcaCdA090b66a", "owner address too long")
assertValid("https://\(domain)/addOwner?safe=eth:0x71592E6Cbe7779D480C1D029e70904041F8f602A&address=0x8e6a5adb2b88257a3dac7a76a7b4ecacda090b66", "must support hex owner address")
assertInvalid("https://\(domain)/addOwner?safe=eth:0x71592E6Cbe7779D480C1D029e70904041F8f602A&address=0x8e6A5aDb2B88257A3DAc7A76A7B4EcaCdA090B66", "must detect wrong checksum in owner address")
assertInvalid("https://\(domain)/settings/setup?safe=eth:0x71592E6Cbe7779D480C1D029e70904041F8f602A&address=", "owner address empty")
assertInvalid("https://\(domain)/settings/setup?safe=eth:0x71592E6Cbe7779D480C1D029e70904041F8f602A&address=0x8e6A5aDb2B88257A3DAc7A76A7B4EcaCdA090b6", "owner address too short")
assertInvalid("https://\(domain)/settings/setup?safe=eth:0x71592E6Cbe7779D480C1D029e70904041F8f602A&address=0x8e6A5aDb2B88257A3DAc7A76A7B4EcaCdA090b66a", "owner address too long")
assertValid("https://\(domain)/settings/setup?safe=eth:0x71592E6Cbe7779D480C1D029e70904041F8f602A&address=0x8e6a5adb2b88257a3dac7a76a7b4ecacda090b66", "must support hex owner address")
assertInvalid("https://\(domain)/settings/setup?safe=eth:0x71592E6Cbe7779D480C1D029e70904041F8f602A&address=0x8e6A5aDb2B88257A3DAc7A76A7B4EcaCdA090B66", "must detect wrong checksum in owner address")

// additional params
assertInvalid("https://\(domain)/addOwner?safe=eth:0x71592E6Cbe7779D480C1D029e70904041F8f602A&address=0x8e6A5aDb2B88257A3DAc7A76A7B4EcaCdA090b66&some=value", "happy case not working")
assertInvalid("https://\(domain)/settings/setup?safe=eth:0x71592E6Cbe7779D480C1D029e70904041F8f602A&address=0x8e6A5aDb2B88257A3DAc7A76A7B4EcaCdA090b66&some=value", "happy case not working")


// happy case
assertValid("https://\(domain)/addOwner?safe=eth:0x71592E6Cbe7779D480C1D029e70904041F8f602A&address=0x8e6A5aDb2B88257A3DAc7A76A7B4EcaCdA090b66", "happy case not working")
assertValid("https://\(domain)/settings/setup?safe=eth:0x71592E6Cbe7779D480C1D029e70904041F8f602A&address=0x8e6A5aDb2B88257A3DAc7A76A7B4EcaCdA090b66", "happy case not working")
}

func testExtractsParameters() {
let url = URL(string: "https://\(domain)/addOwner?safe=eth:0x71592E6Cbe7779D480C1D029e70904041F8f602A&address=0x8e6A5aDb2B88257A3DAc7A76A7B4EcaCdA090b66")!
let url = URL(string: "https://\(domain)/settings/setup?safe=eth:0x71592E6Cbe7779D480C1D029e70904041F8f602A&address=0x8e6A5aDb2B88257A3DAc7A76A7B4EcaCdA090b66")!
guard let parameters = AddOwnerRequestValidator.parameters(from: url) else {
XCTFail("Parameters not found in correct link")
return
Expand All @@ -75,7 +75,7 @@ class AddOwnerRequestValidatorTests: XCTestCase {
ownerAddress: "0x8e6A5aDb2B88257A3DAc7A76A7B4EcaCdA090b66"
).link(base: AddOwnerRequestValidator.webAppURL)

XCTAssertEqual(str, "https://\(domain)/addOwner?safe=eth:0x71592E6Cbe7779D480C1D029e70904041F8f602A&address=0x8e6A5aDb2B88257A3DAc7A76A7B4EcaCdA090b66")
XCTAssertEqual(str, "https://\(domain)/settings/setup?safe=eth:0x71592E6Cbe7779D480C1D029e70904041F8f602A&address=0x8e6A5aDb2B88257A3DAc7A76A7B4EcaCdA090b66")
}

func assertInvalid(_ str: String, _ message: String, line: UInt = #line) {
Expand Down

0 comments on commit 0997c58

Please sign in to comment.