Skip to content

Commit

Permalink
Rotate the session directory each time a new client is built for auth…
Browse files Browse the repository at this point in the history
…entication.
  • Loading branch information
pixlwave committed Aug 12, 2024
1 parent 8e9ed24 commit 5e36811
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 15 deletions.
2 changes: 1 addition & 1 deletion ElementX/Sources/Other/Extensions/FileManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ enum FileManagerError: Error {
extension FileManager {
func directoryExists(at url: URL) -> Bool {
var isDirectory: ObjCBool = false
guard fileExists(atPath: url.path(), isDirectory: &isDirectory) else {
guard fileExists(atPath: url.path(percentEncoded: false), isDirectory: &isDirectory) else {
return false
}
return isDirectory.boolValue
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import MatrixRustSDK

class AuthenticationService: AuthenticationServiceProtocol {
private var client: Client?
private let sessionDirectory: URL
private var sessionDirectory: URL
private let passphrase: String

private let userSessionStore: UserSessionStoreProtocol
Expand Down Expand Up @@ -139,7 +139,11 @@ class AuthenticationService: AuthenticationServiceProtocol {
// MARK: - Private

private func makeClientBuilder() -> ClientBuilder {
ClientBuilder
// Use a fresh session directory each time the user enters a different server
// so that caches (e.g. server versions) are always fresh for the new server.
rotateSessionDirectory()

return ClientBuilder
.baseBuilder(httpProxy: appSettings.websiteURL.globalProxy,
slidingSync: appSettings.simplifiedSlidingSyncEnabled ? .simplified : .discovered,
slidingSyncProxy: appSettings.slidingSyncProxyURL,
Expand All @@ -149,6 +153,14 @@ class AuthenticationService: AuthenticationServiceProtocol {
.passphrase(passphrase: passphrase)
}

private func rotateSessionDirectory() {
if FileManager.default.directoryExists(at: sessionDirectory) {
try? FileManager.default.removeItem(at: sessionDirectory)
}

sessionDirectory = .sessionsBaseDirectory.appending(component: UUID().uuidString)
}

private func userSession(for client: Client) async -> Result<UserSessionProtocol, AuthenticationServiceError> {
switch await userSessionStore.userSession(for: client, sessionDirectory: sessionDirectory, passphrase: passphrase) {
case .success(let clientProxy):
Expand Down
43 changes: 31 additions & 12 deletions ElementX/Sources/Services/QRCode/QRCodeLoginService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import Foundation
import MatrixRustSDK

final class QRCodeLoginService: QRCodeLoginServiceProtocol {
private let sessionDirectory: URL
private var sessionDirectory: URL
private let passphrase: String

private let userSessionStore: UserSessionStoreProtocol
Expand Down Expand Up @@ -57,16 +57,10 @@ final class QRCodeLoginService: QRCodeLoginServiceProtocol {
}

do {
let client = try await ClientBuilder
.baseBuilder(httpProxy: appSettings.websiteURL.globalProxy,
slidingSync: appSettings.simplifiedSlidingSyncEnabled ? .simplified : .discovered,
slidingSyncProxy: appSettings.slidingSyncProxyURL,
sessionDelegate: userSessionStore.clientSessionDelegate,
appHooks: appHooks)
.sessionPath(path: sessionDirectory.path(percentEncoded: false))
.passphrase(passphrase: passphrase)
.buildWithQrCode(qrCodeData: qrData, oidcConfiguration: appSettings.oidcConfiguration.rustValue, progressListener: listener)
return await login(client: client)
let client = try await makeClientBuilder().buildWithQrCode(qrCodeData: qrData,
oidcConfiguration: appSettings.oidcConfiguration.rustValue,
progressListener: listener)
return await userSession(for: client)
} catch let error as HumanQrLoginError {
MXLog.error("QRCode login error: \(error)")
return .failure(error.serviceError)
Expand All @@ -76,7 +70,32 @@ final class QRCodeLoginService: QRCodeLoginServiceProtocol {
}
}

private func login(client: Client) async -> Result<UserSessionProtocol, QRCodeLoginServiceError> {
// MARK: - Private

private func makeClientBuilder() -> ClientBuilder {
// Use a fresh session directory each time the user scans a QR code to ensure caches
// (e.g. server versions) are always fresh in case a different server is used.
rotateSessionDirectory()

return ClientBuilder
.baseBuilder(httpProxy: appSettings.websiteURL.globalProxy,
slidingSync: appSettings.simplifiedSlidingSyncEnabled ? .simplified : .discovered,
slidingSyncProxy: appSettings.slidingSyncProxyURL,
sessionDelegate: userSessionStore.clientSessionDelegate,
appHooks: appHooks)
.sessionPath(path: sessionDirectory.path(percentEncoded: false))
.passphrase(passphrase: passphrase)
}

private func rotateSessionDirectory() {
if FileManager.default.directoryExists(at: sessionDirectory) {
try? FileManager.default.removeItem(at: sessionDirectory)
}

sessionDirectory = .sessionsBaseDirectory.appending(component: UUID().uuidString)
}

private func userSession(for client: Client) async -> Result<UserSessionProtocol, QRCodeLoginServiceError> {
switch await userSessionStore.userSession(for: client, sessionDirectory: sessionDirectory, passphrase: passphrase) {
case .success(let session):
return .success(session)
Expand Down

0 comments on commit 5e36811

Please sign in to comment.