diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d51d0e2..d0f7d48d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,8 +17,9 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ### Fixed - Fixed pagination project overview - [#564](https://github.com/DigitalExcellence/dex-frontend/issues/564) -- Fixed the navbar for longer names, adjusted the loading animation to be smooth. - [#593](https://github.com/DigitalExcellence/dex-frontend/issues/593) - Added a close button onto the add project modal, ignore background click - [#558](https://github.com/DigitalExcellence/dex-frontend/issues/558) +- Fixed input being lost upon session timeout - [#559](https://github.com/DigitalExcellence/dex-frontend/issues/559) +- Fixed the navbar for longer names, adjusted the loading animation to be smooth. - [#593](https://github.com/DigitalExcellence/dex-frontend/issues/593) ### Security diff --git a/src/app/interceptors/http.interceptor.ts b/src/app/interceptors/http.interceptor.ts index aa99ff08..f3151932 100644 --- a/src/app/interceptors/http.interceptor.ts +++ b/src/app/interceptors/http.interceptor.ts @@ -24,6 +24,7 @@ import { AlertConfig } from 'src/app/models/internal/alert-config'; import { AlertType } from 'src/app/models/internal/alert-type'; import { DeXHttpErrorResponse } from 'src/app/models/internal/dex-http-error-response'; import { AlertService } from 'src/app/services/alert.service'; +import { AuthService } from 'src/app/services/auth.service'; import { environment } from 'src/environments/environment'; /** @@ -70,7 +71,8 @@ export class HttpErrorInterceptor implements HttpInterceptor { ]; constructor( - private alertService: AlertService + private alertService: AlertService, + private authService: AuthService ) { } /** @@ -112,10 +114,17 @@ export class HttpErrorInterceptor implements HttpInterceptor { 'Please check your internet connection')); } else { // API Could be reached but returned error - // tslint:disable-next-line: max-line-length - this.alertService.pushAlert(this.createErrorAlertConfig(httpErrorResponse.error.title, httpErrorResponse.error.detail)); + this.alertService.pushAlert(this.createErrorAlertConfig(httpErrorResponse.error.title, + httpErrorResponse.error.detail)); + } + // Api returned unauthorized. + if (httpErrorResponse.status === 401) { + if (this.authService.isUserExpired()) { + this.authService.silentLogin(); + return EMPTY; + } + return EMPTY; } - // Return if the status codes are ignored. if (this.ignoredStatusCodes.includes(httpErrorResponse.status)) { return EMPTY; @@ -134,20 +143,20 @@ export class HttpErrorInterceptor implements HttpInterceptor { ); } - /** - * Method to return the default error AlertConfig for HttpInterceptor - * @param preMessage the alert message prefix. - * @param mainMessage the alert message main content. - */ + /** + * Method to return the default error AlertConfig for HttpInterceptor + * @param preMessage the alert message prefix. + * @param mainMessage the alert message main content. + */ private createErrorAlertConfig(preMessage: string, mainMessage: string): AlertConfig { - const alertConfig: AlertConfig = { - type: AlertType.danger, - preMessage: preMessage, - mainMessage: mainMessage, - dismissible: true, - autoDismiss: true, - timeout: this.alertService.defaultTimeout - }; - return alertConfig; - } + const alertConfig: AlertConfig = { + type: AlertType.danger, + preMessage: preMessage, + mainMessage: mainMessage, + dismissible: true, + autoDismiss: true, + timeout: this.alertService.defaultTimeout + }; + return alertConfig; + } } diff --git a/src/app/services/auth.service.ts b/src/app/services/auth.service.ts index bbcc3396..1ccec69b 100644 --- a/src/app/services/auth.service.ts +++ b/src/app/services/auth.service.ts @@ -44,7 +44,7 @@ export class AuthService { private backenduser: BackendUser | null; constructor( - private userService: UserService + private userService: UserService ) { this.manager = new UserManager(getClientSettings()); @@ -69,7 +69,7 @@ export class AuthService { */ public login(providerSchema?: string): Promise { if (providerSchema != null) { - this.manager.settings.extraQueryParams = { 'provider': providerSchema }; + this.manager.settings.extraQueryParams = {'provider': providerSchema}; } return this.manager.signinRedirect(); } @@ -130,6 +130,31 @@ export class AuthService { return this.user != null && !this.user.expired; } + /** + * Checks if the users token is expired. + * @returns true if expired. + */ + public isUserExpired(): boolean { + return this.user.expired; + } + + /** + * Silent login, for use of the refresh token + */ + public silentLogin(): void { + this.manager.signinSilent().then(() => { + this.manager.getUser().then((user) => { + this.user = user; + if (this.isAuthenticated()) { + this.getBackendUser().then((backendUser) => { + this.backenduser = backendUser; + this.$user.next(backendUser); + }); + } + }).catch(err => console.log(err)); + }); + } + /** * Gets the authorization header value. */