UNPKG

@kephas/ngx-oidc

Version:

Provides the integration of the OIDC API with Kephas and Angular 12+.

736 lines (723 loc) 37 kB
import { __decorate } from 'tslib'; import { AppService, Priority, SingletonAppServiceContract } from '@kephas/core'; import { NgTarget, resolveAppService } from '@kephas/ngx-core'; import * as i0 from '@angular/core'; import { Injectable, Component, Injector, NgModule } from '@angular/core'; import { UserManager } from 'oidc-client'; import { BehaviorSubject, concat, from } from 'rxjs'; import { map, take, filter, tap, mergeMap } from 'rxjs/operators'; import * as i2 from '@angular/router'; import { RouterModule } from '@angular/router'; import * as i4 from '@angular/common'; import { CommonModule } from '@angular/common'; import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http'; /** * This service should be overwritten in the end application * to provide the real identity application ID in the getIdentityAppId() method. * * @export * @class AppIdProvider */ let AppIdProvider = class AppIdProvider { /** * Gets the identity application ID. * * @returns * @memberof AppIdProvider */ getIdentityAppId() { return '[TODO-APP-ID]'; } }; AppIdProvider = __decorate([ AppService({ overridePriority: Priority.Lowest }), SingletonAppServiceContract({ target: NgTarget }) ], AppIdProvider); const ReturnUrlType = 'returnUrl'; const QueryParameterNames = { ReturnUrl: ReturnUrlType, Message: 'message' }; const LogoutActions = { LogoutCallback: 'logout-callback', Logout: 'logout', LoggedOut: 'logged-out' }; const LoginActions = { Login: 'login', LoginCallback: 'login-callback', LoginFailed: 'login-failed', Profile: 'profile', Register: 'register' }; class AuthenticationSettingsProvider { /** * Creates an instance of AuthenticationSettingsProvider. * @param {AppIdProvider} appIdProvider The application ID provider. * @memberof AuthenticationSettingsProvider */ constructor(appIdProvider) { this.settings = this.getSettings(appIdProvider.getIdentityAppId()); } getSettings(identityAppId) { let applicationPaths = { DefaultLoginRedirectPath: '/', ApiAuthorizationClientConfigurationUrl: `/_configuration/${identityAppId}`, Login: `authentication/${LoginActions.Login}`, LoginFailed: `authentication/${LoginActions.LoginFailed}`, LoginCallback: `authentication/${LoginActions.LoginCallback}`, Register: `authentication/${LoginActions.Register}`, Profile: `authentication/${LoginActions.Profile}`, LogOut: `authentication/${LogoutActions.Logout}`, LoggedOut: `authentication/${LogoutActions.LoggedOut}`, LogOutCallback: `authentication/${LogoutActions.LogoutCallback}`, LoginPathComponents: [], LoginFailedPathComponents: [], LoginCallbackPathComponents: [], RegisterPathComponents: [], ProfilePathComponents: [], LogOutPathComponents: [], LoggedOutPathComponents: [], LogOutCallbackPathComponents: [], IdentityRegisterPath: '/Identity/Account/Register', IdentityManagePath: '/Identity/Account/Manage' }; applicationPaths = { ...applicationPaths, LoginPathComponents: applicationPaths.Login.split('/'), LoginFailedPathComponents: applicationPaths.LoginFailed.split('/'), RegisterPathComponents: applicationPaths.Register.split('/'), ProfilePathComponents: applicationPaths.Profile.split('/'), LogOutPathComponents: applicationPaths.LogOut.split('/'), LoggedOutPathComponents: applicationPaths.LoggedOut.split('/'), LogOutCallbackPathComponents: applicationPaths.LogOutCallback.split('/') }; let activity = {}; return { identityAppId: identityAppId, returnUrl: ReturnUrlType, applicationPaths: applicationPaths, activity: activity, // By default pop ups are disabled because they don't work properly on Edge. // If you want to enable pop up authentication simply set this flag to false. popUpDisabled: true, }; } } AuthenticationSettingsProvider.instance = new AuthenticationSettingsProvider(new AppIdProvider()); AuthenticationSettingsProvider.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.0", ngImport: i0, type: AuthenticationSettingsProvider, deps: [{ token: AppIdProvider }], target: i0.ɵɵFactoryTarget.Injectable }); AuthenticationSettingsProvider.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.1.0", ngImport: i0, type: AuthenticationSettingsProvider }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.0", ngImport: i0, type: AuthenticationSettingsProvider, decorators: [{ type: Injectable }], ctorParameters: function () { return [{ type: AppIdProvider }]; } }); var AuthenticationResultStatus; (function (AuthenticationResultStatus) { AuthenticationResultStatus[AuthenticationResultStatus["Success"] = 0] = "Success"; AuthenticationResultStatus[AuthenticationResultStatus["Redirect"] = 1] = "Redirect"; AuthenticationResultStatus[AuthenticationResultStatus["Fail"] = 2] = "Fail"; })(AuthenticationResultStatus || (AuthenticationResultStatus = {})); class AuthenticationService { /** * Creates an instance of AuthorizeService. * @param {AuthenticationSettingsProvider} settingsProvider The settings provider. * @memberof AuthorizeService */ constructor(settingsProvider) { this.settingsProvider = settingsProvider; this.userSubject = new BehaviorSubject(null); this.rawUserSubject = new BehaviorSubject(null); } /** * Gets the time of user's last activity. * * @readonly * @type {(Date | undefined)} * @memberof AuthorizeService */ get lastActivityTime() { return this._lastActivityTime; } /** * Gets an observable indicating whether the user is authenticated. * * @return {*} {Observable<boolean>} * @memberof AuthorizeService */ isAuthenticated() { return this.getUser().pipe(map(u => !!u)); } /** * Gets an observable retrieving the user. * * @return {*} {(Observable<IUser | null | undefined>)} * @memberof AuthorizeService */ getUser() { return concat(this.userSubject.pipe(take(1), filter(u => !!u)), this.getUserFromStorage().pipe(filter(u => !!u), tap(u => this.setUser(u)), map(u => u?.profile)), this.userSubject.asObservable()); } /** * Gets an observable containing the access token of the signed-in user. * * @return {*} {(Observable<string | undefined>)} * @memberof AuthorizeService */ getAccessToken() { return from(this.ensureUserManagerInitialized()) .pipe(mergeMap(() => from(this.userManager.getUser())), map(user => user?.access_token)); } /** * Notifies the authorization service that the user is active. * * @memberof AuthorizeService */ touch() { this._lastActivityTime = new Date(); } /** * Sign in the user. * We try to authenticate the user in three different ways: * 1) We try to see if we can authenticate the user silently. This happens * when the user is already logged in on the IdP and is done using a hidden iframe * on the client. * 2) We try to authenticate the user using a PopUp Window. This might fail if there is a * Pop-Up blocker or the user has disabled PopUps. * 3) If the two methods above fail, we redirect the browser to the IdP to perform a traditional * redirect flow. * * @param {*} state * @return {*} {Promise<IAuthenticationResult>} * @memberof AuthorizeService */ async signIn(state) { await this.ensureUserManagerInitialized(); let user = null; try { user = await this.userManager.signinSilent(this.createArguments()); this.setUser(user); return this.success(state); } catch (silentError) { // User might not be authenticated, fallback to popup authentication console.log('Silent authentication error: ', silentError); const popUpDisabled = this.settingsProvider.settings.popUpDisabled; try { this.ensurePopupEnabled(); user = await this.userManager.signinPopup(this.createArguments()); this.setUser(user); return this.success(state); } catch (popupError) { if (popupError.message === 'Popup window closed') { // The user explicitly cancelled the login action by closing an opened popup. return this.error('The user closed the window.'); } else if (!popUpDisabled) { console.log('Popup authentication error: ', popupError); } // PopUps might be blocked by the user, fallback to redirect try { await this.userManager.signinRedirect(this.createArguments(state)); return this.redirect(); } catch (redirectError) { console.log('Redirect authentication error: ', redirectError); return this.error(redirectError); } } } } async completeSignIn(url) { try { await this.ensureUserManagerInitialized(); const user = await this.userManager.signinCallback(url); this.setUser(user); return this.success(user?.state); } catch (error) { console.log('There was an error signing in: ', error); return this.error('There was an error signing in.'); } } async signOut(state) { try { this.ensurePopupEnabled(); await this.ensureUserManagerInitialized(); await this.userManager.signoutPopup(this.createArguments()); this.setUser(null); return this.success(state); } catch (popupSignOutError) { console.log('Popup signout error: ', popupSignOutError); try { await this.userManager.signoutRedirect(this.createArguments(state)); return this.redirect(); } catch (redirectSignOutError) { console.log('Redirect signout error: ', popupSignOutError); return this.error(redirectSignOutError); } } } async completeSignOut(url) { await this.ensureUserManagerInitialized(); try { const response = await this.userManager.signoutCallback(url); this.setUser(null); return this.success(response && response.state); } catch (error) { console.log(`There was an error trying to log out '${error}'.`); return this.error(error); } } async ensureUserManagerInitialized() { if (this.userManager !== undefined) { return; } const authSettings = this.settingsProvider.settings; const response = await fetch(authSettings.applicationPaths.ApiAuthorizationClientConfigurationUrl); if (!response.ok) { throw new Error(`Could not load settings for '${authSettings.identityAppId}'`); } const settings = await response.json(); settings.automaticSilentRenew = true; settings.includeIdTokenInSilentRenew = true; this.userManager = new UserManager(settings); this.userManager.events.addUserSignedOut(async () => { await this.userManager.removeUser(); this.setUser(null); }); } ensurePopupEnabled() { if (this.settingsProvider.settings.popUpDisabled) { throw new Error('Popup disabled. Instruct the AuthorizationSettingsProvider service to return false in \'settings.popupDisabled\' to enable it.'); } } createArguments(state) { return { useReplaceToNavigate: true, data: state }; } error(message) { return { status: AuthenticationResultStatus.Fail, message }; } success(state) { return { status: AuthenticationResultStatus.Success, state }; } redirect() { return { status: AuthenticationResultStatus.Redirect }; } getUserFromStorage() { return from(this.ensureUserManagerInitialized()) .pipe(mergeMap(() => this.userManager.getUser())); } setUser(user) { const currentUser = this.rawUserSubject.value; // make sure not to issue a change if the user is not really changed. if (currentUser == user || currentUser?.id_token == user?.id_token) { return; } this.rawUserSubject.next(user); this.userSubject.next(user?.profile || null); } } AuthenticationService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.0", ngImport: i0, type: AuthenticationService, deps: [{ token: AuthenticationSettingsProvider }], target: i0.ɵɵFactoryTarget.Injectable }); AuthenticationService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.1.0", ngImport: i0, type: AuthenticationService }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.0", ngImport: i0, type: AuthenticationService, decorators: [{ type: Injectable }], ctorParameters: function () { return [{ type: AuthenticationSettingsProvider }]; } }); /** * Interceptor handling the authorization. * * @export * @class AuthorizeInterceptor * @implements {HttpInterceptor} */ class AuthorizeInterceptor { /** * Creates an instance of AuthorizeInterceptor. * @param {AuthenticationService} authorize The authorization service. * @memberof AuthorizeInterceptor */ constructor(authorize) { this.authorize = authorize; } /** * Intercepts the request. * * @param {HttpRequest<any>} request * @param {HttpHandler} next * @return {*} {Observable<HttpEvent<any>>} * @memberof AuthorizeInterceptor */ intercept(request, next) { return this.authorize.getAccessToken() .pipe(mergeMap(token => this.processRequestWithToken(token, request, next))); } // Checks if there is an access_token available in the authorize service // and adds it to the request in case it's targeted at the same origin as the // single page application. processRequestWithToken(token, req, next) { if (!!token && this.isSameOriginUrl(req)) { req = req.clone({ setHeaders: { Authorization: `Bearer ${token}` } }); } return next.handle(req); } isSameOriginUrl(req) { // It's an absolute url with the same origin. if (req.url.startsWith(`${window.location.origin}/`)) { return true; } // It's a protocol relative url with the same origin. // For example: //www.example.com/api/Products if (req.url.startsWith(`//${window.location.host}/`)) { return true; } // It's a relative url like /api/Products if (/^\/[^\/].*/.test(req.url)) { return true; } // It's an absolute or protocol relative url that // doesn't have the same origin. return false; } } AuthorizeInterceptor.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.0", ngImport: i0, type: AuthorizeInterceptor, deps: [{ token: AuthenticationService }], target: i0.ɵɵFactoryTarget.Injectable }); AuthorizeInterceptor.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.1.0", ngImport: i0, type: AuthorizeInterceptor }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.0", ngImport: i0, type: AuthorizeInterceptor, decorators: [{ type: Injectable }], ctorParameters: function () { return [{ type: AuthenticationService }]; } }); class AuthorizeGuard { constructor(authService, router, settingsProvider) { this.authService = authService; this.router = router; this.settingsProvider = settingsProvider; } canActivate(_next, state) { return this.authService.isAuthenticated() .pipe(tap(isAuthenticated => this.handleAuthorization(isAuthenticated, state))); } handleAuthorization(isAuthenticated, state) { if (!isAuthenticated) { const settings = this.settingsProvider.settings; this.router.navigate(settings.applicationPaths.LoginPathComponents, { queryParams: { [QueryParameterNames.ReturnUrl]: state.url } }); } } } AuthorizeGuard.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.0", ngImport: i0, type: AuthorizeGuard, deps: [{ token: AuthenticationService }, { token: i2.Router }, { token: AuthenticationSettingsProvider }], target: i0.ɵɵFactoryTarget.Injectable }); AuthorizeGuard.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.1.0", ngImport: i0, type: AuthorizeGuard }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.0", ngImport: i0, type: AuthorizeGuard, decorators: [{ type: Injectable }], ctorParameters: function () { return [{ type: AuthenticationService }, { type: i2.Router }, { type: AuthenticationSettingsProvider }]; } }); // The main responsibility of this component is to handle the user's login process. // This is the starting point for the login process. Any component that needs to authenticate // a user can simply perform a redirect to this component with a returnUrl query parameter and // let the component perform the login and return back to the return url. class LoginComponent { constructor(authenticationService, activatedRoute, router, authSettingsProvider) { this.authenticationService = authenticationService; this.activatedRoute = activatedRoute; this.router = router; this.authSettingsProvider = authSettingsProvider; this.message = new BehaviorSubject(null); } async ngOnInit() { const action = this.activatedRoute.snapshot.url[1]; switch (action.path) { case LoginActions.Login: await this.login(this.getReturnUrl()); break; case LoginActions.LoginCallback: await this.processLoginCallback(); break; case LoginActions.LoginFailed: const message = this.activatedRoute.snapshot.queryParamMap.get(QueryParameterNames.Message); this.message.next(message); break; case LoginActions.Profile: this.redirectToProfile(); break; case LoginActions.Register: this.redirectToRegister(); break; default: throw new Error(`Invalid action '${action}'`); } } async login(returnUrl) { const state = { returnUrl }; const result = await this.authenticationService.signIn(state); this.message.next(null); const applicationPaths = this.authSettingsProvider.settings.applicationPaths; switch (result.status) { case AuthenticationResultStatus.Redirect: break; case AuthenticationResultStatus.Success: await this.navigateToReturnUrl(returnUrl); break; case AuthenticationResultStatus.Fail: await this.router.navigate(applicationPaths.LoginFailedPathComponents, { queryParams: { [QueryParameterNames.Message]: result.message } }); break; default: throw new Error(`Invalid status result ${result.status}.`); } } async processLoginCallback() { const url = window.location.href; const result = await this.authenticationService.completeSignIn(url); switch (result.status) { case AuthenticationResultStatus.Redirect: // There should not be any redirects as completeSignIn never redirects. throw new Error('Should not redirect.'); case AuthenticationResultStatus.Success: await this.navigateToReturnUrl(this.getReturnUrl(result.state)); break; case AuthenticationResultStatus.Fail: this.message.next(result.message); break; } } redirectToRegister() { const applicationPaths = this.authSettingsProvider.settings.applicationPaths; this.redirectToApiAuthorizationPath(`${applicationPaths.IdentityRegisterPath}?returnUrl=${encodeURI('/' + applicationPaths.Login)}`); } redirectToProfile() { const applicationPaths = this.authSettingsProvider.settings.applicationPaths; this.redirectToApiAuthorizationPath(applicationPaths.IdentityManagePath); } async navigateToReturnUrl(returnUrl) { // It's important that we do a replace here so that we remove the callback uri with the // fragment containing the tokens from the browser history. await this.router.navigateByUrl(returnUrl, { replaceUrl: true }); } getReturnUrl(state) { const applicationPaths = this.authSettingsProvider.settings.applicationPaths; const fromQuery = this.activatedRoute.snapshot.queryParams.returnUrl; // If the url is comming from the query string, check that is either // a relative url or an absolute url if (fromQuery && !(fromQuery.startsWith(`${window.location.origin}/`) || /\/[^\/].*/.test(fromQuery))) { // This is an extra check to prevent open redirects. throw new Error('Invalid return url. The return url needs to have the same origin as the current page.'); } return (state && state.returnUrl) || fromQuery || applicationPaths.DefaultLoginRedirectPath; } redirectToApiAuthorizationPath(apiAuthorizationPath) { // It's important that we do a replace here so that when the user hits the back arrow on the // browser they get sent back to where it was on the app instead of to an endpoint on this // component. const redirectUrl = `${window.location.origin}${apiAuthorizationPath}`; window.location.replace(redirectUrl); } } LoginComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.0", ngImport: i0, type: LoginComponent, deps: [{ token: AuthenticationService }, { token: i2.ActivatedRoute }, { token: i2.Router }, { token: AuthenticationSettingsProvider }], target: i0.ɵɵFactoryTarget.Component }); LoginComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.0", type: LoginComponent, selector: "app-login", ngImport: i0, template: "<p>{{ message | async }}</p>", styles: [""], pipes: { "async": i4.AsyncPipe } }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.0", ngImport: i0, type: LoginComponent, decorators: [{ type: Component, args: [{ selector: 'app-login', template: "<p>{{ message | async }}</p>", styles: [""] }] }], ctorParameters: function () { return [{ type: AuthenticationService }, { type: i2.ActivatedRoute }, { type: i2.Router }, { type: AuthenticationSettingsProvider }]; } }); // The main responsibility of this component is to handle the user's logout process. // This is the starting point for the logout process, which is usually initiated when a // user clicks on the logout button on the LoginMenu component. class LogoutComponent { constructor(authenticationService, activatedRoute, router, authSettingsProvider) { this.authenticationService = authenticationService; this.activatedRoute = activatedRoute; this.router = router; this.authSettingsProvider = authSettingsProvider; this.message = new BehaviorSubject(null); } async ngOnInit() { const action = this.activatedRoute.snapshot.url[1]; switch (action.path) { case LogoutActions.Logout: if (!!window.history.state.local) { await this.logout(this.getReturnUrl()); } else { // This prevents regular links to <app>/authentication/logout from triggering a logout this.message.next('The logout was not initiated from within the page.'); } break; case LogoutActions.LogoutCallback: await this.processLogoutCallback(); break; case LogoutActions.LoggedOut: this.message.next('You successfully logged out!'); break; default: throw new Error(`Invalid action '${action}'`); } } async logout(returnUrl) { const state = { returnUrl }; const isauthenticated = await this.authenticationService.isAuthenticated().pipe(take(1)).toPromise(); if (isauthenticated) { const result = await this.authenticationService.signOut(state); switch (result.status) { case AuthenticationResultStatus.Redirect: break; case AuthenticationResultStatus.Success: await this.navigateToReturnUrl(returnUrl); break; case AuthenticationResultStatus.Fail: this.message.next(result.message); break; default: throw new Error('Invalid authentication result status.'); } } else { this.message.next('You successfully logged out!'); } } async processLogoutCallback() { const url = window.location.href; const result = await this.authenticationService.completeSignOut(url); switch (result.status) { case AuthenticationResultStatus.Redirect: // There should not be any redirects as the only time completeAuthentication finishes // is when we are doing a redirect sign in flow. throw new Error('Should not redirect.'); case AuthenticationResultStatus.Success: await this.navigateToReturnUrl(this.getReturnUrl(result.state)); break; case AuthenticationResultStatus.Fail: this.message.next(result.message); break; default: throw new Error('Invalid authentication result status.'); } } async navigateToReturnUrl(returnUrl) { await this.router.navigateByUrl(returnUrl, { replaceUrl: true }); } getReturnUrl(state) { const fromQuery = this.activatedRoute.snapshot.queryParams.returnUrl; // If the url is comming from the query string, check that is either // a relative url or an absolute url if (fromQuery && !(fromQuery.startsWith(`${window.location.origin}/`) || /\/[^\/].*/.test(fromQuery))) { // This is an extra check to prevent open redirects. throw new Error('Invalid return url. The return url needs to have the same origin as the current page.'); } return (state && state.returnUrl) || fromQuery || this.authSettingsProvider.settings.applicationPaths.LoggedOut; } } LogoutComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.0", ngImport: i0, type: LogoutComponent, deps: [{ token: AuthenticationService }, { token: i2.ActivatedRoute }, { token: i2.Router }, { token: AuthenticationSettingsProvider }], target: i0.ɵɵFactoryTarget.Component }); LogoutComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.0", type: LogoutComponent, selector: "app-logout", ngImport: i0, template: "<p>{{ message | async }}</p>", styles: [""], pipes: { "async": i4.AsyncPipe } }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.0", ngImport: i0, type: LogoutComponent, decorators: [{ type: Component, args: [{ selector: 'app-logout', template: "<p>{{ message | async }}</p>", styles: [""] }] }], ctorParameters: function () { return [{ type: AuthenticationService }, { type: i2.ActivatedRoute }, { type: i2.Router }, { type: AuthenticationSettingsProvider }]; } }); class LoginMenuComponent { constructor(authenticationService) { this.authenticationService = authenticationService; } ngOnInit() { this.isAuthenticated = this.authenticationService.isAuthenticated(); this.userName = this.authenticationService.getUser().pipe(map(u => u?.name)); } } LoginMenuComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.0", ngImport: i0, type: LoginMenuComponent, deps: [{ token: AuthenticationService }], target: i0.ɵɵFactoryTarget.Component }); LoginMenuComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.0", type: LoginMenuComponent, selector: "app-login-menu", ngImport: i0, template: "<ul class=\"navbar-nav\" *ngIf=\"isAuthenticated | async\">\r\n <li class=\"nav-item\">\r\n <a class=\"nav-link\" [routerLink]='[\"/authentication/profile\"]' title=\"Manage\">Hello {{ userName | async }}</a>\r\n </li>\r\n <li class=\"nav-item\">\r\n <a class=\"nav-link\" [routerLink]='[\"/authentication/logout\"]' [state]='{ local: true }' title=\"Logout\">Logout</a>\r\n </li>\r\n</ul>\r\n<ul class=\"navbar-nav\" *ngIf=\"!(isAuthenticated | async)\">\r\n <li class=\"nav-item\">\r\n <a class=\"nav-link\" [routerLink]='[\"/authentication/register\"]'>Register</a>\r\n </li>\r\n <li class=\"nav-item\">\r\n <a class=\"nav-link\" [routerLink]='[\"/authentication/login\"]'>Login</a>\r\n </li>\r\n</ul>\r\n", styles: [""], directives: [{ type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2.RouterLinkWithHref, selector: "a[routerLink],area[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "preserveFragment", "skipLocationChange", "replaceUrl", "state", "relativeTo", "routerLink"] }], pipes: { "async": i4.AsyncPipe } }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.0", ngImport: i0, type: LoginMenuComponent, decorators: [{ type: Component, args: [{ selector: 'app-login-menu', template: "<ul class=\"navbar-nav\" *ngIf=\"isAuthenticated | async\">\r\n <li class=\"nav-item\">\r\n <a class=\"nav-link\" [routerLink]='[\"/authentication/profile\"]' title=\"Manage\">Hello {{ userName | async }}</a>\r\n </li>\r\n <li class=\"nav-item\">\r\n <a class=\"nav-link\" [routerLink]='[\"/authentication/logout\"]' [state]='{ local: true }' title=\"Logout\">Logout</a>\r\n </li>\r\n</ul>\r\n<ul class=\"navbar-nav\" *ngIf=\"!(isAuthenticated | async)\">\r\n <li class=\"nav-item\">\r\n <a class=\"nav-link\" [routerLink]='[\"/authentication/register\"]'>Register</a>\r\n </li>\r\n <li class=\"nav-item\">\r\n <a class=\"nav-link\" [routerLink]='[\"/authentication/login\"]'>Login</a>\r\n </li>\r\n</ul>\r\n", styles: [""] }] }], ctorParameters: function () { return [{ type: AuthenticationService }]; } }); const applicationPaths = AuthenticationSettingsProvider.instance.settings.applicationPaths; class OidcModule { } OidcModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.0", ngImport: i0, type: OidcModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); OidcModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.1.0", ngImport: i0, type: OidcModule, declarations: [LoginMenuComponent, LoginComponent, LogoutComponent], imports: [CommonModule, HttpClientModule, i2.RouterModule], exports: [LoginMenuComponent, LoginComponent, LogoutComponent] }); OidcModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.1.0", ngImport: i0, type: OidcModule, providers: [ { provide: AppIdProvider, useFactory: resolveAppService(AppIdProvider), deps: [Injector] }, AuthenticationSettingsProvider, AuthenticationService, AuthorizeGuard, { provide: HTTP_INTERCEPTORS, multi: true, useClass: AuthorizeInterceptor, } ], imports: [[ CommonModule, HttpClientModule, RouterModule.forChild([ { path: applicationPaths.Register, component: LoginComponent }, { path: applicationPaths.Profile, component: LoginComponent }, { path: applicationPaths.Login, component: LoginComponent }, { path: applicationPaths.LoginFailed, component: LoginComponent }, { path: applicationPaths.LoginCallback, component: LoginComponent }, { path: applicationPaths.LogOut, component: LogoutComponent }, { path: applicationPaths.LoggedOut, component: LogoutComponent }, { path: applicationPaths.LogOutCallback, component: LogoutComponent } ]) ]] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.0", ngImport: i0, type: OidcModule, decorators: [{ type: NgModule, args: [{ imports: [ CommonModule, HttpClientModule, RouterModule.forChild([ { path: applicationPaths.Register, component: LoginComponent }, { path: applicationPaths.Profile, component: LoginComponent }, { path: applicationPaths.Login, component: LoginComponent }, { path: applicationPaths.LoginFailed, component: LoginComponent }, { path: applicationPaths.LoginCallback, component: LoginComponent }, { path: applicationPaths.LogOut, component: LogoutComponent }, { path: applicationPaths.LoggedOut, component: LogoutComponent }, { path: applicationPaths.LogOutCallback, component: LogoutComponent } ]) ], declarations: [LoginMenuComponent, LoginComponent, LogoutComponent], exports: [LoginMenuComponent, LoginComponent, LogoutComponent], providers: [ { provide: AppIdProvider, useFactory: resolveAppService(AppIdProvider), deps: [Injector] }, AuthenticationSettingsProvider, AuthenticationService, AuthorizeGuard, { provide: HTTP_INTERCEPTORS, multi: true, useClass: AuthorizeInterceptor, } ] }] }] }); /* * Public API Surface of angular-oidc */ /** * Generated bundle index. Do not edit. */ export { AppIdProvider, AuthenticationResultStatus, AuthenticationService, AuthenticationSettingsProvider, AuthorizeGuard, AuthorizeInterceptor, LoginActions, LoginComponent, LoginMenuComponent, LogoutActions, LogoutComponent, OidcModule, QueryParameterNames, ReturnUrlType }; //# sourceMappingURL=kephas-ngx-oidc.mjs.map