ngx-oauth 4.2.2 → 5.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.
@@ -1,291 +0,0 @@
1
- import { Inject, Injectable } from '@angular/core';
2
- import { HttpParams } from '@angular/common/http';
3
- import { catchError, concatMap, delay, filter, map, shareReplay, switchMap, tap } from 'rxjs/operators';
4
- import { firstValueFrom, from, noop, of, ReplaySubject, throwError } from 'rxjs';
5
- import { HEADER_APPLICATION, LOCATION, OAuthStatus, OAuthType } from '../models';
6
- import * as i0 from "@angular/core";
7
- import * as i1 from "../models";
8
- import * as i2 from "./token.service";
9
- import * as i3 from "@angular/common/http";
10
- import * as i4 from "@angular/common";
11
- const arrToString = (buf) => buf.reduce((s, b) => s + String.fromCharCode(b), '');
12
- const base64url = (str) => btoa(str)
13
- .replace(/\+/g, '-')
14
- .replace(/\//g, '_')
15
- .replace(/=/g, '');
16
- const randomString = (length = 48) => {
17
- const buff = arrToString(crypto.getRandomValues(new Uint8Array(length * 2)));
18
- return base64url(buff).substring(0, length);
19
- };
20
- const pkce = async (value) => {
21
- const buff = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(value));
22
- return base64url(arrToString(new Uint8Array(buff)));
23
- };
24
- const parseOauthUri = (hash) => {
25
- const regex = /([^&=]+)=([^&]*)/g;
26
- const params = {};
27
- let m;
28
- // tslint:disable-next-line:no-conditional-assignment
29
- while ((m = regex.exec(hash)) !== null) {
30
- params[decodeURIComponent(m[1])] = decodeURIComponent(m[2]);
31
- }
32
- return Object.keys(params).length && params || {};
33
- };
34
- const jwt = (token) => JSON.parse(atob(token.split('.')[1]));
35
- export class OAuthService {
36
- constructor(authConfig, tokenService, http, location, locationService) {
37
- this.authConfig = authConfig;
38
- this.tokenService = tokenService;
39
- this.http = http;
40
- this.location = location;
41
- this.locationService = locationService;
42
- this.state$ = new ReplaySubject(1);
43
- this.config$ = of(this.config).pipe(filter(Boolean), filter(config => !!config?.clientId), map(config => config), switchMap(config => !config.issuerPath && of(config) || this.http.get(`${config.issuerPath}/.well-known/openid-configuration`).pipe(tap(v => this.config = {
44
- ...v.authorization_endpoint && { authorizePath: v.authorization_endpoint } || {},
45
- ...v.token_endpoint && { tokenPath: v.token_endpoint } || {},
46
- ...v.revocation_endpoint && { revokePath: v.revocation_endpoint } || {},
47
- ...v.code_challenge_methods_supported && { pkce: v.code_challenge_methods_supported.indexOf('S256') > -1 } || {},
48
- ...v.userinfo_endpoint && { userPath: v.userinfo_endpoint } || {},
49
- ...v.introspection_endpoint && { introspectionPath: v.introspection_endpoint } || {},
50
- ...v.end_session_endpoint && { logoutPath: v.end_session_endpoint } || {},
51
- ...{ scope: config.scope || 'openid' }
52
- }), map(() => this.config))), shareReplay(1));
53
- this.token$ = this.config$.pipe(tap(config => {
54
- const { hash, search, origin, pathname } = this.location;
55
- const isImplicitRedirect = hash && /(access_token=)|(error=)/.test(hash);
56
- const isAuthCodeRedirect = search && /(code=)|(error=)/.test(search) || hash && /(code=)|(error=)/.test(hash);
57
- if (isImplicitRedirect) {
58
- const parameters = parseOauthUri(hash.substring(1));
59
- this.token = {
60
- ...parameters,
61
- type: OAuthType.IMPLICIT,
62
- };
63
- this.checkResponse(this.token, parameters);
64
- }
65
- else if (isAuthCodeRedirect) {
66
- const parameters = parseOauthUri(search && search.substring(1) || hash && hash.substring(1));
67
- if (!this.checkResponse(this.token, parameters)) {
68
- this.token = parameters;
69
- }
70
- else {
71
- const newParametersString = this.getCleanedUnSearchParameters();
72
- const { clientId, clientSecret, tokenPath, scope } = config;
73
- const { codeVerifier } = this.token || {}; //should be set by authorizationUrl construction
74
- this.http.post(tokenPath, new HttpParams({
75
- fromObject: {
76
- code: parameters?.['code'],
77
- client_id: clientId,
78
- ...clientSecret && { client_secret: clientSecret } || {},
79
- redirect_uri: `${origin}${pathname}`,
80
- grant_type: 'authorization_code',
81
- ...scope && { scope } || {},
82
- ...codeVerifier && { code_verifier: codeVerifier } || {}
83
- }
84
- }), { headers: HEADER_APPLICATION }).pipe().subscribe(token => {
85
- this.token = {
86
- ...token,
87
- type: OAuthType.AUTHORIZATION_CODE
88
- };
89
- this.locationService.replaceState(`${pathname}${newParametersString}`);
90
- });
91
- }
92
- }
93
- }), switchMap(() => this.tokenService.token$), shareReplay(1));
94
- this.status$ = this.token$.pipe(map(token => token.access_token && OAuthStatus.AUTHORIZED || token.error && OAuthStatus.DENIED || OAuthStatus.NOT_AUTHORIZED), shareReplay(1));
95
- this.userInfo$ = this.status$.pipe(filter(s => s === OAuthStatus.AUTHORIZED), map(() => this.config.userPath), filter(Boolean), switchMap(path => this.getUserInfo(path)), shareReplay(1));
96
- this.type$ = this.tokenService.type$;
97
- this.ignorePaths = this.authConfig.ignorePaths || [];
98
- }
99
- get token() {
100
- return this.tokenService.token;
101
- }
102
- set token(token) {
103
- this.tokenService.token = token;
104
- }
105
- get config() {
106
- return this.authConfig.config;
107
- }
108
- set config(config) {
109
- if (config) {
110
- this.authConfig.config = {
111
- ...this.authConfig.config,
112
- ...config
113
- };
114
- }
115
- }
116
- async login(parameters) {
117
- if (!!parameters && parameters.password) {
118
- await this.resourceLogin(parameters);
119
- }
120
- else if (!!parameters && parameters.redirectUri && parameters.responseType) {
121
- await this.toAuthorizationUrl(parameters);
122
- }
123
- else {
124
- await this.clientCredentialLogin();
125
- }
126
- }
127
- logout(useLogoutUrl) {
128
- this.revoke();
129
- this.token = {};
130
- const { logoutPath, logoutRedirectUri } = this.authConfig.config;
131
- if (useLogoutUrl && logoutPath) {
132
- const { origin, pathname } = this.location;
133
- const currentPath = `${origin}${pathname}`;
134
- this.location.replace(`${logoutPath}?post_logout_redirect_uri=${logoutRedirectUri || currentPath}`);
135
- }
136
- }
137
- getUserInfo(path) {
138
- const { userPath } = this.config;
139
- return this.http.get(path || userPath);
140
- }
141
- revoke() {
142
- const { revokePath, clientId, clientSecret } = this.authConfig.config;
143
- if (revokePath) {
144
- const { access_token, refresh_token } = this.token || {};
145
- const toRevoke = [];
146
- if (access_token) {
147
- toRevoke.push({
148
- ...clientId && { client_id: clientId } || {},
149
- ...clientSecret && { client_secret: clientSecret } || {},
150
- token: access_token,
151
- token_type_hint: 'access_token'
152
- });
153
- }
154
- if (refresh_token) {
155
- toRevoke.push({
156
- ...clientId && { client_id: clientId } || {},
157
- ...clientSecret && { client_secret: clientSecret } || {},
158
- token: refresh_token,
159
- token_type_hint: 'refresh_token'
160
- });
161
- }
162
- from(toRevoke).pipe(concatMap(o => of(o).pipe(delay(300))), // space request to avoid cancellation
163
- switchMap(o => this.http.post(revokePath, new HttpParams({ fromObject: o })))).subscribe(noop);
164
- }
165
- }
166
- clientCredentialLogin() {
167
- const { clientId, clientSecret, tokenPath, scope } = this.authConfig.config;
168
- return firstValueFrom(this.http.post(tokenPath, new HttpParams({
169
- fromObject: {
170
- client_id: clientId,
171
- client_secret: clientSecret,
172
- grant_type: OAuthType.CLIENT_CREDENTIAL,
173
- ...scope ? { scope } : {},
174
- }
175
- }), { headers: HEADER_APPLICATION }).pipe(catchError((err) => {
176
- this.token = err;
177
- return throwError(() => err);
178
- }), tap(params => {
179
- this.token = {
180
- ...params,
181
- type: OAuthType.CLIENT_CREDENTIAL,
182
- };
183
- })));
184
- }
185
- resourceLogin(parameters) {
186
- const { clientId, clientSecret, tokenPath, scope } = this.authConfig.config;
187
- const { username, password } = parameters;
188
- return firstValueFrom(this.http.post(tokenPath, new HttpParams({
189
- fromObject: {
190
- client_id: clientId,
191
- ...clientSecret && { client_secret: clientSecret } || {},
192
- grant_type: OAuthType.RESOURCE,
193
- ...scope && { scope } || {},
194
- username,
195
- password
196
- }
197
- }), { headers: HEADER_APPLICATION }).pipe(catchError(err => {
198
- this.token = err;
199
- return throwError(() => err);
200
- }), tap(params => {
201
- this.token = {
202
- ...params,
203
- type: OAuthType.RESOURCE,
204
- };
205
- })));
206
- }
207
- async toAuthorizationUrl(parameters) {
208
- const { config } = this.authConfig;
209
- let authorizationUrl = `${config.authorizePath}`;
210
- authorizationUrl += config.authorizePath.includes('?') && '&' || '?';
211
- authorizationUrl += `client_id=${config.clientId}`;
212
- authorizationUrl += `&redirect_uri=${encodeURIComponent(parameters.redirectUri)}`;
213
- authorizationUrl += `&response_type=${parameters.responseType}`;
214
- authorizationUrl += `&scope=${encodeURIComponent(config.scope || '')}`;
215
- authorizationUrl += `&state=${encodeURIComponent(parameters.state || '')}`;
216
- return this.location.replace(`${authorizationUrl}${this.generateNonce(config)}${await this.generateCodeChallenge(config)}`);
217
- }
218
- async generateCodeChallenge(config) {
219
- if (config.pkce) {
220
- const codeVerifier = randomString();
221
- this.token = { ...this.token, codeVerifier };
222
- return `&code_challenge=${await pkce(codeVerifier)}&code_challenge_method=S256`;
223
- }
224
- return '';
225
- }
226
- generateNonce(config) {
227
- if (config && config.scope && config.scope.indexOf('openid') > -1) {
228
- const nonce = randomString(10);
229
- this.token = { ...this.token, nonce };
230
- return `&nonce=${nonce}`;
231
- }
232
- return '';
233
- }
234
- checkResponse(token, parameters) {
235
- this.emitState(parameters);
236
- this.cleanLocationHash();
237
- if (!parameters || parameters['error']) {
238
- return false;
239
- }
240
- if (token && token.nonce && parameters['access_token']) {
241
- const jwtToken = jwt(parameters['access_token']);
242
- return token.nonce === jwtToken.nonce;
243
- }
244
- return parameters['access_token'] || parameters['code'];
245
- }
246
- getCleanedUnSearchParameters() {
247
- const { search } = this.location;
248
- let searchString = search && search.substring(1) || '';
249
- const hashKeys = ['code', 'state', 'error', 'error_description', 'session_state', 'scope', 'authuser', 'prompt'];
250
- hashKeys.forEach(hashKey => {
251
- const re = new RegExp('&' + hashKey + '(=[^&]*)?|^' + hashKey + '(=[^&]*)?&?');
252
- searchString = searchString.replace(re, '');
253
- });
254
- return searchString.length && `?${searchString}` || '';
255
- }
256
- cleanLocationHash() {
257
- const { hash } = this.location;
258
- let curHash = hash && hash.substring(1) || '';
259
- const hashKeys = [
260
- 'access_token',
261
- 'token_type',
262
- 'expires_in',
263
- 'scope',
264
- 'state',
265
- 'error',
266
- 'error_description',
267
- 'session_state',
268
- 'nonce',
269
- 'id_token',
270
- 'code'
271
- ];
272
- hashKeys.forEach(hashKey => {
273
- const re = new RegExp('&' + hashKey + '(=[^&]*)?|^' + hashKey + '(=[^&]*)?&?');
274
- curHash = curHash.replace(re, '');
275
- });
276
- this.location.hash = curHash;
277
- }
278
- emitState(parameters) {
279
- const { state } = parameters || {};
280
- state && this.state$.next(state);
281
- }
282
- }
283
- OAuthService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.3", ngImport: i0, type: OAuthService, deps: [{ token: i1.OAuthConfig }, { token: i2.TokenService }, { token: i3.HttpClient }, { token: LOCATION }, { token: i4.Location }], target: i0.ɵɵFactoryTarget.Injectable });
284
- OAuthService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.3", ngImport: i0, type: OAuthService });
285
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.3", ngImport: i0, type: OAuthService, decorators: [{
286
- type: Injectable
287
- }], ctorParameters: function () { return [{ type: i1.OAuthConfig }, { type: i2.TokenService }, { type: i3.HttpClient }, { type: Location, decorators: [{
288
- type: Inject,
289
- args: [LOCATION]
290
- }] }, { type: i4.Location }]; } });
291
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib2F1dGguc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1vYXV0aC9zcmMvbGliL3NlcnZpY2VzL29hdXRoLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFDLE1BQU0sRUFBRSxVQUFVLEVBQUMsTUFBTSxlQUFlLENBQUM7QUFDakQsT0FBTyxFQUFhLFVBQVUsRUFBQyxNQUFNLHNCQUFzQixDQUFDO0FBQzVELE9BQU8sRUFBQyxVQUFVLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFLFdBQVcsRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFDLE1BQU0sZ0JBQWdCLENBQUM7QUFDdEcsT0FBTyxFQUFDLGNBQWMsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFBRSxhQUFhLEVBQUUsVUFBVSxFQUFDLE1BQU0sTUFBTSxDQUFDO0FBQy9FLE9BQU8sRUFHTCxrQkFBa0IsRUFDbEIsUUFBUSxFQUdSLFdBQVcsRUFFWCxTQUFTLEVBTVYsTUFBTSxXQUFXLENBQUM7Ozs7OztBQUluQixNQUFNLFdBQVcsR0FBRyxDQUFDLEdBQWUsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO0FBRTlGLE1BQU0sU0FBUyxHQUFHLENBQUMsR0FBVyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDO0tBQ3pDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDO0tBQ25CLE9BQU8sQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDO0tBQ25CLE9BQU8sQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUM7QUFFckIsTUFBTSxZQUFZLEdBQUcsQ0FB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ICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7SHR0cENsaWVudCwgSHR0cFBhcmFtc30gZnJvbSAnQGFuZ3VsYXIvY29tbW9uL2h0dHAnO1xuaW1wb3J0IHtjYXRjaEVycm9yLCBjb25jYXRNYXAsIGRlbGF5LCBmaWx0ZXIsIG1hcCwgc2hhcmVSZXBsYXksIHN3aXRjaE1hcCwgdGFwfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQge2ZpcnN0VmFsdWVGcm9tLCBmcm9tLCBub29wLCBvZiwgUmVwbGF5U3ViamVjdCwgdGhyb3dFcnJvcn0gZnJvbSAncnhqcyc7XG5pbXBvcnQge1xuICBBdXRob3JpemF0aW9uQ29kZUNvbmZpZyxcbiAgQXV0aG9yaXphdGlvblBhcmFtZXRlcnMsXG4gIEhFQURFUl9BUFBMSUNBVElPTixcbiAgTE9DQVRJT04sXG4gIE9BdXRoQ29uZmlnLFxuICBPQXV0aFBhcmFtZXRlcnMsXG4gIE9BdXRoU3RhdHVzLFxuICBPQXV0aFRva2VuLFxuICBPQXV0aFR5cGUsXG4gIE9BdXRoVHlwZUNvbmZpZyxcbiAgT3BlbklkQ29uZmlnLFxuICBPcGVuSWRDb25maWd1cmF0aW9uLFxuICBSZXNvdXJjZVBhcmFtZXRlcnMsXG4gIFVzZXJJbmZvXG59IGZyb20gJy4uL21vZGVscyc7XG5pbXBvcnQge0xvY2F0aW9uIGFzIExvY2F0aW9uMn0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7VG9rZW5TZXJ2aWNlfSBmcm9tICcuL3Rva2VuLnNlcnZpY2UnO1xuXG5jb25zdCBhcnJUb1N0cmluZyA9IChidWY6IFVpbnQ4QXJyYXkpID0+IGJ1Zi5yZWR1Y2UoKHMsIGIpID0+IHMgKyBTdHJpbmcuZnJvbUNoYXJDb2RlKGIpLCAnJyk7XG5cbmNvbnN0IGJhc2U2NHVybCA9IChzdHI6IHN0cmluZykgPT4gYnRvYShzdHIpXG4gIC5yZXBsYWNlKC9cXCsvZywgJy0nKVxuICAucmVwbGFjZSgvXFwvL2csICdfJylcbiAgLnJlcGxhY2UoLz0vZywgJycpO1xuXG5jb25zdCByYW5kb21TdHJpbmcgPSAobGVuZ3RoOiBudW1iZXIgPSA0OCkgPT4ge1xuICBjb25zdCBidWZmID0gYXJyVG9TdHJpbmcoY3J5cHRvLmdldFJhbmRvbVZhbHVlcyhuZXcgVWludDhBcnJheShsZW5ndGggKiAyKSkpO1xuICByZXR1cm4gYmFzZTY0dXJsKGJ1ZmYpLnN1YnN0cmluZygwLCBsZW5ndGgpO1xufTtcblxuY29uc3QgcGtjZSA9IGFzeW5jICh2YWx1ZTogc3RyaW5nKSA9PiB7XG4gIGNvbnN0IGJ1ZmYgPSBhd2FpdCBjcnlwdG8uc3VidGxlLmRpZ2VzdCgnU0hBLTI1NicsIG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZSh2YWx1ZSkpO1xuICByZXR1cm4gYmFzZTY0dXJsKGFyclRvU3RyaW5nKG5ldyBVaW50OEFycmF5KGJ1ZmYpKSk7XG59O1xuXG5jb25zdCBwYXJzZU9hdXRoVXJpID0gKGhhc2g6IHN0cmluZykgPT4ge1xuICBjb25zdCByZWdleCA9IC8oW14mPV0rKT0oW14mXSopL2c7XG4gIGNvbnN0IHBhcmFtczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9O1xuICBsZXQgbTtcbiAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWNvbmRpdGlvbmFsLWFzc2lnbm1lbnRcbiAgd2hpbGUgKChtID0gcmVnZXguZXhlYyhoYXNoKSkgIT09IG51bGwpIHtcbiAgICBwYXJhbXNbZGVjb2RlVVJJQ29tcG9uZW50KG1bMV0pXSA9IGRlY29kZVVSSUNvbXBvbmVudChtWzJdKTtcbiAgfVxuICByZXR1cm4gT2JqZWN0LmtleXMocGFyYW1zKS5sZW5ndGggJiYgcGFyYW1zIHx8IHt9O1xufTtcblxuY29uc3Qgand0ID0gKHRva2VuOiBzdHJpbmcpID0+IEpTT04ucGFyc2UoYXRvYih0b2tlbi5zcGxpdCgnLicpWzFdKSk7XG5cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBPQXV0aFNlcnZpY2Uge1xuXG4gIHN0YXRlJCA9IG5ldyBSZXBsYXlTdWJqZWN0PHN0cmluZz4oMSk7XG4gIGNvbmZpZyQgPSBvZih0aGlzLmNvbmZpZykucGlwZShcbiAgICBmaWx0ZXIoQm9vbGVhbiksXG4gICAgZmlsdGVyKGNvbmZpZyA9PiAhIWNvbmZpZz8uY2xpZW50SWQpLFxuICAgIG1hcChjb25maWcgPT4gY29uZmlnIGFzIE9wZW5JZENvbmZpZyksXG4gICAgc3dpdGNoTWFwKGNvbmZpZyA9PiAhY29uZmlnLmlzc3VlclBhdGggJiYgb2YoY29uZmlnKSB8fCB0aGlzLmh0dHAuZ2V0PE9wZW5JZENvbmZpZ3VyYXRpb24+KGAke2NvbmZpZy5pc3N1ZXJQYXRofS8ud2VsbC1rbm93bi9vcGVuaWQtY29uZmlndXJhdGlvbmApLnBpcGUoXG4gICAgICB0YXAodiA9PiB0aGlzLmNvbmZpZyA9IHtcbiAgICAgICAgLi4udi5hdXRob3JpemF0aW9uX2VuZHBvaW50ICYmIHthdXRob3JpemVQYXRoOiB2LmF1dGhvcml6YXRpb25fZW5kcG9pbnR9IHx8IHt9LFxuICAgICAgICAuLi52LnRva2VuX2VuZHBvaW50ICYmIHt0b2tlblBhdGg6IHYudG9rZW5fZW5kcG9pbnR9IHx8IHt9LFxuICAgICAgICAuLi52LnJldm9jYXRpb25fZW5kcG9pbnQgJiYge3Jldm9rZVBhdGg6IHYucmV2b2NhdGlvbl9lbmRwb2ludH0gfHwge30sXG4gICAgICAgIC4uLnYuY29kZV9jaGFsbGVuZ2VfbWV0aG9kc19zdXBwb3J0ZWQgJiYge3BrY2U6IHYuY29kZV9jaGFsbGVuZ2VfbWV0aG9kc19zdXBwb3J0ZWQuaW5kZXhPZignUzI1NicpID4gLTF9IHx8IHt9LFxuICAgICAgICAuLi52LnVzZXJpbmZvX2VuZHBvaW50ICYmIHt1c2VyUGF0aDogdi51c2VyaW5mb19lbmRwb2ludH0gfHwge30sXG4gICAgICAgIC4uLnYuaW50cm9zcGVjdGlvbl9lbmRwb2ludCAmJiB7aW50cm9zcGVjdGlvblBhdGg6IHYuaW50cm9zcGVjdGlvbl9lbmRwb2ludH0gfHwge30sXG4gICAgICAgIC4uLnYuZW5kX3Nlc3Npb25fZW5kcG9pbnQgJiYge2xvZ291dFBhdGg6IHYuZW5kX3Nlc3Npb25fZW5kcG9pbnR9IHx8IHt9LFxuICAgICAgICAuLi57c2NvcGU6IGNvbmZpZy5zY29wZSB8fCAnb3BlbmlkJ31cbiAgICAgIH0gYXMgYW55KSxcbiAgICAgIG1hcCgoKSA9PiB0aGlzLmNvbmZpZylcbiAgICApKSxcbiAgICBzaGFyZVJlcGxheSgxKVxuICApO1xuICB0b2tlbiQgPSB0aGlzLmNvbmZpZyQucGlwZShcbiAgICB0YXAoY29uZmlnID0+IHtcbiAgICAgIGNvbnN0IHtoYXNoLCBzZWFyY2gsIG9yaWdpbiwgcGF0aG5hbWV9ID0gdGhpcy5sb2NhdGlvbjtcbiAgICAgIGNvbnN0IGlzSW1wbGljaXRSZWRpcmVjdCA9IGhhc2ggJiYgLyhhY2Nlc3NfdG9rZW49KXwoZXJyb3I9KS8udGVzdChoYXNoKTtcbiAgICAgIGNvbnN0IGlzQXV0aENvZGVSZWRpcmVjdCA9IHNlYXJjaCAmJiAvKGNvZGU9KXwoZXJyb3I9KS8udGVzdChzZWFyY2gpIHx8IGhhc2ggJiYgLyhjb2RlPSl8KGVycm9yPSkvLnRlc3QoaGFzaCk7XG4gICAgICBpZiAoaXNJbXBsaWNpdFJlZGlyZWN0KSB7XG4gICAgICAgIGNvbnN0IHBhcmFtZXRlcnMgPSBwYXJzZU9hdXRoVXJpKGhhc2guc3Vic3RyaW5nKDEpKTtcbiAgICAgICAgdGhpcy50b2tlbiA9IHtcbiAgICAgICAgICAuLi5wYXJhbWV0ZXJzLFxuICAgICAgICAgIHR5cGU6IE9BdXRoVHlwZS5JTVBMSUNJVCxcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5jaGVja1Jlc3BvbnNlKHRoaXMudG9rZW4sIHBhcmFtZXRlcnMpO1xuICAgICAgfSBlbHNlIGlmIChpc0F1dGhDb2RlUmVkaXJlY3QpIHtcbiAgICAgICAgY29uc3QgcGFyYW1ldGVycyA9IHBhcnNlT2F1dGhVcmkoc2VhcmNoICYmIHNlYXJjaC5zdWJzdHJpbmcoMSkgfHwgaGFzaCAmJiBoYXNoLnN1YnN0cmluZygxKSk7XG4gICAgICAgIGlmICghdGhpcy5jaGVja1Jlc3BvbnNlKHRoaXMudG9rZW4sIHBhcmFtZXRlcnMpKSB7XG4gICAgICAgICAgdGhpcy50b2tlbiA9IHBhcmFtZXRlcnM7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc3QgbmV3UGFyYW1ldGVyc1N0cmluZyA9IHRoaXMuZ2V0Q2xlYW5lZFVuU2VhcmNoUGFyYW1ldGVycygpO1xuICAgICAgICAgIGNvbnN0IHtjbGllbnRJZCwgY2xpZW50U2VjcmV0LCB0b2tlblBhdGgsIHNjb3BlfSA9IGNvbmZpZyBhcyBBdXRob3JpemF0aW9uQ29kZUNvbmZpZztcbiAgICAgICAgICBjb25zdCB7Y29kZVZlcmlmaWVyfSA9IHRoaXMudG9rZW4gfHwge307IC8vc2hvdWxkIGJlIHNldCBieSBhdXRob3JpemF0aW9uVXJsIGNvbnN0cnVjdGlvblxuICAgICAgICAgIHRoaXMuaHR0cC5wb3N0KHRva2VuUGF0aCwgbmV3IEh0dHBQYXJhbXMoe1xuICAgICAgICAgICAgZnJvbU9iamVjdDoge1xuICAgICAgICAgICAgICBjb2RlOiBwYXJhbWV0ZXJzPy5bJ2NvZGUnXSxcbiAgICAgICAgICAgICAgY2xpZW50X2lkOiBjbGllbnRJZCxcbiAgICAgICAgICAgICAgLi4uY2xpZW50U2VjcmV0ICYmIHtjbGllbnRfc2VjcmV0OiBjbGllbnRTZWNyZXR9IHx8IHt9LFxuICAgICAgICAgICAgICByZWRpcmVjdF91cmk6IGAke29yaWdpbn0ke3BhdGhuYW1lfWAsXG4gICAgICAgICAgICAgIGdyYW50X3R5cGU6ICdhdXRob3JpemF0aW9uX2NvZGUnLFxuICAgICAgICAgICAgICAuLi5zY29wZSAmJiB7c2NvcGV9IHx8IHt9LFxuICAgICAgICAgICAgICAuLi5jb2RlVmVyaWZpZXIgJiYge2NvZGVfdmVyaWZpZXI6IGNvZGVWZXJpZmllcn0gfHwge31cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KSwge2hlYWRlcnM6IEhFQURFUl9BUFBMSUNBVElPTn0pLnBpcGUoXG4gICAgICAgICAgKS5zdWJzY3JpYmUodG9rZW4gPT4ge1xuICAgICAgICAgICAgdGhpcy50b2tlbiA9IHtcbiAgICAgICAgICAgICAgLi4udG9rZW4sXG4gICAgICAgICAgICAgIHR5cGU6IE9BdXRoVHlwZS5BVVRIT1JJWkFUSU9OX0NPREVcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICB0aGlzLmxvY2F0aW9uU2VydmljZS5yZXBsYWNlU3RhdGUoYCR7cGF0aG5hbWV9JHtuZXdQYXJhbWV0ZXJzU3RyaW5nfWApO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSksXG4gICAgc3dpdGNoTWFwKCgpID0+IHRoaXMudG9rZW5TZXJ2aWNlLnRva2VuJCksXG4gICAgc2hhcmVSZXBsYXkoMSlcbiAgKTtcbiAgc3RhdHVzJCA9IHRoaXMudG9rZW4kLnBpcGUoXG4gICAgbWFwKHRva2VuID0+IHRva2VuLmFjY2Vzc190b2tlbiAmJiBPQXV0aFN0YXR1cy5BVVRIT1JJWkVEIHx8IHRva2VuLmVycm9yICYmIE9BdXRoU3RhdHVzLkRFTklFRCB8fCBPQXV0aFN0YXR1cy5OT1RfQVVUSE9SSVpFRCksXG4gICAgc2hhcmVSZXBsYXkoMSlcbiAgKTtcbiAgdXNlckluZm8kID0gdGhpcy5zdGF0dXMkLnBpcGUoXG4gICAgZmlsdGVyKHMgPT4gcyA9PT0gT0F1dGhTdGF0dXMuQVVUSE9SSVpFRCksXG4gICAgbWFwKCgpID0+ICh0aGlzLmNvbmZpZyBhcyBhbnkpLnVzZXJQYXRoKSxcbiAgICBmaWx0ZXIoQm9vbGVhbiksXG4gICAgc3dpdGNoTWFwKHBhdGggPT4gdGhpcy5nZXRVc2VySW5mbyhwYXRoKSksXG4gICAgc2hhcmVSZXBsYXkoMSlcbiAgKTtcbiAgdHlwZSQgPSB0aGlzLnRva2VuU2VydmljZS50eXBlJDtcbiAgaWdub3JlUGF0aHMgPSB0aGlzLmF1dGhDb25maWcuaWdub3JlUGF0aHMgfHwgW107XG5cbiAgZ2V0IHRva2VuKCkge1xuICAgIHJldHVybiB0aGlzLnRva2VuU2VydmljZS50b2tlbjtcbiAgfVxuXG4gIHNldCB0b2tlbih0b2tlbikge1xuICAgIHRoaXMudG9rZW5TZXJ2aWNlLnRva2VuID0gdG9rZW47XG4gIH1cblxuICBnZXQgY29uZmlnKCkge1xuICAgIHJldHVybiB0aGlzLmF1dGhDb25maWcuY29uZmlnO1xuICB9XG5cbiAgc2V0IGNvbmZpZyhjb25maWc6IE9BdXRoVHlwZUNvbmZpZyB8IHVuZGVmaW5lZCkge1xuICAgIGlmIChjb25maWcpIHtcbiAgICAgIHRoaXMuYXV0aENvbmZpZy5jb25maWcgPSB7XG4gICAgICAgIC4uLnRoaXMuYXV0aENvbmZpZy5jb25maWcsXG4gICAgICAgIC4uLmNvbmZpZ1xuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICBjb25zdHJ1Y3Rvcihwcm90ZWN0ZWQgYXV0aENvbmZpZzogT0F1dGhDb25maWcsXG4gICAgICAgICAgICAgIHByb3RlY3RlZCB0b2tlblNlcnZpY2U6IFRva2VuU2VydmljZSxcbiAgICAgICAgICAgICAgcHJvdGVjdGVkIGh0dHA6IEh0dHBDbGllbnQsXG4gICAgICAgICAgICAgIEBJbmplY3QoTE9DQVRJT04pIHByb3RlY3RlZCBsb2NhdGlvbjogTG9jYXRpb24sXG4gICAgICAgICAgICAgIHByb3RlY3RlZCBsb2NhdGlvblNlcnZpY2U6IExvY2F0aW9uMikge1xuICB9XG5cbiAgYXN5bmMgbG9naW4ocGFyYW1ldGVycz86IE9BdXRoUGFyYW1ldGVycykge1xuICAgIGlmICghIXBhcmFtZXRlcnMgJiYgKHBhcmFtZXRlcnMgYXMgUmVzb3VyY2VQYXJhbWV0ZXJzKS5wYXNzd29yZCkge1xuICAgICAgYXdhaXQgdGhpcy5yZXNvdXJjZUxvZ2luKHBhcmFtZXRlcnMgYXMgUmVzb3VyY2VQYXJhbWV0ZXJzKTtcbiAgICB9IGVsc2UgaWYgKCEhcGFyYW1ldGVycyAmJiAocGFyYW1ldGVycyBhcyBBdXRob3JpemF0aW9uUGFyYW1ldGVycykucmVkaXJlY3RVcmkgJiYgKHBhcmFtZXRlcnMgYXMgQXV0aG9yaXphdGlvblBhcmFtZXRlcnMpLnJlc3BvbnNlVHlwZVxuICAgICkge1xuICAgICAgYXdhaXQgdGhpcy50b0F1dGhvcml6YXRpb25VcmwocGFyYW1ldGVycyBhcyBBdXRob3JpemF0aW9uUGFyYW1ldGVycyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGF3YWl0IHRoaXMuY2xpZW50Q3JlZGVudGlhbExvZ2luKCk7XG4gICAgfVxuICB9XG5cbiAgbG9nb3V0KHVzZUxvZ291dFVybD86IGJvb2xlYW4pIHtcbiAgICB0aGlzLnJldm9rZSgpO1xuICAgIHRoaXMudG9rZW4gPSB7fTtcbiAgICBjb25zdCB7bG9nb3V0UGF0aCwgbG9nb3V0UmVkaXJlY3RVcml9ID0gdGhpcy5hdXRoQ29uZmlnLmNvbmZpZyBhcyBhbnk7XG4gICAgaWYgKHVzZUxvZ291dFVybCAmJiBsb2dvdXRQYXRoKSB7XG4gICAgICBjb25zdCB7b3JpZ2luLCBwYXRobmFtZX0gPSB0aGlzLmxvY2F0aW9uO1xuICAgICAgY29uc3QgY3VycmVudFBhdGggPSBgJHtvcmlnaW59JHtwYXRobmFtZX1gO1xuICAgICAgdGhpcy5sb2NhdGlvbi5yZXBsYWNlKGAke2xvZ291dFBhdGh9P3Bvc3RfbG9nb3V0X3JlZGlyZWN0X3VyaT0ke2xvZ291dFJlZGlyZWN0VXJpIHx8IGN1cnJlbnRQYXRofWApO1xuICAgIH1cbiAgfVxuXG4gIGdldFVzZXJJbmZvKHBhdGg/OiBzdHJpbmcpIHtcbiAgICBjb25zdCB7dXNlclBhdGh9ID0gdGhpcy5jb25maWcgYXMgYW55O1xuICAgIHJldHVybiB0aGlzLmh0dHAuZ2V0PFVzZXJJbmZvPihwYXRoIHx8IHVzZXJQYXRoKTtcbiAgfVxuXG4gIHByb3RlY3RlZCByZXZva2UoKSB7XG4gICAgY29uc3Qge3Jldm9rZVBhdGgsIGNsaWVudElkLCBjbGllbnRTZWNyZXR9ID0gdGhpcy5hdXRoQ29uZmlnLmNvbmZpZyBhcyBhbnk7XG4gICAgaWYgKHJldm9rZVBhdGgpIHtcbiAgICAgIGNvbnN0IHthY2Nlc3NfdG9rZW4sIHJlZnJlc2hfdG9rZW59ID0gdGhpcy50b2tlbiB8fCB7fTtcbiAgICAgIGNvbnN0IHRvUmV2b2tlID0gW107XG4gICAgICBpZiAoYWNjZXNzX3Rva2VuKSB7XG4gICAgICAgIHRvUmV2b2tlLnB1c2goe1xuICAgICAgICAgIC4uLmNsaWVudElkICYmIHtjbGllbnRfaWQ6IGNsaWVudElkfSB8fCB7fSxcbiAgICAgICAgICAuLi5jbGllbnRTZWNyZXQgJiYge2NsaWVudF9zZWNyZXQ6IGNsaWVudFNlY3JldH0gfHwge30sXG4gICAgICAgICAgdG9rZW46IGFjY2Vzc190b2tlbixcbiAgICAgICAgICB0b2tlbl90eXBlX2hpbnQ6ICdhY2Nlc3NfdG9rZW4nXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgaWYgKHJlZnJlc2hfdG9rZW4pIHtcbiAgICAgICAgdG9SZXZva2UucHVzaCh7XG4gICAgICAgICAgLi4uY2xpZW50SWQgJiYge2NsaWVudF9pZDogY2xpZW50SWR9IHx8IHt9LFxuICAgICAgICAgIC4uLmNsaWVudFNlY3JldCAmJiB7Y2xpZW50X3NlY3JldDogY2xpZW50U2VjcmV0fSB8fCB7fSxcbiAgICAgICAgICB0b2tlbjogcmVmcmVzaF90b2tlbixcbiAgICAgICAgICB0b2tlbl90eXBlX2hpbnQ6ICdyZWZyZXNoX3Rva2VuJ1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGZyb20odG9SZXZva2UpLnBpcGUoXG4gICAgICAgIGNvbmNhdE1hcChvID0+IG9mKG8pLnBpcGUoZGVsYXkoMzAwKSkpLCAvLyBzcGFjZSByZXF1ZXN0IHRvIGF2b2lkIGNhbmNlbGxhdGlvblxuICAgICAgICBzd2l0Y2hNYXAobyA9PiB0aGlzLmh0dHAucG9zdChyZXZva2VQYXRoLCBuZXcgSHR0cFBhcmFtcyh7ZnJvbU9iamVjdDogb30pKSksXG4gICAgICApLnN1YnNjcmliZShub29wKTtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgY2xpZW50Q3JlZGVudGlhbExvZ2luKCkge1xuICAgIGNvbnN0IHtjbGllbnRJZCwgY2xpZW50U2VjcmV0LCB0b2tlblBhdGgsIHNjb3BlfSA9IHRoaXMuYXV0aENvbmZpZy5jb25maWcgYXMgYW55O1xuICAgIHJldHVybiBmaXJzdFZhbHVlRnJvbSh0aGlzLmh0dHAucG9zdCh0b2tlblBhdGgsIG5ldyBIdHRwUGFyYW1zKHtcbiAgICAgIGZyb21PYmplY3Q6IHtcbiAgICAgICAgY2xpZW50X2lkOiBjbGllbnRJZCxcbiAgICAgICAgY2xpZW50X3NlY3JldDogY2xpZW50U2VjcmV0LFxuICAgICAgICBncmFudF90eXBlOiBPQXV0aFR5cGUuQ0xJRU5UX0NSRURFTlRJQUwsXG4gICAgICAgIC4uLnNjb3BlID8ge3Njb3BlfSA6IHt9LFxuICAgICAgfVxuICAgIH0pLCB7aGVhZGVyczogSEVBREVSX0FQUExJQ0FUSU9OfSkucGlwZShcbiAgICAgIGNhdGNoRXJyb3IoKGVycikgPT4ge1xuICAgICAgICB0aGlzLnRva2VuID0gZXJyO1xuICAgICAgICByZXR1cm4gdGhyb3dFcnJvcigoKSA9PiBlcnIpO1xuICAgICAgfSksXG4gICAgICB0YXAocGFyYW1zID0+IHtcbiAgICAgICAgdGhpcy50b2tlbiA9IHtcbiAgICAgICAgICAuLi5wYXJhbXMsXG4gICAgICAgICAgdHlwZTogT0F1dGhUeXBlLkNMSUVOVF9DUkVERU5USUFMLFxuICAgICAgICB9O1xuICAgICAgfSksXG4gICAgKSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgcmVzb3VyY2VMb2dpbihwYXJhbWV0ZXJzOiBSZXNvdXJjZVBhcmFtZXRlcnMpIHtcbiAgICBjb25zdCB7Y2xpZW50SWQsIGNsaWVudFNlY3JldCwgdG9rZW5QYXRoLCBzY29wZX0gPSB0aGlzLmF1dGhDb25maWcuY29uZmlnIGFzIGFueTtcbiAgICBjb25zdCB7dXNlcm5hbWUsIHBhc3N3b3JkfSA9IHBhcmFtZXRlcnM7XG4gICAgcmV0dXJuIGZpcnN0VmFsdWVGcm9tKHRoaXMuaHR0cC5wb3N0KHRva2VuUGF0aCwgbmV3IEh0dHBQYXJhbXMoe1xuICAgICAgZnJvbU9iamVjdDoge1xuICAgICAgICBjbGllbnRfaWQ6IGNsaWVudElkLFxuICAgICAgICAuLi5jbGllbnRTZWNyZXQgJiYge2NsaWVudF9zZWNyZXQ6IGNsaWVudFNlY3JldH0gfHwge30sXG4gICAgICAgIGdyYW50X3R5cGU6IE9BdXRoVHlwZS5SRVNPVVJDRSxcbiAgICAgICAgLi4uc2NvcGUgJiYge3Njb3BlfSB8fCB7fSxcbiAgICAgICAgdXNlcm5hbWUsXG4gICAgICAgIHBhc3N3b3JkXG4gICAgICB9XG4gICAgfSksIHtoZWFkZXJzOiBIRUFERVJfQVBQTElDQVRJT059KS5waXBlKFxuICAgICAgY2F0Y2hFcnJvcihlcnIgPT4ge1xuICAgICAgICB0aGlzLnRva2VuID0gZXJyO1xuICAgICAgICByZXR1cm4gdGhyb3dFcnJvcigoKSA9PiBlcnIpO1xuICAgICAgfSksXG4gICAgICB0YXAocGFyYW1zID0+IHtcbiAgICAgICAgdGhpcy50b2tlbiA9IHtcbiAgICAgICAgICAuLi5wYXJhbXMsXG4gICAgICAgICAgdHlwZTogT0F1dGhUeXBlLlJFU09VUkNFLFxuICAgICAgICB9O1xuICAgICAgfSlcbiAgICApKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyB0b0F1dGhvcml6YXRpb25VcmwocGFyYW1ldGVyczogQXV0aG9yaXphdGlvblBhcmFtZXRlcnMpIHtcbiAgICBjb25zdCB7Y29uZmlnfSA9IHRoaXMuYXV0aENvbmZpZyBhcyBhbnk7XG4gICAgbGV0IGF1dGhvcml6YXRpb25VcmwgPSBgJHtjb25maWcuYXV0aG9yaXplUGF0aH1gO1xuICAgIGF1dGhvcml6YXRpb25VcmwgKz0gY29uZmlnLmF1dGhvcml6ZVBhdGguaW5jbHVkZXMoJz8nKSAmJiAnJicgfHwgJz8nO1xuICAgIGF1dGhvcml6YXRpb25VcmwgKz0gYGNsaWVudF9pZD0ke2NvbmZpZy5jbGllbnRJZH1gO1xuICAgIGF1dGhvcml6YXRpb25VcmwgKz0gYCZyZWRpcmVjdF91cmk9JHtlbmNvZGVVUklDb21wb25lbnQocGFyYW1ldGVycy5yZWRpcmVjdFVyaSl9YDtcbiAgICBhdXRob3JpemF0aW9uVXJsICs9IGAmcmVzcG9uc2VfdHlwZT0ke3BhcmFtZXRlcnMucmVzcG9uc2VUeXBlfWA7XG4gICAgYXV0aG9yaXphdGlvblVybCArPSBgJnNjb3BlPSR7ZW5jb2RlVVJJQ29tcG9uZW50KGNvbmZpZy5zY29wZSB8fCAnJyl9YDtcbiAgICBhdXRob3JpemF0aW9uVXJsICs9IGAmc3RhdGU9JHtlbmNvZGVVUklDb21wb25lbnQocGFyYW1ldGVycy5zdGF0ZSB8fCAnJyl9YDtcbiAgICByZXR1cm4gdGhpcy5sb2NhdGlvbi5yZXBsYWNlKGAke2F1dGhvcml6YXRpb25Vcmx9JHt0aGlzLmdlbmVyYXRlTm9uY2UoY29uZmlnKX0ke2F3YWl0IHRoaXMuZ2VuZXJhdGVDb2RlQ2hhbGxlbmdlKGNvbmZpZyl9YCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgZ2VuZXJhdGVDb2RlQ2hhbGxlbmdlKGNvbmZpZzogYW55KSB7XG4gICAgaWYgKGNvbmZpZy5wa2NlKSB7XG4gICAgICBjb25zdCBjb2RlVmVyaWZpZXIgPSByYW5kb21TdHJpbmcoKTtcbiAgICAgIHRoaXMudG9rZW4gPSB7Li4udGhpcy50b2tlbiwgY29kZVZlcmlmaWVyfTtcbiAgICAgIHJldHVybiBgJmNvZGVfY2hhbGxlbmdlPSR7YXdhaXQgcGtjZShjb2RlVmVyaWZpZXIpfSZjb2RlX2NoYWxsZW5nZV9tZXRob2Q9UzI1NmA7XG4gICAgfVxuICAgIHJldHVybiAnJztcbiAgfVxuXG4gIHByb3RlY3RlZCBnZW5lcmF0ZU5vbmNlKGNvbmZpZzogYW55KSB7XG4gICAgaWYgKGNvbmZpZyAmJiBjb25maWcuc2NvcGUgJiYgY29uZmlnLnNjb3BlLmluZGV4T2YoJ29wZW5pZCcpID4gLTEpIHtcbiAgICAgIGNvbnN0IG5vbmNlID0gcmFuZG9tU3RyaW5nKDEwKTtcbiAgICAgIHRoaXMudG9rZW4gPSB7Li4udGhpcy50b2tlbiwgbm9uY2V9O1xuICAgICAgcmV0dXJuIGAmbm9uY2U9JHtub25jZX1gO1xuICAgIH1cbiAgICByZXR1cm4gJyc7XG4gIH1cblxuICBwcml2YXRlIGNoZWNrUmVzcG9uc2UodG9rZW4/OiBPQXV0aFRva2VuLFxuICAgICAgICAgICAgICAgICAgICAgICAgcGFyYW1ldGVycz86IFJlY29yZDxzdHJpbmcsIHN0cmluZz4pIHtcbiAgICB0aGlzLmVtaXRTdGF0ZShwYXJhbWV0ZXJzKTtcbiAgICB0aGlzLmNsZWFuTG9jYXRpb25IYXNoKCk7XG4gICAgaWYgKCFwYXJhbWV0ZXJzIHx8IHBhcmFtZXRlcnNbJ2Vycm9yJ10pIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKHRva2VuICYmIHRva2VuLm5vbmNlICYmIHBhcmFtZXRlcnNbJ2FjY2Vzc190b2tlbiddKSB7XG4gICAgICBjb25zdCBqd3RUb2tlbiA9IGp3dChwYXJhbWV0ZXJzWydhY2Nlc3NfdG9rZW4nXSk7XG4gICAgICByZXR1cm4gdG9rZW4ubm9uY2UgPT09IGp3dFRva2VuLm5vbmNlO1xuICAgIH1cbiAgICByZXR1cm4gcGFyYW1ldGVyc1snYWNjZXNzX3Rva2VuJ10gfHwgcGFyYW1ldGVyc1snY29kZSddO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRDbGVhbmVkVW5TZWFyY2hQYXJhbWV0ZXJzKCkge1xuICAgIGNvbnN0IHtzZWFyY2h9ID0gdGhpcy5sb2NhdGlvbjtcbiAgICBsZXQgc2VhcmNoU3RyaW5nID0gc2VhcmNoICYmIHNlYXJjaC5zdWJzdHJpbmcoMSkgfHwgJyc7XG4gICAgY29uc3QgaGFzaEtleXMgPSBbJ2NvZGUnLCAnc3RhdGUnLCAnZXJyb3InLCAnZXJyb3JfZGVzY3JpcHRpb24nLCAnc2Vzc2lvbl9zdGF0ZScsICdzY29wZScsICdhdXRodXNlcicsICdwcm9tcHQnXTtcbiAgICBoYXNoS2V5cy5mb3JFYWNoKGhhc2hLZXkgPT4ge1xuICAgICAgY29uc3QgcmUgPSBuZXcgUmVnRXhwKCcmJyArIGhhc2hLZXkgKyAnKD1bXiZdKik/fF4nICsgaGFzaEtleSArICcoPVteJl0qKT8mPycpO1xuICAgICAgc2VhcmNoU3RyaW5nID0gc2VhcmNoU3RyaW5nLnJlcGxhY2UocmUsICcnKTtcbiAgICB9KTtcbiAgICByZXR1cm4gc2VhcmNoU3RyaW5nLmxlbmd0aCAmJiBgPyR7c2VhcmNoU3RyaW5nfWAgfHwgJyc7XG4gIH1cblxuICBwcml2YXRlIGNsZWFuTG9jYXRpb25IYXNoKCkge1xuICAgIGNvbnN0IHtoYXNofSA9IHRoaXMubG9jYXRpb247XG4gICAgbGV0IGN1ckhhc2ggPSBoYXNoICYmIGhhc2guc3Vic3RyaW5nKDEpIHx8ICcnO1xuICAgIGNvbnN0IGhhc2hLZXlzID0gW1xuICAgICAgJ2FjY2Vzc190b2tlbicsXG4gICAgICAndG9rZW5fdHlwZScsXG4gICAgICAnZXhwaXJlc19pbicsXG4gICAgICAnc2NvcGUnLFxuICAgICAgJ3N0YXRlJyxcbiAgICAgICdlcnJvcicsXG4gICAgICAnZXJyb3JfZGVzY3JpcHRpb24nLFxuICAgICAgJ3Nlc3Npb25fc3RhdGUnLFxuICAgICAgJ25vbmNlJyxcbiAgICAgICdpZF90b2tlbicsXG4gICAgICAnY29kZSdcbiAgICBdO1xuICAgIGhhc2hLZXlzLmZvckVhY2goaGFzaEtleSA9PiB7XG4gICAgICBjb25zdCByZSA9IG5ldyBSZWdFeHAoJyYnICsgaGFzaEtleSArICcoPVteJl0qKT98XicgKyBoYXNoS2V5ICsgJyg9W14mXSopPyY/Jyk7XG4gICAgICBjdXJIYXNoID0gY3VySGFzaC5yZXBsYWNlKHJlLCAnJyk7XG4gICAgfSk7XG4gICAgdGhpcy5sb2NhdGlvbi5oYXNoID0gY3VySGFzaDtcbiAgfVxuXG4gIHByaXZhdGUgZW1pdFN0YXRlKHBhcmFtZXRlcnM/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+KSB7XG4gICAgY29uc3Qge3N0YXRlfSA9IHBhcmFtZXRlcnMgfHwge307XG4gICAgc3RhdGUgJiYgdGhpcy5zdGF0ZSQubmV4dChzdGF0ZSk7XG4gIH1cbn1cbiJdfQ==
@@ -1,83 +0,0 @@
1
- var _TokenService_token$;
2
- import { __classPrivateFieldGet } from "tslib";
3
- import { Inject, Injectable } from '@angular/core';
4
- import { BehaviorSubject, distinctUntilChanged, of, switchMap } from 'rxjs';
5
- import { HEADER_APPLICATION, OAUTH_HTTP_CLIENT } from '../models';
6
- import { catchError, map, shareReplay } from 'rxjs/operators';
7
- import { HttpParams } from '@angular/common/http';
8
- import * as i0 from "@angular/core";
9
- import * as i1 from "../models";
10
- import * as i2 from "@angular/common/http";
11
- const isExpiredToken = (token) => token && token.expires && Date.now() > token.expires || false;
12
- export class TokenService {
13
- constructor(authConfig, http, zone) {
14
- this.authConfig = authConfig;
15
- this.http = http;
16
- this.zone = zone;
17
- _TokenService_token$.set(this, new BehaviorSubject(this.saved));
18
- this.token$ = __classPrivateFieldGet(this, _TokenService_token$, "f").pipe(distinctUntilChanged((p, c) => JSON.stringify(p || null) === JSON.stringify(c || null)), shareReplay(1), switchMap(token => !isExpiredToken(token) && of(token) || this.refreshToken(token)));
19
- this.type$ = this.token$.pipe(map(token => token?.type), shareReplay(1));
20
- this.accessToken$ = this.token$.pipe(map(token => token?.access_token), shareReplay(1));
21
- }
22
- get token() {
23
- return __classPrivateFieldGet(this, _TokenService_token$, "f").value;
24
- }
25
- set token(token) {
26
- const expiresIn = Number(token.expires_in) || 0;
27
- const result = {
28
- ...token,
29
- ...expiresIn && { expires: Date.now() + expiresIn * 1000 } || {}
30
- };
31
- this.saved = result;
32
- __classPrivateFieldGet(this, _TokenService_token$, "f").next(result);
33
- }
34
- get saved() {
35
- const { storageKey, storage } = this.authConfig;
36
- return storageKey && storage && storage[storageKey] && JSON.parse(storage[storageKey]) || {};
37
- }
38
- set saved(token) {
39
- const { storageKey, storage } = this.authConfig;
40
- if (storage && storageKey) {
41
- if (token) {
42
- storage[storageKey] = JSON.stringify(token);
43
- }
44
- else {
45
- delete storage[storageKey];
46
- }
47
- }
48
- }
49
- refreshToken(token) {
50
- const { tokenPath, clientId, clientSecret, scope } = this.authConfig.config;
51
- const { refresh_token } = token || {};
52
- return tokenPath && refresh_token && this.http.post(tokenPath, new HttpParams({
53
- fromObject: {
54
- client_id: clientId,
55
- ...clientSecret && { client_secret: clientSecret } || {},
56
- grant_type: 'refresh_token',
57
- refresh_token,
58
- ...scope && { scope } || {},
59
- }
60
- }), {
61
- headers: HEADER_APPLICATION
62
- }).pipe(catchError(() => {
63
- this.token = {};
64
- return of(this.token);
65
- }), map(token => {
66
- this.token = {
67
- ...this.token,
68
- ...token
69
- };
70
- return this.token;
71
- })) || of(token);
72
- }
73
- }
74
- _TokenService_token$ = new WeakMap();
75
- TokenService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.3", ngImport: i0, type: TokenService, deps: [{ token: i1.OAuthConfig }, { token: OAUTH_HTTP_CLIENT }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable });
76
- TokenService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.3", ngImport: i0, type: TokenService });
77
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.3", ngImport: i0, type: TokenService, decorators: [{
78
- type: Injectable
79
- }], ctorParameters: function () { return [{ type: i1.OAuthConfig }, { type: i2.HttpClient, decorators: [{
80
- type: Inject,
81
- args: [OAUTH_HTTP_CLIENT]
82
- }] }, { type: i0.NgZone }]; } });
83
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9rZW4uc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1vYXV0aC9zcmMvbGliL3NlcnZpY2VzL3Rva2VuLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSxPQUFPLEVBQUMsTUFBTSxFQUFFLFVBQVUsRUFBUyxNQUFNLGVBQWUsQ0FBQztBQUN6RCxPQUFPLEVBQUMsZUFBZSxFQUFFLG9CQUFvQixFQUFjLEVBQUUsRUFBRSxTQUFTLEVBQUMsTUFBTSxNQUFNLENBQUM7QUFDdEYsT0FBTyxFQUFDLGtCQUFrQixFQUFFLGlCQUFpQixFQUEwQixNQUFNLFdBQVcsQ0FBQztBQUN6RixPQUFPLEVBQUMsVUFBVSxFQUFFLEdBQUcsRUFBRSxXQUFXLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQztBQUM1RCxPQUFPLEVBQWEsVUFBVSxFQUFDLE1BQU0sc0JBQXNCLENBQUM7Ozs7QUFFNUQsTUFBTSxjQUFjLEdBQUcsQ0FBQyxLQUFrQixFQUFFLEVBQUUsQ0FBQyxLQUFLLElBQUksS0FBSyxDQUFDLE9BQU8sSUFBSSxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsS0FBSyxDQUFDLE9BQU8sSUFBSSxLQUFLLENBQUM7QUFHN0csTUFBTSxPQUFPLFlBQVk7SUFpQnZCLFlBQXNCLFVBQXVCLEVBQ0ksSUFBZ0IsRUFDM0MsSUFBWTtRQUZaLGVBQVUsR0FBVixVQUFVLENBQWE7UUFDSSxTQUFJLEdBQUosSUFBSSxDQUFZO1FBQzNDLFNBQUksR0FBSixJQUFJLENBQVE7UUFqQmxDLCtCQUFVLElBQUksZUFBZSxDQUFhLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBQztRQUN0RCxXQUFNLEdBQUcsdUJBQUEsSUFBSSw0QkFBUSxDQUFDLElBQUksQ0FDeEIsb0JBQW9CLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsSUFBSSxJ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Q0FBQyxFQUFFO1lBQ0YsT0FBTyxFQUFFLGtCQUFrQjtTQUM1QixDQUFDLENBQUMsSUFBSSxDQUNMLFVBQVUsQ0FBQyxHQUFHLEVBQUU7WUFDZCxJQUFJLENBQUMsS0FBSyxHQUFHLEVBQUUsQ0FBQztZQUNoQixPQUFPLEVBQUUsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDeEIsQ0FBQyxDQUFDLEVBQ0YsR0FBRyxDQUFDLEtBQUssQ0FBQyxFQUFFO1lBQ1YsSUFBSSxDQUFDLEtBQUssR0FBRztnQkFDWCxHQUFHLElBQUksQ0FBQyxLQUFLO2dCQUNiLEdBQUcsS0FBSzthQUNULENBQUM7WUFDRixPQUFPLElBQUksQ0FBQyxLQUFLLENBQUM7UUFDcEIsQ0FBQyxDQUFDLENBQ0gsSUFBSSxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDakIsQ0FBQzs7O3lHQTlFVSxZQUFZLDZDQWtCSCxpQkFBaUI7NkdBbEIxQixZQUFZOzJGQUFaLFlBQVk7a0JBRHhCLFVBQVU7OzBCQW1CSSxNQUFNOzJCQUFDLGlCQUFpQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7SW5qZWN0LCBJbmplY3RhYmxlLCBOZ1pvbmV9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtCZWhhdmlvclN1YmplY3QsIGRpc3RpbmN0VW50aWxDaGFuZ2VkLCBPYnNlcnZhYmxlLCBvZiwgc3dpdGNoTWFwfSBmcm9tICdyeGpzJztcbmltcG9ydCB7SEVBREVSX0FQUExJQ0FUSU9OLCBPQVVUSF9IVFRQX0NMSUVOVCwgT0F1dGhDb25maWcsIE9BdXRoVG9rZW59IGZyb20gJy4uL21vZGVscyc7XG5pbXBvcnQge2NhdGNoRXJyb3IsIG1hcCwgc2hhcmVSZXBsYXl9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7SHR0cENsaWVudCwgSHR0cFBhcmFtc30gZnJvbSAnQGFuZ3VsYXIvY29tbW9uL2h0dHAnO1xuXG5jb25zdCBpc0V4cGlyZWRUb2tlbiA9ICh0b2tlbj86IE9BdXRoVG9rZW4pID0+IHRva2VuICYmIHRva2VuLmV4cGlyZXMgJiYgRGF0ZS5ub3coKSA+IHRva2VuLmV4cGlyZXMgfHwgZmFsc2U7XG5cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBUb2tlblNlcnZpY2Uge1xuXG4gICN0b2tlbiQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PE9BdXRoVG9rZW4+KHRoaXMuc2F2ZWQpO1xuICB0b2tlbiQgPSB0aGlzLiN0b2tlbiQucGlwZShcbiAgICBkaXN0aW5jdFVudGlsQ2hhbmdlZCgocCwgYykgPT4gSlNPTi5zdHJpbmdpZnkocCB8fCBudWxsKSA9PT0gSlNPTi5zdHJpbmdpZnkoYyB8fCBudWxsKSksXG4gICAgc2hhcmVSZXBsYXkoMSksXG4gICAgc3dpdGNoTWFwKHRva2VuID0+ICFpc0V4cGlyZWRUb2tlbih0b2tlbikgJiYgb2YodG9rZW4pIHx8IHRoaXMucmVmcmVzaFRva2VuKHRva2VuKSksXG4gICk7XG4gIHR5cGUkID0gdGhpcy50b2tlbiQucGlwZShcbiAgICBtYXAodG9rZW4gPT4gdG9rZW4/LnR5cGUpLFxuICAgIHNoYXJlUmVwbGF5KDEpXG4gICk7XG4gIGFjY2Vzc1Rva2VuJCA9IHRoaXMudG9rZW4kLnBpcGUoXG4gICAgbWFwKHRva2VuID0+IHRva2VuPy5hY2Nlc3NfdG9rZW4pLFxuICAgIHNoYXJlUmVwbGF5KDEpLFxuICApO1xuXG4gIGNvbnN0cnVjdG9yKHByb3RlY3RlZCBhdXRoQ29uZmlnOiBPQXV0aENvbmZpZyxcbiAgICAgICAgICAgICAgQEluamVjdChPQVVUSF9IVFRQX0NMSUVOVCkgcHJvdGVjdGVkIGh0dHA6IEh0dHBDbGllbnQsXG4gICAgICAgICAgICAgIHByb3RlY3RlZCB6b25lOiBOZ1pvbmUpIHtcbiAgfVxuXG4gIGdldCB0b2tlbigpIHtcbiAgICByZXR1cm4gdGhpcy4jdG9rZW4kLnZhbHVlO1xuICB9XG5cbiAgc2V0IHRva2VuKHRva2VuKSB7XG4gICAgY29uc3QgZXhwaXJlc0luID0gTnVtYmVyKHRva2VuLmV4cGlyZXNfaW4pIHx8IDA7XG4gICAgY29uc3QgcmVzdWx0ID0ge1xuICAgICAgLi4udG9rZW4sXG4gICAgICAuLi5leHBpcmVzSW4gJiYge2V4cGlyZXM6IERhdGUubm93KCkgKyBleHBpcmVzSW4gKiAxMDAwfSB8fCB7fVxuICAgIH07XG4gICAgdGhpcy5zYXZlZCA9IHJlc3VsdDtcbiAgICB0aGlzLiN0b2tlbiQubmV4dChyZXN1bHQpO1xuICB9XG5cbiAgZ2V0IHNhdmVkKCkge1xuICAgIGNvbnN0IHtzdG9yYWdlS2V5LCBzdG9yYWdlfSA9IHRoaXMuYXV0aENvbmZpZztcbiAgICByZXR1cm4gc3RvcmFnZUtleSAmJiBzdG9yYWdlICYmIHN0b3JhZ2Vbc3RvcmFnZUtleV0gJiYgSlNPTi5wYXJzZShzdG9yYWdlW3N0b3JhZ2VLZXldKSB8fCB7fTtcbiAgfVxuXG4gIHNldCBzYXZlZCh0b2tlbjogT0F1dGhUb2tlbikge1xuICAgIGNvbnN0IHtzdG9yYWdlS2V5LCBzdG9yYWdlfSA9IHRoaXMuYXV0aENvbmZpZztcbiAgICBpZiAoc3RvcmFnZSAmJiBzdG9yYWdlS2V5KSB7XG4gICAgICBpZiAodG9rZW4pIHtcbiAgICAgICAgc3RvcmFnZVtzdG9yYWdlS2V5XSA9IEpTT04uc3RyaW5naWZ5KHRva2VuKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRlbGV0ZSBzdG9yYWdlW3N0b3JhZ2VLZXldO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCByZWZyZXNoVG9rZW4odG9rZW4/OiBPQXV0aFRva2VuKTogT2JzZXJ2YWJsZTxPQXV0aFRva2VuPiB7XG4gICAgY29uc3Qge3Rva2VuUGF0aCwgY2xpZW50SWQsIGNsaWVudFNlY3JldCwgc2NvcGV9ID0gdGhpcy5hdXRoQ29uZmlnLmNvbmZpZyBhcyBhbnk7XG4gICAgY29uc3Qge3JlZnJlc2hfdG9rZW59ID0gdG9rZW4gfHwge307XG4gICAgcmV0dXJuIHRva2VuUGF0aCAmJiByZWZyZXNoX3Rva2VuICYmIHRoaXMuaHR0cC5wb3N0PE9BdXRoVG9rZW4+KHRva2VuUGF0aCwgbmV3IEh0dHBQYXJhbXMoe1xuICAgICAgZnJvbU9iamVjdDoge1xuICAgICAgICBjbGllbnRfaWQ6IGNsaWVudElkLFxuICAgICAgICAuLi5jbGllbnRTZWNyZXQgJiYge2NsaWVudF9zZWNyZXQ6IGNsaWVudFNlY3JldH0gfHwge30sXG4gICAgICAgIGdyYW50X3R5cGU6ICdyZWZyZXNoX3Rva2VuJyxcbiAgICAgICAgcmVmcmVzaF90b2tlbixcbiAgICAgICAgLi4uc2NvcGUgJiYge3Njb3BlfSB8fCB7fSxcbiAgICAgIH1cbiAgICB9KSwge1xuICAgICAgaGVhZGVyczogSEVBREVSX0FQUExJQ0FUSU9OXG4gICAgfSkucGlwZShcbiAgICAgIGNhdGNoRXJyb3IoKCkgPT4ge1xuICAgICAgICB0aGlzLnRva2VuID0ge307XG4gICAgICAgIHJldHVybiBvZih0aGlzLnRva2VuKTtcbiAgICAgIH0pLFxuICAgICAgbWFwKHRva2VuID0+IHtcbiAgICAgICAgdGhpcy50b2tlbiA9IHtcbiAgICAgICAgICAuLi50aGlzLnRva2VuLFxuICAgICAgICAgIC4uLnRva2VuXG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiB0aGlzLnRva2VuO1xuICAgICAgfSlcbiAgICApIHx8IG9mKHRva2VuKTtcbiAgfVxufVxuIl19