UNPKG

keycloak-angular

Version:
1,078 lines (1,077 loc) 82.7 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** * @license * Copyright Mauricio Gemelli Vigolo and contributors. * * Use of this source code is governed by a MIT-style license that can be * found in the LICENSE file at https://github.com/mauriciovigolo/keycloak-angular/LICENSE */ import * as tslib_1 from "tslib"; import { Injectable } from '@angular/core'; import { HttpHeaders } from '@angular/common/http'; import * as Keycloak_ from 'keycloak-js'; /** @type {?} */ export var Keycloak = Keycloak_; import { Observable, Subject } from 'rxjs'; import { KeycloakEventType } from '../interfaces/keycloak-event'; /** * Service to expose existent methods from the Keycloak JS adapter, adding new * functionalities to improve the use of keycloak in Angular v > 4.3 applications. * * This class should be injected in the application bootstrap, so the same instance will be used * along the web application. */ var KeycloakService = /** @class */ (function () { function KeycloakService() { this._keycloakEvents$ = new Subject(); } /** * Sanitizes the bearer prefix, preparing it to be appended to * the token. * * @param {?} bearerPrefix * Prefix to be appended to the authorization header as * Authorization: <bearer-prefix> <token>. * @return {?} * The bearer prefix sanitized, meaning that it will follow the bearerPrefix * param as described in the library initilization or the default value bearer, * with a space append in the end for the token concatenation. */ KeycloakService.prototype.sanitizeBearerPrefix = /** * Sanitizes the bearer prefix, preparing it to be appended to * the token. * * @param {?} bearerPrefix * Prefix to be appended to the authorization header as * Authorization: <bearer-prefix> <token>. * @return {?} * The bearer prefix sanitized, meaning that it will follow the bearerPrefix * param as described in the library initilization or the default value bearer, * with a space append in the end for the token concatenation. */ function (bearerPrefix) { /** @type {?} */ var prefix = (bearerPrefix || 'bearer').trim(); return prefix.concat(' '); }; /** * Sets default value to true if it is undefined or null. * * @param {?} value - boolean value to be checked * @return {?} */ KeycloakService.prototype.ifUndefinedIsTrue = /** * Sets default value to true if it is undefined or null. * * @param {?} value - boolean value to be checked * @return {?} */ function (value) { /** @type {?} */ var returnValue = value; if (returnValue === undefined || returnValue === null) { returnValue = true; } return returnValue; }; /** * Binds the keycloak-js events to the keycloakEvents Subject * which is a good way to monitor for changes, if needed. * * The keycloakEvents returns the keycloak-js event type and any * argument if the source function provides any. * @return {?} */ KeycloakService.prototype.bindsKeycloakEvents = /** * Binds the keycloak-js events to the keycloakEvents Subject * which is a good way to monitor for changes, if needed. * * The keycloakEvents returns the keycloak-js event type and any * argument if the source function provides any. * @return {?} */ function () { var _this = this; if (!this._instance) { console.warn('Keycloak Angular events could not be registered as the keycloak instance is undefined.'); return; } this._instance.onAuthError = function (errorData) { _this._keycloakEvents$.next({ args: errorData, type: KeycloakEventType.OnAuthError }); }; this._instance.onAuthLogout = function () { _this._keycloakEvents$.next({ type: KeycloakEventType.OnAuthLogout }); }; this._instance.onAuthRefreshError = function () { _this._keycloakEvents$.next({ type: KeycloakEventType.OnAuthRefreshError }); }; this._instance.onAuthSuccess = function () { _this._keycloakEvents$.next({ type: KeycloakEventType.OnAuthSuccess }); }; this._instance.onTokenExpired = function () { _this._keycloakEvents$.next({ type: KeycloakEventType.OnTokenExpired }); }; this._instance.onReady = function (authenticated) { _this._keycloakEvents$.next({ args: authenticated, type: KeycloakEventType.OnReady }); }; }; /** * Keycloak initialization. It should be called to initialize the adapter. * Options is a object with 2 main parameters: config and initOptions. The first one * will be used to create the Keycloak instance. The second one are options to initialize the * keycloak instance. * * @param options * Config: may be a string representing the keycloak URI or an object with the * following content: * - url: Keycloak json URL * - realm: realm name * - clientId: client id * * initOptions: * - onLoad: Specifies an action to do on load. Supported values are 'login-required' or * 'check-sso'. * - token: Set an initial value for the token. * - refreshToken: Set an initial value for the refresh token. * - idToken: Set an initial value for the id token (only together with token or refreshToken). * - timeSkew: Set an initial value for skew between local time and Keycloak server in seconds * (only together with token or refreshToken). * - checkLoginIframe: Set to enable/disable monitoring login state (default is true). * - checkLoginIframeInterval: Set the interval to check login state (default is 5 seconds). * - responseMode: Set the OpenID Connect response mode send to Keycloak server at login * request. Valid values are query or fragment . Default value is fragment, which means * that after successful authentication will Keycloak redirect to javascript application * with OpenID Connect parameters added in URL fragment. This is generally safer and * recommended over query. * - flow: Set the OpenID Connect flow. Valid values are standard, implicit or hybrid. * * enableBearerInterceptor: * Flag to indicate if the bearer will added to the authorization header. * * loadUserProfileInStartUp: * Indicates that the user profile should be loaded at the keycloak initialization, * just after the login. * * bearerExcludedUrls: * String Array to exclude the urls that should not have the Authorization Header automatically * added. * * authorizationHeaderName: * This value will be used as the Authorization Http Header name. * * bearerPrefix: * This value will be included in the Authorization Http Header param. * * @returns * A Promise with a boolean indicating if the initialization was successful. */ /** * Keycloak initialization. It should be called to initialize the adapter. * Options is a object with 2 main parameters: config and initOptions. The first one * will be used to create the Keycloak instance. The second one are options to initialize the * keycloak instance. * * @param {?=} options * Config: may be a string representing the keycloak URI or an object with the * following content: * - url: Keycloak json URL * - realm: realm name * - clientId: client id * * initOptions: * - onLoad: Specifies an action to do on load. Supported values are 'login-required' or * 'check-sso'. * - token: Set an initial value for the token. * - refreshToken: Set an initial value for the refresh token. * - idToken: Set an initial value for the id token (only together with token or refreshToken). * - timeSkew: Set an initial value for skew between local time and Keycloak server in seconds * (only together with token or refreshToken). * - checkLoginIframe: Set to enable/disable monitoring login state (default is true). * - checkLoginIframeInterval: Set the interval to check login state (default is 5 seconds). * - responseMode: Set the OpenID Connect response mode send to Keycloak server at login * request. Valid values are query or fragment . Default value is fragment, which means * that after successful authentication will Keycloak redirect to javascript application * with OpenID Connect parameters added in URL fragment. This is generally safer and * recommended over query. * - flow: Set the OpenID Connect flow. Valid values are standard, implicit or hybrid. * * enableBearerInterceptor: * Flag to indicate if the bearer will added to the authorization header. * * loadUserProfileInStartUp: * Indicates that the user profile should be loaded at the keycloak initialization, * just after the login. * * bearerExcludedUrls: * String Array to exclude the urls that should not have the Authorization Header automatically * added. * * authorizationHeaderName: * This value will be used as the Authorization Http Header name. * * bearerPrefix: * This value will be included in the Authorization Http Header param. * * @return {?} * A Promise with a boolean indicating if the initialization was successful. */ KeycloakService.prototype.init = /** * Keycloak initialization. It should be called to initialize the adapter. * Options is a object with 2 main parameters: config and initOptions. The first one * will be used to create the Keycloak instance. The second one are options to initialize the * keycloak instance. * * @param {?=} options * Config: may be a string representing the keycloak URI or an object with the * following content: * - url: Keycloak json URL * - realm: realm name * - clientId: client id * * initOptions: * - onLoad: Specifies an action to do on load. Supported values are 'login-required' or * 'check-sso'. * - token: Set an initial value for the token. * - refreshToken: Set an initial value for the refresh token. * - idToken: Set an initial value for the id token (only together with token or refreshToken). * - timeSkew: Set an initial value for skew between local time and Keycloak server in seconds * (only together with token or refreshToken). * - checkLoginIframe: Set to enable/disable monitoring login state (default is true). * - checkLoginIframeInterval: Set the interval to check login state (default is 5 seconds). * - responseMode: Set the OpenID Connect response mode send to Keycloak server at login * request. Valid values are query or fragment . Default value is fragment, which means * that after successful authentication will Keycloak redirect to javascript application * with OpenID Connect parameters added in URL fragment. This is generally safer and * recommended over query. * - flow: Set the OpenID Connect flow. Valid values are standard, implicit or hybrid. * * enableBearerInterceptor: * Flag to indicate if the bearer will added to the authorization header. * * loadUserProfileInStartUp: * Indicates that the user profile should be loaded at the keycloak initialization, * just after the login. * * bearerExcludedUrls: * String Array to exclude the urls that should not have the Authorization Header automatically * added. * * authorizationHeaderName: * This value will be used as the Authorization Http Header name. * * bearerPrefix: * This value will be included in the Authorization Http Header param. * * @return {?} * A Promise with a boolean indicating if the initialization was successful. */ function (options) { var _this = this; if (options === void 0) { options = {}; } return new Promise(function (resolve, reject) { _this._enableBearerInterceptor = _this.ifUndefinedIsTrue(options.enableBearerInterceptor); _this._loadUserProfileAtStartUp = _this.ifUndefinedIsTrue(options.loadUserProfileAtStartUp); _this._bearerExcludedUrls = options.bearerExcludedUrls || []; _this._authorizationHeaderName = options.authorizationHeaderName || 'Authorization'; _this._bearerPrefix = _this.sanitizeBearerPrefix(options.bearerPrefix); _this._silentRefresh = options.initOptions ? options.initOptions.flow === 'implicit' : false; _this._instance = Keycloak(options.config); _this.bindsKeycloakEvents(); _this._instance .init(/** @type {?} */ ((options.initOptions))) .success(function (authenticated) { return tslib_1.__awaiter(_this, void 0, void 0, function () { return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: if (!(authenticated && this._loadUserProfileAtStartUp)) return [3 /*break*/, 2]; return [4 /*yield*/, this.loadUserProfile()]; case 1: _a.sent(); _a.label = 2; case 2: resolve(authenticated); return [2 /*return*/]; } }); }); }) .error(function (error) { reject('An error happened during Keycloak initialization.'); }); }); }; /** * Redirects to login form on (options is an optional object with redirectUri and/or * prompt fields). * * @param options * Object, where: * - redirectUri: Specifies the uri to redirect to after login. * - prompt:By default the login screen is displayed if the user is not logged-in to Keycloak. * To only authenticate to the application if the user is already logged-in and not display the * login page if the user is not logged-in, set this option to none. To always require * re-authentication and ignore SSO, set this option to login . * - maxAge: Used just if user is already authenticated. Specifies maximum time since the * authentication of user happened. If user is already authenticated for longer time than * maxAge, the SSO is ignored and he will need to re-authenticate again. * - loginHint: Used to pre-fill the username/email field on the login form. * - action: If value is 'register' then user is redirected to registration page, otherwise to * login page. * - locale: Specifies the desired locale for the UI. * @returns * A void Promise if the login is successful and after the user profile loading. */ /** * Redirects to login form on (options is an optional object with redirectUri and/or * prompt fields). * * @param {?=} options * Object, where: * - redirectUri: Specifies the uri to redirect to after login. * - prompt:By default the login screen is displayed if the user is not logged-in to Keycloak. * To only authenticate to the application if the user is already logged-in and not display the * login page if the user is not logged-in, set this option to none. To always require * re-authentication and ignore SSO, set this option to login . * - maxAge: Used just if user is already authenticated. Specifies maximum time since the * authentication of user happened. If user is already authenticated for longer time than * maxAge, the SSO is ignored and he will need to re-authenticate again. * - loginHint: Used to pre-fill the username/email field on the login form. * - action: If value is 'register' then user is redirected to registration page, otherwise to * login page. * - locale: Specifies the desired locale for the UI. * @return {?} * A void Promise if the login is successful and after the user profile loading. */ KeycloakService.prototype.login = /** * Redirects to login form on (options is an optional object with redirectUri and/or * prompt fields). * * @param {?=} options * Object, where: * - redirectUri: Specifies the uri to redirect to after login. * - prompt:By default the login screen is displayed if the user is not logged-in to Keycloak. * To only authenticate to the application if the user is already logged-in and not display the * login page if the user is not logged-in, set this option to none. To always require * re-authentication and ignore SSO, set this option to login . * - maxAge: Used just if user is already authenticated. Specifies maximum time since the * authentication of user happened. If user is already authenticated for longer time than * maxAge, the SSO is ignored and he will need to re-authenticate again. * - loginHint: Used to pre-fill the username/email field on the login form. * - action: If value is 'register' then user is redirected to registration page, otherwise to * login page. * - locale: Specifies the desired locale for the UI. * @return {?} * A void Promise if the login is successful and after the user profile loading. */ function (options) { var _this = this; if (options === void 0) { options = {}; } return new Promise(function (resolve, reject) { _this._instance .login(options) .success(function () { return tslib_1.__awaiter(_this, void 0, void 0, function () { return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: if (!this._loadUserProfileAtStartUp) return [3 /*break*/, 2]; return [4 /*yield*/, this.loadUserProfile()]; case 1: _a.sent(); _a.label = 2; case 2: resolve(); return [2 /*return*/]; } }); }); }) .error(function (error) { reject('An error happened during the login.'); }); }); }; /** * Redirects to logout. * * @param redirectUri * Specifies the uri to redirect to after logout. * @returns * A void Promise if the logout was successful, cleaning also the userProfile. */ /** * Redirects to logout. * * @param {?=} redirectUri * Specifies the uri to redirect to after logout. * @return {?} * A void Promise if the logout was successful, cleaning also the userProfile. */ KeycloakService.prototype.logout = /** * Redirects to logout. * * @param {?=} redirectUri * Specifies the uri to redirect to after logout. * @return {?} * A void Promise if the logout was successful, cleaning also the userProfile. */ function (redirectUri) { var _this = this; return new Promise(function (resolve, reject) { /** @type {?} */ var options = { redirectUri: redirectUri }; _this._instance .logout(options) .success(function () { _this._userProfile = /** @type {?} */ ((undefined)); resolve(); }) .error(function (error) { reject('An error happened during logout.'); }); }); }; /** * Redirects to registration form. Shortcut for login with option * action = 'register'. Options are same as for the login method but 'action' is set to * 'register'. * * @param options * login options * @returns * A void Promise if the register flow was successful. */ /** * Redirects to registration form. Shortcut for login with option * action = 'register'. Options are same as for the login method but 'action' is set to * 'register'. * * @param {?=} options * login options * @return {?} * A void Promise if the register flow was successful. */ KeycloakService.prototype.register = /** * Redirects to registration form. Shortcut for login with option * action = 'register'. Options are same as for the login method but 'action' is set to * 'register'. * * @param {?=} options * login options * @return {?} * A void Promise if the register flow was successful. */ function (options) { var _this = this; if (options === void 0) { options = { action: 'register' }; } return new Promise(function (resolve, reject) { _this._instance .register(options) .success(function () { resolve(); }) .error(function () { reject('An error happened during the register execution'); }); }); }; /** * Check if the user has access to the specified role. It will look for roles in * realm and clientId, but will not check if the user is logged in for better performance. * * @param role * role name * @returns * A boolean meaning if the user has the specified Role. */ /** * Check if the user has access to the specified role. It will look for roles in * realm and clientId, but will not check if the user is logged in for better performance. * * @param {?} role * role name * @return {?} * A boolean meaning if the user has the specified Role. */ KeycloakService.prototype.isUserInRole = /** * Check if the user has access to the specified role. It will look for roles in * realm and clientId, but will not check if the user is logged in for better performance. * * @param {?} role * role name * @return {?} * A boolean meaning if the user has the specified Role. */ function (role) { /** @type {?} */ var hasRole; hasRole = this._instance.hasResourceRole(role); if (!hasRole) { hasRole = this._instance.hasRealmRole(role); } return hasRole; }; /** * Return the roles of the logged user. The allRoles parameter, with default value * true, will return the clientId and realm roles associated with the logged user. If set to false * it will only return the user roles associated with the clientId. * * @param allRoles * Flag to set if all roles should be returned.(Optional: default value is true) * @returns * Array of Roles associated with the logged user. */ /** * Return the roles of the logged user. The allRoles parameter, with default value * true, will return the clientId and realm roles associated with the logged user. If set to false * it will only return the user roles associated with the clientId. * * @param {?=} allRoles * Flag to set if all roles should be returned.(Optional: default value is true) * @return {?} * Array of Roles associated with the logged user. */ KeycloakService.prototype.getUserRoles = /** * Return the roles of the logged user. The allRoles parameter, with default value * true, will return the clientId and realm roles associated with the logged user. If set to false * it will only return the user roles associated with the clientId. * * @param {?=} allRoles * Flag to set if all roles should be returned.(Optional: default value is true) * @return {?} * Array of Roles associated with the logged user. */ function (allRoles) { if (allRoles === void 0) { allRoles = true; } /** @type {?} */ var roles = []; if (this._instance.resourceAccess) { for (var key in this._instance.resourceAccess) { if (this._instance.resourceAccess.hasOwnProperty(key)) { /** @type {?} */ var resourceAccess = this._instance.resourceAccess[key]; /** @type {?} */ var clientRoles = resourceAccess['roles'] || []; roles = roles.concat(clientRoles); } } } if (allRoles && this._instance.realmAccess) { /** @type {?} */ var realmRoles = this._instance.realmAccess['roles'] || []; roles.push.apply(roles, tslib_1.__spread(realmRoles)); } return roles; }; /** * Check if user is logged in. * * @returns * A boolean that indicates if the user is logged in. */ /** * Check if user is logged in. * * @return {?} * A boolean that indicates if the user is logged in. */ KeycloakService.prototype.isLoggedIn = /** * Check if user is logged in. * * @return {?} * A boolean that indicates if the user is logged in. */ function () { var _this = this; return new Promise(function (resolve, reject) { return tslib_1.__awaiter(_this, void 0, void 0, function () { var error_1; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: _a.trys.push([0, 2, , 3]); return [4 /*yield*/, this.updateToken(20)]; case 1: _a.sent(); resolve(true); return [3 /*break*/, 3]; case 2: error_1 = _a.sent(); resolve(false); return [3 /*break*/, 3]; case 3: return [2 /*return*/]; } }); }); }); }; /** * Returns true if the token has less than minValidity seconds left before * it expires. * * @param minValidity * Seconds left. (minValidity) is optional. Default value is 0. * @returns * Boolean indicating if the token is expired. */ /** * Returns true if the token has less than minValidity seconds left before * it expires. * * @param {?=} minValidity * Seconds left. (minValidity) is optional. Default value is 0. * @return {?} * Boolean indicating if the token is expired. */ KeycloakService.prototype.isTokenExpired = /** * Returns true if the token has less than minValidity seconds left before * it expires. * * @param {?=} minValidity * Seconds left. (minValidity) is optional. Default value is 0. * @return {?} * Boolean indicating if the token is expired. */ function (minValidity) { if (minValidity === void 0) { minValidity = 0; } return this._instance.isTokenExpired(minValidity); }; /** * If the token expires within minValidity seconds the token is refreshed. If the * session status iframe is enabled, the session status is also checked. * Returns a promise telling if the token was refreshed or not. If the session is not active * anymore, the promise is rejected. * * @param minValidity * Seconds left. (minValidity is optional, if not specified 5 is used) * @returns * Promise with a boolean indicating if the token was succesfully updated. */ /** * If the token expires within minValidity seconds the token is refreshed. If the * session status iframe is enabled, the session status is also checked. * Returns a promise telling if the token was refreshed or not. If the session is not active * anymore, the promise is rejected. * * @param {?=} minValidity * Seconds left. (minValidity is optional, if not specified 5 is used) * @return {?} * Promise with a boolean indicating if the token was succesfully updated. */ KeycloakService.prototype.updateToken = /** * If the token expires within minValidity seconds the token is refreshed. If the * session status iframe is enabled, the session status is also checked. * Returns a promise telling if the token was refreshed or not. If the session is not active * anymore, the promise is rejected. * * @param {?=} minValidity * Seconds left. (minValidity is optional, if not specified 5 is used) * @return {?} * Promise with a boolean indicating if the token was succesfully updated. */ function (minValidity) { var _this = this; if (minValidity === void 0) { minValidity = 5; } return new Promise(function (resolve, reject) { return tslib_1.__awaiter(_this, void 0, void 0, function () { return tslib_1.__generator(this, function (_a) { // TODO: this is a workaround until the silent refresh (issue #43) // is not implemented, avoiding the redirect loop. if (this._silentRefresh) { if (this.isTokenExpired()) { reject('Failed to refresh the token, or the session is expired'); } else { resolve(true); } return [2 /*return*/]; } if (!this._instance) { reject(); return [2 /*return*/]; } this._instance .updateToken(minValidity) .success(function (refreshed) { resolve(refreshed); }) .error(function (error) { reject('Failed to refresh the token, or the session is expired'); }); return [2 /*return*/]; }); }); }); }; /** * Loads the users profile. * Returns promise to set functions to be invoked if the profile was loaded successfully, or if * the profile could not be loaded. * * @param forceReload * If true will force the loadUserProfile even if its already loaded. * @returns * A promise with the KeycloakProfile data loaded. */ /** * Loads the users profile. * Returns promise to set functions to be invoked if the profile was loaded successfully, or if * the profile could not be loaded. * * @param {?=} forceReload * If true will force the loadUserProfile even if its already loaded. * @return {?} * A promise with the KeycloakProfile data loaded. */ KeycloakService.prototype.loadUserProfile = /** * Loads the users profile. * Returns promise to set functions to be invoked if the profile was loaded successfully, or if * the profile could not be loaded. * * @param {?=} forceReload * If true will force the loadUserProfile even if its already loaded. * @return {?} * A promise with the KeycloakProfile data loaded. */ function (forceReload) { var _this = this; if (forceReload === void 0) { forceReload = false; } return new Promise(function (resolve, reject) { return tslib_1.__awaiter(_this, void 0, void 0, function () { var _this = this; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: if (this._userProfile && !forceReload) { resolve(this._userProfile); return [2 /*return*/]; } return [4 /*yield*/, this.isLoggedIn()]; case 1: if (!(_a.sent())) { reject('The user profile was not loaded as the user is not logged in.'); return [2 /*return*/]; } this._instance .loadUserProfile() .success(function (result) { _this._userProfile = /** @type {?} */ (result); resolve(_this._userProfile); }) .error(function (err) { reject('The user profile could not be loaded.'); }); return [2 /*return*/]; } }); }); }); }; /** * Returns the authenticated token, calling updateToken to get a refreshed one if * necessary. If the session is expired this method calls the login method for a new login. * * @returns * Promise with the generated token. */ /** * Returns the authenticated token, calling updateToken to get a refreshed one if * necessary. If the session is expired this method calls the login method for a new login. * * @return {?} * Promise with the generated token. */ KeycloakService.prototype.getToken = /** * Returns the authenticated token, calling updateToken to get a refreshed one if * necessary. If the session is expired this method calls the login method for a new login. * * @return {?} * Promise with the generated token. */ function () { var _this = this; return new Promise(function (resolve, reject) { return tslib_1.__awaiter(_this, void 0, void 0, function () { var error_2; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: _a.trys.push([0, 2, , 3]); return [4 /*yield*/, this.updateToken(10)]; case 1: _a.sent(); resolve(this._instance.token); return [3 /*break*/, 3]; case 2: error_2 = _a.sent(); this.login(); return [3 /*break*/, 3]; case 3: return [2 /*return*/]; } }); }); }); }; /** * Returns the logged username. * * @returns * The logged username. */ /** * Returns the logged username. * * @return {?} * The logged username. */ KeycloakService.prototype.getUsername = /** * Returns the logged username. * * @return {?} * The logged username. */ function () { if (!this._userProfile) { throw new Error('User not logged in or user profile was not loaded.'); } return /** @type {?} */ ((this._userProfile.username)); }; /** * Clear authentication state, including tokens. This can be useful if application * has detected the session was expired, for example if updating token fails. * Invoking this results in onAuthLogout callback listener being invoked. */ /** * Clear authentication state, including tokens. This can be useful if application * has detected the session was expired, for example if updating token fails. * Invoking this results in onAuthLogout callback listener being invoked. * @return {?} */ KeycloakService.prototype.clearToken = /** * Clear authentication state, including tokens. This can be useful if application * has detected the session was expired, for example if updating token fails. * Invoking this results in onAuthLogout callback listener being invoked. * @return {?} */ function () { this._instance.clearToken(); }; /** * Adds a valid token in header. The key & value format is: * Authorization Bearer <token>. * If the headers param is undefined it will create the Angular headers object. * * @param headers * Updated header with Authorization and Keycloak token. * @returns * An observable with with the HTTP Authorization header and the current token. */ /** * Adds a valid token in header. The key & value format is: * Authorization Bearer <token>. * If the headers param is undefined it will create the Angular headers object. * * @param {?=} headersArg * @return {?} * An observable with with the HTTP Authorization header and the current token. */ KeycloakService.prototype.addTokenToHeader = /** * Adds a valid token in header. The key & value format is: * Authorization Bearer <token>. * If the headers param is undefined it will create the Angular headers object. * * @param {?=} headersArg * @return {?} * An observable with with the HTTP Authorization header and the current token. */ function (headersArg) { var _this = this; return Observable.create(function (observer) { return tslib_1.__awaiter(_this, void 0, void 0, function () { var headers, token, error_3; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: headers = headersArg; if (!headers) { headers = new HttpHeaders(); } _a.label = 1; case 1: _a.trys.push([1, 3, , 4]); return [4 /*yield*/, this.getToken()]; case 2: token = _a.sent(); headers = headers.set(this._authorizationHeaderName, this._bearerPrefix + token); observer.next(headers); observer.complete(); return [3 /*break*/, 4]; case 3: error_3 = _a.sent(); observer.error(error_3); return [3 /*break*/, 4]; case 4: return [2 /*return*/]; } }); }); }); }; /** * Returns the original Keycloak instance, if you need any customization that * this Angular service does not support yet. Use with caution. * * @returns * The KeycloakInstance from keycloak-js. */ /** * Returns the original Keycloak instance, if you need any customization that * this Angular service does not support yet. Use with caution. * * @return {?} * The KeycloakInstance from keycloak-js. */ KeycloakService.prototype.getKeycloakInstance = /** * Returns the original Keycloak instance, if you need any customization that * this Angular service does not support yet. Use with caution. * * @return {?} * The KeycloakInstance from keycloak-js. */ function () { return this._instance; }; Object.defineProperty(KeycloakService.prototype, "bearerExcludedUrls", { /** * Returns the excluded URLs that should not be considered by * the http interceptor which automatically adds the authorization header in the Http Request. * * @returns * The excluded urls that must not be intercepted by the KeycloakBearerInterceptor. */ get: /** * Returns the excluded URLs that should not be considered by * the http interceptor which automatically adds the authorization header in the Http Request. * * @return {?} * The excluded urls that must not be intercepted by the KeycloakBearerInterceptor. */ function () { return this._bearerExcludedUrls; }, enumerable: true, configurable: true }); Object.defineProperty(KeycloakService.prototype, "enableBearerInterceptor", { /** * Flag to indicate if the bearer will be added to the authorization header. * * @returns * Returns if the bearer interceptor was set to be disabled. */ get: /** * Flag to indicate if the bearer will be added to the authorization header. * * @return {?} * Returns if the bearer interceptor was set to be disabled. */ function () { return this._enableBearerInterceptor; }, enumerable: true, configurable: true }); Object.defineProperty(KeycloakService.prototype, "keycloakEvents$", { /** * Keycloak subject to monitor the events triggered by keycloak-js. * The following events as available (as described at keycloak docs - * https://www.keycloak.org/docs/latest/securing_apps/index.html#callback-events): * - OnAuthError * - OnAuthLogout * - OnAuthRefreshError * - OnAuthRefreshSuccess * - OnAuthSuccess * - OnReady * - OnTokenExpire * In each occurrence of any of these, this subject will return the event type, * described at {@link KeycloakEventType} enum and the function args from the keycloak-js * if provided any. * * @returns * A subject with the {@link KeycloakEvent} which describes the event type and attaches the * function args. */ get: /** * Keycloak subject to monitor the events triggered by keycloak-js. * The following events as available (as described at keycloak docs - * https://www.keycloak.org/docs/latest/securing_apps/index.html#callback-events): * - OnAuthError * - OnAuthLogout * - OnAuthRefreshError * - OnAuthRefreshSuccess * - OnAuthSuccess * - OnReady * - OnTokenExpire * In each occurrence of any of these, this subject will return the event type, * described at {\@link KeycloakEventType} enum and the function args from the keycloak-js * if provided any. * * @return {?} * A subject with the {\@link KeycloakEvent} which describes the event type and attaches the * function args. */ function () { return this._keycloakEvents$; }, enumerable: true, configurable: true }); KeycloakService.decorators = [ { type: Injectable }, ]; /** @nocollapse */ KeycloakService.ctorParameters = function () { return []; }; return KeycloakService; }()); export { KeycloakService }; function KeycloakService_tsickle_Closure_declarations() { /** * Keycloak-js instance. * @type {?} */ KeycloakService.prototype._instance; /** * User profile as KeycloakProfile interface. * @type {?} */ KeycloakService.prototype._userProfile; /** * Flag to indicate if the bearer will not be added to the authorization header. * @type {?} */ KeycloakService.prototype._enableBearerInterceptor; /** * When the implicit flow is choosen there must exist a silentRefresh, as there is * no refresh token. * @type {?} */ KeycloakService.prototype._silentRefresh; /** * Indicates that the user profile should be loaded at the keycloak initialization, * just after the login. * @type {?} */ KeycloakService.prototype._loadUserProfileAtStartUp; /** * The bearer prefix that will be appended to the Authorization Header. * @type {?} */ KeycloakService.prototype._bearerPrefix; /** * Value that will be used as the Authorization Http Header name. * @type {?} */ KeycloakService.prototype._authorizationHeaderName; /** * The excluded urls patterns that must skip the KeycloakBearerInterceptor. * @type {?} */ KeycloakService.prototype._bearerExcludedUrls; /** * Observer for the keycloak events * @type {?} */ KeycloakService.prototype._keycloakEvents$; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoia2V5Y2xvYWsuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiJuZzovL2tleWNsb2FrLWFuZ3VsYXIvIiwic291cmNlcyI6WyJsaWIvY29yZS9zZXJ2aWNlcy9rZXljbG9hay5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7OztBQVFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFM0MsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBR25ELE9BQU8sS0FBSyxTQUFTLE1BQU0sYUFBYSxDQUFDOztBQUN6QyxXQUFhLFFBQVEsR0FBRyxTQUFTLENBQUM7QUFFbEMsT0FBTyxFQUFFLFVBQVUsRUFBWSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFHckQsT0FBTyxFQUFpQixpQkFBaUIsRUFBRSxNQUFNLDhCQUE4QixDQUFDOzs7Ozs7Ozs7SUFrRDlFO1FBQ0UsSUFBSSxDQUFDLGdCQUFnQixHQUFHLElBQUksT0FBTyxFQUFpQixDQUFDO0tBQ3REOzs7Ozs7Ozs7Ozs7O0lBY08sOENBQW9COzs7Ozs7Ozs7Ozs7Y0FBQyxZQUFnQzs7UUFDM0QsSUFBSSxNQUFNLEdBQVcsQ0FBQyxZQUFZLElBQUksUUFBUSxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDdkQsTUFBTSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7Ozs7Ozs7O0lBUXBCLDJDQUFpQjs7Ozs7O2NBQUMsS0FBYzs7UUFDdEMsSUFBSSxXQUFXLEdBQVksS0FBSyxDQUFDO1FBQ2pDLEVBQUUsQ0FBQyxDQUFDLFdBQVcsS0FBSyxTQUFTLElBQUksV0FBVyxLQUFLLElBQUksQ0FBQyxDQUFDLENBQUM7WUFDdEQsV0FBVyxHQUFHLElBQUksQ0FBQztTQUNwQjtRQUNELE1BQU0sQ0FBQyxXQUFXLENBQUM7Ozs7Ozs7Ozs7SUFVYiw2Q0FBbUI7Ozs7Ozs7Ozs7UUFDekIsRUFBRSxDQUFDLENBQUMsQ0FBQyxJ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