@ascentgl/ads-identity 0.0.6 → 0.9.2

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.
@@ -9,37 +9,35 @@ class LogHelper {
9
9
  static { this.prefix = 'ADS-IDENTITY'; }
10
10
  static log(...args) {
11
11
  if (!this.options?.debugMode)
12
- return;
12
+ return false;
13
13
  console.group(this.prefix, 'TOKEN UPDATE');
14
14
  console.log(...args);
15
15
  console.groupEnd();
16
+ return true;
16
17
  }
17
18
  static error(...args) {
18
19
  if (!this.options?.debugMode)
19
- return;
20
+ return false;
20
21
  console.group(this.prefix, 'EXCEPTION');
21
22
  console.error(...args);
22
23
  console.groupEnd();
24
+ return true;
23
25
  }
24
26
  }
25
27
 
26
28
  class ErrorHelper {
27
29
  static extractMessage(error) {
28
- if (typeof error === 'string') {
30
+ if (typeof error === 'string' && error) {
29
31
  return error;
30
32
  }
31
33
  let errorMessage;
32
34
  if (error instanceof HttpErrorResponse) {
33
35
  errorMessage = error.error?.message ?? error.message;
34
36
  }
35
- if (!errorMessage &&
36
- typeof error === 'object' &&
37
- typeof error['message'] === 'string') {
37
+ if (!errorMessage && typeof error === 'object' && typeof error['message'] === 'string') {
38
38
  errorMessage = error['message'];
39
39
  }
40
- return errorMessage && typeof errorMessage === 'string'
41
- ? errorMessage
42
- : 'Unknown server error';
40
+ return errorMessage && typeof errorMessage === 'string' ? errorMessage : 'Unknown server error';
43
41
  }
44
42
  }
45
43
 
@@ -52,7 +50,7 @@ class TokenHelper {
52
50
  Object.keys(verifyClaims).forEach((claim) => {
53
51
  const tokenClaimValue = payload[claim];
54
52
  const requestedClaimValue = verifyClaims[claim];
55
- if (tokenClaimValue !== requestedClaimValue) {
53
+ if (!this.isClaimValid(tokenClaimValue, requestedClaimValue)) {
56
54
  throw new InvalidTokenError(`Invalid "${claim}" claim value "${tokenClaimValue}" provided in token. Required value is "${requestedClaimValue}"`);
57
55
  }
58
56
  });
@@ -65,19 +63,33 @@ class TokenHelper {
65
63
  try {
66
64
  let timestamp = token[column];
67
65
  if (typeof timestamp === 'number') {
68
- if (threshold) {
66
+ if (threshold > 0) {
69
67
  timestamp -= threshold;
70
68
  }
71
69
  return !!timestamp && timestamp * 1000 < new Date().getTime();
72
70
  }
73
- throwInvalidColumnError(column.toString());
74
- return true;
71
+ return throwInvalidColumnError(column.toString());
75
72
  }
76
73
  catch (error) {
77
74
  LogHelper.error(new InvalidTokenError(ErrorHelper.extractMessage(error)));
78
75
  return true;
79
76
  }
80
77
  }
78
+ static isClaimValid(tokenClaim, valueToVerify) {
79
+ if (tokenClaim instanceof Array || valueToVerify instanceof Array) {
80
+ if (tokenClaim instanceof Array && valueToVerify instanceof Array) {
81
+ return tokenClaim.filter((value) => valueToVerify.includes(value)).length > 0;
82
+ }
83
+ if (tokenClaim instanceof Array && typeof valueToVerify === 'string') {
84
+ return tokenClaim.includes(valueToVerify);
85
+ }
86
+ if (valueToVerify instanceof Array && typeof tokenClaim === 'string') {
87
+ return valueToVerify.includes(tokenClaim);
88
+ }
89
+ return false;
90
+ }
91
+ return tokenClaim === valueToVerify;
92
+ }
81
93
  }
82
94
 
83
95
  const IDENTITY_OPTIONS = new InjectionToken('IDENTITY_OPTIONS');
@@ -89,6 +101,7 @@ class TokenService {
89
101
  this.accessToken = signal(null);
90
102
  this.refreshToken = signal(null);
91
103
  this.options = inject(IDENTITY_OPTIONS);
104
+ this.issuers = [];
92
105
  }
93
106
  setAccessToken(token) {
94
107
  return this.updateAccessTokenSignal(this.setToken("IDMS_AccessToken", token));
@@ -118,7 +131,7 @@ class TokenService {
118
131
  if (typeof token !== 'string') {
119
132
  throw new InvalidTokenError(`Provided ${key} value is not a string`);
120
133
  }
121
- const identityToken = this.wrapToken(token, true);
134
+ const identityToken = this.wrapToken(token);
122
135
  if (identityToken) {
123
136
  localStorage.setItem(key, token);
124
137
  }
@@ -128,30 +141,41 @@ class TokenService {
128
141
  getToken(key, token) {
129
142
  const actualToken = token ?? localStorage.getItem(key) ?? null;
130
143
  if (typeof actualToken === 'string') {
131
- return this.wrapToken(actualToken, false);
144
+ try {
145
+ return this.wrapToken(actualToken);
146
+ }
147
+ catch (error) {
148
+ LogHelper.error(error);
149
+ }
132
150
  }
133
151
  return null;
134
152
  }
135
- wrapToken(token, throwError) {
136
- try {
137
- const payload = TokenHelper.getPayload(token, {
138
- iss: this.options.backendUrl + '/api',
139
- sub: this.options.application
140
- }, 10);
141
- return { token, payload: payload };
153
+ wrapToken(token) {
154
+ const payload = TokenHelper.getPayload(token, {
155
+ iss: this.getIssuers(),
156
+ sub: this.options.application,
157
+ }, 10);
158
+ return { token, payload: payload };
159
+ }
160
+ getIssuers() {
161
+ if (this.issuers.length) {
162
+ return this.issuers;
142
163
  }
143
- catch (error) {
144
- if (throwError) {
145
- throw error;
146
- }
147
- LogHelper.error(error);
148
- return null;
164
+ const issuer = this.options.serviceIssuer ?? this.options.backendUrl;
165
+ this.issuers = [issuer];
166
+ if (issuer.endsWith('/api')) {
167
+ this.issuers.push(issuer.substring(0, issuer.lastIndexOf('/api')));
149
168
  }
169
+ else {
170
+ this.issuers.push(`${issuer}/api`);
171
+ }
172
+ console.log(this.issuers);
173
+ return this.issuers;
150
174
  }
151
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.2", ngImport: i0, type: TokenService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
152
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.2", ngImport: i0, type: TokenService, providedIn: 'root' }); }
175
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: TokenService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
176
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: TokenService, providedIn: 'root' }); }
153
177
  }
154
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.2", ngImport: i0, type: TokenService, decorators: [{
178
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: TokenService, decorators: [{
155
179
  type: Injectable,
156
180
  args: [{ providedIn: 'root' }]
157
181
  }] });
@@ -182,24 +206,20 @@ class IdentityService {
182
206
  }
183
207
  return this.httpClient
184
208
  .get(`${this.options.backendUrl}/api/v${this.options.apiVersion ?? 1}/refresh-token`, {
185
- headers: { 'Authorization': `Bearer ${refreshToken.token}` }
209
+ headers: { Authorization: `Bearer ${refreshToken.token}` },
186
210
  })
187
211
  .pipe(catchError((error) => {
188
212
  LogHelper.error(new InvalidTokenError(`Failed to obtain tokens. Reason: ${ErrorHelper.extractMessage(error).toLowerCase()}`));
189
213
  return throwError(() => error);
190
214
  }), map((response) => {
191
- const accessToken = this.tokenService.setAccessToken(response.access_token);
192
215
  this.tokenService.setRefreshToken(response.refresh_token);
193
- if (accessToken) {
194
- return accessToken;
195
- }
196
- throw new InvalidTokenError('Could not set access token');
216
+ return this.tokenService.setAccessToken(response.access_token);
197
217
  }));
198
218
  }
199
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.2", ngImport: i0, type: IdentityService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
200
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.2", ngImport: i0, type: IdentityService, providedIn: 'root' }); }
219
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: IdentityService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
220
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: IdentityService, providedIn: 'root' }); }
201
221
  }
202
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.2", ngImport: i0, type: IdentityService, decorators: [{
222
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: IdentityService, decorators: [{
203
223
  type: Injectable,
204
224
  args: [{ providedIn: 'root' }]
205
225
  }] });
@@ -217,7 +237,13 @@ const IDENTITY_AUTH_GUARD = (_route, state) => {
217
237
  const IDENTITY_AUTH_CALLBACK_GUARD = (route) => {
218
238
  const router = inject(Router);
219
239
  const tokenService = inject(TokenService);
240
+ const throwAccessDenied = () => {
241
+ throw new Error('Access denied');
242
+ };
220
243
  try {
244
+ if (!route.queryParams['access_token'] || !route.queryParams['access_token']) {
245
+ throwAccessDenied();
246
+ }
221
247
  tokenService.setAccessToken(route.queryParams['access_token']);
222
248
  tokenService.setRefreshToken(route.queryParams['refresh_token']);
223
249
  return router.navigateByUrl(route.queryParams['redirect_path'] || '/');
@@ -234,7 +260,8 @@ const IDENTITY_AUTH_CALLBACK_GUARD = (route) => {
234
260
 
235
261
  class RequestHelper {
236
262
  static isIdentityEndpointRequest(request) {
237
- return request.url.startsWith(this.options?.backendUrl ?? '');
263
+ return ((!!this.options?.backendUrl && request.url.startsWith(this.options?.backendUrl)) ||
264
+ (!!this.options?.frontendUrl && request.url.startsWith(this.options?.frontendUrl)));
238
265
  }
239
266
  static isAuthorizedRequest(request) {
240
267
  return !this.options?.requestFilter || this.options.requestFilter(request);
@@ -244,7 +271,7 @@ class RequestHelper {
244
271
  }
245
272
  static attachAuthorizationHeader(request, accessToken) {
246
273
  return request.clone({
247
- setHeaders: { authorization: `Bearer ${accessToken.token}` }
274
+ setHeaders: { authorization: `Bearer ${accessToken.token}` },
248
275
  });
249
276
  }
250
277
  static onAuthorizationError(error, injector) {
@@ -253,17 +280,15 @@ class RequestHelper {
253
280
  }
254
281
  return throwError(() => error);
255
282
  }
256
- ;
257
283
  }
258
284
 
259
285
  function requestInterceptor(request, next) {
260
286
  const identityService = inject(IdentityService);
261
287
  const injector = inject(Injector);
262
- if (RequestHelper.isIdentityEndpointRequest(request) ||
263
- !RequestHelper.isAuthorizedRequest(request)) {
288
+ if (RequestHelper.isIdentityEndpointRequest(request) || !RequestHelper.isAuthorizedRequest(request)) {
264
289
  return next(request);
265
290
  }
266
- return identityService.isAuthenticated().pipe(catchError((error) => RequestHelper.onAuthorizationError(error, injector)), switchMap(accessToken => next(RequestHelper.attachAuthorizationHeader(request, accessToken))));
291
+ return identityService.isAuthenticated().pipe(catchError((error) => RequestHelper.onAuthorizationError(error, injector)), switchMap((accessToken) => next(RequestHelper.attachAuthorizationHeader(request, accessToken))));
267
292
  }
268
293
 
269
294
  function responseInterceptor(request, next) {
@@ -288,7 +313,7 @@ function provideIdentity(options) {
288
313
  RequestHelper.options = options;
289
314
  return [
290
315
  { provide: IDENTITY_OPTIONS, useValue: options },
291
- provideHttpClient(withInterceptors([requestInterceptor, responseInterceptor]))
316
+ provideHttpClient(withInterceptors([requestInterceptor, responseInterceptor])),
292
317
  ];
293
318
  }
294
319
 
@@ -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\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\r\n if (!this.options?.debugMode) return;\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 }\r\n\r\n static error(...args: unknown[]) {\r\n\r\n if (!this.options?.debugMode) return;\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 }\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\r\n static extractMessage(error: unknown): string {\r\n\r\n if (typeof error === 'string') {\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 (\r\n !errorMessage &&\r\n typeof error === 'object' &&\r\n typeof (<GenericCollection>error)['message'] === 'string'\r\n ) {\r\n errorMessage = (<GenericCollection>error)['message'];\r\n }\r\n\r\n return errorMessage && typeof errorMessage === 'string'\r\n ? errorMessage\r\n : 'Unknown server error';\r\n }\r\n}\r\n","import { InvalidTokenError, jwtDecode, JwtPayload } from 'jwt-decode';\r\nimport { JwtClaim } from '../types/internal-types';\r\nimport { LogHelper } from './log.helper';\r\nimport { ErrorHelper } from './error.helper';\r\n\r\nexport class TokenHelper {\r\n\r\n static getPayload<T extends JwtPayload>(\r\n token: string,\r\n verifyClaims: Partial<JwtPayload> = {},\r\n threshold = 0\r\n ): T {\r\n\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\r\n const tokenClaimValue = payload[claim];\r\n const requestedClaimValue = verifyClaims[claim];\r\n\r\n if (tokenClaimValue !== requestedClaimValue) {\r\n throw new InvalidTokenError(`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\r\n private static isExpired<T extends JwtPayload>(\r\n token: T,\r\n column: keyof T = 'exp',\r\n threshold = 0\r\n ): boolean {\r\n\r\n const throwInvalidColumnError = (column: string): void => {\r\n throw new InvalidTokenError(\r\n `Column ${column} does not contain a valid number`\r\n );\r\n };\r\n\r\n try {\r\n\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 /**\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) {\r\n timestamp -= threshold;\r\n }\r\n\r\n return !!timestamp && timestamp * 1000 < new Date().getTime();\r\n }\r\n\r\n throwInvalidColumnError(column.toString());\r\n\r\n return true;\r\n } catch (error: unknown) {\r\n\r\n LogHelper.error(new InvalidTokenError(ErrorHelper.extractMessage(error)));\r\n\r\n return true;\r\n }\r\n }\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 { Maybe, Nullable } from '../types/internal-types';\r\nimport { IdentityToken } 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 /**\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<IdentityToken>>(null);\r\n private refreshToken = signal<Nullable<IdentityToken>>(null);\r\n\r\n private readonly options = inject(IDENTITY_OPTIONS);\r\n\r\n setAccessToken(token: unknown) {\r\n return this.updateAccessTokenSignal(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(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(newToken: Nullable<IdentityToken>) {\r\n\r\n if (this.accessToken()?.token !== newToken?.token) {\r\n this.accessToken.set(newToken);\r\n }\r\n\r\n return this.accessToken();\r\n\r\n }\r\n\r\n private updateRefreshTokenSignal(newToken: Nullable<IdentityToken>) {\r\n\r\n if (this.refreshToken()?.token !== newToken?.token) {\r\n this.refreshToken.set(newToken);\r\n }\r\n\r\n return this.refreshToken();\r\n\r\n }\r\n\r\n private setToken(key: TokenKey, token: unknown): Nullable<IdentityToken> {\r\n\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, true);\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\r\n private getToken(key: TokenKey, token: Maybe<string>): Nullable<IdentityToken> {\r\n\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 return this.wrapToken(actualToken, false);\r\n }\r\n\r\n return null;\r\n\r\n }\r\n\r\n private wrapToken(token: string, throwError: boolean): Nullable<IdentityToken> {\r\n\r\n try {\r\n\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.options.backendUrl + '/api',\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 { token, payload: payload };\r\n\r\n } catch (error: unknown) {\r\n\r\n if (throwError) {\r\n throw error;\r\n }\r\n\r\n LogHelper.error(error);\r\n\r\n return null;\r\n\r\n }\r\n\r\n }\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 { IdentityToken } 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 /**\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<IdentityToken> {\r\n\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\r\n refreshTokens(): Observable<IdentityToken> {\r\n\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 IDMS 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 /**\r\n * log error if it happens\r\n */\r\n LogHelper.error(new InvalidTokenError(`Failed to obtain tokens. Reason: ${ErrorHelper.extractMessage(error).toLowerCase()}`));\r\n\r\n return throwError(() => error);\r\n\r\n }),\r\n map((response) => {\r\n\r\n /**\r\n * store new access and refresh tokens\r\n */\r\n const accessToken = this.tokenService.setAccessToken(response.access_token);\r\n\r\n this.tokenService.setRefreshToken(response.refresh_token);\r\n\r\n /**\r\n * if new access token is valid - return it\r\n */\r\n if (accessToken) {\r\n return accessToken;\r\n }\r\n\r\n throw new InvalidTokenError('Could not set access token');\r\n\r\n })\r\n );\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\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\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 }),\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\r\n const router = inject(Router);\r\n const tokenService = inject(TokenService);\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\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\r\n } catch (error: unknown) {\r\n\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\r\n};\r\n","import { HttpErrorResponse, HttpRequest } from '@angular/common/http';\r\nimport { IdentityToken } from '../types/global-types';\r\nimport { throwError } from 'rxjs';\r\nimport { Injector } from '@angular/core';\r\nimport { IdentityOptions } from '../types/internal-types';\r\n\r\nexport class RequestHelper {\r\n\r\n static options?: IdentityOptions;\r\n\r\n static isIdentityEndpointRequest(request: HttpRequest<unknown>): boolean {\r\n return request.url.startsWith(this.options?.backendUrl ?? '');\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: IdentityToken): HttpRequest<unknown> {\r\n\r\n return request.clone({\r\n setHeaders: { authorization: `Bearer ${accessToken.token}` }\r\n });\r\n\r\n }\r\n\r\n static onAuthorizationError(error: unknown, injector: Injector) {\r\n\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\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(\r\n request: HttpRequest<unknown>,\r\n next: HttpHandlerFn\r\n): Observable<HttpEvent<unknown>> {\r\n\r\n const identityService = inject(IdentityService);\r\n const injector = inject(Injector)\r\n\r\n /**\r\n * if it is a request to IDMS or not an authorized request - do not modify it\r\n */\r\n if (RequestHelper.isIdentityEndpointRequest(request) ||\r\n !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\r\n}\r\n","import {\r\n HttpEvent, HttpHandlerFn,\r\n HttpRequest\r\n} 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\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 /**\r\n * if error happened with IDMS 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\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\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, 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}` },\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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"}
@@ -2,6 +2,6 @@ import { IdentityOptions } from '../types/internal-types';
2
2
  export declare class LogHelper {
3
3
  static options?: IdentityOptions;
4
4
  private static readonly prefix;
5
- static log(...args: unknown[]): void;
6
- static error(...args: unknown[]): void;
5
+ static log(...args: unknown[]): boolean;
6
+ static error(...args: unknown[]): boolean;
7
7
  }
@@ -1,12 +1,12 @@
1
1
  import { HttpRequest } from '@angular/common/http';
2
- import { IdentityToken } from '../types/global-types';
3
2
  import { Injector } from '@angular/core';
4
3
  import { IdentityOptions } from '../types/internal-types';
4
+ import { AccessToken } from '../types/global-types';
5
5
  export declare class RequestHelper {
6
6
  static options?: IdentityOptions;
7
7
  static isIdentityEndpointRequest(request: HttpRequest<unknown>): boolean;
8
8
  static isAuthorizedRequest(request: HttpRequest<unknown>): boolean;
9
9
  static isAuthorizationError(error: unknown): boolean;
10
- static attachAuthorizationHeader(request: HttpRequest<unknown>, accessToken: IdentityToken): HttpRequest<unknown>;
10
+ static attachAuthorizationHeader(request: HttpRequest<unknown>, accessToken: AccessToken): HttpRequest<unknown>;
11
11
  static onAuthorizationError(error: unknown, injector: Injector): import("rxjs").Observable<never>;
12
12
  }
@@ -1,5 +1,7 @@
1
1
  import { JwtPayload } from 'jwt-decode';
2
+ import { GenericCollection } from '../types/internal-types';
2
3
  export declare class TokenHelper {
3
- static getPayload<T extends JwtPayload>(token: string, verifyClaims?: Partial<JwtPayload>, threshold?: number): T;
4
+ static getPayload<T extends JwtPayload>(token: string, verifyClaims?: GenericCollection, threshold?: number): T;
4
5
  private static isExpired;
6
+ private static isClaimValid;
5
7
  }
@@ -1,9 +1,9 @@
1
1
  import { Signal } from '@angular/core';
2
- import { IdentityToken } from '../types/global-types';
2
+ import { AccessToken, RefreshToken } from '../types/global-types';
3
3
  import { Observable } from 'rxjs';
4
4
  export interface IdentityServiceInterface {
5
- accessToken: Signal<IdentityToken | null>;
6
- refreshToken: Signal<IdentityToken | null>;
7
- isAuthenticated(): Observable<IdentityToken>;
8
- refreshTokens(): Observable<IdentityToken>;
5
+ accessToken: Signal<AccessToken | null>;
6
+ refreshToken: Signal<RefreshToken | null>;
7
+ isAuthenticated(): Observable<AccessToken>;
8
+ refreshTokens(): Observable<AccessToken>;
9
9
  }
@@ -1,15 +1,15 @@
1
1
  import { Observable } from 'rxjs';
2
- import { IdentityToken } from '../types/global-types';
2
+ 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<IdentityToken>>;
7
- refreshToken: import("@angular/core").Signal<import("../types/internal-types").Nullable<IdentityToken>>;
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>>;
8
8
  private readonly tokenService;
9
9
  private readonly httpClient;
10
10
  private readonly options;
11
- isAuthenticated(): Observable<IdentityToken>;
12
- refreshTokens(): Observable<IdentityToken>;
11
+ isAuthenticated(): Observable<AccessToken>;
12
+ refreshTokens(): Observable<AccessToken>;
13
13
  static ɵfac: i0.ɵɵFactoryDeclaration<IdentityService, never>;
14
14
  static ɵprov: i0.ɵɵInjectableDeclaration<IdentityService>;
15
15
  }
@@ -1,21 +1,23 @@
1
- import { Nullable } from '../types/internal-types';
2
- import { IdentityToken } from '../types/global-types';
1
+ import { IdentityToken, Nullable } from '../types/internal-types';
2
+ import { AccessToken, RefreshToken } from '../types/global-types';
3
3
  import * as i0 from "@angular/core";
4
4
  export declare class TokenService {
5
- readonlyAccessToken: import("@angular/core").Signal<Nullable<IdentityToken>>;
6
- readonlyRefreshToken: import("@angular/core").Signal<Nullable<IdentityToken>>;
5
+ readonlyAccessToken: import("@angular/core").Signal<Nullable<AccessToken>>;
6
+ readonlyRefreshToken: import("@angular/core").Signal<Nullable<RefreshToken>>;
7
7
  private accessToken;
8
8
  private refreshToken;
9
9
  private readonly options;
10
- setAccessToken(token: unknown): Nullable<IdentityToken>;
10
+ private issuers;
11
+ setAccessToken(token: unknown): IdentityToken;
11
12
  getAccessToken(): Nullable<IdentityToken>;
12
- setRefreshToken(token: unknown): Nullable<IdentityToken>;
13
+ setRefreshToken(token: unknown): IdentityToken;
13
14
  getRefreshToken(): Nullable<IdentityToken>;
14
15
  private updateAccessTokenSignal;
15
16
  private updateRefreshTokenSignal;
16
17
  private setToken;
17
18
  private getToken;
18
19
  private wrapToken;
20
+ private getIssuers;
19
21
  static ɵfac: i0.ɵɵFactoryDeclaration<TokenService, never>;
20
22
  static ɵprov: i0.ɵɵInjectableDeclaration<TokenService>;
21
23
  }
@@ -1,5 +1,9 @@
1
1
  import { JwtPayload } from 'jwt-decode';
2
- export type IdentityToken = {
2
+ export type AccessToken = {
3
+ token: string;
4
+ payload: JwtPayload;
5
+ };
6
+ export type RefreshToken = {
3
7
  token: string;
4
8
  payload: JwtPayload;
5
9
  };
@@ -1,13 +1,16 @@
1
1
  import { JwtPayload } from 'jwt-decode';
2
2
  import { HttpRequest } from '@angular/common/http';
3
3
  import { Injector } from '@angular/core';
4
+ import { AccessToken, RefreshToken } from './global-types';
4
5
  export type Nullable<T> = T | null;
5
6
  export type Maybe<T> = T | undefined;
7
+ export type TokenClaim = Maybe<string | string[] | number>;
6
8
  export type GenericCollection<T = unknown, K extends string = string> = Record<K, T>;
7
9
  export type IdentityOptions = {
8
10
  frontendUrl: string;
9
11
  backendUrl: string;
10
12
  application: string;
13
+ serviceIssuer?: string;
11
14
  refreshTokenOnAuthError?: boolean;
12
15
  apiVersion?: number;
13
16
  debugMode?: boolean;
@@ -22,3 +25,4 @@ export type RefreshTokenResponse = {
22
25
  expires_in: string;
23
26
  refresh_token_expires_in: string;
24
27
  };
28
+ export type IdentityToken = AccessToken | RefreshToken;
package/package.json CHANGED
@@ -1,8 +1,7 @@
1
1
  {
2
2
  "name": "@ascentgl/ads-identity",
3
- "version": "0.0.6",
3
+ "version": "0.9.2",
4
4
  "peerDependencies": {
5
- "@ascentgl/ads-store": ">=0.9.5",
6
5
  "jwt-decode": ">=4.0.0"
7
6
  },
8
7
  "description": "This library was generated with [Nx](https://nx.dev).",