ngx-oauth 3.0.2 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -24
- package/esm2020/lib/components/login/oauth-login.component.mjs +30 -22
- package/esm2020/lib/models/index.mjs +3 -1
- package/esm2020/lib/oauth.module.mjs +8 -6
- package/esm2020/lib/services/oauth.interceptor.mjs +29 -32
- package/esm2020/lib/services/oauth.service.mjs +102 -224
- package/esm2020/lib/services/token.service.mjs +80 -0
- package/fesm2015/ngx-oauth.mjs +205 -277
- package/fesm2015/ngx-oauth.mjs.map +1 -1
- package/fesm2020/ngx-oauth.mjs +232 -277
- package/fesm2020/ngx-oauth.mjs.map +1 -1
- package/lib/components/login/oauth-login.component.d.ts +8 -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/fesm2015/ngx-oauth.mjs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { InjectionToken, inject, Injectable, Inject,
|
|
3
|
-
import
|
|
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 {
|
|
7
|
-
import {
|
|
8
|
-
import
|
|
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,6 +17,7 @@ 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
23
|
OAuthConfig.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.5", ngImport: i0, type: OAuthConfig, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
@@ -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.0.5", 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.0.5", ngImport: i0, type: TokenService });
|
|
112
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.5", 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,86 @@ const parseOauthUri = (hash) => {
|
|
|
75
134
|
while ((m = regex.exec(hash)) !== null) {
|
|
76
135
|
params[decodeURIComponent(m[1])] = decodeURIComponent(m[2]);
|
|
77
136
|
}
|
|
78
|
-
|
|
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(
|
|
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.
|
|
95
|
-
this.
|
|
96
|
-
const {
|
|
97
|
-
|
|
98
|
-
|
|
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);
|
|
129
153
|
if (isImplicitRedirect) {
|
|
130
|
-
const parameters = parseOauthUri(hash.
|
|
131
|
-
this.token = parameters;
|
|
132
|
-
this.
|
|
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.
|
|
136
|
-
if (!this.checkResponse(
|
|
159
|
+
const parameters = parseOauthUri(search.substring(1));
|
|
160
|
+
if (!this.checkResponse(this.token, parameters)) {
|
|
137
161
|
this.token = parameters;
|
|
138
|
-
this.status = OAuthStatus.DENIED;
|
|
139
162
|
}
|
|
140
163
|
else {
|
|
141
164
|
const newParametersString = this.getCleanedUnSearchParameters();
|
|
142
165
|
const { clientId, clientSecret, tokenPath, scope } = config;
|
|
143
|
-
const codeVerifier =
|
|
166
|
+
const { codeVerifier } = this.token || {}; //should be set by autorizationUrl construction
|
|
144
167
|
this.http.post(tokenPath, new HttpParams({
|
|
145
168
|
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:
|
|
147
|
-
this.token =
|
|
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;
|
|
169
|
+
}), { headers: HEADER_APPLICATION }).pipe().subscribe(token => {
|
|
170
|
+
this.token = Object.assign(Object.assign({}, token), { type: OAuthType.AUTHORIZATION_CODE });
|
|
154
171
|
this.locationService.replaceState(`${pathname}${newParametersString}`);
|
|
155
172
|
});
|
|
156
173
|
}
|
|
157
174
|
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
175
|
+
}), switchMap$1(() => this.tokenService.token$), shareReplay(1));
|
|
176
|
+
this.status$ = this.token$.pipe(map(token => token.access_token && OAuthStatus.AUTHORIZED || token.error && OAuthStatus.DENIED || OAuthStatus.NOT_AUTHORIZED), shareReplay(1));
|
|
177
|
+
this.userInfo$ = this.status$.pipe(filter(s => s === OAuthStatus.AUTHORIZED), map(() => {
|
|
178
|
+
const { config } = this.authConfig;
|
|
179
|
+
return config.userPath;
|
|
180
|
+
}), filter(Boolean), switchMap$1(path => this.http.get(path)), shareReplay(1));
|
|
181
|
+
this.type$ = this.tokenService.type$;
|
|
182
|
+
this.ignorePaths = this.authConfig.ignorePaths || [];
|
|
183
|
+
}
|
|
184
|
+
get token() {
|
|
185
|
+
return this.tokenService.token;
|
|
186
|
+
}
|
|
187
|
+
set token(token) {
|
|
188
|
+
this.tokenService.token = token;
|
|
189
|
+
}
|
|
190
|
+
get config() {
|
|
191
|
+
return this.authConfig.config;
|
|
192
|
+
}
|
|
193
|
+
set config(config) {
|
|
194
|
+
if (config) {
|
|
195
|
+
this.authConfig.config = Object.assign(Object.assign({}, this.authConfig.config), config);
|
|
196
|
+
}
|
|
177
197
|
}
|
|
178
198
|
login(parameters) {
|
|
179
199
|
return __awaiter(this, void 0, void 0, function* () {
|
|
180
|
-
if (
|
|
200
|
+
if (!!parameters && parameters.password) {
|
|
181
201
|
yield this.resourceLogin(parameters);
|
|
182
202
|
}
|
|
183
|
-
else if (
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
yield this.
|
|
203
|
+
else if (!!parameters
|
|
204
|
+
&& parameters.redirectUri
|
|
205
|
+
&& (parameters.responseType === OAuthType.IMPLICIT
|
|
206
|
+
|| parameters.responseType === OAuthType.AUTHORIZATION_CODE)) {
|
|
207
|
+
yield this.toAuthorizationUrl(parameters);
|
|
188
208
|
}
|
|
189
|
-
else
|
|
209
|
+
else {
|
|
190
210
|
yield this.clientCredentialLogin();
|
|
191
211
|
}
|
|
192
212
|
});
|
|
193
213
|
}
|
|
194
214
|
logout(useLogoutUrl) {
|
|
195
215
|
this.revoke();
|
|
196
|
-
this.token =
|
|
197
|
-
this.status = OAuthStatus.NOT_AUTHORIZED;
|
|
216
|
+
this.token = {};
|
|
198
217
|
const { logoutPath, logoutRedirectUri } = this.authConfig.config;
|
|
199
218
|
if (useLogoutUrl && logoutPath) {
|
|
200
219
|
const { origin, pathname } = this.location;
|
|
@@ -205,7 +224,7 @@ class OAuthService {
|
|
|
205
224
|
revoke() {
|
|
206
225
|
const { revokePath, clientId, clientSecret } = this.authConfig.config;
|
|
207
226
|
if (revokePath) {
|
|
208
|
-
const { access_token, refresh_token } = this.token;
|
|
227
|
+
const { access_token, refresh_token } = this.token || {};
|
|
209
228
|
const toRevoke = [];
|
|
210
229
|
if (access_token) {
|
|
211
230
|
toRevoke.push(Object.assign(Object.assign(Object.assign({}, clientId && { client_id: clientId } || {}), clientSecret && { client_secret: clientSecret } || {}), { token: access_token, token_type_hint: 'access_token' }));
|
|
@@ -214,95 +233,44 @@ class OAuthService {
|
|
|
214
233
|
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
234
|
}
|
|
216
235
|
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);
|
|
236
|
+
switchMap$1(o => this.http.post(revokePath, new HttpParams({ fromObject: o })))).subscribe(noop);
|
|
231
237
|
}
|
|
232
238
|
}
|
|
233
|
-
get type() {
|
|
234
|
-
return this.authConfig.type;
|
|
235
|
-
}
|
|
236
|
-
get ignorePaths() {
|
|
237
|
-
return this.authConfig.ignorePaths || [];
|
|
238
|
-
}
|
|
239
239
|
clientCredentialLogin() {
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
this.token = params;
|
|
250
|
-
this.status = OAuthStatus.AUTHORIZED;
|
|
251
|
-
})));
|
|
252
|
-
});
|
|
240
|
+
const { clientId, clientSecret, tokenPath, scope } = this.authConfig.config;
|
|
241
|
+
return firstValueFrom(this.http.post(tokenPath, new HttpParams({
|
|
242
|
+
fromObject: Object.assign({ client_id: clientId, client_secret: clientSecret, grant_type: OAuthType.CLIENT_CREDENTIAL }, scope ? { scope } : {})
|
|
243
|
+
}), { headers: HEADER_APPLICATION }).pipe(catchError((err) => {
|
|
244
|
+
this.token = err;
|
|
245
|
+
return throwError(() => err);
|
|
246
|
+
}), tap(params => {
|
|
247
|
+
this.token = Object.assign(Object.assign({}, params), { type: OAuthType.CLIENT_CREDENTIAL });
|
|
248
|
+
})));
|
|
253
249
|
}
|
|
254
250
|
resourceLogin(parameters) {
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
})));
|
|
269
|
-
});
|
|
270
|
-
}
|
|
271
|
-
implicitLogin(parameters) {
|
|
272
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
273
|
-
const authUrl = yield this.toAuthorizationUrl(parameters, OAuthType.IMPLICIT);
|
|
274
|
-
this.location.replace(authUrl);
|
|
275
|
-
});
|
|
276
|
-
}
|
|
277
|
-
authorizationCodeLogin(parameters) {
|
|
278
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
279
|
-
const authUrl = yield this.toAuthorizationUrl(parameters, OAuthType.AUTHORIZATION_CODE);
|
|
280
|
-
this.location.replace(authUrl);
|
|
281
|
-
});
|
|
282
|
-
}
|
|
283
|
-
isClientCredentialType() {
|
|
284
|
-
return this.authConfig.type === OAuthType.CLIENT_CREDENTIAL;
|
|
285
|
-
}
|
|
286
|
-
isResourceType(parameters) {
|
|
287
|
-
return this.authConfig.type === OAuthType.RESOURCE && !!(parameters === null || parameters === void 0 ? void 0 : parameters.password);
|
|
288
|
-
}
|
|
289
|
-
isImplicitType(parameters) {
|
|
290
|
-
return this.authConfig.type === OAuthType.IMPLICIT && !!(parameters === null || parameters === void 0 ? void 0 : parameters.redirectUri);
|
|
291
|
-
}
|
|
292
|
-
isAuthorizationCodeType(parameters) {
|
|
293
|
-
return this.authConfig.type === OAuthType.AUTHORIZATION_CODE && !!(parameters === null || parameters === void 0 ? void 0 : parameters.redirectUri);
|
|
294
|
-
}
|
|
295
|
-
toAuthorizationUrl(parameters, responseType) {
|
|
251
|
+
const { clientId, clientSecret, tokenPath, scope } = this.authConfig.config;
|
|
252
|
+
const { username, password } = parameters;
|
|
253
|
+
return firstValueFrom(this.http.post(tokenPath, new HttpParams({
|
|
254
|
+
fromObject: Object.assign(Object.assign(Object.assign(Object.assign({ client_id: clientId }, clientSecret && { client_secret: clientSecret } || {}), { grant_type: OAuthType.RESOURCE }), scope && { scope } || {}), { username,
|
|
255
|
+
password })
|
|
256
|
+
}), { headers: HEADER_APPLICATION }).pipe(catchError(err => {
|
|
257
|
+
this.token = err;
|
|
258
|
+
return throwError(() => err);
|
|
259
|
+
}), tap(params => {
|
|
260
|
+
this.token = Object.assign(Object.assign({}, params), { type: OAuthType.RESOURCE });
|
|
261
|
+
})));
|
|
262
|
+
}
|
|
263
|
+
toAuthorizationUrl(parameters) {
|
|
296
264
|
return __awaiter(this, void 0, void 0, function* () {
|
|
297
265
|
const { config } = this.authConfig;
|
|
298
266
|
let authorizationUrl = `${config.authorizePath}`;
|
|
299
267
|
authorizationUrl += config.authorizePath.includes('?') && '&' || '?';
|
|
300
268
|
authorizationUrl += `client_id=${config.clientId}`;
|
|
301
269
|
authorizationUrl += `&redirect_uri=${encodeURIComponent(parameters.redirectUri)}`;
|
|
302
|
-
authorizationUrl += `&response_type=${responseType}`;
|
|
270
|
+
authorizationUrl += `&response_type=${parameters.responseType}`;
|
|
303
271
|
authorizationUrl += `&scope=${encodeURIComponent(config.scope || '')}`;
|
|
304
272
|
authorizationUrl += `&state=${encodeURIComponent(parameters.state || '')}`;
|
|
305
|
-
return `${authorizationUrl}${this.generateNonce(config)}${yield this.generateCodeChallenge(config)}
|
|
273
|
+
return this.location.replace(`${authorizationUrl}${this.generateNonce(config)}${yield this.generateCodeChallenge(config)}`);
|
|
306
274
|
});
|
|
307
275
|
}
|
|
308
276
|
generateCodeChallenge(config) {
|
|
@@ -335,52 +303,11 @@ class OAuthService {
|
|
|
335
303
|
}
|
|
336
304
|
return parameters['access_token'] || parameters['code'];
|
|
337
305
|
}
|
|
338
|
-
set token(token) {
|
|
339
|
-
this._token = token;
|
|
340
|
-
const { storageKey } = this.authConfig;
|
|
341
|
-
if (token) {
|
|
342
|
-
// @ts-ignore
|
|
343
|
-
this.authConfig.storage[storageKey] = JSON.stringify(this.token);
|
|
344
|
-
clearTimeout(this.timer);
|
|
345
|
-
if (this.token && this.token.expires_in) {
|
|
346
|
-
this.zone.runOutsideAngular(() => {
|
|
347
|
-
var _a;
|
|
348
|
-
this.timer = setTimeout(() => {
|
|
349
|
-
this.zone.run(() => {
|
|
350
|
-
this.refreshToken();
|
|
351
|
-
});
|
|
352
|
-
}, Number((_a = this.token) === null || _a === void 0 ? void 0 : _a.expires_in) * 1000);
|
|
353
|
-
});
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
else {
|
|
357
|
-
// @ts-ignore
|
|
358
|
-
delete this.authConfig.storage[storageKey];
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
get token() {
|
|
362
|
-
return this._token;
|
|
363
|
-
}
|
|
364
|
-
refreshToken() {
|
|
365
|
-
const { tokenPath, clientId, clientSecret, scope } = this.authConfig.config;
|
|
366
|
-
const { refresh_token } = this.token;
|
|
367
|
-
if (tokenPath && refresh_token) {
|
|
368
|
-
this.http.post(tokenPath, new HttpParams({
|
|
369
|
-
fromObject: Object.assign(Object.assign(Object.assign({ client_id: clientId }, clientSecret && { client_secret: clientSecret } || {}), { grant_type: 'refresh_token', refresh_token }), scope && { scope } || {})
|
|
370
|
-
}), { headers: REQUEST_HEADER }).pipe(catchError(() => {
|
|
371
|
-
this.logout();
|
|
372
|
-
return EMPTY;
|
|
373
|
-
})).subscribe(params => {
|
|
374
|
-
this.token = Object.assign(Object.assign({}, this.token), params);
|
|
375
|
-
this.status = OAuthStatus.AUTHORIZED;
|
|
376
|
-
});
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
306
|
getCleanedUnSearchParameters() {
|
|
380
307
|
const { search } = this.location;
|
|
381
|
-
let searchString = search.
|
|
308
|
+
let searchString = search && search.substring(1) || '';
|
|
382
309
|
const hashKeys = ['code', 'state', 'error', 'error_description', 'session_state', 'scope', 'authuser', 'prompt'];
|
|
383
|
-
hashKeys.forEach(
|
|
310
|
+
hashKeys.forEach(hashKey => {
|
|
384
311
|
const re = new RegExp('&' + hashKey + '(=[^&]*)?|^' + hashKey + '(=[^&]*)?&?');
|
|
385
312
|
searchString = searchString.replace(re, '');
|
|
386
313
|
});
|
|
@@ -388,64 +315,59 @@ class OAuthService {
|
|
|
388
315
|
}
|
|
389
316
|
cleanLocationHash() {
|
|
390
317
|
const { hash } = this.location;
|
|
391
|
-
let curHash = hash.
|
|
318
|
+
let curHash = hash && hash.substring(1) || '';
|
|
392
319
|
const hashKeys = ['access_token', 'token_type', 'expires_in', 'scope', 'state', 'error', 'error_description', 'session_state', 'nonce'];
|
|
393
|
-
hashKeys.forEach(
|
|
320
|
+
hashKeys.forEach(hashKey => {
|
|
394
321
|
const re = new RegExp('&' + hashKey + '(=[^&]*)?|^' + hashKey + '(=[^&]*)?&?');
|
|
395
322
|
curHash = curHash.replace(re, '');
|
|
396
323
|
});
|
|
397
324
|
this.location.hash = curHash;
|
|
398
325
|
}
|
|
399
326
|
emitState(parameters) {
|
|
400
|
-
const { state } = parameters;
|
|
401
|
-
|
|
402
|
-
this.state$.next(state);
|
|
403
|
-
}
|
|
327
|
+
const { state } = parameters || {};
|
|
328
|
+
state && this.state$.next(state);
|
|
404
329
|
}
|
|
405
330
|
}
|
|
406
|
-
OAuthService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.5", ngImport: i0, type: OAuthService, deps: [{ token:
|
|
331
|
+
OAuthService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.5", ngImport: i0, type: OAuthService, deps: [{ token: OAuthConfig }, { token: TokenService }, { token: i2.HttpClient }, { token: LOCATION }, { token: i2$1.Location }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
407
332
|
OAuthService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.5", ngImport: i0, type: OAuthService });
|
|
408
333
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.5", ngImport: i0, type: OAuthService, decorators: [{
|
|
409
334
|
type: Injectable
|
|
410
335
|
}], ctorParameters: function () {
|
|
411
|
-
return [{ type:
|
|
336
|
+
return [{ type: OAuthConfig }, { type: TokenService }, { type: i2.HttpClient }, { type: Location, decorators: [{
|
|
412
337
|
type: Inject,
|
|
413
338
|
args: [LOCATION]
|
|
414
|
-
}] }, { type: i2.Location }];
|
|
339
|
+
}] }, { type: i2$1.Location }];
|
|
415
340
|
} });
|
|
416
341
|
|
|
417
342
|
class OAuthInterceptor {
|
|
418
|
-
constructor(
|
|
419
|
-
this.
|
|
343
|
+
constructor(tokenService, authConfig) {
|
|
344
|
+
this.tokenService = tokenService;
|
|
345
|
+
this.authConfig = authConfig;
|
|
420
346
|
}
|
|
421
347
|
intercept(req, next) {
|
|
422
|
-
|
|
423
|
-
if (!this.isPathExcepted(req)) {
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
}
|
|
430
|
-
});
|
|
431
|
-
}
|
|
348
|
+
return this.tokenService.token$.pipe(take(1), map(token => {
|
|
349
|
+
if ((token === null || token === void 0 ? void 0 : token.access_token) && !this.isPathExcepted(req)) {
|
|
350
|
+
req = req.clone({
|
|
351
|
+
setHeaders: {
|
|
352
|
+
Authorization: `${token.token_type} ${token.access_token}`
|
|
353
|
+
}
|
|
354
|
+
});
|
|
432
355
|
}
|
|
433
|
-
return
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
}
|
|
356
|
+
return req;
|
|
357
|
+
}), switchMap(req => next.handle(req)), catchError((err) => {
|
|
358
|
+
if (err.status === 401 && !this.isPathExcepted(req)) {
|
|
359
|
+
this.tokenService.token = {
|
|
360
|
+
error: `${err.status}`,
|
|
361
|
+
error_description: err.message
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
return throwError(() => err);
|
|
365
|
+
}));
|
|
444
366
|
}
|
|
445
367
|
isPathExcepted(req) {
|
|
446
|
-
const { ignorePaths } = this.
|
|
368
|
+
const { ignorePaths } = this.authConfig || {};
|
|
447
369
|
if (ignorePaths) {
|
|
448
|
-
for (const ignorePath of
|
|
370
|
+
for (const ignorePath of ignorePaths) {
|
|
449
371
|
try {
|
|
450
372
|
if (req.url.match(ignorePath)) {
|
|
451
373
|
return true;
|
|
@@ -458,39 +380,40 @@ class OAuthInterceptor {
|
|
|
458
380
|
return false;
|
|
459
381
|
}
|
|
460
382
|
}
|
|
461
|
-
OAuthInterceptor.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.5", ngImport: i0, type: OAuthInterceptor, deps: [{ token:
|
|
383
|
+
OAuthInterceptor.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.5", ngImport: i0, type: OAuthInterceptor, deps: [{ token: TokenService }, { token: OAuthConfig }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
462
384
|
OAuthInterceptor.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.5", ngImport: i0, type: OAuthInterceptor });
|
|
463
385
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.5", ngImport: i0, type: OAuthInterceptor, decorators: [{
|
|
464
386
|
type: Injectable
|
|
465
|
-
}], ctorParameters: function () { return [{ type:
|
|
387
|
+
}], ctorParameters: function () { return [{ type: TokenService }, { type: OAuthConfig }]; } });
|
|
466
388
|
|
|
389
|
+
var _OAuthLoginComponent_subscription, _OAuthLoginComponent_redirectUri, _OAuthLoginComponent_i18n;
|
|
467
390
|
class OAuthLoginComponent {
|
|
468
391
|
constructor(oauthService, locationService, location) {
|
|
469
392
|
this.oauthService = oauthService;
|
|
470
393
|
this.locationService = locationService;
|
|
471
394
|
this.location = location;
|
|
472
|
-
this
|
|
473
|
-
this
|
|
395
|
+
_OAuthLoginComponent_subscription.set(this, new Subscription());
|
|
396
|
+
_OAuthLoginComponent_redirectUri.set(this, void 0);
|
|
397
|
+
_OAuthLoginComponent_i18n.set(this, {
|
|
474
398
|
username: 'Username',
|
|
475
399
|
password: 'Password',
|
|
476
400
|
submit: 'Sign in',
|
|
477
401
|
notAuthorized: 'Sign in',
|
|
478
402
|
authorized: 'Welcome',
|
|
479
403
|
denied: 'Access Denied. Try again!'
|
|
480
|
-
};
|
|
404
|
+
});
|
|
481
405
|
this.useLogoutUrl = false;
|
|
482
406
|
this.state = '';
|
|
483
|
-
this.stateChange =
|
|
407
|
+
this.stateChange = this.oauthService.state$.asObservable();
|
|
484
408
|
this.username = '';
|
|
485
409
|
this.password = '';
|
|
486
410
|
this.OAuthStatus = OAuthStatus;
|
|
487
411
|
this.OAuthType = OAuthType;
|
|
488
412
|
this.collapse = false;
|
|
489
|
-
this.type =
|
|
490
|
-
this.state$ = this.oauthService.state$.pipe(tap(s => this.stateChange.emit(s)));
|
|
413
|
+
this.type = OAuthType.RESOURCE;
|
|
491
414
|
this.status$ = this.oauthService.status$.pipe(tap(s => {
|
|
492
415
|
if (s === OAuthStatus.AUTHORIZED && this.profileName$) {
|
|
493
|
-
this.
|
|
416
|
+
__classPrivateFieldGet(this, _OAuthLoginComponent_subscription, "f").add(this.profileName$.pipe(take(1)).subscribe(n => this.profileName = n));
|
|
494
417
|
}
|
|
495
418
|
else {
|
|
496
419
|
const { token } = this.oauthService;
|
|
@@ -502,30 +425,28 @@ class OAuthLoginComponent {
|
|
|
502
425
|
this.logoutFunction = () => this.logout();
|
|
503
426
|
}
|
|
504
427
|
get i18n() {
|
|
505
|
-
return this
|
|
428
|
+
return __classPrivateFieldGet(this, _OAuthLoginComponent_i18n, "f");
|
|
506
429
|
}
|
|
507
430
|
set i18n(i18n) {
|
|
508
|
-
this
|
|
431
|
+
__classPrivateFieldSet(this, _OAuthLoginComponent_i18n, Object.assign(Object.assign({}, __classPrivateFieldGet(this, _OAuthLoginComponent_i18n, "f")), i18n), "f");
|
|
432
|
+
}
|
|
433
|
+
get redirectUri() {
|
|
434
|
+
return __classPrivateFieldGet(this, _OAuthLoginComponent_redirectUri, "f") || `${this.location.origin}${this.locationService.path(true) || '/'}`;
|
|
509
435
|
}
|
|
510
436
|
set redirectUri(redirectUri) {
|
|
511
437
|
if (redirectUri) {
|
|
512
|
-
this
|
|
438
|
+
__classPrivateFieldSet(this, _OAuthLoginComponent_redirectUri, redirectUri, "f");
|
|
513
439
|
}
|
|
514
440
|
}
|
|
515
|
-
get redirectUri() {
|
|
516
|
-
return this._redirectUri || `${this.location.origin}${this.locationService.path(true) || '/'}`;
|
|
517
|
-
}
|
|
518
441
|
ngOnDestroy() {
|
|
519
|
-
this.
|
|
442
|
+
__classPrivateFieldGet(this, _OAuthLoginComponent_subscription, "f").unsubscribe();
|
|
520
443
|
}
|
|
521
444
|
logout() {
|
|
522
445
|
this.oauthService.logout(this.useLogoutUrl);
|
|
523
446
|
}
|
|
524
447
|
login(parameters) {
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
this.collapse = false;
|
|
528
|
-
});
|
|
448
|
+
this.collapse = false;
|
|
449
|
+
return this.oauthService.login(parameters);
|
|
529
450
|
}
|
|
530
451
|
toggleCollapse() {
|
|
531
452
|
this.collapse = !this.collapse;
|
|
@@ -533,14 +454,18 @@ class OAuthLoginComponent {
|
|
|
533
454
|
keyboardEvent() {
|
|
534
455
|
this.collapse = false;
|
|
535
456
|
}
|
|
457
|
+
get responseType() {
|
|
458
|
+
return this.type; //avoid complains
|
|
459
|
+
}
|
|
536
460
|
}
|
|
537
|
-
|
|
538
|
-
OAuthLoginComponent.ɵ
|
|
461
|
+
_OAuthLoginComponent_subscription = new WeakMap(), _OAuthLoginComponent_redirectUri = new WeakMap(), _OAuthLoginComponent_i18n = new WeakMap();
|
|
462
|
+
OAuthLoginComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.5", ngImport: i0, type: OAuthLoginComponent, deps: [{ token: OAuthService }, { token: i2$1.Location }, { token: LOCATION }], target: i0.ɵɵFactoryTarget.Component });
|
|
463
|
+
OAuthLoginComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.5", type: OAuthLoginComponent, selector: "oauth-login", inputs: { i18n: "i18n", redirectUri: "redirectUri", useLogoutUrl: "useLogoutUrl", state: "state", profileName$: "profileName$", type: "type" }, 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\" #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({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 });
|
|
539
464
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.5", ngImport: i0, type: OAuthLoginComponent, decorators: [{
|
|
540
465
|
type: Component,
|
|
541
|
-
args: [{ selector: 'oauth-login', encapsulation: ViewEncapsulation.None, template: "<ng-container *ngIf=\"
|
|
466
|
+
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\" #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({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"] }]
|
|
542
467
|
}], ctorParameters: function () {
|
|
543
|
-
return [{ type: OAuthService }, { type: i2.Location }, { type: Location, decorators: [{
|
|
468
|
+
return [{ type: OAuthService }, { type: i2$1.Location }, { type: Location, decorators: [{
|
|
544
469
|
type: Inject,
|
|
545
470
|
args: [LOCATION]
|
|
546
471
|
}] }];
|
|
@@ -559,6 +484,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.5", ngImpor
|
|
|
559
484
|
}], loginTemplate: [{
|
|
560
485
|
type: ContentChild,
|
|
561
486
|
args: ['login', { static: false }]
|
|
487
|
+
}], type: [{
|
|
488
|
+
type: Input
|
|
562
489
|
}], keyboardEvent: [{
|
|
563
490
|
type: HostListener,
|
|
564
491
|
args: ['window:keydown.escape']
|
|
@@ -571,10 +498,10 @@ const mockLocation = (serverHost, serverPath) => {
|
|
|
571
498
|
href, origin, protocol, host, hostname, port, pathname, search, hash,
|
|
572
499
|
reload() {
|
|
573
500
|
},
|
|
574
|
-
assign(
|
|
501
|
+
assign(_) {
|
|
575
502
|
},
|
|
576
503
|
ancestorOrigins: {},
|
|
577
|
-
replace(
|
|
504
|
+
replace(_) {
|
|
578
505
|
}
|
|
579
506
|
};
|
|
580
507
|
};
|
|
@@ -630,9 +557,10 @@ class OAuthModule {
|
|
|
630
557
|
providers: [
|
|
631
558
|
LocationService,
|
|
632
559
|
StorageService,
|
|
633
|
-
OAuthService,
|
|
634
|
-
OAuthInterceptorService,
|
|
635
560
|
provideOAuthConfigFactory((storage) => (Object.assign(Object.assign({}, defaultConfig(storage)), config)), [STORAGE]),
|
|
561
|
+
TokenService,
|
|
562
|
+
OAuthInterceptorService,
|
|
563
|
+
OAuthService,
|
|
636
564
|
]
|
|
637
565
|
};
|
|
638
566
|
}
|
|
@@ -668,5 +596,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.5", ngImpor
|
|
|
668
596
|
* Generated bundle index. Do not edit.
|
|
669
597
|
*/
|
|
670
598
|
|
|
671
|
-
export { LOCATION, OAUTH_CONFIG, OAUTH_TOKEN, OAuthConfig, OAuthInterceptor, OAuthLoginComponent, OAuthModule, OAuthService, OAuthStatus, OAuthType, SERVER_HOST, SERVER_PATH, STORAGE, provideOAuthConfig, provideOAuthConfigFactory };
|
|
599
|
+
export { HEADER_APPLICATION, LOCATION, OAUTH_CONFIG, OAUTH_TOKEN, OAuthConfig, OAuthInterceptor, OAuthLoginComponent, OAuthModule, OAuthService, OAuthStatus, OAuthType, SERVER_HOST, SERVER_PATH, STORAGE, provideOAuthConfig, provideOAuthConfigFactory };
|
|
672
600
|
//# sourceMappingURL=ngx-oauth.mjs.map
|