mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-02 21:33:26 +00:00
Add timeouts after verifying the device owner when linking a new device. (#5970)
* Support for waitingForAuth continuation sender during Link new device
* Stop automatically regenerating new QR codes when they expire.
This reverts part of commit e235e3ba81.
* Add a timeout after the Face/TouchID verification when linking a desktop computer.
---------
Co-authored-by: Hugh Nimmo-Smith <hughns@element.io>
This commit is contained in:
@@ -377,7 +377,7 @@ private extension HumanQrLoginError {
|
||||
.qrCodeError(.deviceNotSignedIn)
|
||||
case .UnsupportedQrCodeType:
|
||||
.qrCodeError(.invalidQRCode)
|
||||
case .Unknown, .OAuthMetadataInvalid, .CheckCodeAlreadySent, .CheckCodeCannotBeSent, .ContinuationCannotBeSent, .ContinuationAlreadySent:
|
||||
case .Unknown, .OAuthMetadataInvalid, .CheckCodeAlreadySent, .CheckCodeCannotBeSent, .ContinuationAlreadySent, .ContinuationCannotBeSent:
|
||||
.qrCodeError(.unknown)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ class LinkNewDeviceService: LinkNewDeviceServiceProtocol {
|
||||
case starting
|
||||
case qrReady(UIImage)
|
||||
case qrScanned(CheckCodeSenderProxy)
|
||||
case waitingForAuthorisation(verificationURL: URL)
|
||||
case waitingForAuthorisation(verificationURL: URL, continuationSender: ContinuationMessageSenderProxy)
|
||||
case syncingSecrets
|
||||
case done
|
||||
}
|
||||
@@ -38,7 +38,7 @@ class LinkNewDeviceService: LinkNewDeviceServiceProtocol {
|
||||
enum LinkDesktopProgress: Equatable {
|
||||
case starting
|
||||
case establishingSecureChannel(checkCodeString: String)
|
||||
case waitingForAuthorisation(verificationURL: URL)
|
||||
case waitingForAuthorisation(verificationURL: URL, continuationSender: ContinuationMessageSenderProxy)
|
||||
case syncingSecrets
|
||||
case done
|
||||
}
|
||||
@@ -163,10 +163,10 @@ extension LinkNewDeviceService.LinkMobileProgress: CustomStringConvertible {
|
||||
throw Error.invalidQRCodeData
|
||||
}
|
||||
case .qrScanned(let checkCodeSender): .qrScanned(.init(underlyingSender: checkCodeSender))
|
||||
case .waitingForAuth(let verificationURI, _):
|
||||
case .waitingForAuth(let verificationURI, let continuationSender):
|
||||
// verificationURI is a String; ASWebAuthenticationSession requires a URL.
|
||||
if let url = URL(string: verificationURI) {
|
||||
.waitingForAuthorisation(verificationURL: url)
|
||||
.waitingForAuthorisation(verificationURL: url, continuationSender: .init(underlyingSender: continuationSender))
|
||||
} else {
|
||||
throw Error.invalidVerificationURI(verificationURI)
|
||||
}
|
||||
@@ -194,10 +194,10 @@ extension LinkNewDeviceService.LinkDesktopProgress: CustomStringConvertible {
|
||||
self = switch rustProgress {
|
||||
case .starting: .starting
|
||||
case .establishingSecureChannel(_, let checkCodeString): .establishingSecureChannel(checkCodeString: checkCodeString)
|
||||
case .waitingForAuth(let verificationURI, _):
|
||||
case .waitingForAuth(let verificationURI, let continuationSender):
|
||||
// verificationURI is a String; ASWebAuthenticationSession requires a URL.
|
||||
if let url = URL(string: verificationURI) {
|
||||
.waitingForAuthorisation(verificationURL: url)
|
||||
.waitingForAuthorisation(verificationURL: url, continuationSender: .init(underlyingSender: continuationSender))
|
||||
} else {
|
||||
throw Error.invalidVerificationURI(verificationURI)
|
||||
}
|
||||
@@ -240,8 +240,9 @@ private extension QRCodeLoginError {
|
||||
}
|
||||
}
|
||||
|
||||
nonisolated class CheckCodeSenderProxy: Equatable {
|
||||
final nonisolated class CheckCodeSenderProxy: Equatable, Sendable {
|
||||
static func == (lhs: CheckCodeSenderProxy, rhs: CheckCodeSenderProxy) -> Bool {
|
||||
// Not ideal but good enough as the equality check is purely for removing duplicates from the progress stream.
|
||||
lhs.underlyingSender === rhs.underlyingSender
|
||||
}
|
||||
|
||||
@@ -256,6 +257,35 @@ nonisolated class CheckCodeSenderProxy: Equatable {
|
||||
}
|
||||
}
|
||||
|
||||
final nonisolated class ContinuationMessageSenderProxy: Equatable, Sendable {
|
||||
static func == (lhs: ContinuationMessageSenderProxy, rhs: ContinuationMessageSenderProxy) -> Bool {
|
||||
// Not ideal but good enough as the equality check is purely for removing duplicates from the progress stream.
|
||||
lhs.underlyingSender === rhs.underlyingSender
|
||||
}
|
||||
|
||||
let underlyingSender: ContinuationMessageSenderProtocol
|
||||
|
||||
init(underlyingSender: ContinuationMessageSenderProtocol) {
|
||||
self.underlyingSender = underlyingSender
|
||||
}
|
||||
|
||||
func confirm() async {
|
||||
do {
|
||||
try await underlyingSender.confirm()
|
||||
} catch {
|
||||
MXLog.error("Failed to confirm the continuation of the login grant: \(error)")
|
||||
}
|
||||
}
|
||||
|
||||
func cancel() async {
|
||||
do {
|
||||
try await underlyingSender.cancel()
|
||||
} catch {
|
||||
MXLog.error("Failed to cancel the login grant: \(error)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension UIImage {
|
||||
convenience init?(qrCodeData: Data) {
|
||||
let qrContext = CIContext()
|
||||
|
||||
Reference in New Issue
Block a user