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