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