@ascentgl/ads-identity 0.9.4 → 0.9.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/ascentgl-ads-identity.mjs +18 -7
- package/fesm2022/ascentgl-ads-identity.mjs.map +1 -1
- package/lib/helpers/token.helper.d.ts +2 -3
- package/lib/interfaces/identity-service.interface.d.ts +5 -3
- package/lib/services/identity.service.d.ts +5 -3
- package/lib/services/token.service.d.ts +8 -7
- package/lib/types/global-types.d.ts +3 -3
- package/lib/types/internal-types.d.ts +16 -3
- package/package.json +1 -1
|
@@ -56,19 +56,19 @@ class TokenHelper {
|
|
|
56
56
|
});
|
|
57
57
|
return payload;
|
|
58
58
|
}
|
|
59
|
-
static isExpired(token,
|
|
59
|
+
static isExpired(token, claim = 'exp', threshold = 0) {
|
|
60
60
|
const throwInvalidColumnError = (column) => {
|
|
61
61
|
throw new InvalidTokenError(`Column ${column} does not contain a valid number`);
|
|
62
62
|
};
|
|
63
63
|
try {
|
|
64
|
-
let timestamp = token[
|
|
64
|
+
let timestamp = token[claim];
|
|
65
65
|
if (typeof timestamp === 'number') {
|
|
66
66
|
if (threshold > 0) {
|
|
67
67
|
timestamp -= threshold;
|
|
68
68
|
}
|
|
69
69
|
return !!timestamp && timestamp * 1000 < new Date().getTime();
|
|
70
70
|
}
|
|
71
|
-
return throwInvalidColumnError(
|
|
71
|
+
return throwInvalidColumnError(claim.toString());
|
|
72
72
|
}
|
|
73
73
|
catch (error) {
|
|
74
74
|
LogHelper.error(new InvalidTokenError(ErrorHelper.extractMessage(error)));
|
|
@@ -115,6 +115,12 @@ class TokenService {
|
|
|
115
115
|
getRefreshToken() {
|
|
116
116
|
return this.updateRefreshTokenSignal(this.getToken("IDMS_RefreshToken", this.refreshToken()?.token));
|
|
117
117
|
}
|
|
118
|
+
clearTokens() {
|
|
119
|
+
localStorage.removeItem("IDMS_AccessToken");
|
|
120
|
+
localStorage.removeItem("IDMS_RefreshToken");
|
|
121
|
+
this.updateAccessTokenSignal(null);
|
|
122
|
+
this.updateRefreshTokenSignal(null);
|
|
123
|
+
}
|
|
118
124
|
updateAccessTokenSignal(newToken) {
|
|
119
125
|
if (this.accessToken()?.token !== newToken?.token) {
|
|
120
126
|
this.accessToken.set(newToken);
|
|
@@ -154,7 +160,7 @@ class TokenService {
|
|
|
154
160
|
const payload = TokenHelper.getPayload(token, {
|
|
155
161
|
iss: this.getIssuers(),
|
|
156
162
|
sub: this.options.application,
|
|
157
|
-
},
|
|
163
|
+
}, 60);
|
|
158
164
|
return { token, payload: payload };
|
|
159
165
|
}
|
|
160
166
|
getIssuers() {
|
|
@@ -169,7 +175,6 @@ class TokenService {
|
|
|
169
175
|
else {
|
|
170
176
|
this.issuers.push(`${issuer}/api`);
|
|
171
177
|
}
|
|
172
|
-
console.log(this.issuers);
|
|
173
178
|
return this.issuers;
|
|
174
179
|
}
|
|
175
180
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: TokenService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
@@ -189,6 +194,9 @@ class IdentityService {
|
|
|
189
194
|
this.options = inject(IDENTITY_OPTIONS);
|
|
190
195
|
}
|
|
191
196
|
isAuthenticated() {
|
|
197
|
+
return !!this.tokenService.getAccessToken();
|
|
198
|
+
}
|
|
199
|
+
authenticate() {
|
|
192
200
|
const accessToken = this.tokenService.getAccessToken();
|
|
193
201
|
const refreshToken = this.tokenService.getRefreshToken();
|
|
194
202
|
if (accessToken) {
|
|
@@ -216,6 +224,9 @@ class IdentityService {
|
|
|
216
224
|
return this.tokenService.setAccessToken(response.access_token);
|
|
217
225
|
}));
|
|
218
226
|
}
|
|
227
|
+
clearTokens() {
|
|
228
|
+
this.tokenService.clearTokens();
|
|
229
|
+
}
|
|
219
230
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: IdentityService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
220
231
|
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: IdentityService, providedIn: 'root' }); }
|
|
221
232
|
}
|
|
@@ -227,7 +238,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImpor
|
|
|
227
238
|
const IDENTITY_AUTH_GUARD = (_route, state) => {
|
|
228
239
|
const identityService = inject(IdentityService);
|
|
229
240
|
const options = inject(IDENTITY_OPTIONS);
|
|
230
|
-
return identityService.
|
|
241
|
+
return identityService.authenticate().pipe(catchError((error) => {
|
|
231
242
|
window.location.href = `${options.frontendUrl}/apps/${options.application}?redirect=true&redirect_path=${encodeURIComponent(state.url)}`;
|
|
232
243
|
LogHelper.error(error);
|
|
233
244
|
return of(null);
|
|
@@ -288,7 +299,7 @@ function requestInterceptor(request, next) {
|
|
|
288
299
|
if (RequestHelper.isIdentityEndpointRequest(request) || !RequestHelper.isAuthorizedRequest(request)) {
|
|
289
300
|
return next(request);
|
|
290
301
|
}
|
|
291
|
-
return identityService.
|
|
302
|
+
return identityService.authenticate().pipe(catchError((error) => RequestHelper.onAuthorizationError(error, injector)), switchMap((accessToken) => next(RequestHelper.attachAuthorizationHeader(request, accessToken))));
|
|
292
303
|
}
|
|
293
304
|
|
|
294
305
|
function responseInterceptor(request, next) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ascentgl-ads-identity.mjs","sources":["../../../../libs/ads-identity/src/lib/helpers/log.helper.ts","../../../../libs/ads-identity/src/lib/helpers/error.helper.ts","../../../../libs/ads-identity/src/lib/helpers/token.helper.ts","../../../../libs/ads-identity/src/lib/types/internal-consts.ts","../../../../libs/ads-identity/src/lib/services/token.service.ts","../../../../libs/ads-identity/src/lib/services/identity.service.ts","../../../../libs/ads-identity/src/lib/guards/auth.guard.ts","../../../../libs/ads-identity/src/lib/guards/auth-callback.guard.ts","../../../../libs/ads-identity/src/lib/helpers/request.helper.ts","../../../../libs/ads-identity/src/lib/interceptors/request.interceptor.ts","../../../../libs/ads-identity/src/lib/interceptors/response.interceptor.ts","../../../../libs/ads-identity/src/lib/providers/identity.provider.ts"],"sourcesContent":["import { IdentityOptions } from '../types/internal-types';\r\n\r\nexport class LogHelper {\r\n static options?: IdentityOptions;\r\n\r\n private static readonly prefix = 'ADS-IDENTITY';\r\n\r\n static log(...args: unknown[]) {\r\n if (!this.options?.debugMode) return false;\r\n\r\n console.group(this.prefix, 'TOKEN UPDATE');\r\n\r\n console.log(...args);\r\n\r\n console.groupEnd();\r\n\r\n return true;\r\n }\r\n\r\n static error(...args: unknown[]) {\r\n if (!this.options?.debugMode) return false;\r\n\r\n console.group(this.prefix, 'EXCEPTION');\r\n\r\n console.error(...args);\r\n\r\n console.groupEnd();\r\n\r\n return true;\r\n }\r\n}\r\n","import { HttpErrorResponse } from '@angular/common/http';\r\nimport { GenericCollection } from '../types/internal-types';\r\n\r\nexport class ErrorHelper {\r\n static extractMessage(error: unknown): string {\r\n if (typeof error === 'string' && error) {\r\n return error;\r\n }\r\n\r\n let errorMessage: unknown;\r\n\r\n if (error instanceof HttpErrorResponse) {\r\n errorMessage = error.error?.message ?? error.message;\r\n }\r\n\r\n if (!errorMessage && typeof error === 'object' && typeof (<GenericCollection>error)['message'] === 'string') {\r\n errorMessage = (<GenericCollection>error)['message'];\r\n }\r\n\r\n return errorMessage && typeof errorMessage === 'string' ? errorMessage : 'Unknown server error';\r\n }\r\n}\r\n","import { InvalidTokenError, jwtDecode, JwtPayload } from 'jwt-decode';\r\nimport { GenericCollection, JwtClaim, TokenClaim } from '../types/internal-types';\r\nimport { LogHelper } from './log.helper';\r\nimport { ErrorHelper } from './error.helper';\r\n\r\nexport class TokenHelper {\r\n static getPayload<T extends JwtPayload>(token: string, verifyClaims: GenericCollection = {}, threshold = 0): T {\r\n const payload = jwtDecode(token) satisfies T;\r\n\r\n /**\r\n * throw error if token is expired\r\n */\r\n if (this.isExpired(payload, 'exp', threshold)) {\r\n throw new InvalidTokenError('Token expired');\r\n }\r\n\r\n /**\r\n * loop through claims to verify and make sure the payload match their values\r\n */\r\n (<JwtClaim[]>Object.keys(verifyClaims)).forEach((claim) => {\r\n const tokenClaimValue = payload[claim];\r\n const requestedClaimValue = verifyClaims[claim];\r\n\r\n if (!this.isClaimValid(tokenClaimValue, requestedClaimValue)) {\r\n throw new InvalidTokenError(\r\n `Invalid \"${claim}\" claim value \"${tokenClaimValue}\" provided in token. Required value is \"${requestedClaimValue}\"`,\r\n );\r\n }\r\n });\r\n\r\n return payload;\r\n }\r\n\r\n private static isExpired<T extends JwtPayload>(token: T, column: keyof T = 'exp', threshold = 0): boolean {\r\n const throwInvalidColumnError = (column: string): true => {\r\n throw new InvalidTokenError(`Column ${column} does not contain a valid number`);\r\n };\r\n\r\n try {\r\n /**\r\n * get value from the column\r\n */\r\n let timestamp: unknown = token[column];\r\n\r\n /**\r\n * if values is a number - compare it against current date\r\n */\r\n if (typeof timestamp === 'number') {\r\n /**\r\n * if threshold is set - extract it from the timestamp\r\n * NOTE: threshold allows to consider the timestamp expired earlier;\r\n * this allows to make sure the token does not expire while being transferred to backend\r\n */\r\n if (threshold > 0) {\r\n timestamp -= threshold;\r\n }\r\n\r\n return !!timestamp && timestamp * 1000 < new Date().getTime();\r\n }\r\n\r\n return throwInvalidColumnError(column.toString());\r\n } catch (error: unknown) {\r\n LogHelper.error(new InvalidTokenError(ErrorHelper.extractMessage(error)));\r\n\r\n return true;\r\n }\r\n }\r\n\r\n private static isClaimValid(tokenClaim: TokenClaim, valueToVerify: unknown) {\r\n /**\r\n * if any of the values is an array - apply special logic;\r\n * otherwise do strict comparison\r\n */\r\n if (tokenClaim instanceof Array || valueToVerify instanceof Array) {\r\n /**\r\n * if both claims are arrays - make sure they intersect\r\n */\r\n if (tokenClaim instanceof Array && valueToVerify instanceof Array) {\r\n return tokenClaim.filter((value) => valueToVerify.includes(value)).length > 0;\r\n }\r\n\r\n /**\r\n * if the first claim is an array and the second is a string -\r\n * check if the second is within the first\r\n */\r\n if (tokenClaim instanceof Array && typeof valueToVerify === 'string') {\r\n return tokenClaim.includes(valueToVerify);\r\n }\r\n\r\n /**\r\n * if the second claim is an array and the first is a string -\r\n * check if the first is within the second\r\n */\r\n if (valueToVerify instanceof Array && typeof tokenClaim === 'string') {\r\n return valueToVerify.includes(tokenClaim);\r\n }\r\n\r\n return false;\r\n }\r\n\r\n return tokenClaim === valueToVerify;\r\n }\r\n}\r\n","import { InjectionToken } from '@angular/core';\r\nimport { IdentityOptions } from './internal-types';\r\n\r\nexport const IDENTITY_OPTIONS = new InjectionToken<IdentityOptions>('IDENTITY_OPTIONS');\r\n","import { computed, inject, Injectable, signal } from '@angular/core';\r\nimport { IdentityToken, Maybe, Nullable } from '../types/internal-types';\r\nimport { AccessToken, RefreshToken } from '../types/global-types';\r\nimport { TokenHelper } from '../helpers/token.helper';\r\nimport { InvalidTokenError } from 'jwt-decode';\r\nimport { IDENTITY_OPTIONS } from '../types/internal-consts';\r\nimport { TokenKey } from '../types/internal-enums';\r\nimport { LogHelper } from '../helpers/log.helper';\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class TokenService {\r\n /**\r\n * NOTE: we expose access and refresh tokens as computed signals so that they can be\r\n * used in \"IdentityService\" to allow library users reactive readonly access to tokens,\r\n * since \"IdentityService\" is the only \"public\" service in the library\r\n */\r\n readonlyAccessToken = computed(() => this.accessToken());\r\n readonlyRefreshToken = computed(() => this.refreshToken());\r\n\r\n private accessToken = signal<Nullable<AccessToken>>(null);\r\n private refreshToken = signal<Nullable<RefreshToken>>(null);\r\n\r\n private readonly options = inject(IDENTITY_OPTIONS);\r\n\r\n private issuers: string[] = [];\r\n\r\n setAccessToken(token: unknown) {\r\n return this.updateAccessTokenSignal<IdentityToken>(this.setToken(TokenKey.accessToken, token));\r\n }\r\n\r\n getAccessToken() {\r\n return this.updateAccessTokenSignal(this.getToken(TokenKey.accessToken, this.accessToken()?.token));\r\n }\r\n\r\n setRefreshToken(token: unknown) {\r\n return this.updateRefreshTokenSignal<IdentityToken>(this.setToken(TokenKey.refreshToken, token));\r\n }\r\n\r\n getRefreshToken() {\r\n return this.updateRefreshTokenSignal(this.getToken(TokenKey.refreshToken, this.refreshToken()?.token));\r\n }\r\n\r\n private updateAccessTokenSignal<T extends Nullable<IdentityToken>>(newToken: Nullable<AccessToken>): T {\r\n if (this.accessToken()?.token !== newToken?.token) {\r\n this.accessToken.set(newToken);\r\n }\r\n\r\n return <T>this.accessToken();\r\n }\r\n\r\n private updateRefreshTokenSignal<T extends Nullable<IdentityToken>>(newToken: Nullable<RefreshToken>): T {\r\n if (this.refreshToken()?.token !== newToken?.token) {\r\n this.refreshToken.set(newToken);\r\n }\r\n\r\n return <T>this.refreshToken();\r\n }\r\n\r\n private setToken(key: TokenKey, token: unknown): IdentityToken {\r\n /**\r\n * make sure provided token is at least a string\r\n */\r\n if (typeof token !== 'string') {\r\n throw new InvalidTokenError(`Provided ${key} value is not a string`);\r\n }\r\n\r\n /**\r\n * get identity token\r\n */\r\n const identityToken = this.wrapToken(token);\r\n\r\n /**\r\n * if provided - save it to local storage\r\n */\r\n if (identityToken) {\r\n localStorage.setItem(key, token);\r\n }\r\n\r\n LogHelper.log(key, identityToken);\r\n\r\n return identityToken;\r\n }\r\n\r\n private getToken(key: TokenKey, token: Maybe<string>): Nullable<IdentityToken> {\r\n /**\r\n * either use provided token value or get one from the local storage\r\n */\r\n const actualToken = token ?? localStorage.getItem(key) ?? null;\r\n\r\n if (typeof actualToken === 'string') {\r\n try {\r\n return this.wrapToken(actualToken);\r\n } catch (error) {\r\n LogHelper.error(error);\r\n }\r\n }\r\n\r\n return null;\r\n }\r\n\r\n private wrapToken(token: string): IdentityToken {\r\n /**\r\n * parse token and obtain its payload\r\n * NOTE: errors will be thrown if token is expired or has invalid claims\r\n */\r\n const payload = TokenHelper.getPayload(\r\n token,\r\n {\r\n iss: this.getIssuers(),\r\n sub: this.options.application,\r\n },\r\n 10,\r\n );\r\n\r\n /**\r\n * return identity token object\r\n */\r\n return <IdentityToken>{ token, payload: payload };\r\n }\r\n\r\n private getIssuers(): string[] {\r\n /**\r\n * if we already have issuers - ise them\r\n */\r\n if (this.issuers.length) {\r\n return this.issuers;\r\n }\r\n\r\n /**\r\n * get issuer value from the options\r\n */\r\n const issuer = this.options.serviceIssuer ?? this.options.backendUrl;\r\n\r\n this.issuers = [issuer];\r\n\r\n /**\r\n * make sure we have both variants (with and without \"/api\" suffix) as issuers\r\n * todo \"/api\" suffix verification must be removed when \"/api\" suffix will be removed from the \"issuer\" in IDMS\r\n */\r\n if (issuer.endsWith('/api')) {\r\n this.issuers.push(issuer.substring(0, issuer.lastIndexOf('/api')));\r\n } else {\r\n this.issuers.push(`${issuer}/api`);\r\n }\r\n console.log(this.issuers);\r\n return this.issuers;\r\n }\r\n}\r\n","import { computed, inject, Injectable } from '@angular/core';\r\nimport { catchError, map, Observable, of, throwError } from 'rxjs';\r\nimport { TokenService } from './token.service';\r\nimport { HttpClient } from '@angular/common/http';\r\nimport { IDENTITY_OPTIONS } from '../types/internal-consts';\r\nimport { RefreshTokenResponse } from '../types/internal-types';\r\nimport { LogHelper } from '../helpers/log.helper';\r\nimport { AccessToken } from '../types/global-types';\r\nimport { InvalidTokenError } from 'jwt-decode';\r\nimport { ErrorHelper } from '../helpers/error.helper';\r\nimport { IdentityServiceInterface } from '../interfaces/identity-service.interface';\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class IdentityService implements IdentityServiceInterface {\r\n /**\r\n * NOTE: we expose access and refresh tokens as computed signals to allow\r\n * library users reactive readonly access to tokens, since \"IdentityService\"\r\n * is the only \"public\" service in the library\r\n */\r\n accessToken = computed(() => this.tokenService.readonlyAccessToken());\r\n refreshToken = computed(() => this.tokenService.readonlyRefreshToken());\r\n\r\n private readonly tokenService = inject(TokenService);\r\n private readonly httpClient = inject(HttpClient);\r\n private readonly options = inject(IDENTITY_OPTIONS);\r\n\r\n isAuthenticated(): Observable<AccessToken> {\r\n /**\r\n * get access and refresh token\r\n */\r\n const accessToken = this.tokenService.getAccessToken();\r\n const refreshToken = this.tokenService.getRefreshToken();\r\n\r\n /**\r\n * if it is available - return it; otherwise try refreshing the tokens by calling IDMS\r\n */\r\n if (accessToken) {\r\n return of(accessToken);\r\n }\r\n\r\n /**\r\n * if refresh token is available - try getting new tokens\r\n */\r\n if (refreshToken) {\r\n return this.refreshTokens();\r\n }\r\n\r\n /**\r\n * throw error if no tokens are available\r\n */\r\n return throwError(() => new InvalidTokenError('No valid tokens found'));\r\n }\r\n\r\n refreshTokens(): Observable<AccessToken> {\r\n const refreshToken = this.tokenService.getRefreshToken();\r\n\r\n /**\r\n * throw error if refresh token is not available\r\n */\r\n if (!refreshToken) {\r\n return throwError(() => new InvalidTokenError('No refresh token found'));\r\n }\r\n\r\n /**\r\n * make request to Identity service to get new tokens\r\n */\r\n return this.httpClient\r\n .get<RefreshTokenResponse>(`${this.options.backendUrl}/api/v${this.options.apiVersion ?? 1}/refresh-token`, {\r\n headers: { Authorization: `Bearer ${refreshToken.token}` },\r\n })\r\n .pipe(\r\n catchError((error: unknown) => {\r\n /**\r\n * log error if it happens\r\n */\r\n LogHelper.error(\r\n new InvalidTokenError(\r\n `Failed to obtain tokens. Reason: ${ErrorHelper.extractMessage(error).toLowerCase()}`,\r\n ),\r\n );\r\n\r\n return throwError(() => error);\r\n }),\r\n map((response) => {\r\n /**\r\n * set refresh token\r\n */\r\n this.tokenService.setRefreshToken(response.refresh_token);\r\n\r\n /**\r\n * set and return access token\r\n */\r\n return this.tokenService.setAccessToken(response.access_token);\r\n }),\r\n );\r\n }\r\n}\r\n","import { CanActivateFn } from '@angular/router';\r\nimport { inject } from '@angular/core';\r\nimport { IdentityService } from '../services/identity.service';\r\nimport { catchError, map, of } from 'rxjs';\r\nimport { IDENTITY_OPTIONS } from '../types/internal-consts';\r\nimport { LogHelper } from '../helpers/log.helper';\r\n\r\nexport const IDENTITY_AUTH_GUARD: CanActivateFn = (_route, state) => {\r\n const identityService = inject(IdentityService);\r\n const options = inject(IDENTITY_OPTIONS);\r\n\r\n /**\r\n * check if user is authenticated;\r\n * if error happened - redirect to IDMS url to re-login;\r\n * return true on success and false on error\r\n */\r\n return identityService.isAuthenticated().pipe(\r\n catchError((error) => {\r\n window.location.href = `${options.frontendUrl}/apps/${options.application}?redirect=true&redirect_path=${encodeURIComponent(\r\n state.url,\r\n )}`;\r\n\r\n LogHelper.error(error);\r\n\r\n return of(null);\r\n }),\r\n map((accessToken) => !!accessToken),\r\n );\r\n};\r\n","import { CanActivateFn, Router } from '@angular/router';\r\nimport { inject } from '@angular/core';\r\nimport { TokenService } from '../services/token.service';\r\nimport { LogHelper } from '../helpers/log.helper';\r\nimport { ErrorHelper } from '../helpers/error.helper';\r\n\r\nexport const IDENTITY_AUTH_CALLBACK_GUARD: CanActivateFn = (route) => {\r\n const router = inject(Router);\r\n const tokenService = inject(TokenService);\r\n\r\n const throwAccessDenied = () => {\r\n throw new Error('Access denied');\r\n };\r\n\r\n /**\r\n * save access and refresh tokens and redirect either to root or to provided \"redirect_path\";\r\n * if error happened - display error message on the page and return false to stop further navigation\r\n */\r\n try {\r\n if (!route.queryParams['access_token'] || !route.queryParams['access_token']) {\r\n throwAccessDenied();\r\n }\r\n\r\n tokenService.setAccessToken(route.queryParams['access_token']);\r\n\r\n tokenService.setRefreshToken(route.queryParams['refresh_token']);\r\n\r\n return router.navigateByUrl(route.queryParams['redirect_path'] || '/');\r\n } catch (error: unknown) {\r\n const routerOutlet = document.body.querySelector('router-outlet');\r\n\r\n if (routerOutlet) {\r\n routerOutlet.innerHTML = ErrorHelper.extractMessage(error);\r\n }\r\n\r\n LogHelper.error(error);\r\n\r\n return false;\r\n }\r\n};\r\n","import { HttpErrorResponse, HttpRequest } from '@angular/common/http';\r\nimport { throwError } from 'rxjs';\r\nimport { Injector } from '@angular/core';\r\nimport { IdentityOptions } from '../types/internal-types';\r\nimport { AccessToken } from '../types/global-types';\r\n\r\nexport class RequestHelper {\r\n static options?: IdentityOptions;\r\n\r\n static isIdentityEndpointRequest(request: HttpRequest<unknown>): boolean {\r\n return (\r\n (!!this.options?.backendUrl && request.url.startsWith(this.options?.backendUrl)) ||\r\n (!!this.options?.frontendUrl && request.url.startsWith(this.options?.frontendUrl))\r\n );\r\n }\r\n\r\n static isAuthorizedRequest(request: HttpRequest<unknown>): boolean {\r\n return !this.options?.requestFilter || this.options.requestFilter(request);\r\n }\r\n\r\n static isAuthorizationError(error: unknown): boolean {\r\n return error instanceof HttpErrorResponse && error.status === 401;\r\n }\r\n\r\n static attachAuthorizationHeader(request: HttpRequest<unknown>, accessToken: AccessToken): HttpRequest<unknown> {\r\n return request.clone({\r\n setHeaders: { authorization: `Bearer ${accessToken.token}`, 'auth-source': 'IDMS' },\r\n });\r\n }\r\n\r\n static onAuthorizationError(error: unknown, injector: Injector) {\r\n if (this.options?.onAuthorizationError) {\r\n this.options?.onAuthorizationError(error, injector);\r\n }\r\n\r\n return throwError(() => error);\r\n }\r\n}\r\n","import { HttpEvent, HttpHandlerFn, HttpRequest } from '@angular/common/http';\r\nimport { catchError, Observable, switchMap } from 'rxjs';\r\nimport { inject, Injector } from '@angular/core';\r\nimport { IdentityService } from '../services/identity.service';\r\nimport { RequestHelper } from '../helpers/request.helper';\r\n\r\nexport function requestInterceptor(request: HttpRequest<unknown>, next: HttpHandlerFn): Observable<HttpEvent<unknown>> {\r\n const identityService = inject(IdentityService);\r\n const injector = inject(Injector);\r\n\r\n /**\r\n * if it is a request to Identity Service or not an authorized request - do not modify it\r\n */\r\n if (RequestHelper.isIdentityEndpointRequest(request) || !RequestHelper.isAuthorizedRequest(request)) {\r\n return next(request);\r\n }\r\n\r\n /**\r\n * if current user is authenticated - attach \"Authorization\" header to the request;\r\n * or process the error if it happens\r\n */\r\n return identityService.isAuthenticated().pipe(\r\n catchError((error: unknown) => RequestHelper.onAuthorizationError(error, injector)),\r\n switchMap((accessToken) => next(RequestHelper.attachAuthorizationHeader(request, accessToken))),\r\n );\r\n}\r\n","import { HttpEvent, HttpHandlerFn, HttpRequest } from '@angular/common/http';\r\nimport { catchError, Observable, switchMap, throwError } from 'rxjs';\r\nimport { inject, Injector } from '@angular/core';\r\nimport { IdentityService } from '../services/identity.service';\r\nimport { IDENTITY_OPTIONS } from '../types/internal-consts';\r\nimport { RequestHelper } from '../helpers/request.helper';\r\n\r\nexport function responseInterceptor(\r\n request: HttpRequest<unknown>,\r\n next: HttpHandlerFn,\r\n): Observable<HttpEvent<unknown>> {\r\n const options = inject(IDENTITY_OPTIONS);\r\n const identityService = inject(IdentityService);\r\n const injector = inject(Injector);\r\n\r\n /**\r\n * process all response errors\r\n */\r\n return next(request).pipe(\r\n catchError((error: unknown) => {\r\n /**\r\n * if error happened with Identity Service request, or not-authorized request, or it is not an authorization (401) error -\r\n * do not change anything and return the error as is\r\n */\r\n if (\r\n RequestHelper.isIdentityEndpointRequest(request) ||\r\n !RequestHelper.isAuthorizedRequest(request) ||\r\n !RequestHelper.isAuthorizationError(error)\r\n ) {\r\n return throwError(() => error);\r\n }\r\n\r\n /**\r\n * if options do not allow to try and refresh tokens on error 401 -\r\n * process the error and return it\r\n */\r\n if (!options.refreshTokenOnAuthError) {\r\n return RequestHelper.onAuthorizationError(error, injector);\r\n }\r\n\r\n /**\r\n * if tokens were refreshed - attach \"Authorization\" header to the request and call it again;\r\n * or process the error if it happens\r\n */\r\n return identityService.refreshTokens().pipe(\r\n switchMap((accessToken) => next(RequestHelper.attachAuthorizationHeader(request, accessToken))),\r\n catchError((error: unknown) => RequestHelper.onAuthorizationError(error, injector)),\r\n );\r\n }),\r\n );\r\n}\r\n","import { provideHttpClient, withInterceptors } from '@angular/common/http';\r\nimport { requestInterceptor } from '../interceptors/request.interceptor';\r\nimport { responseInterceptor } from '../interceptors/response.interceptor';\r\nimport { IDENTITY_OPTIONS } from '../types/internal-consts';\r\nimport { LogHelper } from '../helpers/log.helper';\r\nimport { RequestHelper } from '../helpers/request.helper';\r\nimport { IdentityOptions } from '../types/internal-types';\r\n\r\nexport function provideIdentity(options: IdentityOptions) {\r\n LogHelper.options = options;\r\n RequestHelper.options = options;\r\n\r\n return [\r\n { provide: IDENTITY_OPTIONS, useValue: options },\r\n provideHttpClient(withInterceptors([requestInterceptor, responseInterceptor])),\r\n ];\r\n}\r\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ascentgl-ads-identity.mjs","sources":["../../../../libs/ads-identity/src/lib/helpers/log.helper.ts","../../../../libs/ads-identity/src/lib/helpers/error.helper.ts","../../../../libs/ads-identity/src/lib/helpers/token.helper.ts","../../../../libs/ads-identity/src/lib/types/internal-consts.ts","../../../../libs/ads-identity/src/lib/services/token.service.ts","../../../../libs/ads-identity/src/lib/services/identity.service.ts","../../../../libs/ads-identity/src/lib/guards/auth.guard.ts","../../../../libs/ads-identity/src/lib/guards/auth-callback.guard.ts","../../../../libs/ads-identity/src/lib/helpers/request.helper.ts","../../../../libs/ads-identity/src/lib/interceptors/request.interceptor.ts","../../../../libs/ads-identity/src/lib/interceptors/response.interceptor.ts","../../../../libs/ads-identity/src/lib/providers/identity.provider.ts"],"sourcesContent":["import { IdentityOptions } from '../types/internal-types';\r\n\r\nexport class LogHelper {\r\n static options?: IdentityOptions;\r\n\r\n private static readonly prefix = 'ADS-IDENTITY';\r\n\r\n static log(...args: unknown[]) {\r\n if (!this.options?.debugMode) return false;\r\n\r\n console.group(this.prefix, 'TOKEN UPDATE');\r\n\r\n console.log(...args);\r\n\r\n console.groupEnd();\r\n\r\n return true;\r\n }\r\n\r\n static error(...args: unknown[]) {\r\n if (!this.options?.debugMode) return false;\r\n\r\n console.group(this.prefix, 'EXCEPTION');\r\n\r\n console.error(...args);\r\n\r\n console.groupEnd();\r\n\r\n return true;\r\n }\r\n}\r\n","import { HttpErrorResponse } from '@angular/common/http';\r\nimport { GenericCollection } from '../types/internal-types';\r\n\r\nexport class ErrorHelper {\r\n static extractMessage(error: unknown): string {\r\n if (typeof error === 'string' && error) {\r\n return error;\r\n }\r\n\r\n let errorMessage: unknown;\r\n\r\n if (error instanceof HttpErrorResponse) {\r\n errorMessage = error.error?.message ?? error.message;\r\n }\r\n\r\n if (!errorMessage && typeof error === 'object' && typeof (<GenericCollection>error)['message'] === 'string') {\r\n errorMessage = (<GenericCollection>error)['message'];\r\n }\r\n\r\n return errorMessage && typeof errorMessage === 'string' ? errorMessage : 'Unknown server error';\r\n }\r\n}\r\n","import { InvalidTokenError, jwtDecode } from 'jwt-decode';\r\nimport { GenericCollection, IdentityJwtClaim, AccessTokenPayload, RefreshTokenPayload } from '../types/internal-types';\r\nimport { LogHelper } from './log.helper';\r\nimport { ErrorHelper } from './error.helper';\r\n\r\nexport class TokenHelper {\r\n static getPayload<T extends AccessTokenPayload | RefreshTokenPayload>(\r\n token: string,\r\n verifyClaims: GenericCollection = {},\r\n threshold = 0,\r\n ): T {\r\n const payload: T = jwtDecode(token);\r\n\r\n /**\r\n * throw error if token is expired\r\n */\r\n if (this.isExpired(payload, 'exp', threshold)) {\r\n throw new InvalidTokenError('Token expired');\r\n }\r\n\r\n /**\r\n * loop through claims to verify and make sure the payload match their values\r\n */\r\n Object.keys(verifyClaims).forEach((claim) => {\r\n const tokenClaimValue = payload[claim];\r\n const requestedClaimValue = verifyClaims[claim];\r\n\r\n if (!this.isClaimValid(tokenClaimValue, requestedClaimValue)) {\r\n throw new InvalidTokenError(\r\n `Invalid \"${claim}\" claim value \"${tokenClaimValue}\" provided in token. Required value is \"${requestedClaimValue}\"`,\r\n );\r\n }\r\n });\r\n\r\n return payload;\r\n }\r\n\r\n private static isExpired<T extends AccessTokenPayload | RefreshTokenPayload>(\r\n token: T,\r\n claim: IdentityJwtClaim = 'exp',\r\n threshold = 0,\r\n ): boolean {\r\n const throwInvalidColumnError = (column: string): true => {\r\n throw new InvalidTokenError(`Column ${column} does not contain a valid number`);\r\n };\r\n\r\n try {\r\n /**\r\n * get value from the column\r\n */\r\n let timestamp: unknown = token[claim];\r\n\r\n /**\r\n * if values is a number - compare it against current date\r\n */\r\n if (typeof timestamp === 'number') {\r\n /**\r\n * if threshold is set - extract it from the timestamp\r\n * NOTE: threshold allows to consider the timestamp expired earlier;\r\n * this allows to make sure the token does not expire while being transferred to backend\r\n */\r\n if (threshold > 0) {\r\n timestamp -= threshold;\r\n }\r\n\r\n return !!timestamp && timestamp * 1000 < new Date().getTime();\r\n }\r\n\r\n return throwInvalidColumnError(claim.toString());\r\n } catch (error: unknown) {\r\n LogHelper.error(new InvalidTokenError(ErrorHelper.extractMessage(error)));\r\n\r\n return true;\r\n }\r\n }\r\n\r\n private static isClaimValid(tokenClaim: unknown, valueToVerify: unknown) {\r\n /**\r\n * if any of the values is an array - apply special logic;\r\n * otherwise do strict comparison\r\n */\r\n if (tokenClaim instanceof Array || valueToVerify instanceof Array) {\r\n /**\r\n * if both claims are arrays - make sure they intersect\r\n */\r\n if (tokenClaim instanceof Array && valueToVerify instanceof Array) {\r\n return tokenClaim.filter((value) => valueToVerify.includes(value)).length > 0;\r\n }\r\n\r\n /**\r\n * if the first claim is an array and the second is a string -\r\n * check if the second is within the first\r\n */\r\n if (tokenClaim instanceof Array && typeof valueToVerify === 'string') {\r\n return tokenClaim.includes(valueToVerify);\r\n }\r\n\r\n /**\r\n * if the second claim is an array and the first is a string -\r\n * check if the first is within the second\r\n */\r\n if (valueToVerify instanceof Array && typeof tokenClaim === 'string') {\r\n return valueToVerify.includes(tokenClaim);\r\n }\r\n\r\n return false;\r\n }\r\n\r\n return tokenClaim === valueToVerify;\r\n }\r\n}\r\n","import { InjectionToken } from '@angular/core';\r\nimport { IdentityOptions } from './internal-types';\r\n\r\nexport const IDENTITY_OPTIONS = new InjectionToken<IdentityOptions>('IDENTITY_OPTIONS');\r\n","import { computed, inject, Injectable, signal } from '@angular/core';\r\nimport { IdentityToken, Maybe, Nullable } from '../types/internal-types';\r\nimport { AccessToken, RefreshToken } from '../types/global-types';\r\nimport { TokenHelper } from '../helpers/token.helper';\r\nimport { InvalidTokenError } from 'jwt-decode';\r\nimport { IDENTITY_OPTIONS } from '../types/internal-consts';\r\nimport { TokenKey } from '../types/internal-enums';\r\nimport { LogHelper } from '../helpers/log.helper';\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class TokenService {\r\n /**\r\n * NOTE: we expose access and refresh tokens as computed signals so that they can be\r\n * used in \"IdentityService\" to allow library users reactive readonly access to tokens,\r\n * since \"IdentityService\" is the only \"public\" service in the library\r\n */\r\n readonlyAccessToken = computed(() => this.accessToken());\r\n readonlyRefreshToken = computed(() => this.refreshToken());\r\n\r\n private readonly accessToken = signal<Nullable<AccessToken>>(null);\r\n private readonly refreshToken = signal<Nullable<RefreshToken>>(null);\r\n\r\n private readonly options = inject(IDENTITY_OPTIONS);\r\n\r\n private issuers: string[] = [];\r\n\r\n setAccessToken(token: unknown) {\r\n return this.updateAccessTokenSignal<AccessToken>(this.setToken<AccessToken>(TokenKey.accessToken, token));\r\n }\r\n\r\n getAccessToken() {\r\n return this.updateAccessTokenSignal(this.getToken(TokenKey.accessToken, this.accessToken()?.token));\r\n }\r\n\r\n setRefreshToken(token: unknown) {\r\n return this.updateRefreshTokenSignal<RefreshToken>(this.setToken(TokenKey.refreshToken, token));\r\n }\r\n\r\n getRefreshToken() {\r\n return this.updateRefreshTokenSignal(this.getToken(TokenKey.refreshToken, this.refreshToken()?.token));\r\n }\r\n\r\n clearTokens() {\r\n localStorage.removeItem(TokenKey.accessToken);\r\n localStorage.removeItem(TokenKey.refreshToken);\r\n\r\n this.updateAccessTokenSignal(null);\r\n this.updateRefreshTokenSignal(null);\r\n }\r\n\r\n private updateAccessTokenSignal<T extends Nullable<AccessToken>>(newToken: Nullable<AccessToken>): T {\r\n if (this.accessToken()?.token !== newToken?.token) {\r\n this.accessToken.set(newToken);\r\n }\r\n\r\n return <T>this.accessToken();\r\n }\r\n\r\n private updateRefreshTokenSignal<T extends Nullable<RefreshToken>>(newToken: Nullable<RefreshToken>): T {\r\n if (this.refreshToken()?.token !== newToken?.token) {\r\n this.refreshToken.set(newToken);\r\n }\r\n\r\n return <T>this.refreshToken();\r\n }\r\n\r\n private setToken<T extends IdentityToken>(key: TokenKey, token: unknown): T {\r\n /**\r\n * make sure provided token is at least a string\r\n */\r\n if (typeof token !== 'string') {\r\n throw new InvalidTokenError(`Provided ${key} value is not a string`);\r\n }\r\n\r\n /**\r\n * get identity token\r\n */\r\n const identityToken = this.wrapToken<T>(token);\r\n\r\n /**\r\n * if provided - save it to local storage\r\n */\r\n if (identityToken) {\r\n localStorage.setItem(key, token);\r\n }\r\n\r\n LogHelper.log(key, identityToken);\r\n\r\n return identityToken;\r\n }\r\n\r\n private getToken<T extends IdentityToken>(key: TokenKey, token: Maybe<string>): Nullable<T> {\r\n /**\r\n * either use provided token value or get one from the local storage\r\n */\r\n const actualToken = token ?? localStorage.getItem(key) ?? null;\r\n\r\n if (typeof actualToken === 'string') {\r\n try {\r\n return this.wrapToken<T>(actualToken);\r\n } catch (error) {\r\n LogHelper.error(error);\r\n }\r\n }\r\n\r\n return null;\r\n }\r\n\r\n private wrapToken<T extends IdentityToken>(token: string): T {\r\n /**\r\n * parse token and obtain its payload\r\n * NOTE: errors will be thrown if token is expired or has invalid claims\r\n */\r\n const payload = TokenHelper.getPayload(\r\n token,\r\n {\r\n iss: this.getIssuers(),\r\n sub: this.options.application,\r\n },\r\n 60,\r\n );\r\n\r\n /**\r\n * return identity token object\r\n */\r\n return <T>{ token, payload: payload };\r\n }\r\n\r\n private getIssuers(): string[] {\r\n /**\r\n * if we already have issuers - ise them\r\n */\r\n if (this.issuers.length) {\r\n return this.issuers;\r\n }\r\n\r\n /**\r\n * get issuer value from the options\r\n */\r\n const issuer = this.options.serviceIssuer ?? this.options.backendUrl;\r\n\r\n this.issuers = [issuer];\r\n\r\n /**\r\n * make sure we have both variants (with and without \"/api\" suffix) as issuers\r\n * todo \"/api\" suffix verification must be removed when \"/api\" suffix will be removed from the \"issuer\" in IDMS\r\n */\r\n if (issuer.endsWith('/api')) {\r\n this.issuers.push(issuer.substring(0, issuer.lastIndexOf('/api')));\r\n } else {\r\n this.issuers.push(`${issuer}/api`);\r\n }\r\n\r\n return this.issuers;\r\n }\r\n}\r\n","import { computed, inject, Injectable } from '@angular/core';\r\nimport { catchError, map, Observable, of, throwError } from 'rxjs';\r\nimport { TokenService } from './token.service';\r\nimport { HttpClient } from '@angular/common/http';\r\nimport { IDENTITY_OPTIONS } from '../types/internal-consts';\r\nimport { RefreshTokenResponse } from '../types/internal-types';\r\nimport { LogHelper } from '../helpers/log.helper';\r\nimport { AccessToken } from '../types/global-types';\r\nimport { InvalidTokenError } from 'jwt-decode';\r\nimport { ErrorHelper } from '../helpers/error.helper';\r\nimport { IdentityServiceInterface } from '../interfaces/identity-service.interface';\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class IdentityService implements IdentityServiceInterface {\r\n /**\r\n * NOTE: we expose access and refresh tokens as computed signals to allow\r\n * library users reactive readonly access to tokens, since \"IdentityService\"\r\n * is the only \"public\" service in the library\r\n */\r\n readonly accessToken = computed(() => this.tokenService.readonlyAccessToken());\r\n readonly refreshToken = computed(() => this.tokenService.readonlyRefreshToken());\r\n\r\n private readonly tokenService = inject(TokenService);\r\n private readonly httpClient = inject(HttpClient);\r\n private readonly options = inject(IDENTITY_OPTIONS);\r\n\r\n isAuthenticated() {\r\n return !!this.tokenService.getAccessToken();\r\n }\r\n\r\n authenticate(): Observable<AccessToken> {\r\n /**\r\n * get access and refresh token\r\n */\r\n const accessToken = this.tokenService.getAccessToken();\r\n const refreshToken = this.tokenService.getRefreshToken();\r\n\r\n /**\r\n * if it is available - return it; otherwise try refreshing the tokens by calling IDMS\r\n */\r\n if (accessToken) {\r\n return of(accessToken);\r\n }\r\n\r\n /**\r\n * if refresh token is available - try getting new tokens\r\n */\r\n if (refreshToken) {\r\n return this.refreshTokens();\r\n }\r\n\r\n /**\r\n * throw error if no tokens are available\r\n */\r\n return throwError(() => new InvalidTokenError('No valid tokens found'));\r\n }\r\n\r\n refreshTokens(): Observable<AccessToken> {\r\n const refreshToken = this.tokenService.getRefreshToken();\r\n\r\n /**\r\n * throw error if refresh token is not available\r\n */\r\n if (!refreshToken) {\r\n return throwError(() => new InvalidTokenError('No refresh token found'));\r\n }\r\n\r\n /**\r\n * make request to Identity service to get new tokens\r\n */\r\n return this.httpClient\r\n .get<RefreshTokenResponse>(`${this.options.backendUrl}/api/v${this.options.apiVersion ?? 1}/refresh-token`, {\r\n headers: { Authorization: `Bearer ${refreshToken.token}` },\r\n })\r\n .pipe(\r\n catchError((error: unknown) => {\r\n /**\r\n * log error if it happens\r\n */\r\n LogHelper.error(\r\n new InvalidTokenError(\r\n `Failed to obtain tokens. Reason: ${ErrorHelper.extractMessage(error).toLowerCase()}`,\r\n ),\r\n );\r\n\r\n return throwError(() => error);\r\n }),\r\n map((response) => {\r\n /**\r\n * set refresh token\r\n */\r\n this.tokenService.setRefreshToken(response.refresh_token);\r\n\r\n /**\r\n * set and return access token\r\n */\r\n return this.tokenService.setAccessToken(response.access_token);\r\n }),\r\n );\r\n }\r\n\r\n clearTokens() {\r\n this.tokenService.clearTokens();\r\n }\r\n}\r\n","import { CanActivateFn } from '@angular/router';\r\nimport { inject } from '@angular/core';\r\nimport { IdentityService } from '../services/identity.service';\r\nimport { catchError, map, of } from 'rxjs';\r\nimport { IDENTITY_OPTIONS } from '../types/internal-consts';\r\nimport { LogHelper } from '../helpers/log.helper';\r\n\r\nexport const IDENTITY_AUTH_GUARD: CanActivateFn = (_route, state) => {\r\n const identityService = inject(IdentityService);\r\n const options = inject(IDENTITY_OPTIONS);\r\n\r\n /**\r\n * check if user is authenticated;\r\n * if error happened - redirect to IDMS url to re-login;\r\n * return true on success and false on error\r\n */\r\n return identityService.authenticate().pipe(\r\n catchError((error) => {\r\n window.location.href = `${options.frontendUrl}/apps/${options.application}?redirect=true&redirect_path=${encodeURIComponent(\r\n state.url,\r\n )}`;\r\n\r\n LogHelper.error(error);\r\n\r\n return of(null);\r\n }),\r\n map((accessToken) => !!accessToken),\r\n );\r\n};\r\n","import { CanActivateFn, Router } from '@angular/router';\r\nimport { inject } from '@angular/core';\r\nimport { TokenService } from '../services/token.service';\r\nimport { LogHelper } from '../helpers/log.helper';\r\nimport { ErrorHelper } from '../helpers/error.helper';\r\n\r\nexport const IDENTITY_AUTH_CALLBACK_GUARD: CanActivateFn = (route) => {\r\n const router = inject(Router);\r\n const tokenService = inject(TokenService);\r\n\r\n const throwAccessDenied = () => {\r\n throw new Error('Access denied');\r\n };\r\n\r\n /**\r\n * save access and refresh tokens and redirect either to root or to provided \"redirect_path\";\r\n * if error happened - display error message on the page and return false to stop further navigation\r\n */\r\n try {\r\n if (!route.queryParams['access_token'] || !route.queryParams['access_token']) {\r\n throwAccessDenied();\r\n }\r\n\r\n tokenService.setAccessToken(route.queryParams['access_token']);\r\n\r\n tokenService.setRefreshToken(route.queryParams['refresh_token']);\r\n\r\n return router.navigateByUrl(route.queryParams['redirect_path'] || '/');\r\n } catch (error: unknown) {\r\n const routerOutlet = document.body.querySelector('router-outlet');\r\n\r\n if (routerOutlet) {\r\n routerOutlet.innerHTML = ErrorHelper.extractMessage(error);\r\n }\r\n\r\n LogHelper.error(error);\r\n\r\n return false;\r\n }\r\n};\r\n","import { HttpErrorResponse, HttpRequest } from '@angular/common/http';\r\nimport { throwError } from 'rxjs';\r\nimport { Injector } from '@angular/core';\r\nimport { IdentityOptions } from '../types/internal-types';\r\nimport { AccessToken } from '../types/global-types';\r\n\r\nexport class RequestHelper {\r\n static options?: IdentityOptions;\r\n\r\n static isIdentityEndpointRequest(request: HttpRequest<unknown>): boolean {\r\n return (\r\n (!!this.options?.backendUrl && request.url.startsWith(this.options?.backendUrl)) ||\r\n (!!this.options?.frontendUrl && request.url.startsWith(this.options?.frontendUrl))\r\n );\r\n }\r\n\r\n static isAuthorizedRequest(request: HttpRequest<unknown>): boolean {\r\n return !this.options?.requestFilter || this.options.requestFilter(request);\r\n }\r\n\r\n static isAuthorizationError(error: unknown): boolean {\r\n return error instanceof HttpErrorResponse && error.status === 401;\r\n }\r\n\r\n static attachAuthorizationHeader(request: HttpRequest<unknown>, accessToken: AccessToken): HttpRequest<unknown> {\r\n return request.clone({\r\n setHeaders: { authorization: `Bearer ${accessToken.token}`, 'auth-source': 'IDMS' },\r\n });\r\n }\r\n\r\n static onAuthorizationError(error: unknown, injector: Injector) {\r\n if (this.options?.onAuthorizationError) {\r\n this.options?.onAuthorizationError(error, injector);\r\n }\r\n\r\n return throwError(() => error);\r\n }\r\n}\r\n","import { HttpEvent, HttpHandlerFn, HttpRequest } from '@angular/common/http';\r\nimport { catchError, Observable, switchMap } from 'rxjs';\r\nimport { inject, Injector } from '@angular/core';\r\nimport { IdentityService } from '../services/identity.service';\r\nimport { RequestHelper } from '../helpers/request.helper';\r\n\r\nexport function requestInterceptor(request: HttpRequest<unknown>, next: HttpHandlerFn): Observable<HttpEvent<unknown>> {\r\n const identityService = inject(IdentityService);\r\n const injector = inject(Injector);\r\n\r\n /**\r\n * if it is a request to Identity Service or not an authorized request - do not modify it\r\n */\r\n if (RequestHelper.isIdentityEndpointRequest(request) || !RequestHelper.isAuthorizedRequest(request)) {\r\n return next(request);\r\n }\r\n\r\n /**\r\n * if current user is authenticated - attach \"Authorization\" header to the request;\r\n * or process the error if it happens\r\n */\r\n return identityService.authenticate().pipe(\r\n catchError((error: unknown) => RequestHelper.onAuthorizationError(error, injector)),\r\n switchMap((accessToken) => next(RequestHelper.attachAuthorizationHeader(request, accessToken))),\r\n );\r\n}\r\n","import { HttpEvent, HttpHandlerFn, HttpRequest } from '@angular/common/http';\r\nimport { catchError, Observable, switchMap, throwError } from 'rxjs';\r\nimport { inject, Injector } from '@angular/core';\r\nimport { IdentityService } from '../services/identity.service';\r\nimport { IDENTITY_OPTIONS } from '../types/internal-consts';\r\nimport { RequestHelper } from '../helpers/request.helper';\r\n\r\nexport function responseInterceptor(\r\n request: HttpRequest<unknown>,\r\n next: HttpHandlerFn,\r\n): Observable<HttpEvent<unknown>> {\r\n const options = inject(IDENTITY_OPTIONS);\r\n const identityService = inject(IdentityService);\r\n const injector = inject(Injector);\r\n\r\n /**\r\n * process all response errors\r\n */\r\n return next(request).pipe(\r\n catchError((error: unknown) => {\r\n /**\r\n * if error happened with Identity Service request, or not-authorized request, or it is not an authorization (401) error -\r\n * do not change anything and return the error as is\r\n */\r\n if (\r\n RequestHelper.isIdentityEndpointRequest(request) ||\r\n !RequestHelper.isAuthorizedRequest(request) ||\r\n !RequestHelper.isAuthorizationError(error)\r\n ) {\r\n return throwError(() => error);\r\n }\r\n\r\n /**\r\n * if options do not allow to try and refresh tokens on error 401 -\r\n * process the error and return it\r\n */\r\n if (!options.refreshTokenOnAuthError) {\r\n return RequestHelper.onAuthorizationError(error, injector);\r\n }\r\n\r\n /**\r\n * if tokens were refreshed - attach \"Authorization\" header to the request and call it again;\r\n * or process the error if it happens\r\n */\r\n return identityService.refreshTokens().pipe(\r\n switchMap((accessToken) => next(RequestHelper.attachAuthorizationHeader(request, accessToken))),\r\n catchError((error: unknown) => RequestHelper.onAuthorizationError(error, injector)),\r\n );\r\n }),\r\n );\r\n}\r\n","import { provideHttpClient, withInterceptors } from '@angular/common/http';\r\nimport { requestInterceptor } from '../interceptors/request.interceptor';\r\nimport { responseInterceptor } from '../interceptors/response.interceptor';\r\nimport { IDENTITY_OPTIONS } from '../types/internal-consts';\r\nimport { LogHelper } from '../helpers/log.helper';\r\nimport { RequestHelper } from '../helpers/request.helper';\r\nimport { IdentityOptions } from '../types/internal-types';\r\n\r\nexport function provideIdentity(options: IdentityOptions) {\r\n LogHelper.options = options;\r\n RequestHelper.options = options;\r\n\r\n return [\r\n { provide: IDENTITY_OPTIONS, useValue: options },\r\n provideHttpClient(withInterceptors([requestInterceptor, responseInterceptor])),\r\n ];\r\n}\r\n"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { GenericCollection } from '../types/internal-types';
|
|
1
|
+
import { GenericCollection, AccessTokenPayload, RefreshTokenPayload } from '../types/internal-types';
|
|
3
2
|
export declare class TokenHelper {
|
|
4
|
-
static getPayload<T extends
|
|
3
|
+
static getPayload<T extends AccessTokenPayload | RefreshTokenPayload>(token: string, verifyClaims?: GenericCollection, threshold?: number): T;
|
|
5
4
|
private static isExpired;
|
|
6
5
|
private static isClaimValid;
|
|
7
6
|
}
|
|
@@ -2,8 +2,10 @@ import { Signal } from '@angular/core';
|
|
|
2
2
|
import { AccessToken, RefreshToken } from '../types/global-types';
|
|
3
3
|
import { Observable } from 'rxjs';
|
|
4
4
|
export interface IdentityServiceInterface {
|
|
5
|
-
accessToken: Signal<AccessToken | null>;
|
|
6
|
-
refreshToken: Signal<RefreshToken | null>;
|
|
7
|
-
isAuthenticated():
|
|
5
|
+
readonly accessToken: Signal<AccessToken | null>;
|
|
6
|
+
readonly refreshToken: Signal<RefreshToken | null>;
|
|
7
|
+
isAuthenticated(): boolean;
|
|
8
|
+
authenticate(): Observable<AccessToken>;
|
|
8
9
|
refreshTokens(): Observable<AccessToken>;
|
|
10
|
+
clearTokens(): void;
|
|
9
11
|
}
|
|
@@ -3,13 +3,15 @@ import { AccessToken } from '../types/global-types';
|
|
|
3
3
|
import { IdentityServiceInterface } from '../interfaces/identity-service.interface';
|
|
4
4
|
import * as i0 from "@angular/core";
|
|
5
5
|
export declare class IdentityService implements IdentityServiceInterface {
|
|
6
|
-
accessToken: import("@angular/core").Signal<import("../types/internal-types").Nullable<AccessToken>>;
|
|
7
|
-
refreshToken: import("@angular/core").Signal<import("../types/internal-types").Nullable<import("../types/global-types").RefreshToken>>;
|
|
6
|
+
readonly accessToken: import("@angular/core").Signal<import("../types/internal-types").Nullable<AccessToken>>;
|
|
7
|
+
readonly refreshToken: import("@angular/core").Signal<import("../types/internal-types").Nullable<import("../types/global-types").RefreshToken>>;
|
|
8
8
|
private readonly tokenService;
|
|
9
9
|
private readonly httpClient;
|
|
10
10
|
private readonly options;
|
|
11
|
-
isAuthenticated():
|
|
11
|
+
isAuthenticated(): boolean;
|
|
12
|
+
authenticate(): Observable<AccessToken>;
|
|
12
13
|
refreshTokens(): Observable<AccessToken>;
|
|
14
|
+
clearTokens(): void;
|
|
13
15
|
static ɵfac: i0.ɵɵFactoryDeclaration<IdentityService, never>;
|
|
14
16
|
static ɵprov: i0.ɵɵInjectableDeclaration<IdentityService>;
|
|
15
17
|
}
|
|
@@ -1,17 +1,18 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Nullable } from '../types/internal-types';
|
|
2
2
|
import { AccessToken, RefreshToken } from '../types/global-types';
|
|
3
3
|
import * as i0 from "@angular/core";
|
|
4
4
|
export declare class TokenService {
|
|
5
5
|
readonlyAccessToken: import("@angular/core").Signal<Nullable<AccessToken>>;
|
|
6
6
|
readonlyRefreshToken: import("@angular/core").Signal<Nullable<RefreshToken>>;
|
|
7
|
-
private accessToken;
|
|
8
|
-
private refreshToken;
|
|
7
|
+
private readonly accessToken;
|
|
8
|
+
private readonly refreshToken;
|
|
9
9
|
private readonly options;
|
|
10
10
|
private issuers;
|
|
11
|
-
setAccessToken(token: unknown):
|
|
12
|
-
getAccessToken(): Nullable<
|
|
13
|
-
setRefreshToken(token: unknown):
|
|
14
|
-
getRefreshToken(): Nullable<
|
|
11
|
+
setAccessToken(token: unknown): AccessToken;
|
|
12
|
+
getAccessToken(): Nullable<AccessToken>;
|
|
13
|
+
setRefreshToken(token: unknown): RefreshToken;
|
|
14
|
+
getRefreshToken(): Nullable<RefreshToken>;
|
|
15
|
+
clearTokens(): void;
|
|
15
16
|
private updateAccessTokenSignal;
|
|
16
17
|
private updateRefreshTokenSignal;
|
|
17
18
|
private setToken;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { AccessTokenPayload, RefreshTokenPayload } from './internal-types';
|
|
2
2
|
export type AccessToken = {
|
|
3
3
|
token: string;
|
|
4
|
-
payload:
|
|
4
|
+
payload: AccessTokenPayload;
|
|
5
5
|
};
|
|
6
6
|
export type RefreshToken = {
|
|
7
7
|
token: string;
|
|
8
|
-
payload:
|
|
8
|
+
payload: RefreshTokenPayload;
|
|
9
9
|
};
|
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
import { JwtPayload } from 'jwt-decode';
|
|
2
1
|
import { HttpRequest } from '@angular/common/http';
|
|
3
2
|
import { Injector } from '@angular/core';
|
|
4
3
|
import { AccessToken, RefreshToken } from './global-types';
|
|
5
4
|
export type Nullable<T> = T | null;
|
|
6
5
|
export type Maybe<T> = T | undefined;
|
|
7
|
-
export type TokenClaim = Maybe<string | string[] | number>;
|
|
8
6
|
export type GenericCollection<T = unknown, K extends string = string> = Record<K, T>;
|
|
9
7
|
export type IdentityOptions = {
|
|
10
8
|
frontendUrl: string;
|
|
@@ -17,7 +15,22 @@ export type IdentityOptions = {
|
|
|
17
15
|
requestFilter?: (request: HttpRequest<unknown>) => boolean;
|
|
18
16
|
onAuthorizationError?: (error: unknown, injector: Injector) => void;
|
|
19
17
|
};
|
|
20
|
-
export type
|
|
18
|
+
export type IdentityJwtPayload = {
|
|
19
|
+
iss: string;
|
|
20
|
+
sub: string;
|
|
21
|
+
aud: string[] | string;
|
|
22
|
+
exp: number;
|
|
23
|
+
oid: string;
|
|
24
|
+
iat: number;
|
|
25
|
+
sid: string;
|
|
26
|
+
[key: string]: unknown;
|
|
27
|
+
} & GenericCollection;
|
|
28
|
+
export type AccessTokenPayload = IdentityJwtPayload & {
|
|
29
|
+
name: string;
|
|
30
|
+
email: string;
|
|
31
|
+
};
|
|
32
|
+
export type RefreshTokenPayload = IdentityJwtPayload;
|
|
33
|
+
export type IdentityJwtClaim = keyof IdentityJwtPayload;
|
|
21
34
|
export type RefreshTokenResponse = {
|
|
22
35
|
access_token: string;
|
|
23
36
|
refresh_token: string;
|