UNPKG

20.2 kBJavaScriptView Raw
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 */
6import { Inject, Injectable } from '@angular/core';
7import { of as observableOf } from 'rxjs';
8import { switchMap, map } from 'rxjs/operators';
9import { NB_AUTH_STRATEGIES } from '../auth.options';
10import * as i0 from "@angular/core";
11import * 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 */
16export 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}
198NbAuthService.ɵ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 });
199NbAuthService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: NbAuthService });
200i0.ɵɵ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