Skip to content
This repository has been archived by the owner on Jun 17, 2022. It is now read-only.

Commit

Permalink
[AuthService refactor] Don't clear state if 2FA is invalid (#690)
Browse files Browse the repository at this point in the history
* Don't clear state if 2FA is invalid

* Add session timeout to 2FA

* Clear internal authService state if unhandled error
  • Loading branch information
eliykat committed Feb 24, 2022
1 parent fdaa4f9 commit 1cbc119
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 4 deletions.
1 change: 1 addition & 0 deletions angular/src/services/jslib-services.module.ts
Expand Up @@ -119,6 +119,7 @@ import { ValidationService } from "./validation.service";
EnvironmentServiceAbstraction,
StateServiceAbstraction,
TwoFactorServiceAbstraction,
I18nServiceAbstraction,
],
},
{
Expand Down
41 changes: 37 additions & 4 deletions common/src/services/auth.service.ts
Expand Up @@ -3,6 +3,7 @@ import { AppIdService } from "../abstractions/appId.service";
import { AuthService as AuthServiceAbstraction } from "../abstractions/auth.service";
import { CryptoService } from "../abstractions/crypto.service";
import { EnvironmentService } from "../abstractions/environment.service";
import { I18nService } from "../abstractions/i18n.service";
import { KeyConnectorService } from "../abstractions/keyConnector.service";
import { LogService } from "../abstractions/log.service";
import { MessagingService } from "../abstractions/messaging.service";
Expand All @@ -24,6 +25,9 @@ import {
import { SymmetricCryptoKey } from "../models/domain/symmetricCryptoKey";
import { TokenRequestTwoFactor } from "../models/request/identityToken/tokenRequest";
import { PreloginRequest } from "../models/request/preloginRequest";
import { ErrorResponse } from "../models/response/errorResponse";

const sessionTimeoutLength = 2 * 60 * 1000; // 2 minutes

export class AuthService implements AuthServiceAbstraction {
get email(): string {
Expand All @@ -37,6 +41,7 @@ export class AuthService implements AuthServiceAbstraction {
}

private logInStrategy: ApiLogInStrategy | PasswordLogInStrategy | SsoLogInStrategy;
private sessionTimeout: any;

constructor(
protected cryptoService: CryptoService,
Expand All @@ -49,7 +54,8 @@ export class AuthService implements AuthServiceAbstraction {
protected keyConnectorService: KeyConnectorService,
protected environmentService: EnvironmentService,
protected stateService: StateService,
protected twoFactorService: TwoFactorService
protected twoFactorService: TwoFactorService,
protected i18nService: I18nService
) {}

async logIn(
Expand Down Expand Up @@ -110,10 +116,24 @@ export class AuthService implements AuthServiceAbstraction {
}

async logInTwoFactor(twoFactor: TokenRequestTwoFactor): Promise<AuthResult> {
if (this.logInStrategy == null) {
throw new Error(this.i18nService.t("sessionTimeout"));
}

try {
return await this.logInStrategy.logInTwoFactor(twoFactor);
} finally {
this.clearState();
const result = await this.logInStrategy.logInTwoFactor(twoFactor);

// Only clear state if 2FA token has been accepted, otherwise we need to be able to try again
if (!result.requiresTwoFactor) {
this.clearState();
}
return result;
} catch (e) {
// API exceptions are okay, but if there are any unhandled client-side errors then clear state to be safe
if (!(e instanceof ErrorResponse)) {
this.clearState();
}
throw e;
}
}

Expand Down Expand Up @@ -154,9 +174,22 @@ export class AuthService implements AuthServiceAbstraction {

private saveState(strategy: ApiLogInStrategy | PasswordLogInStrategy | SsoLogInStrategy) {
this.logInStrategy = strategy;
this.startSessionTimeout();
}

private clearState() {
this.logInStrategy = null;
this.clearSessionTimeout();
}

private startSessionTimeout() {
this.clearSessionTimeout();
this.sessionTimeout = setTimeout(() => this.clearState(), sessionTimeoutLength);
}

private clearSessionTimeout() {
if (this.sessionTimeout != null) {
clearTimeout(this.sessionTimeout);
}
}
}

0 comments on commit 1cbc119

Please sign in to comment.