Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ public enum AuthenticationAPIError: Error {

case serviceUnavailable

case tooManyRequests(_ message: String, retyAfter: TimeInterval?)

/// Thrown by `requestVerificationCode(for:)`.

case invalidEmail
Expand Down Expand Up @@ -73,7 +75,6 @@ public extension AuthenticationAPIError {
case userCreationRestricted

case unauthorized

}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,41 +73,51 @@ class AuthenticationAPIV0: AuthenticationAPI, VersionedAPI {
for: responseURL
)

let accessToken = try ResponseParser()
.success(
code: .ok,
type: AccessTokenV0.self
)
.failure(
code: .forbidden,
label: "code-authentication-required",
error: AuthenticationAPIError.twoFactorAuthenticationRequired
)
.failure(
code: .forbidden,
label: "code-authentication-failed",
error: AuthenticationAPIError.twoFactorAuthenticationFailed
)
.failure(
code: .forbidden,
label: "pending-activation",
error: AuthenticationAPIError.accountPendingActivation
)
.failure(
code: .forbidden,
label: "suspended",
error: AuthenticationAPIError.accountSuspended
)
.failure(
code: .forbidden,
label: "invalid-credentials",
error: AuthenticationAPIError.invalidCredentials
)
.parse(
code: response.statusCode,
data: data
)

let accessToken: AccessToken
do {
accessToken = try ResponseParser()
.success(
code: .ok,
type: AccessTokenV0.self
)
.failure(
code: .forbidden,
label: "code-authentication-required",
error: AuthenticationAPIError.twoFactorAuthenticationRequired
)
.failure(
code: .forbidden,
label: "code-authentication-failed",
error: AuthenticationAPIError.twoFactorAuthenticationFailed
)
.failure(
code: .forbidden,
label: "pending-activation",
error: AuthenticationAPIError.accountPendingActivation
)
.failure(
code: .forbidden,
label: "suspended",
error: AuthenticationAPIError.accountSuspended
)
.failure(
code: .forbidden,
label: "invalid-credentials",
error: AuthenticationAPIError.invalidCredentials
)
.failure(code: .tooManyRequests, decodableError: FailureResponseV0.self)
.parse(
code: response.statusCode,
data: data
)
} catch let error as FailureResponseV0 {
if error.code == HTTPStatusCode.tooManyRequests.rawValue && error.label == "client-error" {
let retryAfter = responseHeaders["retry-after"].flatMap { TimeInterval($0) }
throw AuthenticationAPIError.tooManyRequests(error.message, retyAfter: retryAfter)
}
throw error
}

return (cookies, accessToken)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ enum HTTPStatusCode: Int {
/// conflict - 409

case conflict = 409

// too many requests - 429

case tooManyRequests = 429

/// domain blocked - 451

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,16 +69,18 @@ extension ZMUserSession {

func close(deleteCookie: Bool, completion: @escaping () -> Void) {
// Clear all notifications associated with the account from the notification center
syncManagedObjectContext.performGroupedBlock {
self.localNotificationDispatcher?.cancelAllNotifications()

syncManagedObjectContext.performAndWait { [weak self] in
self?.syncManagedObjectContext.disableSaves()
self?.localNotificationDispatcher?.cancelAllNotifications()
}

if deleteCookie {
deleteUserKeychainItems()
}

syncManagedObjectContext.perform {
self.tearDown()
syncManagedObjectContext.performAndWait { [weak self] in
self?.tearDown()
}

completion()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -655,7 +655,9 @@ public final class ZMUserSession: NSObject {
operationLoop = nil
transportSession.tearDown()
notificationDispatcher.tearDown()
callCenter?.tearDown()
managedObjectContext.performAndWait { [weak self] in
self?.callCenter?.tearDown()
}
coreDataStack.close()
contextStorage.clear()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ final class LogOutHelper {
return viewController
}

private func logout(password: String? = nil) {
func logout(password: String? = nil) {
guard let selfUser = ZMUser.selfUser() else { return }

if selfUser.usesCompanyLogin || password != nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,9 @@ final class DeveloperDebugActionsViewModel: ObservableObject {
.init(title: "Clear collapsed messages cache", action: clearCollapsedMessagesCache),
.init(title: "Simulate access token failure", action: simulateAccessTokenFailure),
.init(title: "Invalidate all conversations", action: invalidateAllConversations),
.init(title: "Set last app version migration", action: requestAppVersionInput)
.init(title: "Set last app version migration", action: requestAppVersionInput),
.init(title: "Logout", action: logout)

]

let toggleItems: [DeveloperDebugActionsDisplayModel.ToggleItem] = [
Expand Down Expand Up @@ -147,6 +149,10 @@ final class DeveloperDebugActionsViewModel: ObservableObject {

// MARK: - Forces logout

func logout() {
LogOutHelper(showLoading: {}, hideLoading: {}).logout()
}

private func simulateAccessTokenFailure() {
guard let selfUserID = userSession?.managedObjectContext.performAndWait({
userSession?.selfUser.remoteIdentifier
Expand Down