Select Git revision
authentication.service.ts 4.26 KiB
/*
* Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den
* Ministerpräsidenten des Landes Schleswig-Holstein
* Staatskanzlei
* Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
*
* Lizenziert unter der EUPL, Version 1.2 oder - sobald
* diese von der Europäischen Kommission genehmigt wurden -
* Folgeversionen der EUPL ("Lizenz");
* Sie dürfen dieses Werk ausschließlich gemäß
* dieser Lizenz nutzen.
* Eine Kopie der Lizenz finden Sie hier:
*
* https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
*
* Sofern nicht durch anwendbare Rechtsvorschriften
* gefordert oder in schriftlicher Form vereinbart, wird
* die unter der Lizenz verbreitete Software "so wie sie
* ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
* ausdrücklich oder stillschweigend - verbreitet.
* Die sprachspezifischen Genehmigungen und Beschränkungen
* unter der Lizenz sind dem Lizenztext zu entnehmen.
*/
import { Environment, ENVIRONMENT_CONFIG } from '@alfa-client/environment-shared';
import { Inject, Injectable } from '@angular/core';
import { AuthConfig, OAuthEvent, OAuthService } from 'angular-oauth2-oidc';
import { JwksValidationHandler } from 'angular-oauth2-oidc-jwks';
import { UserProfileResource } from 'libs/user-profile-shared/src/lib/user-profile.model';
import { getUserNameInitials } from 'libs/user-profile-shared/src/lib/user-profile.util';
import { filter, Subscription } from 'rxjs';
@Injectable({ providedIn: 'root' })
export class AuthenticationService {
currentUserResource: UserProfileResource;
private eventSubscription: Subscription;
constructor(
private oAuthService: OAuthService,
@Inject(ENVIRONMENT_CONFIG) private envConfig: Environment,
) {}
public async login(): Promise<void> {
this.oAuthService.configure(this.buildConfiguration());
this.oAuthService.setupAutomaticSilentRefresh();
this.oAuthService.tokenValidationHandler = new JwksValidationHandler();
const eventPromise: Promise<void> = this.buildEventPromise();
await this.oAuthService.loadDiscoveryDocumentAndLogin();
return eventPromise;
}
buildEventPromise(): Promise<void> {
return new Promise<void>((resolve, reject) => this.handleOAuthEventsForPromise(resolve, reject));
}
private handleOAuthEventsForPromise(resolve: (value: void | PromiseLike<void>) => void, reject: (reason?: any) => void): void {
this.eventSubscription = this.oAuthService.events
.pipe(filter((event: OAuthEvent) => this.shouldProceedByType(event)))
.subscribe({
next: () => {
this.setCurrentUser();
this.unsubscribeEvents();
resolve();
},
error: (error: any) => {
this.unsubscribeEvents();
reject(error);
},
});
}
shouldProceedByType(event: OAuthEvent): boolean {
return this.consideredAsLoginEvent(event.type) || this.consideredAsPageReloadEvent(event.type);
}
consideredAsLoginEvent(eventType: string): boolean {
return eventType === 'token_received';
}
consideredAsPageReloadEvent(eventType: string): boolean {
return eventType === 'discovery_document_loaded' && this.hasValidToken();
}
hasValidToken(): boolean {
return this.oAuthService.hasValidAccessToken() && this.oAuthService.hasValidIdToken();
}
buildConfiguration(): AuthConfig {
return {
issuer: this.envConfig.authServer + '/realms/' + this.envConfig.realm,
tokenEndpoint: this.envConfig.authServer + '/realms/' + this.envConfig.realm + '/protocol/openid-connect/token',
redirectUri: window.location.origin + '/',
clientId: this.envConfig.clientId,
scope: 'openid profile',
requireHttps: false,
responseType: 'code',
showDebugInformation: false,
};
}
setCurrentUser(): void {
const claims: Record<string, any> = this.oAuthService.getIdentityClaims();
const userResource: UserProfileResource = <any>{
firstName: claims['given_name'],
lastName: claims['family_name'],
};
this.currentUserResource = userResource;
}
unsubscribeEvents(): void {
this.eventSubscription.unsubscribe();
}
public getCurrentUserInitials(): string {
return getUserNameInitials(this.currentUserResource);
}
public logout(): void {
this.oAuthService.revokeTokenAndLogout();
}
}