ngx-oauth 3.0.2 → 4.2.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.
@@ -1,13 +1,13 @@
1
1
  import * as i0 from '@angular/core';
2
- import { InjectionToken, inject, Injectable, Inject, EventEmitter, Component, ViewEncapsulation, Input, Output, ContentChild, HostListener, PLATFORM_ID, Optional, NgModule } from '@angular/core';
3
- import { __awaiter } from 'tslib';
4
- import * as i1 from '@angular/common/http';
5
- import { HttpHeaders, HttpParams, HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http';
6
- import { filter, map, switchMap, shareReplay, tap, catchError, concatMap, delay } from 'rxjs/operators';
7
- import { ReplaySubject, of, EMPTY, from, noop, firstValueFrom, throwError, Subscription, take } from 'rxjs';
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 { shareReplay, map, catchError, filter, switchMap as switchMap$1, tap, concatMap, delay } from 'rxjs/operators';
7
+ import { BehaviorSubject, distinctUntilChanged, switchMap, of, ReplaySubject, from, noop, firstValueFrom, throwError, take, Subscription } from 'rxjs';
8
8
  import * as i2 from '@angular/common';
9
9
  import { isPlatformBrowser, CommonModule } from '@angular/common';
10
- import * as i3 from '@angular/forms';
10
+ import * as i3$1 from '@angular/forms';
11
11
  import { FormsModule } from '@angular/forms';
12
12
  import { RouterModule } from '@angular/router';
13
13
 
@@ -17,11 +17,13 @@ const LOCATION = new InjectionToken('Location');
17
17
  const STORAGE = new InjectionToken('Storage');
18
18
  const OAUTH_CONFIG = new InjectionToken('OAuthConfig');
19
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');
20
22
  class OAuthConfig {
21
23
  }
22
- OAuthConfig.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.5", ngImport: i0, type: OAuthConfig, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
23
- OAuthConfig.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.5", ngImport: i0, type: OAuthConfig, providedIn: 'root', useFactory: () => inject(OAUTH_CONFIG).reduce((p, c) => (Object.assign(Object.assign({}, p), c)), {}) });
24
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.5", ngImport: i0, type: OAuthConfig, decorators: [{
24
+ OAuthConfig.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.3", ngImport: i0, type: OAuthConfig, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
25
+ OAuthConfig.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.3", 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: "14.1.3", ngImport: i0, type: OAuthConfig, decorators: [{
25
27
  type: Injectable,
26
28
  args: [{
27
29
  providedIn: 'root',
@@ -53,6 +55,70 @@ var OAuthStatus;
53
55
  OAuthStatus["DENIED"] = "DENIED";
54
56
  })(OAuthStatus || (OAuthStatus = {}));
55
57
 
58
+ var _TokenService_token$;
59
+ const isExpiredToken = (token) => token && token.expires && Date.now() > token.expires || false;
60
+ class TokenService {
61
+ constructor(authConfig, http, zone) {
62
+ this.authConfig = authConfig;
63
+ this.http = http;
64
+ this.zone = zone;
65
+ _TokenService_token$.set(this, new BehaviorSubject(this.saved));
66
+ this.token$ = __classPrivateFieldGet(this, _TokenService_token$, "f").pipe(distinctUntilChanged((p, c) => JSON.stringify(p || null) === JSON.stringify(c || null)), switchMap(token => !isExpiredToken(token) && of(token) || this.refreshToken(token)), shareReplay(1));
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, _TokenService_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, _TokenService_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
+ _TokenService_token$ = new WeakMap();
111
+ TokenService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.3", ngImport: i0, type: TokenService, deps: [{ token: OAuthConfig }, { token: OAUTH_HTTP_CLIENT }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable });
112
+ TokenService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.3", ngImport: i0, type: TokenService });
113
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.3", ngImport: i0, type: TokenService, 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
+
56
122
  const arrToString = (buf) => buf.reduce((s, b) => s + String.fromCharCode(b), '');
57
123
  const base64url = (str) => btoa(str)
58
124
  .replace(/\+/g, '-')
@@ -66,7 +132,6 @@ const pkce = (value) => __awaiter(void 0, void 0, void 0, function* () {
66
132
  const buff = yield crypto.subtle.digest('SHA-256', new TextEncoder().encode(value));
67
133
  return base64url(arrToString(new Uint8Array(buff)));
68
134
  });
69
- const REQUEST_HEADER = new HttpHeaders({ 'Content-Type': 'application/x-www-form-urlencoded' });
70
135
  const parseOauthUri = (hash) => {
71
136
  const regex = /([^&=]+)=([^&]*)/g;
72
137
  const params = {};
@@ -75,126 +140,83 @@ const parseOauthUri = (hash) => {
75
140
  while ((m = regex.exec(hash)) !== null) {
76
141
  params[decodeURIComponent(m[1])] = decodeURIComponent(m[2]);
77
142
  }
78
- if (Object.keys(params).length) {
79
- return params;
80
- }
81
- return null;
143
+ return Object.keys(params).length && params || {};
82
144
  };
83
145
  const jwt = (token) => JSON.parse(atob(token.split('.')[1]));
84
146
  class OAuthService {
85
- constructor(http, zone, authConfig, location, locationService) {
86
- this.http = http;
87
- this.zone = zone;
147
+ constructor(authConfig, tokenService, http, location, locationService) {
88
148
  this.authConfig = authConfig;
149
+ this.tokenService = tokenService;
150
+ this.http = http;
89
151
  this.location = location;
90
152
  this.locationService = locationService;
91
- this._token = null;
92
- this._status = OAuthStatus.NOT_AUTHORIZED;
93
153
  this.state$ = new ReplaySubject(1);
94
- this.status$ = new ReplaySubject(1);
95
- this.userInfo$ = this.status$.pipe(filter(s => s === OAuthStatus.AUTHORIZED), map(() => {
96
- const { config } = this.authConfig;
97
- return config.userPath;
98
- }), filter(p => !!p), switchMap(path => this.http.get(path)), shareReplay());
99
- setTimeout(() => this.init()); // decouple for http interceptor
100
- }
101
- /**
102
- * Get the oauth config for initialize. If OpenId with issuerPath is configured then configure from server openid configuration.
103
- * @protected
104
- */
105
- get config$() {
106
- let { config } = this.authConfig;
107
- if (config && config.clientId) {
108
- const { issuerPath, scope } = config;
109
- if (issuerPath) {
110
- return this.http.get(`${issuerPath}/.well-known/openid-configuration`).pipe(tap(v => this.type && this.set(this.type, 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 && {} || { scope: 'openid' }))), map(() => this.authConfig.config));
111
- }
112
- return of(config);
113
- }
114
- console.warn('clientId is missing in oauth config');
115
- return EMPTY;
116
- }
117
- /**
118
- * Init. Will check the url implicit or authorization flow or existing saved token.
119
- * @protected
120
- */
121
- init() {
122
- const { hash, search, origin, pathname } = this.location;
123
- const isImplicitRedirect = hash && /(access_token=)|(error=)/.test(hash);
124
- const isAuthCodeRedirect = search && /(code=)|(error=)/.test(search);
125
- const { storageKey } = this.authConfig;
126
- const savedToken = storageKey && this.authConfig.storage && this.authConfig.storage[storageKey] &&
127
- JSON.parse(this.authConfig.storage[storageKey]);
128
- this.config$.subscribe(config => {
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);
129
159
  if (isImplicitRedirect) {
130
- const parameters = parseOauthUri(hash.substr(1));
131
- this.token = parameters;
132
- this.status = this.checkResponse(savedToken, parameters) && OAuthStatus.AUTHORIZED || OAuthStatus.DENIED;
160
+ const parameters = parseOauthUri(hash.substring(1));
161
+ this.token = Object.assign(Object.assign({}, parameters), { type: OAuthType.IMPLICIT });
162
+ this.checkResponse(this.token, parameters);
133
163
  }
134
164
  else if (isAuthCodeRedirect) {
135
- const parameters = parseOauthUri(search.substr(1));
136
- if (!this.checkResponse(savedToken, parameters)) {
165
+ const parameters = parseOauthUri(search && search.substring(1) || hash && hash.substring(1));
166
+ if (!this.checkResponse(this.token, parameters)) {
137
167
  this.token = parameters;
138
- this.status = OAuthStatus.DENIED;
139
168
  }
140
169
  else {
141
170
  const newParametersString = this.getCleanedUnSearchParameters();
142
171
  const { clientId, clientSecret, tokenPath, scope } = config;
143
- const codeVerifier = savedToken && savedToken.codeVerifier;
172
+ const { codeVerifier } = this.token || {}; //should be set by authorizationUrl construction
144
173
  this.http.post(tokenPath, new HttpParams({
145
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 } || {})
146
- }), { headers: REQUEST_HEADER }).pipe(catchError((err) => {
147
- this.token = err;
148
- this.status = OAuthStatus.DENIED;
149
- this.locationService.replaceState(`${pathname}${newParametersString}`);
150
- return EMPTY;
151
- })).subscribe(token => {
152
- this.token = token;
153
- this.status = OAuthStatus.AUTHORIZED;
175
+ }), { headers: HEADER_APPLICATION }).pipe().subscribe(token => {
176
+ this.token = Object.assign(Object.assign({}, token), { type: OAuthType.AUTHORIZATION_CODE });
154
177
  this.locationService.replaceState(`${pathname}${newParametersString}`);
155
178
  });
156
179
  }
157
180
  }
158
- else if (savedToken) {
159
- this._token = savedToken;
160
- const { access_token, refresh_token, error } = savedToken;
161
- if (access_token) {
162
- if (refresh_token) { // force refresh since might be a manual page refresh
163
- this.refreshToken();
164
- }
165
- else {
166
- this.status = OAuthStatus.AUTHORIZED;
167
- }
168
- }
169
- else {
170
- this.status = error && OAuthStatus.DENIED || OAuthStatus.NOT_AUTHORIZED;
171
- }
172
- }
173
- else {
174
- this.status = OAuthStatus.NOT_AUTHORIZED;
175
- }
176
- });
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(() => {
184
+ const { config } = this.authConfig;
185
+ return config.userPath;
186
+ }), filter(Boolean), switchMap$1(path => this.http.get(path)), shareReplay(1));
187
+ this.type$ = this.tokenService.type$;
188
+ this.ignorePaths = this.authConfig.ignorePaths || [];
189
+ }
190
+ get token() {
191
+ return this.tokenService.token;
192
+ }
193
+ set token(token) {
194
+ this.tokenService.token = token;
195
+ }
196
+ get config() {
197
+ return this.authConfig.config;
198
+ }
199
+ set config(config) {
200
+ if (config) {
201
+ this.authConfig.config = Object.assign(Object.assign({}, this.authConfig.config), config);
202
+ }
177
203
  }
178
204
  login(parameters) {
179
205
  return __awaiter(this, void 0, void 0, function* () {
180
- if (this.isResourceType(parameters)) {
206
+ if (!!parameters && parameters.password) {
181
207
  yield this.resourceLogin(parameters);
182
208
  }
183
- else if (this.isAuthorizationCodeType(parameters)) {
184
- yield this.authorizationCodeLogin(parameters);
185
- }
186
- else if (this.isImplicitType(parameters)) {
187
- yield this.implicitLogin(parameters);
209
+ else if (!!parameters && parameters.redirectUri && parameters.responseType) {
210
+ yield this.toAuthorizationUrl(parameters);
188
211
  }
189
- else if (this.isClientCredentialType()) {
212
+ else {
190
213
  yield this.clientCredentialLogin();
191
214
  }
192
215
  });
193
216
  }
194
217
  logout(useLogoutUrl) {
195
218
  this.revoke();
196
- this.token = null;
197
- this.status = OAuthStatus.NOT_AUTHORIZED;
219
+ this.token = {};
198
220
  const { logoutPath, logoutRedirectUri } = this.authConfig.config;
199
221
  if (useLogoutUrl && logoutPath) {
200
222
  const { origin, pathname } = this.location;
@@ -205,7 +227,7 @@ class OAuthService {
205
227
  revoke() {
206
228
  const { revokePath, clientId, clientSecret } = this.authConfig.config;
207
229
  if (revokePath) {
208
- const { access_token, refresh_token } = this.token;
230
+ const { access_token, refresh_token } = this.token || {};
209
231
  const toRevoke = [];
210
232
  if (access_token) {
211
233
  toRevoke.push(Object.assign(Object.assign(Object.assign({}, clientId && { client_id: clientId } || {}), clientSecret && { client_secret: clientSecret } || {}), { token: access_token, token_type_hint: 'access_token' }));
@@ -214,95 +236,44 @@ class OAuthService {
214
236
  toRevoke.push(Object.assign(Object.assign(Object.assign({}, clientId && { client_id: clientId } || {}), clientSecret && { client_secret: clientSecret } || {}), { token: refresh_token, token_type_hint: 'refresh_token' }));
215
237
  }
216
238
  from(toRevoke).pipe(concatMap(o => of(o).pipe(delay(300))), // space request to avoid cancellation
217
- switchMap(o => this.http.post(revokePath, new HttpParams({ fromObject: o })))).subscribe(noop);
218
- }
219
- }
220
- get status() {
221
- return this._status;
222
- }
223
- set status(status) {
224
- this._status = status;
225
- this.status$.next(status);
226
- }
227
- set(type, config) {
228
- this.authConfig.type = type;
229
- if (config) {
230
- this.authConfig.config = Object.assign(Object.assign({}, this.authConfig.config), config);
239
+ switchMap$1(o => this.http.post(revokePath, new HttpParams({ fromObject: o })))).subscribe(noop);
231
240
  }
232
241
  }
233
- get type() {
234
- return this.authConfig.type;
235
- }
236
- get ignorePaths() {
237
- return this.authConfig.ignorePaths || [];
238
- }
239
242
  clientCredentialLogin() {
240
- return __awaiter(this, void 0, void 0, function* () {
241
- const { clientId, clientSecret, tokenPath, scope } = this.authConfig.config;
242
- yield firstValueFrom(this.http.post(tokenPath, new HttpParams({
243
- fromObject: Object.assign({ client_id: clientId, client_secret: clientSecret, grant_type: OAuthType.CLIENT_CREDENTIAL }, scope ? { scope } : {})
244
- }), { headers: REQUEST_HEADER }).pipe(catchError((err) => {
245
- this.token = err;
246
- this.status = OAuthStatus.DENIED;
247
- return EMPTY;
248
- }), tap(params => {
249
- this.token = params;
250
- this.status = OAuthStatus.AUTHORIZED;
251
- })));
252
- });
243
+ const { clientId, clientSecret, tokenPath, scope } = this.authConfig.config;
244
+ return firstValueFrom(this.http.post(tokenPath, new HttpParams({
245
+ fromObject: Object.assign({ client_id: clientId, client_secret: clientSecret, grant_type: OAuthType.CLIENT_CREDENTIAL }, scope ? { scope } : {})
246
+ }), { headers: HEADER_APPLICATION }).pipe(catchError((err) => {
247
+ this.token = err;
248
+ return throwError(() => err);
249
+ }), tap(params => {
250
+ this.token = Object.assign(Object.assign({}, params), { type: OAuthType.CLIENT_CREDENTIAL });
251
+ })));
253
252
  }
254
253
  resourceLogin(parameters) {
255
- return __awaiter(this, void 0, void 0, function* () {
256
- const { clientId, clientSecret, tokenPath, scope } = this.authConfig.config;
257
- const { username, password } = parameters;
258
- yield firstValueFrom(this.http.post(tokenPath, new HttpParams({
259
- fromObject: Object.assign(Object.assign(Object.assign(Object.assign({ client_id: clientId }, clientSecret && { client_secret: clientSecret } || {}), { grant_type: OAuthType.RESOURCE }), scope && { scope } || {}), { username,
260
- password })
261
- }), { headers: REQUEST_HEADER }).pipe(catchError(err => {
262
- this.token = err;
263
- this.status = OAuthStatus.DENIED;
264
- return EMPTY;
265
- }), tap(params => {
266
- this.token = params;
267
- this.status = OAuthStatus.AUTHORIZED;
268
- })));
269
- });
270
- }
271
- implicitLogin(parameters) {
272
- return __awaiter(this, void 0, void 0, function* () {
273
- const authUrl = yield this.toAuthorizationUrl(parameters, OAuthType.IMPLICIT);
274
- this.location.replace(authUrl);
275
- });
276
- }
277
- authorizationCodeLogin(parameters) {
278
- return __awaiter(this, void 0, void 0, function* () {
279
- const authUrl = yield this.toAuthorizationUrl(parameters, OAuthType.AUTHORIZATION_CODE);
280
- this.location.replace(authUrl);
281
- });
282
- }
283
- isClientCredentialType() {
284
- return this.authConfig.type === OAuthType.CLIENT_CREDENTIAL;
285
- }
286
- isResourceType(parameters) {
287
- return this.authConfig.type === OAuthType.RESOURCE && !!(parameters === null || parameters === void 0 ? void 0 : parameters.password);
288
- }
289
- isImplicitType(parameters) {
290
- return this.authConfig.type === OAuthType.IMPLICIT && !!(parameters === null || parameters === void 0 ? void 0 : parameters.redirectUri);
291
- }
292
- isAuthorizationCodeType(parameters) {
293
- return this.authConfig.type === OAuthType.AUTHORIZATION_CODE && !!(parameters === null || parameters === void 0 ? void 0 : parameters.redirectUri);
294
- }
295
- toAuthorizationUrl(parameters, responseType) {
254
+ const { clientId, clientSecret, tokenPath, scope } = this.authConfig.config;
255
+ const { username, password } = parameters;
256
+ return firstValueFrom(this.http.post(tokenPath, new HttpParams({
257
+ fromObject: Object.assign(Object.assign(Object.assign(Object.assign({ client_id: clientId }, clientSecret && { client_secret: clientSecret } || {}), { grant_type: OAuthType.RESOURCE }), scope && { scope } || {}), { username,
258
+ password })
259
+ }), { headers: HEADER_APPLICATION }).pipe(catchError(err => {
260
+ this.token = err;
261
+ return throwError(() => err);
262
+ }), tap(params => {
263
+ this.token = Object.assign(Object.assign({}, params), { type: OAuthType.RESOURCE });
264
+ })));
265
+ }
266
+ toAuthorizationUrl(parameters) {
296
267
  return __awaiter(this, void 0, void 0, function* () {
297
268
  const { config } = this.authConfig;
298
269
  let authorizationUrl = `${config.authorizePath}`;
299
270
  authorizationUrl += config.authorizePath.includes('?') && '&' || '?';
300
271
  authorizationUrl += `client_id=${config.clientId}`;
301
272
  authorizationUrl += `&redirect_uri=${encodeURIComponent(parameters.redirectUri)}`;
302
- authorizationUrl += `&response_type=${responseType}`;
273
+ authorizationUrl += `&response_type=${parameters.responseType}`;
303
274
  authorizationUrl += `&scope=${encodeURIComponent(config.scope || '')}`;
304
275
  authorizationUrl += `&state=${encodeURIComponent(parameters.state || '')}`;
305
- return `${authorizationUrl}${this.generateNonce(config)}${yield this.generateCodeChallenge(config)}`;
276
+ return this.location.replace(`${authorizationUrl}${this.generateNonce(config)}${yield this.generateCodeChallenge(config)}`);
306
277
  });
307
278
  }
308
279
  generateCodeChallenge(config) {
@@ -335,52 +306,11 @@ class OAuthService {
335
306
  }
336
307
  return parameters['access_token'] || parameters['code'];
337
308
  }
338
- set token(token) {
339
- this._token = token;
340
- const { storageKey } = this.authConfig;
341
- if (token) {
342
- // @ts-ignore
343
- this.authConfig.storage[storageKey] = JSON.stringify(this.token);
344
- clearTimeout(this.timer);
345
- if (this.token && this.token.expires_in) {
346
- this.zone.runOutsideAngular(() => {
347
- var _a;
348
- this.timer = setTimeout(() => {
349
- this.zone.run(() => {
350
- this.refreshToken();
351
- });
352
- }, Number((_a = this.token) === null || _a === void 0 ? void 0 : _a.expires_in) * 1000);
353
- });
354
- }
355
- }
356
- else {
357
- // @ts-ignore
358
- delete this.authConfig.storage[storageKey];
359
- }
360
- }
361
- get token() {
362
- return this._token;
363
- }
364
- refreshToken() {
365
- const { tokenPath, clientId, clientSecret, scope } = this.authConfig.config;
366
- const { refresh_token } = this.token;
367
- if (tokenPath && refresh_token) {
368
- this.http.post(tokenPath, new HttpParams({
369
- fromObject: Object.assign(Object.assign(Object.assign({ client_id: clientId }, clientSecret && { client_secret: clientSecret } || {}), { grant_type: 'refresh_token', refresh_token }), scope && { scope } || {})
370
- }), { headers: REQUEST_HEADER }).pipe(catchError(() => {
371
- this.logout();
372
- return EMPTY;
373
- })).subscribe(params => {
374
- this.token = Object.assign(Object.assign({}, this.token), params);
375
- this.status = OAuthStatus.AUTHORIZED;
376
- });
377
- }
378
- }
379
309
  getCleanedUnSearchParameters() {
380
310
  const { search } = this.location;
381
- let searchString = search.substr(1);
311
+ let searchString = search && search.substring(1) || '';
382
312
  const hashKeys = ['code', 'state', 'error', 'error_description', 'session_state', 'scope', 'authuser', 'prompt'];
383
- hashKeys.forEach((hashKey) => {
313
+ hashKeys.forEach(hashKey => {
384
314
  const re = new RegExp('&' + hashKey + '(=[^&]*)?|^' + hashKey + '(=[^&]*)?&?');
385
315
  searchString = searchString.replace(re, '');
386
316
  });
@@ -388,64 +318,71 @@ class OAuthService {
388
318
  }
389
319
  cleanLocationHash() {
390
320
  const { hash } = this.location;
391
- let curHash = hash.substr(1);
392
- const hashKeys = ['access_token', 'token_type', 'expires_in', 'scope', 'state', 'error', 'error_description', 'session_state', 'nonce'];
393
- hashKeys.forEach((hashKey) => {
321
+ let curHash = hash && hash.substring(1) || '';
322
+ const hashKeys = [
323
+ 'access_token',
324
+ 'token_type',
325
+ 'expires_in',
326
+ 'scope',
327
+ 'state',
328
+ 'error',
329
+ 'error_description',
330
+ 'session_state',
331
+ 'nonce',
332
+ 'id_token',
333
+ 'code'
334
+ ];
335
+ hashKeys.forEach(hashKey => {
394
336
  const re = new RegExp('&' + hashKey + '(=[^&]*)?|^' + hashKey + '(=[^&]*)?&?');
395
337
  curHash = curHash.replace(re, '');
396
338
  });
397
339
  this.location.hash = curHash;
398
340
  }
399
341
  emitState(parameters) {
400
- const { state } = parameters;
401
- if (state) {
402
- this.state$.next(state);
403
- }
342
+ const { state } = parameters || {};
343
+ state && this.state$.next(state);
404
344
  }
405
345
  }
406
- OAuthService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.5", ngImport: i0, type: OAuthService, deps: [{ token: i1.HttpClient }, { token: i0.NgZone }, { token: OAuthConfig }, { token: LOCATION }, { token: i2.Location }], target: i0.ɵɵFactoryTarget.Injectable });
407
- OAuthService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.5", ngImport: i0, type: OAuthService });
408
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.5", ngImport: i0, type: OAuthService, decorators: [{
346
+ OAuthService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.3", ngImport: i0, type: OAuthService, deps: [{ token: OAuthConfig }, { token: TokenService }, { token: i3.HttpClient }, { token: LOCATION }, { token: i2.Location }], target: i0.ɵɵFactoryTarget.Injectable });
347
+ OAuthService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.3", ngImport: i0, type: OAuthService });
348
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.3", ngImport: i0, type: OAuthService, decorators: [{
409
349
  type: Injectable
410
350
  }], ctorParameters: function () {
411
- return [{ type: i1.HttpClient }, { type: i0.NgZone }, { type: OAuthConfig }, { type: Location, decorators: [{
351
+ return [{ type: OAuthConfig }, { type: TokenService }, { type: i3.HttpClient }, { type: Location, decorators: [{
412
352
  type: Inject,
413
353
  args: [LOCATION]
414
354
  }] }, { type: i2.Location }];
415
355
  } });
416
356
 
417
357
  class OAuthInterceptor {
418
- constructor(oauthService) {
419
- this.oauthService = oauthService;
358
+ constructor(tokenService, authConfig) {
359
+ this.tokenService = tokenService;
360
+ this.authConfig = authConfig;
420
361
  }
421
362
  intercept(req, next) {
422
- if (this.oauthService) {
423
- if (!this.isPathExcepted(req)) {
424
- const { token } = this.oauthService;
425
- if (token && token.access_token) {
426
- req = req.clone({
427
- setHeaders: {
428
- Authorization: `${token.token_type} ${token.access_token}`
429
- }
430
- });
431
- }
363
+ return this.tokenService.token$.pipe(take(1), map(token => {
364
+ if ((token === null || token === void 0 ? void 0 : token.access_token) && !this.isPathExcepted(req)) {
365
+ req = req.clone({
366
+ setHeaders: {
367
+ Authorization: `${token.token_type} ${token.access_token}`
368
+ }
369
+ });
432
370
  }
433
- return next.handle(req).pipe(catchError((err) => {
434
- if (err.status === 401 && !this.isPathExcepted(req)) {
435
- this.oauthService.token = null;
436
- this.oauthService.status = OAuthStatus.DENIED;
437
- }
438
- return throwError(err);
439
- }));
440
- }
441
- else {
442
- return next.handle(req);
443
- }
371
+ return req;
372
+ }), switchMap(req => next.handle(req)), catchError((err) => {
373
+ if (err.status === 401 && !this.isPathExcepted(req)) {
374
+ this.tokenService.token = {
375
+ error: `${err.status}`,
376
+ error_description: err.message
377
+ };
378
+ }
379
+ return throwError(() => err);
380
+ }));
444
381
  }
445
382
  isPathExcepted(req) {
446
- const { ignorePaths } = this.oauthService;
383
+ const { ignorePaths } = this.authConfig || {};
447
384
  if (ignorePaths) {
448
- for (const ignorePath of this.oauthService.ignorePaths) {
385
+ for (const ignorePath of ignorePaths) {
449
386
  try {
450
387
  if (req.url.match(ignorePath)) {
451
388
  return true;
@@ -458,39 +395,41 @@ class OAuthInterceptor {
458
395
  return false;
459
396
  }
460
397
  }
461
- OAuthInterceptor.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.5", ngImport: i0, type: OAuthInterceptor, deps: [{ token: OAuthService }], target: i0.ɵɵFactoryTarget.Injectable });
462
- OAuthInterceptor.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.5", ngImport: i0, type: OAuthInterceptor });
463
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.5", ngImport: i0, type: OAuthInterceptor, decorators: [{
398
+ OAuthInterceptor.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.3", ngImport: i0, type: OAuthInterceptor, deps: [{ token: TokenService }, { token: OAuthConfig }], target: i0.ɵɵFactoryTarget.Injectable });
399
+ OAuthInterceptor.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.3", ngImport: i0, type: OAuthInterceptor });
400
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.3", ngImport: i0, type: OAuthInterceptor, decorators: [{
464
401
  type: Injectable
465
- }], ctorParameters: function () { return [{ type: OAuthService }]; } });
402
+ }], ctorParameters: function () { return [{ type: TokenService }, { type: OAuthConfig }]; } });
466
403
 
404
+ var _OAuthLoginComponent_subscription, _OAuthLoginComponent_redirectUri, _OAuthLoginComponent_responseType, _OAuthLoginComponent_i18n;
467
405
  class OAuthLoginComponent {
468
406
  constructor(oauthService, locationService, location) {
469
407
  this.oauthService = oauthService;
470
408
  this.locationService = locationService;
471
409
  this.location = location;
472
- this.subscription = new Subscription();
473
- this._i18n = {
410
+ _OAuthLoginComponent_subscription.set(this, new Subscription());
411
+ _OAuthLoginComponent_redirectUri.set(this, void 0);
412
+ _OAuthLoginComponent_responseType.set(this, void 0);
413
+ _OAuthLoginComponent_i18n.set(this, {
474
414
  username: 'Username',
475
415
  password: 'Password',
476
416
  submit: 'Sign in',
477
417
  notAuthorized: 'Sign in',
478
418
  authorized: 'Welcome',
479
419
  denied: 'Access Denied. Try again!'
480
- };
420
+ });
421
+ this.type = OAuthType.RESOURCE;
481
422
  this.useLogoutUrl = false;
482
423
  this.state = '';
483
- this.stateChange = new EventEmitter();
424
+ this.stateChange = this.oauthService.state$.asObservable();
484
425
  this.username = '';
485
426
  this.password = '';
486
427
  this.OAuthStatus = OAuthStatus;
487
428
  this.OAuthType = OAuthType;
488
429
  this.collapse = false;
489
- this.type = this.oauthService.type;
490
- this.state$ = this.oauthService.state$.pipe(tap(s => this.stateChange.emit(s)));
491
430
  this.status$ = this.oauthService.status$.pipe(tap(s => {
492
431
  if (s === OAuthStatus.AUTHORIZED && this.profileName$) {
493
- this.subscription.add(this.profileName$.pipe(take(1)).subscribe(n => this.profileName = n));
432
+ __classPrivateFieldGet(this, _OAuthLoginComponent_subscription, "f").add(this.profileName$.pipe(take(1)).subscribe(n => this.profileName = n));
494
433
  }
495
434
  else {
496
435
  const { token } = this.oauthService;
@@ -502,30 +441,36 @@ class OAuthLoginComponent {
502
441
  this.logoutFunction = () => this.logout();
503
442
  }
504
443
  get i18n() {
505
- return this._i18n;
444
+ return __classPrivateFieldGet(this, _OAuthLoginComponent_i18n, "f");
506
445
  }
507
446
  set i18n(i18n) {
508
- this._i18n = Object.assign(Object.assign({}, this._i18n), i18n);
447
+ __classPrivateFieldSet(this, _OAuthLoginComponent_i18n, Object.assign(Object.assign({}, __classPrivateFieldGet(this, _OAuthLoginComponent_i18n, "f")), i18n), "f");
448
+ }
449
+ get redirectUri() {
450
+ return __classPrivateFieldGet(this, _OAuthLoginComponent_redirectUri, "f") || `${this.location.origin}${this.locationService.path(true) || '/'}`;
509
451
  }
510
452
  set redirectUri(redirectUri) {
511
453
  if (redirectUri) {
512
- this._redirectUri = redirectUri;
454
+ __classPrivateFieldSet(this, _OAuthLoginComponent_redirectUri, redirectUri, "f");
513
455
  }
514
456
  }
515
- get redirectUri() {
516
- return this._redirectUri || `${this.location.origin}${this.locationService.path(true) || '/'}`;
457
+ set responseType(responseType) {
458
+ if (this.responseType) {
459
+ __classPrivateFieldSet(this, _OAuthLoginComponent_responseType, responseType, "f");
460
+ }
461
+ }
462
+ get responseType() {
463
+ return __classPrivateFieldGet(this, _OAuthLoginComponent_responseType, "f") || this.type;
517
464
  }
518
465
  ngOnDestroy() {
519
- this.subscription.unsubscribe();
466
+ __classPrivateFieldGet(this, _OAuthLoginComponent_subscription, "f").unsubscribe();
520
467
  }
521
468
  logout() {
522
469
  this.oauthService.logout(this.useLogoutUrl);
523
470
  }
524
471
  login(parameters) {
525
- return __awaiter(this, void 0, void 0, function* () {
526
- yield this.oauthService.login(parameters);
527
- this.collapse = false;
528
- });
472
+ this.collapse = false;
473
+ return this.oauthService.login(parameters);
529
474
  }
530
475
  toggleCollapse() {
531
476
  this.collapse = !this.collapse;
@@ -534,20 +479,25 @@ class OAuthLoginComponent {
534
479
  this.collapse = false;
535
480
  }
536
481
  }
537
- OAuthLoginComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.5", ngImport: i0, type: OAuthLoginComponent, deps: [{ token: OAuthService }, { token: i2.Location }, { token: LOCATION }], target: i0.ɵɵFactoryTarget.Component });
538
- OAuthLoginComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.5", type: OAuthLoginComponent, selector: "oauth-login", inputs: { i18n: "i18n", redirectUri: "redirectUri", 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=\"state$ | async\"></ng-container>\r\n<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 p-3 {{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\" #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\" class=\"oauth\"\r\n (click)=\"status === OAuthStatus.AUTHORIZED ? logout() : login({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 *ngIf=\"status === OAuthStatus.NOT_AUTHORIZED\" class=\"not-authorized\">{{i18n.notAuthorized}}</span>\r\n <span *ngIf=\"status === OAuthStatus.AUTHORIZED\" class=\"authorized\">\r\n <span class=\"welcome\">{{i18n.authorized}}&nbsp;</span>\r\n <strong class=\"profile-name\" [innerHTML]=\"profileName\"></strong>\r\n </span>\r\n <span *ngIf=\"status === OAuthStatus.DENIED\" class=\"denied\">{{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.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i3.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.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i3.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 });
539
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.5", ngImport: i0, type: OAuthLoginComponent, decorators: [{
482
+ _OAuthLoginComponent_subscription = new WeakMap(), _OAuthLoginComponent_redirectUri = new WeakMap(), _OAuthLoginComponent_responseType = new WeakMap(), _OAuthLoginComponent_i18n = new WeakMap();
483
+ OAuthLoginComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.3", ngImport: i0, type: OAuthLoginComponent, deps: [{ token: OAuthService }, { token: i2.Location }, { token: LOCATION }], target: i0.ɵɵFactoryTarget.Component });
484
+ OAuthLoginComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.3", 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 });
485
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.3", ngImport: i0, type: OAuthLoginComponent, decorators: [{
540
486
  type: Component,
541
- args: [{ selector: 'oauth-login', encapsulation: ViewEncapsulation.None, template: "<ng-container *ngIf=\"state$ | async\"></ng-container>\r\n<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 p-3 {{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\" #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\" class=\"oauth\"\r\n (click)=\"status === OAuthStatus.AUTHORIZED ? logout() : login({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 *ngIf=\"status === OAuthStatus.NOT_AUTHORIZED\" class=\"not-authorized\">{{i18n.notAuthorized}}</span>\r\n <span *ngIf=\"status === OAuthStatus.AUTHORIZED\" class=\"authorized\">\r\n <span class=\"welcome\">{{i18n.authorized}}&nbsp;</span>\r\n <strong class=\"profile-name\" [innerHTML]=\"profileName\"></strong>\r\n </span>\r\n <span *ngIf=\"status === OAuthStatus.DENIED\" class=\"denied\">{{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"] }]
487
+ 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"] }]
542
488
  }], ctorParameters: function () {
543
489
  return [{ type: OAuthService }, { type: i2.Location }, { type: Location, decorators: [{
544
490
  type: Inject,
545
491
  args: [LOCATION]
546
492
  }] }];
547
- }, propDecorators: { i18n: [{
493
+ }, propDecorators: { type: [{
494
+ type: Input
495
+ }], i18n: [{
548
496
  type: Input
549
497
  }], redirectUri: [{
550
498
  type: Input
499
+ }], responseType: [{
500
+ type: Input
551
501
  }], useLogoutUrl: [{
552
502
  type: Input
553
503
  }], state: [{
@@ -571,10 +521,10 @@ const mockLocation = (serverHost, serverPath) => {
571
521
  href, origin, protocol, host, hostname, port, pathname, search, hash,
572
522
  reload() {
573
523
  },
574
- assign(u) {
524
+ assign(_) {
575
525
  },
576
526
  ancestorOrigins: {},
577
- replace(u) {
527
+ replace(_) {
578
528
  }
579
529
  };
580
530
  };
@@ -611,6 +561,14 @@ const StorageService = {
611
561
  },
612
562
  deps: [PLATFORM_ID]
613
563
  };
564
+ const OAuthHttpClient = {
565
+ provide: OAUTH_HTTP_CLIENT,
566
+ useFactory(httpBackend) {
567
+ // avoid http interceptors
568
+ return new HttpClient(httpBackend);
569
+ },
570
+ deps: [HttpBackend]
571
+ };
614
572
  const OAuthInterceptorService = {
615
573
  provide: HTTP_INTERCEPTORS,
616
574
  useClass: OAuthInterceptor,
@@ -630,23 +588,25 @@ class OAuthModule {
630
588
  providers: [
631
589
  LocationService,
632
590
  StorageService,
633
- OAuthService,
634
- OAuthInterceptorService,
591
+ OAuthHttpClient,
635
592
  provideOAuthConfigFactory((storage) => (Object.assign(Object.assign({}, defaultConfig(storage)), config)), [STORAGE]),
593
+ TokenService,
594
+ OAuthInterceptorService,
595
+ OAuthService,
636
596
  ]
637
597
  };
638
598
  }
639
599
  }
640
- OAuthModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.5", ngImport: i0, type: OAuthModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
641
- OAuthModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.0.5", ngImport: i0, type: OAuthModule, declarations: [OAuthLoginComponent], imports: [CommonModule,
600
+ OAuthModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.3", ngImport: i0, type: OAuthModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
601
+ OAuthModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.1.3", ngImport: i0, type: OAuthModule, declarations: [OAuthLoginComponent], imports: [CommonModule,
642
602
  FormsModule,
643
603
  HttpClientModule,
644
604
  RouterModule], exports: [OAuthLoginComponent] });
645
- OAuthModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.0.5", ngImport: i0, type: OAuthModule, imports: [CommonModule,
605
+ OAuthModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.1.3", ngImport: i0, type: OAuthModule, imports: [CommonModule,
646
606
  FormsModule,
647
607
  HttpClientModule,
648
608
  RouterModule] });
649
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.5", ngImport: i0, type: OAuthModule, decorators: [{
609
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.3", ngImport: i0, type: OAuthModule, decorators: [{
650
610
  type: NgModule,
651
611
  args: [{
652
612
  imports: [
@@ -668,5 +628,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.5", ngImpor
668
628
  * Generated bundle index. Do not edit.
669
629
  */
670
630
 
671
- export { LOCATION, OAUTH_CONFIG, OAUTH_TOKEN, OAuthConfig, OAuthInterceptor, OAuthLoginComponent, OAuthModule, OAuthService, OAuthStatus, OAuthType, SERVER_HOST, SERVER_PATH, STORAGE, provideOAuthConfig, provideOAuthConfigFactory };
631
+ export { HEADER_APPLICATION, LOCATION, OAUTH_CONFIG, OAUTH_HTTP_CLIENT, OAUTH_TOKEN, OAuthConfig, OAuthInterceptor, OAuthLoginComponent, OAuthModule, OAuthService, OAuthStatus, OAuthType, SERVER_HOST, SERVER_PATH, STORAGE, provideOAuthConfig, provideOAuthConfigFactory };
672
632
  //# sourceMappingURL=ngx-oauth.mjs.map