red-ui/apps/red-ui/src/app/auth/auth.guard.ts
2020-10-12 13:37:05 +03:00

68 lines
2.3 KiB
TypeScript

import {Injectable} from "@angular/core";
import {ActivatedRouteSnapshot, CanActivate, RouterStateSnapshot, UrlTree} from "@angular/router";
import {Observable} from "rxjs";
import {AuthConfig, OAuthService} from "angular-oauth2-oidc";
import {AppConfigKey, AppConfigService} from "../app-config/app-config.service";
import {map} from "rxjs/operators";
import {JwksValidationHandler} from "angular-oauth2-oidc-jwks";
import {UserService} from "../user/user.service";
@Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate {
private _configured = false;
constructor(private readonly _oauthService: OAuthService,
private readonly _userService: UserService,
private readonly _appConfigService: AppConfigService) {
}
private async _configure() {
this._configured = true;
const authConfig = await this._createConfiguration().toPromise();
this._oauthService.configure(authConfig);
this._oauthService.tokenValidationHandler = new JwksValidationHandler();
this._oauthService.setupAutomaticSilentRefresh();
return this._oauthService.loadDiscoveryDocumentAndTryLogin();
}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
if (!this._configured) {
return this._configure().then(() => this._checkToken());
}
return this._checkToken();
}
private async _checkToken() {
const expired = this._oauthService.getAccessTokenExpiration() - new Date().getTime() < 0;
if (!this._oauthService.getAccessToken() || expired) {
this._oauthService.initLoginFlow();
return false;
}
if (!this._userService.user) {
await this._userService.loadCurrentUser();
return true;
}
return true;
}
private _createConfiguration(): Observable<AuthConfig> {
return this._appConfigService.loadAppConfig().pipe(map(config => {
return {
issuer: config[AppConfigKey.OAUTH_URL],
redirectUri: window.location.origin,
clientId: config[AppConfigKey.OAUTH_CLIENT_ID],
scope: 'openid',
showDebugInformation: true,
silentRefreshRedirectUri: window.location.origin + '/assets/oauth/silent-refresh.html',
useSilentRefresh: true,
}
}));
}
}