keycloak-angular 20.0.0 → 20.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -917,25 +917,51 @@ class HasRolesDirective {
917
917
  this.checkRealm = false;
918
918
  this.viewContainer.clear();
919
919
  const keycloakSignal = inject(KEYCLOAK_EVENT_SIGNAL);
920
+ /**
921
+ * This effect will reevaluate roles after authentication or token refresh.
922
+ * Or clear the view on logout.
923
+ */
920
924
  effect(() => {
921
925
  const keycloakEvent = keycloakSignal();
922
- if (keycloakEvent.type !== KeycloakEventType.Ready) {
923
- return;
924
- }
925
- const authenticated = typeEventArgs(keycloakEvent.args);
926
- if (authenticated) {
927
- this.render();
926
+ switch (keycloakEvent.type) {
927
+ case KeycloakEventType.Ready: {
928
+ const authenticated = typeEventArgs(keycloakEvent.args);
929
+ if (authenticated) {
930
+ this.render();
931
+ }
932
+ else {
933
+ this.viewContainer.clear();
934
+ }
935
+ break;
936
+ }
937
+ case KeycloakEventType.AuthSuccess:
938
+ case KeycloakEventType.AuthRefreshSuccess:
939
+ case KeycloakEventType.TokenExpired:
940
+ this.render();
941
+ break;
942
+ case KeycloakEventType.AuthLogout:
943
+ this.viewContainer.clear();
944
+ break;
945
+ default:
946
+ break;
928
947
  }
929
948
  });
930
949
  }
950
+ /**
951
+ * Here to reevaluate access when inputs change.
952
+ */
953
+ ngOnChanges() {
954
+ this.render();
955
+ }
956
+ /**
957
+ * Clear the view and render it if user has access.
958
+ */
931
959
  render() {
932
960
  const hasAccess = this.checkUserRoles();
961
+ this.viewContainer.clear();
933
962
  if (hasAccess) {
934
963
  this.viewContainer.createEmbeddedView(this.templateRef);
935
964
  }
936
- else {
937
- this.viewContainer.clear();
938
- }
939
965
  }
940
966
  /**
941
967
  * Checks if the user has at least one of the specified roles in the resource or realm.
@@ -947,7 +973,7 @@ class HasRolesDirective {
947
973
  return hasResourceRole || hasRealmRole;
948
974
  }
949
975
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: HasRolesDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
950
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.0.3", type: HasRolesDirective, isStandalone: true, selector: "[kaHasRoles]", inputs: { roles: ["kaHasRoles", "roles"], resource: ["kaHasRolesResource", "resource"], checkRealm: ["kaHasRolesCheckRealm", "checkRealm"] }, ngImport: i0 }); }
976
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.0.3", type: HasRolesDirective, isStandalone: true, selector: "[kaHasRoles]", inputs: { roles: ["kaHasRoles", "roles"], resource: ["kaHasRolesResource", "resource"], checkRealm: ["kaHasRolesCheckRealm", "checkRealm"] }, usesOnChanges: true, ngImport: i0 }); }
951
977
  }
952
978
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: HasRolesDirective, decorators: [{
953
979
  type: Directive,
@@ -1101,16 +1127,22 @@ class AutoRefreshTokenService {
1101
1127
  get defaultOptions() {
1102
1128
  return {
1103
1129
  sessionTimeout: 300000,
1104
- onInactivityTimeout: 'logout'
1130
+ onInactivityTimeout: 'logout',
1131
+ logoutOptions: undefined,
1132
+ loginOptions: undefined
1105
1133
  };
1106
1134
  }
1107
1135
  executeOnInactivityTimeout() {
1108
1136
  switch (this.options.onInactivityTimeout) {
1109
1137
  case 'login':
1110
- this.keycloak.login().catch((error) => console.error('Failed to execute the login call', error));
1138
+ this.keycloak
1139
+ .login(this.options.loginOptions)
1140
+ .catch((error) => console.error('Failed to execute the login call', error));
1111
1141
  break;
1112
1142
  case 'logout':
1113
- this.keycloak.logout().catch((error) => console.error('Failed to execute the logout call', error));
1143
+ this.keycloak
1144
+ .logout(this.options.logoutOptions)
1145
+ .catch((error) => console.error('Failed to execute the logout call', error));
1114
1146
  break;
1115
1147
  default:
1116
1148
  break;
@@ -1173,6 +1205,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImpor
1173
1205
  * - `'login'`: Execute `keycloak.login` function.
1174
1206
  * - `'logout'`: Logs the user out by calling `keycloak.logout`.
1175
1207
  * - `'none'`: No action is taken.
1208
+ * - `logoutOptions` (optional): Logout options to pass to keycloak.logout
1209
+ * when the user is getting logged out automatically after timout.
1210
+ * - `loginOptions` (optional): Login options to pass to keycloak.login
1211
+ * when the user is getting logged in automatically after timout.
1176
1212
  *
1177
1213
  * @returns A `KeycloakFeature` instance that configures and enables the
1178
1214
  * auto-refresh token functionality.
@@ -1 +1 @@
1
- {"version":3,"file":"keycloak-angular.mjs","sources":["../../../projects/keycloak-angular/src/lib/legacy/core/interfaces/keycloak-event.ts","../../../projects/keycloak-angular/src/lib/legacy/core/services/keycloak-auth-guard.ts","../../../projects/keycloak-angular/src/lib/legacy/core/services/keycloak.service.ts","../../../projects/keycloak-angular/src/lib/legacy/core/interceptors/keycloak-bearer.interceptor.ts","../../../projects/keycloak-angular/src/lib/legacy/core/core.module.ts","../../../projects/keycloak-angular/src/lib/legacy/keycloak-angular.module.ts","../../../projects/keycloak-angular/src/lib/legacy/public_api.ts","../../../projects/keycloak-angular/src/lib/signals/keycloak-events-signal.ts","../../../projects/keycloak-angular/src/lib/directives/has-roles.directive.ts","../../../projects/keycloak-angular/src/lib/features/keycloak.feature.ts","../../../projects/keycloak-angular/src/lib/services/user-activity.service.ts","../../../projects/keycloak-angular/src/lib/services/auto-refresh-token.service.ts","../../../projects/keycloak-angular/src/lib/features/with-refresh-token.feature.ts","../../../projects/keycloak-angular/src/lib/guards/auth.guard.ts","../../../projects/keycloak-angular/src/lib/interceptors/keycloak.interceptor.ts","../../../projects/keycloak-angular/src/lib/interceptors/custom-bearer-token.interceptor.ts","../../../projects/keycloak-angular/src/lib/interceptors/include-bearer-token.interceptor.ts","../../../projects/keycloak-angular/src/lib/provide-keycloak.ts","../../../projects/keycloak-angular/src/public_api.ts","../../../projects/keycloak-angular/src/keycloak-angular.ts"],"sourcesContent":["/**\n * @license\n * Copyright Mauricio Gemelli Vigolo and contributors.\n *\n * Use of this source code is governed by a MIT-style license that can be\n * found in the LICENSE file at https://github.com/mauriciovigolo/keycloak-angular/blob/main/LICENSE.md\n */\n\n/**\n * Keycloak event types, as described at the keycloak-js documentation:\n * https://www.keycloak.org/docs/latest/securing_apps/index.html#callback-events\n *\n * @deprecated Keycloak Event based on the KeycloakService is deprecated and\n * will be removed in future versions.\n * Use the new `KEYCLOAK_EVENT_SIGNAL` injection token to listen for the keycloak\n * events.\n * More info: https://github.com/mauriciovigolo/keycloak-angular/blob/main/docs/migration-guides/v19.md\n */\nexport enum KeycloakEventTypeLegacy {\n /**\n * Called if there was an error during authentication.\n */\n OnAuthError,\n /**\n * Called if the user is logged out\n * (will only be called if the session status iframe is enabled, or in Cordova mode).\n */\n OnAuthLogout,\n /**\n * Called if there was an error while trying to refresh the token.\n */\n OnAuthRefreshError,\n /**\n * Called when the token is refreshed.\n */\n OnAuthRefreshSuccess,\n /**\n * Called when a user is successfully authenticated.\n */\n OnAuthSuccess,\n /**\n * Called when the adapter is initialized.\n */\n OnReady,\n /**\n * Called when the access token is expired. If a refresh token is available the token\n * can be refreshed with updateToken, or in cases where it is not (that is, with implicit flow)\n * you can redirect to login screen to obtain a new access token.\n */\n OnTokenExpired,\n /**\n * Called when a AIA has been requested by the application.\n */\n OnActionUpdate\n}\n\n/**\n * Structure of an event triggered by Keycloak, contains it's type\n * and arguments (if any).\n *\n * @deprecated Keycloak Event based on the KeycloakService is deprecated and\n * will be removed in future versions.\n * Use the new `KEYCLOAK_EVENT_SIGNAL` injection token to listen for the keycloak\n * events.\n * More info: https://github.com/mauriciovigolo/keycloak-angular/blob/main/docs/migration-guides/v19.md\n */\nexport interface KeycloakEventLegacy {\n /**\n * Event type as described at {@link KeycloakEventTypeLegacy}.\n */\n type: KeycloakEventTypeLegacy;\n /**\n * Arguments from the keycloak-js event function.\n */\n args?: unknown;\n}\n","/**\n * @license\n * Copyright Mauricio Gemelli Vigolo and contributors.\n *\n * Use of this source code is governed by a MIT-style license that can be\n * found in the LICENSE file at https://github.com/mauriciovigolo/keycloak-angular/blob/main/LICENSE.md\n */\n\nimport { CanActivate, Router, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree } from '@angular/router';\n\nimport { KeycloakService } from './keycloak.service';\n\n/**\n * A simple guard implementation out of the box. This class should be inherited and\n * implemented by the application. The only method that should be implemented is #isAccessAllowed.\n * The reason for this is that the authorization flow is usually not unique, so in this way you will\n * have more freedom to customize your authorization flow.\n *\n * @deprecated Class based guards are deprecated in Keycloak Angular and will be removed in future versions.\n * Use the new `createAuthGuard` function to create a Guard for your application.\n * More info: https://github.com/mauriciovigolo/keycloak-angular/blob/main/docs/migration-guides/v19.md\n */\nexport abstract class KeycloakAuthGuard implements CanActivate {\n /**\n * Indicates if the user is authenticated or not.\n */\n protected authenticated: boolean;\n /**\n * Roles of the logged user. It contains the clientId and realm user roles.\n */\n protected roles: string[];\n\n constructor(\n protected router: Router,\n protected keycloakAngular: KeycloakService\n ) {}\n\n /**\n * CanActivate checks if the user is logged in and get the full list of roles (REALM + CLIENT)\n * of the logged user. This values are set to authenticated and roles params.\n *\n * @param route\n * @param state\n */\n async canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<boolean | UrlTree> {\n try {\n this.authenticated = await this.keycloakAngular.isLoggedIn();\n this.roles = await this.keycloakAngular.getUserRoles(true);\n\n return await this.isAccessAllowed(route, state);\n } catch (error) {\n throw new Error('An error happened during access validation. Details:' + error);\n }\n }\n\n /**\n * Create your own customized authorization flow in this method. From here you already known\n * if the user is authenticated (this.authenticated) and the user roles (this.roles).\n *\n * Return a UrlTree if the user should be redirected to another route.\n *\n * @param route\n * @param state\n */\n abstract isAccessAllowed(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<boolean | UrlTree>;\n}\n","/**\n * @license\n * Copyright Mauricio Gemelli Vigolo and contributors.\n *\n * Use of this source code is governed by a MIT-style license that can be\n * found in the LICENSE file at https://github.com/mauriciovigolo/keycloak-angular/blob/main/LICENSE.md\n */\n\nimport { Injectable } from '@angular/core';\nimport { HttpHeaders, HttpRequest } from '@angular/common/http';\n\nimport { Subject, from } from 'rxjs';\nimport { map } from 'rxjs/operators';\nimport Keycloak from 'keycloak-js';\n\nimport { ExcludedUrl, ExcludedUrlRegex, KeycloakOptions } from '../interfaces/keycloak-options';\nimport { KeycloakEventLegacy, KeycloakEventTypeLegacy } from '../interfaces/keycloak-event';\n\n/**\n * Service to expose existent methods from the Keycloak JS adapter, adding new\n * functionalities to improve the use of keycloak in Angular v > 4.3 applications.\n *\n * This class should be injected in the application bootstrap, so the same instance will be used\n * along the web application.\n *\n * @deprecated This service is deprecated and will be removed in future versions.\n * Use the new `provideKeycloak` function to load Keycloak in an Angular application.\n * More info: https://github.com/mauriciovigolo/keycloak-angular/blob/main/docs/migration-guides/v19.md\n */\n@Injectable()\nexport class KeycloakService {\n /**\n * Keycloak-js instance.\n */\n private _instance: Keycloak;\n /**\n * User profile as KeycloakProfile interface.\n */\n private _userProfile: Keycloak.KeycloakProfile;\n /**\n * Flag to indicate if the bearer will not be added to the authorization header.\n */\n private _enableBearerInterceptor: boolean;\n /**\n * When the implicit flow is choosen there must exist a silentRefresh, as there is\n * no refresh token.\n */\n private _silentRefresh: boolean;\n /**\n * Indicates that the user profile should be loaded at the keycloak initialization,\n * just after the login.\n */\n private _loadUserProfileAtStartUp: boolean;\n /**\n * The bearer prefix that will be appended to the Authorization Header.\n */\n private _bearerPrefix: string;\n /**\n * Value that will be used as the Authorization Http Header name.\n */\n private _authorizationHeaderName: string;\n /**\n * @deprecated\n * The excluded urls patterns that must skip the KeycloakBearerInterceptor.\n */\n private _excludedUrls: ExcludedUrlRegex[];\n /**\n * Observer for the keycloak events\n */\n private _keycloakEvents$: Subject<KeycloakEventLegacy> = new Subject<KeycloakEventLegacy>();\n /**\n * The amount of required time remaining before expiry of the token before the token will be refreshed.\n */\n private _updateMinValidity: number;\n /**\n * Returns true if the request should have the token added to the headers by the KeycloakBearerInterceptor.\n */\n shouldAddToken: (request: HttpRequest<unknown>) => boolean;\n /**\n * Returns true if the request being made should potentially update the token.\n */\n shouldUpdateToken: (request: HttpRequest<unknown>) => boolean;\n\n /**\n * Binds the keycloak-js events to the keycloakEvents Subject\n * which is a good way to monitor for changes, if needed.\n *\n * The keycloakEvents returns the keycloak-js event type and any\n * argument if the source function provides any.\n */\n private bindsKeycloakEvents(): void {\n this._instance.onAuthError = (errorData) => {\n this._keycloakEvents$.next({\n args: errorData,\n type: KeycloakEventTypeLegacy.OnAuthError\n });\n };\n\n this._instance.onAuthLogout = () => {\n this._keycloakEvents$.next({ type: KeycloakEventTypeLegacy.OnAuthLogout });\n };\n\n this._instance.onAuthRefreshSuccess = () => {\n this._keycloakEvents$.next({\n type: KeycloakEventTypeLegacy.OnAuthRefreshSuccess\n });\n };\n\n this._instance.onAuthRefreshError = () => {\n this._keycloakEvents$.next({\n type: KeycloakEventTypeLegacy.OnAuthRefreshError\n });\n };\n\n this._instance.onAuthSuccess = () => {\n this._keycloakEvents$.next({ type: KeycloakEventTypeLegacy.OnAuthSuccess });\n };\n\n this._instance.onTokenExpired = () => {\n this._keycloakEvents$.next({\n type: KeycloakEventTypeLegacy.OnTokenExpired\n });\n };\n\n this._instance.onActionUpdate = (state) => {\n this._keycloakEvents$.next({\n args: state,\n type: KeycloakEventTypeLegacy.OnActionUpdate\n });\n };\n\n this._instance.onReady = (authenticated) => {\n this._keycloakEvents$.next({\n args: authenticated,\n type: KeycloakEventTypeLegacy.OnReady\n });\n };\n }\n\n /**\n * Loads all bearerExcludedUrl content in a uniform type: ExcludedUrl,\n * so it becomes easier to handle.\n *\n * @param bearerExcludedUrls array of strings or ExcludedUrl that includes\n * the url and HttpMethod.\n */\n private loadExcludedUrls(bearerExcludedUrls: (string | ExcludedUrl)[]): ExcludedUrlRegex[] {\n const excludedUrls: ExcludedUrlRegex[] = [];\n for (const item of bearerExcludedUrls) {\n let excludedUrl: ExcludedUrlRegex;\n if (typeof item === 'string') {\n excludedUrl = { urlPattern: new RegExp(item, 'i'), httpMethods: [] };\n } else {\n excludedUrl = {\n urlPattern: new RegExp(item.url, 'i'),\n httpMethods: item.httpMethods\n };\n }\n excludedUrls.push(excludedUrl);\n }\n return excludedUrls;\n }\n\n /**\n * Handles the class values initialization.\n *\n * @param options\n */\n private initServiceValues({\n enableBearerInterceptor = true,\n loadUserProfileAtStartUp = false,\n bearerExcludedUrls = [],\n authorizationHeaderName = 'Authorization',\n bearerPrefix = 'Bearer',\n initOptions,\n updateMinValidity = 20,\n shouldAddToken = () => true,\n shouldUpdateToken = () => true\n }: KeycloakOptions): void {\n this._enableBearerInterceptor = enableBearerInterceptor;\n this._loadUserProfileAtStartUp = loadUserProfileAtStartUp;\n this._authorizationHeaderName = authorizationHeaderName;\n this._bearerPrefix = bearerPrefix.trim().concat(' ');\n this._excludedUrls = this.loadExcludedUrls(bearerExcludedUrls);\n this._silentRefresh = initOptions ? initOptions.flow === 'implicit' : false;\n this._updateMinValidity = updateMinValidity;\n this.shouldAddToken = shouldAddToken;\n this.shouldUpdateToken = shouldUpdateToken;\n }\n\n /**\n * Keycloak initialization. It should be called to initialize the adapter.\n * Options is an object with 2 main parameters: config and initOptions. The first one\n * will be used to create the Keycloak instance. The second one are options to initialize the\n * keycloak instance.\n *\n * @param options\n * Config: may be a string representing the keycloak URI or an object with the\n * following content:\n * - url: Keycloak json URL\n * - realm: realm name\n * - clientId: client id\n *\n * initOptions:\n * Options to initialize the Keycloak adapter, matches the options as provided by Keycloak itself.\n *\n * enableBearerInterceptor:\n * Flag to indicate if the bearer will added to the authorization header.\n *\n * loadUserProfileInStartUp:\n * Indicates that the user profile should be loaded at the keycloak initialization,\n * just after the login.\n *\n * bearerExcludedUrls:\n * String Array to exclude the urls that should not have the Authorization Header automatically\n * added.\n *\n * authorizationHeaderName:\n * This value will be used as the Authorization Http Header name.\n *\n * bearerPrefix:\n * This value will be included in the Authorization Http Header param.\n *\n * tokenUpdateExcludedHeaders:\n * Array of Http Header key/value maps that should not trigger the token to be updated.\n *\n * updateMinValidity:\n * This value determines if the token will be refreshed based on its expiration time.\n *\n * @returns\n * A Promise with a boolean indicating if the initialization was successful.\n */\n public async init(options: KeycloakOptions = {}) {\n this.initServiceValues(options);\n const { config, initOptions } = options;\n\n this._instance = new Keycloak(config);\n this.bindsKeycloakEvents();\n\n const authenticated = await this._instance.init(initOptions);\n\n if (authenticated && this._loadUserProfileAtStartUp) {\n await this.loadUserProfile();\n }\n\n return authenticated;\n }\n\n /**\n * Redirects to login form on (options is an optional object with redirectUri and/or\n * prompt fields).\n *\n * @param options\n * Object, where:\n * - redirectUri: Specifies the uri to redirect to after login.\n * - prompt:By default the login screen is displayed if the user is not logged-in to Keycloak.\n * To only authenticate to the application if the user is already logged-in and not display the\n * login page if the user is not logged-in, set this option to none. To always require\n * re-authentication and ignore SSO, set this option to login .\n * - maxAge: Used just if user is already authenticated. Specifies maximum time since the\n * authentication of user happened. If user is already authenticated for longer time than\n * maxAge, the SSO is ignored and he will need to re-authenticate again.\n * - loginHint: Used to pre-fill the username/email field on the login form.\n * - action: If value is 'register' then user is redirected to registration page, otherwise to\n * login page.\n * - locale: Specifies the desired locale for the UI.\n * @returns\n * A void Promise if the login is successful and after the user profile loading.\n */\n public async login(options: Keycloak.KeycloakLoginOptions = {}) {\n await this._instance.login(options);\n\n if (this._loadUserProfileAtStartUp) {\n await this.loadUserProfile();\n }\n }\n\n /**\n * Redirects to logout.\n *\n * @param redirectUri\n * Specifies the uri to redirect to after logout.\n * @returns\n * A void Promise if the logout was successful, cleaning also the userProfile.\n */\n public async logout(redirectUri?: string) {\n const options = {\n redirectUri\n };\n\n await this._instance.logout(options);\n this._userProfile = undefined;\n }\n\n /**\n * Redirects to registration form. Shortcut for login with option\n * action = 'register'. Options are same as for the login method but 'action' is set to\n * 'register'.\n *\n * @param options\n * login options\n * @returns\n * A void Promise if the register flow was successful.\n */\n public async register(options: Keycloak.KeycloakLoginOptions = { action: 'register' }) {\n await this._instance.register(options);\n }\n\n /**\n * Check if the user has access to the specified role. It will look for roles in\n * realm and the given resource, but will not check if the user is logged in for better performance.\n *\n * @param role\n * role name\n * @param resource\n * resource name. If not specified, `clientId` is used\n * @returns\n * A boolean meaning if the user has the specified Role.\n */\n isUserInRole(role: string, resource?: string): boolean {\n let hasRole: boolean;\n hasRole = this._instance.hasResourceRole(role, resource);\n if (!hasRole) {\n hasRole = this._instance.hasRealmRole(role);\n }\n return hasRole;\n }\n\n /**\n * Return the roles of the logged user. The realmRoles parameter, with default value\n * true, will return the resource roles and realm roles associated with the logged user. If set to false\n * it will only return the resource roles. The resource parameter, if specified, will return only resource roles\n * associated with the given resource.\n *\n * @param realmRoles\n * Set to false to exclude realm roles (only client roles)\n * @param resource\n * resource name If not specified, returns roles from all resources\n * @returns\n * Array of Roles associated with the logged user.\n */\n getUserRoles(realmRoles: boolean = true, resource?: string): string[] {\n let roles: string[] = [];\n\n if (this._instance.resourceAccess) {\n Object.keys(this._instance.resourceAccess).forEach((key) => {\n if (resource && resource !== key) {\n return;\n }\n\n const resourceAccess = this._instance.resourceAccess[key];\n const clientRoles = resourceAccess['roles'] || [];\n roles = roles.concat(clientRoles);\n });\n }\n\n if (realmRoles && this._instance.realmAccess) {\n const realmRoles = this._instance.realmAccess['roles'] || [];\n roles.push(...realmRoles);\n }\n\n return roles;\n }\n\n /**\n * Check if user is logged in.\n *\n * @returns\n * A boolean that indicates if the user is logged in.\n */\n isLoggedIn(): boolean {\n if (!this._instance) {\n return false;\n }\n\n return this._instance.authenticated;\n }\n\n /**\n * Returns true if the token has less than minValidity seconds left before\n * it expires.\n *\n * @param minValidity\n * Seconds left. (minValidity) is optional. Default value is 0.\n * @returns\n * Boolean indicating if the token is expired.\n */\n isTokenExpired(minValidity: number = 0): boolean {\n return this._instance.isTokenExpired(minValidity);\n }\n\n /**\n * If the token expires within _updateMinValidity seconds the token is refreshed. If the\n * session status iframe is enabled, the session status is also checked.\n * Returns a promise telling if the token was refreshed or not. If the session is not active\n * anymore, the promise is rejected.\n *\n * @param minValidity\n * Seconds left. (minValidity is optional, if not specified updateMinValidity - default 20 is used)\n * @returns\n * Promise with a boolean indicating if the token was succesfully updated.\n */\n public async updateToken(minValidity = this._updateMinValidity) {\n // TODO: this is a workaround until the silent refresh (issue #43)\n // is not implemented, avoiding the redirect loop.\n if (this._silentRefresh) {\n if (this.isTokenExpired()) {\n throw new Error('Failed to refresh the token, or the session is expired');\n }\n\n return true;\n }\n\n if (!this._instance) {\n throw new Error('Keycloak Angular library is not initialized.');\n }\n\n try {\n return await this._instance.updateToken(minValidity);\n } catch (error) {\n return false;\n }\n }\n\n /**\n * Loads the user profile.\n * Returns promise to set functions to be invoked if the profile was loaded\n * successfully, or if the profile could not be loaded.\n *\n * @param forceReload\n * If true will force the loadUserProfile even if its already loaded.\n * @returns\n * A promise with the KeycloakProfile data loaded.\n */\n public async loadUserProfile(forceReload = false) {\n if (this._userProfile && !forceReload) {\n return this._userProfile;\n }\n\n if (!this._instance.authenticated) {\n throw new Error('The user profile was not loaded as the user is not logged in.');\n }\n\n return (this._userProfile = await this._instance.loadUserProfile());\n }\n\n /**\n * Returns the authenticated token.\n */\n public async getToken() {\n return this._instance.token;\n }\n\n /**\n * Returns the logged username.\n *\n * @returns\n * The logged username.\n */\n public getUsername() {\n if (!this._userProfile) {\n throw new Error('User not logged in or user profile was not loaded.');\n }\n\n return this._userProfile.username;\n }\n\n /**\n * Clear authentication state, including tokens. This can be useful if application\n * has detected the session was expired, for example if updating token fails.\n * Invoking this results in onAuthLogout callback listener being invoked.\n */\n clearToken(): void {\n this._instance.clearToken();\n }\n\n /**\n * Adds a valid token in header. The key & value format is:\n * Authorization Bearer <token>.\n * If the headers param is undefined it will create the Angular headers object.\n *\n * @param headers\n * Updated header with Authorization and Keycloak token.\n * @returns\n * An observable with with the HTTP Authorization header and the current token.\n */\n public addTokenToHeader(headers: HttpHeaders = new HttpHeaders()) {\n return from(this.getToken()).pipe(\n map((token) => (token ? headers.set(this._authorizationHeaderName, this._bearerPrefix + token) : headers))\n );\n }\n\n /**\n * Returns the original Keycloak instance, if you need any customization that\n * this Angular service does not support yet. Use with caution.\n *\n * @returns\n * The KeycloakInstance from keycloak-js.\n */\n getKeycloakInstance(): Keycloak.KeycloakInstance {\n return this._instance;\n }\n\n /**\n * @deprecated\n * Returns the excluded URLs that should not be considered by\n * the http interceptor which automatically adds the authorization header in the Http Request.\n *\n * @returns\n * The excluded urls that must not be intercepted by the KeycloakBearerInterceptor.\n */\n get excludedUrls(): ExcludedUrlRegex[] {\n return this._excludedUrls;\n }\n\n /**\n * Flag to indicate if the bearer will be added to the authorization header.\n *\n * @returns\n * Returns if the bearer interceptor was set to be disabled.\n */\n get enableBearerInterceptor(): boolean {\n return this._enableBearerInterceptor;\n }\n\n /**\n * Keycloak subject to monitor the events triggered by keycloak-js.\n * The following events as available (as described at keycloak docs -\n * https://www.keycloak.org/docs/latest/securing_apps/index.html#callback-events):\n * - OnAuthError\n * - OnAuthLogout\n * - OnAuthRefreshError\n * - OnAuthRefreshSuccess\n * - OnAuthSuccess\n * - OnReady\n * - OnTokenExpire\n * In each occurrence of any of these, this subject will return the event type,\n * described at {@link KeycloakEventTypeLegacy} enum and the function args from the keycloak-js\n * if provided any.\n *\n * @returns\n * A subject with the {@link KeycloakEventLegacy} which describes the event type and attaches the\n * function args.\n */\n get keycloakEvents$(): Subject<KeycloakEventLegacy> {\n return this._keycloakEvents$;\n }\n}\n","/**\n * @license\n * Copyright Mauricio Gemelli Vigolo and contributors.\n *\n * Use of this source code is governed by a MIT-style license that can be\n * found in the LICENSE file at https://github.com/mauriciovigolo/keycloak-angular/blob/main/LICENSE.md\n */\n\nimport { Injectable, inject } from '@angular/core';\nimport { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http';\n\nimport { Observable, combineLatest, from, of } from 'rxjs';\nimport { mergeMap } from 'rxjs/operators';\n\nimport { KeycloakService } from '../services/keycloak.service';\nimport { ExcludedUrlRegex } from '../interfaces/keycloak-options';\n\n/**\n * This interceptor includes the bearer by default in all HttpClient requests.\n *\n * If you need to exclude some URLs from adding the bearer, please, take a look\n * at the {@link KeycloakOptions} bearerExcludedUrls property.\n *\n * @deprecated KeycloakBearerInterceptor is deprecated and will be removed in future versions.\n * Use the new functional interceptor such as `includeBearerTokenInterceptor`.\n * More info: https://github.com/mauriciovigolo/keycloak-angular/blob/main/docs/migration-guides/v19.md\n */\n@Injectable()\nexport class KeycloakBearerInterceptor implements HttpInterceptor {\n private keycloak = inject(KeycloakService);\n\n /**\n * Calls to update the keycloak token if the request should update the token.\n *\n * @param req http request from @angular http module.\n * @returns\n * A promise boolean for the token update or noop result.\n */\n private async conditionallyUpdateToken(req: HttpRequest<unknown>): Promise<boolean> {\n if (this.keycloak.shouldUpdateToken(req)) {\n return await this.keycloak.updateToken();\n }\n\n return true;\n }\n\n /**\n * @deprecated\n * Checks if the url is excluded from having the Bearer Authorization\n * header added.\n *\n * @param req http request from @angular http module.\n * @param excludedUrlRegex contains the url pattern and the http methods,\n * excluded from adding the bearer at the Http Request.\n */\n private isUrlExcluded({ method, url }: HttpRequest<unknown>, { urlPattern, httpMethods }: ExcludedUrlRegex): boolean {\n const httpTest = httpMethods.length === 0 || httpMethods.join().indexOf(method.toUpperCase()) > -1;\n\n const urlTest = urlPattern.test(url);\n\n return httpTest && urlTest;\n }\n\n /**\n * Intercept implementation that checks if the request url matches the excludedUrls.\n * If not, adds the Authorization header to the request if the user is logged in.\n *\n * @param req\n * @param next\n */\n public intercept(req: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {\n const { enableBearerInterceptor, excludedUrls } = this.keycloak;\n if (!enableBearerInterceptor) {\n return next.handle(req);\n }\n\n const shallPass: boolean =\n !this.keycloak.shouldAddToken(req) || excludedUrls.findIndex((item) => this.isUrlExcluded(req, item)) > -1;\n if (shallPass) {\n return next.handle(req);\n }\n\n return combineLatest([from(this.conditionallyUpdateToken(req)), of(this.keycloak.isLoggedIn())]).pipe(\n mergeMap(([_, isLoggedIn]) => (isLoggedIn ? this.handleRequestWithTokenHeader(req, next) : next.handle(req)))\n );\n }\n\n /**\n * Adds the token of the current user to the Authorization header\n *\n * @param req\n * @param next\n */\n private handleRequestWithTokenHeader(req: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {\n return this.keycloak.addTokenToHeader(req.headers).pipe(\n mergeMap((headersWithBearer) => {\n const kcReq = req.clone({ headers: headersWithBearer });\n return next.handle(kcReq);\n })\n );\n }\n}\n","/**\n * @license\n * Copyright Mauricio Gemelli Vigolo and contributors.\n *\n * Use of this source code is governed by a MIT-style license that can be\n * found in the LICENSE file at https://github.com/mauriciovigolo/keycloak-angular/blob/main/LICENSE.md\n */\n\nimport { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { HTTP_INTERCEPTORS } from '@angular/common/http';\n\nimport { KeycloakService } from './services/keycloak.service';\nimport { KeycloakBearerInterceptor } from './interceptors/keycloak-bearer.interceptor';\n\n/**\n * @deprecated NgModules are deprecated in Keycloak Angular and will be removed in future versions.\n * Use the new `provideKeycloak` function to load Keycloak in an Angular application.\n * More info: https://github.com/mauriciovigolo/keycloak-angular/blob/main/docs/migration-guides/v19.md\n */\n@NgModule({\n imports: [CommonModule],\n providers: [\n KeycloakService,\n {\n provide: HTTP_INTERCEPTORS,\n useClass: KeycloakBearerInterceptor,\n multi: true\n }\n ]\n})\nexport class CoreModule {}\n","/**\n * @license\n * Copyright Mauricio Gemelli Vigolo and contributors.\n *\n * Use of this source code is governed by a MIT-style license that can be\n * found in the LICENSE file at https://github.com/mauriciovigolo/keycloak-angular/blob/main/LICENSE.md\n */\n\nimport { NgModule } from '@angular/core';\n\nimport { CoreModule } from './core/core.module';\n\n/**\n * @deprecated NgModules are deprecated in Keycloak Angular and will be removed in future versions.\n * Use the new `provideKeycloak` function to load Keycloak in an Angular application.\n * More info: https://github.com/mauriciovigolo/keycloak-angular/blob/main/docs/migration-guides/v19.md\n */\n@NgModule({\n imports: [CoreModule]\n})\nexport class KeycloakAngularModule {}\n","/**\n * @license\n * Copyright Mauricio Gemelli Vigolo All Rights Reserved.\n *\n * Use of this source code is governed by a MIT-style license that can be\n * found in the LICENSE file at https://github.com/mauriciovigolo/keycloak-angular/blob/main/LICENSE.md\n */\n\n// This legacy implementation will be removed in Keycloak Angular v20\nexport { KeycloakEventLegacy, KeycloakEventTypeLegacy } from './core/interfaces/keycloak-event';\nexport { KeycloakOptions } from './core/interfaces/keycloak-options';\nexport { KeycloakAuthGuard } from './core/services/keycloak-auth-guard';\nexport { KeycloakService } from './core/services/keycloak.service';\nexport { KeycloakBearerInterceptor } from './core/interceptors/keycloak-bearer.interceptor';\nexport { CoreModule } from './core/core.module';\nexport { KeycloakAngularModule } from './keycloak-angular.module';\n","/**\n * @license\n * Copyright Mauricio Gemelli Vigolo All Rights Reserved.\n *\n * Use of this source code is governed by a MIT-style license that can be\n * found in the LICENSE file at https://github.com/mauriciovigolo/keycloak-angular/blob/main/LICENSE.md\n */\n\nimport Keycloak, { KeycloakError } from 'keycloak-js';\nimport { signal, Signal, InjectionToken } from '@angular/core';\n\n/**\n * Keycloak event types, as described at the keycloak-js documentation:\n * https://www.keycloak.org/docs/latest/securing_apps/index.html#callback-events\n */\nexport enum KeycloakEventType {\n /**\n * Keycloak Angular is not initialized yet. This is the initial state applied to the Keycloak Event Signal.\n * Note: This event is only emitted in Keycloak Angular, it is not part of the keycloak-js.\n */\n KeycloakAngularNotInitialized = 'KeycloakAngularNotInitialized',\n /**\n * Keycloak Angular is in the process of initializing the providers and Keycloak Instance.\n * Note: This event is only emitted in Keycloak Angular, it is not part of the keycloak-js.\n */\n KeycloakAngularInit = 'KeycloakAngularInit',\n /**\n * Triggered if there is an error during authentication.\n */\n AuthError = 'AuthError',\n /**\n * Triggered when the user logs out. This event will only be triggered\n * if the session status iframe is enabled or in Cordova mode.\n */\n AuthLogout = 'AuthLogout',\n /**\n * Triggered if an error occurs while attempting to refresh the token.\n */\n AuthRefreshError = 'AuthRefreshError',\n /**\n * Triggered when the token is successfully refreshed.\n */\n AuthRefreshSuccess = 'AuthRefreshSuccess',\n /**\n * Triggered when a user is successfully authenticated.\n */\n AuthSuccess = 'AuthSuccess',\n /**\n * Triggered when the Keycloak adapter has completed initialization.\n */\n Ready = 'Ready',\n /**\n * Triggered when the access token expires. Depending on the flow, you may\n * need to use `updateToken` to refresh the token or redirect the user\n * to the login screen.\n */\n TokenExpired = 'TokenExpired',\n /**\n * Triggered when an authentication action is requested by the application.\n */\n ActionUpdate = 'ActionUpdate'\n}\n\n/**\n * Arguments for the `Ready` event, representing the authentication state.\n */\nexport type ReadyArgs = boolean;\n\n/**\n * Arguments for the `ActionUpdate` event, providing information about the status\n * and optional details about the action.\n */\nexport type ActionUpdateArgs = {\n /**\n * Status of the action, indicating whether it was successful, encountered an error,\n * or was cancelled.\n */\n status: 'success' | 'error' | 'cancelled';\n /**\n * Optional name or identifier of the action performed.\n */\n action?: string;\n};\n\n/**\n * Arguments for the `AuthError` event, providing detailed error information.\n */\nexport type AuthErrorArgs = KeycloakError;\n\ntype EventArgs = ReadyArgs | ActionUpdateArgs | AuthErrorArgs;\n\n/**\n * Helper function to typecast unknown arguments into a specific Keycloak event type.\n *\n * @template T - The expected argument type.\n * @param args - The arguments to be cast.\n * @returns The arguments typed as `T`.\n */\nexport const typeEventArgs = <T extends EventArgs>(args: unknown): T => args as T;\n\n/**\n * Structure of a Keycloak event, including its type and optional arguments.\n */\nexport interface KeycloakEvent {\n /**\n * Event type as described at {@link KeycloakEventType}.\n */\n type: KeycloakEventType;\n /**\n * Arguments from the keycloak-js event function.\n */\n args?: unknown;\n}\n\n/**\n * Creates a signal to manage Keycloak events, initializing the signal with\n * appropriate default values or values from a given Keycloak instance.\n *\n * @param keycloak - An instance of the Keycloak client.\n * @returns A `Signal` that tracks the current Keycloak event state.\n */\nexport const createKeycloakSignal = (keycloak?: Keycloak) => {\n const keycloakSignal = signal<KeycloakEvent>({\n type: KeycloakEventType.KeycloakAngularInit\n });\n\n if (!keycloak) {\n keycloakSignal.set({\n type: KeycloakEventType.KeycloakAngularNotInitialized\n });\n\n return keycloakSignal;\n }\n\n keycloak.onReady = (authenticated) => {\n keycloakSignal.set({\n type: KeycloakEventType.Ready,\n args: authenticated\n });\n };\n\n keycloak.onAuthError = (errorData) => {\n keycloakSignal.set({\n type: KeycloakEventType.AuthError,\n args: errorData\n });\n };\n\n keycloak.onAuthLogout = () => {\n keycloakSignal.set({\n type: KeycloakEventType.AuthLogout\n });\n };\n\n keycloak.onActionUpdate = (status, action) => {\n keycloakSignal.set({\n type: KeycloakEventType.ActionUpdate,\n args: { status, action }\n });\n };\n\n keycloak.onAuthRefreshError = () => {\n keycloakSignal.set({\n type: KeycloakEventType.AuthRefreshError\n });\n };\n\n keycloak.onAuthRefreshSuccess = () => {\n keycloakSignal.set({\n type: KeycloakEventType.AuthRefreshSuccess\n });\n };\n\n keycloak.onAuthSuccess = () => {\n keycloakSignal.set({\n type: KeycloakEventType.AuthSuccess\n });\n };\n\n keycloak.onTokenExpired = () => {\n keycloakSignal.set({\n type: KeycloakEventType.TokenExpired\n });\n };\n\n return keycloakSignal;\n};\n\n/**\n * Injection token for the Keycloak events signal, used for dependency injection.\n */\nexport const KEYCLOAK_EVENT_SIGNAL = new InjectionToken<Signal<KeycloakEvent>>('Keycloak Events Signal');\n","/**\n * @license\n * Copyright Mauricio Gemelli Vigolo All Rights Reserved.\n *\n * Use of this source code is governed by a MIT-style license that can be\n * found in the LICENSE file at https://github.com/mauriciovigolo/keycloak-angular/blob/main/LICENSE.md\n */\n\nimport { Directive, Input, TemplateRef, ViewContainerRef, inject, effect } from '@angular/core';\nimport Keycloak from 'keycloak-js';\n\nimport { KEYCLOAK_EVENT_SIGNAL, KeycloakEventType, ReadyArgs, typeEventArgs } from '../signals/keycloak-events-signal';\n\n/**\n * Structural directive to conditionally display elements based on Keycloak user roles.\n *\n * This directive checks if the authenticated user has at least one of the specified roles.\n * Roles can be validated against a specific **resource (client ID)** or the **realm**.\n *\n * ### Features:\n * - Supports role checking in both **resources (client-level roles)** and the **realm**.\n * - Accepts an array of roles to match.\n * - Optional configuration to check realm-level roles.\n *\n * ### Inputs:\n * - `kaHasRoles` (Required): Array of roles to validate.\n * - `resource` (Optional): The client ID or resource name to validate resource-level roles.\n * - `checkRealm` (Optional): A boolean flag to enable realm role validation (default is `false`).\n *\n * ### Requirements:\n * - A Keycloak instance must be injected via Angular's dependency injection.\n * - The user must be authenticated in Keycloak.\n *\n * @example\n * #### Example 1: Check for Global Realm Roles\n * Show the content only if the user has the `admin` or `editor` role in the realm.\n * ```html\n * <div *kaHasRoles=\"['admin', 'editor']; checkRealm:true\">\n * <p>This content is visible only to users with 'admin' or 'editor' realm roles.</p>\n * </div>\n * ```\n *\n * @example\n * #### Example 2: Check for Resource Roles\n * Show the content only if the user has the `read` or `write` role for a specific resource (`my-client`).\n * ```html\n * <div *kaHasRoles=\"['read', 'write']; resource:'my-client'\">\n * <p>This content is visible only to users with 'read' or 'write' roles for 'my-client'.</p>\n * </div>\n * ```\n *\n * @example\n * #### Example 3: Check for Both Resource and Realm Roles\n * Show the content if the user has the roles in either the realm or a resource.\n * ```html\n * <div *kaHasRoles=\"['admin', 'write']; resource:'my-client' checkRealm:true\">\n * <p>This content is visible to users with 'admin' in the realm or 'write' in 'my-client'.</p>\n * </div>\n * ```\n *\n * @example\n * #### Example 4: Fallback Content When Roles Do Not Match\n * Use an `<ng-template>` to display fallback content if the user lacks the required roles.\n * ```html\n * <div *kaHasRoles=\"['admin']; resource:'my-client'\">\n * <p>Welcome, Admin!</p>\n * </div>\n * <ng-template #noAccess>\n * <p>Access Denied</p>\n * </ng-template>\n * ```\n */\n@Directive({\n selector: '[kaHasRoles]'\n})\nexport class HasRolesDirective {\n private templateRef = inject<TemplateRef<unknown>>(TemplateRef);\n private viewContainer = inject(ViewContainerRef);\n private keycloak = inject(Keycloak);\n\n /**\n * List of roles to validate against the resource or realm.\n */\n @Input('kaHasRoles') roles: string[] = [];\n\n /**\n * The resource (client ID) to validate roles against.\n */\n @Input('kaHasRolesResource') resource?: string;\n\n /**\n * Flag to enable realm-level role validation.\n */\n @Input('kaHasRolesCheckRealm') checkRealm: boolean = false;\n\n constructor() {\n this.viewContainer.clear();\n\n const keycloakSignal = inject(KEYCLOAK_EVENT_SIGNAL);\n\n effect(() => {\n const keycloakEvent = keycloakSignal();\n if (keycloakEvent.type !== KeycloakEventType.Ready) {\n return;\n }\n\n const authenticated = typeEventArgs<ReadyArgs>(keycloakEvent.args);\n if (authenticated) {\n this.render();\n }\n });\n }\n\n private render(): void {\n const hasAccess = this.checkUserRoles();\n if (hasAccess) {\n this.viewContainer.createEmbeddedView(this.templateRef);\n } else {\n this.viewContainer.clear();\n }\n }\n\n /**\n * Checks if the user has at least one of the specified roles in the resource or realm.\n * @returns True if the user has access, false otherwise.\n */\n private checkUserRoles(): boolean {\n const hasResourceRole = this.roles.some((role) => this.keycloak.hasResourceRole(role, this.resource));\n\n const hasRealmRole = this.checkRealm ? this.roles.some((role) => this.keycloak.hasRealmRole(role)) : false;\n\n return hasResourceRole || hasRealmRole;\n }\n}\n","/**\n * @license\n * Copyright Mauricio Gemelli Vigolo All Rights Reserved.\n *\n * Use of this source code is governed by a MIT-style license that can be\n * found in the LICENSE file at https://github.com/mauriciovigolo/keycloak-angular/blob/main/LICENSE.md\n */\n\n/**\n * Represents a feature from keycloak-angular that can be configured during the library initialization.\n *\n * This type defines the structure of a feature that includes a `configure` method,\n * which is responsible for setting up or initializing the feature's behavior or properties\n * related to Keycloak.\n *\n * ### Usage:\n * The `KeycloakFeature` type is typically used for defining modular, reusable Keycloak\n * features that can be dynamically configured and integrated into an application.\n *\n * @property {() => void} configure - A method that initializes or configures the feature.\n * This method is invoked to perform any setup or customization required for the feature.\n *\n * ### Example:\n * ```typescript\n * const withLoggingFeature: KeycloakFeature = {\n * configure: () => {\n * console.log('Configuring Keycloak logging feature');\n * },\n * };\n *\n * const withAnalyticsFeature: KeycloakFeature = {\n * configure: () => {\n * console.log('Configuring Keycloak analytics feature');\n * },\n * };\n *\n * // Configure and initialize features\n * withLoggingFeature.configure();\n * withAnalyticsFeature.configure();\n * ```\n */\nexport type KeycloakFeature = {\n configure: () => void;\n};\n","/**\n * @license\n * Copyright Mauricio Gemelli Vigolo All Rights Reserved.\n *\n * Use of this source code is governed by a MIT-style license that can be\n * found in the LICENSE file at https://github.com/mauriciovigolo/keycloak-angular/blob/main/LICENSE.md\n */\n\nimport { Injectable, OnDestroy, NgZone, signal, computed, inject, PLATFORM_ID } from '@angular/core';\nimport { isPlatformBrowser } from '@angular/common';\nimport { fromEvent, Subject } from 'rxjs';\nimport { debounceTime, takeUntil } from 'rxjs/operators';\n\n/**\n * Service to monitor user activity in an Angular application.\n * Tracks user interactions (e.g., mouse movement, touch, key presses, clicks, and scrolls)\n * and updates the last activity timestamp. Consumers can check for user inactivity\n * based on a configurable timeout.\n *\n * The service is supposed to be used in the client context and for safety, it checks during the startup\n * if it is a browser context.\n */\n@Injectable()\nexport class UserActivityService implements OnDestroy {\n private ngZone = inject(NgZone);\n\n /**\n * Signal to store the timestamp of the last user activity.\n * The timestamp is represented as the number of milliseconds since epoch.\n */\n private lastActivity = signal<number>(Date.now());\n\n /**\n * Subject to signal the destruction of the service.\n * Used to clean up RxJS subscriptions.\n */\n private destroy$ = new Subject<void>();\n\n /**\n * Computed signal to expose the last user activity as a read-only signal.\n */\n public readonly lastActivitySignal = computed(() => this.lastActivity());\n\n /**\n * Starts monitoring user activity events (`mousemove`, `touchstart`, `keydown`, `click`, `scroll`)\n * and updates the last activity timestamp using RxJS with debounce.\n * The events are processed outside Angular zone for performance optimization.\n */\n startMonitoring(): void {\n const isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n if (!isBrowser) {\n return;\n }\n\n this.ngZone.runOutsideAngular(() => {\n const events = ['mousemove', 'touchstart', 'keydown', 'click', 'scroll'];\n\n events.forEach((event) => {\n fromEvent(window, event)\n .pipe(debounceTime(300), takeUntil(this.destroy$))\n .subscribe(() => this.updateLastActivity());\n });\n });\n }\n\n /**\n * Updates the last activity timestamp to the current time.\n * This method runs inside Angular's zone to ensure reactivity with Angular signals.\n */\n private updateLastActivity(): void {\n this.ngZone.run(() => {\n this.lastActivity.set(Date.now());\n });\n }\n\n /**\n * Retrieves the timestamp of the last recorded user activity.\n * @returns {number} The last activity timestamp in milliseconds since epoch.\n */\n get lastActivityTime(): number {\n return this.lastActivity();\n }\n\n /**\n * Determines whether the user interacted with the application, meaning it is activily using the application, based on\n * the specified duration.\n * @param timeout - The inactivity timeout in milliseconds.\n * @returns {boolean} `true` if the user is inactive, otherwise `false`.\n */\n isActive(timeout: number): boolean {\n return Date.now() - this.lastActivityTime < timeout;\n }\n\n /**\n * Cleans up RxJS subscriptions and resources when the service is destroyed.\n * This method is automatically called by Angular when the service is removed.\n */\n ngOnDestroy(): void {\n this.destroy$.next();\n this.destroy$.complete();\n }\n}\n","/**\n * @license\n * Copyright Mauricio Gemelli Vigolo All Rights Reserved.\n *\n * Use of this source code is governed by a MIT-style license that can be\n * found in the LICENSE file at https://github.com/mauriciovigolo/keycloak-angular/blob/main/LICENSE.md\n */\n\nimport { effect, inject, Injectable } from '@angular/core';\nimport Keycloak from 'keycloak-js';\n\nimport { KEYCLOAK_EVENT_SIGNAL, KeycloakEventType } from '../signals/keycloak-events-signal';\nimport { UserActivityService } from './user-activity.service';\n\n/**\n * Configuration options for the `AutoRefreshTokenService`.\n */\ntype AutoRefreshTokenOptions = {\n /**\n * Maximum allowed inactivity duration in milliseconds before\n * the session times out. Default is `300000`.\n */\n sessionTimeout?: number;\n\n /**\n * Action to take when the session times out due to inactivity.\n * Options are:\n * - `'login'`: Redirect to the Keycloak login page.\n * - `'logout'`: Log the user out of the session.\n * - `'none'`: Do nothing.\n * Default is `'logout'`.\n */\n onInactivityTimeout?: 'login' | 'logout' | 'none';\n};\n\n/**\n * Service to automatically manage the Keycloak token refresh process\n * based on user activity and token expiration events. This service\n * integrates with Keycloak for session management and interacts with\n * user activity monitoring to determine the appropriate action when\n * the token expires.\n *\n * The service listens to `KeycloakSignal` for token-related events\n * (e.g., `TokenExpired`) and provides configurable options for\n * session timeout and inactivity handling.\n */\n@Injectable()\nexport class AutoRefreshTokenService {\n private readonly keycloak = inject(Keycloak);\n private readonly userActivity = inject(UserActivityService);\n\n private options: Required<AutoRefreshTokenOptions> = this.defaultOptions;\n private initialized = false;\n\n constructor() {\n const keycloakSignal = inject(KEYCLOAK_EVENT_SIGNAL);\n\n effect(() => {\n const keycloakEvent = keycloakSignal();\n\n if (keycloakEvent.type === KeycloakEventType.TokenExpired) {\n this.processTokenExpiredEvent();\n }\n });\n }\n\n private get defaultOptions(): Required<AutoRefreshTokenOptions> {\n return {\n sessionTimeout: 300000,\n onInactivityTimeout: 'logout'\n };\n }\n\n private executeOnInactivityTimeout() {\n switch (this.options.onInactivityTimeout) {\n case 'login':\n this.keycloak.login().catch((error) => console.error('Failed to execute the login call', error));\n break;\n case 'logout':\n this.keycloak.logout().catch((error) => console.error('Failed to execute the logout call', error));\n break;\n default:\n break;\n }\n }\n\n private processTokenExpiredEvent() {\n if (!this.initialized || !this.keycloak.authenticated) {\n return;\n }\n\n if (this.userActivity.isActive(this.options.sessionTimeout)) {\n this.keycloak.updateToken().catch(() => this.executeOnInactivityTimeout());\n } else {\n this.executeOnInactivityTimeout();\n }\n }\n\n start(options?: AutoRefreshTokenOptions) {\n this.options = { ...this.defaultOptions, ...options };\n this.initialized = true;\n this.userActivity.startMonitoring();\n }\n}\n","/**\n * @license\n * Copyright Mauricio Gemelli Vigolo All Rights Reserved.\n *\n * Use of this source code is governed by a MIT-style license that can be\n * found in the LICENSE file at https://github.com/mauriciovigolo/keycloak-angular/blob/main/LICENSE.md\n */\n\nimport { inject } from '@angular/core';\n\nimport { AutoRefreshTokenService } from '../services/auto-refresh-token.service';\nimport { KeycloakFeature } from './keycloak.feature';\n\n/**\n * Options for configuring the auto-refresh token feature.\n *\n * This type defines the configuration parameters for enabling auto-refresh\n * of Keycloak tokens and handling session inactivity scenarios.\n */\ntype WithRefreshTokenOptions = {\n /**\n * The session timeout duration in milliseconds. This specifies the time\n * of inactivity after which the session is considered expired.\n *\n * Default value: `300000` milliseconds (5 minutes).\n */\n sessionTimeout?: number;\n\n /**\n * Action to take when the session timeout due to inactivity occurs.\n *\n * - `'login'`: Execute the `keycloak.login` method.\n * - `'logout'`: Logs the user out by calling the `keycloak.logout` method.\n * - `'none'`: Takes no action on session timeout.\n *\n * Default value: `'logout'`.\n */\n onInactivityTimeout?: 'login' | 'logout' | 'none';\n};\n\n/**\n * Enables automatic token refresh and session inactivity handling for a\n * Keycloak-enabled Angular application.\n *\n * This function initializes a service that tracks user interactions, such as\n * mouse movements, touches, key presses, clicks, and scrolls. If user activity\n * is detected, it periodically calls `Keycloak.updateToken` to ensure the bearer\n * token remains valid and does not expire.\n *\n * If the session remains inactive beyond the defined `sessionTimeout`, the\n * specified action (`logout`, `login`, or `none`) will be executed. By default,\n * the service will call `keycloak.logout` upon inactivity timeout.\n *\n * Event tracking uses RxJS observables with a debounce of 300 milliseconds to\n * monitor user interactions. When the Keycloak `OnTokenExpired` event occurs,\n * the service checks the user's last activity timestamp. If the user has been\n * active within the session timeout period, it refreshes the token using `updateToken`.\n *\n *\n * @param options - Configuration options for the auto-refresh token feature.\n * - `sessionTimeout` (optional): The duration in milliseconds after which\n * the session is considered inactive. Defaults to `300000` (5 minutes).\n * - `onInactivityTimeout` (optional): The action to take when session inactivity\n * exceeds the specified timeout. Defaults to `'logout'`.\n * - `'login'`: Execute `keycloak.login` function.\n * - `'logout'`: Logs the user out by calling `keycloak.logout`.\n * - `'none'`: No action is taken.\n *\n * @returns A `KeycloakFeature` instance that configures and enables the\n * auto-refresh token functionality.\n */\nexport function withAutoRefreshToken(options?: WithRefreshTokenOptions): KeycloakFeature {\n return {\n configure: () => {\n const autoRefreshTokenService = inject(AutoRefreshTokenService);\n autoRefreshTokenService.start(options);\n }\n };\n}\n","/**\n * @license\n * Copyright Mauricio Gemelli Vigolo All Rights Reserved.\n *\n * Use of this source code is governed by a MIT-style license that can be\n * found in the LICENSE file at https://github.com/mauriciovigolo/keycloak-angular/blob/main/LICENSE.md\n */\n\nimport Keycloak, { KeycloakResourceAccess } from 'keycloak-js';\nimport { inject } from '@angular/core';\nimport {\n ActivatedRouteSnapshot,\n CanActivateChildFn,\n CanActivateFn,\n RouterStateSnapshot,\n UrlTree\n} from '@angular/router';\n\n/**\n * Type representing the roles granted to a user, including both realm and resource-level roles.\n */\ntype Roles = {\n /**\n * Roles assigned at the realm level.\n */\n realmRoles: string[];\n /**\n * Roles assigned at the resource level, organized by resource name.\n */\n resourceRoles: { [resource: string]: string[] };\n};\n\n/**\n * Data structure passed to the custom authorization guard to determine access.\n */\nexport type AuthGuardData = {\n /**\n * Indicates whether the user is currently authenticated.\n */\n authenticated: boolean;\n /**\n * A collection of roles granted to the user, including both realm and resource roles.\n */\n grantedRoles: Roles;\n /**\n * The Keycloak instance managing the user's session and access.\n */\n keycloak: Keycloak;\n};\n\nconst mapResourceRoles = (resourceAccess: KeycloakResourceAccess = {}): Record<string, string[]> => {\n return Object.entries(resourceAccess).reduce<Record<string, string[]>>((roles, [key, value]) => {\n roles[key] = value.roles;\n return roles;\n }, {});\n};\n\n/**\n * Creates a custom authorization guard for Angular routes, enabling fine-grained access control.\n *\n * This guard invokes the provided `isAccessAllowed` function to determine if access is permitted\n * based on the current route, router state, and user's authentication and roles data.\n *\n * @template T - The type of the guard function (`CanActivateFn` or `CanActivateChildFn`).\n * @param isAccessAllowed - A callback function that evaluates access conditions. The function receives:\n * - `route`: The current `ActivatedRouteSnapshot` for the route being accessed.\n * - `state`: The current `RouterStateSnapshot` representing the router's state.\n * - `authData`: An `AuthGuardData` object containing the user's authentication status, roles, and Keycloak instance.\n * @returns A guard function of type `T` that can be used as a route `canActivate` or `canActivateChild` guard.\n *\n * @example\n * ```ts\n * import { createAuthGuard } from './auth-guard';\n * import { Routes } from '@angular/router';\n *\n * const isUserAllowed = async (route, state, authData) => {\n * const { authenticated, grantedRoles } = authData;\n * return authenticated && grantedRoles.realmRoles.includes('admin');\n * };\n *\n * const routes: Routes = [\n * {\n * path: 'admin',\n * canActivate: [createAuthGuard(isUserAllowed)],\n * component: AdminComponent,\n * },\n * ];\n * ```\n */\nexport const createAuthGuard = <T extends CanActivateFn | CanActivateChildFn>(\n isAccessAllowed: (\n route: ActivatedRouteSnapshot,\n state: RouterStateSnapshot,\n authData: AuthGuardData\n ) => Promise<boolean | UrlTree>\n): T => {\n return ((next: ActivatedRouteSnapshot, state: RouterStateSnapshot) => {\n const keycloak = inject(Keycloak);\n\n const authenticated = keycloak?.authenticated ?? false;\n const grantedRoles: Roles = {\n resourceRoles: mapResourceRoles(keycloak?.resourceAccess),\n realmRoles: keycloak?.realmAccess?.roles ?? []\n };\n const authData = { authenticated, keycloak, grantedRoles };\n\n return isAccessAllowed(next, state, authData);\n }) as T;\n};\n","/**\n * @license\n * Copyright Mauricio Gemelli Vigolo All Rights Reserved.\n *\n * Use of this source code is governed by a MIT-style license that can be\n * found in the LICENSE file at https://github.com/mauriciovigolo/keycloak-angular/blob/main/LICENSE.md\n */\n\nimport { Observable } from 'rxjs';\nimport Keycloak from 'keycloak-js';\nimport { HttpEvent, HttpHandlerFn, HttpRequest } from '@angular/common/http';\n\n/**\n * Default value for the authorization header prefix, used to construct the Authorization token.\n */\nconst BEARER_PREFIX = 'Bearer';\n/**\n * Default name of the authorization header.\n */\nconst AUTHORIZATION_HEADER_NAME = 'Authorization';\n/**\n * Represents the HTTP methods supported by the interceptor for authorization purposes.\n */\nexport type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'OPTIONS' | 'HEAD' | 'PATCH';\n\n/**\n * Common attributes for the Auth Bearer interceptor that can be reused in other interceptor implementations.\n */\nexport type BearerTokenCondition = {\n /**\n * Prefix to be used in the Authorization header. Default is \"Bearer\".\n * This will result in a header formatted as: `Authorization: Bearer <token>`.\n *\n * Adjust this value if your backend expects a different prefix in the Authorization header.\n */\n bearerPrefix?: string;\n /**\n * Name of the HTTP header used for authorization. Default is \"Authorization\".\n * Customize this value if your backend expects a different header, e.g., \"JWT-Authorization\".\n */\n authorizationHeaderName?: string;\n /**\n * Function to determine whether the token should be updated before a request. Default is a function returning true.\n * If the function returns `true`, the token's validity will be checked and updated if needed.\n * If it returns `false`, the token update process will be skipped for that request.\n *\n * @param request - The current `HttpRequest` object being intercepted.\n * @returns A boolean indicating whether to update the token.\n */\n\n shouldUpdateToken?: (request: HttpRequest<unknown>) => boolean;\n};\n\n/**\n * Generic factory function to create an interceptor condition with default values.\n *\n * This utility allows you to define custom interceptor conditions while ensuring that\n * default values are applied to any missing fields. By using generics, you can enforce\n * strong typing when creating the fields for the interceptor condition, enhancing type safety.\n *\n * @template T - A type that extends `AuthBearerCondition`.\n * @param value - An object of type `T` (extending `AuthBearerCondition`) to be enhanced with default values.\n * @returns A new object of type `T` with default values assigned to any undefined properties.\n */\nexport const createInterceptorCondition = <T extends BearerTokenCondition>(value: T): T => ({\n ...value,\n bearerPrefix: value.bearerPrefix ?? BEARER_PREFIX,\n authorizationHeaderName: value.authorizationHeaderName ?? AUTHORIZATION_HEADER_NAME,\n shouldUpdateToken: value.shouldUpdateToken ?? (() => true)\n});\n\n/**\n * Conditionally updates the Keycloak token based on the provided request and conditions.\n *\n * @param req - The `HttpRequest` object being processed.\n * @param keycloak - The Keycloak instance managing authentication.\n * @param condition - An `AuthBearerCondition` object with the `shouldUpdateToken` function.\n * @returns A `Promise<boolean>` indicating whether the token was successfully updated.\n */\nexport const conditionallyUpdateToken = async (\n req: HttpRequest<unknown>,\n keycloak: Keycloak,\n { shouldUpdateToken = (_) => true }: BearerTokenCondition\n): Promise<boolean> => {\n if (shouldUpdateToken(req)) {\n return await keycloak.updateToken().catch(() => false);\n }\n return true;\n};\n\n/**\n * Adds the Authorization header to an HTTP request and forwards it to the next handler.\n *\n * @param req - The original `HttpRequest` object.\n * @param next - The `HttpHandlerFn` function for forwarding the HTTP request.\n * @param keycloak - The Keycloak instance providing the authentication token.\n * @param condition - An `AuthBearerCondition` object specifying header configuration.\n * @returns An `Observable<HttpEvent<unknown>>` representing the HTTP response.\n */\nexport const addAuthorizationHeader = (\n req: HttpRequest<unknown>,\n next: HttpHandlerFn,\n keycloak: Keycloak,\n condition: BearerTokenCondition\n): Observable<HttpEvent<unknown>> => {\n const { bearerPrefix = BEARER_PREFIX, authorizationHeaderName = AUTHORIZATION_HEADER_NAME } = condition;\n\n const clonedRequest = req.clone({\n setHeaders: {\n [authorizationHeaderName]: `${bearerPrefix} ${keycloak.token}`\n }\n });\n\n return next(clonedRequest);\n};\n","/**\n * @license\n * Copyright Mauricio Gemelli Vigolo All Rights Reserved.\n *\n * Use of this source code is governed by a MIT-style license that can be\n * found in the LICENSE file at https://github.com/mauriciovigolo/keycloak-angular/blob/main/LICENSE.md\n */\n\nimport Keycloak from 'keycloak-js';\nimport { from, mergeMap, Observable } from 'rxjs';\nimport { inject, InjectionToken } from '@angular/core';\nimport { HttpEvent, HttpHandlerFn, HttpRequest } from '@angular/common/http';\n\nimport { addAuthorizationHeader, conditionallyUpdateToken, BearerTokenCondition } from './keycloak.interceptor';\n\n/**\n * Defines a custom condition for determining whether a Bearer token should be included\n * in the `Authorization` header of an outgoing HTTP request.\n *\n * This type extends the `BearerTokenCondition` type and adds a dynamic function\n * (`shouldAddToken`) that evaluates whether the token should be added based on the\n * request, handler, and Keycloak state.\n */\nexport type CustomBearerTokenCondition = Partial<BearerTokenCondition> & {\n /**\n * A function that dynamically determines whether the Bearer token should be included\n * in the `Authorization` header for a given request.\n *\n * This function is asynchronous and receives the following arguments:\n * - `req`: The `HttpRequest` object representing the current outgoing HTTP request.\n * - `next`: The `HttpHandlerFn` for forwarding the request to the next handler in the chain.\n * - `keycloak`: The `Keycloak` instance representing the authentication context.\n */\n shouldAddToken: (req: HttpRequest<unknown>, next: HttpHandlerFn, keycloak: Keycloak) => Promise<boolean>;\n};\n\n/**\n * Injection token for configuring the `customBearerTokenInterceptor`.\n *\n * This injection token holds an array of `CustomBearerTokenCondition` objects, which define\n * the conditions under which a Bearer token should be included in the `Authorization` header\n * of outgoing HTTP requests. Each condition provides a `shouldAddToken` function that dynamically\n * determines whether the token should be added based on the request, handler, and Keycloak state.\n */\nexport const CUSTOM_BEARER_TOKEN_INTERCEPTOR_CONFIG = new InjectionToken<CustomBearerTokenCondition[]>(\n 'Include the bearer token as implemented by the provided function'\n);\n\n/**\n * Custom HTTP Interceptor for dynamically adding a Bearer token to requests based on conditions.\n *\n * This interceptor uses a flexible approach where the decision to include a Bearer token in the\n * `Authorization` HTTP header is determined by a user-provided function (`shouldAddToken`).\n * This enables a dynamic and granular control over when tokens are added to HTTP requests.\n *\n * ### Key Features:\n * 1. **Dynamic Token Inclusion**: Uses a condition function (`shouldAddToken`) to decide dynamically\n * whether to add the token based on the request, Keycloak state, and other factors.\n * 2. **Token Management**: Optionally refreshes the Keycloak token before adding it to the request.\n * 3. **Controlled Authorization**: Adds the Bearer token only when the condition function allows\n * and the user is authenticated in Keycloak.\n *\n * ### Configuration:\n * The interceptor relies on `CUSTOM_BEARER_TOKEN_INTERCEPTOR_CONFIG`, an injection token that contains\n * an array of `CustomBearerTokenCondition` objects. Each condition specifies a `shouldAddToken` function\n * that determines whether to add the Bearer token for a given request.\n *\n * ### Workflow:\n * 1. Reads the conditions from the `CUSTOM_BEARER_TOKEN_INTERCEPTOR_CONFIG` injection token.\n * 2. Iterates through the conditions and evaluates the `shouldAddToken` function for the request.\n * 3. If a condition matches:\n * - Optionally refreshes the Keycloak token if needed.\n * - Adds the Bearer token to the request's `Authorization` header if the user is authenticated.\n * 4. If no conditions match, the request proceeds unchanged.\n *\n * ### Parameters:\n * @param req - The `HttpRequest` object representing the outgoing HTTP request.\n * @param next - The `HttpHandlerFn` for passing the request to the next handler in the chain.\n *\n * @returns An `Observable<HttpEvent<unknown>>` representing the HTTP response.\n *\n * ### Usage Example:\n * ```typescript\n * // Define a custom condition to include the token\n * const customCondition: CustomBearerTokenCondition = {\n * shouldAddToken: async (req, next, keycloak) => {\n * // Add token only for requests to the /api endpoint\n * return req.url.startsWith('/api') && keycloak.authenticated;\n * },\n * };\n *\n * // Configure the interceptor with the custom condition\n * export const appConfig: ApplicationConfig = {\n * providers: [\n * provideHttpClient(withInterceptors([customBearerTokenInterceptor])),\n * {\n * provide: CUSTOM_BEARER_TOKEN_INTERCEPTOR_CONFIG,\n * useValue: [customCondition],\n * },\n * ],\n * };\n * ```\n */\nexport const customBearerTokenInterceptor = (\n req: HttpRequest<unknown>,\n next: HttpHandlerFn\n): Observable<HttpEvent<unknown>> => {\n const conditions = inject(CUSTOM_BEARER_TOKEN_INTERCEPTOR_CONFIG) ?? [];\n\n const keycloak = inject(Keycloak);\n\n return from(\n Promise.all(conditions.map(async (condition) => await condition.shouldAddToken(req, next, keycloak)))\n ).pipe(\n mergeMap((evaluatedConditions) => {\n const matchingConditionIndex = evaluatedConditions.findIndex(Boolean);\n const matchingCondition = conditions[matchingConditionIndex];\n\n if (!matchingCondition) {\n return next(req);\n }\n\n return from(conditionallyUpdateToken(req, keycloak, matchingCondition)).pipe(\n mergeMap(() =>\n keycloak.authenticated ? addAuthorizationHeader(req, next, keycloak, matchingCondition) : next(req)\n )\n );\n })\n );\n};\n","/**\n * @license\n * Copyright Mauricio Gemelli Vigolo All Rights Reserved.\n *\n * Use of this source code is governed by a MIT-style license that can be\n * found in the LICENSE file at https://github.com/mauriciovigolo/keycloak-angular/blob/main/LICENSE.md\n */\n\nimport Keycloak from 'keycloak-js';\nimport { from, mergeMap, Observable } from 'rxjs';\nimport { inject, InjectionToken } from '@angular/core';\nimport { HttpEvent, HttpHandlerFn, HttpRequest } from '@angular/common/http';\n\nimport {\n addAuthorizationHeader,\n conditionallyUpdateToken,\n HttpMethod,\n BearerTokenCondition\n} from './keycloak.interceptor';\n\n/**\n * Defines the conditions for including the Bearer token in the Authorization HTTP header.\n */\nexport type IncludeBearerTokenCondition = Partial<BearerTokenCondition> & {\n /**\n * A URL pattern (as a `RegExp`) used to determine whether the Bearer token should be added\n * to the Authorization HTTP header for a given request. The Bearer token is only added if\n * this pattern matches the request's URL.\n *\n * This EXPLICIT configuration is for security purposes, ensuring that internal tokens are not\n * shared with unintended services.\n */\n urlPattern: RegExp;\n /**\n * An optional array of HTTP methods (`HttpMethod[]`) to further refine the conditions under\n * which the Bearer token is added. If not provided, the default behavior is to add the token\n * for all HTTP methods matching the `urlPattern`.\n */\n httpMethods?: HttpMethod[];\n};\n\n/**\n * Injection token for configuring the `includeBearerTokenInterceptor`, allowing the specification\n * of conditions under which the Bearer token should be included in HTTP request headers.\n *\n * This configuration supports multiple conditions, enabling customization for different URLs.\n * It also provides options to tailor the Bearer prefix and the Authorization header name as needed.\n */\nexport const INCLUDE_BEARER_TOKEN_INTERCEPTOR_CONFIG = new InjectionToken<IncludeBearerTokenCondition[]>(\n 'Include the bearer token when explicitly defined int the URL pattern condition'\n);\n\nconst findMatchingCondition = (\n { method, url }: HttpRequest<unknown>,\n { urlPattern, httpMethods = [] }: IncludeBearerTokenCondition\n): boolean => {\n const httpMethodTest = httpMethods.length === 0 || httpMethods.join().indexOf(method.toUpperCase()) > -1;\n\n const urlTest = urlPattern.test(url);\n\n return httpMethodTest && urlTest;\n};\n\n/**\n * HTTP Interceptor to include a Bearer token in the Authorization header for specific HTTP requests.\n *\n * This interceptor ensures that a Bearer token is added to outgoing HTTP requests based on explicitly\n * defined conditions. By default, the interceptor does not include the Bearer token unless the request\n * matches the provided configuration (`IncludeBearerTokenCondition`). This approach enhances security\n * by preventing sensitive tokens from being unintentionally sent to unauthorized services.\n *\n * ### Features:\n * 1. **Explicit URL Matching**: The interceptor uses regular expressions to match URLs where the Bearer token should be included.\n * 2. **HTTP Method Filtering**: Optional filtering by HTTP methods (e.g., `GET`, `POST`, `PUT`) to refine the conditions for adding the token.\n * 3. **Token Management**: Ensures the Keycloak token is valid by optionally refreshing it before attaching it to the request.\n * 4. **Controlled Authorization**: Sends the token only for requests where the user is authenticated, and the conditions match.\n *\n * ### Workflow:\n * - Reads conditions from `INCLUDE_BEARER_TOKEN_INTERCEPTOR_CONFIG`, which specifies when the Bearer token should be included.\n * - If a request matches the conditions:\n * 1. The Keycloak token is refreshed if needed.\n * 2. The Bearer token is added to the Authorization header.\n * 3. The modified request is passed to the next handler.\n * - If no conditions match, the request proceeds unchanged.\n *\n * ### Security:\n * By explicitly defining URL patterns and optional HTTP methods, this interceptor prevents the leakage of tokens\n * to unintended endpoints, such as third-party APIs or external services. This is especially critical for applications\n * that interact with both internal and external services.\n *\n * @param req - The `HttpRequest` object representing the outgoing HTTP request.\n * @param next - The `HttpHandlerFn` for passing the request to the next handler in the chain.\n * @returns An `Observable<HttpEvent<unknown>>` representing the asynchronous HTTP response.\n *\n * ### Configuration:\n * The interceptor relies on `INCLUDE_BEARER_TOKEN_INTERCEPTOR_CONFIG`, an injection token that holds\n * an array of `IncludeBearerTokenCondition` objects. Each object defines the conditions for including\n * the Bearer token in the request.\n *\n * #### Example Configuration:\n * ```typescript\n * provideHttpClient(\n * withInterceptors([includeBearerTokenInterceptor]),\n * {\n * provide: INCLUDE_BEARER_TOKEN_INTERCEPTOR_CONFIG,\n * useValue: [\n * {\n * urlPattern: /^https:\\/\\/api\\.internal\\.myapp\\.com\\/.*\\/,\n * httpMethods: ['GET', 'POST'], // Add the token only for GET and POST methods\n * },\n * ],\n * }\n * );\n * ```\n *\n * ### Example Usage:\n * ```typescript\n * export const appConfig: ApplicationConfig = {\n * providers: [\n * provideHttpClient(withInterceptors([includeBearerTokenInterceptor])),\n * provideZoneChangeDetection({ eventCoalescing: true }),\n * provideRouter(routes),\n * ],\n * };\n * ```\n *\n * ### Example Matching Condition:\n * ```typescript\n * {\n * urlPattern: /^(https:\\/\\/internal\\.mycompany\\.com)(\\/.*)?$/i,\n * httpMethods: ['GET', 'PUT'], // Optional: Match only specific HTTP methods\n * }\n * ```\n */\nexport const includeBearerTokenInterceptor = (\n req: HttpRequest<unknown>,\n next: HttpHandlerFn\n): Observable<HttpEvent<unknown>> => {\n const conditions = inject(INCLUDE_BEARER_TOKEN_INTERCEPTOR_CONFIG) ?? [];\n\n const matchingCondition = conditions.find((condition) => findMatchingCondition(req, condition));\n if (!matchingCondition) {\n return next(req);\n }\n\n const keycloak = inject(Keycloak);\n\n return from(conditionallyUpdateToken(req, keycloak, matchingCondition)).pipe(\n mergeMap(() =>\n keycloak.authenticated ? addAuthorizationHeader(req, next, keycloak, matchingCondition) : next(req)\n )\n );\n};\n","/**\n * @license\n * Copyright Mauricio Gemelli Vigolo All Rights Reserved.\n *\n * Use of this source code is governed by a MIT-style license that can be\n * found in the LICENSE file at https://github.com/mauriciovigolo/keycloak-angular/blob/main/LICENSE.md\n */\n\nimport Keycloak, { KeycloakConfig, KeycloakInitOptions } from 'keycloak-js';\nimport {\n EnvironmentInjector,\n EnvironmentProviders,\n inject,\n makeEnvironmentProviders,\n provideAppInitializer,\n Provider,\n runInInjectionContext\n} from '@angular/core';\nimport { createKeycloakSignal, KEYCLOAK_EVENT_SIGNAL } from './signals/keycloak-events-signal';\nimport { KeycloakFeature } from './features/keycloak.feature';\n\n/**\n * Options for configuring Keycloak and additional providers.\n */\nexport type ProvideKeycloakOptions = {\n /**\n * Keycloak configuration, including the server URL, realm, and client ID.\n */\n config: KeycloakConfig;\n\n /**\n * Optional initialization options for the Keycloak instance.\n * If not provided, Keycloak will not initialize automatically.\n */\n initOptions?: KeycloakInitOptions;\n\n /**\n * Optional array of additional Angular providers or environment providers.\n */\n providers?: Array<Provider | EnvironmentProviders>;\n\n /**\n * Optional array of Keycloak features to extend the functionality of the Keycloak integration.\n */\n features?: Array<KeycloakFeature>;\n};\n\n/**\n * Provides Keycloak initialization logic for the app initializer phase.\n * Ensures Keycloak is initialized and features are configured.\n *\n * @param keycloak - The Keycloak instance.\n * @param options - ProvideKeycloakOptions for configuration.\n * @returns EnvironmentProviders or an empty array if `initOptions` is not provided.\n */\nconst provideKeycloakInAppInitializer = (\n keycloak: Keycloak,\n options: ProvideKeycloakOptions\n): EnvironmentProviders | Provider[] => {\n const { initOptions, features = [] } = options;\n\n if (!initOptions) {\n return [];\n }\n\n return provideAppInitializer(async () => {\n const injector = inject(EnvironmentInjector);\n runInInjectionContext(injector, () => features.forEach((feature) => feature.configure()));\n await keycloak.init(initOptions).catch((error) => console.error('Keycloak initialization failed', error));\n });\n};\n\n/**\n * Configures and provides Keycloak as a dependency in an Angular application.\n *\n * This function initializes a Keycloak instance with the provided configuration and\n * optional initialization options. It integrates Keycloak into Angular dependency\n * injection system, allowing easy consumption throughout the application. Additionally,\n * it supports custom providers and Keycloak Angular features.\n *\n * If `initOptions` is not provided, the Keycloak instance will not be automatically initialized.\n * In such cases, the application must call `keycloak.init()` explicitly.\n *\n * @param options - Configuration object for Keycloak:\n * - `config`: The Keycloak configuration, including the server URL, realm, and client ID.\n * - `initOptions` (Optional): Initialization options for the Keycloak instance.\n * - `providers` (Optional): Additional Angular providers to include.\n * - `features` (Optional): Keycloak Angular features to configure during initialization.\n *\n * @returns An `EnvironmentProviders` object integrating Keycloak setup and additional providers.\n *\n * @example\n * ```ts\n * import { provideKeycloak } from './keycloak.providers';\n * import { bootstrapApplication } from '@angular/platform-browser';\n * import { AppComponent } from './app/app.component';\n *\n * bootstrapApplication(AppComponent, {\n * providers: [\n * provideKeycloak({\n * config: {\n * url: 'https://auth-server.example.com',\n * realm: 'my-realm',\n * clientId: 'my-client',\n * },\n * initOptions: {\n * onLoad: 'login-required',\n * },\n * }),\n * ],\n * });\n * ```\n */\nexport function provideKeycloak(options: ProvideKeycloakOptions): EnvironmentProviders {\n const keycloak = new Keycloak(options.config);\n\n const providers = options.providers ?? [];\n const keycloakSignal = createKeycloakSignal(keycloak);\n\n return makeEnvironmentProviders([\n {\n provide: KEYCLOAK_EVENT_SIGNAL,\n useValue: keycloakSignal\n },\n {\n provide: Keycloak,\n useValue: keycloak\n },\n ...providers,\n provideKeycloakInAppInitializer(keycloak, options)\n ]);\n}\n","/**\n * @license\n * Copyright Mauricio Gemelli Vigolo All Rights Reserved.\n *\n * Use of this source code is governed by a MIT-style license that can be\n * found in the LICENSE file at https://github.com/mauriciovigolo/keycloak-angular/blob/main/LICENSE.md\n */\nexport * from './lib/legacy/public_api';\nexport * from './lib/directives/has-roles.directive';\nexport * from './lib/features/keycloak.feature';\nexport * from './lib/features/with-refresh-token.feature';\nexport * from './lib/guards/auth.guard';\nexport * from './lib/interceptors/custom-bearer-token.interceptor';\nexport * from './lib/interceptors/include-bearer-token.interceptor';\nexport * from './lib/interceptors/keycloak.interceptor';\nexport * from './lib/services/user-activity.service';\nexport * from './lib/services/auto-refresh-token.service';\nexport * from './lib/signals/keycloak-events-signal';\nexport * from './lib/provide-keycloak';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":["mergeMap"],"mappings":"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"}
1
+ {"version":3,"file":"keycloak-angular.mjs","sources":["../../../projects/keycloak-angular/src/lib/legacy/core/interfaces/keycloak-event.ts","../../../projects/keycloak-angular/src/lib/legacy/core/services/keycloak-auth-guard.ts","../../../projects/keycloak-angular/src/lib/legacy/core/services/keycloak.service.ts","../../../projects/keycloak-angular/src/lib/legacy/core/interceptors/keycloak-bearer.interceptor.ts","../../../projects/keycloak-angular/src/lib/legacy/core/core.module.ts","../../../projects/keycloak-angular/src/lib/legacy/keycloak-angular.module.ts","../../../projects/keycloak-angular/src/lib/legacy/public_api.ts","../../../projects/keycloak-angular/src/lib/signals/keycloak-events-signal.ts","../../../projects/keycloak-angular/src/lib/directives/has-roles.directive.ts","../../../projects/keycloak-angular/src/lib/features/keycloak.feature.ts","../../../projects/keycloak-angular/src/lib/services/user-activity.service.ts","../../../projects/keycloak-angular/src/lib/services/auto-refresh-token.service.ts","../../../projects/keycloak-angular/src/lib/features/with-refresh-token.feature.ts","../../../projects/keycloak-angular/src/lib/guards/auth.guard.ts","../../../projects/keycloak-angular/src/lib/interceptors/keycloak.interceptor.ts","../../../projects/keycloak-angular/src/lib/interceptors/custom-bearer-token.interceptor.ts","../../../projects/keycloak-angular/src/lib/interceptors/include-bearer-token.interceptor.ts","../../../projects/keycloak-angular/src/lib/provide-keycloak.ts","../../../projects/keycloak-angular/src/public_api.ts","../../../projects/keycloak-angular/src/keycloak-angular.ts"],"sourcesContent":["/**\n * @license\n * Copyright Mauricio Gemelli Vigolo and contributors.\n *\n * Use of this source code is governed by a MIT-style license that can be\n * found in the LICENSE file at https://github.com/mauriciovigolo/keycloak-angular/blob/main/LICENSE.md\n */\n\n/**\n * Keycloak event types, as described at the keycloak-js documentation:\n * https://www.keycloak.org/docs/latest/securing_apps/index.html#callback-events\n *\n * @deprecated Keycloak Event based on the KeycloakService is deprecated and\n * will be removed in future versions.\n * Use the new `KEYCLOAK_EVENT_SIGNAL` injection token to listen for the keycloak\n * events.\n * More info: https://github.com/mauriciovigolo/keycloak-angular/blob/main/docs/migration-guides/v19.md\n */\nexport enum KeycloakEventTypeLegacy {\n /**\n * Called if there was an error during authentication.\n */\n OnAuthError,\n /**\n * Called if the user is logged out\n * (will only be called if the session status iframe is enabled, or in Cordova mode).\n */\n OnAuthLogout,\n /**\n * Called if there was an error while trying to refresh the token.\n */\n OnAuthRefreshError,\n /**\n * Called when the token is refreshed.\n */\n OnAuthRefreshSuccess,\n /**\n * Called when a user is successfully authenticated.\n */\n OnAuthSuccess,\n /**\n * Called when the adapter is initialized.\n */\n OnReady,\n /**\n * Called when the access token is expired. If a refresh token is available the token\n * can be refreshed with updateToken, or in cases where it is not (that is, with implicit flow)\n * you can redirect to login screen to obtain a new access token.\n */\n OnTokenExpired,\n /**\n * Called when a AIA has been requested by the application.\n */\n OnActionUpdate\n}\n\n/**\n * Structure of an event triggered by Keycloak, contains it's type\n * and arguments (if any).\n *\n * @deprecated Keycloak Event based on the KeycloakService is deprecated and\n * will be removed in future versions.\n * Use the new `KEYCLOAK_EVENT_SIGNAL` injection token to listen for the keycloak\n * events.\n * More info: https://github.com/mauriciovigolo/keycloak-angular/blob/main/docs/migration-guides/v19.md\n */\nexport interface KeycloakEventLegacy {\n /**\n * Event type as described at {@link KeycloakEventTypeLegacy}.\n */\n type: KeycloakEventTypeLegacy;\n /**\n * Arguments from the keycloak-js event function.\n */\n args?: unknown;\n}\n","/**\n * @license\n * Copyright Mauricio Gemelli Vigolo and contributors.\n *\n * Use of this source code is governed by a MIT-style license that can be\n * found in the LICENSE file at https://github.com/mauriciovigolo/keycloak-angular/blob/main/LICENSE.md\n */\n\nimport { CanActivate, Router, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree } from '@angular/router';\n\nimport { KeycloakService } from './keycloak.service';\n\n/**\n * A simple guard implementation out of the box. This class should be inherited and\n * implemented by the application. The only method that should be implemented is #isAccessAllowed.\n * The reason for this is that the authorization flow is usually not unique, so in this way you will\n * have more freedom to customize your authorization flow.\n *\n * @deprecated Class based guards are deprecated in Keycloak Angular and will be removed in future versions.\n * Use the new `createAuthGuard` function to create a Guard for your application.\n * More info: https://github.com/mauriciovigolo/keycloak-angular/blob/main/docs/migration-guides/v19.md\n */\nexport abstract class KeycloakAuthGuard implements CanActivate {\n /**\n * Indicates if the user is authenticated or not.\n */\n protected authenticated: boolean;\n /**\n * Roles of the logged user. It contains the clientId and realm user roles.\n */\n protected roles: string[];\n\n constructor(\n protected router: Router,\n protected keycloakAngular: KeycloakService\n ) {}\n\n /**\n * CanActivate checks if the user is logged in and get the full list of roles (REALM + CLIENT)\n * of the logged user. This values are set to authenticated and roles params.\n *\n * @param route\n * @param state\n */\n async canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<boolean | UrlTree> {\n try {\n this.authenticated = await this.keycloakAngular.isLoggedIn();\n this.roles = await this.keycloakAngular.getUserRoles(true);\n\n return await this.isAccessAllowed(route, state);\n } catch (error) {\n throw new Error('An error happened during access validation. Details:' + error);\n }\n }\n\n /**\n * Create your own customized authorization flow in this method. From here you already known\n * if the user is authenticated (this.authenticated) and the user roles (this.roles).\n *\n * Return a UrlTree if the user should be redirected to another route.\n *\n * @param route\n * @param state\n */\n abstract isAccessAllowed(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<boolean | UrlTree>;\n}\n","/**\n * @license\n * Copyright Mauricio Gemelli Vigolo and contributors.\n *\n * Use of this source code is governed by a MIT-style license that can be\n * found in the LICENSE file at https://github.com/mauriciovigolo/keycloak-angular/blob/main/LICENSE.md\n */\n\nimport { Injectable } from '@angular/core';\nimport { HttpHeaders, HttpRequest } from '@angular/common/http';\n\nimport { Subject, from } from 'rxjs';\nimport { map } from 'rxjs/operators';\nimport Keycloak from 'keycloak-js';\n\nimport { ExcludedUrl, ExcludedUrlRegex, KeycloakOptions } from '../interfaces/keycloak-options';\nimport { KeycloakEventLegacy, KeycloakEventTypeLegacy } from '../interfaces/keycloak-event';\n\n/**\n * Service to expose existent methods from the Keycloak JS adapter, adding new\n * functionalities to improve the use of keycloak in Angular v > 4.3 applications.\n *\n * This class should be injected in the application bootstrap, so the same instance will be used\n * along the web application.\n *\n * @deprecated This service is deprecated and will be removed in future versions.\n * Use the new `provideKeycloak` function to load Keycloak in an Angular application.\n * More info: https://github.com/mauriciovigolo/keycloak-angular/blob/main/docs/migration-guides/v19.md\n */\n@Injectable()\nexport class KeycloakService {\n /**\n * Keycloak-js instance.\n */\n private _instance: Keycloak;\n /**\n * User profile as KeycloakProfile interface.\n */\n private _userProfile: Keycloak.KeycloakProfile;\n /**\n * Flag to indicate if the bearer will not be added to the authorization header.\n */\n private _enableBearerInterceptor: boolean;\n /**\n * When the implicit flow is choosen there must exist a silentRefresh, as there is\n * no refresh token.\n */\n private _silentRefresh: boolean;\n /**\n * Indicates that the user profile should be loaded at the keycloak initialization,\n * just after the login.\n */\n private _loadUserProfileAtStartUp: boolean;\n /**\n * The bearer prefix that will be appended to the Authorization Header.\n */\n private _bearerPrefix: string;\n /**\n * Value that will be used as the Authorization Http Header name.\n */\n private _authorizationHeaderName: string;\n /**\n * @deprecated\n * The excluded urls patterns that must skip the KeycloakBearerInterceptor.\n */\n private _excludedUrls: ExcludedUrlRegex[];\n /**\n * Observer for the keycloak events\n */\n private _keycloakEvents$: Subject<KeycloakEventLegacy> = new Subject<KeycloakEventLegacy>();\n /**\n * The amount of required time remaining before expiry of the token before the token will be refreshed.\n */\n private _updateMinValidity: number;\n /**\n * Returns true if the request should have the token added to the headers by the KeycloakBearerInterceptor.\n */\n shouldAddToken: (request: HttpRequest<unknown>) => boolean;\n /**\n * Returns true if the request being made should potentially update the token.\n */\n shouldUpdateToken: (request: HttpRequest<unknown>) => boolean;\n\n /**\n * Binds the keycloak-js events to the keycloakEvents Subject\n * which is a good way to monitor for changes, if needed.\n *\n * The keycloakEvents returns the keycloak-js event type and any\n * argument if the source function provides any.\n */\n private bindsKeycloakEvents(): void {\n this._instance.onAuthError = (errorData) => {\n this._keycloakEvents$.next({\n args: errorData,\n type: KeycloakEventTypeLegacy.OnAuthError\n });\n };\n\n this._instance.onAuthLogout = () => {\n this._keycloakEvents$.next({ type: KeycloakEventTypeLegacy.OnAuthLogout });\n };\n\n this._instance.onAuthRefreshSuccess = () => {\n this._keycloakEvents$.next({\n type: KeycloakEventTypeLegacy.OnAuthRefreshSuccess\n });\n };\n\n this._instance.onAuthRefreshError = () => {\n this._keycloakEvents$.next({\n type: KeycloakEventTypeLegacy.OnAuthRefreshError\n });\n };\n\n this._instance.onAuthSuccess = () => {\n this._keycloakEvents$.next({ type: KeycloakEventTypeLegacy.OnAuthSuccess });\n };\n\n this._instance.onTokenExpired = () => {\n this._keycloakEvents$.next({\n type: KeycloakEventTypeLegacy.OnTokenExpired\n });\n };\n\n this._instance.onActionUpdate = (state) => {\n this._keycloakEvents$.next({\n args: state,\n type: KeycloakEventTypeLegacy.OnActionUpdate\n });\n };\n\n this._instance.onReady = (authenticated) => {\n this._keycloakEvents$.next({\n args: authenticated,\n type: KeycloakEventTypeLegacy.OnReady\n });\n };\n }\n\n /**\n * Loads all bearerExcludedUrl content in a uniform type: ExcludedUrl,\n * so it becomes easier to handle.\n *\n * @param bearerExcludedUrls array of strings or ExcludedUrl that includes\n * the url and HttpMethod.\n */\n private loadExcludedUrls(bearerExcludedUrls: (string | ExcludedUrl)[]): ExcludedUrlRegex[] {\n const excludedUrls: ExcludedUrlRegex[] = [];\n for (const item of bearerExcludedUrls) {\n let excludedUrl: ExcludedUrlRegex;\n if (typeof item === 'string') {\n excludedUrl = { urlPattern: new RegExp(item, 'i'), httpMethods: [] };\n } else {\n excludedUrl = {\n urlPattern: new RegExp(item.url, 'i'),\n httpMethods: item.httpMethods\n };\n }\n excludedUrls.push(excludedUrl);\n }\n return excludedUrls;\n }\n\n /**\n * Handles the class values initialization.\n *\n * @param options\n */\n private initServiceValues({\n enableBearerInterceptor = true,\n loadUserProfileAtStartUp = false,\n bearerExcludedUrls = [],\n authorizationHeaderName = 'Authorization',\n bearerPrefix = 'Bearer',\n initOptions,\n updateMinValidity = 20,\n shouldAddToken = () => true,\n shouldUpdateToken = () => true\n }: KeycloakOptions): void {\n this._enableBearerInterceptor = enableBearerInterceptor;\n this._loadUserProfileAtStartUp = loadUserProfileAtStartUp;\n this._authorizationHeaderName = authorizationHeaderName;\n this._bearerPrefix = bearerPrefix.trim().concat(' ');\n this._excludedUrls = this.loadExcludedUrls(bearerExcludedUrls);\n this._silentRefresh = initOptions ? initOptions.flow === 'implicit' : false;\n this._updateMinValidity = updateMinValidity;\n this.shouldAddToken = shouldAddToken;\n this.shouldUpdateToken = shouldUpdateToken;\n }\n\n /**\n * Keycloak initialization. It should be called to initialize the adapter.\n * Options is an object with 2 main parameters: config and initOptions. The first one\n * will be used to create the Keycloak instance. The second one are options to initialize the\n * keycloak instance.\n *\n * @param options\n * Config: may be a string representing the keycloak URI or an object with the\n * following content:\n * - url: Keycloak json URL\n * - realm: realm name\n * - clientId: client id\n *\n * initOptions:\n * Options to initialize the Keycloak adapter, matches the options as provided by Keycloak itself.\n *\n * enableBearerInterceptor:\n * Flag to indicate if the bearer will added to the authorization header.\n *\n * loadUserProfileInStartUp:\n * Indicates that the user profile should be loaded at the keycloak initialization,\n * just after the login.\n *\n * bearerExcludedUrls:\n * String Array to exclude the urls that should not have the Authorization Header automatically\n * added.\n *\n * authorizationHeaderName:\n * This value will be used as the Authorization Http Header name.\n *\n * bearerPrefix:\n * This value will be included in the Authorization Http Header param.\n *\n * tokenUpdateExcludedHeaders:\n * Array of Http Header key/value maps that should not trigger the token to be updated.\n *\n * updateMinValidity:\n * This value determines if the token will be refreshed based on its expiration time.\n *\n * @returns\n * A Promise with a boolean indicating if the initialization was successful.\n */\n public async init(options: KeycloakOptions = {}) {\n this.initServiceValues(options);\n const { config, initOptions } = options;\n\n this._instance = new Keycloak(config);\n this.bindsKeycloakEvents();\n\n const authenticated = await this._instance.init(initOptions);\n\n if (authenticated && this._loadUserProfileAtStartUp) {\n await this.loadUserProfile();\n }\n\n return authenticated;\n }\n\n /**\n * Redirects to login form on (options is an optional object with redirectUri and/or\n * prompt fields).\n *\n * @param options\n * Object, where:\n * - redirectUri: Specifies the uri to redirect to after login.\n * - prompt:By default the login screen is displayed if the user is not logged-in to Keycloak.\n * To only authenticate to the application if the user is already logged-in and not display the\n * login page if the user is not logged-in, set this option to none. To always require\n * re-authentication and ignore SSO, set this option to login .\n * - maxAge: Used just if user is already authenticated. Specifies maximum time since the\n * authentication of user happened. If user is already authenticated for longer time than\n * maxAge, the SSO is ignored and he will need to re-authenticate again.\n * - loginHint: Used to pre-fill the username/email field on the login form.\n * - action: If value is 'register' then user is redirected to registration page, otherwise to\n * login page.\n * - locale: Specifies the desired locale for the UI.\n * @returns\n * A void Promise if the login is successful and after the user profile loading.\n */\n public async login(options: Keycloak.KeycloakLoginOptions = {}) {\n await this._instance.login(options);\n\n if (this._loadUserProfileAtStartUp) {\n await this.loadUserProfile();\n }\n }\n\n /**\n * Redirects to logout.\n *\n * @param redirectUri\n * Specifies the uri to redirect to after logout.\n * @returns\n * A void Promise if the logout was successful, cleaning also the userProfile.\n */\n public async logout(redirectUri?: string) {\n const options = {\n redirectUri\n };\n\n await this._instance.logout(options);\n this._userProfile = undefined;\n }\n\n /**\n * Redirects to registration form. Shortcut for login with option\n * action = 'register'. Options are same as for the login method but 'action' is set to\n * 'register'.\n *\n * @param options\n * login options\n * @returns\n * A void Promise if the register flow was successful.\n */\n public async register(options: Keycloak.KeycloakLoginOptions = { action: 'register' }) {\n await this._instance.register(options);\n }\n\n /**\n * Check if the user has access to the specified role. It will look for roles in\n * realm and the given resource, but will not check if the user is logged in for better performance.\n *\n * @param role\n * role name\n * @param resource\n * resource name. If not specified, `clientId` is used\n * @returns\n * A boolean meaning if the user has the specified Role.\n */\n isUserInRole(role: string, resource?: string): boolean {\n let hasRole: boolean;\n hasRole = this._instance.hasResourceRole(role, resource);\n if (!hasRole) {\n hasRole = this._instance.hasRealmRole(role);\n }\n return hasRole;\n }\n\n /**\n * Return the roles of the logged user. The realmRoles parameter, with default value\n * true, will return the resource roles and realm roles associated with the logged user. If set to false\n * it will only return the resource roles. The resource parameter, if specified, will return only resource roles\n * associated with the given resource.\n *\n * @param realmRoles\n * Set to false to exclude realm roles (only client roles)\n * @param resource\n * resource name If not specified, returns roles from all resources\n * @returns\n * Array of Roles associated with the logged user.\n */\n getUserRoles(realmRoles: boolean = true, resource?: string): string[] {\n let roles: string[] = [];\n\n if (this._instance.resourceAccess) {\n Object.keys(this._instance.resourceAccess).forEach((key) => {\n if (resource && resource !== key) {\n return;\n }\n\n const resourceAccess = this._instance.resourceAccess[key];\n const clientRoles = resourceAccess['roles'] || [];\n roles = roles.concat(clientRoles);\n });\n }\n\n if (realmRoles && this._instance.realmAccess) {\n const realmRoles = this._instance.realmAccess['roles'] || [];\n roles.push(...realmRoles);\n }\n\n return roles;\n }\n\n /**\n * Check if user is logged in.\n *\n * @returns\n * A boolean that indicates if the user is logged in.\n */\n isLoggedIn(): boolean {\n if (!this._instance) {\n return false;\n }\n\n return this._instance.authenticated;\n }\n\n /**\n * Returns true if the token has less than minValidity seconds left before\n * it expires.\n *\n * @param minValidity\n * Seconds left. (minValidity) is optional. Default value is 0.\n * @returns\n * Boolean indicating if the token is expired.\n */\n isTokenExpired(minValidity: number = 0): boolean {\n return this._instance.isTokenExpired(minValidity);\n }\n\n /**\n * If the token expires within _updateMinValidity seconds the token is refreshed. If the\n * session status iframe is enabled, the session status is also checked.\n * Returns a promise telling if the token was refreshed or not. If the session is not active\n * anymore, the promise is rejected.\n *\n * @param minValidity\n * Seconds left. (minValidity is optional, if not specified updateMinValidity - default 20 is used)\n * @returns\n * Promise with a boolean indicating if the token was succesfully updated.\n */\n public async updateToken(minValidity = this._updateMinValidity) {\n // TODO: this is a workaround until the silent refresh (issue #43)\n // is not implemented, avoiding the redirect loop.\n if (this._silentRefresh) {\n if (this.isTokenExpired()) {\n throw new Error('Failed to refresh the token, or the session is expired');\n }\n\n return true;\n }\n\n if (!this._instance) {\n throw new Error('Keycloak Angular library is not initialized.');\n }\n\n try {\n return await this._instance.updateToken(minValidity);\n } catch (error) {\n return false;\n }\n }\n\n /**\n * Loads the user profile.\n * Returns promise to set functions to be invoked if the profile was loaded\n * successfully, or if the profile could not be loaded.\n *\n * @param forceReload\n * If true will force the loadUserProfile even if its already loaded.\n * @returns\n * A promise with the KeycloakProfile data loaded.\n */\n public async loadUserProfile(forceReload = false) {\n if (this._userProfile && !forceReload) {\n return this._userProfile;\n }\n\n if (!this._instance.authenticated) {\n throw new Error('The user profile was not loaded as the user is not logged in.');\n }\n\n return (this._userProfile = await this._instance.loadUserProfile());\n }\n\n /**\n * Returns the authenticated token.\n */\n public async getToken() {\n return this._instance.token;\n }\n\n /**\n * Returns the logged username.\n *\n * @returns\n * The logged username.\n */\n public getUsername() {\n if (!this._userProfile) {\n throw new Error('User not logged in or user profile was not loaded.');\n }\n\n return this._userProfile.username;\n }\n\n /**\n * Clear authentication state, including tokens. This can be useful if application\n * has detected the session was expired, for example if updating token fails.\n * Invoking this results in onAuthLogout callback listener being invoked.\n */\n clearToken(): void {\n this._instance.clearToken();\n }\n\n /**\n * Adds a valid token in header. The key & value format is:\n * Authorization Bearer <token>.\n * If the headers param is undefined it will create the Angular headers object.\n *\n * @param headers\n * Updated header with Authorization and Keycloak token.\n * @returns\n * An observable with with the HTTP Authorization header and the current token.\n */\n public addTokenToHeader(headers: HttpHeaders = new HttpHeaders()) {\n return from(this.getToken()).pipe(\n map((token) => (token ? headers.set(this._authorizationHeaderName, this._bearerPrefix + token) : headers))\n );\n }\n\n /**\n * Returns the original Keycloak instance, if you need any customization that\n * this Angular service does not support yet. Use with caution.\n *\n * @returns\n * The KeycloakInstance from keycloak-js.\n */\n getKeycloakInstance(): Keycloak.KeycloakInstance {\n return this._instance;\n }\n\n /**\n * @deprecated\n * Returns the excluded URLs that should not be considered by\n * the http interceptor which automatically adds the authorization header in the Http Request.\n *\n * @returns\n * The excluded urls that must not be intercepted by the KeycloakBearerInterceptor.\n */\n get excludedUrls(): ExcludedUrlRegex[] {\n return this._excludedUrls;\n }\n\n /**\n * Flag to indicate if the bearer will be added to the authorization header.\n *\n * @returns\n * Returns if the bearer interceptor was set to be disabled.\n */\n get enableBearerInterceptor(): boolean {\n return this._enableBearerInterceptor;\n }\n\n /**\n * Keycloak subject to monitor the events triggered by keycloak-js.\n * The following events as available (as described at keycloak docs -\n * https://www.keycloak.org/docs/latest/securing_apps/index.html#callback-events):\n * - OnAuthError\n * - OnAuthLogout\n * - OnAuthRefreshError\n * - OnAuthRefreshSuccess\n * - OnAuthSuccess\n * - OnReady\n * - OnTokenExpire\n * In each occurrence of any of these, this subject will return the event type,\n * described at {@link KeycloakEventTypeLegacy} enum and the function args from the keycloak-js\n * if provided any.\n *\n * @returns\n * A subject with the {@link KeycloakEventLegacy} which describes the event type and attaches the\n * function args.\n */\n get keycloakEvents$(): Subject<KeycloakEventLegacy> {\n return this._keycloakEvents$;\n }\n}\n","/**\n * @license\n * Copyright Mauricio Gemelli Vigolo and contributors.\n *\n * Use of this source code is governed by a MIT-style license that can be\n * found in the LICENSE file at https://github.com/mauriciovigolo/keycloak-angular/blob/main/LICENSE.md\n */\n\nimport { Injectable, inject } from '@angular/core';\nimport { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http';\n\nimport { Observable, combineLatest, from, of } from 'rxjs';\nimport { mergeMap } from 'rxjs/operators';\n\nimport { KeycloakService } from '../services/keycloak.service';\nimport { ExcludedUrlRegex } from '../interfaces/keycloak-options';\n\n/**\n * This interceptor includes the bearer by default in all HttpClient requests.\n *\n * If you need to exclude some URLs from adding the bearer, please, take a look\n * at the {@link KeycloakOptions} bearerExcludedUrls property.\n *\n * @deprecated KeycloakBearerInterceptor is deprecated and will be removed in future versions.\n * Use the new functional interceptor such as `includeBearerTokenInterceptor`.\n * More info: https://github.com/mauriciovigolo/keycloak-angular/blob/main/docs/migration-guides/v19.md\n */\n@Injectable()\nexport class KeycloakBearerInterceptor implements HttpInterceptor {\n private keycloak = inject(KeycloakService);\n\n /**\n * Calls to update the keycloak token if the request should update the token.\n *\n * @param req http request from @angular http module.\n * @returns\n * A promise boolean for the token update or noop result.\n */\n private async conditionallyUpdateToken(req: HttpRequest<unknown>): Promise<boolean> {\n if (this.keycloak.shouldUpdateToken(req)) {\n return await this.keycloak.updateToken();\n }\n\n return true;\n }\n\n /**\n * @deprecated\n * Checks if the url is excluded from having the Bearer Authorization\n * header added.\n *\n * @param req http request from @angular http module.\n * @param excludedUrlRegex contains the url pattern and the http methods,\n * excluded from adding the bearer at the Http Request.\n */\n private isUrlExcluded({ method, url }: HttpRequest<unknown>, { urlPattern, httpMethods }: ExcludedUrlRegex): boolean {\n const httpTest = httpMethods.length === 0 || httpMethods.join().indexOf(method.toUpperCase()) > -1;\n\n const urlTest = urlPattern.test(url);\n\n return httpTest && urlTest;\n }\n\n /**\n * Intercept implementation that checks if the request url matches the excludedUrls.\n * If not, adds the Authorization header to the request if the user is logged in.\n *\n * @param req\n * @param next\n */\n public intercept(req: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {\n const { enableBearerInterceptor, excludedUrls } = this.keycloak;\n if (!enableBearerInterceptor) {\n return next.handle(req);\n }\n\n const shallPass: boolean =\n !this.keycloak.shouldAddToken(req) || excludedUrls.findIndex((item) => this.isUrlExcluded(req, item)) > -1;\n if (shallPass) {\n return next.handle(req);\n }\n\n return combineLatest([from(this.conditionallyUpdateToken(req)), of(this.keycloak.isLoggedIn())]).pipe(\n mergeMap(([_, isLoggedIn]) => (isLoggedIn ? this.handleRequestWithTokenHeader(req, next) : next.handle(req)))\n );\n }\n\n /**\n * Adds the token of the current user to the Authorization header\n *\n * @param req\n * @param next\n */\n private handleRequestWithTokenHeader(req: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {\n return this.keycloak.addTokenToHeader(req.headers).pipe(\n mergeMap((headersWithBearer) => {\n const kcReq = req.clone({ headers: headersWithBearer });\n return next.handle(kcReq);\n })\n );\n }\n}\n","/**\n * @license\n * Copyright Mauricio Gemelli Vigolo and contributors.\n *\n * Use of this source code is governed by a MIT-style license that can be\n * found in the LICENSE file at https://github.com/mauriciovigolo/keycloak-angular/blob/main/LICENSE.md\n */\n\nimport { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { HTTP_INTERCEPTORS } from '@angular/common/http';\n\nimport { KeycloakService } from './services/keycloak.service';\nimport { KeycloakBearerInterceptor } from './interceptors/keycloak-bearer.interceptor';\n\n/**\n * @deprecated NgModules are deprecated in Keycloak Angular and will be removed in future versions.\n * Use the new `provideKeycloak` function to load Keycloak in an Angular application.\n * More info: https://github.com/mauriciovigolo/keycloak-angular/blob/main/docs/migration-guides/v19.md\n */\n@NgModule({\n imports: [CommonModule],\n providers: [\n KeycloakService,\n {\n provide: HTTP_INTERCEPTORS,\n useClass: KeycloakBearerInterceptor,\n multi: true\n }\n ]\n})\nexport class CoreModule {}\n","/**\n * @license\n * Copyright Mauricio Gemelli Vigolo and contributors.\n *\n * Use of this source code is governed by a MIT-style license that can be\n * found in the LICENSE file at https://github.com/mauriciovigolo/keycloak-angular/blob/main/LICENSE.md\n */\n\nimport { NgModule } from '@angular/core';\n\nimport { CoreModule } from './core/core.module';\n\n/**\n * @deprecated NgModules are deprecated in Keycloak Angular and will be removed in future versions.\n * Use the new `provideKeycloak` function to load Keycloak in an Angular application.\n * More info: https://github.com/mauriciovigolo/keycloak-angular/blob/main/docs/migration-guides/v19.md\n */\n@NgModule({\n imports: [CoreModule]\n})\nexport class KeycloakAngularModule {}\n","/**\n * @license\n * Copyright Mauricio Gemelli Vigolo All Rights Reserved.\n *\n * Use of this source code is governed by a MIT-style license that can be\n * found in the LICENSE file at https://github.com/mauriciovigolo/keycloak-angular/blob/main/LICENSE.md\n */\n\n// This legacy implementation will be removed in Keycloak Angular v20\nexport { KeycloakEventLegacy, KeycloakEventTypeLegacy } from './core/interfaces/keycloak-event';\nexport { KeycloakOptions } from './core/interfaces/keycloak-options';\nexport { KeycloakAuthGuard } from './core/services/keycloak-auth-guard';\nexport { KeycloakService } from './core/services/keycloak.service';\nexport { KeycloakBearerInterceptor } from './core/interceptors/keycloak-bearer.interceptor';\nexport { CoreModule } from './core/core.module';\nexport { KeycloakAngularModule } from './keycloak-angular.module';\n","/**\n * @license\n * Copyright Mauricio Gemelli Vigolo All Rights Reserved.\n *\n * Use of this source code is governed by a MIT-style license that can be\n * found in the LICENSE file at https://github.com/mauriciovigolo/keycloak-angular/blob/main/LICENSE.md\n */\n\nimport Keycloak, { KeycloakError } from 'keycloak-js';\nimport { signal, Signal, InjectionToken } from '@angular/core';\n\n/**\n * Keycloak event types, as described at the keycloak-js documentation:\n * https://www.keycloak.org/docs/latest/securing_apps/index.html#callback-events\n */\nexport enum KeycloakEventType {\n /**\n * Keycloak Angular is not initialized yet. This is the initial state applied to the Keycloak Event Signal.\n * Note: This event is only emitted in Keycloak Angular, it is not part of the keycloak-js.\n */\n KeycloakAngularNotInitialized = 'KeycloakAngularNotInitialized',\n /**\n * Keycloak Angular is in the process of initializing the providers and Keycloak Instance.\n * Note: This event is only emitted in Keycloak Angular, it is not part of the keycloak-js.\n */\n KeycloakAngularInit = 'KeycloakAngularInit',\n /**\n * Triggered if there is an error during authentication.\n */\n AuthError = 'AuthError',\n /**\n * Triggered when the user logs out. This event will only be triggered\n * if the session status iframe is enabled or in Cordova mode.\n */\n AuthLogout = 'AuthLogout',\n /**\n * Triggered if an error occurs while attempting to refresh the token.\n */\n AuthRefreshError = 'AuthRefreshError',\n /**\n * Triggered when the token is successfully refreshed.\n */\n AuthRefreshSuccess = 'AuthRefreshSuccess',\n /**\n * Triggered when a user is successfully authenticated.\n */\n AuthSuccess = 'AuthSuccess',\n /**\n * Triggered when the Keycloak adapter has completed initialization.\n */\n Ready = 'Ready',\n /**\n * Triggered when the access token expires. Depending on the flow, you may\n * need to use `updateToken` to refresh the token or redirect the user\n * to the login screen.\n */\n TokenExpired = 'TokenExpired',\n /**\n * Triggered when an authentication action is requested by the application.\n */\n ActionUpdate = 'ActionUpdate'\n}\n\n/**\n * Arguments for the `Ready` event, representing the authentication state.\n */\nexport type ReadyArgs = boolean;\n\n/**\n * Arguments for the `ActionUpdate` event, providing information about the status\n * and optional details about the action.\n */\nexport type ActionUpdateArgs = {\n /**\n * Status of the action, indicating whether it was successful, encountered an error,\n * or was cancelled.\n */\n status: 'success' | 'error' | 'cancelled';\n /**\n * Optional name or identifier of the action performed.\n */\n action?: string;\n};\n\n/**\n * Arguments for the `AuthError` event, providing detailed error information.\n */\nexport type AuthErrorArgs = KeycloakError;\n\ntype EventArgs = ReadyArgs | ActionUpdateArgs | AuthErrorArgs;\n\n/**\n * Helper function to typecast unknown arguments into a specific Keycloak event type.\n *\n * @template T - The expected argument type.\n * @param args - The arguments to be cast.\n * @returns The arguments typed as `T`.\n */\nexport const typeEventArgs = <T extends EventArgs>(args: unknown): T => args as T;\n\n/**\n * Structure of a Keycloak event, including its type and optional arguments.\n */\nexport interface KeycloakEvent {\n /**\n * Event type as described at {@link KeycloakEventType}.\n */\n type: KeycloakEventType;\n /**\n * Arguments from the keycloak-js event function.\n */\n args?: unknown;\n}\n\n/**\n * Creates a signal to manage Keycloak events, initializing the signal with\n * appropriate default values or values from a given Keycloak instance.\n *\n * @param keycloak - An instance of the Keycloak client.\n * @returns A `Signal` that tracks the current Keycloak event state.\n */\nexport const createKeycloakSignal = (keycloak?: Keycloak) => {\n const keycloakSignal = signal<KeycloakEvent>({\n type: KeycloakEventType.KeycloakAngularInit\n });\n\n if (!keycloak) {\n keycloakSignal.set({\n type: KeycloakEventType.KeycloakAngularNotInitialized\n });\n\n return keycloakSignal;\n }\n\n keycloak.onReady = (authenticated) => {\n keycloakSignal.set({\n type: KeycloakEventType.Ready,\n args: authenticated\n });\n };\n\n keycloak.onAuthError = (errorData) => {\n keycloakSignal.set({\n type: KeycloakEventType.AuthError,\n args: errorData\n });\n };\n\n keycloak.onAuthLogout = () => {\n keycloakSignal.set({\n type: KeycloakEventType.AuthLogout\n });\n };\n\n keycloak.onActionUpdate = (status, action) => {\n keycloakSignal.set({\n type: KeycloakEventType.ActionUpdate,\n args: { status, action }\n });\n };\n\n keycloak.onAuthRefreshError = () => {\n keycloakSignal.set({\n type: KeycloakEventType.AuthRefreshError\n });\n };\n\n keycloak.onAuthRefreshSuccess = () => {\n keycloakSignal.set({\n type: KeycloakEventType.AuthRefreshSuccess\n });\n };\n\n keycloak.onAuthSuccess = () => {\n keycloakSignal.set({\n type: KeycloakEventType.AuthSuccess\n });\n };\n\n keycloak.onTokenExpired = () => {\n keycloakSignal.set({\n type: KeycloakEventType.TokenExpired\n });\n };\n\n return keycloakSignal;\n};\n\n/**\n * Injection token for the Keycloak events signal, used for dependency injection.\n */\nexport const KEYCLOAK_EVENT_SIGNAL = new InjectionToken<Signal<KeycloakEvent>>('Keycloak Events Signal');\n","/**\n * @license\n * Copyright Mauricio Gemelli Vigolo All Rights Reserved.\n *\n * Use of this source code is governed by a MIT-style license that can be\n * found in the LICENSE file at https://github.com/mauriciovigolo/keycloak-angular/blob/main/LICENSE.md\n */\n\nimport { Directive, effect, inject, Input, type OnChanges, TemplateRef, ViewContainerRef } from '@angular/core';\nimport Keycloak from 'keycloak-js';\n\nimport {\n KEYCLOAK_EVENT_SIGNAL,\n KeycloakEventType,\n type ReadyArgs,\n typeEventArgs\n} from '../signals/keycloak-events-signal';\n\n/**\n * Structural directive to conditionally display elements based on Keycloak user roles.\n *\n * This directive checks if the authenticated user has at least one of the specified roles.\n * Roles can be validated against a specific **resource (client ID)** or the **realm**.\n *\n * ### Features:\n * - Supports role checking in both **resources (client-level roles)** and the **realm**.\n * - Accepts an array of roles to match.\n * - Optional configuration to check realm-level roles.\n *\n * ### Inputs:\n * - `kaHasRoles` (Required): Array of roles to validate.\n * - `resource` (Optional): The client ID or resource name to validate resource-level roles.\n * - `checkRealm` (Optional): A boolean flag to enable realm role validation (default is `false`).\n *\n * ### Requirements:\n * - A Keycloak instance must be injected via Angular's dependency injection.\n * - The user must be authenticated in Keycloak.\n *\n * @example\n * #### Example 1: Check for Global Realm Roles\n * Show the content only if the user has the `admin` or `editor` role in the realm.\n * ```html\n * <div *kaHasRoles=\"['admin', 'editor']; checkRealm:true\">\n * <p>This content is visible only to users with 'admin' or 'editor' realm roles.</p>\n * </div>\n * ```\n *\n * @example\n * #### Example 2: Check for Resource Roles\n * Show the content only if the user has the `read` or `write` role for a specific resource (`my-client`).\n * ```html\n * <div *kaHasRoles=\"['read', 'write']; resource:'my-client'\">\n * <p>This content is visible only to users with 'read' or 'write' roles for 'my-client'.</p>\n * </div>\n * ```\n *\n * @example\n * #### Example 3: Check for Both Resource and Realm Roles\n * Show the content if the user has the roles in either the realm or a resource.\n * ```html\n * <div *kaHasRoles=\"['admin', 'write']; resource:'my-client' checkRealm:true\">\n * <p>This content is visible to users with 'admin' in the realm or 'write' in 'my-client'.</p>\n * </div>\n * ```\n *\n * @example\n * #### Example 4: Fallback Content When Roles Do Not Match\n * Use an `<ng-template>` to display fallback content if the user lacks the required roles.\n * ```html\n * <div *kaHasRoles=\"['admin']; resource:'my-client'\">\n * <p>Welcome, Admin!</p>\n * </div>\n * <ng-template #noAccess>\n * <p>Access Denied</p>\n * </ng-template>\n * ```\n */\n@Directive({\n selector: '[kaHasRoles]'\n})\nexport class HasRolesDirective implements OnChanges {\n private templateRef = inject<TemplateRef<unknown>>(TemplateRef);\n private viewContainer = inject(ViewContainerRef);\n private keycloak = inject(Keycloak);\n\n /**\n * List of roles to validate against the resource or realm.\n */\n @Input('kaHasRoles') roles: string[] = [];\n\n /**\n * The resource (client ID) to validate roles against.\n */\n @Input('kaHasRolesResource') resource?: string;\n\n /**\n * Flag to enable realm-level role validation.\n */\n @Input('kaHasRolesCheckRealm') checkRealm: boolean = false;\n\n constructor() {\n this.viewContainer.clear();\n\n const keycloakSignal = inject(KEYCLOAK_EVENT_SIGNAL);\n\n /**\n * This effect will reevaluate roles after authentication or token refresh.\n * Or clear the view on logout.\n */\n effect(() => {\n const keycloakEvent = keycloakSignal();\n\n switch (keycloakEvent.type) {\n case KeycloakEventType.Ready: {\n const authenticated = typeEventArgs<ReadyArgs>(keycloakEvent.args);\n if (authenticated) {\n this.render();\n } else {\n this.viewContainer.clear();\n }\n break;\n }\n case KeycloakEventType.AuthSuccess:\n case KeycloakEventType.AuthRefreshSuccess:\n case KeycloakEventType.TokenExpired:\n this.render();\n break;\n case KeycloakEventType.AuthLogout:\n this.viewContainer.clear();\n break;\n default:\n break;\n }\n });\n }\n\n /**\n * Here to reevaluate access when inputs change.\n */\n public ngOnChanges(): void {\n this.render();\n }\n\n /**\n * Clear the view and render it if user has access.\n */\n private render(): void {\n const hasAccess = this.checkUserRoles();\n this.viewContainer.clear();\n\n if (hasAccess) {\n this.viewContainer.createEmbeddedView(this.templateRef);\n }\n }\n\n /**\n * Checks if the user has at least one of the specified roles in the resource or realm.\n * @returns True if the user has access, false otherwise.\n */\n private checkUserRoles(): boolean {\n const hasResourceRole = this.roles.some((role) => this.keycloak.hasResourceRole(role, this.resource));\n\n const hasRealmRole = this.checkRealm ? this.roles.some((role) => this.keycloak.hasRealmRole(role)) : false;\n\n return hasResourceRole || hasRealmRole;\n }\n}\n","/**\n * @license\n * Copyright Mauricio Gemelli Vigolo All Rights Reserved.\n *\n * Use of this source code is governed by a MIT-style license that can be\n * found in the LICENSE file at https://github.com/mauriciovigolo/keycloak-angular/blob/main/LICENSE.md\n */\n\n/**\n * Represents a feature from keycloak-angular that can be configured during the library initialization.\n *\n * This type defines the structure of a feature that includes a `configure` method,\n * which is responsible for setting up or initializing the feature's behavior or properties\n * related to Keycloak.\n *\n * ### Usage:\n * The `KeycloakFeature` type is typically used for defining modular, reusable Keycloak\n * features that can be dynamically configured and integrated into an application.\n *\n * @property {() => void} configure - A method that initializes or configures the feature.\n * This method is invoked to perform any setup or customization required for the feature.\n *\n * ### Example:\n * ```typescript\n * const withLoggingFeature: KeycloakFeature = {\n * configure: () => {\n * console.log('Configuring Keycloak logging feature');\n * },\n * };\n *\n * const withAnalyticsFeature: KeycloakFeature = {\n * configure: () => {\n * console.log('Configuring Keycloak analytics feature');\n * },\n * };\n *\n * // Configure and initialize features\n * withLoggingFeature.configure();\n * withAnalyticsFeature.configure();\n * ```\n */\nexport type KeycloakFeature = {\n configure: () => void;\n};\n","/**\n * @license\n * Copyright Mauricio Gemelli Vigolo All Rights Reserved.\n *\n * Use of this source code is governed by a MIT-style license that can be\n * found in the LICENSE file at https://github.com/mauriciovigolo/keycloak-angular/blob/main/LICENSE.md\n */\n\nimport { Injectable, OnDestroy, NgZone, signal, computed, inject, PLATFORM_ID } from '@angular/core';\nimport { isPlatformBrowser } from '@angular/common';\nimport { fromEvent, Subject } from 'rxjs';\nimport { debounceTime, takeUntil } from 'rxjs/operators';\n\n/**\n * Service to monitor user activity in an Angular application.\n * Tracks user interactions (e.g., mouse movement, touch, key presses, clicks, and scrolls)\n * and updates the last activity timestamp. Consumers can check for user inactivity\n * based on a configurable timeout.\n *\n * The service is supposed to be used in the client context and for safety, it checks during the startup\n * if it is a browser context.\n */\n@Injectable()\nexport class UserActivityService implements OnDestroy {\n private ngZone = inject(NgZone);\n\n /**\n * Signal to store the timestamp of the last user activity.\n * The timestamp is represented as the number of milliseconds since epoch.\n */\n private lastActivity = signal<number>(Date.now());\n\n /**\n * Subject to signal the destruction of the service.\n * Used to clean up RxJS subscriptions.\n */\n private destroy$ = new Subject<void>();\n\n /**\n * Computed signal to expose the last user activity as a read-only signal.\n */\n public readonly lastActivitySignal = computed(() => this.lastActivity());\n\n /**\n * Starts monitoring user activity events (`mousemove`, `touchstart`, `keydown`, `click`, `scroll`)\n * and updates the last activity timestamp using RxJS with debounce.\n * The events are processed outside Angular zone for performance optimization.\n */\n startMonitoring(): void {\n const isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n if (!isBrowser) {\n return;\n }\n\n this.ngZone.runOutsideAngular(() => {\n const events = ['mousemove', 'touchstart', 'keydown', 'click', 'scroll'];\n\n events.forEach((event) => {\n fromEvent(window, event)\n .pipe(debounceTime(300), takeUntil(this.destroy$))\n .subscribe(() => this.updateLastActivity());\n });\n });\n }\n\n /**\n * Updates the last activity timestamp to the current time.\n * This method runs inside Angular's zone to ensure reactivity with Angular signals.\n */\n private updateLastActivity(): void {\n this.ngZone.run(() => {\n this.lastActivity.set(Date.now());\n });\n }\n\n /**\n * Retrieves the timestamp of the last recorded user activity.\n * @returns {number} The last activity timestamp in milliseconds since epoch.\n */\n get lastActivityTime(): number {\n return this.lastActivity();\n }\n\n /**\n * Determines whether the user interacted with the application, meaning it is activily using the application, based on\n * the specified duration.\n * @param timeout - The inactivity timeout in milliseconds.\n * @returns {boolean} `true` if the user is inactive, otherwise `false`.\n */\n isActive(timeout: number): boolean {\n return Date.now() - this.lastActivityTime < timeout;\n }\n\n /**\n * Cleans up RxJS subscriptions and resources when the service is destroyed.\n * This method is automatically called by Angular when the service is removed.\n */\n ngOnDestroy(): void {\n this.destroy$.next();\n this.destroy$.complete();\n }\n}\n","/**\n * @license\n * Copyright Mauricio Gemelli Vigolo All Rights Reserved.\n *\n * Use of this source code is governed by a MIT-style license that can be\n * found in the LICENSE file at https://github.com/mauriciovigolo/keycloak-angular/blob/main/LICENSE.md\n */\n\nimport { effect, inject, Injectable } from '@angular/core';\nimport Keycloak, { KeycloakLoginOptions, KeycloakLogoutOptions } from 'keycloak-js';\n\nimport { KEYCLOAK_EVENT_SIGNAL, KeycloakEventType } from '../signals/keycloak-events-signal';\nimport { UserActivityService } from './user-activity.service';\n\n/**\n * Configuration options for the `AutoRefreshTokenService`.\n */\ntype AutoRefreshTokenOptions = {\n /**\n * Maximum allowed inactivity duration in milliseconds before\n * the session times out. Default is `300000`.\n */\n sessionTimeout?: number;\n\n /**\n * Action to take when the session times out due to inactivity.\n * Options are:\n * - `'login'`: Redirect to the Keycloak login page.\n * - `'logout'`: Log the user out of the session.\n * - `'none'`: Do nothing.\n * Default is `'logout'`.\n */\n onInactivityTimeout?: 'login' | 'logout' | 'none';\n\n /**\n * Logout options to pass to keycloak.logout when the user is getting logged out automatically after timout.\n *\n * Default value: undefined\n */\n logoutOptions?: KeycloakLogoutOptions;\n\n /**\n * Login options to pass to keycloak.login when the user is getting logged in automatically after timeout.\n *\n * Default value: undefined\n */\n loginOptions?: KeycloakLoginOptions;\n};\n\n/**\n * Service to automatically manage the Keycloak token refresh process\n * based on user activity and token expiration events. This service\n * integrates with Keycloak for session management and interacts with\n * user activity monitoring to determine the appropriate action when\n * the token expires.\n *\n * The service listens to `KeycloakSignal` for token-related events\n * (e.g., `TokenExpired`) and provides configurable options for\n * session timeout and inactivity handling.\n */\n@Injectable()\nexport class AutoRefreshTokenService {\n private readonly keycloak = inject(Keycloak);\n private readonly userActivity = inject(UserActivityService);\n\n private options: Required<AutoRefreshTokenOptions> = this.defaultOptions;\n private initialized = false;\n\n constructor() {\n const keycloakSignal = inject(KEYCLOAK_EVENT_SIGNAL);\n\n effect(() => {\n const keycloakEvent = keycloakSignal();\n\n if (keycloakEvent.type === KeycloakEventType.TokenExpired) {\n this.processTokenExpiredEvent();\n }\n });\n }\n\n private get defaultOptions(): Required<AutoRefreshTokenOptions> {\n return {\n sessionTimeout: 300000,\n onInactivityTimeout: 'logout',\n logoutOptions: undefined,\n loginOptions: undefined\n };\n }\n\n private executeOnInactivityTimeout() {\n switch (this.options.onInactivityTimeout) {\n case 'login':\n this.keycloak\n .login(this.options.loginOptions)\n .catch((error) => console.error('Failed to execute the login call', error));\n break;\n case 'logout':\n this.keycloak\n .logout(this.options.logoutOptions)\n .catch((error) => console.error('Failed to execute the logout call', error));\n break;\n default:\n break;\n }\n }\n\n private processTokenExpiredEvent() {\n if (!this.initialized || !this.keycloak.authenticated) {\n return;\n }\n\n if (this.userActivity.isActive(this.options.sessionTimeout)) {\n this.keycloak.updateToken().catch(() => this.executeOnInactivityTimeout());\n } else {\n this.executeOnInactivityTimeout();\n }\n }\n\n start(options?: AutoRefreshTokenOptions) {\n this.options = { ...this.defaultOptions, ...options };\n this.initialized = true;\n this.userActivity.startMonitoring();\n }\n}\n","/**\n * @license\n * Copyright Mauricio Gemelli Vigolo All Rights Reserved.\n *\n * Use of this source code is governed by a MIT-style license that can be\n * found in the LICENSE file at https://github.com/mauriciovigolo/keycloak-angular/blob/main/LICENSE.md\n */\n\nimport { inject } from '@angular/core';\n\nimport { AutoRefreshTokenService } from '../services/auto-refresh-token.service';\nimport { KeycloakFeature } from './keycloak.feature';\nimport { KeycloakLoginOptions, KeycloakLogoutOptions } from 'keycloak-js';\n\n/**\n * Options for configuring the auto-refresh token feature.\n *\n * This type defines the configuration parameters for enabling auto-refresh\n * of Keycloak tokens and handling session inactivity scenarios.\n */\ntype WithRefreshTokenOptions = {\n /**\n * The session timeout duration in milliseconds. This specifies the time\n * of inactivity after which the session is considered expired.\n *\n * Default value: `300000` milliseconds (5 minutes).\n */\n sessionTimeout?: number;\n\n /**\n * Action to take when the session timeout due to inactivity occurs.\n *\n * - `'login'`: Execute the `keycloak.login` method.\n * - `'logout'`: Logs the user out by calling the `keycloak.logout` method.\n * - `'none'`: Takes no action on session timeout.\n *\n * Default value: `'logout'`.\n */\n onInactivityTimeout?: 'login' | 'logout' | 'none';\n\n /**\n * Logout options to pass to keycloak.logout when the user is getting logged out automatically after timout.\n *\n * Default value: undefined\n */\n logoutOptions?: KeycloakLogoutOptions;\n\n /**\n * Login options to pass to keycloak.login when the user is getting logged in automatically after timeout.\n *\n * Default value: undefined\n */\n loginOptions?: KeycloakLoginOptions;\n};\n\n/**\n * Enables automatic token refresh and session inactivity handling for a\n * Keycloak-enabled Angular application.\n *\n * This function initializes a service that tracks user interactions, such as\n * mouse movements, touches, key presses, clicks, and scrolls. If user activity\n * is detected, it periodically calls `Keycloak.updateToken` to ensure the bearer\n * token remains valid and does not expire.\n *\n * If the session remains inactive beyond the defined `sessionTimeout`, the\n * specified action (`logout`, `login`, or `none`) will be executed. By default,\n * the service will call `keycloak.logout` upon inactivity timeout.\n *\n * Event tracking uses RxJS observables with a debounce of 300 milliseconds to\n * monitor user interactions. When the Keycloak `OnTokenExpired` event occurs,\n * the service checks the user's last activity timestamp. If the user has been\n * active within the session timeout period, it refreshes the token using `updateToken`.\n *\n *\n * @param options - Configuration options for the auto-refresh token feature.\n * - `sessionTimeout` (optional): The duration in milliseconds after which\n * the session is considered inactive. Defaults to `300000` (5 minutes).\n * - `onInactivityTimeout` (optional): The action to take when session inactivity\n * exceeds the specified timeout. Defaults to `'logout'`.\n * - `'login'`: Execute `keycloak.login` function.\n * - `'logout'`: Logs the user out by calling `keycloak.logout`.\n * - `'none'`: No action is taken.\n * - `logoutOptions` (optional): Logout options to pass to keycloak.logout\n * when the user is getting logged out automatically after timout.\n * - `loginOptions` (optional): Login options to pass to keycloak.login\n * when the user is getting logged in automatically after timout.\n *\n * @returns A `KeycloakFeature` instance that configures and enables the\n * auto-refresh token functionality.\n */\nexport function withAutoRefreshToken(options?: WithRefreshTokenOptions): KeycloakFeature {\n return {\n configure: () => {\n const autoRefreshTokenService = inject(AutoRefreshTokenService);\n autoRefreshTokenService.start(options);\n }\n };\n}\n","/**\n * @license\n * Copyright Mauricio Gemelli Vigolo All Rights Reserved.\n *\n * Use of this source code is governed by a MIT-style license that can be\n * found in the LICENSE file at https://github.com/mauriciovigolo/keycloak-angular/blob/main/LICENSE.md\n */\n\nimport Keycloak, { KeycloakResourceAccess } from 'keycloak-js';\nimport { inject } from '@angular/core';\nimport {\n ActivatedRouteSnapshot,\n CanActivateChildFn,\n CanActivateFn,\n RouterStateSnapshot,\n UrlTree\n} from '@angular/router';\n\n/**\n * Type representing the roles granted to a user, including both realm and resource-level roles.\n */\nexport type Roles = {\n /**\n * Roles assigned at the realm level.\n */\n realmRoles: string[];\n /**\n * Roles assigned at the resource level, organized by resource name.\n */\n resourceRoles: { [resource: string]: string[] };\n};\n\n/**\n * Data structure passed to the custom authorization guard to determine access.\n */\nexport type AuthGuardData = {\n /**\n * Indicates whether the user is currently authenticated.\n */\n authenticated: boolean;\n /**\n * A collection of roles granted to the user, including both realm and resource roles.\n */\n grantedRoles: Roles;\n /**\n * The Keycloak instance managing the user's session and access.\n */\n keycloak: Keycloak;\n};\n\nconst mapResourceRoles = (resourceAccess: KeycloakResourceAccess = {}): Record<string, string[]> => {\n return Object.entries(resourceAccess).reduce<Record<string, string[]>>((roles, [key, value]) => {\n roles[key] = value.roles;\n return roles;\n }, {});\n};\n\n/**\n * Creates a custom authorization guard for Angular routes, enabling fine-grained access control.\n *\n * This guard invokes the provided `isAccessAllowed` function to determine if access is permitted\n * based on the current route, router state, and user's authentication and roles data.\n *\n * @template T - The type of the guard function (`CanActivateFn` or `CanActivateChildFn`).\n * @param isAccessAllowed - A callback function that evaluates access conditions. The function receives:\n * - `route`: The current `ActivatedRouteSnapshot` for the route being accessed.\n * - `state`: The current `RouterStateSnapshot` representing the router's state.\n * - `authData`: An `AuthGuardData` object containing the user's authentication status, roles, and Keycloak instance.\n * @returns A guard function of type `T` that can be used as a route `canActivate` or `canActivateChild` guard.\n *\n * @example\n * ```ts\n * import { createAuthGuard } from './auth-guard';\n * import { Routes } from '@angular/router';\n *\n * const isUserAllowed = async (route, state, authData) => {\n * const { authenticated, grantedRoles } = authData;\n * return authenticated && grantedRoles.realmRoles.includes('admin');\n * };\n *\n * const routes: Routes = [\n * {\n * path: 'admin',\n * canActivate: [createAuthGuard(isUserAllowed)],\n * component: AdminComponent,\n * },\n * ];\n * ```\n */\nexport const createAuthGuard = <T extends CanActivateFn | CanActivateChildFn>(\n isAccessAllowed: (\n route: ActivatedRouteSnapshot,\n state: RouterStateSnapshot,\n authData: AuthGuardData\n ) => Promise<boolean | UrlTree>\n): T => {\n return ((next: ActivatedRouteSnapshot, state: RouterStateSnapshot) => {\n const keycloak = inject(Keycloak);\n\n const authenticated = keycloak?.authenticated ?? false;\n const grantedRoles: Roles = {\n resourceRoles: mapResourceRoles(keycloak?.resourceAccess),\n realmRoles: keycloak?.realmAccess?.roles ?? []\n };\n const authData = { authenticated, keycloak, grantedRoles };\n\n return isAccessAllowed(next, state, authData);\n }) as T;\n};\n","/**\n * @license\n * Copyright Mauricio Gemelli Vigolo All Rights Reserved.\n *\n * Use of this source code is governed by a MIT-style license that can be\n * found in the LICENSE file at https://github.com/mauriciovigolo/keycloak-angular/blob/main/LICENSE.md\n */\n\nimport { Observable } from 'rxjs';\nimport Keycloak from 'keycloak-js';\nimport { HttpEvent, HttpHandlerFn, HttpRequest } from '@angular/common/http';\n\n/**\n * Default value for the authorization header prefix, used to construct the Authorization token.\n */\nconst BEARER_PREFIX = 'Bearer';\n/**\n * Default name of the authorization header.\n */\nconst AUTHORIZATION_HEADER_NAME = 'Authorization';\n/**\n * Represents the HTTP methods supported by the interceptor for authorization purposes.\n */\nexport type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'OPTIONS' | 'HEAD' | 'PATCH';\n\n/**\n * Common attributes for the Auth Bearer interceptor that can be reused in other interceptor implementations.\n */\nexport type BearerTokenCondition = {\n /**\n * Prefix to be used in the Authorization header. Default is \"Bearer\".\n * This will result in a header formatted as: `Authorization: Bearer <token>`.\n *\n * Adjust this value if your backend expects a different prefix in the Authorization header.\n */\n bearerPrefix?: string;\n /**\n * Name of the HTTP header used for authorization. Default is \"Authorization\".\n * Customize this value if your backend expects a different header, e.g., \"JWT-Authorization\".\n */\n authorizationHeaderName?: string;\n /**\n * Function to determine whether the token should be updated before a request. Default is a function returning true.\n * If the function returns `true`, the token's validity will be checked and updated if needed.\n * If it returns `false`, the token update process will be skipped for that request.\n *\n * @param request - The current `HttpRequest` object being intercepted.\n * @returns A boolean indicating whether to update the token.\n */\n\n shouldUpdateToken?: (request: HttpRequest<unknown>) => boolean;\n};\n\n/**\n * Generic factory function to create an interceptor condition with default values.\n *\n * This utility allows you to define custom interceptor conditions while ensuring that\n * default values are applied to any missing fields. By using generics, you can enforce\n * strong typing when creating the fields for the interceptor condition, enhancing type safety.\n *\n * @template T - A type that extends `AuthBearerCondition`.\n * @param value - An object of type `T` (extending `AuthBearerCondition`) to be enhanced with default values.\n * @returns A new object of type `T` with default values assigned to any undefined properties.\n */\nexport const createInterceptorCondition = <T extends BearerTokenCondition>(value: T): T => ({\n ...value,\n bearerPrefix: value.bearerPrefix ?? BEARER_PREFIX,\n authorizationHeaderName: value.authorizationHeaderName ?? AUTHORIZATION_HEADER_NAME,\n shouldUpdateToken: value.shouldUpdateToken ?? (() => true)\n});\n\n/**\n * Conditionally updates the Keycloak token based on the provided request and conditions.\n *\n * @param req - The `HttpRequest` object being processed.\n * @param keycloak - The Keycloak instance managing authentication.\n * @param condition - An `AuthBearerCondition` object with the `shouldUpdateToken` function.\n * @returns A `Promise<boolean>` indicating whether the token was successfully updated.\n */\nexport const conditionallyUpdateToken = async (\n req: HttpRequest<unknown>,\n keycloak: Keycloak,\n { shouldUpdateToken = (_) => true }: BearerTokenCondition\n): Promise<boolean> => {\n if (shouldUpdateToken(req)) {\n return await keycloak.updateToken().catch(() => false);\n }\n return true;\n};\n\n/**\n * Adds the Authorization header to an HTTP request and forwards it to the next handler.\n *\n * @param req - The original `HttpRequest` object.\n * @param next - The `HttpHandlerFn` function for forwarding the HTTP request.\n * @param keycloak - The Keycloak instance providing the authentication token.\n * @param condition - An `AuthBearerCondition` object specifying header configuration.\n * @returns An `Observable<HttpEvent<unknown>>` representing the HTTP response.\n */\nexport const addAuthorizationHeader = (\n req: HttpRequest<unknown>,\n next: HttpHandlerFn,\n keycloak: Keycloak,\n condition: BearerTokenCondition\n): Observable<HttpEvent<unknown>> => {\n const { bearerPrefix = BEARER_PREFIX, authorizationHeaderName = AUTHORIZATION_HEADER_NAME } = condition;\n\n const clonedRequest = req.clone({\n setHeaders: {\n [authorizationHeaderName]: `${bearerPrefix} ${keycloak.token}`\n }\n });\n\n return next(clonedRequest);\n};\n","/**\n * @license\n * Copyright Mauricio Gemelli Vigolo All Rights Reserved.\n *\n * Use of this source code is governed by a MIT-style license that can be\n * found in the LICENSE file at https://github.com/mauriciovigolo/keycloak-angular/blob/main/LICENSE.md\n */\n\nimport Keycloak from 'keycloak-js';\nimport { from, mergeMap, Observable } from 'rxjs';\nimport { inject, InjectionToken } from '@angular/core';\nimport { HttpEvent, HttpHandlerFn, HttpRequest } from '@angular/common/http';\n\nimport { addAuthorizationHeader, conditionallyUpdateToken, BearerTokenCondition } from './keycloak.interceptor';\n\n/**\n * Defines a custom condition for determining whether a Bearer token should be included\n * in the `Authorization` header of an outgoing HTTP request.\n *\n * This type extends the `BearerTokenCondition` type and adds a dynamic function\n * (`shouldAddToken`) that evaluates whether the token should be added based on the\n * request, handler, and Keycloak state.\n */\nexport type CustomBearerTokenCondition = Partial<BearerTokenCondition> & {\n /**\n * A function that dynamically determines whether the Bearer token should be included\n * in the `Authorization` header for a given request.\n *\n * This function is asynchronous and receives the following arguments:\n * - `req`: The `HttpRequest` object representing the current outgoing HTTP request.\n * - `next`: The `HttpHandlerFn` for forwarding the request to the next handler in the chain.\n * - `keycloak`: The `Keycloak` instance representing the authentication context.\n */\n shouldAddToken: (req: HttpRequest<unknown>, next: HttpHandlerFn, keycloak: Keycloak) => Promise<boolean>;\n};\n\n/**\n * Injection token for configuring the `customBearerTokenInterceptor`.\n *\n * This injection token holds an array of `CustomBearerTokenCondition` objects, which define\n * the conditions under which a Bearer token should be included in the `Authorization` header\n * of outgoing HTTP requests. Each condition provides a `shouldAddToken` function that dynamically\n * determines whether the token should be added based on the request, handler, and Keycloak state.\n */\nexport const CUSTOM_BEARER_TOKEN_INTERCEPTOR_CONFIG = new InjectionToken<CustomBearerTokenCondition[]>(\n 'Include the bearer token as implemented by the provided function'\n);\n\n/**\n * Custom HTTP Interceptor for dynamically adding a Bearer token to requests based on conditions.\n *\n * This interceptor uses a flexible approach where the decision to include a Bearer token in the\n * `Authorization` HTTP header is determined by a user-provided function (`shouldAddToken`).\n * This enables a dynamic and granular control over when tokens are added to HTTP requests.\n *\n * ### Key Features:\n * 1. **Dynamic Token Inclusion**: Uses a condition function (`shouldAddToken`) to decide dynamically\n * whether to add the token based on the request, Keycloak state, and other factors.\n * 2. **Token Management**: Optionally refreshes the Keycloak token before adding it to the request.\n * 3. **Controlled Authorization**: Adds the Bearer token only when the condition function allows\n * and the user is authenticated in Keycloak.\n *\n * ### Configuration:\n * The interceptor relies on `CUSTOM_BEARER_TOKEN_INTERCEPTOR_CONFIG`, an injection token that contains\n * an array of `CustomBearerTokenCondition` objects. Each condition specifies a `shouldAddToken` function\n * that determines whether to add the Bearer token for a given request.\n *\n * ### Workflow:\n * 1. Reads the conditions from the `CUSTOM_BEARER_TOKEN_INTERCEPTOR_CONFIG` injection token.\n * 2. Iterates through the conditions and evaluates the `shouldAddToken` function for the request.\n * 3. If a condition matches:\n * - Optionally refreshes the Keycloak token if needed.\n * - Adds the Bearer token to the request's `Authorization` header if the user is authenticated.\n * 4. If no conditions match, the request proceeds unchanged.\n *\n * ### Parameters:\n * @param req - The `HttpRequest` object representing the outgoing HTTP request.\n * @param next - The `HttpHandlerFn` for passing the request to the next handler in the chain.\n *\n * @returns An `Observable<HttpEvent<unknown>>` representing the HTTP response.\n *\n * ### Usage Example:\n * ```typescript\n * // Define a custom condition to include the token\n * const customCondition: CustomBearerTokenCondition = {\n * shouldAddToken: async (req, next, keycloak) => {\n * // Add token only for requests to the /api endpoint\n * return req.url.startsWith('/api') && keycloak.authenticated;\n * },\n * };\n *\n * // Configure the interceptor with the custom condition\n * export const appConfig: ApplicationConfig = {\n * providers: [\n * provideHttpClient(withInterceptors([customBearerTokenInterceptor])),\n * {\n * provide: CUSTOM_BEARER_TOKEN_INTERCEPTOR_CONFIG,\n * useValue: [customCondition],\n * },\n * ],\n * };\n * ```\n */\nexport const customBearerTokenInterceptor = (\n req: HttpRequest<unknown>,\n next: HttpHandlerFn\n): Observable<HttpEvent<unknown>> => {\n const conditions = inject(CUSTOM_BEARER_TOKEN_INTERCEPTOR_CONFIG) ?? [];\n\n const keycloak = inject(Keycloak);\n\n return from(\n Promise.all(conditions.map(async (condition) => await condition.shouldAddToken(req, next, keycloak)))\n ).pipe(\n mergeMap((evaluatedConditions) => {\n const matchingConditionIndex = evaluatedConditions.findIndex(Boolean);\n const matchingCondition = conditions[matchingConditionIndex];\n\n if (!matchingCondition) {\n return next(req);\n }\n\n return from(conditionallyUpdateToken(req, keycloak, matchingCondition)).pipe(\n mergeMap(() =>\n keycloak.authenticated ? addAuthorizationHeader(req, next, keycloak, matchingCondition) : next(req)\n )\n );\n })\n );\n};\n","/**\n * @license\n * Copyright Mauricio Gemelli Vigolo All Rights Reserved.\n *\n * Use of this source code is governed by a MIT-style license that can be\n * found in the LICENSE file at https://github.com/mauriciovigolo/keycloak-angular/blob/main/LICENSE.md\n */\n\nimport Keycloak from 'keycloak-js';\nimport { from, mergeMap, Observable } from 'rxjs';\nimport { inject, InjectionToken } from '@angular/core';\nimport { HttpEvent, HttpHandlerFn, HttpRequest } from '@angular/common/http';\n\nimport {\n addAuthorizationHeader,\n conditionallyUpdateToken,\n HttpMethod,\n BearerTokenCondition\n} from './keycloak.interceptor';\n\n/**\n * Defines the conditions for including the Bearer token in the Authorization HTTP header.\n */\nexport type IncludeBearerTokenCondition = Partial<BearerTokenCondition> & {\n /**\n * A URL pattern (as a `RegExp`) used to determine whether the Bearer token should be added\n * to the Authorization HTTP header for a given request. The Bearer token is only added if\n * this pattern matches the request's URL.\n *\n * This EXPLICIT configuration is for security purposes, ensuring that internal tokens are not\n * shared with unintended services.\n */\n urlPattern: RegExp;\n /**\n * An optional array of HTTP methods (`HttpMethod[]`) to further refine the conditions under\n * which the Bearer token is added. If not provided, the default behavior is to add the token\n * for all HTTP methods matching the `urlPattern`.\n */\n httpMethods?: HttpMethod[];\n};\n\n/**\n * Injection token for configuring the `includeBearerTokenInterceptor`, allowing the specification\n * of conditions under which the Bearer token should be included in HTTP request headers.\n *\n * This configuration supports multiple conditions, enabling customization for different URLs.\n * It also provides options to tailor the Bearer prefix and the Authorization header name as needed.\n */\nexport const INCLUDE_BEARER_TOKEN_INTERCEPTOR_CONFIG = new InjectionToken<IncludeBearerTokenCondition[]>(\n 'Include the bearer token when explicitly defined int the URL pattern condition'\n);\n\nconst findMatchingCondition = (\n { method, url }: HttpRequest<unknown>,\n { urlPattern, httpMethods = [] }: IncludeBearerTokenCondition\n): boolean => {\n const httpMethodTest = httpMethods.length === 0 || httpMethods.join().indexOf(method.toUpperCase()) > -1;\n\n const urlTest = urlPattern.test(url);\n\n return httpMethodTest && urlTest;\n};\n\n/**\n * HTTP Interceptor to include a Bearer token in the Authorization header for specific HTTP requests.\n *\n * This interceptor ensures that a Bearer token is added to outgoing HTTP requests based on explicitly\n * defined conditions. By default, the interceptor does not include the Bearer token unless the request\n * matches the provided configuration (`IncludeBearerTokenCondition`). This approach enhances security\n * by preventing sensitive tokens from being unintentionally sent to unauthorized services.\n *\n * ### Features:\n * 1. **Explicit URL Matching**: The interceptor uses regular expressions to match URLs where the Bearer token should be included.\n * 2. **HTTP Method Filtering**: Optional filtering by HTTP methods (e.g., `GET`, `POST`, `PUT`) to refine the conditions for adding the token.\n * 3. **Token Management**: Ensures the Keycloak token is valid by optionally refreshing it before attaching it to the request.\n * 4. **Controlled Authorization**: Sends the token only for requests where the user is authenticated, and the conditions match.\n *\n * ### Workflow:\n * - Reads conditions from `INCLUDE_BEARER_TOKEN_INTERCEPTOR_CONFIG`, which specifies when the Bearer token should be included.\n * - If a request matches the conditions:\n * 1. The Keycloak token is refreshed if needed.\n * 2. The Bearer token is added to the Authorization header.\n * 3. The modified request is passed to the next handler.\n * - If no conditions match, the request proceeds unchanged.\n *\n * ### Security:\n * By explicitly defining URL patterns and optional HTTP methods, this interceptor prevents the leakage of tokens\n * to unintended endpoints, such as third-party APIs or external services. This is especially critical for applications\n * that interact with both internal and external services.\n *\n * @param req - The `HttpRequest` object representing the outgoing HTTP request.\n * @param next - The `HttpHandlerFn` for passing the request to the next handler in the chain.\n * @returns An `Observable<HttpEvent<unknown>>` representing the asynchronous HTTP response.\n *\n * ### Configuration:\n * The interceptor relies on `INCLUDE_BEARER_TOKEN_INTERCEPTOR_CONFIG`, an injection token that holds\n * an array of `IncludeBearerTokenCondition` objects. Each object defines the conditions for including\n * the Bearer token in the request.\n *\n * #### Example Configuration:\n * ```typescript\n * provideHttpClient(\n * withInterceptors([includeBearerTokenInterceptor]),\n * {\n * provide: INCLUDE_BEARER_TOKEN_INTERCEPTOR_CONFIG,\n * useValue: [\n * {\n * urlPattern: /^https:\\/\\/api\\.internal\\.myapp\\.com\\/.*\\/,\n * httpMethods: ['GET', 'POST'], // Add the token only for GET and POST methods\n * },\n * ],\n * }\n * );\n * ```\n *\n * ### Example Usage:\n * ```typescript\n * export const appConfig: ApplicationConfig = {\n * providers: [\n * provideHttpClient(withInterceptors([includeBearerTokenInterceptor])),\n * provideZoneChangeDetection({ eventCoalescing: true }),\n * provideRouter(routes),\n * ],\n * };\n * ```\n *\n * ### Example Matching Condition:\n * ```typescript\n * {\n * urlPattern: /^(https:\\/\\/internal\\.mycompany\\.com)(\\/.*)?$/i,\n * httpMethods: ['GET', 'PUT'], // Optional: Match only specific HTTP methods\n * }\n * ```\n */\nexport const includeBearerTokenInterceptor = (\n req: HttpRequest<unknown>,\n next: HttpHandlerFn\n): Observable<HttpEvent<unknown>> => {\n const conditions = inject(INCLUDE_BEARER_TOKEN_INTERCEPTOR_CONFIG) ?? [];\n\n const matchingCondition = conditions.find((condition) => findMatchingCondition(req, condition));\n if (!matchingCondition) {\n return next(req);\n }\n\n const keycloak = inject(Keycloak);\n\n return from(conditionallyUpdateToken(req, keycloak, matchingCondition)).pipe(\n mergeMap(() =>\n keycloak.authenticated ? addAuthorizationHeader(req, next, keycloak, matchingCondition) : next(req)\n )\n );\n};\n","/**\n * @license\n * Copyright Mauricio Gemelli Vigolo All Rights Reserved.\n *\n * Use of this source code is governed by a MIT-style license that can be\n * found in the LICENSE file at https://github.com/mauriciovigolo/keycloak-angular/blob/main/LICENSE.md\n */\n\nimport Keycloak, { KeycloakConfig, KeycloakInitOptions } from 'keycloak-js';\nimport {\n EnvironmentInjector,\n EnvironmentProviders,\n inject,\n makeEnvironmentProviders,\n provideAppInitializer,\n Provider,\n runInInjectionContext\n} from '@angular/core';\nimport { createKeycloakSignal, KEYCLOAK_EVENT_SIGNAL } from './signals/keycloak-events-signal';\nimport { KeycloakFeature } from './features/keycloak.feature';\n\n/**\n * Options for configuring Keycloak and additional providers.\n */\nexport type ProvideKeycloakOptions = {\n /**\n * Keycloak configuration, including the server URL, realm, and client ID.\n */\n config: KeycloakConfig;\n\n /**\n * Optional initialization options for the Keycloak instance.\n * If not provided, Keycloak will not initialize automatically.\n */\n initOptions?: KeycloakInitOptions;\n\n /**\n * Optional array of additional Angular providers or environment providers.\n */\n providers?: Array<Provider | EnvironmentProviders>;\n\n /**\n * Optional array of Keycloak features to extend the functionality of the Keycloak integration.\n */\n features?: Array<KeycloakFeature>;\n};\n\n/**\n * Provides Keycloak initialization logic for the app initializer phase.\n * Ensures Keycloak is initialized and features are configured.\n *\n * @param keycloak - The Keycloak instance.\n * @param options - ProvideKeycloakOptions for configuration.\n * @returns EnvironmentProviders or an empty array if `initOptions` is not provided.\n */\nconst provideKeycloakInAppInitializer = (\n keycloak: Keycloak,\n options: ProvideKeycloakOptions\n): EnvironmentProviders | Provider[] => {\n const { initOptions, features = [] } = options;\n\n if (!initOptions) {\n return [];\n }\n\n return provideAppInitializer(async () => {\n const injector = inject(EnvironmentInjector);\n runInInjectionContext(injector, () => features.forEach((feature) => feature.configure()));\n await keycloak.init(initOptions).catch((error) => console.error('Keycloak initialization failed', error));\n });\n};\n\n/**\n * Configures and provides Keycloak as a dependency in an Angular application.\n *\n * This function initializes a Keycloak instance with the provided configuration and\n * optional initialization options. It integrates Keycloak into Angular dependency\n * injection system, allowing easy consumption throughout the application. Additionally,\n * it supports custom providers and Keycloak Angular features.\n *\n * If `initOptions` is not provided, the Keycloak instance will not be automatically initialized.\n * In such cases, the application must call `keycloak.init()` explicitly.\n *\n * @param options - Configuration object for Keycloak:\n * - `config`: The Keycloak configuration, including the server URL, realm, and client ID.\n * - `initOptions` (Optional): Initialization options for the Keycloak instance.\n * - `providers` (Optional): Additional Angular providers to include.\n * - `features` (Optional): Keycloak Angular features to configure during initialization.\n *\n * @returns An `EnvironmentProviders` object integrating Keycloak setup and additional providers.\n *\n * @example\n * ```ts\n * import { provideKeycloak } from './keycloak.providers';\n * import { bootstrapApplication } from '@angular/platform-browser';\n * import { AppComponent } from './app/app.component';\n *\n * bootstrapApplication(AppComponent, {\n * providers: [\n * provideKeycloak({\n * config: {\n * url: 'https://auth-server.example.com',\n * realm: 'my-realm',\n * clientId: 'my-client',\n * },\n * initOptions: {\n * onLoad: 'login-required',\n * },\n * }),\n * ],\n * });\n * ```\n */\nexport function provideKeycloak(options: ProvideKeycloakOptions): EnvironmentProviders {\n const keycloak = new Keycloak(options.config);\n\n const providers = options.providers ?? [];\n const keycloakSignal = createKeycloakSignal(keycloak);\n\n return makeEnvironmentProviders([\n {\n provide: KEYCLOAK_EVENT_SIGNAL,\n useValue: keycloakSignal\n },\n {\n provide: Keycloak,\n useValue: keycloak\n },\n ...providers,\n provideKeycloakInAppInitializer(keycloak, options)\n ]);\n}\n","/**\n * @license\n * Copyright Mauricio Gemelli Vigolo All Rights Reserved.\n *\n * Use of this source code is governed by a MIT-style license that can be\n * found in the LICENSE file at https://github.com/mauriciovigolo/keycloak-angular/blob/main/LICENSE.md\n */\nexport * from './lib/legacy/public_api';\nexport * from './lib/directives/has-roles.directive';\nexport * from './lib/features/keycloak.feature';\nexport * from './lib/features/with-refresh-token.feature';\nexport * from './lib/guards/auth.guard';\nexport * from './lib/interceptors/custom-bearer-token.interceptor';\nexport * from './lib/interceptors/include-bearer-token.interceptor';\nexport * from './lib/interceptors/keycloak.interceptor';\nexport * from './lib/services/user-activity.service';\nexport * from './lib/services/auto-refresh-token.service';\nexport * from './lib/signals/keycloak-events-signal';\nexport * from './lib/provide-keycloak';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":["mergeMap"],"mappings":"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"}
package/index.d.ts CHANGED
@@ -3,9 +3,9 @@ import { CanActivate, Router, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTr
3
3
  import * as rxjs from 'rxjs';
4
4
  import { Subject, Observable } from 'rxjs';
5
5
  import * as Keycloak$1 from 'keycloak-js';
6
- import Keycloak__default, { KeycloakError, KeycloakConfig, KeycloakInitOptions } from 'keycloak-js';
6
+ import Keycloak__default, { KeycloakLogoutOptions, KeycloakLoginOptions, KeycloakError, KeycloakConfig, KeycloakInitOptions } from 'keycloak-js';
7
7
  import * as i0 from '@angular/core';
8
- import { InjectionToken, OnDestroy, Signal, Provider, EnvironmentProviders } from '@angular/core';
8
+ import { OnChanges, InjectionToken, OnDestroy, Signal, Provider, EnvironmentProviders } from '@angular/core';
9
9
  import * as i1 from '@angular/common';
10
10
 
11
11
  /**
@@ -663,6 +663,14 @@ declare class KeycloakAngularModule {
663
663
  static ɵinj: i0.ɵɵInjectorDeclaration<KeycloakAngularModule>;
664
664
  }
665
665
 
666
+ /**
667
+ * @license
668
+ * Copyright Mauricio Gemelli Vigolo All Rights Reserved.
669
+ *
670
+ * Use of this source code is governed by a MIT-style license that can be
671
+ * found in the LICENSE file at https://github.com/mauriciovigolo/keycloak-angular/blob/main/LICENSE.md
672
+ */
673
+
666
674
  /**
667
675
  * Structural directive to conditionally display elements based on Keycloak user roles.
668
676
  *
@@ -722,7 +730,7 @@ declare class KeycloakAngularModule {
722
730
  * </ng-template>
723
731
  * ```
724
732
  */
725
- declare class HasRolesDirective {
733
+ declare class HasRolesDirective implements OnChanges {
726
734
  private templateRef;
727
735
  private viewContainer;
728
736
  private keycloak;
@@ -739,6 +747,13 @@ declare class HasRolesDirective {
739
747
  */
740
748
  checkRealm: boolean;
741
749
  constructor();
750
+ /**
751
+ * Here to reevaluate access when inputs change.
752
+ */
753
+ ngOnChanges(): void;
754
+ /**
755
+ * Clear the view and render it if user has access.
756
+ */
742
757
  private render;
743
758
  /**
744
759
  * Checks if the user has at least one of the specified roles in the resource or realm.
@@ -825,6 +840,18 @@ type WithRefreshTokenOptions = {
825
840
  * Default value: `'logout'`.
826
841
  */
827
842
  onInactivityTimeout?: 'login' | 'logout' | 'none';
843
+ /**
844
+ * Logout options to pass to keycloak.logout when the user is getting logged out automatically after timout.
845
+ *
846
+ * Default value: undefined
847
+ */
848
+ logoutOptions?: KeycloakLogoutOptions;
849
+ /**
850
+ * Login options to pass to keycloak.login when the user is getting logged in automatically after timeout.
851
+ *
852
+ * Default value: undefined
853
+ */
854
+ loginOptions?: KeycloakLoginOptions;
828
855
  };
829
856
  /**
830
857
  * Enables automatic token refresh and session inactivity handling for a
@@ -853,6 +880,10 @@ type WithRefreshTokenOptions = {
853
880
  * - `'login'`: Execute `keycloak.login` function.
854
881
  * - `'logout'`: Logs the user out by calling `keycloak.logout`.
855
882
  * - `'none'`: No action is taken.
883
+ * - `logoutOptions` (optional): Logout options to pass to keycloak.logout
884
+ * when the user is getting logged out automatically after timout.
885
+ * - `loginOptions` (optional): Login options to pass to keycloak.login
886
+ * when the user is getting logged in automatically after timout.
856
887
  *
857
888
  * @returns A `KeycloakFeature` instance that configures and enables the
858
889
  * auto-refresh token functionality.
@@ -1281,6 +1312,18 @@ type AutoRefreshTokenOptions = {
1281
1312
  * Default is `'logout'`.
1282
1313
  */
1283
1314
  onInactivityTimeout?: 'login' | 'logout' | 'none';
1315
+ /**
1316
+ * Logout options to pass to keycloak.logout when the user is getting logged out automatically after timout.
1317
+ *
1318
+ * Default value: undefined
1319
+ */
1320
+ logoutOptions?: KeycloakLogoutOptions;
1321
+ /**
1322
+ * Login options to pass to keycloak.login when the user is getting logged in automatically after timeout.
1323
+ *
1324
+ * Default value: undefined
1325
+ */
1326
+ loginOptions?: KeycloakLoginOptions;
1284
1327
  };
1285
1328
  /**
1286
1329
  * Service to automatically manage the Keycloak token refresh process
@@ -1490,4 +1533,4 @@ type ProvideKeycloakOptions = {
1490
1533
  declare function provideKeycloak(options: ProvideKeycloakOptions): EnvironmentProviders;
1491
1534
 
1492
1535
  export { AutoRefreshTokenService, CUSTOM_BEARER_TOKEN_INTERCEPTOR_CONFIG, CoreModule, HasRolesDirective, INCLUDE_BEARER_TOKEN_INTERCEPTOR_CONFIG, KEYCLOAK_EVENT_SIGNAL, KeycloakAngularModule, KeycloakAuthGuard, KeycloakBearerInterceptor, KeycloakEventType, KeycloakEventTypeLegacy, KeycloakService, UserActivityService, addAuthorizationHeader, conditionallyUpdateToken, createAuthGuard, createInterceptorCondition, createKeycloakSignal, customBearerTokenInterceptor, includeBearerTokenInterceptor, provideKeycloak, typeEventArgs, withAutoRefreshToken };
1493
- export type { ActionUpdateArgs, AuthErrorArgs, AuthGuardData, BearerTokenCondition, CustomBearerTokenCondition, HttpMethod, IncludeBearerTokenCondition, KeycloakEvent, KeycloakEventLegacy, KeycloakFeature, KeycloakOptions, ProvideKeycloakOptions, ReadyArgs };
1536
+ export type { ActionUpdateArgs, AuthErrorArgs, AuthGuardData, BearerTokenCondition, CustomBearerTokenCondition, HttpMethod, IncludeBearerTokenCondition, KeycloakEvent, KeycloakEventLegacy, KeycloakFeature, KeycloakOptions, ProvideKeycloakOptions, ReadyArgs, Roles };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "keycloak-angular",
3
- "version": "20.0.0",
3
+ "version": "20.1.0",
4
4
  "description": "Easy Keycloak integration for Angular applications.",
5
5
  "repository": {
6
6
  "type": "git",