mirror of
https://github.com/vector-im/element-ios.git
synced 2024-09-28 23:32:41 +00:00
Multi session logut
This commit is contained in:
parent
1a6486a41c
commit
d2cde943de
6 changed files with 72 additions and 8 deletions
|
@ -78,7 +78,7 @@ final class CrossSigningService: NSObject {
|
|||
|
||||
func setupCrossSigningRequest() -> AuthenticatedEndpointRequest {
|
||||
let path = "\(kMXAPIPrefixPathUnstable)/keys/device_signing/upload"
|
||||
return AuthenticatedEndpointRequest(path: path, httpMethod: "POST")
|
||||
return AuthenticatedEndpointRequest(path: path, httpMethod: "POST", params: [:])
|
||||
}
|
||||
|
||||
/// Setup cross-signing without authentication. Useful when a grace period is enabled.
|
||||
|
|
|
@ -47,7 +47,7 @@ enum DeactivateAccountServiceError: Error {
|
|||
@objcMembers class DeactivateAccountService: NSObject {
|
||||
private let session: MXSession
|
||||
private let uiaService: UserInteractiveAuthenticationService
|
||||
private let request = AuthenticatedEndpointRequest(path: "\(kMXAPIPrefixPathR0)/account/deactivate", httpMethod: "POST")
|
||||
private let request = AuthenticatedEndpointRequest(path: "\(kMXAPIPrefixPathR0)/account/deactivate", httpMethod: "POST", params: [:])
|
||||
|
||||
/// The authentication session's ID if interactive authentication has begun, otherwise `nil`.
|
||||
private var sessionID: String?
|
||||
|
|
|
@ -673,7 +673,7 @@ enum {
|
|||
NSString *title = [VectorL10n deviceDetailsDeletePromptTitle];
|
||||
NSString *message = [VectorL10n deviceDetailsDeletePromptMessage];
|
||||
|
||||
AuthenticatedEndpointRequest *deleteDeviceRequest = [[AuthenticatedEndpointRequest alloc] initWithPath:[NSString stringWithFormat:@"%@/devices/%@", kMXAPIPrefixPathR0, [MXTools encodeURIComponent:device.deviceId]] httpMethod:@"DELETE"];
|
||||
AuthenticatedEndpointRequest *deleteDeviceRequest = [[AuthenticatedEndpointRequest alloc] initWithPath:[NSString stringWithFormat:@"%@/devices/%@", kMXAPIPrefixPathR0, [MXTools encodeURIComponent:device.deviceId]] httpMethod:@"DELETE" params:[[NSDictionary alloc] init]];
|
||||
|
||||
ReauthenticationCoordinatorParameters *coordinatorParameters = [[ReauthenticationCoordinatorParameters alloc] initWithSession:self.mainSession presenter:self title:title message:message authenticatedEndpointRequest:deleteDeviceRequest];
|
||||
|
||||
|
|
|
@ -22,10 +22,11 @@ class AuthenticatedEndpointRequest: NSObject {
|
|||
|
||||
let path: String
|
||||
let httpMethod: String
|
||||
|
||||
init(path: String, httpMethod: String) {
|
||||
let params: [String: Any]
|
||||
init(path: String, httpMethod: String, params: [String: Any]) {
|
||||
self.path = path
|
||||
self.httpMethod = httpMethod
|
||||
self.params = params
|
||||
super.init()
|
||||
}
|
||||
}
|
||||
|
@ -37,6 +38,15 @@ extension AuthenticatedEndpointRequest {
|
|||
/// - Parameter deviceID: The device ID that is to be deleted.
|
||||
static func deleteDevice(_ deviceID: String) -> AuthenticatedEndpointRequest {
|
||||
let path = String(format: "%@/devices/%@", kMXAPIPrefixPathR0, MXTools.encodeURIComponent(deviceID))
|
||||
return AuthenticatedEndpointRequest(path: path, httpMethod: "DELETE")
|
||||
return AuthenticatedEndpointRequest(path: path, httpMethod: "DELETE", params: [:])
|
||||
}
|
||||
}
|
||||
|
||||
extension AuthenticatedEndpointRequest {
|
||||
/// Create an authenticated request on `_matrix/client/r0/delete_devices`.
|
||||
/// - Parameter deviceID: The device ID that is to be deleted.
|
||||
static func deleteDevices(_ deviceIDs: [String]) -> AuthenticatedEndpointRequest {
|
||||
let path = String(format: "%@/delete_devices", kMXAPIPrefixPathR0)
|
||||
return AuthenticatedEndpointRequest(path: path, httpMethod: "POST", params: ["devices": deviceIDs])
|
||||
}
|
||||
}
|
||||
|
|
|
@ -131,7 +131,7 @@ final class UserInteractiveAuthenticationService: NSObject {
|
|||
success: @escaping (MXAuthenticationSession?) -> Void,
|
||||
failure: @escaping (Error) -> Void) -> MXHTTPOperation {
|
||||
// Get the authentication flow required for this API
|
||||
return self.session.matrixRestClient.authSessionForRequest(withMethod: request.httpMethod, path: request.path, parameters: [:], success: { [weak self] (authenticationSession) in
|
||||
return self.session.matrixRestClient.authSessionForRequest(withMethod: request.httpMethod, path: request.path, parameters: request.params, success: { [weak self] (authenticationSession) in
|
||||
guard let self = self else {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -184,7 +184,7 @@ final class UserSessionsFlowCoordinator: Coordinator, Presentable {
|
|||
if sessionInfos.count == 1, let onlySession = sessionInfos.first {
|
||||
self?.showLogoutAuthentication(for: onlySession)
|
||||
} else {
|
||||
// todo:
|
||||
self?.showLogoutAuthenticationAndLogoutFromSessions(sessionInfos: sessionInfos)
|
||||
}
|
||||
})
|
||||
alert.addAction(UIAlertAction(title: VectorL10n.cancel, style: .cancel))
|
||||
|
@ -228,6 +228,60 @@ final class UserSessionsFlowCoordinator: Coordinator, Presentable {
|
|||
reauthenticationPresenter = presenter
|
||||
}
|
||||
|
||||
|
||||
|
||||
// TODO: move to into a command
|
||||
private func showLogoutAuthenticationAndLogoutFromSessions(sessionInfos: [UserSessionInfo]) {
|
||||
startLoading()
|
||||
let deviceIds = sessionInfos.map { $0.id }
|
||||
let deleteDeviceRequest = AuthenticatedEndpointRequest.deleteDevices(deviceIds)
|
||||
let coordinatorParameters = ReauthenticationCoordinatorParameters(session: parameters.session,
|
||||
presenter: navigationRouter.toPresentable(),
|
||||
title: VectorL10n.deviceDetailsDeletePromptTitle,
|
||||
message: VectorL10n.deviceDetailsDeletePromptMessage,
|
||||
authenticatedEndpointRequest: deleteDeviceRequest)
|
||||
let presenter = ReauthenticationCoordinatorBridgePresenter()
|
||||
presenter.present(with: coordinatorParameters, animated: true) { [weak self] authenticationParameters in
|
||||
self?.finalizeLogout2(of: deviceIds, with: authenticationParameters)
|
||||
self?.reauthenticationPresenter = nil
|
||||
} cancel: { [weak self] in
|
||||
self?.stopLoading()
|
||||
self?.reauthenticationPresenter = nil
|
||||
} failure: { [weak self] error in
|
||||
guard let self = self else { return }
|
||||
self.stopLoading()
|
||||
self.errorPresenter.presentError(from: self.toPresentable(), forError: error, animated: true, handler: { })
|
||||
self.reauthenticationPresenter = nil
|
||||
}
|
||||
|
||||
reauthenticationPresenter = presenter
|
||||
}
|
||||
|
||||
private func finalizeLogout2(of deviceIds: [String], with authenticationParameters: [String: Any]?) {
|
||||
|
||||
parameters.session.matrixRestClient.deleteDevices(deviceIds,
|
||||
authParameters: authenticationParameters ?? [:]) { [weak self] response in
|
||||
guard let self = self else { return }
|
||||
|
||||
self.stopLoading()
|
||||
|
||||
guard response.isSuccess else {
|
||||
MXLog.debug("[UserSessionsFlowCoordinator] Delete devices failed")
|
||||
if let error = response.error {
|
||||
self.errorPresenter.presentError(from: self.toPresentable(), forError: error, animated: true, handler: { })
|
||||
} else {
|
||||
self.errorPresenter.presentGenericError(from: self.toPresentable(), animated: true, handler: { })
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
self.popToSessionsOverview()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// Finishes the logout process by deleting the device from the user's account.
|
||||
/// - Parameters:
|
||||
/// - sessionInfo: The `UserSessionInfo` for the session to be removed.
|
||||
|
|
Loading…
Reference in a new issue