ngx-oauth 5.0.0 → 7.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +17 -16
  3. package/components/index.d.ts +1 -0
  4. package/components/{login/oauth-login.component.d.ts → o-auth-login.component.d.ts} +5 -6
  5. package/config/index.d.ts +17 -0
  6. package/esm2022/components/index.mjs +2 -0
  7. package/esm2022/components/o-auth-login.component.mjs +261 -0
  8. package/esm2022/config/index.mjs +32 -0
  9. package/esm2022/index.mjs +8 -0
  10. package/esm2022/models/index.mjs +16 -0
  11. package/esm2022/services/index.mjs +5 -0
  12. package/esm2022/services/o-auth-http-client.mjs +15 -0
  13. package/esm2022/services/o-auth-token.service.mjs +80 -0
  14. package/esm2022/services/o-auth.interceptor.mjs +43 -0
  15. package/esm2022/services/o-auth.service.mjs +302 -0
  16. package/fesm2022/ngx-oauth.mjs +731 -0
  17. package/fesm2022/ngx-oauth.mjs.map +1 -0
  18. package/index.d.ts +3 -5
  19. package/models/index.d.ts +3 -23
  20. package/package.json +10 -18
  21. package/services/index.d.ts +4 -0
  22. package/services/o-auth-http-client.d.ts +6 -0
  23. package/services/{token.service.d.ts → o-auth-token.service.d.ts} +5 -6
  24. package/services/o-auth.interceptor.d.ts +2 -0
  25. package/services/{oauth.service.d.ts → o-auth.service.d.ts} +5 -5
  26. package/esm2020/components/login/oauth-login.component.mjs +0 -119
  27. package/esm2020/index.mjs +0 -10
  28. package/esm2020/models/index.mjs +0 -47
  29. package/esm2020/oauth.module.mjs +0 -120
  30. package/esm2020/services/oauth.interceptor.mjs +0 -53
  31. package/esm2020/services/oauth.service.mjs +0 -300
  32. package/esm2020/services/token.service.mjs +0 -83
  33. package/fesm2015/ngx-oauth.mjs +0 -639
  34. package/fesm2015/ngx-oauth.mjs.map +0 -1
  35. package/fesm2020/ngx-oauth.mjs +0 -698
  36. package/fesm2020/ngx-oauth.mjs.map +0 -1
  37. package/oauth.module.d.ts +0 -14
  38. package/services/oauth.interceptor.d.ts +0 -13
  39. /package/{esm2020 → esm2022}/ngx-oauth.mjs +0 -0
@@ -1,639 +0,0 @@
1
- import * as i0 from '@angular/core';
2
- import { InjectionToken, inject, Injectable, Inject, Component, ViewEncapsulation, Input, Output, ContentChild, HostListener, PLATFORM_ID, Optional, NgModule } from '@angular/core';
3
- import * as i3 from '@angular/common/http';
4
- import { HttpHeaders, HttpParams, HttpClient, HttpBackend, HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http';
5
- import { __classPrivateFieldGet, __awaiter, __classPrivateFieldSet } from 'tslib';
6
- import { BehaviorSubject, distinctUntilChanged, switchMap, of, ReplaySubject, from, noop, firstValueFrom, throwError, take } from 'rxjs';
7
- import { shareReplay, map, catchError, filter, switchMap as switchMap$1, tap, concatMap, delay } from 'rxjs/operators';
8
- import * as i2 from '@angular/common';
9
- import { isPlatformBrowser, CommonModule } from '@angular/common';
10
- import * as i3$1 from '@angular/forms';
11
- import { FormsModule } from '@angular/forms';
12
- import { RouterModule } from '@angular/router';
13
-
14
- const SERVER_HOST = new InjectionToken('SERVER_HOST');
15
- const SERVER_PATH = new InjectionToken('SERVER_PATH');
16
- const LOCATION = new InjectionToken('Location');
17
- const STORAGE = new InjectionToken('Storage');
18
- const OAUTH_CONFIG = new InjectionToken('OAuthConfig');
19
- const OAUTH_TOKEN = new InjectionToken('OAuthToken');
20
- const HEADER_APPLICATION = new HttpHeaders({ 'Content-Type': 'application/x-www-form-urlencoded' });
21
- const OAUTH_HTTP_CLIENT = new InjectionToken('OAuthHttpClient');
22
- class OAuthConfig {
23
- }
24
- OAuthConfig.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: OAuthConfig, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
25
- OAuthConfig.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: OAuthConfig, providedIn: 'root', useFactory: () => inject(OAUTH_CONFIG).reduce((p, c) => (Object.assign(Object.assign({}, p), c)), {}) });
26
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: OAuthConfig, decorators: [{
27
- type: Injectable,
28
- args: [{
29
- providedIn: 'root',
30
- useFactory: () => inject(OAUTH_CONFIG).reduce((p, c) => (Object.assign(Object.assign({}, p), c)), {})
31
- }]
32
- }] });
33
- const provideOAuthConfig = (config = {}) => ({
34
- provide: OAUTH_CONFIG,
35
- useValue: config,
36
- multi: true
37
- });
38
- const provideOAuthConfigFactory = (factory, deps) => ({
39
- provide: OAUTH_CONFIG,
40
- useFactory: factory,
41
- deps: deps,
42
- multi: true
43
- });
44
- var OAuthType;
45
- (function (OAuthType) {
46
- OAuthType["RESOURCE"] = "password";
47
- OAuthType["AUTHORIZATION_CODE"] = "code";
48
- OAuthType["IMPLICIT"] = "token";
49
- OAuthType["CLIENT_CREDENTIAL"] = "client_credentials";
50
- })(OAuthType || (OAuthType = {}));
51
- var OAuthStatus;
52
- (function (OAuthStatus) {
53
- OAuthStatus["NOT_AUTHORIZED"] = "NOT_AUTHORIZED";
54
- OAuthStatus["AUTHORIZED"] = "AUTHORIZED";
55
- OAuthStatus["DENIED"] = "DENIED";
56
- })(OAuthStatus || (OAuthStatus = {}));
57
-
58
- var _OAuthTokenService_token$;
59
- const isExpiredToken = (token) => token && token.expires && Date.now() > token.expires || false;
60
- class OAuthTokenService {
61
- constructor(authConfig, http, zone) {
62
- this.authConfig = authConfig;
63
- this.http = http;
64
- this.zone = zone;
65
- _OAuthTokenService_token$.set(this, new BehaviorSubject(this.saved));
66
- this.token$ = __classPrivateFieldGet(this, _OAuthTokenService_token$, "f").pipe(distinctUntilChanged((p, c) => JSON.stringify(p || null) === JSON.stringify(c || null)), shareReplay(1), switchMap(token => !isExpiredToken(token) && of(token) || this.refreshToken(token)));
67
- this.type$ = this.token$.pipe(map(token => token === null || token === void 0 ? void 0 : token.type), shareReplay(1));
68
- this.accessToken$ = this.token$.pipe(map(token => token === null || token === void 0 ? void 0 : token.access_token), shareReplay(1));
69
- }
70
- get token() {
71
- return __classPrivateFieldGet(this, _OAuthTokenService_token$, "f").value;
72
- }
73
- set token(token) {
74
- const expiresIn = Number(token.expires_in) || 0;
75
- const result = Object.assign(Object.assign({}, token), expiresIn && { expires: Date.now() + expiresIn * 1000 } || {});
76
- this.saved = result;
77
- __classPrivateFieldGet(this, _OAuthTokenService_token$, "f").next(result);
78
- }
79
- get saved() {
80
- const { storageKey, storage } = this.authConfig;
81
- return storageKey && storage && storage[storageKey] && JSON.parse(storage[storageKey]) || {};
82
- }
83
- set saved(token) {
84
- const { storageKey, storage } = this.authConfig;
85
- if (storage && storageKey) {
86
- if (token) {
87
- storage[storageKey] = JSON.stringify(token);
88
- }
89
- else {
90
- delete storage[storageKey];
91
- }
92
- }
93
- }
94
- refreshToken(token) {
95
- const { tokenPath, clientId, clientSecret, scope } = this.authConfig.config;
96
- const { refresh_token } = token || {};
97
- return tokenPath && refresh_token && this.http.post(tokenPath, new HttpParams({
98
- fromObject: Object.assign(Object.assign(Object.assign({ client_id: clientId }, clientSecret && { client_secret: clientSecret } || {}), { grant_type: 'refresh_token', refresh_token }), scope && { scope } || {})
99
- }), {
100
- headers: HEADER_APPLICATION
101
- }).pipe(catchError(() => {
102
- this.token = {};
103
- return of(this.token);
104
- }), map(token => {
105
- this.token = Object.assign(Object.assign({}, this.token), token);
106
- return this.token;
107
- })) || of(token);
108
- }
109
- }
110
- _OAuthTokenService_token$ = new WeakMap();
111
- OAuthTokenService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: OAuthTokenService, deps: [{ token: OAuthConfig }, { token: OAUTH_HTTP_CLIENT }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable });
112
- OAuthTokenService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: OAuthTokenService });
113
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: OAuthTokenService, decorators: [{
114
- type: Injectable
115
- }], ctorParameters: function () {
116
- return [{ type: OAuthConfig }, { type: i3.HttpClient, decorators: [{
117
- type: Inject,
118
- args: [OAUTH_HTTP_CLIENT]
119
- }] }, { type: i0.NgZone }];
120
- } });
121
-
122
- const arrToString = (buf) => buf.reduce((s, b) => s + String.fromCharCode(b), '');
123
- const base64url = (str) => btoa(str)
124
- .replace(/\+/g, '-')
125
- .replace(/\//g, '_')
126
- .replace(/=/g, '');
127
- const randomString = (length = 48) => {
128
- const buff = arrToString(crypto.getRandomValues(new Uint8Array(length * 2)));
129
- return base64url(buff).substring(0, length);
130
- };
131
- const pkce = (value) => __awaiter(void 0, void 0, void 0, function* () {
132
- const buff = yield crypto.subtle.digest('SHA-256', new TextEncoder().encode(value));
133
- return base64url(arrToString(new Uint8Array(buff)));
134
- });
135
- const parseOauthUri = (hash) => {
136
- const regex = /([^&=]+)=([^&]*)/g;
137
- const params = {};
138
- let m;
139
- // tslint:disable-next-line:no-conditional-assignment
140
- while ((m = regex.exec(hash)) !== null) {
141
- params[decodeURIComponent(m[1])] = decodeURIComponent(m[2]);
142
- }
143
- return Object.keys(params).length && params || {};
144
- };
145
- const jwt = (token) => JSON.parse(atob(token.split('.')[1]));
146
- class OAuthService {
147
- constructor(authConfig, tokenService, http, location, locationService) {
148
- this.authConfig = authConfig;
149
- this.tokenService = tokenService;
150
- this.http = http;
151
- this.location = location;
152
- this.locationService = locationService;
153
- this.state$ = new ReplaySubject(1);
154
- this.config$ = of(this.config).pipe(filter(Boolean), filter(config => !!(config === null || config === void 0 ? void 0 : config.clientId)), map(config => config), switchMap$1(config => !config.issuerPath && of(config) || this.http.get(`${config.issuerPath}/.well-known/openid-configuration`).pipe(tap(v => this.config = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, v.authorization_endpoint && { authorizePath: v.authorization_endpoint } || {}), v.token_endpoint && { tokenPath: v.token_endpoint } || {}), v.revocation_endpoint && { revokePath: v.revocation_endpoint } || {}), v.code_challenge_methods_supported && { pkce: v.code_challenge_methods_supported.indexOf('S256') > -1 } || {}), v.userinfo_endpoint && { userPath: v.userinfo_endpoint } || {}), v.introspection_endpoint && { introspectionPath: v.introspection_endpoint } || {}), v.end_session_endpoint && { logoutPath: v.end_session_endpoint } || {}), { scope: config.scope || 'openid' })), map(() => this.config))), shareReplay(1));
155
- this.token$ = this.config$.pipe(tap(config => {
156
- const { hash, search, origin, pathname } = this.location;
157
- const isImplicitRedirect = hash && /(access_token=)|(error=)/.test(hash);
158
- const isAuthCodeRedirect = search && /(code=)|(error=)/.test(search) || hash && /(code=)|(error=)/.test(hash);
159
- if (isImplicitRedirect) {
160
- const parameters = parseOauthUri(hash.substring(1));
161
- this.token = Object.assign(Object.assign({}, parameters), { type: OAuthType.IMPLICIT });
162
- this.checkResponse(this.token, parameters);
163
- }
164
- else if (isAuthCodeRedirect) {
165
- const parameters = parseOauthUri(search && search.substring(1) || hash && hash.substring(1));
166
- if (!this.checkResponse(this.token, parameters)) {
167
- this.token = parameters;
168
- }
169
- else {
170
- const newParametersString = this.getCleanedUnSearchParameters();
171
- const { clientId, clientSecret, tokenPath, scope } = config;
172
- const { codeVerifier } = this.token || {}; //should be set by authorizationUrl construction
173
- this.http.post(tokenPath, new HttpParams({
174
- fromObject: Object.assign(Object.assign(Object.assign(Object.assign({ code: parameters === null || parameters === void 0 ? void 0 : parameters['code'], client_id: clientId }, clientSecret && { client_secret: clientSecret } || {}), { redirect_uri: `${origin}${pathname}`, grant_type: 'authorization_code' }), scope && { scope } || {}), codeVerifier && { code_verifier: codeVerifier } || {})
175
- }), { headers: HEADER_APPLICATION }).pipe().subscribe(token => {
176
- this.token = Object.assign(Object.assign({}, token), { type: OAuthType.AUTHORIZATION_CODE });
177
- this.locationService.replaceState(`${pathname}${newParametersString}`);
178
- });
179
- }
180
- }
181
- }), switchMap$1(() => this.tokenService.token$), shareReplay(1));
182
- this.status$ = this.token$.pipe(map(token => token.access_token && OAuthStatus.AUTHORIZED || token.error && OAuthStatus.DENIED || OAuthStatus.NOT_AUTHORIZED), shareReplay(1));
183
- this.userInfo$ = this.status$.pipe(filter(s => s === OAuthStatus.AUTHORIZED), map(() => this.config.userPath), filter(Boolean), switchMap$1(path => this.getUserInfo(path)), shareReplay(1));
184
- this.type$ = this.tokenService.type$;
185
- this.ignorePaths = this.authConfig.ignorePaths || [];
186
- }
187
- get storageKey() {
188
- return this.authConfig.storageKey;
189
- }
190
- set storageKey(storageKey) {
191
- if (storageKey) {
192
- this.authConfig.storageKey = storageKey;
193
- this.tokenService.token = this.tokenService.saved;
194
- }
195
- }
196
- get token() {
197
- return this.tokenService.token;
198
- }
199
- set token(token) {
200
- this.tokenService.token = token;
201
- }
202
- get config() {
203
- return this.authConfig.config;
204
- }
205
- set config(config) {
206
- if (config) {
207
- this.authConfig.config = Object.assign(Object.assign({}, this.authConfig.config), config);
208
- }
209
- }
210
- login(parameters) {
211
- return __awaiter(this, void 0, void 0, function* () {
212
- if (!!parameters && parameters.password) {
213
- yield this.resourceLogin(parameters);
214
- }
215
- else if (!!parameters && parameters.redirectUri && parameters.responseType) {
216
- yield this.toAuthorizationUrl(parameters);
217
- }
218
- else {
219
- yield this.clientCredentialLogin();
220
- }
221
- });
222
- }
223
- logout(useLogoutUrl) {
224
- this.revoke();
225
- this.token = {};
226
- const { logoutPath, logoutRedirectUri } = this.authConfig.config;
227
- if (useLogoutUrl && logoutPath) {
228
- const { origin, pathname } = this.location;
229
- const currentPath = `${origin}${pathname}`;
230
- this.location.replace(`${logoutPath}?post_logout_redirect_uri=${logoutRedirectUri || currentPath}`);
231
- }
232
- }
233
- getUserInfo(path) {
234
- const { userPath } = this.config;
235
- return this.http.get(path || userPath);
236
- }
237
- revoke() {
238
- const { revokePath, clientId, clientSecret } = this.authConfig.config;
239
- if (revokePath) {
240
- const { access_token, refresh_token } = this.token || {};
241
- const toRevoke = [];
242
- if (access_token) {
243
- toRevoke.push(Object.assign(Object.assign(Object.assign({}, clientId && { client_id: clientId } || {}), clientSecret && { client_secret: clientSecret } || {}), { token: access_token, token_type_hint: 'access_token' }));
244
- }
245
- if (refresh_token) {
246
- toRevoke.push(Object.assign(Object.assign(Object.assign({}, clientId && { client_id: clientId } || {}), clientSecret && { client_secret: clientSecret } || {}), { token: refresh_token, token_type_hint: 'refresh_token' }));
247
- }
248
- from(toRevoke).pipe(concatMap(o => of(o).pipe(delay(300))), // space request to avoid cancellation
249
- switchMap$1(o => this.http.post(revokePath, new HttpParams({ fromObject: o })))).subscribe(noop);
250
- }
251
- }
252
- clientCredentialLogin() {
253
- const { clientId, clientSecret, tokenPath, scope } = this.authConfig.config;
254
- return firstValueFrom(this.http.post(tokenPath, new HttpParams({
255
- fromObject: Object.assign({ client_id: clientId, client_secret: clientSecret, grant_type: OAuthType.CLIENT_CREDENTIAL }, scope ? { scope } : {})
256
- }), { headers: HEADER_APPLICATION }).pipe(catchError((err) => {
257
- this.token = err;
258
- return throwError(() => err);
259
- }), tap(params => {
260
- this.token = Object.assign(Object.assign({}, params), { type: OAuthType.CLIENT_CREDENTIAL });
261
- })));
262
- }
263
- resourceLogin(parameters) {
264
- const { clientId, clientSecret, tokenPath, scope } = this.authConfig.config;
265
- const { username, password } = parameters;
266
- return firstValueFrom(this.http.post(tokenPath, new HttpParams({
267
- fromObject: Object.assign(Object.assign(Object.assign(Object.assign({ client_id: clientId }, clientSecret && { client_secret: clientSecret } || {}), { grant_type: OAuthType.RESOURCE }), scope && { scope } || {}), { username,
268
- password })
269
- }), { headers: HEADER_APPLICATION }).pipe(catchError(err => {
270
- this.token = err;
271
- return throwError(() => err);
272
- }), tap(params => {
273
- this.token = Object.assign(Object.assign({}, params), { type: OAuthType.RESOURCE });
274
- })));
275
- }
276
- toAuthorizationUrl(parameters) {
277
- return __awaiter(this, void 0, void 0, function* () {
278
- const { config } = this.authConfig;
279
- let authorizationUrl = `${config.authorizePath}`;
280
- authorizationUrl += config.authorizePath.includes('?') && '&' || '?';
281
- authorizationUrl += `client_id=${config.clientId}`;
282
- authorizationUrl += `&redirect_uri=${encodeURIComponent(parameters.redirectUri)}`;
283
- authorizationUrl += `&response_type=${parameters.responseType}`;
284
- authorizationUrl += `&scope=${encodeURIComponent(config.scope || '')}`;
285
- authorizationUrl += `&state=${encodeURIComponent(parameters.state || '')}`;
286
- return this.location.replace(`${authorizationUrl}${this.generateNonce(config)}${yield this.generateCodeChallenge(config)}`);
287
- });
288
- }
289
- generateCodeChallenge(config) {
290
- return __awaiter(this, void 0, void 0, function* () {
291
- if (config.pkce) {
292
- const codeVerifier = randomString();
293
- this.token = Object.assign(Object.assign({}, this.token), { codeVerifier });
294
- return `&code_challenge=${yield pkce(codeVerifier)}&code_challenge_method=S256`;
295
- }
296
- return '';
297
- });
298
- }
299
- generateNonce(config) {
300
- if (config && config.scope && config.scope.indexOf('openid') > -1) {
301
- const nonce = randomString(10);
302
- this.token = Object.assign(Object.assign({}, this.token), { nonce });
303
- return `&nonce=${nonce}`;
304
- }
305
- return '';
306
- }
307
- checkResponse(token, parameters) {
308
- this.emitState(parameters);
309
- this.cleanLocationHash();
310
- if (!parameters || parameters['error']) {
311
- return false;
312
- }
313
- if (token && token.nonce && parameters['access_token']) {
314
- const jwtToken = jwt(parameters['access_token']);
315
- return token.nonce === jwtToken.nonce;
316
- }
317
- return parameters['access_token'] || parameters['code'];
318
- }
319
- getCleanedUnSearchParameters() {
320
- const { search } = this.location;
321
- let searchString = search && search.substring(1) || '';
322
- const hashKeys = ['code', 'state', 'error', 'error_description', 'session_state', 'scope', 'authuser', 'prompt'];
323
- hashKeys.forEach(hashKey => {
324
- const re = new RegExp('&' + hashKey + '(=[^&]*)?|^' + hashKey + '(=[^&]*)?&?');
325
- searchString = searchString.replace(re, '');
326
- });
327
- return searchString.length && `?${searchString}` || '';
328
- }
329
- cleanLocationHash() {
330
- const { hash } = this.location;
331
- let curHash = hash && hash.substring(1) || '';
332
- const hashKeys = [
333
- 'access_token',
334
- 'token_type',
335
- 'expires_in',
336
- 'scope',
337
- 'state',
338
- 'error',
339
- 'error_description',
340
- 'session_state',
341
- 'nonce',
342
- 'id_token',
343
- 'code'
344
- ];
345
- hashKeys.forEach(hashKey => {
346
- const re = new RegExp('&' + hashKey + '(=[^&]*)?|^' + hashKey + '(=[^&]*)?&?');
347
- curHash = curHash.replace(re, '');
348
- });
349
- this.location.hash = curHash;
350
- }
351
- emitState(parameters) {
352
- const { state } = parameters || {};
353
- state && this.state$.next(state);
354
- }
355
- }
356
- OAuthService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: OAuthService, deps: [{ token: OAuthConfig }, { token: OAuthTokenService }, { token: i3.HttpClient }, { token: LOCATION }, { token: i2.Location }], target: i0.ɵɵFactoryTarget.Injectable });
357
- OAuthService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: OAuthService });
358
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: OAuthService, decorators: [{
359
- type: Injectable
360
- }], ctorParameters: function () {
361
- return [{ type: OAuthConfig }, { type: OAuthTokenService }, { type: i3.HttpClient }, { type: Location, decorators: [{
362
- type: Inject,
363
- args: [LOCATION]
364
- }] }, { type: i2.Location }];
365
- } });
366
-
367
- class OAuthInterceptor {
368
- constructor(tokenService, authConfig) {
369
- this.tokenService = tokenService;
370
- this.authConfig = authConfig;
371
- }
372
- intercept(req, next) {
373
- return this.isPathExcepted(req) && next.handle(req) || this.tokenService.token$.pipe(take(1), map(token => {
374
- if (token === null || token === void 0 ? void 0 : token.access_token) {
375
- req = req.clone({
376
- setHeaders: {
377
- Authorization: `${token.token_type} ${token.access_token}`
378
- }
379
- });
380
- }
381
- return req;
382
- }), switchMap(req => next.handle(req)), catchError((err) => {
383
- if (err.status === 401) {
384
- this.tokenService.token = {
385
- error: `${err.status}`,
386
- error_description: err.message
387
- };
388
- }
389
- return throwError(() => err);
390
- }));
391
- }
392
- isPathExcepted(req) {
393
- const { ignorePaths } = this.authConfig || {};
394
- if (ignorePaths) {
395
- for (const ignorePath of ignorePaths) {
396
- try {
397
- if (req.url.match(ignorePath)) {
398
- return true;
399
- }
400
- }
401
- catch (err) {
402
- }
403
- }
404
- }
405
- return false;
406
- }
407
- }
408
- OAuthInterceptor.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: OAuthInterceptor, deps: [{ token: OAuthTokenService }, { token: OAuthConfig }], target: i0.ɵɵFactoryTarget.Injectable });
409
- OAuthInterceptor.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: OAuthInterceptor });
410
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: OAuthInterceptor, decorators: [{
411
- type: Injectable
412
- }], ctorParameters: function () { return [{ type: OAuthTokenService }, { type: OAuthConfig }]; } });
413
-
414
- var _OAuthLoginComponent_redirectUri, _OAuthLoginComponent_responseType, _OAuthLoginComponent_i18n;
415
- class OAuthLoginComponent {
416
- constructor(oauthService, locationService, location) {
417
- this.oauthService = oauthService;
418
- this.locationService = locationService;
419
- this.location = location;
420
- _OAuthLoginComponent_redirectUri.set(this, void 0);
421
- _OAuthLoginComponent_responseType.set(this, void 0);
422
- _OAuthLoginComponent_i18n.set(this, {
423
- username: 'Username',
424
- password: 'Password',
425
- submit: 'Sign in',
426
- notAuthorized: 'Sign in',
427
- authorized: 'Welcome',
428
- denied: 'Access Denied. Try again!'
429
- });
430
- this.type = OAuthType.RESOURCE;
431
- this.useLogoutUrl = false;
432
- this.state = '';
433
- this.stateChange = this.oauthService.state$.asObservable();
434
- this.username = '';
435
- this.password = '';
436
- this.OAuthStatus = OAuthStatus;
437
- this.OAuthType = OAuthType;
438
- this.collapse = false;
439
- this.status$ = this.oauthService.status$.pipe(tap(s => {
440
- if (s === OAuthStatus.AUTHORIZED && this.profileName$) {
441
- this.profileName$.pipe(take(1)).subscribe(n => this.profileName = n);
442
- }
443
- else {
444
- const { token } = this.oauthService;
445
- const userInfo = token && token.id_token && JSON.parse(atob(token.id_token.split('.')[1])) || {};
446
- this.profileName = userInfo.name || userInfo.username || userInfo.email || userInfo.sub || '';
447
- }
448
- }));
449
- this.loginFunction = (p) => this.login(p);
450
- this.logoutFunction = () => this.logout();
451
- }
452
- get i18n() {
453
- return __classPrivateFieldGet(this, _OAuthLoginComponent_i18n, "f");
454
- }
455
- set i18n(i18n) {
456
- __classPrivateFieldSet(this, _OAuthLoginComponent_i18n, Object.assign(Object.assign({}, __classPrivateFieldGet(this, _OAuthLoginComponent_i18n, "f")), i18n), "f");
457
- }
458
- get redirectUri() {
459
- return __classPrivateFieldGet(this, _OAuthLoginComponent_redirectUri, "f") || `${this.location.origin}${this.locationService.path(true) || '/'}`;
460
- }
461
- set redirectUri(redirectUri) {
462
- if (redirectUri) {
463
- __classPrivateFieldSet(this, _OAuthLoginComponent_redirectUri, redirectUri, "f");
464
- }
465
- }
466
- set responseType(responseType) {
467
- if (this.responseType) {
468
- __classPrivateFieldSet(this, _OAuthLoginComponent_responseType, responseType, "f");
469
- }
470
- }
471
- get responseType() {
472
- return __classPrivateFieldGet(this, _OAuthLoginComponent_responseType, "f") || this.type;
473
- }
474
- logout() {
475
- this.oauthService.logout(this.useLogoutUrl);
476
- }
477
- login(parameters) {
478
- this.collapse = false;
479
- return this.oauthService.login(parameters);
480
- }
481
- toggleCollapse() {
482
- this.collapse = !this.collapse;
483
- }
484
- keyboardEvent() {
485
- this.collapse = false;
486
- }
487
- }
488
- _OAuthLoginComponent_redirectUri = new WeakMap(), _OAuthLoginComponent_responseType = new WeakMap(), _OAuthLoginComponent_i18n = new WeakMap();
489
- OAuthLoginComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: OAuthLoginComponent, deps: [{ token: OAuthService }, { token: i2.Location }, { token: LOCATION }], target: i0.ɵɵFactoryTarget.Component });
490
- OAuthLoginComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: OAuthLoginComponent, selector: "oauth-login", inputs: { type: "type", i18n: "i18n", redirectUri: "redirectUri", responseType: "responseType", useLogoutUrl: "useLogoutUrl", state: "state", profileName$: "profileName$" }, outputs: { stateChange: "stateChange" }, host: { listeners: { "window:keydown.escape": "keyboardEvent()" } }, queries: [{ propertyName: "loginTemplate", first: true, predicate: ["login"], descendants: true }], ngImport: i0, template: "<ng-container *ngIf=\"loginTemplate; else defaultLogin\"\r\n [ngTemplateOutlet]=\"loginTemplate\"\r\n [ngTemplateOutletContext]=\"{login: loginFunction, logout: logoutFunction, status: status$ | async}\">\r\n</ng-container>\r\n<ng-template #defaultLogin>\r\n <ng-container *ngIf=\"status$ | async as status\">\r\n <ng-container *ngIf=\"type === OAuthType.RESOURCE; else noResource\">\r\n <div class=\"oauth dropdown text-end {{collapse ? 'show': ''}}\">\r\n <button class=\"btn btn-link p-0 dropdown-toggle\"\r\n (click)=\"status === OAuthStatus.AUTHORIZED ? logout() : toggleCollapse()\">\r\n <ng-container *ngTemplateOutlet=\"message\"></ng-container>\r\n </button>\r\n <div class=\"dropdown-menu mr-3 {{collapse ? 'show': ''}}\">\r\n <form class=\"p-3\"\r\n #form=\"ngForm\"\r\n *ngIf=\"status === OAuthStatus.NOT_AUTHORIZED || status === OAuthStatus.DENIED\"\r\n (submit)=\"login({username: username, password: password})\">\r\n <div class=\"mb-3\">\r\n <input type=\"text\"\r\n class=\"form-control\"\r\n name=\"username\"\r\n required\r\n [(ngModel)]=\"username\"\r\n [placeholder]=\"i18n.username\">\r\n </div>\r\n <div class=\"mb-3\">\r\n <input type=\"password\"\r\n class=\"form-control\"\r\n name=\"password\"\r\n required\r\n [(ngModel)]=\"password\"\r\n [placeholder]=\"i18n.password\">\r\n </div>\r\n <div class=\"text-end\">\r\n <button type=\"submit\"\r\n class=\"btn btn-primary\"\r\n [disabled]=\"form.invalid\">{{i18n.submit}}</button>\r\n </div>\r\n </form>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <ng-template #noResource>\r\n <a role=\"button\"\r\n class=\"oauth\"\r\n (click)=\"status === OAuthStatus.AUTHORIZED ? logout() : login({responseType: responseType, redirectUri: redirectUri, state:state})\">\r\n <ng-container *ngTemplateOutlet=\"message\"></ng-container>\r\n </a>\r\n </ng-template>\r\n\r\n <ng-template #message>\r\n <span class=\"not-authorized\"\r\n *ngIf=\"status === OAuthStatus.NOT_AUTHORIZED\"\r\n [innerHTML]=\"i18n.notAuthorized\"></span>\r\n <span class=\"authorized\"\r\n *ngIf=\"status === OAuthStatus.AUTHORIZED\">\r\n <span class=\"welcome\" [innerHTML]=\"i18n.authorized + '&nbsp;'\"></span>\r\n <strong class=\"profile-name\"\r\n [innerHTML]=\"profileName\"></strong>\r\n </span>\r\n <span class=\"denied\"\r\n *ngIf=\"status === OAuthStatus.DENIED\"\r\n [innerHTML]=\"i18n.denied\"></span>\r\n </ng-template>\r\n </ng-container>\r\n</ng-template>\r\n\r\n", styles: [".oauth .dropdown-menu{left:auto;right:0;box-shadow:0 5px 10px #0003;min-width:250px}.oauth .dropdown-menu:before{content:\"\";display:inline-block;border-left:7px solid transparent;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-bottom-color:#0003;position:absolute;top:-7px;left:auto;right:15px}.oauth .dropdown-menu:after{content:\"\";display:inline-block;border-left:6px solid transparent;border-right:6px solid transparent;border-bottom:6px solid #ffffff;position:absolute;top:-6px;left:auto;right:16px}\n"], dependencies: [{ kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i3$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i3$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3$1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i3$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i3$1.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "pipe", type: i2.AsyncPipe, name: "async" }], encapsulation: i0.ViewEncapsulation.None });
491
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: OAuthLoginComponent, decorators: [{
492
- type: Component,
493
- args: [{ selector: 'oauth-login', encapsulation: ViewEncapsulation.None, template: "<ng-container *ngIf=\"loginTemplate; else defaultLogin\"\r\n [ngTemplateOutlet]=\"loginTemplate\"\r\n [ngTemplateOutletContext]=\"{login: loginFunction, logout: logoutFunction, status: status$ | async}\">\r\n</ng-container>\r\n<ng-template #defaultLogin>\r\n <ng-container *ngIf=\"status$ | async as status\">\r\n <ng-container *ngIf=\"type === OAuthType.RESOURCE; else noResource\">\r\n <div class=\"oauth dropdown text-end {{collapse ? 'show': ''}}\">\r\n <button class=\"btn btn-link p-0 dropdown-toggle\"\r\n (click)=\"status === OAuthStatus.AUTHORIZED ? logout() : toggleCollapse()\">\r\n <ng-container *ngTemplateOutlet=\"message\"></ng-container>\r\n </button>\r\n <div class=\"dropdown-menu mr-3 {{collapse ? 'show': ''}}\">\r\n <form class=\"p-3\"\r\n #form=\"ngForm\"\r\n *ngIf=\"status === OAuthStatus.NOT_AUTHORIZED || status === OAuthStatus.DENIED\"\r\n (submit)=\"login({username: username, password: password})\">\r\n <div class=\"mb-3\">\r\n <input type=\"text\"\r\n class=\"form-control\"\r\n name=\"username\"\r\n required\r\n [(ngModel)]=\"username\"\r\n [placeholder]=\"i18n.username\">\r\n </div>\r\n <div class=\"mb-3\">\r\n <input type=\"password\"\r\n class=\"form-control\"\r\n name=\"password\"\r\n required\r\n [(ngModel)]=\"password\"\r\n [placeholder]=\"i18n.password\">\r\n </div>\r\n <div class=\"text-end\">\r\n <button type=\"submit\"\r\n class=\"btn btn-primary\"\r\n [disabled]=\"form.invalid\">{{i18n.submit}}</button>\r\n </div>\r\n </form>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <ng-template #noResource>\r\n <a role=\"button\"\r\n class=\"oauth\"\r\n (click)=\"status === OAuthStatus.AUTHORIZED ? logout() : login({responseType: responseType, redirectUri: redirectUri, state:state})\">\r\n <ng-container *ngTemplateOutlet=\"message\"></ng-container>\r\n </a>\r\n </ng-template>\r\n\r\n <ng-template #message>\r\n <span class=\"not-authorized\"\r\n *ngIf=\"status === OAuthStatus.NOT_AUTHORIZED\"\r\n [innerHTML]=\"i18n.notAuthorized\"></span>\r\n <span class=\"authorized\"\r\n *ngIf=\"status === OAuthStatus.AUTHORIZED\">\r\n <span class=\"welcome\" [innerHTML]=\"i18n.authorized + '&nbsp;'\"></span>\r\n <strong class=\"profile-name\"\r\n [innerHTML]=\"profileName\"></strong>\r\n </span>\r\n <span class=\"denied\"\r\n *ngIf=\"status === OAuthStatus.DENIED\"\r\n [innerHTML]=\"i18n.denied\"></span>\r\n </ng-template>\r\n </ng-container>\r\n</ng-template>\r\n\r\n", styles: [".oauth .dropdown-menu{left:auto;right:0;box-shadow:0 5px 10px #0003;min-width:250px}.oauth .dropdown-menu:before{content:\"\";display:inline-block;border-left:7px solid transparent;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-bottom-color:#0003;position:absolute;top:-7px;left:auto;right:15px}.oauth .dropdown-menu:after{content:\"\";display:inline-block;border-left:6px solid transparent;border-right:6px solid transparent;border-bottom:6px solid #ffffff;position:absolute;top:-6px;left:auto;right:16px}\n"] }]
494
- }], ctorParameters: function () {
495
- return [{ type: OAuthService }, { type: i2.Location }, { type: Location, decorators: [{
496
- type: Inject,
497
- args: [LOCATION]
498
- }] }];
499
- }, propDecorators: { type: [{
500
- type: Input
501
- }], i18n: [{
502
- type: Input
503
- }], redirectUri: [{
504
- type: Input
505
- }], responseType: [{
506
- type: Input
507
- }], useLogoutUrl: [{
508
- type: Input
509
- }], state: [{
510
- type: Input
511
- }], stateChange: [{
512
- type: Output
513
- }], profileName$: [{
514
- type: Input
515
- }], loginTemplate: [{
516
- type: ContentChild,
517
- args: ['login', { static: false }]
518
- }], keyboardEvent: [{
519
- type: HostListener,
520
- args: ['window:keydown.escape']
521
- }] } });
522
-
523
- const mockLocation = (serverHost, serverPath) => {
524
- const url = new URL(serverHost && serverPath ? `${serverHost}${serverPath}` : 'http://localhost');
525
- const { href, origin, protocol, host, hostname, port, pathname, search, hash } = url;
526
- return {
527
- href, origin, protocol, host, hostname, port, pathname, search, hash,
528
- reload() {
529
- },
530
- assign(_) {
531
- },
532
- ancestorOrigins: {},
533
- replace(_) {
534
- }
535
- };
536
- };
537
- const LocationService = {
538
- provide: LOCATION,
539
- useFactory(platformId, serverHost, serverPath) {
540
- return isPlatformBrowser(platformId) ? location : mockLocation(serverHost, serverPath);
541
- },
542
- deps: [
543
- PLATFORM_ID,
544
- [new Optional(), SERVER_HOST],
545
- [new Optional(), SERVER_PATH]
546
- ]
547
- };
548
- const mockStorage = {
549
- clear() {
550
- },
551
- getItem(key) {
552
- return null;
553
- },
554
- key(index) {
555
- return null;
556
- },
557
- removeItem(key) {
558
- },
559
- setItem(key, value) {
560
- },
561
- length: 0
562
- };
563
- const StorageService = {
564
- provide: STORAGE,
565
- useFactory(platformId) {
566
- return isPlatformBrowser(platformId) ? localStorage : mockStorage;
567
- },
568
- deps: [PLATFORM_ID]
569
- };
570
- const OAuthHttpClient = {
571
- provide: OAUTH_HTTP_CLIENT,
572
- useFactory(httpBackend) {
573
- // avoid http interceptors
574
- return new HttpClient(httpBackend);
575
- },
576
- deps: [HttpBackend]
577
- };
578
- const OAuthInterceptorService = {
579
- provide: HTTP_INTERCEPTORS,
580
- useClass: OAuthInterceptor,
581
- multi: true,
582
- };
583
- const defaultConfig = (storage) => {
584
- return {
585
- storage,
586
- storageKey: 'token',
587
- ignorePaths: []
588
- };
589
- };
590
- class OAuthModule {
591
- static forRoot(config = {}) {
592
- return {
593
- ngModule: OAuthModule,
594
- providers: [
595
- LocationService,
596
- StorageService,
597
- OAuthHttpClient,
598
- provideOAuthConfigFactory((storage) => (Object.assign(Object.assign({}, defaultConfig(storage)), config)), [STORAGE]),
599
- OAuthTokenService,
600
- OAuthInterceptorService,
601
- OAuthService,
602
- ]
603
- };
604
- }
605
- }
606
- OAuthModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: OAuthModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
607
- OAuthModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.0.4", ngImport: i0, type: OAuthModule, declarations: [OAuthLoginComponent], imports: [CommonModule,
608
- FormsModule,
609
- HttpClientModule,
610
- RouterModule], exports: [OAuthLoginComponent] });
611
- OAuthModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: OAuthModule, imports: [CommonModule,
612
- FormsModule,
613
- HttpClientModule,
614
- RouterModule] });
615
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: OAuthModule, decorators: [{
616
- type: NgModule,
617
- args: [{
618
- imports: [
619
- CommonModule,
620
- FormsModule,
621
- HttpClientModule,
622
- RouterModule,
623
- ],
624
- declarations: [OAuthLoginComponent],
625
- exports: [OAuthLoginComponent]
626
- }]
627
- }] });
628
-
629
- /*
630
- * Public API Surface of ngx-oauth
631
- */
632
-
633
- /**
634
- * Generated bundle index. Do not edit.
635
- */
636
-
637
- export { HEADER_APPLICATION, LOCATION, OAUTH_CONFIG, OAUTH_HTTP_CLIENT, OAUTH_TOKEN, OAuthConfig, OAuthInterceptor, OAuthLoginComponent, OAuthModule, OAuthService, OAuthStatus, OAuthTokenService, OAuthType, SERVER_HOST, SERVER_PATH, STORAGE, provideOAuthConfig, provideOAuthConfigFactory };
638
- //# sourceMappingURL=ngx-oauth.mjs.map
639
- //# sourceMappingURL=ngx-oauth.mjs.map