AssumeRoleProvider.js 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. var http = _interopRequireWildcard(require("http"), true);
  6. var https = _interopRequireWildcard(require("https"), true);
  7. var _url = require("url");
  8. var _CredentialProvider = require("./CredentialProvider.js");
  9. var _Credentials = require("./Credentials.js");
  10. var _helper = require("./internal/helper.js");
  11. var _request = require("./internal/request.js");
  12. var _response = require("./internal/response.js");
  13. var _signing = require("./signing.js");
  14. function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
  15. /**
  16. * @see https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html
  17. */
  18. const defaultExpirySeconds = 900;
  19. class AssumeRoleProvider extends _CredentialProvider.CredentialProvider {
  20. accessExpiresAt = '';
  21. constructor({
  22. stsEndpoint,
  23. accessKey,
  24. secretKey,
  25. durationSeconds = defaultExpirySeconds,
  26. sessionToken,
  27. policy,
  28. region = '',
  29. roleArn,
  30. roleSessionName,
  31. externalId,
  32. token,
  33. webIdentityToken,
  34. action = 'AssumeRole',
  35. transportAgent = undefined
  36. }) {
  37. super({
  38. accessKey,
  39. secretKey,
  40. sessionToken
  41. });
  42. this.stsEndpoint = new _url.URL(stsEndpoint);
  43. this.accessKey = accessKey;
  44. this.secretKey = secretKey;
  45. this.policy = policy;
  46. this.region = region;
  47. this.roleArn = roleArn;
  48. this.roleSessionName = roleSessionName;
  49. this.externalId = externalId;
  50. this.token = token;
  51. this.webIdentityToken = webIdentityToken;
  52. this.action = action;
  53. this.durationSeconds = parseInt(durationSeconds);
  54. let expirySeconds = this.durationSeconds;
  55. if (this.durationSeconds < defaultExpirySeconds) {
  56. expirySeconds = defaultExpirySeconds;
  57. }
  58. this.expirySeconds = expirySeconds; // for calculating refresh of credentials.
  59. // By default, nodejs uses a global agent if the 'agent' property
  60. // is set to undefined. Otherwise, it's okay to assume the users
  61. // know what they're doing if they specify a custom transport agent.
  62. this.transportAgent = transportAgent;
  63. const isHttp = this.stsEndpoint.protocol === 'http:';
  64. this.transport = isHttp ? http : https;
  65. /**
  66. * Internal Tracking variables
  67. */
  68. this._credentials = null;
  69. }
  70. getRequestConfig() {
  71. const hostValue = this.stsEndpoint.hostname;
  72. const portValue = this.stsEndpoint.port;
  73. const qryParams = new _url.URLSearchParams({
  74. Action: this.action,
  75. Version: '2011-06-15'
  76. });
  77. qryParams.set('DurationSeconds', this.expirySeconds.toString());
  78. if (this.policy) {
  79. qryParams.set('Policy', this.policy);
  80. }
  81. if (this.roleArn) {
  82. qryParams.set('RoleArn', this.roleArn);
  83. }
  84. if (this.roleSessionName != null) {
  85. qryParams.set('RoleSessionName', this.roleSessionName);
  86. }
  87. if (this.token != null) {
  88. qryParams.set('Token', this.token);
  89. }
  90. if (this.webIdentityToken) {
  91. qryParams.set('WebIdentityToken', this.webIdentityToken);
  92. }
  93. if (this.externalId) {
  94. qryParams.set('ExternalId', this.externalId);
  95. }
  96. const urlParams = qryParams.toString();
  97. const contentSha256 = (0, _helper.toSha256)(urlParams);
  98. const date = new Date();
  99. const requestOptions = {
  100. hostname: hostValue,
  101. port: portValue,
  102. path: '/',
  103. protocol: this.stsEndpoint.protocol,
  104. method: 'POST',
  105. headers: {
  106. 'Content-Type': 'application/x-www-form-urlencoded',
  107. 'content-length': urlParams.length.toString(),
  108. host: hostValue,
  109. 'x-amz-date': (0, _helper.makeDateLong)(date),
  110. 'x-amz-content-sha256': contentSha256
  111. },
  112. agent: this.transportAgent
  113. };
  114. requestOptions.headers.authorization = (0, _signing.signV4ByServiceName)(requestOptions, this.accessKey, this.secretKey, this.region, date, contentSha256, 'sts');
  115. return {
  116. requestOptions,
  117. requestData: urlParams
  118. };
  119. }
  120. async performRequest() {
  121. const {
  122. requestOptions,
  123. requestData
  124. } = this.getRequestConfig();
  125. const res = await (0, _request.request)(this.transport, requestOptions, requestData);
  126. const body = await (0, _response.readAsString)(res);
  127. return (0, _helper.parseXml)(body);
  128. }
  129. parseCredentials(respObj) {
  130. if (respObj.ErrorResponse) {
  131. var _respObj$ErrorRespons, _respObj$ErrorRespons2, _respObj$ErrorRespons3, _respObj$ErrorRespons4;
  132. throw new Error(`Unable to obtain credentials: ${(_respObj$ErrorRespons = respObj.ErrorResponse) === null || _respObj$ErrorRespons === void 0 ? void 0 : (_respObj$ErrorRespons2 = _respObj$ErrorRespons.Error) === null || _respObj$ErrorRespons2 === void 0 ? void 0 : _respObj$ErrorRespons2.Code} ${(_respObj$ErrorRespons3 = respObj.ErrorResponse) === null || _respObj$ErrorRespons3 === void 0 ? void 0 : (_respObj$ErrorRespons4 = _respObj$ErrorRespons3.Error) === null || _respObj$ErrorRespons4 === void 0 ? void 0 : _respObj$ErrorRespons4.Message}`, {
  133. cause: respObj
  134. });
  135. }
  136. const {
  137. AssumeRoleResponse: {
  138. AssumeRoleResult: {
  139. Credentials: {
  140. AccessKeyId: accessKey,
  141. SecretAccessKey: secretKey,
  142. SessionToken: sessionToken,
  143. Expiration: expiresAt
  144. }
  145. }
  146. }
  147. } = respObj;
  148. this.accessExpiresAt = expiresAt;
  149. return new _Credentials.Credentials({
  150. accessKey,
  151. secretKey,
  152. sessionToken
  153. });
  154. }
  155. async refreshCredentials() {
  156. try {
  157. const assumeRoleCredentials = await this.performRequest();
  158. this._credentials = this.parseCredentials(assumeRoleCredentials);
  159. } catch (err) {
  160. throw new Error(`Failed to get Credentials: ${err}`, {
  161. cause: err
  162. });
  163. }
  164. return this._credentials;
  165. }
  166. async getCredentials() {
  167. if (this._credentials && !this.isAboutToExpire()) {
  168. return this._credentials;
  169. }
  170. this._credentials = await this.refreshCredentials();
  171. return this._credentials;
  172. }
  173. isAboutToExpire() {
  174. const expiresAt = new Date(this.accessExpiresAt);
  175. const provisionalExpiry = new Date(Date.now() + 1000 * 10); // check before 10 seconds.
  176. return provisionalExpiry > expiresAt;
  177. }
  178. }
  179. // deprecated default export, please use named exports.
  180. // keep for backward compatibility.
  181. // eslint-disable-next-line import/no-default-export
  182. exports.AssumeRoleProvider = AssumeRoleProvider;
  183. var _default = AssumeRoleProvider;
  184. exports.default = _default;
  185. //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJodHRwIiwiX2ludGVyb3BSZXF1aXJlV2lsZGNhcmQiLCJyZXF1aXJlIiwiaHR0cHMiLCJfdXJsIiwiX0NyZWRlbnRpYWxQcm92aWRlciIsIl9DcmVkZW50aWFscyIsIl9oZWxwZXIiLCJfcmVxdWVzdCIsIl9yZXNwb25zZSIsIl9zaWduaW5nIiwiZSIsInQiLCJXZWFrTWFwIiwiciIsIm4iLCJfX2VzTW9kdWxlIiwibyIsImkiLCJmIiwiX19wcm90b19fIiwiZGVmYXVsdCIsImhhcyIsImdldCIsInNldCIsImhhc093blByb3BlcnR5IiwiY2FsbCIsIk9iamVjdCIsImRlZmluZVByb3BlcnR5IiwiZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yIiwiZGVmYXVsdEV4cGlyeVNlY29uZHMiLCJBc3N1bWVSb2xlUHJvdmlkZXIiLCJDcmVkZW50aWFsUHJvdmlkZXIiLCJhY2Nlc3NFeHBpcmVzQXQiLCJjb25zdHJ1Y3RvciIsInN0c0VuZHBvaW50IiwiYWNjZXNzS2V5Iiwic2VjcmV0S2V5IiwiZHVyYXRpb25TZWNvbmRzIiwic2Vzc2lvblRva2VuIiwicG9saWN5IiwicmVnaW9uIiwicm9sZUFybiIsInJvbGVTZXNzaW9uTmFtZSIsImV4dGVybmFsSWQiLCJ0b2tlbiIsIndlYklkZW50aXR5VG9rZW4iLCJhY3Rpb24iLCJ0cmFuc3BvcnRBZ2VudCIsInVuZGVmaW5lZCIsIlVSTCIsInBhcnNlSW50IiwiZXhwaXJ5U2Vjb25kcyIsImlzSHR0cCIsInByb3RvY29sIiwidHJhbnNwb3J0IiwiX2NyZWRlbnRpYWxzIiwiZ2V0UmVxdWVzdENvbmZpZyIsImhvc3RWYWx1ZSIsImhvc3RuYW1lIiwicG9ydFZhbHVlIiwicG9ydCIsInFyeVBhcmFtcyIsIlVSTFNlYXJjaFBhcmFtcyIsIkFjdGlvbiIsIlZlcnNpb24iLCJ0b1N0cmluZyIsInVybFBhcmFtcyIsImNvbnRlbnRTaGEyNTYiLCJ0b1NoYTI1NiIsImRhdGUiLCJEYXRlIiwicmVxdWVzdE9wdGlvbnMiLCJwYXRoIiwibWV0aG9kIiwiaGVhZGVycyIsImxlbmd0aCIsImhvc3QiLCJtYWtlRGF0ZUxvbmciLCJhZ2VudCIsImF1dGhvcml6YXRpb24iLCJzaWduVjRCeVNlcnZpY2VOYW1lIiwicmVxdWVzdERhdGEiLCJwZXJmb3JtUmVxdWVzdCIsInJlcyIsInJlcXVlc3QiLCJib2R5IiwicmVhZEFzU3RyaW5nIiwicGFyc2VYbWwiLCJwYXJzZUNyZWRlbnRpYWxzIiwicmVzcE9iaiIsIkVycm9yUmVzcG9uc2UiLCJfcmVzcE9iaiRFcnJvclJlc3BvbnMiLCJfcmVzcE9iaiRFcnJvclJlc3BvbnMyIiwiX3Jlc3BPYmokRXJyb3JSZXNwb25zMyIsIl9yZXNwT2JqJEVycm9yUmVzcG9uczQiLCJFcnJvciIsIkNvZGUiLCJNZXNzYWdlIiwiY2F1c2UiLCJBc3N1bWVSb2xlUmVzcG9uc2UiLCJBc3N1bWVSb2xlUmVzdWx0IiwiQ3JlZGVudGlhbHMiLCJBY2Nlc3NLZXlJZCIsIlNlY3JldEFjY2Vzc0tleSIsIlNlc3Npb25Ub2tlbiIsIkV4cGlyYXRpb24iLCJleHBpcmVzQXQiLCJyZWZyZXNoQ3JlZGVudGlhbHMiLCJhc3N1bWVSb2xlQ3JlZGVudGlhbHMiLCJlcnIiLCJnZXRDcmVkZW50aWFscyIsImlzQWJvdXRUb0V4cGlyZSIsInByb3Zpc2lvbmFsRXhwaXJ5Iiwibm93IiwiZXhwb3J0cyIsIl9kZWZhdWx0Il0sInNvdXJjZXMiOlsiQXNzdW1lUm9sZVByb3ZpZGVyLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGh0dHAgZnJvbSAnbm9kZTpodHRwJ1xuaW1wb3J0ICogYXMgaHR0cHMgZnJvbSAnbm9kZTpodHRwcydcbmltcG9ydCB7IFVSTCwgVVJMU2VhcmNoUGFyYW1zIH0gZnJvbSAnbm9kZTp1cmwnXG5cbmltcG9ydCB7IENyZWRlbnRpYWxQcm92aWRlciB9IGZyb20gJy4vQ3JlZGVudGlhbFByb3ZpZGVyLnRzJ1xuaW1wb3J0IHsgQ3JlZGVudGlhbHMgfSBmcm9tICcuL0NyZWRlbnRpYWxzLnRzJ1xuaW1wb3J0IHsgbWFrZURhdGVMb25nLCBwYXJzZVhtbCwgdG9TaGEyNTYgfSBmcm9tICcuL2ludGVybmFsL2hlbHBlci50cydcbmltcG9ydCB7IHJlcXVlc3QgfSBmcm9tICcuL2ludGVybmFsL3JlcXVlc3QudHMnXG5pbXBvcnQgeyByZWFkQXNTdHJpbmcgfSBmcm9tICcuL2ludGVybmFsL3Jlc3BvbnNlLnRzJ1xuaW1wb3J0IHR5cGUgeyBUcmFuc3BvcnQgfSBmcm9tICcuL2ludGVybmFsL3R5cGUudHMnXG5pbXBvcnQgeyBzaWduVjRCeVNlcnZpY2VOYW1lIH0gZnJvbSAnLi9zaWduaW5nLnRzJ1xuXG4vKipcbiAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL1NUUy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9Bc3N1bWVSb2xlLmh0bWxcbiAqL1xudHlwZSBDcmVkZW50aWFsUmVzcG9uc2UgPSB7XG4gIEVycm9yUmVzcG9uc2U/OiB7XG4gICAgRXJyb3I/OiB7XG4gICAgICBDb2RlPzogc3RyaW5nXG4gICAgICBNZXNzYWdlPzogc3RyaW5nXG4gICAgfVxuICB9XG5cbiAgQXNzdW1lUm9sZVJlc3BvbnNlOiB7XG4gICAgQXNzdW1lUm9sZVJlc3VsdDoge1xuICAgICAgQ3JlZGVudGlhbHM6IHtcbiAgICAgICAgQWNjZXNzS2V5SWQ6IHN0cmluZ1xuICAgICAgICBTZWNyZXRBY2Nlc3NLZXk6IHN0cmluZ1xuICAgICAgICBTZXNzaW9uVG9rZW46IHN0cmluZ1xuICAgICAgICBFeHBpcmF0aW9uOiBzdHJpbmdcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGludGVyZmFjZSBBc3N1bWVSb2xlUHJvdmlkZXJPcHRpb25zIHtcbiAgc3RzRW5kcG9pbnQ6IHN0cmluZ1xuICBhY2Nlc3NLZXk6IHN0cmluZ1xuICBzZWNyZXRLZXk6IHN0cmluZ1xuICBkdXJhdGlvblNlY29uZHM/OiBudW1iZXJcbiAgc2Vzc2lvblRva2VuPzogc3RyaW5nXG4gIHBvbGljeT86IHN0cmluZ1xuICByZWdpb24/OiBzdHJpbmdcbiAgcm9sZUFybj86IHN0cmluZ1xuICByb2xlU2Vzc2lvbk5hbWU/OiBzdHJpbmdcbiAgZXh0ZXJuYWxJZD86IHN0cmluZ1xuICB0b2tlbj86IHN0cmluZ1xuICB3ZWJJZGVudGl0eVRva2VuPzogc3RyaW5nXG4gIGFjdGlvbj86IHN0cmluZ1xuICB0cmFuc3BvcnRBZ2VudD86IGh0dHAuQWdlbnRcbn1cblxuY29uc3QgZGVmYXVsdEV4cGlyeVNlY29uZHMgPSA5MDBcblxuZXhwb3J0IGNsYXNzIEFzc3VtZVJvbGVQcm92aWRlciBleHRlbmRzIENyZWRlbnRpYWxQcm92aWRlciB7XG4gIHByaXZhdGUgcmVhZG9ubHkgc3RzRW5kcG9pbnQ6IFVSTFxuICBwcml2YXRlIHJlYWRvbmx5IGFjY2Vzc0tleTogc3RyaW5nXG4gIHByaXZhdGUgcmVhZG9ubHkgc2VjcmV0S2V5OiBzdHJpbmdcbiAgcHJpdmF0ZSByZWFkb25seSBkdXJhdGlvblNlY29uZHM6IG51bWJlclxuICBwcml2YXRlIHJlYWRvbmx5IHBvbGljeT86IHN0cmluZ1xuICBwcml2YXRlIHJlYWRvbmx5IHJlZ2lvbjogc3RyaW5nXG4gIHByaXZhdGUgcmVhZG9ubHkgcm9sZUFybj86IHN0cmluZ1xuICBwcml2YXRlIHJlYWRvbmx5IHJvbGVTZXNzaW9uTmFtZT86IHN0cmluZ1xuICBwcml2YXRlIHJlYWRvbmx5IGV4dGVybmFsSWQ/OiBzdHJpbmdcbiAgcHJpdmF0ZSByZWFkb25seSB0b2tlbj86IHN0cmluZ1xuICBwcml2YXRlIHJlYWRvbmx5IHdlYklkZW50aXR5VG9rZW4/OiBzdHJpbmdcbiAgcHJpdmF0ZSByZWFkb25seSBhY3Rpb246IHN0cmluZ1xuXG4gIHByaXZhdGUgX2NyZWRlbnRpYWxzOiBDcmVkZW50aWFscyB8IG51bGxcbiAgcHJpdmF0ZSByZWFkb25seSBleHBpcnlTZWNvbmRzOiBudW1iZXJcbiAgcHJpdmF0ZSBhY2Nlc3NFeHBpcmVzQXQgPSAnJ1xuICBwcml2YXRlIHJlYWRvbmx5IHRyYW5zcG9ydEFnZW50PzogaHR0cC5BZ2VudFxuXG4gIHByaXZhdGUgcmVhZG9ubHkgdHJhbnNwb3J0OiBUcmFuc3BvcnRcblxuICBjb25zdHJ1Y3Rvcih7XG4gICAgc3RzRW5kcG9pbnQsXG4gICAgYWNjZXNzS2V5LFxuICAgIHNlY3JldEtleSxcbiAgICBkdXJhdGlvblNlY29uZHMgPSBkZWZhdWx0RXhwaXJ5U2Vjb25kcyxcbiAgICBzZXNzaW9uVG9rZW4sXG4gICAgcG9saWN5LFxuICAgIHJlZ2lvbiA9ICcnLFxuICAgIHJvbGVBcm4sXG4gICAgcm9sZVNlc3Npb25OYW1lLFxuICAgIGV4dGVybmFsSWQsXG4gICAgdG9rZW4sXG4gICAgd2ViSWRlbnRpdHlUb2tlbixcbiAgICBhY3Rpb24gPSAnQXNzdW1lUm9sZScsXG4gICAgdHJhbnNwb3J0QWdlbnQgPSB1bmRlZmluZWQsXG4gIH06IEFzc3VtZVJvbGVQcm92aWRlck9wdGlvbnMpIHtcbiAgICBzdXBlcih7IGFjY2Vzc0tleSwgc2VjcmV0S2V5LCBzZXNzaW9uVG9rZW4gfSlcblxuICAgIHRoaXMuc3RzRW5kcG9pbnQgPSBuZXcgVVJMKHN0c0VuZHBvaW50KVxuICAgIHRoaXMuYWNjZXNzS2V5ID0gYWNjZXNzS2V5XG4gICAgdGhpcy5zZWNyZXRLZXkgPSBzZWNyZXRLZXlcbiAgICB0aGlzLnBvbGljeSA9IHBvbGljeVxuICAgIHRoaXMucmVnaW9uID0gcmVnaW9uXG4gICAgdGhpcy5yb2xlQXJuID0gcm9sZUFyblxuICAgIHRoaXMucm9sZVNlc3Npb25OYW1lID0gcm9sZVNlc3Npb25OYW1lXG4gICAgdGhpcy5leHRlcm5hbElkID0gZXh0ZXJuYWxJZFxuICAgIHRoaXMudG9rZW4gPSB0b2tlblxuICAgIHRoaXMud2ViSWRlbnRpdHlUb2tlbiA9IHdlYklkZW50aXR5VG9rZW5cbiAgICB0aGlzLmFjdGlvbiA9IGFjdGlvblxuXG4gICAgdGhpcy5kdXJhdGlvblNlY29uZHMgPSBwYXJzZUludChkdXJhdGlvblNlY29uZHMgYXMgdW5rbm93biBhcyBzdHJpbmcpXG5cbiAgICBsZXQgZXhwaXJ5U2Vjb25kcyA9IHRoaXMuZHVyYXRpb25TZWNvbmRzXG4gICAgaWYgKHRoaXMuZHVyYXRpb25TZWNvbmRzIDwgZGVmYXVsdEV4cGlyeVNlY29uZHMpIHtcbiAgICAgIGV4cGlyeVNlY29uZHMgPSBkZWZhdWx0RXhwaXJ5U2Vjb25kc1xuICAgIH1cbiAgICB0aGlzLmV4cGlyeVNlY29uZHMgPSBleHBpcnlTZWNvbmRzIC8vIGZvciBjYWxjdWxhdGluZyByZWZyZXNoIG9mIGNyZWRlbnRpYWxzLlxuXG4gICAgLy8gQnkgZGVmYXVsdCwgbm9kZWpzIHVzZXMgYSBnbG9iYWwgYWdlbnQgaWYgdGhlICdhZ2VudCcgcHJvcGVydHlcbiAgICAvLyBpcyBzZXQgdG8gdW5kZWZpbmVkLiBPdGhlcndpc2UsIGl0J3Mgb2theSB0byBhc3N1bWUgdGhlIHVzZXJzXG4gICAgLy8ga25vdyB3aGF0IHRoZXkncmUgZG9pbmcgaWYgdGhleSBzcGVjaWZ5IGEgY3VzdG9tIHRyYW5zcG9ydCBhZ2VudC5cbiAgICB0aGlzLnRyYW5zcG9ydEFnZW50ID0gdHJhbnNwb3J0QWdlbnRcbiAgICBjb25zdCBpc0h0dHA6IGJvb2xlYW4gPSB0aGlzLnN0c0VuZHBvaW50LnByb3RvY29sID09PSAnaHR0cDonXG4gICAgdGhpcy50cmFuc3BvcnQgPSBpc0h0dHAgPyBodHRwIDogaHR0cHNcblxuICAgIC8qKlxuICAgICAqIEludGVybmFsIFRyYWNraW5nIHZhcmlhYmxlc1xuICAgICAqL1xuICAgIHRoaXMuX2NyZWRlbnRpYWxzID0gbnVsbFxuICB9XG5cbiAgZ2V0UmVxdWVzdENvbmZpZygpOiB7XG4gICAgcmVxdWVzdE9wdGlvbnM6IGh0dHAuUmVxdWVzdE9wdGlvbnNcbiAgICByZXF1ZXN0RGF0YTogc3RyaW5nXG4gIH0ge1xuICAgIGNvbnN0IGhvc3RWYWx1ZSA9IHRoaXMuc3RzRW5kcG9pbnQuaG9zdG5hbWVcbiAgICBjb25zdCBwb3J0VmFsdWUgPSB0aGlzLnN0c0VuZHBvaW50LnBvcnRcbiAgICBjb25zdCBxcnlQYXJhbXMgPSBuZXcgVVJMU2VhcmNoUGFyYW1zKHsgQWN0aW9uOiB0aGlzLmFjdGlvbiwgVmVyc2lvbjogJzIwMTEtMDYtMTUnIH0pXG5cbiAgICBxcnlQYXJhbXMuc2V0KCdEdXJhdGlvblNlY29uZHMnLCB0aGlzLmV4cGlyeVNlY29uZHMudG9TdHJpbmcoKSlcblxuICAgIGlmICh0aGlzLnBvbGljeSkge1xuICAgICAgcXJ5UGFyYW1zLnNldCgnUG9saWN5JywgdGhpcy5wb2xpY3kpXG4gICAgfVxuICAgIGlmICh0aGlzLnJvbGVBcm4pIHtcbiAgICAgIHFyeVBhcmFtcy5zZXQoJ1JvbGVBcm4nLCB0aGlzLnJvbGVBcm4pXG4gICAgfVxuXG4gICAgaWYgKHRoaXMucm9sZVNlc3Npb25OYW1lICE9IG51bGwpIHtcbiAgICAgIHFyeVBhcmFtcy5zZXQoJ1JvbGVTZXNzaW9uTmFtZScsIHRoaXMucm9sZVNlc3Npb25OYW1lKVxuICAgIH1cbiAgICBpZiAodGhpcy50b2tlbiAhPSBudWxsKSB7XG4gICAgICBxcnlQYXJhbXMuc2V0KCdUb2tlbicsIHRoaXMudG9rZW4pXG4gICAgfVxuXG4gICAgaWYgKHRoaXMud2ViSWRlbnRpdHlUb2tlbikge1xuICAgICAgcXJ5UGFyYW1zLnNldCgnV2ViSWRlbnRpdHlUb2tlbicsIHRoaXMud2ViSWRlbnRpdHlUb2tlbilcbiAgICB9XG5cbiAgICBpZiAodGhpcy5leHRlcm5hbElkKSB7XG4gICAgICBxcnlQYXJhbXMuc2V0KCdFeHRlcm5hbElkJywgdGhpcy5leHRlcm5hbElkKVxuICAgIH1cblxuICAgIGNvbnN0IHVybFBhcmFtcyA9IHFyeVBhcmFtcy50b1N0cmluZygpXG4gICAgY29uc3QgY29udGVudFNoYTI1NiA9IHRvU2hhMjU2KHVybFBhcmFtcylcblxuICAgIGNvbnN0IGRhdGUgPSBuZXcgRGF0ZSgpXG5cbiAgICBjb25zdCByZXF1ZXN0T3B0aW9ucyA9IHtcbiAgICAgIGhvc3RuYW1lOiBob3N0VmFsdWUsXG4gICAgICBwb3J0OiBwb3J0VmFsdWUsXG4gICAgICBwYXRoOiAnLycsXG4gICAgICBwcm90b2NvbDogdGhpcy5zdHNFbmRwb2ludC5wcm90b2NvbCxcbiAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgaGVhZGVyczoge1xuICAgICAgICAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCcsXG4gICAgICAgICdjb250ZW50LWxlbmd0aCc6IHVybFBhcmFtcy5sZW5ndGgudG9TdHJpbmcoKSxcbiAgICAgICAgaG9zdDogaG9zdFZhbHVlLFxuICAgICAgICAneC1hbXotZGF0ZSc6IG1ha2VEYXRlTG9uZyhkYXRlKSxcbiAgICAgICAgJ3gtYW16LWNvbnRlbnQtc2hhMjU2JzogY29udGVudFNoYTI1NixcbiAgICAgIH0gYXMgUmVjb3JkPHN0cmluZywgc3RyaW5nPixcbiAgICAgIGFnZW50OiB0aGlzLnRyYW5zcG9ydEFnZW50LFxuICAgIH0gc2F0aXNmaWVzIGh0dHAuUmVxdWVzdE9wdGlvbnNcblxuICAgIHJlcXVlc3RPcHRpb25zLmhlYWRlcnMuYXV0aG9yaXphdGlvbiA9IHNpZ25WNEJ5U2VydmljZU5hbWUoXG4gICAgICByZXF1ZXN0T3B0aW9ucyxcbiAgICAgIHRoaXMuYWNjZXNzS2V5LFxuICAgICAgdGhpcy5zZWNyZXRLZXksXG4gICAgICB0aGlzLnJlZ2lvbixcbiAgICAgIGRhdGUsXG4gICAgICBjb250ZW50U2hhMjU2LFxuICAgICAgJ3N0cycsXG4gICAgKVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIHJlcXVlc3RPcHRpb25zLFxuICAgICAgcmVxdWVzdERhdGE6IHVybFBhcmFtcyxcbiAgICB9XG4gIH1cblxuICBhc3luYyBwZXJmb3JtUmVxdWVzdCgpOiBQcm9taXNlPENyZWRlbnRpYWxSZXNwb25zZT4ge1xuICAgIGNvbnN0IHsgcmVxdWVzdE9wdGlvbnMsIHJlcXVlc3REYXRhIH0gPSB0aGlzLmdldFJlcXVlc3RDb25maWcoKVxuXG4gICAgY29uc3QgcmVzID0gYXdhaXQgcmVxdWVzdCh0aGlzLnRyYW5zcG9ydCwgcmVxdWVzdE9wdGlvbnMsIHJlcXVlc3REYXRhKVxuXG4gICAgY29uc3QgYm9keSA9IGF3YWl0IHJlYWRBc1N0cmluZyhyZXMpXG5cbiAgICByZXR1cm4gcGFyc2VYbWwoYm9keSlcbiAgfVxuXG4gIHBhcnNlQ3JlZGVudGlhbHMocmVzcE9iajogQ3JlZGVudGlhbFJlc3BvbnNlKTogQ3JlZGVudGlhbHMge1xuICAgIGlmIChyZXNwT2JqLkVycm9yUmVzcG9uc2UpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYFVuYWJsZSB0byBvYnRhaW4gY3JlZGVudGlhbHM6ICR7cmVzcE9iai5FcnJvclJlc3BvbnNlPy5FcnJvcj8uQ29kZX0gJHtyZXNwT2JqLkVycm9yUmVzcG9uc2U/LkVycm9yPy5NZXNzYWdlfWAsXG4gICAgICAgIHsgY2F1c2U6IHJlc3BPYmogfSxcbiAgICAgIClcbiAgICB9XG5cbiAgICBjb25zdCB7XG4gICAgICBBc3N1bWVSb2xlUmVzcG9uc2U6IHtcbiAgICAgICAgQXNzdW1lUm9sZVJlc3VsdDoge1xuICAgICAgICAgIENyZWRlbnRpYWxzOiB7XG4gICAgICAgICAgICBBY2Nlc3NLZXlJZDogYWNjZXNzS2V5LFxuICAgICAgICAgICAgU2VjcmV0QWNjZXNzS2V5OiBzZWNyZXRLZXksXG4gICAgICAgICAgICBTZXNzaW9uVG9rZW46IHNlc3Npb25Ub2tlbixcbiAgICAgICAgICAgIEV4cGlyYXRpb246IGV4cGlyZXNBdCxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9ID0gcmVzcE9ialxuXG4gICAgdGhpcy5hY2Nlc3NFeHBpcmVzQXQgPSBleHBpcmVzQXRcblxuICAgIHJldHVybiBuZXcgQ3JlZGVudGlhbHMoeyBhY2Nlc3NLZXksIHNlY3JldEtleSwgc2Vzc2lvblRva2VuIH0pXG4gIH1cblxuICBhc3luYyByZWZyZXNoQ3JlZGVudGlhbHMoKTogUHJvbWlzZTxDcmVkZW50aWFscz4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBhc3N1bWVSb2xlQ3JlZGVudGlhbHMgPSBhd2FpdCB0aGlzLnBlcmZvcm1SZXF1ZXN0KClcbiAgICAgIHRoaXMuX2NyZWRlbnRpYWxzID0gdGhpcy5wYXJzZUNyZWRlbnRpYWxzKGFzc3VtZVJvbGVDcmVkZW50aWFscylcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgRmFpbGVkIHRvIGdldCBDcmVkZW50aWFsczogJHtlcnJ9YCwgeyBjYXVzZTogZXJyIH0pXG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuX2NyZWRlbnRpYWxzXG4gIH1cblxuICBhc3luYyBnZXRDcmVkZW50aWFscygpOiBQcm9taXNlPENyZWRlbnRpYWxzPiB7XG4gICAgaWYgKHRoaXMuX2NyZWRlbnRpYWxzICYmICF0aGlzLmlzQWJvdXRUb0V4cGlyZSgpKSB7XG4gICAgICByZXR1cm4gdGhpcy5fY3JlZGVudGlhbHNcbiAgICB9XG5cbiAgICB0aGlzLl9jcmVkZW50aWFscyA9IGF3YWl0IHRoaXMucmVmcmVzaENyZWRlbnRpYWxzKClcbiAgICByZXR1cm4gdGhpcy5fY3JlZGVudGlhbHNcbiAgfVxuXG4gIGlzQWJvdXRUb0V4cGlyZSgpIHtcbiAgICBjb25zdCBleHBpcmVzQXQgPSBuZXcgRGF0ZSh0aGlzLmFjY2Vzc0V4cGlyZXNBdClcbiAgICBjb25zdCBwcm92aXNpb25hbEV4cGlyeSA9IG5ldyBEYXRlKERhdGUubm93KCkgKyAxMDAwICogMTApIC8vIGNoZWNrIGJlZm9yZSAxMCBzZWNvbmRzLlxuICAgIHJldHVybiBwcm92aXNpb25hbEV4cGlyeSA+IGV4cGlyZXNBdFxuICB9XG59XG5cbi8vIGRlcHJlY2F0ZWQgZGVmYXVsdCBleHBvcnQsIHBsZWFzZSB1c2UgbmFtZWQgZXhwb3J0cy5cbi8vIGtlZXAgZm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHkuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgaW1wb3J0L25vLWRlZmF1bHQt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