{"version":3,"sources":["node_modules/angular-oauth2-oidc/fesm2020/angular-oauth2-oidc.mjs","src/app/auth-models/auth.model.ts","src/app/auth-models/user.model.ts","src/app/auth-services/app-auth.service.ts"],"sourcesContent":["import * as i0 from '@angular/core';\nimport { Injectable, Optional, Inject, makeEnvironmentProviders, NgModule, InjectionToken } from '@angular/core';\nimport { DOCUMENT, CommonModule } from '@angular/common';\nimport * as i1 from '@angular/common/http';\nimport { HttpHeaders, HttpParams, HTTP_INTERCEPTORS } from '@angular/common/http';\nimport { Subject, of, from, race, throwError, combineLatest, merge } from 'rxjs';\nimport { filter, tap, debounceTime, delay, switchMap, map, first, catchError, timeout, take, mergeMap } from 'rxjs/operators';\n\n/**\r\n * A validation handler that isn't validating nothing.\r\n * Can be used to skip validation (at your own risk).\r\n */\nclass NullValidationHandler {\n validateSignature(validationParams) {\n return Promise.resolve(null);\n }\n validateAtHash(validationParams) {\n return Promise.resolve(true);\n }\n}\nclass OAuthModuleConfig {}\nclass OAuthResourceServerConfig {}\nclass DateTimeProvider {}\nlet SystemDateTimeProvider = /*#__PURE__*/(() => {\n class SystemDateTimeProvider extends DateTimeProvider {\n now() {\n return Date.now();\n }\n new() {\n return new Date();\n }\n }\n SystemDateTimeProvider.ɵfac = /* @__PURE__ */(() => {\n let ɵSystemDateTimeProvider_BaseFactory;\n return function SystemDateTimeProvider_Factory(t) {\n return (ɵSystemDateTimeProvider_BaseFactory || (ɵSystemDateTimeProvider_BaseFactory = i0.ɵɵgetInheritedFactory(SystemDateTimeProvider)))(t || SystemDateTimeProvider);\n };\n })();\n SystemDateTimeProvider.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n token: SystemDateTimeProvider,\n factory: SystemDateTimeProvider.ɵfac\n });\n return SystemDateTimeProvider;\n})();\n(() => {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n\n/**\r\n * Additional options that can be passed to tryLogin.\r\n */\nclass LoginOptions {\n constructor() {\n /**\r\n * Set this to true to disable the nonce\r\n * check which is used to avoid\r\n * replay attacks.\r\n * This flag should never be true in\r\n * production environments.\r\n */\n this.disableNonceCheck = false;\n /**\r\n * Normally, you want to clear your hash fragment after\r\n * the lib read the token(s) so that they are not displayed\r\n * anymore in the url. If not, set this to true. For code flow\r\n * this controls removing query string values.\r\n */\n this.preventClearHashAfterLogin = false;\n }\n}\n/**\r\n * Defines the logging interface the OAuthService uses\r\n * internally. Is compatible with the `console` object,\r\n * but you can provide your own implementation as well\r\n * through dependency injection.\r\n */\nclass OAuthLogger {}\n/**\r\n * Defines a simple storage that can be used for\r\n * storing the tokens at client side.\r\n * Is compatible to localStorage and sessionStorage,\r\n * but you can also create your own implementations.\r\n */\nclass OAuthStorage {}\nlet MemoryStorage = /*#__PURE__*/(() => {\n class MemoryStorage {\n constructor() {\n this.data = new Map();\n }\n getItem(key) {\n return this.data.get(key);\n }\n removeItem(key) {\n this.data.delete(key);\n }\n setItem(key, data) {\n this.data.set(key, data);\n }\n }\n MemoryStorage.ɵfac = function MemoryStorage_Factory(t) {\n return new (t || MemoryStorage)();\n };\n MemoryStorage.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n token: MemoryStorage,\n factory: MemoryStorage.ɵfac\n });\n return MemoryStorage;\n})();\n(() => {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\r\n * Represents the received tokens, the received state\r\n * and the parsed claims from the id-token.\r\n */\nclass ReceivedTokens {}\nclass OAuthEvent {\n constructor(type) {\n this.type = type;\n }\n}\nclass OAuthSuccessEvent extends OAuthEvent {\n constructor(type, info = null) {\n super(type);\n this.info = info;\n }\n}\nclass OAuthInfoEvent extends OAuthEvent {\n constructor(type, info = null) {\n super(type);\n this.info = info;\n }\n}\nclass OAuthErrorEvent extends OAuthEvent {\n constructor(type, reason, params = null) {\n super(type);\n this.reason = reason;\n this.params = params;\n }\n}\n\n// see: https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/Base64_encoding_and_decoding#The_.22Unicode_Problem.22\nfunction b64DecodeUnicode(str) {\n const base64 = str.replace(/\\-/g, '+').replace(/\\_/g, '/');\n return decodeURIComponent(atob(base64).split('').map(function (c) {\n return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);\n }).join(''));\n}\nfunction base64UrlEncode(str) {\n const base64 = btoa(str);\n return base64.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, '');\n}\nclass AuthConfig {\n constructor(json) {\n /**\r\n * The client's id as registered with the auth server\r\n */\n this.clientId = '';\n /**\r\n * The client's redirectUri as registered with the auth server\r\n */\n this.redirectUri = '';\n /**\r\n * An optional second redirectUri where the auth server\r\n * redirects the user to after logging out.\r\n */\n this.postLogoutRedirectUri = '';\n /**\r\n * Defines whether to use 'redirectUri' as a replacement\r\n * of 'postLogoutRedirectUri' if the latter is not set.\r\n */\n this.redirectUriAsPostLogoutRedirectUriFallback = true;\n /**\r\n * The auth server's endpoint that allows to log\r\n * the user in when using implicit flow.\r\n */\n this.loginUrl = '';\n /**\r\n * The requested scopes\r\n */\n this.scope = 'openid profile';\n this.resource = '';\n this.rngUrl = '';\n /**\r\n * Defines whether to use OpenId Connect during\r\n * implicit flow.\r\n */\n this.oidc = true;\n /**\r\n * Defines whether to request an access token during\r\n * implicit flow.\r\n */\n this.requestAccessToken = true;\n this.options = null;\n /**\r\n * The issuer's uri.\r\n */\n this.issuer = '';\n /**\r\n * The logout url.\r\n */\n this.logoutUrl = '';\n /**\r\n * Defines whether to clear the hash fragment after logging in.\r\n */\n this.clearHashAfterLogin = true;\n /**\r\n * Url of the token endpoint as defined by OpenId Connect and OAuth 2.\r\n */\n this.tokenEndpoint = null;\n /**\r\n * Url of the revocation endpoint as defined by OpenId Connect and OAuth 2.\r\n */\n this.revocationEndpoint = null;\n /**\r\n * Names of known parameters sent out in the TokenResponse. https://tools.ietf.org/html/rfc6749#section-5.1\r\n */\n this.customTokenParameters = [];\n /**\r\n * Url of the userinfo endpoint as defined by OpenId Connect.\r\n */\n this.userinfoEndpoint = null;\n this.responseType = '';\n /**\r\n * Defines whether additional debug information should\r\n * be shown at the console. Note that in certain browsers\r\n * the verbosity of the console needs to be explicitly set\r\n * to include Debug level messages.\r\n */\n this.showDebugInformation = false;\n /**\r\n * The redirect uri used when doing silent refresh.\r\n */\n this.silentRefreshRedirectUri = '';\n this.silentRefreshMessagePrefix = '';\n /**\r\n * Set this to true to display the iframe used for\r\n * silent refresh for debugging.\r\n */\n this.silentRefreshShowIFrame = false;\n /**\r\n * Timeout for silent refresh.\r\n * @internal\r\n * depreacted b/c of typo, see silentRefreshTimeout\r\n */\n this.siletRefreshTimeout = 1000 * 20;\n /**\r\n * Timeout for silent refresh.\r\n */\n this.silentRefreshTimeout = 1000 * 20;\n /**\r\n * Some auth servers don't allow using password flow\r\n * w/o a client secret while the standards do not\r\n * demand for it. In this case, you can set a password\r\n * here. As this password is exposed to the public\r\n * it does not bring additional security and is therefore\r\n * as good as using no password.\r\n */\n this.dummyClientSecret = '';\n /**\r\n * Defines whether https is required.\r\n * The default value is remoteOnly which only allows\r\n * http for localhost, while every other domains need\r\n * to be used with https.\r\n */\n this.requireHttps = 'remoteOnly';\n /**\r\n * Defines whether every url provided by the discovery\r\n * document has to start with the issuer's url.\r\n */\n this.strictDiscoveryDocumentValidation = true;\n /**\r\n * JSON Web Key Set (https://tools.ietf.org/html/rfc7517)\r\n * with keys used to validate received id_tokens.\r\n * This is taken out of the disovery document. Can be set manually too.\r\n */\n this.jwks = null;\n /**\r\n * Map with additional query parameter that are appended to\r\n * the request when initializing implicit flow.\r\n */\n this.customQueryParams = null;\n this.silentRefreshIFrameName = 'angular-oauth-oidc-silent-refresh-iframe';\n /**\r\n * Defines when the token_timeout event should be raised.\r\n * If you set this to the default value 0.75, the event\r\n * is triggered after 75% of the token's life time.\r\n */\n this.timeoutFactor = 0.75;\n /**\r\n * If true, the lib will try to check whether the user\r\n * is still logged in on a regular basis as described\r\n * in http://openid.net/specs/openid-connect-session-1_0.html#ChangeNotification\r\n */\n this.sessionChecksEnabled = false;\n /**\r\n * Interval in msec for checking the session\r\n * according to http://openid.net/specs/openid-connect-session-1_0.html#ChangeNotification\r\n */\n this.sessionCheckIntervall = 3 * 1000;\n /**\r\n * Url for the iframe used for session checks\r\n */\n this.sessionCheckIFrameUrl = null;\n /**\r\n * Name of the iframe to use for session checks\r\n */\n this.sessionCheckIFrameName = 'angular-oauth-oidc-check-session-iframe';\n /**\r\n * This property has been introduced to disable at_hash checks\r\n * and is indented for Identity Provider that does not deliver\r\n * an at_hash EVEN THOUGH its recommended by the OIDC specs.\r\n * Of course, when disabling these checks then we are bypassing\r\n * a security check which means we are more vulnerable.\r\n */\n this.disableAtHashCheck = false;\n /**\r\n * Defines wether to check the subject of a refreshed token after silent refresh.\r\n * Normally, it should be the same as before.\r\n */\n this.skipSubjectCheck = false;\n this.useIdTokenHintForSilentRefresh = false;\n /**\r\n * Defined whether to skip the validation of the issuer in the discovery document.\r\n * Normally, the discovey document's url starts with the url of the issuer.\r\n */\n this.skipIssuerCheck = false;\n /**\r\n * final state sent to issuer is built as follows:\r\n * state = nonce + nonceStateSeparator + additional state\r\n * Default separator is ';' (encoded %3B).\r\n * In rare cases, this character might be forbidden or inconvenient to use by the issuer so it can be customized.\r\n */\n this.nonceStateSeparator = ';';\n /**\r\n * Set this to true to use HTTP BASIC auth for AJAX calls\r\n */\n this.useHttpBasicAuth = false;\n /**\r\n * Decreases the Expiration time of tokens by this number of seconds\r\n */\n this.decreaseExpirationBySec = 0;\n /**\r\n * The interceptors waits this time span if there is no token\r\n */\n this.waitForTokenInMsec = 0;\n /**\r\n * Code Flow is by defauld used together with PKCI which is also higly recommented.\r\n * You can disbale it here by setting this flag to true.\r\n * https://tools.ietf.org/html/rfc7636#section-1.1\r\n */\n this.disablePKCE = false;\n /**\r\n * Set this to true to preserve the requested route including query parameters after code flow login.\r\n * This setting enables deep linking for the code flow.\r\n */\n this.preserveRequestedRoute = false;\n /**\r\n * Allows to disable the timer for the id_token used\r\n * for token refresh\r\n */\n this.disableIdTokenTimer = false;\n /**\r\n * Blocks other origins requesting a silent refresh\r\n */\n this.checkOrigin = false;\n /**\r\n * This property allows you to override the method that is used to open the login url,\r\n * allowing a way for implementations to specify their own method of routing to new\r\n * urls.\r\n */\n this.openUri = uri => {\n location.href = uri;\n };\n if (json) {\n Object.assign(this, json);\n }\n }\n}\n\n/**\r\n * This custom encoder allows charactes like +, % and / to be used in passwords\r\n */\nclass WebHttpUrlEncodingCodec {\n encodeKey(k) {\n return encodeURIComponent(k);\n }\n encodeValue(v) {\n return encodeURIComponent(v);\n }\n decodeKey(k) {\n return decodeURIComponent(k);\n }\n decodeValue(v) {\n return decodeURIComponent(v);\n }\n}\n\n/**\r\n * Interface for Handlers that are hooked in to\r\n * validate tokens.\r\n */\nclass ValidationHandler {}\n/**\r\n * This abstract implementation of ValidationHandler already implements\r\n * the method validateAtHash. However, to make use of it,\r\n * you have to override the method calcHash.\r\n */\nclass AbstractValidationHandler {\n /**\r\n * Validates the at_hash in an id_token against the received access_token.\r\n */\n async validateAtHash(params) {\n let hashAlg = this.inferHashAlgorithm(params.idTokenHeader);\n let tokenHash = await this.calcHash(params.accessToken, hashAlg); // sha256(accessToken, { asString: true });\n let leftMostHalf = tokenHash.substr(0, tokenHash.length / 2);\n let atHash = base64UrlEncode(leftMostHalf);\n let claimsAtHash = params.idTokenClaims['at_hash'].replace(/=/g, '');\n if (atHash !== claimsAtHash) {\n console.error('exptected at_hash: ' + atHash);\n console.error('actual at_hash: ' + claimsAtHash);\n }\n return atHash === claimsAtHash;\n }\n /**\r\n * Infers the name of the hash algorithm to use\r\n * from the alg field of an id_token.\r\n *\r\n * @param jwtHeader the id_token's parsed header\r\n */\n inferHashAlgorithm(jwtHeader) {\n let alg = jwtHeader['alg'];\n if (!alg.match(/^.S[0-9]{3}$/)) {\n throw new Error('Algorithm not supported: ' + alg);\n }\n return 'sha-' + alg.substr(2);\n }\n}\nlet UrlHelperService = /*#__PURE__*/(() => {\n class UrlHelperService {\n getHashFragmentParams(customHashFragment) {\n let hash = customHashFragment || window.location.hash;\n hash = decodeURIComponent(hash);\n if (hash.indexOf('#') !== 0) {\n return {};\n }\n const questionMarkPosition = hash.indexOf('?');\n if (questionMarkPosition > -1) {\n hash = hash.substr(questionMarkPosition + 1);\n } else {\n hash = hash.substr(1);\n }\n return this.parseQueryString(hash);\n }\n parseQueryString(queryString) {\n const data = {};\n let pairs, pair, separatorIndex, escapedKey, escapedValue, key, value;\n if (queryString === null) {\n return data;\n }\n pairs = queryString.split('&');\n for (let i = 0; i < pairs.length; i++) {\n pair = pairs[i];\n separatorIndex = pair.indexOf('=');\n if (separatorIndex === -1) {\n escapedKey = pair;\n escapedValue = null;\n } else {\n escapedKey = pair.substr(0, separatorIndex);\n escapedValue = pair.substr(separatorIndex + 1);\n }\n key = decodeURIComponent(escapedKey);\n value = decodeURIComponent(escapedValue);\n if (key.substr(0, 1) === '/') {\n key = key.substr(1);\n }\n data[key] = value;\n }\n return data;\n }\n }\n UrlHelperService.ɵfac = function UrlHelperService_Factory(t) {\n return new (t || UrlHelperService)();\n };\n UrlHelperService.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n token: UrlHelperService,\n factory: UrlHelperService.ɵfac\n });\n return UrlHelperService;\n})();\n(() => {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n\n// Credits: https://github.com/dchest/fast-sha256-js/tree/master/src\n// We add this lib directly b/c the published version of fast-sha256-js\n// is commonjs and hence leads to a warning about tree-shakability emitted\n// by the Angular CLI\n// SHA-256 (+ HMAC and PBKDF2) for JavaScript.\n//\n// Written in 2014-2016 by Dmitry Chestnykh.\n// Public domain, no warranty.\n//\n// Functions (accept and return Uint8Arrays):\n//\n// sha256(message) -> hash\n// sha256.hmac(key, message) -> mac\n// sha256.pbkdf2(password, salt, rounds, dkLen) -> dk\n//\n// Classes:\n//\n// new sha256.Hash()\n// new sha256.HMAC(key)\n//\nconst digestLength = 32;\nconst blockSize = 64;\n// SHA-256 constants\nconst K = new Uint32Array([0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2]);\nfunction hashBlocks(w, v, p, pos, len) {\n let a, b, c, d, e, f, g, h, u, i, j, t1, t2;\n while (len >= 64) {\n a = v[0];\n b = v[1];\n c = v[2];\n d = v[3];\n e = v[4];\n f = v[5];\n g = v[6];\n h = v[7];\n for (i = 0; i < 16; i++) {\n j = pos + i * 4;\n w[i] = (p[j] & 0xff) << 24 | (p[j + 1] & 0xff) << 16 | (p[j + 2] & 0xff) << 8 | p[j + 3] & 0xff;\n }\n for (i = 16; i < 64; i++) {\n u = w[i - 2];\n t1 = (u >>> 17 | u << 32 - 17) ^ (u >>> 19 | u << 32 - 19) ^ u >>> 10;\n u = w[i - 15];\n t2 = (u >>> 7 | u << 32 - 7) ^ (u >>> 18 | u << 32 - 18) ^ u >>> 3;\n w[i] = (t1 + w[i - 7] | 0) + (t2 + w[i - 16] | 0);\n }\n for (i = 0; i < 64; i++) {\n t1 = (((e >>> 6 | e << 32 - 6) ^ (e >>> 11 | e << 32 - 11) ^ (e >>> 25 | e << 32 - 25)) + (e & f ^ ~e & g) | 0) + (h + (K[i] + w[i] | 0) | 0) | 0;\n t2 = ((a >>> 2 | a << 32 - 2) ^ (a >>> 13 | a << 32 - 13) ^ (a >>> 22 | a << 32 - 22)) + (a & b ^ a & c ^ b & c) | 0;\n h = g;\n g = f;\n f = e;\n e = d + t1 | 0;\n d = c;\n c = b;\n b = a;\n a = t1 + t2 | 0;\n }\n v[0] += a;\n v[1] += b;\n v[2] += c;\n v[3] += d;\n v[4] += e;\n v[5] += f;\n v[6] += g;\n v[7] += h;\n pos += 64;\n len -= 64;\n }\n return pos;\n}\n// Hash implements SHA256 hash algorithm.\nclass Hash {\n constructor() {\n this.digestLength = digestLength;\n this.blockSize = blockSize;\n // Note: Int32Array is used instead of Uint32Array for performance reasons.\n this.state = new Int32Array(8); // hash state\n this.temp = new Int32Array(64); // temporary state\n this.buffer = new Uint8Array(128); // buffer for data to hash\n this.bufferLength = 0; // number of bytes in buffer\n this.bytesHashed = 0; // number of total bytes hashed\n this.finished = false; // indicates whether the hash was finalized\n this.reset();\n }\n // Resets hash state making it possible\n // to re-use this instance to hash other data.\n reset() {\n this.state[0] = 0x6a09e667;\n this.state[1] = 0xbb67ae85;\n this.state[2] = 0x3c6ef372;\n this.state[3] = 0xa54ff53a;\n this.state[4] = 0x510e527f;\n this.state[5] = 0x9b05688c;\n this.state[6] = 0x1f83d9ab;\n this.state[7] = 0x5be0cd19;\n this.bufferLength = 0;\n this.bytesHashed = 0;\n this.finished = false;\n return this;\n }\n // Cleans internal buffers and re-initializes hash state.\n clean() {\n for (let i = 0; i < this.buffer.length; i++) {\n this.buffer[i] = 0;\n }\n for (let i = 0; i < this.temp.length; i++) {\n this.temp[i] = 0;\n }\n this.reset();\n }\n // Updates hash state with the given data.\n //\n // Optionally, length of the data can be specified to hash\n // fewer bytes than data.length.\n //\n // Throws error when trying to update already finalized hash:\n // instance must be reset to use it again.\n update(data, dataLength = data.length) {\n if (this.finished) {\n throw new Error(\"SHA256: can't update because hash was finished.\");\n }\n let dataPos = 0;\n this.bytesHashed += dataLength;\n if (this.bufferLength > 0) {\n while (this.bufferLength < 64 && dataLength > 0) {\n this.buffer[this.bufferLength++] = data[dataPos++];\n dataLength--;\n }\n if (this.bufferLength === 64) {\n hashBlocks(this.temp, this.state, this.buffer, 0, 64);\n this.bufferLength = 0;\n }\n }\n if (dataLength >= 64) {\n dataPos = hashBlocks(this.temp, this.state, data, dataPos, dataLength);\n dataLength %= 64;\n }\n while (dataLength > 0) {\n this.buffer[this.bufferLength++] = data[dataPos++];\n dataLength--;\n }\n return this;\n }\n // Finalizes hash state and puts hash into out.\n //\n // If hash was already finalized, puts the same value.\n finish(out) {\n if (!this.finished) {\n const bytesHashed = this.bytesHashed;\n const left = this.bufferLength;\n const bitLenHi = bytesHashed / 0x20000000 | 0;\n const bitLenLo = bytesHashed << 3;\n const padLength = bytesHashed % 64 < 56 ? 64 : 128;\n this.buffer[left] = 0x80;\n for (let i = left + 1; i < padLength - 8; i++) {\n this.buffer[i] = 0;\n }\n this.buffer[padLength - 8] = bitLenHi >>> 24 & 0xff;\n this.buffer[padLength - 7] = bitLenHi >>> 16 & 0xff;\n this.buffer[padLength - 6] = bitLenHi >>> 8 & 0xff;\n this.buffer[padLength - 5] = bitLenHi >>> 0 & 0xff;\n this.buffer[padLength - 4] = bitLenLo >>> 24 & 0xff;\n this.buffer[padLength - 3] = bitLenLo >>> 16 & 0xff;\n this.buffer[padLength - 2] = bitLenLo >>> 8 & 0xff;\n this.buffer[padLength - 1] = bitLenLo >>> 0 & 0xff;\n hashBlocks(this.temp, this.state, this.buffer, 0, padLength);\n this.finished = true;\n }\n for (let i = 0; i < 8; i++) {\n out[i * 4 + 0] = this.state[i] >>> 24 & 0xff;\n out[i * 4 + 1] = this.state[i] >>> 16 & 0xff;\n out[i * 4 + 2] = this.state[i] >>> 8 & 0xff;\n out[i * 4 + 3] = this.state[i] >>> 0 & 0xff;\n }\n return this;\n }\n // Returns the final hash digest.\n digest() {\n const out = new Uint8Array(this.digestLength);\n this.finish(out);\n return out;\n }\n // Internal function for use in HMAC for optimization.\n _saveState(out) {\n for (let i = 0; i < this.state.length; i++) {\n out[i] = this.state[i];\n }\n }\n // Internal function for use in HMAC for optimization.\n _restoreState(from, bytesHashed) {\n for (let i = 0; i < this.state.length; i++) {\n this.state[i] = from[i];\n }\n this.bytesHashed = bytesHashed;\n this.finished = false;\n this.bufferLength = 0;\n }\n}\n// HMAC implements HMAC-SHA256 message authentication algorithm.\nclass HMAC {\n constructor(key) {\n this.inner = new Hash();\n this.outer = new Hash();\n this.blockSize = this.inner.blockSize;\n this.digestLength = this.inner.digestLength;\n const pad = new Uint8Array(this.blockSize);\n if (key.length > this.blockSize) {\n new Hash().update(key).finish(pad).clean();\n } else {\n for (let i = 0; i < key.length; i++) {\n pad[i] = key[i];\n }\n }\n for (let i = 0; i < pad.length; i++) {\n pad[i] ^= 0x36;\n }\n this.inner.update(pad);\n for (let i = 0; i < pad.length; i++) {\n pad[i] ^= 0x36 ^ 0x5c;\n }\n this.outer.update(pad);\n this.istate = new Uint32Array(8);\n this.ostate = new Uint32Array(8);\n this.inner._saveState(this.istate);\n this.outer._saveState(this.ostate);\n for (let i = 0; i < pad.length; i++) {\n pad[i] = 0;\n }\n }\n // Returns HMAC state to the state initialized with key\n // to make it possible to run HMAC over the other data with the same\n // key without creating a new instance.\n reset() {\n this.inner._restoreState(this.istate, this.inner.blockSize);\n this.outer._restoreState(this.ostate, this.outer.blockSize);\n return this;\n }\n // Cleans HMAC state.\n clean() {\n for (let i = 0; i < this.istate.length; i++) {\n this.ostate[i] = this.istate[i] = 0;\n }\n this.inner.clean();\n this.outer.clean();\n }\n // Updates state with provided data.\n update(data) {\n this.inner.update(data);\n return this;\n }\n // Finalizes HMAC and puts the result in out.\n finish(out) {\n if (this.outer.finished) {\n this.outer.finish(out);\n } else {\n this.inner.finish(out);\n this.outer.update(out, this.digestLength).finish(out);\n }\n return this;\n }\n // Returns message authentication code.\n digest() {\n const out = new Uint8Array(this.digestLength);\n this.finish(out);\n return out;\n }\n}\n// Returns SHA256 hash of data.\nfunction hash(data) {\n const h = new Hash().update(data);\n const digest = h.digest();\n h.clean();\n return digest;\n}\n// Returns HMAC-SHA256 of data under the key.\nfunction hmac(key, data) {\n const h = new HMAC(key).update(data);\n const digest = h.digest();\n h.clean();\n return digest;\n}\n// Fills hkdf buffer like this:\n// T(1) = HMAC-Hash(PRK, T(0) | info | 0x01)\nfunction fillBuffer(buffer, hmac, info, counter) {\n // Counter is a byte value: check if it overflowed.\n const num = counter[0];\n if (num === 0) {\n throw new Error('hkdf: cannot expand more');\n }\n // Prepare HMAC instance for new data with old key.\n hmac.reset();\n // Hash in previous output if it was generated\n // (i.e. counter is greater than 1).\n if (num > 1) {\n hmac.update(buffer);\n }\n // Hash in info if it exists.\n if (info) {\n hmac.update(info);\n }\n // Hash in the counter.\n hmac.update(counter);\n // Output result to buffer and clean HMAC instance.\n hmac.finish(buffer);\n // Increment counter inside typed array, this works properly.\n counter[0]++;\n}\nconst hkdfSalt = new Uint8Array(digestLength); // Filled with zeroes.\nfunction hkdf(key, salt = hkdfSalt, info, length = 32) {\n const counter = new Uint8Array([1]);\n // HKDF-Extract uses salt as HMAC key, and key as data.\n const okm = hmac(salt, key);\n // Initialize HMAC for expanding with extracted key.\n // Ensure no collisions with `hmac` function.\n const hmac_ = new HMAC(okm);\n // Allocate buffer.\n const buffer = new Uint8Array(hmac_.digestLength);\n let bufpos = buffer.length;\n const out = new Uint8Array(length);\n for (let i = 0; i < length; i++) {\n if (bufpos === buffer.length) {\n fillBuffer(buffer, hmac_, info, counter);\n bufpos = 0;\n }\n out[i] = buffer[bufpos++];\n }\n hmac_.clean();\n buffer.fill(0);\n counter.fill(0);\n return out;\n}\n// Derives a key from password and salt using PBKDF2-HMAC-SHA256\n// with the given number of iterations.\n//\n// The number of bytes returned is equal to dkLen.\n//\n// (For better security, avoid dkLen greater than hash length - 32 bytes).\nfunction pbkdf2(password, salt, iterations, dkLen) {\n const prf = new HMAC(password);\n const len = prf.digestLength;\n const ctr = new Uint8Array(4);\n const t = new Uint8Array(len);\n const u = new Uint8Array(len);\n const dk = new Uint8Array(dkLen);\n for (let i = 0; i * len < dkLen; i++) {\n let c = i + 1;\n ctr[0] = c >>> 24 & 0xff;\n ctr[1] = c >>> 16 & 0xff;\n ctr[2] = c >>> 8 & 0xff;\n ctr[3] = c >>> 0 & 0xff;\n prf.reset();\n prf.update(salt);\n prf.update(ctr);\n prf.finish(u);\n for (let j = 0; j < len; j++) {\n t[j] = u[j];\n }\n for (let j = 2; j <= iterations; j++) {\n prf.reset();\n prf.update(u).finish(u);\n for (let k = 0; k < len; k++) {\n t[k] ^= u[k];\n }\n }\n for (let j = 0; j < len && i * len + j < dkLen; j++) {\n dk[i * len + j] = t[j];\n }\n }\n for (let i = 0; i < len; i++) {\n t[i] = u[i] = 0;\n }\n for (let i = 0; i < 4; i++) {\n ctr[i] = 0;\n }\n prf.clean();\n return dk;\n}\n\n/**\r\n * Abstraction for crypto algorithms\r\n */\nclass HashHandler {}\nfunction decodeUTF8(s) {\n if (typeof s !== 'string') throw new TypeError('expected string');\n var i,\n d = s,\n b = new Uint8Array(d.length);\n for (i = 0; i < d.length; i++) b[i] = d.charCodeAt(i);\n return b;\n}\nfunction encodeUTF8(arr) {\n var i,\n s = [];\n for (i = 0; i < arr.length; i++) s.push(String.fromCharCode(arr[i]));\n return s.join('');\n}\nlet DefaultHashHandler = /*#__PURE__*/(() => {\n class DefaultHashHandler {\n async calcHash(valueToHash, algorithm) {\n // const encoder = new TextEncoder();\n // const hashArray = await window.crypto.subtle.digest(algorithm, data);\n // const data = encoder.encode(valueToHash);\n // const fhash = fsha256(valueToHash);\n const candHash = encodeUTF8(hash(decodeUTF8(valueToHash)));\n // const hashArray = (sha256 as any).array(valueToHash);\n // // const hashString = this.toHashString(hashArray);\n // const hashString = this.toHashString2(hashArray);\n // console.debug('hash orig - cand', candHash, hashString);\n // alert(1);\n return candHash;\n }\n toHashString2(byteArray) {\n let result = '';\n for (let e of byteArray) {\n result += String.fromCharCode(e);\n }\n return result;\n }\n toHashString(buffer) {\n const byteArray = new Uint8Array(buffer);\n let result = '';\n for (let e of byteArray) {\n result += String.fromCharCode(e);\n }\n return result;\n }\n }\n DefaultHashHandler.ɵfac = function DefaultHashHandler_Factory(t) {\n return new (t || DefaultHashHandler)();\n };\n DefaultHashHandler.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n token: DefaultHashHandler,\n factory: DefaultHashHandler.ɵfac\n });\n return DefaultHashHandler;\n})();\n(() => {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n\n/**\r\n * Service for logging in and logging out with\r\n * OIDC and OAuth2. Supports implicit flow and\r\n * password flow.\r\n */\nlet OAuthService = /*#__PURE__*/(() => {\n class OAuthService extends AuthConfig {\n constructor(ngZone, http, storage, tokenValidationHandler, config, urlHelper, logger, crypto, document, dateTimeService) {\n super();\n this.ngZone = ngZone;\n this.http = http;\n this.config = config;\n this.urlHelper = urlHelper;\n this.logger = logger;\n this.crypto = crypto;\n this.dateTimeService = dateTimeService;\n /**\r\n * @internal\r\n * Deprecated: use property events instead\r\n */\n this.discoveryDocumentLoaded = false;\n /**\r\n * The received (passed around) state, when logging\r\n * in with implicit flow.\r\n */\n this.state = '';\n this.eventsSubject = new Subject();\n this.discoveryDocumentLoadedSubject = new Subject();\n this.grantTypesSupported = [];\n this.inImplicitFlow = false;\n this.saveNoncesInLocalStorage = false;\n this.debug('angular-oauth2-oidc v10');\n // See https://github.com/manfredsteyer/angular-oauth2-oidc/issues/773 for why this is needed\n this.document = document;\n if (!config) {\n config = {};\n }\n this.discoveryDocumentLoaded$ = this.discoveryDocumentLoadedSubject.asObservable();\n this.events = this.eventsSubject.asObservable();\n if (tokenValidationHandler) {\n this.tokenValidationHandler = tokenValidationHandler;\n }\n if (config) {\n this.configure(config);\n }\n try {\n if (storage) {\n this.setStorage(storage);\n } else if (typeof sessionStorage !== 'undefined') {\n this.setStorage(sessionStorage);\n }\n } catch (e) {\n console.error('No OAuthStorage provided and cannot access default (sessionStorage).' + 'Consider providing a custom OAuthStorage implementation in your module.', e);\n }\n // in IE, sessionStorage does not always survive a redirect\n if (this.checkLocalStorageAccessable()) {\n const ua = window?.navigator?.userAgent;\n const msie = ua?.includes('MSIE ') || ua?.includes('Trident');\n if (msie) {\n this.saveNoncesInLocalStorage = true;\n }\n }\n this.setupRefreshTimer();\n }\n checkLocalStorageAccessable() {\n if (typeof window === 'undefined') return false;\n const test = 'test';\n try {\n if (typeof window['localStorage'] === 'undefined') return false;\n localStorage.setItem(test, test);\n localStorage.removeItem(test);\n return true;\n } catch (e) {\n return false;\n }\n }\n /**\r\n * Use this method to configure the service\r\n * @param config the configuration\r\n */\n configure(config) {\n // For the sake of downward compatibility with\n // original configuration API\n Object.assign(this, new AuthConfig(), config);\n this.config = Object.assign({}, new AuthConfig(), config);\n if (this.sessionChecksEnabled) {\n this.setupSessionCheck();\n }\n this.configChanged();\n }\n configChanged() {\n this.setupRefreshTimer();\n }\n restartSessionChecksIfStillLoggedIn() {\n if (this.hasValidIdToken()) {\n this.initSessionCheck();\n }\n }\n restartRefreshTimerIfStillLoggedIn() {\n this.setupExpirationTimers();\n }\n setupSessionCheck() {\n this.events.pipe(filter(e => e.type === 'token_received')).subscribe(e => {\n this.initSessionCheck();\n });\n }\n /**\r\n * Will setup up silent refreshing for when the token is\r\n * about to expire. When the user is logged out via this.logOut method, the\r\n * silent refreshing will pause and not refresh the tokens until the user is\r\n * logged back in via receiving a new token.\r\n * @param params Additional parameter to pass\r\n * @param listenTo Setup automatic refresh of a specific token type\r\n */\n setupAutomaticSilentRefresh(params = {}, listenTo, noPrompt = true) {\n let shouldRunSilentRefresh = true;\n this.clearAutomaticRefreshTimer();\n this.automaticRefreshSubscription = this.events.pipe(tap(e => {\n if (e.type === 'token_received') {\n shouldRunSilentRefresh = true;\n } else if (e.type === 'logout') {\n shouldRunSilentRefresh = false;\n }\n }), filter(e => e.type === 'token_expires' && (listenTo == null || listenTo === 'any' || e.info === listenTo)), debounceTime(1000)).subscribe(_ => {\n if (shouldRunSilentRefresh) {\n // this.silentRefresh(params, noPrompt).catch(_ => {\n this.refreshInternal(params, noPrompt).catch(_ => {\n this.debug('Automatic silent refresh did not work');\n });\n }\n });\n this.restartRefreshTimerIfStillLoggedIn();\n }\n refreshInternal(params, noPrompt) {\n if (!this.useSilentRefresh && this.responseType === 'code') {\n return this.refreshToken();\n } else {\n return this.silentRefresh(params, noPrompt);\n }\n }\n /**\r\n * Convenience method that first calls `loadDiscoveryDocument(...)` and\r\n * directly chains using the `then(...)` part of the promise to call\r\n * the `tryLogin(...)` method.\r\n *\r\n * @param options LoginOptions to pass through to `tryLogin(...)`\r\n */\n loadDiscoveryDocumentAndTryLogin(options = null) {\n return this.loadDiscoveryDocument().then(doc => {\n return this.tryLogin(options);\n });\n }\n /**\r\n * Convenience method that first calls `loadDiscoveryDocumentAndTryLogin(...)`\r\n * and if then chains to `initLoginFlow()`, but only if there is no valid\r\n * IdToken or no valid AccessToken.\r\n *\r\n * @param options LoginOptions to pass through to `tryLogin(...)`\r\n */\n loadDiscoveryDocumentAndLogin(options = null) {\n options = options || {};\n return this.loadDiscoveryDocumentAndTryLogin(options).then(_ => {\n if (!this.hasValidIdToken() || !this.hasValidAccessToken()) {\n const state = typeof options.state === 'string' ? options.state : '';\n this.initLoginFlow(state);\n return false;\n } else {\n return true;\n }\n });\n }\n debug(...args) {\n if (this.showDebugInformation) {\n this.logger.debug.apply(this.logger, args);\n }\n }\n validateUrlFromDiscoveryDocument(url) {\n const errors = [];\n const httpsCheck = this.validateUrlForHttps(url);\n const issuerCheck = this.validateUrlAgainstIssuer(url);\n if (!httpsCheck) {\n errors.push('https for all urls required. Also for urls received by discovery.');\n }\n if (!issuerCheck) {\n errors.push('Every url in discovery document has to start with the issuer url.' + 'Also see property strictDiscoveryDocumentValidation.');\n }\n return errors;\n }\n validateUrlForHttps(url) {\n if (!url) {\n return true;\n }\n const lcUrl = url.toLowerCase();\n if (this.requireHttps === false) {\n return true;\n }\n if ((lcUrl.match(/^http:\\/\\/localhost($|[:\\/])/) || lcUrl.match(/^http:\\/\\/localhost($|[:\\/])/)) && this.requireHttps === 'remoteOnly') {\n return true;\n }\n return lcUrl.startsWith('https://');\n }\n assertUrlNotNullAndCorrectProtocol(url, description) {\n if (!url) {\n throw new Error(`'${description}' should not be null`);\n }\n if (!this.validateUrlForHttps(url)) {\n throw new Error(`'${description}' must use HTTPS (with TLS), or config value for property 'requireHttps' must be set to 'false' and allow HTTP (without TLS).`);\n }\n }\n validateUrlAgainstIssuer(url) {\n if (!this.strictDiscoveryDocumentValidation) {\n return true;\n }\n if (!url) {\n return true;\n }\n return url.toLowerCase().startsWith(this.issuer.toLowerCase());\n }\n setupRefreshTimer() {\n if (typeof window === 'undefined') {\n this.debug('timer not supported on this plattform');\n return;\n }\n if (this.hasValidIdToken() || this.hasValidAccessToken()) {\n this.clearAccessTokenTimer();\n this.clearIdTokenTimer();\n this.setupExpirationTimers();\n }\n if (this.tokenReceivedSubscription) this.tokenReceivedSubscription.unsubscribe();\n this.tokenReceivedSubscription = this.events.pipe(filter(e => e.type === 'token_received')).subscribe(_ => {\n this.clearAccessTokenTimer();\n this.clearIdTokenTimer();\n this.setupExpirationTimers();\n });\n }\n setupExpirationTimers() {\n if (this.hasValidAccessToken()) {\n this.setupAccessTokenTimer();\n }\n if (!this.disableIdTokenTimer && this.hasValidIdToken()) {\n this.setupIdTokenTimer();\n }\n }\n setupAccessTokenTimer() {\n const expiration = this.getAccessTokenExpiration();\n const storedAt = this.getAccessTokenStoredAt();\n const timeout = this.calcTimeout(storedAt, expiration);\n this.ngZone.runOutsideAngular(() => {\n this.accessTokenTimeoutSubscription = of(new OAuthInfoEvent('token_expires', 'access_token')).pipe(delay(timeout)).subscribe(e => {\n this.ngZone.run(() => {\n this.eventsSubject.next(e);\n });\n });\n });\n }\n setupIdTokenTimer() {\n const expiration = this.getIdTokenExpiration();\n const storedAt = this.getIdTokenStoredAt();\n const timeout = this.calcTimeout(storedAt, expiration);\n this.ngZone.runOutsideAngular(() => {\n this.idTokenTimeoutSubscription = of(new OAuthInfoEvent('token_expires', 'id_token')).pipe(delay(timeout)).subscribe(e => {\n this.ngZone.run(() => {\n this.eventsSubject.next(e);\n });\n });\n });\n }\n /**\r\n * Stops timers for automatic refresh.\r\n * To restart it, call setupAutomaticSilentRefresh again.\r\n */\n stopAutomaticRefresh() {\n this.clearAccessTokenTimer();\n this.clearIdTokenTimer();\n this.clearAutomaticRefreshTimer();\n }\n clearAccessTokenTimer() {\n if (this.accessTokenTimeoutSubscription) {\n this.accessTokenTimeoutSubscription.unsubscribe();\n }\n }\n clearIdTokenTimer() {\n if (this.idTokenTimeoutSubscription) {\n this.idTokenTimeoutSubscription.unsubscribe();\n }\n }\n clearAutomaticRefreshTimer() {\n if (this.automaticRefreshSubscription) {\n this.automaticRefreshSubscription.unsubscribe();\n }\n }\n calcTimeout(storedAt, expiration) {\n const now = this.dateTimeService.now();\n const delta = (expiration - storedAt) * this.timeoutFactor - (now - storedAt);\n const duration = Math.max(0, delta);\n const maxTimeoutValue = 2147483647;\n return duration > maxTimeoutValue ? maxTimeoutValue : duration;\n }\n /**\r\n * DEPRECATED. Use a provider for OAuthStorage instead:\r\n *\r\n * { provide: OAuthStorage, useFactory: oAuthStorageFactory }\r\n * export function oAuthStorageFactory(): OAuthStorage { return localStorage; }\r\n * Sets a custom storage used to store the received\r\n * tokens on client side. By default, the browser's\r\n * sessionStorage is used.\r\n * @ignore\r\n *\r\n * @param storage\r\n */\n setStorage(storage) {\n this._storage = storage;\n this.configChanged();\n }\n /**\r\n * Loads the discovery document to configure most\r\n * properties of this service. The url of the discovery\r\n * document is infered from the issuer's url according\r\n * to the OpenId Connect spec. To use another url you\r\n * can pass it to to optional parameter fullUrl.\r\n *\r\n * @param fullUrl\r\n */\n loadDiscoveryDocument(fullUrl = null) {\n return new Promise((resolve, reject) => {\n if (!fullUrl) {\n fullUrl = this.issuer || '';\n if (!fullUrl.endsWith('/')) {\n fullUrl += '/';\n }\n fullUrl += '.well-known/openid-configuration';\n }\n if (!this.validateUrlForHttps(fullUrl)) {\n reject(\"issuer must use HTTPS (with TLS), or config value for property 'requireHttps' must be set to 'false' and allow HTTP (without TLS).\");\n return;\n }\n this.http.get(fullUrl).subscribe(doc => {\n if (!this.validateDiscoveryDocument(doc)) {\n this.eventsSubject.next(new OAuthErrorEvent('discovery_document_validation_error', null));\n reject('discovery_document_validation_error');\n return;\n }\n this.loginUrl = doc.authorization_endpoint;\n this.logoutUrl = doc.end_session_endpoint || this.logoutUrl;\n this.grantTypesSupported = doc.grant_types_supported;\n this.issuer = doc.issuer;\n this.tokenEndpoint = doc.token_endpoint;\n this.userinfoEndpoint = doc.userinfo_endpoint || this.userinfoEndpoint;\n this.jwksUri = doc.jwks_uri;\n this.sessionCheckIFrameUrl = doc.check_session_iframe || this.sessionCheckIFrameUrl;\n this.discoveryDocumentLoaded = true;\n this.discoveryDocumentLoadedSubject.next(doc);\n this.revocationEndpoint = doc.revocation_endpoint || this.revocationEndpoint;\n if (this.sessionChecksEnabled) {\n this.restartSessionChecksIfStillLoggedIn();\n }\n this.loadJwks().then(jwks => {\n const result = {\n discoveryDocument: doc,\n jwks: jwks\n };\n const event = new OAuthSuccessEvent('discovery_document_loaded', result);\n this.eventsSubject.next(event);\n resolve(event);\n return;\n }).catch(err => {\n this.eventsSubject.next(new OAuthErrorEvent('discovery_document_load_error', err));\n reject(err);\n return;\n });\n }, err => {\n this.logger.error('error loading discovery document', err);\n this.eventsSubject.next(new OAuthErrorEvent('discovery_document_load_error', err));\n reject(err);\n });\n });\n }\n loadJwks() {\n return new Promise((resolve, reject) => {\n if (this.jwksUri) {\n this.http.get(this.jwksUri).subscribe(jwks => {\n this.jwks = jwks;\n // this.eventsSubject.next(\n // new OAuthSuccessEvent('discovery_document_loaded')\n // );\n resolve(jwks);\n }, err => {\n this.logger.error('error loading jwks', err);\n this.eventsSubject.next(new OAuthErrorEvent('jwks_load_error', err));\n reject(err);\n });\n } else {\n resolve(null);\n }\n });\n }\n validateDiscoveryDocument(doc) {\n let errors;\n if (!this.skipIssuerCheck && doc.issuer !== this.issuer) {\n this.logger.error('invalid issuer in discovery document', 'expected: ' + this.issuer, 'current: ' + doc.issuer);\n return false;\n }\n errors = this.validateUrlFromDiscoveryDocument(doc.authorization_endpoint);\n if (errors.length > 0) {\n this.logger.error('error validating authorization_endpoint in discovery document', errors);\n return false;\n }\n errors = this.validateUrlFromDiscoveryDocument(doc.end_session_endpoint);\n if (errors.length > 0) {\n this.logger.error('error validating end_session_endpoint in discovery document', errors);\n return false;\n }\n errors = this.validateUrlFromDiscoveryDocument(doc.token_endpoint);\n if (errors.length > 0) {\n this.logger.error('error validating token_endpoint in discovery document', errors);\n }\n errors = this.validateUrlFromDiscoveryDocument(doc.revocation_endpoint);\n if (errors.length > 0) {\n this.logger.error('error validating revocation_endpoint in discovery document', errors);\n }\n errors = this.validateUrlFromDiscoveryDocument(doc.userinfo_endpoint);\n if (errors.length > 0) {\n this.logger.error('error validating userinfo_endpoint in discovery document', errors);\n return false;\n }\n errors = this.validateUrlFromDiscoveryDocument(doc.jwks_uri);\n if (errors.length > 0) {\n this.logger.error('error validating jwks_uri in discovery document', errors);\n return false;\n }\n if (this.sessionChecksEnabled && !doc.check_session_iframe) {\n this.logger.warn('sessionChecksEnabled is activated but discovery document' + ' does not contain a check_session_iframe field');\n }\n return true;\n }\n /**\r\n * Uses password flow to exchange userName and password for an\r\n * access_token. After receiving the access_token, this method\r\n * uses it to query the userinfo endpoint in order to get information\r\n * about the user in question.\r\n *\r\n * When using this, make sure that the property oidc is set to false.\r\n * Otherwise stricter validations take place that make this operation\r\n * fail.\r\n *\r\n * @param userName\r\n * @param password\r\n * @param headers Optional additional http-headers.\r\n */\n fetchTokenUsingPasswordFlowAndLoadUserProfile(userName, password, headers = new HttpHeaders()) {\n return this.fetchTokenUsingPasswordFlow(userName, password, headers).then(() => this.loadUserProfile());\n }\n /**\r\n * Loads the user profile by accessing the user info endpoint defined by OpenId Connect.\r\n *\r\n * When using this with OAuth2 password flow, make sure that the property oidc is set to false.\r\n * Otherwise stricter validations take place that make this operation fail.\r\n */\n loadUserProfile() {\n if (!this.hasValidAccessToken()) {\n throw new Error('Can not load User Profile without access_token');\n }\n if (!this.validateUrlForHttps(this.userinfoEndpoint)) {\n throw new Error(\"userinfoEndpoint must use HTTPS (with TLS), or config value for property 'requireHttps' must be set to 'false' and allow HTTP (without TLS).\");\n }\n return new Promise((resolve, reject) => {\n const headers = new HttpHeaders().set('Authorization', 'Bearer ' + this.getAccessToken());\n this.http.get(this.userinfoEndpoint, {\n headers,\n observe: 'response',\n responseType: 'text'\n }).subscribe(response => {\n this.debug('userinfo received', JSON.stringify(response));\n if (response.headers.get('content-type').startsWith('application/json')) {\n let info = JSON.parse(response.body);\n const existingClaims = this.getIdentityClaims() || {};\n if (!this.skipSubjectCheck) {\n if (this.oidc && (!existingClaims['sub'] || info.sub !== existingClaims['sub'])) {\n const err = 'if property oidc is true, the received user-id (sub) has to be the user-id ' + 'of the user that has logged in with oidc.\\n' + 'if you are not using oidc but just oauth2 password flow set oidc to false';\n reject(err);\n return;\n }\n }\n info = Object.assign({}, existingClaims, info);\n this._storage.setItem('id_token_claims_obj', JSON.stringify(info));\n this.eventsSubject.next(new OAuthSuccessEvent('user_profile_loaded'));\n resolve({\n info\n });\n } else {\n this.debug('userinfo is not JSON, treating it as JWE/JWS');\n this.eventsSubject.next(new OAuthSuccessEvent('user_profile_loaded'));\n resolve(JSON.parse(response.body));\n }\n }, err => {\n this.logger.error('error loading user info', err);\n this.eventsSubject.next(new OAuthErrorEvent('user_profile_load_error', err));\n reject(err);\n });\n });\n }\n /**\r\n * Uses password flow to exchange userName and password for an access_token.\r\n * @param userName\r\n * @param password\r\n * @param headers Optional additional http-headers.\r\n */\n fetchTokenUsingPasswordFlow(userName, password, headers = new HttpHeaders()) {\n const parameters = {\n username: userName,\n password: password\n };\n return this.fetchTokenUsingGrant('password', parameters, headers);\n }\n /**\r\n * Uses a custom grant type to retrieve tokens.\r\n * @param grantType Grant type.\r\n * @param parameters Parameters to pass.\r\n * @param headers Optional additional HTTP headers.\r\n */\n fetchTokenUsingGrant(grantType, parameters, headers = new HttpHeaders()) {\n this.assertUrlNotNullAndCorrectProtocol(this.tokenEndpoint, 'tokenEndpoint');\n /**\r\n * A `HttpParameterCodec` that uses `encodeURIComponent` and `decodeURIComponent` to\r\n * serialize and parse URL parameter keys and values.\r\n *\r\n * @stable\r\n */\n let params = new HttpParams({\n encoder: new WebHttpUrlEncodingCodec()\n }).set('grant_type', grantType).set('scope', this.scope);\n if (this.useHttpBasicAuth) {\n const header = btoa(`${this.clientId}:${this.dummyClientSecret}`);\n headers = headers.set('Authorization', 'Basic ' + header);\n }\n if (!this.useHttpBasicAuth) {\n params = params.set('client_id', this.clientId);\n }\n if (!this.useHttpBasicAuth && this.dummyClientSecret) {\n params = params.set('client_secret', this.dummyClientSecret);\n }\n if (this.customQueryParams) {\n for (const key of Object.getOwnPropertyNames(this.customQueryParams)) {\n params = params.set(key, this.customQueryParams[key]);\n }\n }\n // set explicit parameters last, to allow overwriting\n for (const key of Object.keys(parameters)) {\n params = params.set(key, parameters[key]);\n }\n headers = headers.set('Content-Type', 'application/x-www-form-urlencoded');\n return new Promise((resolve, reject) => {\n this.http.post(this.tokenEndpoint, params, {\n headers\n }).subscribe(tokenResponse => {\n this.debug('tokenResponse', tokenResponse);\n this.storeAccessTokenResponse(tokenResponse.access_token, tokenResponse.refresh_token, tokenResponse.expires_in || this.fallbackAccessTokenExpirationTimeInSec, tokenResponse.scope, this.extractRecognizedCustomParameters(tokenResponse));\n if (this.oidc && tokenResponse.id_token) {\n this.processIdToken(tokenResponse.id_token, tokenResponse.access_token).then(result => {\n this.storeIdToken(result);\n resolve(tokenResponse);\n });\n }\n this.eventsSubject.next(new OAuthSuccessEvent('token_received'));\n resolve(tokenResponse);\n }, err => {\n this.logger.error('Error performing ${grantType} flow', err);\n this.eventsSubject.next(new OAuthErrorEvent('token_error', err));\n reject(err);\n });\n });\n }\n /**\r\n * Refreshes the token using a refresh_token.\r\n * This does not work for implicit flow, b/c\r\n * there is no refresh_token in this flow.\r\n * A solution for this is provided by the\r\n * method silentRefresh.\r\n */\n refreshToken() {\n this.assertUrlNotNullAndCorrectProtocol(this.tokenEndpoint, 'tokenEndpoint');\n return new Promise((resolve, reject) => {\n let params = new HttpParams({\n encoder: new WebHttpUrlEncodingCodec()\n }).set('grant_type', 'refresh_token').set('scope', this.scope).set('refresh_token', this._storage.getItem('refresh_token'));\n let headers = new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded');\n if (this.useHttpBasicAuth) {\n const header = btoa(`${this.clientId}:${this.dummyClientSecret}`);\n headers = headers.set('Authorization', 'Basic ' + header);\n }\n if (!this.useHttpBasicAuth) {\n params = params.set('client_id', this.clientId);\n }\n if (!this.useHttpBasicAuth && this.dummyClientSecret) {\n params = params.set('client_secret', this.dummyClientSecret);\n }\n if (this.customQueryParams) {\n for (const key of Object.getOwnPropertyNames(this.customQueryParams)) {\n params = params.set(key, this.customQueryParams[key]);\n }\n }\n this.http.post(this.tokenEndpoint, params, {\n headers\n }).pipe(switchMap(tokenResponse => {\n if (this.oidc && tokenResponse.id_token) {\n return from(this.processIdToken(tokenResponse.id_token, tokenResponse.access_token, true)).pipe(tap(result => this.storeIdToken(result)), map(_ => tokenResponse));\n } else {\n return of(tokenResponse);\n }\n })).subscribe(tokenResponse => {\n this.debug('refresh tokenResponse', tokenResponse);\n this.storeAccessTokenResponse(tokenResponse.access_token, tokenResponse.refresh_token, tokenResponse.expires_in || this.fallbackAccessTokenExpirationTimeInSec, tokenResponse.scope, this.extractRecognizedCustomParameters(tokenResponse));\n this.eventsSubject.next(new OAuthSuccessEvent('token_received'));\n this.eventsSubject.next(new OAuthSuccessEvent('token_refreshed'));\n resolve(tokenResponse);\n }, err => {\n this.logger.error('Error refreshing token', err);\n this.eventsSubject.next(new OAuthErrorEvent('token_refresh_error', err));\n reject(err);\n });\n });\n }\n removeSilentRefreshEventListener() {\n if (this.silentRefreshPostMessageEventListener) {\n window.removeEventListener('message', this.silentRefreshPostMessageEventListener);\n this.silentRefreshPostMessageEventListener = null;\n }\n }\n setupSilentRefreshEventListener() {\n this.removeSilentRefreshEventListener();\n this.silentRefreshPostMessageEventListener = e => {\n const message = this.processMessageEventMessage(e);\n if (this.checkOrigin && e.origin !== location.origin) {\n console.error('wrong origin requested silent refresh!');\n }\n this.tryLogin({\n customHashFragment: message,\n preventClearHashAfterLogin: true,\n customRedirectUri: this.silentRefreshRedirectUri || this.redirectUri\n }).catch(err => this.debug('tryLogin during silent refresh failed', err));\n };\n window.addEventListener('message', this.silentRefreshPostMessageEventListener);\n }\n /**\r\n * Performs a silent refresh for implicit flow.\r\n * Use this method to get new tokens when/before\r\n * the existing tokens expire.\r\n */\n silentRefresh(params = {}, noPrompt = true) {\n const claims = this.getIdentityClaims() || {};\n if (this.useIdTokenHintForSilentRefresh && this.hasValidIdToken()) {\n params['id_token_hint'] = this.getIdToken();\n }\n if (!this.validateUrlForHttps(this.loginUrl)) {\n throw new Error(\"loginUrl must use HTTPS (with TLS), or config value for property 'requireHttps' must be set to 'false' and allow HTTP (without TLS).\");\n }\n if (typeof this.document === 'undefined') {\n throw new Error('silent refresh is not supported on this platform');\n }\n const existingIframe = this.document.getElementById(this.silentRefreshIFrameName);\n if (existingIframe) {\n this.document.body.removeChild(existingIframe);\n }\n this.silentRefreshSubject = claims['sub'];\n const iframe = this.document.createElement('iframe');\n iframe.id = this.silentRefreshIFrameName;\n this.setupSilentRefreshEventListener();\n const redirectUri = this.silentRefreshRedirectUri || this.redirectUri;\n this.createLoginUrl(null, null, redirectUri, noPrompt, params).then(url => {\n iframe.setAttribute('src', url);\n if (!this.silentRefreshShowIFrame) {\n iframe.style['display'] = 'none';\n }\n this.document.body.appendChild(iframe);\n });\n const errors = this.events.pipe(filter(e => e instanceof OAuthErrorEvent), first());\n const success = this.events.pipe(filter(e => e.type === 'token_received'), first());\n const timeout = of(new OAuthErrorEvent('silent_refresh_timeout', null)).pipe(delay(this.silentRefreshTimeout));\n return race([errors, success, timeout]).pipe(map(e => {\n if (e instanceof OAuthErrorEvent) {\n if (e.type === 'silent_refresh_timeout') {\n this.eventsSubject.next(e);\n } else {\n e = new OAuthErrorEvent('silent_refresh_error', e);\n this.eventsSubject.next(e);\n }\n throw e;\n } else if (e.type === 'token_received') {\n e = new OAuthSuccessEvent('silently_refreshed');\n this.eventsSubject.next(e);\n }\n return e;\n })).toPromise();\n }\n /**\r\n * This method exists for backwards compatibility.\r\n * {@link OAuthService#initLoginFlowInPopup} handles both code\r\n * and implicit flows.\r\n */\n initImplicitFlowInPopup(options) {\n return this.initLoginFlowInPopup(options);\n }\n initLoginFlowInPopup(options) {\n options = options || {};\n return this.createLoginUrl(null, null, this.silentRefreshRedirectUri, false, {\n display: 'popup'\n }).then(url => {\n return new Promise((resolve, reject) => {\n /**\r\n * Error handling section\r\n */\n const checkForPopupClosedInterval = 500;\n let windowRef = null;\n // If we got no window reference we open a window\n // else we are using the window already opened\n if (!options.windowRef) {\n windowRef = window.open(url, 'ngx-oauth2-oidc-login', this.calculatePopupFeatures(options));\n } else if (options.windowRef && !options.windowRef.closed) {\n windowRef = options.windowRef;\n windowRef.location.href = url;\n }\n let checkForPopupClosedTimer;\n const tryLogin = hash => {\n this.tryLogin({\n customHashFragment: hash,\n preventClearHashAfterLogin: true,\n customRedirectUri: this.silentRefreshRedirectUri\n }).then(() => {\n cleanup();\n resolve(true);\n }, err => {\n cleanup();\n reject(err);\n });\n };\n const checkForPopupClosed = () => {\n if (!windowRef || windowRef.closed) {\n cleanup();\n reject(new OAuthErrorEvent('popup_closed', {}));\n }\n };\n if (!windowRef) {\n reject(new OAuthErrorEvent('popup_blocked', {}));\n } else {\n checkForPopupClosedTimer = window.setInterval(checkForPopupClosed, checkForPopupClosedInterval);\n }\n const cleanup = () => {\n window.clearInterval(checkForPopupClosedTimer);\n window.removeEventListener('storage', storageListener);\n window.removeEventListener('message', listener);\n if (windowRef !== null) {\n windowRef.close();\n }\n windowRef = null;\n };\n const listener = e => {\n const message = this.processMessageEventMessage(e);\n if (message && message !== null) {\n window.removeEventListener('storage', storageListener);\n tryLogin(message);\n } else {\n console.log('false event firing');\n }\n };\n const storageListener = event => {\n if (event.key === 'auth_hash') {\n window.removeEventListener('message', listener);\n tryLogin(event.newValue);\n }\n };\n window.addEventListener('message', listener);\n window.addEventListener('storage', storageListener);\n });\n });\n }\n calculatePopupFeatures(options) {\n // Specify an static height and width and calculate centered position\n const height = options.height || 470;\n const width = options.width || 500;\n const left = window.screenLeft + (window.outerWidth - width) / 2;\n const top = window.screenTop + (window.outerHeight - height) / 2;\n return `location=no,toolbar=no,width=${width},height=${height},top=${top},left=${left}`;\n }\n processMessageEventMessage(e) {\n let expectedPrefix = '#';\n if (this.silentRefreshMessagePrefix) {\n expectedPrefix += this.silentRefreshMessagePrefix;\n }\n if (!e || !e.data || typeof e.data !== 'string') {\n return;\n }\n const prefixedMessage = e.data;\n if (!prefixedMessage.startsWith(expectedPrefix)) {\n return;\n }\n return '#' + prefixedMessage.substr(expectedPrefix.length);\n }\n canPerformSessionCheck() {\n if (!this.sessionChecksEnabled) {\n return false;\n }\n if (!this.sessionCheckIFrameUrl) {\n console.warn('sessionChecksEnabled is activated but there is no sessionCheckIFrameUrl');\n return false;\n }\n const sessionState = this.getSessionState();\n if (!sessionState) {\n console.warn('sessionChecksEnabled is activated but there is no session_state');\n return false;\n }\n if (typeof this.document === 'undefined') {\n return false;\n }\n return true;\n }\n setupSessionCheckEventListener() {\n this.removeSessionCheckEventListener();\n this.sessionCheckEventListener = e => {\n const origin = e.origin.toLowerCase();\n const issuer = this.issuer.toLowerCase();\n this.debug('sessionCheckEventListener');\n if (!issuer.startsWith(origin)) {\n this.debug('sessionCheckEventListener', 'wrong origin', origin, 'expected', issuer, 'event', e);\n return;\n }\n // only run in Angular zone if it is 'changed' or 'error'\n switch (e.data) {\n case 'unchanged':\n this.ngZone.run(() => {\n this.handleSessionUnchanged();\n });\n break;\n case 'changed':\n this.ngZone.run(() => {\n this.handleSessionChange();\n });\n break;\n case 'error':\n this.ngZone.run(() => {\n this.handleSessionError();\n });\n break;\n }\n this.debug('got info from session check inframe', e);\n };\n // prevent Angular from refreshing the view on every message (runs in intervals)\n this.ngZone.runOutsideAngular(() => {\n window.addEventListener('message', this.sessionCheckEventListener);\n });\n }\n handleSessionUnchanged() {\n this.debug('session check', 'session unchanged');\n this.eventsSubject.next(new OAuthInfoEvent('session_unchanged'));\n }\n handleSessionChange() {\n this.eventsSubject.next(new OAuthInfoEvent('session_changed'));\n this.stopSessionCheckTimer();\n if (!this.useSilentRefresh && this.responseType === 'code') {\n this.refreshToken().then(_ => {\n this.debug('token refresh after session change worked');\n }).catch(_ => {\n this.debug('token refresh did not work after session changed');\n this.eventsSubject.next(new OAuthInfoEvent('session_terminated'));\n this.logOut(true);\n });\n } else if (this.silentRefreshRedirectUri) {\n this.silentRefresh().catch(_ => this.debug('silent refresh failed after session changed'));\n this.waitForSilentRefreshAfterSessionChange();\n } else {\n this.eventsSubject.next(new OAuthInfoEvent('session_terminated'));\n this.logOut(true);\n }\n }\n waitForSilentRefreshAfterSessionChange() {\n this.events.pipe(filter(e => e.type === 'silently_refreshed' || e.type === 'silent_refresh_timeout' || e.type === 'silent_refresh_error'), first()).subscribe(e => {\n if (e.type !== 'silently_refreshed') {\n this.debug('silent refresh did not work after session changed');\n this.eventsSubject.next(new OAuthInfoEvent('session_terminated'));\n this.logOut(true);\n }\n });\n }\n handleSessionError() {\n this.stopSessionCheckTimer();\n this.eventsSubject.next(new OAuthInfoEvent('session_error'));\n }\n removeSessionCheckEventListener() {\n if (this.sessionCheckEventListener) {\n window.removeEventListener('message', this.sessionCheckEventListener);\n this.sessionCheckEventListener = null;\n }\n }\n initSessionCheck() {\n if (!this.canPerformSessionCheck()) {\n return;\n }\n const existingIframe = this.document.getElementById(this.sessionCheckIFrameName);\n if (existingIframe) {\n this.document.body.removeChild(existingIframe);\n }\n const iframe = this.document.createElement('iframe');\n iframe.id = this.sessionCheckIFrameName;\n this.setupSessionCheckEventListener();\n const url = this.sessionCheckIFrameUrl;\n iframe.setAttribute('src', url);\n iframe.style.display = 'none';\n this.document.body.appendChild(iframe);\n this.startSessionCheckTimer();\n }\n startSessionCheckTimer() {\n this.stopSessionCheckTimer();\n this.ngZone.runOutsideAngular(() => {\n this.sessionCheckTimer = setInterval(this.checkSession.bind(this), this.sessionCheckIntervall);\n });\n }\n stopSessionCheckTimer() {\n if (this.sessionCheckTimer) {\n clearInterval(this.sessionCheckTimer);\n this.sessionCheckTimer = null;\n }\n }\n checkSession() {\n const iframe = this.document.getElementById(this.sessionCheckIFrameName);\n if (!iframe) {\n this.logger.warn('checkSession did not find iframe', this.sessionCheckIFrameName);\n }\n const sessionState = this.getSessionState();\n if (!sessionState) {\n this.stopSessionCheckTimer();\n }\n const message = this.clientId + ' ' + sessionState;\n iframe.contentWindow.postMessage(message, this.issuer);\n }\n async createLoginUrl(state = '', loginHint = '', customRedirectUri = '', noPrompt = false, params = {}) {\n const that = this;\n let redirectUri;\n if (customRedirectUri) {\n redirectUri = customRedirectUri;\n } else {\n redirectUri = this.redirectUri;\n }\n const nonce = await this.createAndSaveNonce();\n if (state) {\n state = nonce + this.config.nonceStateSeparator + encodeURIComponent(state);\n } else {\n state = nonce;\n }\n if (!this.requestAccessToken && !this.oidc) {\n throw new Error('Either requestAccessToken or oidc or both must be true');\n }\n if (this.config.responseType) {\n this.responseType = this.config.responseType;\n } else {\n if (this.oidc && this.requestAccessToken) {\n this.responseType = 'id_token token';\n } else if (this.oidc && !this.requestAccessToken) {\n this.responseType = 'id_token';\n } else {\n this.responseType = 'token';\n }\n }\n const seperationChar = that.loginUrl.indexOf('?') > -1 ? '&' : '?';\n let scope = that.scope;\n if (this.oidc && !scope.match(/(^|\\s)openid($|\\s)/)) {\n scope = 'openid ' + scope;\n }\n let url = that.loginUrl + seperationChar + 'response_type=' + encodeURIComponent(that.responseType) + '&client_id=' + encodeURIComponent(that.clientId) + '&state=' + encodeURIComponent(state) + '&redirect_uri=' + encodeURIComponent(redirectUri) + '&scope=' + encodeURIComponent(scope);\n if (this.responseType.includes('code') && !this.disablePKCE) {\n const [challenge, verifier] = await this.createChallangeVerifierPairForPKCE();\n if (this.saveNoncesInLocalStorage && typeof window['localStorage'] !== 'undefined') {\n localStorage.setItem('PKCE_verifier', verifier);\n } else {\n this._storage.setItem('PKCE_verifier', verifier);\n }\n url += '&code_challenge=' + challenge;\n url += '&code_challenge_method=S256';\n }\n if (loginHint) {\n url += '&login_hint=' + encodeURIComponent(loginHint);\n }\n if (that.resource) {\n url += '&resource=' + encodeURIComponent(that.resource);\n }\n if (that.oidc) {\n url += '&nonce=' + encodeURIComponent(nonce);\n }\n if (noPrompt) {\n url += '&prompt=none';\n }\n for (const key of Object.keys(params)) {\n url += '&' + encodeURIComponent(key) + '=' + encodeURIComponent(params[key]);\n }\n if (this.customQueryParams) {\n for (const key of Object.getOwnPropertyNames(this.customQueryParams)) {\n url += '&' + key + '=' + encodeURIComponent(this.customQueryParams[key]);\n }\n }\n return url;\n }\n initImplicitFlowInternal(additionalState = '', params = '') {\n if (this.inImplicitFlow) {\n return;\n }\n this.inImplicitFlow = true;\n if (!this.validateUrlForHttps(this.loginUrl)) {\n throw new Error(\"loginUrl must use HTTPS (with TLS), or config value for property 'requireHttps' must be set to 'false' and allow HTTP (without TLS).\");\n }\n let addParams = {};\n let loginHint = null;\n if (typeof params === 'string') {\n loginHint = params;\n } else if (typeof params === 'object') {\n addParams = params;\n }\n this.createLoginUrl(additionalState, loginHint, null, false, addParams).then(this.config.openUri).catch(error => {\n console.error('Error in initImplicitFlow', error);\n this.inImplicitFlow = false;\n });\n }\n /**\r\n * Starts the implicit flow and redirects to user to\r\n * the auth servers' login url.\r\n *\r\n * @param additionalState Optional state that is passed around.\r\n * You'll find this state in the property `state` after `tryLogin` logged in the user.\r\n * @param params Hash with additional parameter. If it is a string, it is used for the\r\n * parameter loginHint (for the sake of compatibility with former versions)\r\n */\n initImplicitFlow(additionalState = '', params = '') {\n if (this.loginUrl !== '') {\n this.initImplicitFlowInternal(additionalState, params);\n } else {\n this.events.pipe(filter(e => e.type === 'discovery_document_loaded')).subscribe(_ => this.initImplicitFlowInternal(additionalState, params));\n }\n }\n /**\r\n * Reset current implicit flow\r\n *\r\n * @description This method allows resetting the current implict flow in order to be initialized again.\r\n */\n resetImplicitFlow() {\n this.inImplicitFlow = false;\n }\n callOnTokenReceivedIfExists(options) {\n const that = this;\n if (options.onTokenReceived) {\n const tokenParams = {\n idClaims: that.getIdentityClaims(),\n idToken: that.getIdToken(),\n accessToken: that.getAccessToken(),\n state: that.state\n };\n options.onTokenReceived(tokenParams);\n }\n }\n storeAccessTokenResponse(accessToken, refreshToken, expiresIn, grantedScopes, customParameters) {\n this._storage.setItem('access_token', accessToken);\n if (grantedScopes && !Array.isArray(grantedScopes)) {\n this._storage.setItem('granted_scopes', JSON.stringify(grantedScopes.split(' ')));\n } else if (grantedScopes && Array.isArray(grantedScopes)) {\n this._storage.setItem('granted_scopes', JSON.stringify(grantedScopes));\n }\n this._storage.setItem('access_token_stored_at', '' + this.dateTimeService.now());\n if (expiresIn) {\n const expiresInMilliSeconds = expiresIn * 1000;\n const now = this.dateTimeService.new();\n const expiresAt = now.getTime() + expiresInMilliSeconds;\n this._storage.setItem('expires_at', '' + expiresAt);\n }\n if (refreshToken) {\n this._storage.setItem('refresh_token', refreshToken);\n }\n if (customParameters) {\n customParameters.forEach((value, key) => {\n this._storage.setItem(key, value);\n });\n }\n }\n /**\r\n * Delegates to tryLoginImplicitFlow for the sake of competability\r\n * @param options Optional options.\r\n */\n tryLogin(options = null) {\n if (this.config.responseType === 'code') {\n return this.tryLoginCodeFlow(options).then(_ => true);\n } else {\n return this.tryLoginImplicitFlow(options);\n }\n }\n parseQueryString(queryString) {\n if (!queryString || queryString.length === 0) {\n return {};\n }\n if (queryString.charAt(0) === '?') {\n queryString = queryString.substr(1);\n }\n return this.urlHelper.parseQueryString(queryString);\n }\n async tryLoginCodeFlow(options = null) {\n options = options || {};\n const querySource = options.customHashFragment ? options.customHashFragment.substring(1) : window.location.search;\n const parts = this.getCodePartsFromUrl(querySource);\n const code = parts['code'];\n const state = parts['state'];\n const sessionState = parts['session_state'];\n if (!options.preventClearHashAfterLogin) {\n const href = location.origin + location.pathname + location.search.replace(/code=[^&\\$]*/, '').replace(/scope=[^&\\$]*/, '').replace(/state=[^&\\$]*/, '').replace(/session_state=[^&\\$]*/, '').replace(/^\\?&/, '?').replace(/&$/, '').replace(/^\\?$/, '').replace(/&+/g, '&').replace(/\\?&/, '?').replace(/\\?$/, '') + location.hash;\n history.replaceState(null, window.name, href);\n }\n let [nonceInState, userState] = this.parseState(state);\n this.state = userState;\n if (parts['error']) {\n this.debug('error trying to login');\n this.handleLoginError(options, parts);\n const err = new OAuthErrorEvent('code_error', {}, parts);\n this.eventsSubject.next(err);\n return Promise.reject(err);\n }\n if (!options.disableNonceCheck) {\n if (!nonceInState) {\n this.saveRequestedRoute();\n return Promise.resolve();\n }\n if (!options.disableOAuth2StateCheck) {\n const success = this.validateNonce(nonceInState);\n if (!success) {\n const event = new OAuthErrorEvent('invalid_nonce_in_state', null);\n this.eventsSubject.next(event);\n return Promise.reject(event);\n }\n }\n }\n this.storeSessionState(sessionState);\n if (code) {\n await this.getTokenFromCode(code, options);\n this.restoreRequestedRoute();\n return Promise.resolve();\n } else {\n return Promise.resolve();\n }\n }\n saveRequestedRoute() {\n if (this.config.preserveRequestedRoute) {\n this._storage.setItem('requested_route', window.location.pathname + window.location.search);\n }\n }\n restoreRequestedRoute() {\n const requestedRoute = this._storage.getItem('requested_route');\n if (requestedRoute) {\n history.replaceState(null, '', window.location.origin + requestedRoute);\n }\n }\n /**\r\n * Retrieve the returned auth code from the redirect uri that has been called.\r\n * If required also check hash, as we could use hash location strategy.\r\n */\n getCodePartsFromUrl(queryString) {\n if (!queryString || queryString.length === 0) {\n return this.urlHelper.getHashFragmentParams();\n }\n // normalize query string\n if (queryString.charAt(0) === '?') {\n queryString = queryString.substr(1);\n }\n return this.urlHelper.parseQueryString(queryString);\n }\n /**\r\n * Get token using an intermediate code. Works for the Authorization Code flow.\r\n */\n getTokenFromCode(code, options) {\n let params = new HttpParams({\n encoder: new WebHttpUrlEncodingCodec()\n }).set('grant_type', 'authorization_code').set('code', code).set('redirect_uri', options.customRedirectUri || this.redirectUri);\n if (!this.disablePKCE) {\n let PKCEVerifier;\n if (this.saveNoncesInLocalStorage && typeof window['localStorage'] !== 'undefined') {\n PKCEVerifier = localStorage.getItem('PKCE_verifier');\n } else {\n PKCEVerifier = this._storage.getItem('PKCE_verifier');\n }\n if (!PKCEVerifier) {\n console.warn('No PKCE verifier found in oauth storage!');\n } else {\n params = params.set('code_verifier', PKCEVerifier);\n }\n }\n return this.fetchAndProcessToken(params, options);\n }\n fetchAndProcessToken(params, options) {\n options = options || {};\n this.assertUrlNotNullAndCorrectProtocol(this.tokenEndpoint, 'tokenEndpoint');\n let headers = new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded');\n if (this.useHttpBasicAuth) {\n const header = btoa(`${this.clientId}:${this.dummyClientSecret}`);\n headers = headers.set('Authorization', 'Basic ' + header);\n }\n if (!this.useHttpBasicAuth) {\n params = params.set('client_id', this.clientId);\n }\n if (!this.useHttpBasicAuth && this.dummyClientSecret) {\n params = params.set('client_secret', this.dummyClientSecret);\n }\n return new Promise((resolve, reject) => {\n if (this.customQueryParams) {\n for (let key of Object.getOwnPropertyNames(this.customQueryParams)) {\n params = params.set(key, this.customQueryParams[key]);\n }\n }\n this.http.post(this.tokenEndpoint, params, {\n headers\n }).subscribe(tokenResponse => {\n this.debug('refresh tokenResponse', tokenResponse);\n this.storeAccessTokenResponse(tokenResponse.access_token, tokenResponse.refresh_token, tokenResponse.expires_in || this.fallbackAccessTokenExpirationTimeInSec, tokenResponse.scope, this.extractRecognizedCustomParameters(tokenResponse));\n if (this.oidc && tokenResponse.id_token) {\n this.processIdToken(tokenResponse.id_token, tokenResponse.access_token, options.disableNonceCheck).then(result => {\n this.storeIdToken(result);\n this.eventsSubject.next(new OAuthSuccessEvent('token_received'));\n this.eventsSubject.next(new OAuthSuccessEvent('token_refreshed'));\n resolve(tokenResponse);\n }).catch(reason => {\n this.eventsSubject.next(new OAuthErrorEvent('token_validation_error', reason));\n console.error('Error validating tokens');\n console.error(reason);\n reject(reason);\n });\n } else {\n this.eventsSubject.next(new OAuthSuccessEvent('token_received'));\n this.eventsSubject.next(new OAuthSuccessEvent('token_refreshed'));\n resolve(tokenResponse);\n }\n }, err => {\n console.error('Error getting token', err);\n this.eventsSubject.next(new OAuthErrorEvent('token_refresh_error', err));\n reject(err);\n });\n });\n }\n /**\r\n * Checks whether there are tokens in the hash fragment\r\n * as a result of the implicit flow. These tokens are\r\n * parsed, validated and used to sign the user in to the\r\n * current client.\r\n *\r\n * @param options Optional options.\r\n */\n tryLoginImplicitFlow(options = null) {\n options = options || {};\n let parts;\n if (options.customHashFragment) {\n parts = this.urlHelper.getHashFragmentParams(options.customHashFragment);\n } else {\n parts = this.urlHelper.getHashFragmentParams();\n }\n this.debug('parsed url', parts);\n const state = parts['state'];\n let [nonceInState, userState] = this.parseState(state);\n this.state = userState;\n if (parts['error']) {\n this.debug('error trying to login');\n this.handleLoginError(options, parts);\n const err = new OAuthErrorEvent('token_error', {}, parts);\n this.eventsSubject.next(err);\n return Promise.reject(err);\n }\n const accessToken = parts['access_token'];\n const idToken = parts['id_token'];\n const sessionState = parts['session_state'];\n const grantedScopes = parts['scope'];\n if (!this.requestAccessToken && !this.oidc) {\n return Promise.reject('Either requestAccessToken or oidc (or both) must be true.');\n }\n if (this.requestAccessToken && !accessToken) {\n return Promise.resolve(false);\n }\n if (this.requestAccessToken && !options.disableOAuth2StateCheck && !state) {\n return Promise.resolve(false);\n }\n if (this.oidc && !idToken) {\n return Promise.resolve(false);\n }\n if (this.sessionChecksEnabled && !sessionState) {\n this.logger.warn('session checks (Session Status Change Notification) ' + 'were activated in the configuration but the id_token ' + 'does not contain a session_state claim');\n }\n if (this.requestAccessToken && !options.disableNonceCheck) {\n const success = this.validateNonce(nonceInState);\n if (!success) {\n const event = new OAuthErrorEvent('invalid_nonce_in_state', null);\n this.eventsSubject.next(event);\n return Promise.reject(event);\n }\n }\n if (this.requestAccessToken) {\n this.storeAccessTokenResponse(accessToken, null, parts['expires_in'] || this.fallbackAccessTokenExpirationTimeInSec, grantedScopes);\n }\n if (!this.oidc) {\n this.eventsSubject.next(new OAuthSuccessEvent('token_received'));\n if (this.clearHashAfterLogin && !options.preventClearHashAfterLogin) {\n this.clearLocationHash();\n }\n this.callOnTokenReceivedIfExists(options);\n return Promise.resolve(true);\n }\n return this.processIdToken(idToken, accessToken, options.disableNonceCheck).then(result => {\n if (options.validationHandler) {\n return options.validationHandler({\n accessToken: accessToken,\n idClaims: result.idTokenClaims,\n idToken: result.idToken,\n state: state\n }).then(_ => result);\n }\n return result;\n }).then(result => {\n this.storeIdToken(result);\n this.storeSessionState(sessionState);\n if (this.clearHashAfterLogin && !options.preventClearHashAfterLogin) {\n this.clearLocationHash();\n }\n this.eventsSubject.next(new OAuthSuccessEvent('token_received'));\n this.callOnTokenReceivedIfExists(options);\n this.inImplicitFlow = false;\n return true;\n }).catch(reason => {\n this.eventsSubject.next(new OAuthErrorEvent('token_validation_error', reason));\n this.logger.error('Error validating tokens');\n this.logger.error(reason);\n return Promise.reject(reason);\n });\n }\n parseState(state) {\n let nonce = state;\n let userState = '';\n if (state) {\n const idx = state.indexOf(this.config.nonceStateSeparator);\n if (idx > -1) {\n nonce = state.substr(0, idx);\n userState = state.substr(idx + this.config.nonceStateSeparator.length);\n }\n }\n return [nonce, userState];\n }\n validateNonce(nonceInState) {\n let savedNonce;\n if (this.saveNoncesInLocalStorage && typeof window['localStorage'] !== 'undefined') {\n savedNonce = localStorage.getItem('nonce');\n } else {\n savedNonce = this._storage.getItem('nonce');\n }\n if (savedNonce !== nonceInState) {\n const err = 'Validating access_token failed, wrong state/nonce.';\n console.error(err, savedNonce, nonceInState);\n return false;\n }\n return true;\n }\n storeIdToken(idToken) {\n this._storage.setItem('id_token', idToken.idToken);\n this._storage.setItem('id_token_claims_obj', idToken.idTokenClaimsJson);\n this._storage.setItem('id_token_expires_at', '' + idToken.idTokenExpiresAt);\n this._storage.setItem('id_token_stored_at', '' + this.dateTimeService.now());\n }\n storeSessionState(sessionState) {\n this._storage.setItem('session_state', sessionState);\n }\n getSessionState() {\n return this._storage.getItem('session_state');\n }\n handleLoginError(options, parts) {\n if (options.onLoginError) {\n options.onLoginError(parts);\n }\n if (this.clearHashAfterLogin && !options.preventClearHashAfterLogin) {\n this.clearLocationHash();\n }\n }\n getClockSkewInMsec(defaultSkewMsc = 600000) {\n if (!this.clockSkewInSec && this.clockSkewInSec !== 0) {\n return defaultSkewMsc;\n }\n return this.clockSkewInSec * 1000;\n }\n /**\r\n * @ignore\r\n */\n processIdToken(idToken, accessToken, skipNonceCheck = false) {\n const tokenParts = idToken.split('.');\n const headerBase64 = this.padBase64(tokenParts[0]);\n const headerJson = b64DecodeUnicode(headerBase64);\n const header = JSON.parse(headerJson);\n const claimsBase64 = this.padBase64(tokenParts[1]);\n const claimsJson = b64DecodeUnicode(claimsBase64);\n const claims = JSON.parse(claimsJson);\n let savedNonce;\n if (this.saveNoncesInLocalStorage && typeof window['localStorage'] !== 'undefined') {\n savedNonce = localStorage.getItem('nonce');\n } else {\n savedNonce = this._storage.getItem('nonce');\n }\n if (Array.isArray(claims.aud)) {\n if (claims.aud.every(v => v !== this.clientId)) {\n const err = 'Wrong audience: ' + claims.aud.join(',');\n this.logger.warn(err);\n return Promise.reject(err);\n }\n } else {\n if (claims.aud !== this.clientId) {\n const err = 'Wrong audience: ' + claims.aud;\n this.logger.warn(err);\n return Promise.reject(err);\n }\n }\n if (!claims.sub) {\n const err = 'No sub claim in id_token';\n this.logger.warn(err);\n return Promise.reject(err);\n }\n /* For now, we only check whether the sub against\r\n * silentRefreshSubject when sessionChecksEnabled is on\r\n * We will reconsider in a later version to do this\r\n * in every other case too.\r\n */\n if (this.sessionChecksEnabled && this.silentRefreshSubject && this.silentRefreshSubject !== claims['sub']) {\n const err = 'After refreshing, we got an id_token for another user (sub). ' + `Expected sub: ${this.silentRefreshSubject}, received sub: ${claims['sub']}`;\n this.logger.warn(err);\n return Promise.reject(err);\n }\n if (!claims.iat) {\n const err = 'No iat claim in id_token';\n this.logger.warn(err);\n return Promise.reject(err);\n }\n if (!this.skipIssuerCheck && claims.iss !== this.issuer) {\n const err = 'Wrong issuer: ' + claims.iss;\n this.logger.warn(err);\n return Promise.reject(err);\n }\n if (!skipNonceCheck && claims.nonce !== savedNonce) {\n const err = 'Wrong nonce: ' + claims.nonce;\n this.logger.warn(err);\n return Promise.reject(err);\n }\n // at_hash is not applicable to authorization code flow\n // addressing https://github.com/manfredsteyer/angular-oauth2-oidc/issues/661\n // i.e. Based on spec the at_hash check is only true for implicit code flow on Ping Federate\n // https://www.pingidentity.com/developer/en/resources/openid-connect-developers-guide.html\n if (this.hasOwnProperty('responseType') && (this.responseType === 'code' || this.responseType === 'id_token')) {\n this.disableAtHashCheck = true;\n }\n if (!this.disableAtHashCheck && this.requestAccessToken && !claims['at_hash']) {\n const err = 'An at_hash is needed!';\n this.logger.warn(err);\n return Promise.reject(err);\n }\n const now = this.dateTimeService.now();\n const issuedAtMSec = claims.iat * 1000;\n const expiresAtMSec = claims.exp * 1000;\n const clockSkewInMSec = this.getClockSkewInMsec(); // (this.getClockSkewInMsec() || 600) * 1000;\n if (issuedAtMSec - clockSkewInMSec >= now || expiresAtMSec + clockSkewInMSec - this.decreaseExpirationBySec <= now) {\n const err = 'Token has expired';\n console.error(err);\n console.error({\n now: now,\n issuedAtMSec: issuedAtMSec,\n expiresAtMSec: expiresAtMSec\n });\n return Promise.reject(err);\n }\n const validationParams = {\n accessToken: accessToken,\n idToken: idToken,\n jwks: this.jwks,\n idTokenClaims: claims,\n idTokenHeader: header,\n loadKeys: () => this.loadJwks()\n };\n if (this.disableAtHashCheck) {\n return this.checkSignature(validationParams).then(_ => {\n const result = {\n idToken: idToken,\n idTokenClaims: claims,\n idTokenClaimsJson: claimsJson,\n idTokenHeader: header,\n idTokenHeaderJson: headerJson,\n idTokenExpiresAt: expiresAtMSec\n };\n return result;\n });\n }\n return this.checkAtHash(validationParams).then(atHashValid => {\n if (!this.disableAtHashCheck && this.requestAccessToken && !atHashValid) {\n const err = 'Wrong at_hash';\n this.logger.warn(err);\n return Promise.reject(err);\n }\n return this.checkSignature(validationParams).then(_ => {\n const atHashCheckEnabled = !this.disableAtHashCheck;\n const result = {\n idToken: idToken,\n idTokenClaims: claims,\n idTokenClaimsJson: claimsJson,\n idTokenHeader: header,\n idTokenHeaderJson: headerJson,\n idTokenExpiresAt: expiresAtMSec\n };\n if (atHashCheckEnabled) {\n return this.checkAtHash(validationParams).then(atHashValid => {\n if (this.requestAccessToken && !atHashValid) {\n const err = 'Wrong at_hash';\n this.logger.warn(err);\n return Promise.reject(err);\n } else {\n return result;\n }\n });\n } else {\n return result;\n }\n });\n });\n }\n /**\r\n * Returns the received claims about the user.\r\n */\n getIdentityClaims() {\n const claims = this._storage.getItem('id_token_claims_obj');\n if (!claims) {\n return null;\n }\n return JSON.parse(claims);\n }\n /**\r\n * Returns the granted scopes from the server.\r\n */\n getGrantedScopes() {\n const scopes = this._storage.getItem('granted_scopes');\n if (!scopes) {\n return null;\n }\n return JSON.parse(scopes);\n }\n /**\r\n * Returns the current id_token.\r\n */\n getIdToken() {\n return this._storage ? this._storage.getItem('id_token') : null;\n }\n padBase64(base64data) {\n while (base64data.length % 4 !== 0) {\n base64data += '=';\n }\n return base64data;\n }\n /**\r\n * Returns the current access_token.\r\n */\n getAccessToken() {\n return this._storage ? this._storage.getItem('access_token') : null;\n }\n getRefreshToken() {\n return this._storage ? this._storage.getItem('refresh_token') : null;\n }\n /**\r\n * Returns the expiration date of the access_token\r\n * as milliseconds since 1970.\r\n */\n getAccessTokenExpiration() {\n if (!this._storage.getItem('expires_at')) {\n return null;\n }\n return parseInt(this._storage.getItem('expires_at'), 10);\n }\n getAccessTokenStoredAt() {\n return parseInt(this._storage.getItem('access_token_stored_at'), 10);\n }\n getIdTokenStoredAt() {\n return parseInt(this._storage.getItem('id_token_stored_at'), 10);\n }\n /**\r\n * Returns the expiration date of the id_token\r\n * as milliseconds since 1970.\r\n */\n getIdTokenExpiration() {\n if (!this._storage.getItem('id_token_expires_at')) {\n return null;\n }\n return parseInt(this._storage.getItem('id_token_expires_at'), 10);\n }\n /**\r\n * Checkes, whether there is a valid access_token.\r\n */\n hasValidAccessToken() {\n if (this.getAccessToken()) {\n const expiresAt = this._storage.getItem('expires_at');\n const now = this.dateTimeService.new();\n if (expiresAt && parseInt(expiresAt, 10) - this.decreaseExpirationBySec < now.getTime() - this.getClockSkewInMsec()) {\n return false;\n }\n return true;\n }\n return false;\n }\n /**\r\n * Checks whether there is a valid id_token.\r\n */\n hasValidIdToken() {\n if (this.getIdToken()) {\n const expiresAt = this._storage.getItem('id_token_expires_at');\n const now = this.dateTimeService.new();\n if (expiresAt && parseInt(expiresAt, 10) - this.decreaseExpirationBySec < now.getTime() - this.getClockSkewInMsec()) {\n return false;\n }\n return true;\n }\n return false;\n }\n /**\r\n * Retrieve a saved custom property of the TokenReponse object. Only if predefined in authconfig.\r\n */\n getCustomTokenResponseProperty(requestedProperty) {\n return this._storage && this.config.customTokenParameters && this.config.customTokenParameters.indexOf(requestedProperty) >= 0 && this._storage.getItem(requestedProperty) !== null ? JSON.parse(this._storage.getItem(requestedProperty)) : null;\n }\n /**\r\n * Returns the auth-header that can be used\r\n * to transmit the access_token to a service\r\n */\n authorizationHeader() {\n return 'Bearer ' + this.getAccessToken();\n }\n logOut(customParameters = {}, state = '') {\n let noRedirectToLogoutUrl = false;\n if (typeof customParameters === 'boolean') {\n noRedirectToLogoutUrl = customParameters;\n customParameters = {};\n }\n const id_token = this.getIdToken();\n this._storage.removeItem('access_token');\n this._storage.removeItem('id_token');\n this._storage.removeItem('refresh_token');\n if (this.saveNoncesInLocalStorage) {\n localStorage.removeItem('nonce');\n localStorage.removeItem('PKCE_verifier');\n } else {\n this._storage.removeItem('nonce');\n this._storage.removeItem('PKCE_verifier');\n }\n this._storage.removeItem('expires_at');\n this._storage.removeItem('id_token_claims_obj');\n this._storage.removeItem('id_token_expires_at');\n this._storage.removeItem('id_token_stored_at');\n this._storage.removeItem('access_token_stored_at');\n this._storage.removeItem('granted_scopes');\n this._storage.removeItem('session_state');\n if (this.config.customTokenParameters) {\n this.config.customTokenParameters.forEach(customParam => this._storage.removeItem(customParam));\n }\n this.silentRefreshSubject = null;\n this.eventsSubject.next(new OAuthInfoEvent('logout'));\n if (!this.logoutUrl) {\n return;\n }\n if (noRedirectToLogoutUrl) {\n return;\n }\n // if (!id_token && !this.postLogoutRedirectUri) {\n // return;\n // }\n let logoutUrl;\n if (!this.validateUrlForHttps(this.logoutUrl)) {\n throw new Error(\"logoutUrl must use HTTPS (with TLS), or config value for property 'requireHttps' must be set to 'false' and allow HTTP (without TLS).\");\n }\n // For backward compatibility\n if (this.logoutUrl.indexOf('{{') > -1) {\n logoutUrl = this.logoutUrl.replace(/\\{\\{id_token\\}\\}/, encodeURIComponent(id_token)).replace(/\\{\\{client_id\\}\\}/, encodeURIComponent(this.clientId));\n } else {\n let params = new HttpParams({\n encoder: new WebHttpUrlEncodingCodec()\n });\n if (id_token) {\n params = params.set('id_token_hint', id_token);\n }\n const postLogoutUrl = this.postLogoutRedirectUri || this.redirectUriAsPostLogoutRedirectUriFallback && this.redirectUri || '';\n if (postLogoutUrl) {\n params = params.set('post_logout_redirect_uri', postLogoutUrl);\n if (state) {\n params = params.set('state', state);\n }\n }\n for (let key in customParameters) {\n params = params.set(key, customParameters[key]);\n }\n logoutUrl = this.logoutUrl + (this.logoutUrl.indexOf('?') > -1 ? '&' : '?') + params.toString();\n }\n this.config.openUri(logoutUrl);\n }\n /**\r\n * @ignore\r\n */\n createAndSaveNonce() {\n const that = this;\n return this.createNonce().then(function (nonce) {\n // Use localStorage for nonce if possible\n // localStorage is the only storage who survives a\n // redirect in ALL browsers (also IE)\n // Otherwiese we'd force teams who have to support\n // IE into using localStorage for everything\n if (that.saveNoncesInLocalStorage && typeof window['localStorage'] !== 'undefined') {\n localStorage.setItem('nonce', nonce);\n } else {\n that._storage.setItem('nonce', nonce);\n }\n return nonce;\n });\n }\n /**\r\n * @ignore\r\n */\n ngOnDestroy() {\n this.clearAccessTokenTimer();\n this.clearIdTokenTimer();\n this.removeSilentRefreshEventListener();\n const silentRefreshFrame = this.document.getElementById(this.silentRefreshIFrameName);\n if (silentRefreshFrame) {\n silentRefreshFrame.remove();\n }\n this.stopSessionCheckTimer();\n this.removeSessionCheckEventListener();\n const sessionCheckFrame = this.document.getElementById(this.sessionCheckIFrameName);\n if (sessionCheckFrame) {\n sessionCheckFrame.remove();\n }\n }\n createNonce() {\n return new Promise(resolve => {\n if (this.rngUrl) {\n throw new Error('createNonce with rng-web-api has not been implemented so far');\n }\n /*\r\n * This alphabet is from:\r\n * https://tools.ietf.org/html/rfc7636#section-4.1\r\n *\r\n * [A-Z] / [a-z] / [0-9] / \"-\" / \".\" / \"_\" / \"~\"\r\n */\n const unreserved = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~';\n let size = 45;\n let id = '';\n const crypto = typeof self === 'undefined' ? null : self.crypto || self['msCrypto'];\n if (crypto) {\n let bytes = new Uint8Array(size);\n crypto.getRandomValues(bytes);\n // Needed for IE\n if (!bytes.map) {\n bytes.map = Array.prototype.map;\n }\n bytes = bytes.map(x => unreserved.charCodeAt(x % unreserved.length));\n id = String.fromCharCode.apply(null, bytes);\n } else {\n while (0 < size--) {\n id += unreserved[Math.random() * unreserved.length | 0];\n }\n }\n resolve(base64UrlEncode(id));\n });\n }\n async checkAtHash(params) {\n if (!this.tokenValidationHandler) {\n this.logger.warn('No tokenValidationHandler configured. Cannot check at_hash.');\n return true;\n }\n return this.tokenValidationHandler.validateAtHash(params);\n }\n checkSignature(params) {\n if (!this.tokenValidationHandler) {\n this.logger.warn('No tokenValidationHandler configured. Cannot check signature.');\n return Promise.resolve(null);\n }\n return this.tokenValidationHandler.validateSignature(params);\n }\n /**\r\n * Start the implicit flow or the code flow,\r\n * depending on your configuration.\r\n */\n initLoginFlow(additionalState = '', params = {}) {\n if (this.responseType === 'code') {\n return this.initCodeFlow(additionalState, params);\n } else {\n return this.initImplicitFlow(additionalState, params);\n }\n }\n /**\r\n * Starts the authorization code flow and redirects to user to\r\n * the auth servers login url.\r\n */\n initCodeFlow(additionalState = '', params = {}) {\n if (this.loginUrl !== '') {\n this.initCodeFlowInternal(additionalState, params);\n } else {\n this.events.pipe(filter(e => e.type === 'discovery_document_loaded')).subscribe(_ => this.initCodeFlowInternal(additionalState, params));\n }\n }\n initCodeFlowInternal(additionalState = '', params = {}) {\n if (!this.validateUrlForHttps(this.loginUrl)) {\n throw new Error(\"loginUrl must use HTTPS (with TLS), or config value for property 'requireHttps' must be set to 'false' and allow HTTP (without TLS).\");\n }\n let addParams = {};\n let loginHint = null;\n if (typeof params === 'string') {\n loginHint = params;\n } else if (typeof params === 'object') {\n addParams = params;\n }\n this.createLoginUrl(additionalState, loginHint, null, false, addParams).then(this.config.openUri).catch(error => {\n console.error('Error in initAuthorizationCodeFlow');\n console.error(error);\n });\n }\n async createChallangeVerifierPairForPKCE() {\n if (!this.crypto) {\n throw new Error('PKCE support for code flow needs a CryptoHander. Did you import the OAuthModule using forRoot() ?');\n }\n const verifier = await this.createNonce();\n const challengeRaw = await this.crypto.calcHash(verifier, 'sha-256');\n const challenge = base64UrlEncode(challengeRaw);\n return [challenge, verifier];\n }\n extractRecognizedCustomParameters(tokenResponse) {\n let foundParameters = new Map();\n if (!this.config.customTokenParameters) {\n return foundParameters;\n }\n this.config.customTokenParameters.forEach(recognizedParameter => {\n if (tokenResponse[recognizedParameter]) {\n foundParameters.set(recognizedParameter, JSON.stringify(tokenResponse[recognizedParameter]));\n }\n });\n return foundParameters;\n }\n /**\r\n * Revokes the auth token to secure the vulnarability\r\n * of the token issued allowing the authorization server to clean\r\n * up any security credentials associated with the authorization\r\n */\n revokeTokenAndLogout(customParameters = {}, ignoreCorsIssues = false) {\n let revokeEndpoint = this.revocationEndpoint;\n let accessToken = this.getAccessToken();\n let refreshToken = this.getRefreshToken();\n if (!accessToken) {\n return Promise.resolve();\n }\n let params = new HttpParams({\n encoder: new WebHttpUrlEncodingCodec()\n });\n let headers = new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded');\n if (this.useHttpBasicAuth) {\n const header = btoa(`${this.clientId}:${this.dummyClientSecret}`);\n headers = headers.set('Authorization', 'Basic ' + header);\n }\n if (!this.useHttpBasicAuth) {\n params = params.set('client_id', this.clientId);\n }\n if (!this.useHttpBasicAuth && this.dummyClientSecret) {\n params = params.set('client_secret', this.dummyClientSecret);\n }\n if (this.customQueryParams) {\n for (const key of Object.getOwnPropertyNames(this.customQueryParams)) {\n params = params.set(key, this.customQueryParams[key]);\n }\n }\n return new Promise((resolve, reject) => {\n let revokeAccessToken;\n let revokeRefreshToken;\n if (accessToken) {\n let revokationParams = params.set('token', accessToken).set('token_type_hint', 'access_token');\n revokeAccessToken = this.http.post(revokeEndpoint, revokationParams, {\n headers\n });\n } else {\n revokeAccessToken = of(null);\n }\n if (refreshToken) {\n let revokationParams = params.set('token', refreshToken).set('token_type_hint', 'refresh_token');\n revokeRefreshToken = this.http.post(revokeEndpoint, revokationParams, {\n headers\n });\n } else {\n revokeRefreshToken = of(null);\n }\n if (ignoreCorsIssues) {\n revokeAccessToken = revokeAccessToken.pipe(catchError(err => {\n if (err.status === 0) {\n return of(null);\n }\n return throwError(err);\n }));\n revokeRefreshToken = revokeRefreshToken.pipe(catchError(err => {\n if (err.status === 0) {\n return of(null);\n }\n return throwError(err);\n }));\n }\n combineLatest([revokeAccessToken, revokeRefreshToken]).subscribe(res => {\n this.logOut(customParameters);\n resolve(res);\n this.logger.info('Token successfully revoked');\n }, err => {\n this.logger.error('Error revoking token', err);\n this.eventsSubject.next(new OAuthErrorEvent('token_revoke_error', err));\n reject(err);\n });\n });\n }\n /**\r\n * Clear location.hash if it's present\r\n */\n clearLocationHash() {\n // Checking for empty hash is necessary for Firefox\n // as setting an empty hash to an empty string adds # to the URL\n if (location.hash != '') {\n location.hash = '';\n }\n }\n }\n OAuthService.ɵfac = function OAuthService_Factory(t) {\n return new (t || OAuthService)(i0.ɵɵinject(i0.NgZone), i0.ɵɵinject(i1.HttpClient), i0.ɵɵinject(OAuthStorage, 8), i0.ɵɵinject(ValidationHandler, 8), i0.ɵɵinject(AuthConfig, 8), i0.ɵɵinject(UrlHelperService), i0.ɵɵinject(OAuthLogger), i0.ɵɵinject(HashHandler, 8), i0.ɵɵinject(DOCUMENT), i0.ɵɵinject(DateTimeProvider));\n };\n OAuthService.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n token: OAuthService,\n factory: OAuthService.ɵfac\n });\n return OAuthService;\n})();\n(() => {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\nclass OAuthResourceServerErrorHandler {}\nclass OAuthNoopResourceServerErrorHandler {\n handleError(err) {\n return throwError(err);\n }\n}\nlet DefaultOAuthInterceptor = /*#__PURE__*/(() => {\n class DefaultOAuthInterceptor {\n constructor(oAuthService, errorHandler, moduleConfig) {\n this.oAuthService = oAuthService;\n this.errorHandler = errorHandler;\n this.moduleConfig = moduleConfig;\n }\n checkUrl(url) {\n if (this.moduleConfig.resourceServer.customUrlValidation) {\n return this.moduleConfig.resourceServer.customUrlValidation(url);\n }\n if (this.moduleConfig.resourceServer.allowedUrls) {\n return !!this.moduleConfig.resourceServer.allowedUrls.find(u => url.toLowerCase().startsWith(u.toLowerCase()));\n }\n return true;\n }\n intercept(req, next) {\n const url = req.url.toLowerCase();\n if (!this.moduleConfig || !this.moduleConfig.resourceServer || !this.checkUrl(url)) {\n return next.handle(req);\n }\n const sendAccessToken = this.moduleConfig.resourceServer.sendAccessToken;\n if (!sendAccessToken) {\n return next.handle(req).pipe(catchError(err => this.errorHandler.handleError(err)));\n }\n return merge(of(this.oAuthService.getAccessToken()).pipe(filter(token => !!token)), this.oAuthService.events.pipe(filter(e => e.type === 'token_received'), timeout(this.oAuthService.waitForTokenInMsec || 0), catchError(_ => of(null)),\n // timeout is not an error\n map(_ => this.oAuthService.getAccessToken()))).pipe(take(1), mergeMap(token => {\n if (token) {\n const header = 'Bearer ' + token;\n const headers = req.headers.set('Authorization', header);\n req = req.clone({\n headers\n });\n }\n return next.handle(req).pipe(catchError(err => this.errorHandler.handleError(err)));\n }));\n }\n }\n DefaultOAuthInterceptor.ɵfac = function DefaultOAuthInterceptor_Factory(t) {\n return new (t || DefaultOAuthInterceptor)(i0.ɵɵinject(OAuthService), i0.ɵɵinject(OAuthResourceServerErrorHandler), i0.ɵɵinject(OAuthModuleConfig, 8));\n };\n DefaultOAuthInterceptor.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n token: DefaultOAuthInterceptor,\n factory: DefaultOAuthInterceptor.ɵfac\n });\n return DefaultOAuthInterceptor;\n})();\n(() => {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\nfunction createDefaultLogger() {\n return console;\n}\nfunction createDefaultStorage() {\n return typeof sessionStorage !== 'undefined' ? sessionStorage : new MemoryStorage();\n}\nfunction provideOAuthClient(config = null, validationHandlerClass = NullValidationHandler) {\n return makeEnvironmentProviders([OAuthService, UrlHelperService, {\n provide: OAuthLogger,\n useFactory: createDefaultLogger\n }, {\n provide: OAuthStorage,\n useFactory: createDefaultStorage\n }, {\n provide: ValidationHandler,\n useClass: validationHandlerClass\n }, {\n provide: HashHandler,\n useClass: DefaultHashHandler\n }, {\n provide: OAuthResourceServerErrorHandler,\n useClass: OAuthNoopResourceServerErrorHandler\n }, {\n provide: OAuthModuleConfig,\n useValue: config\n }, {\n provide: HTTP_INTERCEPTORS,\n useClass: DefaultOAuthInterceptor,\n multi: true\n }, {\n provide: DateTimeProvider,\n useClass: SystemDateTimeProvider\n }]);\n}\nlet OAuthModule = /*#__PURE__*/(() => {\n class OAuthModule {\n static forRoot(config = null, validationHandlerClass = NullValidationHandler) {\n return {\n ngModule: OAuthModule,\n providers: [provideOAuthClient(config, validationHandlerClass)]\n };\n }\n }\n OAuthModule.ɵfac = function OAuthModule_Factory(t) {\n return new (t || OAuthModule)();\n };\n OAuthModule.ɵmod = /* @__PURE__ */i0.ɵɵdefineNgModule({\n type: OAuthModule\n });\n OAuthModule.ɵinj = /* @__PURE__ */i0.ɵɵdefineInjector({\n imports: [CommonModule]\n });\n return OAuthModule;\n})();\n(() => {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\nconst err = `PLEASE READ THIS CAREFULLY:\n\nBeginning with angular-oauth2-oidc version 9, the JwksValidationHandler\nhas been moved to an library of its own. If you need it for implementing\nOAuth2/OIDC **implicit flow**, please install it using npm:\n\n npm i angular-oauth2-oidc-jwks --save\n\nAfter that, you can import it into your application:\n\n import { JwksValidationHandler } from 'angular-oauth2-oidc-jwks';\n\nPlease note, that this dependency is not needed for the **code flow**,\nwhich is nowadays the **recommented** one for single page applications.\nThis also results in smaller bundle sizes.\n`;\n/**\r\n * This is just a dummy of the JwksValidationHandler\r\n * telling the users that the real one has been moved\r\n * to an library of its own, namely angular-oauth2-oidc-utils\r\n */\nclass JwksValidationHandler extends NullValidationHandler {\n constructor() {\n super();\n console.error(err);\n }\n}\nconst AUTH_CONFIG = new InjectionToken('AUTH_CONFIG');\n\n/**\r\n * Generated bundle index. Do not edit.\r\n */\n\nexport { AUTH_CONFIG, AbstractValidationHandler, AuthConfig, DateTimeProvider, DefaultHashHandler, DefaultOAuthInterceptor, HashHandler, JwksValidationHandler, LoginOptions, MemoryStorage, NullValidationHandler, OAuthErrorEvent, OAuthEvent, OAuthInfoEvent, OAuthLogger, OAuthModule, OAuthModuleConfig, OAuthNoopResourceServerErrorHandler, OAuthResourceServerConfig, OAuthResourceServerErrorHandler, OAuthService, OAuthStorage, OAuthSuccessEvent, ReceivedTokens, SystemDateTimeProvider, UrlHelperService, ValidationHandler, provideOAuthClient };\n","export class AuthModel {\r\n authToken?: string;\r\n refreshToken?: string;\r\n expiresIn?: number; // Date;\r\n\r\n setAuth(auth: any) {\r\n this.authToken = auth.authToken;\r\n this.refreshToken = auth.refreshToken;\r\n this.expiresIn = auth.expiresIn;\r\n }\r\n}\r\n","import { AuthModel } from '../auth-models/auth.model';\r\n\r\nexport class UserProfile {\r\n at_hash?: string;\r\n aud?: string;\r\n auth_time?: number;\r\n email?: string;\r\n email_verified?: string;\r\n exp?: number;\r\n given_name?: string;\r\n iat?: number;\r\n idp?: string;\r\n iss?: string;\r\n name?: string;\r\n nbf?: number;\r\n nonce?: string;\r\n phone_number_verified?: string;\r\n preferred_username?: string;\r\n role?: string;\r\n s_hash?: string;\r\n sid?: string;\r\n sub?: string;\r\n}\r\n\r\nexport class UserModel extends AuthModel {\r\n at_hash?: string;\r\n aud?: string;\r\n auth_time?: number;\r\n email?: string;\r\n email_verified?: string;\r\n exp?: number;\r\n given_name?: string;\r\n iat?: number;\r\n idp?: string;\r\n iss?: string;\r\n name?: string;\r\n nbf?: number;\r\n nonce?: string;\r\n phone_number_verified?: string;\r\n preferred_username?: string;\r\n role?: string;\r\n s_hash?: string;\r\n sid?: string;\r\n sub?: string;\r\n pic?: string;\r\n roles?: string[];\r\n fullname?: string;\r\n password?: string;\r\n\r\n setUser(user: any) {\r\n if (user && user.info) {\r\n this.name = user.info.name || '';\r\n this.given_name = user.info.given_name || '';\r\n this.fullname = user.info.preferred_username || user.info.name;\r\n this.email = user.info.email || '';\r\n this.email_verified = user.info.email_verified || 'False';\r\n this.phone_number_verified = user.info.phone_number_verified || 'False';\r\n this.pic = user.info.pic || './assets/media/avatars/default.jpg';\r\n this.roles = [user.info.role] || [];\r\n this.sub = user.info.sub;\r\n }\r\n }\r\n}\r\n","import { isNullOrEmpty } from '@abp/ng.core';\r\nimport { Injectable, OnDestroy } from '@angular/core';\r\nimport { Router } from '@angular/router';\r\nimport { OAuthService } from 'angular-oauth2-oidc';\r\n//import { AbpOAuthModule } from \"@abp/ng.oauth\";\r\nimport { BehaviorSubject, Observable, of } from 'rxjs';\r\nimport { finalize } from 'rxjs/operators';\r\nimport { SubSink } from 'subsink';\r\nimport { UserModel, UserProfile } from '../auth-models/user.model';\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class AppAuthService implements OnDestroy {\r\n isLoading$: Observable;\r\n currentUser$: Observable;\r\n currentUserSubject: BehaviorSubject;\r\n isLoadingSubject: BehaviorSubject;\r\n subs = new SubSink();\r\n\r\n get currentUserValue(): UserModel {\r\n return this.currentUserSubject.value;\r\n }\r\n\r\n set currentUserValue(user: UserModel) {\r\n this.currentUserSubject.next(user);\r\n }\r\n\r\n constructor(private oAuthService: OAuthService, private router: Router) {\r\n this.isLoadingSubject = new BehaviorSubject(false);\r\n this.currentUserSubject = new BehaviorSubject(undefined);\r\n this.currentUser$ = this.currentUserSubject.asObservable();\r\n this.isLoading$ = this.isLoadingSubject.asObservable();\r\n }\r\n\r\n getUserByToken(): Observable {\r\n if (!this.oAuthService.hasValidAccessToken()) {\r\n return of();\r\n }\r\n return of(this.createUserModel(this.oAuthService.getIdentityClaims()));\r\n }\r\n\r\n login(username: string, password: string): any {\r\n try {\r\n if (\r\n !this.oAuthService.hasValidAccessToken() &&\r\n !this.oAuthService.hasValidIdToken()\r\n ) {\r\n this.isLoadingSubject.next(true);\r\n this.oAuthService.oidc = false;\r\n this.oAuthService\r\n .fetchTokenUsingPasswordFlowAndLoadUserProfile(username, password)\r\n .then((userProfile: UserProfile) => {\r\n if (userProfile) {\r\n this.createUserModel(userProfile);\r\n } else {\r\n this.logout();\r\n }\r\n return of(userProfile);\r\n })\r\n .catch((errorResponse) => {\r\n console.log(errorResponse);\r\n this.isLoadingSubject.next(false);\r\n // alert(errorResponse.error.error_description);\r\n }),\r\n finalize(() => this.isLoadingSubject.next(false));\r\n } else {\r\n return of(this.createUserModel(this.oAuthService.getIdentityClaims()));\r\n }\r\n } catch (err) {\r\n throw err;\r\n }\r\n }\r\n\r\n createUserModel(userProfile: any): UserModel {\r\n const userModel = new UserModel();\r\n userModel.setUser(userProfile);\r\n userModel.setAuth(this.getAuthData());\r\n this.currentUserSubject = new BehaviorSubject(userModel);\r\n this.currentUserSubject.next(userModel);\r\n return userModel;\r\n }\r\n\r\n getAuthData(): any {\r\n const authData = {\r\n authToken: this.oAuthService.getAccessToken(),\r\n refreshToken: this.oAuthService.getRefreshToken(),\r\n expiresIn: this.oAuthService.getAccessTokenExpiration(),\r\n };\r\n return authData;\r\n }\r\n\r\n logout() {\r\n this.oAuthService.logOut();\r\n this.router.navigate(['/auth/login']);\r\n }\r\n\r\n ngOnDestroy() {\r\n this.subs.unsubscribe();\r\n }\r\n}\r\n"],"mappings":"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","names":["NullValidationHandler","validationParams","OAuthModuleConfig","DateTimeProvider","SystemDateTimeProvider","ɵSystemDateTimeProvider_BaseFactory","ɵɵgetInheritedFactory","ɵɵdefineInjectable","OAuthLogger","OAuthStorage","MemoryStorage","key","data","t","ɵɵdefineInjectable","OAuthEvent","type","OAuthSuccessEvent","info","OAuthInfoEvent","OAuthErrorEvent","reason","params","b64DecodeUnicode","str","base64","c","base64UrlEncode","AuthConfig","json","uri","WebHttpUrlEncodingCodec","k","v","ValidationHandler","UrlHelperService","customHashFragment","hash","questionMarkPosition","queryString","data","pairs","pair","separatorIndex","escapedKey","escapedValue","key","value","i","t","ɵɵdefineInjectable","digestLength","blockSize","K","hashBlocks","w","v","p","pos","len","a","b","c","d","e","f","g","h","j","t1","t2","Hash","dataLength","dataPos","out","bytesHashed","left","bitLenHi","bitLenLo","padLength","from","hash","data","h","Hash","digest","hkdfSalt","digestLength","HashHandler","decodeUTF8","s","i","d","b","encodeUTF8","arr","DefaultHashHandler","valueToHash","algorithm","__async","hash","byteArray","result","e","buffer","t","ɵɵdefineInjectable","OAuthService","AuthConfig","ngZone","http","storage","tokenValidationHandler","config","urlHelper","logger","crypto","document","dateTimeService","Subject","ua","test","filter","params","listenTo","noPrompt","shouldRunSilentRefresh","tap","debounceTime","_","options","doc","state","args","url","errors","httpsCheck","issuerCheck","lcUrl","description","expiration","storedAt","timeout","of","OAuthInfoEvent","delay","now","delta","duration","maxTimeoutValue","fullUrl","resolve","reject","OAuthErrorEvent","jwks","event","OAuthSuccessEvent","err","userName","password","headers","HttpHeaders","response","info","existingClaims","parameters","grantType","HttpParams","WebHttpUrlEncodingCodec","header","key","tokenResponse","switchMap","from","map","message","claims","existingIframe","iframe","redirectUri","first","success","race","windowRef","checkForPopupClosedTimer","tryLogin","cleanup","checkForPopupClosed","storageListener","listener","height","width","left","top","expectedPrefix","prefixedMessage","origin","issuer","sessionState","loginHint","customRedirectUri","that","nonce","seperationChar","scope","challenge","verifier","additionalState","addParams","error","tokenParams","accessToken","refreshToken","expiresIn","grantedScopes","customParameters","expiresInMilliSeconds","expiresAt","value","queryString","querySource","parts","code","href","nonceInState","userState","requestedRoute","PKCEVerifier","reason","idToken","idx","savedNonce","defaultSkewMsc","skipNonceCheck","tokenParts","headerBase64","headerJson","b64DecodeUnicode","claimsBase64","claimsJson","v","issuedAtMSec","expiresAtMSec","clockSkewInMSec","validationParams","atHashValid","atHashCheckEnabled","scopes","base64data","requestedProperty","noRedirectToLogoutUrl","id_token","customParam","logoutUrl","postLogoutUrl","silentRefreshFrame","sessionCheckFrame","unreserved","size","id","bytes","x","base64UrlEncode","challengeRaw","foundParameters","recognizedParameter","ignoreCorsIssues","revokeEndpoint","revokeAccessToken","revokeRefreshToken","revokationParams","catchError","throwError","combineLatest","res","ɵɵinject","NgZone","HttpClient","OAuthStorage","ValidationHandler","UrlHelperService","OAuthLogger","DOCUMENT","DateTimeProvider","OAuthResourceServerErrorHandler","OAuthNoopResourceServerErrorHandler","DefaultOAuthInterceptor","oAuthService","errorHandler","moduleConfig","u","req","next","merge","token","take","mergeMap","OAuthModuleConfig","createDefaultLogger","createDefaultStorage","MemoryStorage","provideOAuthClient","validationHandlerClass","NullValidationHandler","makeEnvironmentProviders","HTTP_INTERCEPTORS","SystemDateTimeProvider","OAuthModule","ɵɵdefineNgModule","ɵɵdefineInjector","CommonModule","AUTH_CONFIG","InjectionToken","AuthModel","setAuth","auth","authToken","refreshToken","expiresIn","UserModel","AuthModel","setUser","user","info","name","given_name","fullname","preferred_username","email","email_verified","phone_number_verified","pic","roles","role","sub","AppAuthService","currentUserValue","currentUserSubject","value","user","next","constructor","oAuthService","router","subs","SubSink","isLoadingSubject","BehaviorSubject","undefined","currentUser$","asObservable","isLoading$","getUserByToken","hasValidAccessToken","of","createUserModel","getIdentityClaims","login","username","password","hasValidIdToken","oidc","fetchTokenUsingPasswordFlowAndLoadUserProfile","then","userProfile","logout","catch","errorResponse","console","log","finalize","err","userModel","UserModel","setUser","setAuth","getAuthData","authToken","getAccessToken","refreshToken","getRefreshToken","expiresIn","getAccessTokenExpiration","logOut","navigate","ngOnDestroy","unsubscribe","ɵɵinject","OAuthService","Router","factory","ɵfac","providedIn","_AppAuthService"],"x_google_ignoreList":[0]}