1 | /**
|
2 | * @license
|
3 | * Copyright Akveo. All Rights Reserved.
|
4 | * Licensed under the MIT License. See License.txt in the project root for license information.
|
5 | */
|
6 | import { Inject, Injectable } from '@angular/core';
|
7 | import { of as observableOf } from 'rxjs';
|
8 | import { switchMap, map } from 'rxjs/operators';
|
9 | import { NB_AUTH_STRATEGIES } from '../auth.options';
|
10 | import * as i0 from "@angular/core";
|
11 | import * as i1 from "./token/token.service";
|
12 | /**
|
13 | * Common authentication service.
|
14 | * Should be used to as an interlayer between UI Components and Auth Strategy.
|
15 | */
|
16 | export class NbAuthService {
|
17 | constructor(tokenService, strategies) {
|
18 | this.tokenService = tokenService;
|
19 | this.strategies = strategies;
|
20 | }
|
21 | /**
|
22 | * Retrieves current authenticated token stored
|
23 | * @returns {Observable<any>}
|
24 | */
|
25 | getToken() {
|
26 | return this.tokenService.get();
|
27 | }
|
28 | /**
|
29 | * Returns true if auth token is present in the token storage
|
30 | * @returns {Observable<boolean>}
|
31 | */
|
32 | isAuthenticated() {
|
33 | return this.getToken()
|
34 | .pipe(map((token) => token.isValid()));
|
35 | }
|
36 | /**
|
37 | * Returns true if valid auth token is present in the token storage.
|
38 | * If not, calls the strategy refreshToken, and returns isAuthenticated() if success, false otherwise
|
39 | * @returns {Observable<boolean>}
|
40 | */
|
41 | isAuthenticatedOrRefresh() {
|
42 | return this.getToken()
|
43 | .pipe(switchMap(token => {
|
44 | if (token.getValue() && !token.isValid()) {
|
45 | return this.refreshToken(token.getOwnerStrategyName(), token)
|
46 | .pipe(switchMap(res => {
|
47 | if (res.isSuccess()) {
|
48 | return this.isAuthenticated();
|
49 | }
|
50 | else {
|
51 | return observableOf(false);
|
52 | }
|
53 | }));
|
54 | }
|
55 | else {
|
56 | return observableOf(token.isValid());
|
57 | }
|
58 | }));
|
59 | }
|
60 | /**
|
61 | * Returns tokens stream
|
62 | * @returns {Observable<NbAuthSimpleToken>}
|
63 | */
|
64 | onTokenChange() {
|
65 | return this.tokenService.tokenChange();
|
66 | }
|
67 | /**
|
68 | * Returns authentication status stream
|
69 | * @returns {Observable<boolean>}
|
70 | */
|
71 | onAuthenticationChange() {
|
72 | return this.onTokenChange()
|
73 | .pipe(map((token) => token.isValid()));
|
74 | }
|
75 | /**
|
76 | * Authenticates with the selected strategy
|
77 | * Stores received token in the token storage
|
78 | *
|
79 | * Example:
|
80 | * authenticate('email', {email: 'email@example.com', password: 'test'})
|
81 | *
|
82 | * @param strategyName
|
83 | * @param data
|
84 | * @returns {Observable<NbAuthResult>}
|
85 | */
|
86 | authenticate(strategyName, data) {
|
87 | return this.getStrategy(strategyName).authenticate(data)
|
88 | .pipe(switchMap((result) => {
|
89 | return this.processResultToken(result);
|
90 | }));
|
91 | }
|
92 | /**
|
93 | * Registers with the selected strategy
|
94 | * Stores received token in the token storage
|
95 | *
|
96 | * Example:
|
97 | * register('email', {email: 'email@example.com', name: 'Some Name', password: 'test'})
|
98 | *
|
99 | * @param strategyName
|
100 | * @param data
|
101 | * @returns {Observable<NbAuthResult>}
|
102 | */
|
103 | register(strategyName, data) {
|
104 | return this.getStrategy(strategyName).register(data)
|
105 | .pipe(switchMap((result) => {
|
106 | return this.processResultToken(result);
|
107 | }));
|
108 | }
|
109 | /**
|
110 | * Sign outs with the selected strategy
|
111 | * Removes token from the token storage
|
112 | *
|
113 | * Example:
|
114 | * logout('email')
|
115 | *
|
116 | * @param strategyName
|
117 | * @returns {Observable<NbAuthResult>}
|
118 | */
|
119 | logout(strategyName) {
|
120 | return this.getStrategy(strategyName).logout()
|
121 | .pipe(switchMap((result) => {
|
122 | if (result.isSuccess()) {
|
123 | this.tokenService.clear()
|
124 | .pipe(map(() => result));
|
125 | }
|
126 | return observableOf(result);
|
127 | }));
|
128 | }
|
129 | /**
|
130 | * Sends forgot password request to the selected strategy
|
131 | *
|
132 | * Example:
|
133 | * requestPassword('email', {email: 'email@example.com'})
|
134 | *
|
135 | * @param strategyName
|
136 | * @param data
|
137 | * @returns {Observable<NbAuthResult>}
|
138 | */
|
139 | requestPassword(strategyName, data) {
|
140 | return this.getStrategy(strategyName).requestPassword(data);
|
141 | }
|
142 | /**
|
143 | * Tries to reset password with the selected strategy
|
144 | *
|
145 | * Example:
|
146 | * resetPassword('email', {newPassword: 'test'})
|
147 | *
|
148 | * @param strategyName
|
149 | * @param data
|
150 | * @returns {Observable<NbAuthResult>}
|
151 | */
|
152 | resetPassword(strategyName, data) {
|
153 | return this.getStrategy(strategyName).resetPassword(data);
|
154 | }
|
155 | /**
|
156 | * Sends a refresh token request
|
157 | * Stores received token in the token storage
|
158 | *
|
159 | * Example:
|
160 | * refreshToken('email', {token: token})
|
161 | *
|
162 | * @param {string} strategyName
|
163 | * @param data
|
164 | * @returns {Observable<NbAuthResult>}
|
165 | */
|
166 | refreshToken(strategyName, data) {
|
167 | return this.getStrategy(strategyName).refreshToken(data)
|
168 | .pipe(switchMap((result) => {
|
169 | return this.processResultToken(result);
|
170 | }));
|
171 | }
|
172 | /**
|
173 | * Get registered strategy by name
|
174 | *
|
175 | * Example:
|
176 | * getStrategy('email')
|
177 | *
|
178 | * @param {string} provider
|
179 | * @returns {NbAbstractAuthProvider}
|
180 | */
|
181 | getStrategy(strategyName) {
|
182 | const found = this.strategies.find((strategy) => strategy.getName() === strategyName);
|
183 | if (!found) {
|
184 | throw new TypeError(`There is no Auth Strategy registered under '${strategyName}' name`);
|
185 | }
|
186 | return found;
|
187 | }
|
188 | processResultToken(result) {
|
189 | if (result.isSuccess() && result.getToken()) {
|
190 | return this.tokenService.set(result.getToken())
|
191 | .pipe(map((token) => {
|
192 | return result;
|
193 | }));
|
194 | }
|
195 | return observableOf(result);
|
196 | }
|
197 | }
|
198 | NbAuthService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: NbAuthService, deps: [{ token: i1.NbTokenService }, { token: NB_AUTH_STRATEGIES }], target: i0.ɵɵFactoryTarget.Injectable });
|
199 | NbAuthService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: NbAuthService });
|
200 | i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: NbAuthService, decorators: [{
|
201 | type: Injectable
|
202 | }], ctorParameters: function () { return [{ type: i1.NbTokenService }, { type: undefined, decorators: [{
|
203 | type: Inject,
|
204 | args: [NB_AUTH_STRATEGIES]
|
205 | }] }]; } });
|
206 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXV0aC5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2ZyYW1ld29yay9hdXRoL3NlcnZpY2VzL2F1dGguc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7OztHQUlHO0FBQ0gsT0FBTyxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFbkQsT0FBTyxFQUFjLEVBQUUsSUFBSSxZQUFZLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDdEQsT0FBTyxFQUFFLFNBQVMsRUFBRSxHQUFHLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUdoRCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQzs7O0FBS3JEOzs7R0FHRztBQUVILE1BQU0sT0FBTyxhQUFhO0lBRXhCLFlBQXNCLFlBQTRCLEVBQ0EsVUFBVTtRQUR0QyxpQkFBWSxHQUFaLFlBQVksQ0FBZ0I7UUFDQSxlQUFVLEdBQVYsVUFBVSxDQUFBO0lBQzVELENBQUM7SUFFRDs7O09BR0c7SUFDSCxRQUFRO1FBQ04sT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLEdBQUcsRUFBRSxDQUFDO0lBQ2pDLENBQUM7SUFFRDs7O09BR0c7SUFDSCxlQUFlO1FBQ2IsT0FBTyxJQUFJLENBQUMsUUFBUSxFQUFFO2FBQ25CLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFrQixFQUFFLEVBQUUsQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ3hELENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsd0JBQXdCO1FBQ3RCLE9BQU8sSUFBSSxDQUFDLFFBQVEsRUFBRTthQUNuQixJQUFJLENBQ0gsU0FBUyxDQUFDLEtBQUssQ0FBQyxFQUFFO1lBQ2xCLElBQUksS0FBSyxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxFQUFFO2dCQUN4QyxPQUFPLElBQUksQ0FBQyxZ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QUM7YUFDckQsSUFBSSxDQUNILFNBQVMsQ0FBQyxDQUFDLE1BQW9CLEVBQUUsRUFBRTtZQUNqQyxPQUFPLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUN6QyxDQUFDLENBQUMsQ0FDSCxDQUFDO0lBQ04sQ0FBQztJQUVEOzs7Ozs7OztPQVFHO0lBQ08sV0FBVyxDQUFDLFlBQW9CO1FBQ3hDLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUMsUUFBd0IsRUFBRSxFQUFFLENBQUMsUUFBUSxDQUFDLE9BQU8sRUFBRSxLQUFLLFlBQVksQ0FBQyxDQUFDO1FBRXRHLElBQUksQ0FBQyxLQUFLLEVBQUU7WUFDVixNQUFNLElBQUksU0FBUyxDQUFDLCtDQUErQyxZQUFZLFFBQVEsQ0FBQyxDQUFDO1NBQzFGO1FBRUQsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBRU8sa0JBQWtCLENBQUMsTUFBb0I7UUFDN0MsSUFBSSxNQUFNLENBQUMsU0FBUyxFQUFFLElBQUksTUFBTSxDQUFDLFFBQVEsRUFBRSxFQUFFO1lBQzNDLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRSxDQUFDO2lCQUM1QyxJQUFJLENBQ0gsR0FBRyxDQUFDLENBQUMsS0FBa0IsRUFBRSxFQUFFO2dCQUN6QixPQUFPLE1BQU0sQ0FBQztZQUNoQixDQUFDLENBQUMsQ0FDSCxDQUFDO1NBQ0w7UUFFRCxPQUFPLFlBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUM5QixDQUFDOzsyR0EvTVUsYUFBYSxnREFHSixrQkFBa0I7K0dBSDNCLGFBQWE7NEZBQWIsYUFBYTtrQkFEekIsVUFBVTs7MEJBSUksTUFBTTsyQkFBQyxrQkFBa0IiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgQWt2ZW8uIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuIFNlZSBMaWNlbnNlLnR4dCBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxuICovXG5pbXBvcnQgeyBJbmplY3QsIEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgb2YgYXMgb2JzZXJ2YWJsZU9mIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBzd2l0Y2hNYXAsIG1hcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuaW1wb3J0IHsgTmJBdXRoU3RyYXRlZ3kgfSBmcm9tICcuLi9zdHJhdGVnaWVzL2F1dGgtc3RyYXRlZ3knO1xuaW1wb3J0IHsgTkJfQVVUSF9TVFJBVEVHSUVTIH0gZnJvbSAnLi4vYXV0aC5vcHRpb25zJztcbmltcG9ydCB7IE5iQXV0aFJlc3VsdCB9IGZyb20gJy4vYXV0aC1yZXN1bHQnO1xuaW1wb3J0IHsgTmJUb2tlblNlcnZpY2UgfSBmcm9tICcuL3Rva2VuL3Rva2VuLnNlcnZpY2UnO1xuaW1wb3J0IHsgTmJBdXRoVG9rZW4gfSBmcm9tICcuL3Rva2VuL3Rva2VuJztcblxuLyoqXG4gKiBDb21tb24gYXV0aGVudGljYXRpb24gc2VydmljZS5cbiAqIFNob3VsZCBiZSB1c2VkIHRvIGFzIGFuIGludGVybGF5ZXIgYmV0d2VlbiBVSSBDb21wb25lbnRzIGFuZCBBdXRoIFN0cmF0ZWd5LlxuICovXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgTmJBdXRoU2VydmljZSB7XG5cbiAgY29uc3RydWN0b3IocHJvdGVjdGVkIHRva2VuU2VydmljZTogTmJUb2tlblNlcnZpY2UsXG4gICAgICAgICAgICAgIEBJbmplY3QoTkJfQVVUSF9TVFJBVEVHSUVTKSBwcm90ZWN0ZWQgc3RyYXRlZ2llcykge1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHJpZXZlcyBjdXJyZW50IGF1dGhlbnRpY2F0ZWQgdG9rZW4gc3RvcmVkXG4gICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlPGFueT59XG4gICAqL1xuICBnZXRUb2tlbigpOiBPYnNlcnZhYmxlPE5iQXV0aFRva2VuPiB7XG4gICAgcmV0dXJuIHRoaXMudG9rZW5TZXJ2aWNlLmdldCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdHJ1ZSBpZiBhdXRoIHRva2VuIGlzIHByZXNlbnQgaW4gdGhlIHRva2VuIHN0b3JhZ2VcbiAgICogQHJldHVybnMge09ic2VydmFibGU8Ym9vbGVhbj59XG4gICAqL1xuICBpc0F1dGhlbnRpY2F0ZWQoKTogT2JzZXJ2YWJsZTxib29sZWFuPiB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0VG9rZW4oKVxuICAgICAgLnBpcGUobWFwKCh0b2tlbjogTmJBdXRoVG9rZW4pID0+IHRva2VuLmlzVmFsaWQoKSkpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdHJ1ZSBpZiB2YWxpZCBhdXRoIHRva2VuIGlzIHByZXNlbnQgaW4gdGhlIHRva2VuIHN0b3JhZ2UuXG4gICAqIElmIG5vdCwgY2FsbHMgdGhlIHN0cmF0ZWd5IHJlZnJlc2hUb2tlbiwgYW5kIHJldHVybnMgaXNBdXRoZW50aWNhdGVkKCkgaWYgc3VjY2VzcywgZmFsc2Ugb3RoZXJ3aXNlXG4gICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlPGJvb2xlYW4+fVxuICAgKi9cbiAgaXNBdXRoZW50aWNhdGVkT3JSZWZyZXNoKCk6IE9ic2VydmFibGU8Ym9vbGVhbj4ge1xuICAgIHJldHVybiB0aGlzLmdldFRva2VuKClcbiAgICAgIC5waXBlKFxuICAgICAgICBzd2l0Y2hNYXAodG9rZW4gPT4ge1xuICAgICAgICBpZiAodG9rZW4uZ2V0VmFsdWUoKSAmJiAhdG9rZW4uaXNWYWxpZCgpKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMucmVmcmVzaFRva2VuKHRva2VuLmdldE93bmVyU3RyYXRlZ3lOYW1lKCksIHRva2VuKVxuICAgICAgICAgICAgLnBpcGUoXG4gICAgICAgICAgICAgIHN3aXRjaE1hcChyZXMgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChyZXMuaXNTdWNjZXNzKCkpIHtcbiAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmlzQXV0aGVudGljYXRlZCgpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICByZXR1cm4gb2JzZXJ2YWJsZU9mKGZhbHNlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBvYnNlcnZhYmxlT2YodG9rZW4uaXNWYWxpZCgpKTtcbiAgICAgICAgfVxuICAgIH0pKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRva2VucyBzdHJlYW1cbiAgICogQHJldHVybnMge09ic2VydmFibGU8TmJBdXRoU2ltcGxlVG9rZW4+fVxuICAgKi9cbiAgb25Ub2tlbkNoYW5nZSgpOiBPYnNlcnZhYmxlPE5iQXV0aFRva2VuPiB7XG4gICAgcmV0dXJuIHRoaXMudG9rZW5TZXJ2aWNlLnRva2VuQ2hhbmdlKCk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBhdXRoZW50aWNhdGlvbiBzdGF0dXMgc3RyZWFtXG4gICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlPGJvb2xlYW4+fVxuICAgKi9cbiAgb25BdXRoZW50aWNhdGlvbkNoYW5nZSgpOiBPYnNlcnZhYmxlPGJvb2xlYW4+IHtcbiAgICByZXR1cm4gdGhpcy5vblRva2VuQ2hhbmdlKClcbiAgICAgIC5waXBlKG1hcCgodG9rZW46IE5iQXV0aFRva2VuKSA9PiB0b2tlbi5pc1ZhbGlkKCkpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBdXRoZW50aWNhdGVzIHdpdGggdGhlIHNlbGVjdGVkIHN0cmF0ZWd5XG4gICAqIFN0b3JlcyByZWNlaXZlZCB0b2tlbiBpbiB0aGUgdG9rZW4gc3RvcmFnZVxuICAgKlxuICAgKiBFeGFtcGxlOlxuICAgKiBhdXRoZW50aWNhdGUoJ2VtYWlsJywge2VtYWlsOiAnZW1haWxAZXhhbXBsZS5jb20nLCBwYXNzd29yZDogJ3Rlc3QnfSlcbiAgICpcbiAgICogQHBhcmFtIHN0cmF0ZWd5TmFtZVxuICAgKiBAcGFyYW0gZGF0YVxuICAgKiBAcmV0dXJucyB7T2JzZXJ2YWJsZTxOYkF1dGhSZXN1bHQ+fVxuICAgKi9cbiAgYXV0aGVudGljYXRlKHN0cmF0ZWd5TmFtZTogc3RyaW5nLCBkYXRhPzogYW55KTogT2JzZXJ2YWJsZTxOYkF1dGhSZXN1bHQ+IHtcbiAgICByZXR1cm4gdGhpcy5nZXRTdHJhdGVneShzdHJhdGVneU5hbWUpLmF1dGhlbnRpY2F0ZShkYXRhKVxuICAgICAgLnBpcGUoXG4gICAgICAgIHN3aXRjaE1hcCgocmVzdWx0OiBOYkF1dGhSZXN1bHQpID0+IHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5wcm9jZXNzUmVzdWx0VG9rZW4ocmVzdWx0KTtcbiAgICAgICAgfSksXG4gICAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlZ2lzdGVycyB3aXRoIHRoZSBzZWxlY3RlZCBzdHJhdGVneVxuICAgKiBTdG9yZXMgcmVjZWl2ZWQgdG9rZW4gaW4gdGhlIHRva2VuIHN0b3JhZ2VcbiAgICpcbiAgICogRXhhbXBsZTpcbiAgICogcmVnaXN0ZXIoJ2VtYWlsJywge2VtYWlsOiAnZW1haWxAZXhhbXBsZS5jb20nLCBuYW1lOiAnU29tZSBOYW1lJywgcGFzc3dvcmQ6ICd0ZXN0J30pXG4gICAqXG4gICAqIEBwYXJhbSBzdHJhdGVneU5hbWVcbiAgICogQHBhcmFtIGRhdGFcbiAgICogQHJldHVybnMge09ic2VydmFibGU8TmJBdXRoUmVzdWx0Pn1cbiAgICovXG4gIHJlZ2lzdGVyKHN0cmF0ZWd5TmFtZTogc3RyaW5nLCBkYXRhPzogYW55KTogT2JzZXJ2YWJsZTxOYkF1dGhSZXN1bHQ+IHtcbiAgICByZXR1cm4gdGhpcy5nZXRTdHJhdGVneShzdHJhdGVneU5hbWUpLnJlZ2lzdGVyKGRhdGEpXG4gICAgICAucGlwZShcbiAgICAgICAgc3dpdGNoTWFwKChyZXN1bHQ6IE5iQXV0aFJlc3VsdCkgPT4ge1xuICAgICAgICAgIHJldHVybiB0aGlzLnByb2Nlc3NSZXN1bHRUb2tlbihyZXN1bHQpO1xuICAgICAgICB9KSxcbiAgICAgICk7XG4gIH1cblxuICAvKipcbiAgICogU2lnbiBvdXRzIHdpdGggdGhlIHNlbGVjdGVkIHN0cmF0ZWd5XG4gICAqIFJlbW92ZXMgdG9rZW4gZnJvbSB0aGUgdG9rZW4gc3RvcmFnZVxuICAgKlxuICAgKiBFeGFtcGxlOlxuICAgKiBsb2dvdXQoJ2VtYWlsJylcbiAgICpcbiAgICogQHBhcmFtIHN0cmF0ZWd5TmFtZVxuICAgKiBAcmV0dXJucyB7T2JzZXJ2YWJsZTxOYkF1dGhSZXN1bHQ+fVxuICAgKi9cbiAgbG9nb3V0KHN0cmF0ZWd5TmFtZTogc3RyaW5nKTogT2JzZXJ2YWJsZTxOYkF1dGhSZXN1bHQ+IHtcbiAgICByZXR1cm4gdGhpcy5nZXRTdHJhdGVneShzdHJhdGVneU5hbWUpLmxvZ291dCgpXG4gICAgICAucGlwZShcbiAgICAgICAgc3dpdGNoTWFwKChyZXN1bHQ6IE5iQXV0aFJlc3VsdCkgPT4ge1xuICAgICAgICAgIGlmIChyZXN1bHQuaXNTdWNjZXNzKCkpIHtcbiAgICAgICAgICAgIHRoaXMudG9rZW5TZXJ2aWNlLmNsZWFyKClcbiAgICAgICAgICAgICAgLnBpcGUobWFwKCgpID0+IHJlc3VsdCkpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gb2JzZXJ2YWJsZU9mKHJlc3VsdCk7XG4gICAgICAgIH0pLFxuICAgICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZW5kcyBmb3Jnb3QgcGFzc3dvcmQgcmVxdWVzdCB0byB0aGUgc2VsZWN0ZWQgc3RyYXRlZ3lcbiAgICpcbiAgICogRXhhbXBsZTpcbiAgICogcmVxdWVzdFBhc3N3b3JkKCdlbWFpbCcsIHtlbWFpbDogJ2VtYWlsQGV4YW1wbGUuY29tJ30pXG4gICAqXG4gICAqIEBwYXJhbSBzdHJhdGVneU5hbWVcbiAgICogQHBhcmFtIGRhdGFcbiAgICogQHJldHVybnMge09ic2VydmFibGU8TmJBdXRoUmVzdWx0Pn1cbiAgICovXG4gIHJlcXVlc3RQYXNzd29yZChzdHJhdGVneU5hbWU6IHN0cmluZywgZGF0YT86IGFueSk6IE9ic2VydmFibGU8TmJBdXRoUmVzdWx0PiB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0U3RyYXRlZ3koc3RyYXRlZ3lOYW1lKS5yZXF1ZXN0UGFzc3dvcmQoZGF0YSk7XG4gIH1cblxuICAvKipcbiAgICogVHJpZXMgdG8gcmVzZXQgcGFzc3dvcmQgd2l0aCB0aGUgc2VsZWN0ZWQgc3RyYXRlZ3lcbiAgICpcbiAgICogRXhhbXBsZTpcbiAgICogcmVzZXRQYXNzd29yZCgnZW1haWwnLCB7bmV3UGFzc3dvcmQ6ICd0ZXN0J30pXG4gICAqXG4gICAqIEBwYXJhbSBzdHJhdGVneU5hbWVcbiAgICogQHBhcmFtIGRhdGFcbiAgICogQHJldHVybnMge09ic2VydmFibGU8TmJBdXRoUmVzdWx0Pn1cbiAgICovXG4gIHJlc2V0UGFzc3dvcmQoc3RyYXRlZ3lOYW1lOiBzdHJpbmcsIGRhdGE/OiBhbnkpOiBPYnNlcnZhYmxlPE5iQXV0aFJlc3VsdD4ge1xuICAgIHJldHVybiB0aGlzLmdldFN0cmF0ZWd5KHN0cmF0ZWd5TmFtZSkucmVzZXRQYXNzd29yZChkYXRhKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZW5kcyBhIHJlZnJlc2ggdG9rZW4gcmVxdWVzdFxuICAgKiBTdG9yZXMgcmVjZWl2ZWQgdG9rZW4gaW4gdGhlIHRva2VuIHN0b3JhZ2VcbiAgICpcbiAgICogRXhhbXBsZTpcbiAgICogcmVmcmVzaFRva2VuKCdlbWFpbCcsIHt0b2tlbjogdG9rZW59KVxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyYXRlZ3lOYW1lXG4gICAqIEBwYXJhbSBkYXRhXG4gICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlPE5iQXV0aFJlc3VsdD59XG4gICAqL1xuICByZWZyZXNoVG9rZW4oc3RyYXRlZ3lOYW1lOiBzdHJpbmcsIGRhdGE/OiBhbnkpOiBPYnNlcnZhYmxlPE5iQXV0aFJlc3VsdD4ge1xuICAgIHJldHVybiB0aGlzLmdldFN0cmF0ZWd5KHN0cmF0ZWd5TmFtZSkucmVmcmVzaFRva2VuKGRhdGEpXG4gICAgICAucGlwZShcbiAgICAgICAgc3dpdGNoTWFwKChyZXN1bHQ6IE5iQXV0aFJlc3VsdCkgPT4ge1xuICAgICAgICAgIHJldHVybiB0aGlzLnByb2Nlc3NSZXN1bHRUb2tlbihyZXN1bHQpO1xuICAgICAgICB9KSxcbiAgICAgICk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IHJlZ2lzdGVyZWQgc3RyYXRlZ3kgYnkgbmFtZVxuICAgKlxuICAgKiBFeGFtcGxlOlxuICAgKiBnZXRTdHJhdGVneSgnZW1haWwnKVxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gcHJvdmlkZXJcbiAgICogQHJldHVybnMge05iQWJzdHJhY3RBdXRoUHJvdmlkZXJ9XG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0U3RyYXRlZ3koc3RyYXRlZ3lOYW1lOiBzdHJpbmcpOiBOYkF1dGhTdHJhdGVneSB7XG4gICAgY29uc3QgZm91bmQgPSB0aGlzLnN0cmF0ZWdpZXMuZmluZCgoc3RyYXRlZ3k6IE5iQXV0aFN0cmF0ZWd5KSA9PiBzdHJhdGVneS5nZXROYW1lKCkgPT09IHN0cmF0ZWd5TmFtZSk7XG5cbiAgICBpZiAoIWZvdW5kKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBUaGVyZSBpcyBubyBBdXRoIFN0cmF0ZWd5IHJlZ2lzdGVyZWQgdW5kZXIgJyR7c3RyYXRlZ3lOYW1lfScgbmFtZWApO1xuICAgIH1cblxuICAgIHJldHVybiBmb3VuZDtcbiAgfVxuXG4gIHByaXZhdGUgcHJvY2Vzc1Jlc3VsdFRva2VuKHJlc3VsdDogTmJBdXRoUmVzdWx0KSB7XG4gICAgaWYgKHJlc3VsdC5pc1N1Y2Nlc3MoKSAmJiByZXN1bHQuZ2V0VG9rZW4oKSkge1xuICAgICAgcmV0dXJuIHRoaXMudG9rZW5TZXJ2aWNlLnNldChyZXN1bHQuZ2V0VG9rZW4oKSlcbiAgICAgICAgLnBpcGUoXG4gICAgICAgICAgbWFwKCh0b2tlbjogTmJBdXRoVG9rZW4pID0+IHtcbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgfSksXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG9ic2VydmFibGVPZihyZXN1bHQpO1xuICB9XG59XG4iXX0= |
\ | No newline at end of file |