name-password-strategy.service.js 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. /**
  2. * @fileoverview added by tsickle
  3. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  4. */
  5. import { Injectable } from '@angular/core';
  6. import { NbAuthIllegalTokenError, NbAuthResult, NbAuthStrategy } from '@nebular/auth';
  7. import { of as observableOf } from 'rxjs';
  8. import { switchMap, map, catchError, concatAll } from 'rxjs/operators';
  9. import { HttpClient, HttpErrorResponse } from '@angular/common/http';
  10. import { ActivatedRoute } from '@angular/router';
  11. import { namePasswordStrategyOptions } from './name-password-strategy-option';
  12. import * as JSEncrypt from 'jsencrypt';
  13. export class ResultError {
  14. /**
  15. * @param {?} message
  16. */
  17. constructor(message) {
  18. this.message = message;
  19. }
  20. }
  21. if (false) {
  22. /** @type {?} */
  23. ResultError.prototype.message;
  24. }
  25. export class NamePasswordStrategyService extends NbAuthStrategy {
  26. /**
  27. * @param {?} http
  28. * @param {?} route
  29. */
  30. constructor(http, route) {
  31. super();
  32. this.http = http;
  33. this.route = route;
  34. this.defaultOptions = namePasswordStrategyOptions;
  35. }
  36. /**
  37. * @param {?} options
  38. * @return {?}
  39. */
  40. static setup(options) {
  41. return [NamePasswordStrategyService, options];
  42. }
  43. /**
  44. * @param {?=} data
  45. * @return {?}
  46. */
  47. authenticate(data) {
  48. /** @type {?} */
  49. const module = 'login';
  50. /** @type {?} */
  51. const method = this.getOption(`${module}.method`);
  52. /** @type {?} */
  53. const url = this.getActionEndpoint(module);
  54. /** @type {?} */
  55. const requireValidToken = this.getOption(`${module}.requireValidToken`);
  56. return this.getEncryptPassword(data.loginPassword).pipe(map((/**
  57. * @param {?} body
  58. * @return {?}
  59. */
  60. (body) => {
  61. body.loginID = data.loginId;
  62. return this.http.request(method, url, { body, observe: 'response' })
  63. .pipe(map((/**
  64. * @param {?} res
  65. * @return {?}
  66. */
  67. (res) => {
  68. if (this.getOption(`${module}.alwaysFail`)) {
  69. throw this.createFailResponse(data);
  70. }
  71. else if (!this.getOption('success.getter')(module, res, this.options)) {
  72. throw new ResultError(this.getOption('messages.getter')(module, res, this.options));
  73. }
  74. return res;
  75. })), map((/**
  76. * @param {?} res
  77. * @return {?}
  78. */
  79. (res) => {
  80. return new NbAuthResult(true, res, this.getOption(`${module}.redirect.success`), [], this.getOption('messages.getter')(module, res, this.options));
  81. })), catchError((/**
  82. * @param {?} res
  83. * @return {?}
  84. */
  85. (res) => {
  86. return this.handleResponseError(res, module);
  87. })));
  88. })), concatAll());
  89. }
  90. /**
  91. * @return {?}
  92. */
  93. logout() {
  94. /** @type {?} */
  95. const module = 'logout';
  96. /** @type {?} */
  97. const method = this.getOption(`${module}.method`);
  98. /** @type {?} */
  99. const url = this.getActionEndpoint(module);
  100. return observableOf({})
  101. .pipe(switchMap((/**
  102. * @param {?} res
  103. * @return {?}
  104. */
  105. (res) => {
  106. if (!url) {
  107. return observableOf(res);
  108. }
  109. return this.http.request(method, url, { observe: 'response' });
  110. })), map((/**
  111. * @param {?} res
  112. * @return {?}
  113. */
  114. (res) => {
  115. if (this.getOption(`${module}.alwaysFail`)) {
  116. throw this.createFailResponse();
  117. }
  118. return res;
  119. })), map((/**
  120. * @param {?} res
  121. * @return {?}
  122. */
  123. (res) => {
  124. return new NbAuthResult(true, res, this.getOption(`${module}.redirect.success`), [], this.getOption('messages.getter')(module, res, this.options));
  125. })), catchError((/**
  126. * @param {?} res
  127. * @return {?}
  128. */
  129. (res) => {
  130. return this.handleResponseError(res, module);
  131. })));
  132. }
  133. /**
  134. * @param {?=} data
  135. * @return {?}
  136. */
  137. refreshToken(data) {
  138. return undefined;
  139. }
  140. /**
  141. * @param {?=} data
  142. * @return {?}
  143. */
  144. register(data) {
  145. return undefined;
  146. }
  147. /**
  148. * @param {?=} data
  149. * @return {?}
  150. */
  151. requestPassword(data) {
  152. return undefined;
  153. }
  154. /**
  155. * @param {?=} data
  156. * @return {?}
  157. */
  158. resetPassword(data) {
  159. /** @type {?} */
  160. const module = 'resetPass';
  161. /** @type {?} */
  162. const method = this.getOption(`${module}.method`);
  163. /** @type {?} */
  164. const url = this.getActionEndpoint(module);
  165. return this.getEncryptPassword(data.loginPasswordNew + '-' + data.loginPasswordOld).pipe(map((/**
  166. * @param {?} body
  167. * @return {?}
  168. */
  169. (body) => {
  170. body.passwordData = body.loginPassword;
  171. return this.http.request(method, url, { body, observe: 'response' })
  172. .pipe(map((/**
  173. * @param {?} res
  174. * @return {?}
  175. */
  176. (res) => {
  177. if (this.getOption(`${module}.alwaysFail`)) {
  178. throw this.createFailResponse(data);
  179. }
  180. else if (!this.getOption('success.getter')(module, res, this.options)) {
  181. throw new ResultError(this.getOption('messages.getter')(module, res, this.options));
  182. }
  183. return res;
  184. })), map((/**
  185. * @param {?} res
  186. * @return {?}
  187. */
  188. (res) => {
  189. return new NbAuthResult(true, res, this.getOption(`${module}.redirect.success`), [], this.getOption('messages.getter')(module, res, this.options));
  190. })), catchError((/**
  191. * @param {?} res
  192. * @return {?}
  193. */
  194. (res) => {
  195. return this.handleResponseError(res, module);
  196. })));
  197. })), concatAll());
  198. }
  199. /**
  200. * @param {?=} data
  201. * @return {?}
  202. */
  203. createUser(data) {
  204. /** @type {?} */
  205. const module = 'createUser';
  206. /** @type {?} */
  207. const method = this.getOption(`${module}.method`);
  208. /** @type {?} */
  209. const url = this.getActionEndpoint(module);
  210. return this.getEncryptPassword(data.loginPassword).pipe(map((/**
  211. * @param {?} body
  212. * @return {?}
  213. */
  214. (body) => {
  215. body.userName = data.userName;
  216. body.loginID = data.loginID;
  217. return this.http.request(method, url, { body, observe: 'response' })
  218. .pipe(map((/**
  219. * @param {?} res
  220. * @return {?}
  221. */
  222. (res) => {
  223. if (this.getOption(`${module}.alwaysFail`)) {
  224. throw this.createFailResponse(data);
  225. }
  226. else if (!this.getOption('success.getter')(module, res, this.options)) {
  227. throw new ResultError(this.getOption('messages.getter')(module, res, this.options));
  228. }
  229. return res;
  230. })), map((/**
  231. * @param {?} res
  232. * @return {?}
  233. */
  234. (res) => {
  235. return new NbAuthResult(true, res, this.getOption(`${module}.redirect.success`), [], this.getOption('messages.getter')(module, res, this.options));
  236. })), catchError((/**
  237. * @param {?} res
  238. * @return {?}
  239. */
  240. (res) => {
  241. return this.handleResponseError(res, module);
  242. })));
  243. })), concatAll());
  244. }
  245. /**
  246. * @param {?=} data
  247. * @return {?}
  248. */
  249. updatePasswordForAdmin(data) {
  250. /** @type {?} */
  251. const module = 'updatePasswordForAdmin';
  252. /** @type {?} */
  253. const method = this.getOption(`${module}.method`);
  254. /** @type {?} */
  255. const url = this.getActionEndpoint(module);
  256. return this.getEncryptPassword(data.loginPassword).pipe(map((/**
  257. * @param {?} body
  258. * @return {?}
  259. */
  260. (body) => {
  261. body.userID = data.userID;
  262. return this.http.request(method, url, { body, observe: 'response' })
  263. .pipe(map((/**
  264. * @param {?} res
  265. * @return {?}
  266. */
  267. (res) => {
  268. if (this.getOption(`${module}.alwaysFail`)) {
  269. throw this.createFailResponse(data);
  270. }
  271. else if (!this.getOption('success.getter')(module, res, this.options)) {
  272. throw new ResultError(this.getOption('messages.getter')(module, res, this.options));
  273. }
  274. return res;
  275. })), map((/**
  276. * @param {?} res
  277. * @return {?}
  278. */
  279. (res) => {
  280. return new NbAuthResult(true, res, this.getOption(`${module}.redirect.success`), [], this.getOption('messages.getter')(module, res, this.options));
  281. })), catchError((/**
  282. * @param {?} res
  283. * @return {?}
  284. */
  285. (res) => {
  286. return this.handleResponseError(res, module);
  287. })));
  288. })), concatAll());
  289. }
  290. /**
  291. * @param {?} password
  292. * @return {?}
  293. */
  294. getEncryptPassword(password) {
  295. /** @type {?} */
  296. const module = 'getPublicKey';
  297. /** @type {?} */
  298. const method = this.getOption(`${module}.method`);
  299. /** @type {?} */
  300. const url = this.getActionEndpoint(module);
  301. return this.http.request(method, url, { observe: 'response' })
  302. .pipe(map((/**
  303. * @param {?} res
  304. * @return {?}
  305. */
  306. (res) => {
  307. return encryptPassword(res.body, password);
  308. })), catchError((/**
  309. * @param {?} res
  310. * @return {?}
  311. */
  312. (res) => {
  313. return this.handleResponseError(res, module);
  314. })));
  315. /**
  316. * @param {?} result
  317. * @param {?} data
  318. * @return {?}
  319. */
  320. function encryptPassword(result, data) {
  321. /** @type {?} */
  322. let now = Date.now();
  323. /** @type {?} */
  324. let encrypt = new JSEncrypt.JSEncrypt();
  325. encrypt.setPublicKey(result.data.publicPEMKey);
  326. /** @type {?} */
  327. let encryptPass = encrypt.encrypt(data + now);
  328. return {
  329. cryptoKeyID: result.data.cryptoKeyID,
  330. utcTimestamp: now,
  331. loginPassword: encryptPass
  332. };
  333. }
  334. }
  335. /**
  336. * @protected
  337. * @param {?} res
  338. * @param {?} module
  339. * @return {?}
  340. */
  341. handleResponseError(res, module) {
  342. /** @type {?} */
  343. let errors = [];
  344. if (res instanceof HttpErrorResponse) {
  345. errors = this.getOption('errors.getter')(module, res, this.options);
  346. }
  347. else if (res instanceof NbAuthIllegalTokenError) {
  348. errors.push(res.message);
  349. }
  350. else if (res instanceof ResultError) {
  351. errors = res.message;
  352. }
  353. else {
  354. errors.push('Something went wrong.');
  355. }
  356. return observableOf(new NbAuthResult(false, res, this.getOption(`${module}.redirect.failure`), errors));
  357. }
  358. }
  359. NamePasswordStrategyService.decorators = [
  360. { type: Injectable }
  361. ];
  362. /** @nocollapse */
  363. NamePasswordStrategyService.ctorParameters = () => [
  364. { type: HttpClient },
  365. { type: ActivatedRoute }
  366. ];
  367. if (false) {
  368. /**
  369. * @type {?}
  370. * @protected
  371. */
  372. NamePasswordStrategyService.prototype.defaultOptions;
  373. /**
  374. * @type {?}
  375. * @protected
  376. */
  377. NamePasswordStrategyService.prototype.http;
  378. /**
  379. * @type {?}
  380. * @private
  381. */
  382. NamePasswordStrategyService.prototype.route;
  383. }
  384. //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmFtZS1wYXNzd29yZC1zdHJhdGVneS5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6Im5nOi8vZ2UtYWRtaW4tYXV0aC8iLCJzb3VyY2VzIjpbImxpYi9zdHJhdGVneS9uYW1lLXBhc3N3b3JkLXN0cmF0ZWd5LnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUFBLE9BQU8sRUFBVSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDbkQsT0FBTyxFQUVMLHVCQUF1QixFQUN2QixZQUFZLEVBQ1osY0FBYyxFQUNmLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBYyxFQUFFLElBQUksWUFBWSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ3RELE9BQU8sRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLFVBQVUsRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUN2RSxPQUFPLEVBQUUsVUFBVSxFQUFFLGlCQUFpQixFQUErQyxNQUFNLHNCQUFzQixDQUFDO0FBRWxILE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNqRCxPQUFPLEVBQW1DLDJCQUEyQixFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDL0csT0FBTyxLQUFLLFNBQVMsTUFBTSxXQUFXLENBQUM7QUFHdkMsTUFBTSxPQUFPLFdBQVc7Ozs7SUFDdEIsWUFBbUIsT0FBaUI7UUFBakIsWUFBTyxHQUFQLE9BQU8sQ0FBVTtJQUVwQyxDQUFDO0NBQ0Y7OztJQUhhLDhCQUF3Qjs7QUFNdEMsTUFBTSxPQUFPLDJCQUE0QixTQUFRLGNBQWM7Ozs7O0lBUTdELFlBQXNCLElBQWdCLEVBQVUsS0FBcUI7UUFDbkUsS0FBSyxFQUFFLENBQUM7UUFEWSxTQUFJLEdBQUosSUFBSSxDQUFZO1FBQVUsVUFBSyxHQUFMLEtBQUssQ0FBZ0I7UUFGM0QsbUJBQWMsR0FBb0MsMkJBQTJCLENBQUM7SUFJeEYsQ0FBQzs7Ozs7SUFSRCxNQUFNLENBQUMsS0FBSyxDQUFDLE9BQXdD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QWlCLEVBQUU7WUFDcEMsTUFBTSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsZUFBZSxDQUFDLENBQUMsTUFBTSxFQUFFLEdBQUcsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7U0FDckU7YUFBTSxJQUFJLEdBQUcsWUFBWSx1QkFBdUIsRUFBRTtZQUNqRCxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQztTQUMxQjthQUFNLElBQUksR0FBRyxZQUFZLFdBQVcsRUFBRTtZQUNyQyxNQUFNLEdBQUcsR0FBRyxDQUFDLE9BQU8sQ0FBQztTQUN0QjthQUFNO1lBQ0wsTUFBTSxDQUFDLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO1NBQ3RDO1FBQ0QsT0FBTyxZQUFZLENBQ2pCLElBQUksWUFBWSxDQUNkLEtBQUssRUFDTCxHQUFHLEVBQ0gsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLE1BQU0sbUJBQW1CLENBQUMsRUFDNUMsTUFBTSxDQUNQLENBQUMsQ0FBQztJQUNQLENBQUM7OztZQTNPRixVQUFVOzs7O1lBYkYsVUFBVTtZQUVWLGNBQWM7Ozs7Ozs7SUFrQnJCLHFEQUF3Rjs7Ozs7SUFFNUUsMkNBQTBCOzs7OztJQUFFLDRDQUE2QiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdCwgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQge1xyXG4gIE5CX0FVVEhfT1BUSU9OUyxcclxuICBOYkF1dGhJbGxlZ2FsVG9rZW5FcnJvcixcclxuICBOYkF1dGhSZXN1bHQsXHJcbiAgTmJBdXRoU3RyYXRlZ3ksIE5iQXV0aFN0cmF0ZWd5Q2xhc3NcclxufSBmcm9tICdAbmVidWxhci9hdXRoJztcclxuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgb2YgYXMgb2JzZXJ2YWJsZU9mIH0gZnJvbSAncnhqcyc7XHJcbmltcG9ydCB7IHN3aXRjaE1hcCwgbWFwLCBjYXRjaEVycm9yLCBjb25jYXRBbGwgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XHJcbmltcG9ydCB7IEh0dHBDbGllbnQsIEh0dHBFcnJvclJlc3BvbnNlLCBIdHRwSGVhZGVycywgSHR0cFJlc3BvbnNlLCBIdHRwUmVzcG9uc2VCYXNlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uL2h0dHAnO1xyXG5pbXBvcnQgeyB0aHJvd0Vycm9yIGFzIF9vYnNlcnZhYmxlVGhyb3cgfSBmcm9tICdyeGpzL2luZGV4JztcclxuaW1wb3J0IHsgQWN0aXZhdGVkUm91dGUgfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xyXG5pbXBvcnQgeyBOYW1lUGFzc3dvcmRBdXRoU3RyYXRlZ3lPcHRpb25zLCBuYW1lUGFzc3dvcmRTdHJhdGVneU9wdGlvbnMgfSBmcm9tICcuL25hbWUtcGFzc3dvcmQtc3RyYXRlZ3ktb3B0aW9uJztcclxuaW1wb3J0ICogYXMgSlNFbmNyeXB0IGZyb20gJ2pzZW5jcnlwdCc7XHJcblxyXG5cclxuZXhwb3J0IGNsYXNzIFJlc3VsdEVycm9yIHtcclxuICBjb25zdHJ1Y3RvcihwdWJsaWMgbWVzc2FnZTogU3RyaW5nW10pIHtcclxuXHJcbiAgfVxyXG59XHJcblxyXG5ASW5qZWN0YWJsZSgpXHJcbmV4cG9ydCBjbGFzcyBOYW1lUGFzc3dvcmRTdHJhdGVneVNlcnZpY2UgZXh0ZW5kcyBOYkF1dGhTdHJhdGVneSB7XHJcblxyXG4gIHN0YXRpYyBzZXR1cChvcHRpb25zOiBOYW1lUGFzc3dvcmRBdXRoU3RyYXRlZ3lPcHRpb25zKTogW05iQXV0aFN0cmF0ZWd5Q2xhc3MsIE5hbWVQYXNzd29yZEF1dGhTdHJhdGVneU9wdGlvbnNdIHtcclxuICAgIHJldHVybiBbTmFtZVBhc3N3b3JkU3RyYXRlZ3lTZXJ2aWNlLCBvcHRpb25zXTtcclxuICB9XHJcblxyXG4gIHByb3RlY3RlZCBkZWZhdWx0T3B0aW9uczogTmFtZVBhc3N3b3JkQXV0aFN0cmF0ZWd5T3B0aW9ucyA9IG5hbWVQYXNzd29yZFN0cmF0ZWd5T3B0aW9ucztcclxuXHJcbiAgY29uc3RydWN0b3IocHJvdGVjdGVkIGh0dHA6IEh0dHBDbGllbnQsIHByaXZhdGUgcm91dGU6IEFjdGl2YXRlZFJvdXRlKSB7XHJcbiAgICBzdXBlcigpO1xyXG4gIH1cclxuXHJcbiAgYXV0aGVudGljYXRlKGRhdGE/OiBhbnkpOiBPYnNlcnZhYmxlPE5iQXV0aFJlc3VsdD4ge1xyXG4gICAgY29uc3QgbW9kdWxlID0gJ2xvZ2luJztcclxuICAgIGNvbnN0IG1ldGhvZCA9IHRoaXMuZ2V0T3B0aW9uKGAke21vZHVsZX0ubWV0aG9kYCk7XHJcbiAgICBjb25zdCB1cmwgPSB0aGlzLmdldEFjdGlvbkVuZHBvaW50KG1vZHVsZSk7XHJcbiAgICBjb25zdCByZXF1aXJlVmFsaWRUb2tlbiA9IHRoaXMuZ2V0T3B0aW9uKGAke21vZHVsZX0ucmVxdWlyZVZhbGlkVG9rZW5gKTtcclxuICAgIHJldHVybiB0aGlzLmdldEVuY3J5cHRQYXNzd29yZChkYXRhLmxvZ2luUGFzc3dvcmQpLnBpcGUobWFwKChib2R5KSA9PiB7XHJcbiAgICAgIGJvZHkubG9naW5JRCA9IGRhdGEubG9naW5JZDtcclxuICAgICAgcmV0dXJuIHRoaXMuaHR0cC5yZXF1ZXN0KG1ldGhvZCwgdXJsLCB7IGJvZHksIG9ic2VydmU6ICdyZXNwb25zZScgfSlcclxuICAgICAgICAucGlwZShcclxuICAgICAgICAgIG1hcCgocmVzKSA9PiB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLmdldE9wdGlvbihgJHttb2R1bGV9LmFsd2F5c0ZhaWxgKSkge1xyXG4gICAgICAgICAgICAgIHRocm93IHRoaXMuY3JlYXRlRmFpbFJlc3BvbnNlKGRhdGEpO1xyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKCF0aGlzLmdldE9wdGlvbignc3VjY2Vzcy5nZXR0ZXInKShtb2R1bGUsIHJlcywgdGhpcy5vcHRpb25zKSkge1xyXG4gICAgICAgICAgICAgIHRocm93IG5ldyBSZXN1bHRFcnJvcih0aGlzLmdldE9wdGlvbignbWVzc2FnZXMuZ2V0dGVyJykobW9kdWxlLCByZXMsIHRoaXMub3B0aW9ucykpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiByZXM7XHJcbiAgICAgICAgICB9KSxcclxuICAgICAgICAgIG1hcCgocmVzKSA9PiB7XHJcbiAgICAgICAgICAgIHJldHVybiBuZXcgTmJBdXRoUmVzdWx0KFxyXG4gICAgICAgICAgICAgIHRydWUsXHJcbiAgICAgICAgICAgICAgcmVzLFxyXG4gICAgICAgICAgICAgIHRoaXMuZ2V0T3B0aW9uKGAke21vZHVsZX0ucmVkaXJlY3Quc3VjY2Vzc2ApLFxyXG4gICAgICAgICAgICAgIFtdLFxyXG4gICAgICAgICAgICAgIHRoaXMuZ2V0T3B0aW9uKCdtZXNzYWdlcy5nZXR0ZXInKShtb2R1bGUsIHJlcywgdGhpcy5vcHRpb25zKSk7XHJcbiAgICAgICAgICB9KSxcclxuICAgICAgICAgIGNhdGNoRXJyb3IoKHJlcykgPT4ge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5oYW5kbGVSZXNwb25zZUVycm9yKHJlcywgbW9kdWxlKTtcclxuICAgICAgICAgIH0pXHJcbiAgICAgICAgKTtcclxuICAgIH0pLCBjb25jYXRBbGwoKSk7XHJcblxyXG5cclxuICB9XHJcblxyXG5cclxuICBsb2dvdXQoKTogT2JzZXJ2YWJsZTxOYkF1dGhSZXN1bHQ+IHtcclxuICAgIGNvbnN0IG1vZHVsZSA9ICdsb2dvdXQnO1xyXG4gICAgY29uc3QgbWV0aG9kID0gdGhpcy5nZXRPcHRpb24oYCR7bW9kdWxlfS5tZXRob2RgKTtcclxuICAgIGNvbnN0IHVybCA9IHRoaXMuZ2V0QWN0aW9uRW5kcG9pbnQobW9kdWxlKTtcclxuXHJcbiAgICByZXR1cm4gb2JzZXJ2YWJsZU9mKHt9KVxyXG4gICAgICAucGlwZShcclxuICAgICAgICBzd2l0Y2hNYXAoKHJlczogYW55KSA9PiB7XHJcbiAgICAgICAgICBpZiAoIXVybCkge1xyXG4gICAgICAgICAgICByZXR1cm4gb2JzZXJ2YWJsZU9mKHJlcyk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICByZXR1cm4gdGhpcy5odHRwLnJlcXVlc3QobWV0aG9kLCB1cmwsIHsgb2JzZXJ2ZTogJ3Jlc3BvbnNlJyB9KTtcclxuICAgICAgICB9KSxcclxuICAgICAgICBtYXAoKHJlcykgPT4ge1xyXG4gICAgICAgICAgaWYgKHRoaXMuZ2V0T3B0aW9uKGAke21vZHVsZX0uYWx3YXlzRmFpbGApKSB7XHJcbiAgICAgICAgICAgIHRocm93IHRoaXMuY3JlYXRlRmFpbFJlc3BvbnNlKCk7XHJcbiAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgcmV0dXJuIHJlcztcclxuICAgICAgICB9KSxcclxuICAgICAgICBtYXAoKHJlcykgPT4ge1xyXG4gICAgICAgICAgcmV0dXJuIG5ldyBOYkF1dGhSZXN1bHQoXHJcbiAgICAgICAgICAgIHRydWUsXHJcbiAgICAgICAgICAgIHJlcyxcclxuICAgICAgICAgICAgdGhpcy5nZXRPcHRpb24oYCR7bW9kdWxlfS5yZWRpcmVjdC5zdWNjZXNzYCksXHJcbiAgICAgICAgICAgIFtdLFxyXG4gICAgICAgICAgICB0aGlzLmdldE9wdGlvbignbWVzc2FnZXMuZ2V0dGVyJykobW9kdWxlLCByZXMsIHRoaXMub3B0aW9ucykpO1xyXG4gICAgICAgIH0pLFxyXG4gICAgICAgIGNhdGNoRXJyb3IoKHJlcykgPT4ge1xyXG4gICAgICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlUmVzcG9uc2VFcnJvcihyZXMsIG1vZHVsZSk7XHJcbiAgICAgICAgfSlcclxuICAgICAgKTtcclxuICB9XHJcblxyXG4gIHJlZnJlc2hUb2tlbihkYXRhPzogYW55KTogT2JzZXJ2YWJsZTxOYkF1dGhSZXN1bHQ+IHtcclxuICAgIHJldHVybiB1bmRlZmluZWQ7XHJcbiAgfVxyXG5cclxuICByZWdpc3RlcihkYXRhPzogYW55KTogT2JzZXJ2YWJsZTxOYkF1dGhSZXN1bHQ+IHtcclxuICAgIHJldHVybiB1bmRlZmluZWQ7XHJcbiAgfVxyXG5cclxuICByZXF1ZXN0UGFzc3dvcmQoZGF0YT86IGFueSk6IE9ic2VydmFibGU8TmJBdXRoUmVzdWx0PiB7XHJcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xyXG4gIH1cclxuXHJcbiAgcmVzZXRQYXNzd29yZChkYXRhPzogYW55KTogT2JzZXJ2YWJsZTxOYkF1dGhSZXN1bHQ+IHtcclxuICAgIGNvbnN0IG1vZHVsZSA9ICdyZXNldFBhc3MnO1xyXG4gICAgY29uc3QgbWV0aG9kID0gdGhpcy5nZXRPcHRpb24oYCR7bW9kdWxlfS5tZXRob2RgKTtcclxuICAgIGNvbnN0IHVybCA9IHRoaXMuZ2V0QWN0aW9uRW5kcG9pbnQobW9kdWxlKTtcclxuICAgIHJldHVybiB0aGlzLmdldEVuY3J5cHRQYXNzd29yZChkYXRhLmxvZ2luUGFzc3dvcmROZXcgKyAnLScgKyBkYXRhLmxvZ2luUGFzc3dvcmRPbGQpLnBpcGUobWFwKChib2R5KSA9PiB7XHJcbiAgICAgIGJvZHkucGFzc3dvcmREYXRhID0gYm9keS5sb2dpblBhc3N3b3JkO1xyXG4gICAgICByZXR1cm4gdGhpcy5odHRwLnJlcXVlc3QobWV0aG9kLCB1cmwsIHsgYm9keSwgb2JzZXJ2ZTogJ3Jlc3BvbnNlJyB9KVxyXG4gICAgICAgIC5waXBlKFxyXG4gICAgICAgICAgbWFwKChyZXMpID0+IHtcclxuICAgICAgICAgICAgaWYgKHRoaXMuZ2V0T3B0aW9uKGAke21vZHVsZX0uYWx3YXlzRmFpbGApKSB7XHJcbiAgICAgICAgICAgICAgdGhyb3cgdGhpcy5jcmVhdGVGYWlsUmVzcG9uc2UoZGF0YSk7XHJcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoIXRoaXMuZ2V0T3B0aW9uKCdzdWNjZXNzLmdldHRlcicpKG1vZHVsZSwgcmVzLCB0aGlzLm9wdGlvbnMpKSB7XHJcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IFJlc3VsdEVycm9yKHRoaXMuZ2V0T3B0aW9uKCdtZXNzYWdlcy5nZXR0ZXInKShtb2R1bGUsIHJlcywgdGhpcy5vcHRpb25zKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIHJlcztcclxuICAgICAgICAgIH0pLFxyXG4gICAgICAgICAgbWFwKChyZXMpID0+IHtcclxuICAgICAgICAgICAgcmV0dXJuIG5ldyBOYkF1dGhSZXN1bHQoXHJcbiAgICAgICAgICAgICAgdHJ1ZSxcclxuICAgICAgICAgICAgICByZXMsXHJcbiAgICAgICAgICAgICAgdGhpcy5nZXRPcHRpb24oYCR7bW9kdWxlfS5yZWRpcmVjdC5zdWNjZXNzYCksXHJcbiAgICAgICAgICAgICAgW10sXHJcbiAgICAgICAgICAgICAgdGhpcy5nZXRPcHRpb24oJ21lc3NhZ2VzLmdldHRlcicpKG1vZHVsZSwgcmVzLCB0aGlzLm9wdGlvbnMpKTtcclxuICAgICAgICAgIH0pLFxyXG4gICAgICAgICAgY2F0Y2hFcnJvcigocmVzKSA9PiB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmhhbmRsZVJlc3BvbnNlRXJyb3IocmVzLCBtb2R1bGUpO1xyXG4gICAgICAgICAgfSlcclxuICAgICAgICApO1xyXG4gICAgfSksIGNvbmNhdEFsbCgpKTtcclxuICB9XHJcblxyXG4gIGNyZWF0ZVVzZXIoZGF0YT86IGFueSk6IE9ic2VydmFibGU8TmJBdXRoUmVzdWx0PiB7XHJcbiAgICBjb25zdCBtb2R1bGUgPSAnY3JlYXRlVXNlcic7XHJcbiAgICBjb25zdCBtZXRob2QgPSB0aGlzLmdldE9wdGlvbihgJHttb2R1bGV9Lm1ldGhvZGApO1xyXG4gICAgY29uc3QgdXJsID0gdGhpcy5nZXRBY3Rpb25FbmRwb2ludChtb2R1bGUpO1xyXG4gICAgcmV0dXJuIHRoaXMuZ2V0RW5jcnlwdFBhc3N3b3JkKGRhdGEubG9naW5QYXNzd29yZCkucGlwZShtYXAoKGJvZHkpID0+IHtcclxuICAgICAgYm9keS51c2VyTmFtZSA9IGRhdGEudXNlck5hbWU7XHJcbiAgICAgIGJvZHkubG9naW5JRCA9IGRhdGEubG9naW5JRDtcclxuICAgICAgcmV0dXJuIHRoaXMuaHR0cC5yZXF1ZXN0KG1ldGhvZCwgdXJsLCB7IGJvZHksIG9ic2VydmU6ICdyZXNwb25zZScgfSlcclxuICAgICAgICAucGlwZShcclxuICAgICAgICAgIG1hcCgocmVzKSA9PiB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLmdldE9wdGlvbihgJHttb2R1bGV9LmFsd2F5c0ZhaWxgKSkge1xyXG4gICAgICAgICAgICAgIHRocm93IHRoaXMuY3JlYXRlRmFpbFJlc3BvbnNlKGRhdGEpO1xyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKCF0aGlzLmdldE9wdGlvbignc3VjY2Vzcy5nZXR0ZXInKShtb2R1bGUsIHJlcywgdGhpcy5vcHRpb25zKSkge1xyXG4gICAgICAgICAgICAgIHRocm93IG5ldyBSZXN1bHRFcnJvcih0aGlzLmdldE9wdGlvbignbWVzc2FnZXMuZ2V0dGVyJykobW9kdWxlLCByZXMsIHRoaXMub3B0aW9ucykpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiByZXM7XHJcbiAgICAgICAgICB9KSxcclxuICAgICAgICAgIG1hcCgocmVzKSA9PiB7XHJcbiAgICAgICAgICAgIHJldHVybiBuZXcgTmJBdXRoUmVzdWx0KFxyXG4gICAgICAgICAgICAgIHRydWUsXHJcbiAgICAgICAgICAgICAgcmVzLFxyXG4gICAgICAgICAgICAgIHRoaXMuZ2V0T3B0aW9uKGAke21vZHVsZX0ucmVkaXJlY3Quc3VjY2Vzc2ApLFxyXG4gICAgICAgICAgICAgIFtdLFxyXG4gICAgICAgICAgICAgIHRoaXMuZ2V0T3B0aW9uKCdtZXNzYWdlcy5nZXR0ZXInKShtb2R1bGUsIHJlcywgdGhpcy5vcHRpb25zKSk7XHJcbiAgICAgICAgICB9KSxcclxuICAgICAgICAgIGNhdGNoRXJyb3IoKHJlcykgPT4ge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5oYW5kbGVSZXNwb25zZUVycm9yKHJlcywgbW9kdWxlKTtcclxuICAgICAgICAgIH0pXHJcbiAgICAgICAgKTtcclxuICAgIH0pLCBjb25jYXRBbGwoKSk7XHJcbiAgfVxyXG5cclxuICB1cGRhdGVQYXNzd29yZEZvckFkbWluKGRhdGE/OiBhbnkpOiBPYnNlcnZhYmxlPE5iQXV0aFJlc3VsdD4ge1xyXG4gICAgY29uc3QgbW9kdWxlID0gJ3VwZGF0ZVBhc3N3b3JkRm9yQWRtaW4nO1xyXG4gICAgY29uc3QgbWV0aG9kID0gdGhpcy5nZXRPcHRpb24oYCR7bW9kdWxlfS5tZXRob2RgKTtcclxuICAgIGNvbnN0IHVybCA9IHRoaXMuZ2V0QWN0aW9uRW5kcG9pbnQobW9kdWxlKTtcclxuICAgIHJldHVybiB0aGlzLmdldEVuY3J5cHRQYXNzd29yZChkYXRhLmxvZ2luUGFzc3dvcmQpLnBpcGUobWFwKChib2R5KSA9PiB7XHJcbiAgICAgIGJvZHkudXNlcklEID0gZGF0YS51c2VySUQ7XHJcbiAgICAgIHJldHVybiB0aGlzLmh0dHAucmVxdWVzdChtZXRob2QsIHVybCwgeyBib2R5LCBvYnNlcnZlOiAncmVzcG9uc2UnIH0pXHJcbiAgICAgICAgLnBpcGUoXHJcbiAgICAgICAgICBtYXAoKHJlcykgPT4ge1xyXG4gICAgICAgICAgICBpZiAodGhpcy5nZXRPcHRpb24oYCR7bW9kdWxlfS5hbHdheXNGYWlsYCkpIHtcclxuICAgICAgICAgICAgICB0aHJvdyB0aGlzLmNyZWF0ZUZhaWxSZXNwb25zZShkYXRhKTtcclxuICAgICAgICAgICAgfSBlbHNlIGlmICghdGhpcy5nZXRPcHRpb24oJ3N1Y2Nlc3MuZ2V0dGVyJykobW9kdWxlLCByZXMsIHRoaXMub3B0aW9ucykpIHtcclxuICAgICAgICAgICAgICB0aHJvdyBuZXcgUmVzdWx0RXJyb3IodGhpcy5nZXRPcHRpb24oJ21lc3NhZ2VzLmdldHRlcicpKG1vZHVsZSwgcmVzLCB0aGlzLm9wdGlvbnMpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gcmVzO1xyXG4gICAgICAgICAgfSksXHJcbiAgICAgICAgICBtYXAoKHJlcykgPT4ge1xyXG4gICAgICAgICAgICByZXR1cm4gbmV3IE5iQXV0aFJlc3VsdChcclxuICAgICAgICAgICAgICB0cnVlLFxyXG4gICAgICAgICAgICAgIHJlcyxcclxuICAgICAgICAgICAgICB0aGlzLmdldE9wdGlvbihgJHttb2R1bGV9LnJlZGlyZWN0LnN1Y2Nlc3NgKSxcclxuICAgICAgICAgICAgICBbXSxcclxuICAgICAgICAgICAgICB0aGlzLmdldE9wdGlvbignbWVzc2FnZXMuZ2V0dGVyJykobW9kdWxlLCByZXMsIHRoaXMub3B0aW9ucykpO1xyXG4gICAgICAgICAgfSksXHJcbiAgICAgICAgICBjYXRjaEVycm9yKChyZXMpID0+IHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlUmVzcG9uc2VFcnJvcihyZXMsIG1vZHVsZSk7XHJcbiAgICAgICAgICB9KVxyXG4gICAgICAgICk7XHJcbiAgICB9KSwgY29uY2F0QWxsKCkpO1xyXG4gIH1cclxuXHJcblxyXG4gIGdldEVuY3J5cHRQYXNzd29yZChwYXNzd29yZCk6IE9ic2VydmFibGU8YW55PiB7XHJcbiAgICBjb25zdCBtb2R1bGUgPSAnZ2V0UHVibGljS2V5JztcclxuICAgIGNvbnN0IG1ldGhvZCA9IHRoaXMuZ2V0T3B0aW9uKGAke21vZHVsZX0ubWV0aG9kYCk7XHJcbiAgICBjb25zdCB1cmwgPSB0aGlzLmdldEFjdGlvbkVuZHBvaW50KG1vZHVsZSk7XHJcbiAgICByZXR1cm4gdGhpcy5odHRwLnJlcXVlc3QobWV0aG9kLCB1cmwsIHsgb2JzZXJ2ZTogJ3Jlc3BvbnNlJyB9KVxyXG4gICAgICAucGlwZShcclxuICAgICAgICBtYXAoKHJlcykgPT4ge1xyXG4gICAgICAgICAgcmV0dXJuIGVuY3J5cHRQYXNzd29yZChyZXMuYm9keSwgcGFzc3dvcmQpO1xyXG4gICAgICAgIH0pLFxyXG4gICAgICAgIGNhdGNoRXJyb3IoKHJlcykgPT4ge1xyXG4gICAgICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlUmVzcG9uc2VFcnJvcihyZXMsIG1vZHVsZSk7XHJcbiAgICAgICAgfSlcclxuICAgICAgKTtcclxuXHJcbiAgICBmdW5jdGlvbiBlbmNyeXB0UGFzc3dvcmQocmVzdWx0LCBkYXRhKSB7XHJcbiAgICAgIGxldCBub3cgPSBEYXRlLm5vdygpO1xyXG4gICAgICBsZXQgZW5jcnlwdCA9IG5ldyBKU0VuY3J5cHQuSlNFbmNyeXB0KCk7XHJcbiAgICAgIGVuY3J5cHQuc2V0UHVibGljS2V5KHJlc3VsdC5kYXRhLnB1YmxpY1BFTUtleSk7XHJcbiAgICAgIGxldCBlbmNyeXB0UGFzcyA9IGVuY3J5cHQuZW5jcnlwdChkYXRhICsgbm93KTtcclxuICAgICAgcmV0dXJuIHtcclxuICAgICAgICBjcnlwdG9LZXlJRDogcmVzdWx0LmRhdGEuY3J5cHRvS2V5SUQsXHJcbiAgICAgICAgdXRjVGltZXN0YW1wOiBub3csXHJcbiAgICAgICAgbG9naW5QYXNzd29yZDogZW5jcnlwdFBhc3NcclxuICAgICAgfTtcclxuICAgIH1cclxuICB9XHJcblxyXG5cclxuICBwcm90ZWN0ZWQgaGFuZGxlUmVzcG9uc2VFcnJvcihyZXM6IGFueSwgbW9kdWxlOiBzdHJpbmcpOiBPYnNlcnZhYmxlPE5iQXV0aFJlc3VsdD4ge1xyXG4gICAgbGV0IGVycm9ycyA9IFtdO1xyXG4gICAgaWYgKHJlcyBpbnN0YW5jZW9mIEh0dHBFcnJvclJlc3BvbnNlKSB7XHJcbiAgICAgIGVycm9ycyA9IHRoaXMuZ2V0T3B0aW9uKCdlcnJvcnMuZ2V0dGVyJykobW9kdWxlLCByZXMsIHRoaXMub3B0aW9ucyk7XHJcbiAgICB9IGVsc2UgaWYgKHJlcyBpbnN0YW5jZW9mIE5iQXV0aElsbGVnYWxUb2tlbkVycm9yKSB7XHJcbiAgICAgIGVycm9ycy5wdXNoKHJlcy5tZXNzYWdlKTtcclxuICAgIH0gZWxzZSBpZiAocmVzIGluc3RhbmNlb2YgUmVzdWx0RXJyb3IpIHtcclxuICAgICAgZXJyb3JzID0gcmVzLm1lc3NhZ2U7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBlcnJvcnMucHVzaCgnU29tZXRoaW5nIHdlbnQgd3JvbmcuJyk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gb2JzZXJ2YWJsZU9mKFxyXG4gICAgICBuZXcgTmJBdXRoUmVzdWx0KFxyXG4gICAgICAgIGZhbHNlLFxyXG4gICAgICAgIHJlcyxcclxuICAgICAgICB0aGlzLmdldE9wdGlvbihgJHttb2R1bGV9LnJlZGlyZWN0LmZhaWx1cmVgKSxcclxuICAgICAgICBlcnJvcnNcclxuICAgICAgKSk7XHJcbiAgfVxyXG59XHJcblxyXG4iXX0=