minio
Version:
S3 Compatible Cloud Storage client
183 lines (178 loc) • 24.5 kB
JavaScript
import * as http from "http";
import * as https from "https";
import { URL, URLSearchParams } from "url";
import { CredentialProvider } from "./CredentialProvider.mjs";
import { Credentials } from "./Credentials.mjs";
import { makeDateLong, parseXml, toSha256 } from "./internal/helper.mjs";
import { request } from "./internal/request.mjs";
import { readAsString } from "./internal/response.mjs";
import { signV4ByServiceName } from "./signing.mjs";
/**
* @see https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html
*/
const defaultExpirySeconds = 900;
export class AssumeRoleProvider extends CredentialProvider {
accessExpiresAt = '';
constructor({
stsEndpoint,
accessKey,
secretKey,
durationSeconds = defaultExpirySeconds,
sessionToken,
policy,
region = '',
roleArn,
roleSessionName,
externalId,
token,
webIdentityToken,
action = 'AssumeRole',
transportAgent = undefined
}) {
super({
accessKey,
secretKey,
sessionToken
});
this.stsEndpoint = new URL(stsEndpoint);
this.accessKey = accessKey;
this.secretKey = secretKey;
this.policy = policy;
this.region = region;
this.roleArn = roleArn;
this.roleSessionName = roleSessionName;
this.externalId = externalId;
this.token = token;
this.webIdentityToken = webIdentityToken;
this.action = action;
this.durationSeconds = parseInt(durationSeconds);
let expirySeconds = this.durationSeconds;
if (this.durationSeconds < defaultExpirySeconds) {
expirySeconds = defaultExpirySeconds;
}
this.expirySeconds = expirySeconds; // for calculating refresh of credentials.
// By default, nodejs uses a global agent if the 'agent' property
// is set to undefined. Otherwise, it's okay to assume the users
// know what they're doing if they specify a custom transport agent.
this.transportAgent = transportAgent;
const isHttp = this.stsEndpoint.protocol === 'http:';
this.transport = isHttp ? http : https;
/**
* Internal Tracking variables
*/
this._credentials = null;
}
getRequestConfig() {
const hostValue = this.stsEndpoint.hostname;
const portValue = this.stsEndpoint.port;
const qryParams = new URLSearchParams({
Action: this.action,
Version: '2011-06-15'
});
qryParams.set('DurationSeconds', this.expirySeconds.toString());
if (this.policy) {
qryParams.set('Policy', this.policy);
}
if (this.roleArn) {
qryParams.set('RoleArn', this.roleArn);
}
if (this.roleSessionName != null) {
qryParams.set('RoleSessionName', this.roleSessionName);
}
if (this.token != null) {
qryParams.set('Token', this.token);
}
if (this.webIdentityToken) {
qryParams.set('WebIdentityToken', this.webIdentityToken);
}
if (this.externalId) {
qryParams.set('ExternalId', this.externalId);
}
const urlParams = qryParams.toString();
const contentSha256 = toSha256(urlParams);
const date = new Date();
const requestOptions = {
hostname: hostValue,
port: portValue,
path: '/',
protocol: this.stsEndpoint.protocol,
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'content-length': urlParams.length.toString(),
host: hostValue,
'x-amz-date': makeDateLong(date),
'x-amz-content-sha256': contentSha256
},
agent: this.transportAgent
};
requestOptions.headers.authorization = signV4ByServiceName(requestOptions, this.accessKey, this.secretKey, this.region, date, contentSha256, 'sts');
return {
requestOptions,
requestData: urlParams
};
}
async performRequest() {
const {
requestOptions,
requestData
} = this.getRequestConfig();
const res = await request(this.transport, requestOptions, requestData);
const body = await readAsString(res);
return parseXml(body);
}
parseCredentials(respObj) {
if (respObj.ErrorResponse) {
var _respObj$ErrorRespons, _respObj$ErrorRespons2, _respObj$ErrorRespons3, _respObj$ErrorRespons4;
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}`, {
cause: respObj
});
}
const {
AssumeRoleResponse: {
AssumeRoleResult: {
Credentials: {
AccessKeyId: accessKey,
SecretAccessKey: secretKey,
SessionToken: sessionToken,
Expiration: expiresAt
}
}
}
} = respObj;
this.accessExpiresAt = expiresAt;
return new Credentials({
accessKey,
secretKey,
sessionToken
});
}
async refreshCredentials() {
try {
const assumeRoleCredentials = await this.performRequest();
this._credentials = this.parseCredentials(assumeRoleCredentials);
} catch (err) {
throw new Error(`Failed to get Credentials: ${err}`, {
cause: err
});
}
return this._credentials;
}
async getCredentials() {
if (this._credentials && !this.isAboutToExpire()) {
return this._credentials;
}
this._credentials = await this.refreshCredentials();
return this._credentials;
}
isAboutToExpire() {
const expiresAt = new Date(this.accessExpiresAt);
const provisionalExpiry = new Date(Date.now() + 1000 * 10); // check before 10 seconds.
return provisionalExpiry > expiresAt;
}
}
// deprecated default export, please use named exports.
// keep for backward compatibility.
// eslint-disable-next-line import/no-default-export
export default AssumeRoleProvider;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJodHRwIiwiaHR0cHMiLCJVUkwiLCJVUkxTZWFyY2hQYXJhbXMiLCJDcmVkZW50aWFsUHJvdmlkZXIiLCJDcmVkZW50aWFscyIsIm1ha2VEYXRlTG9uZyIsInBhcnNlWG1sIiwidG9TaGEyNTYiLCJyZXF1ZXN0IiwicmVhZEFzU3RyaW5nIiwic2lnblY0QnlTZXJ2aWNlTmFtZSIsImRlZmF1bHRFeHBpcnlTZWNvbmRzIiwiQXNzdW1lUm9sZVByb3ZpZGVyIiwiYWNjZXNzRXhwaXJlc0F0IiwiY29uc3RydWN0b3IiLCJzdHNFbmRwb2ludCIsImFjY2Vzc0tleSIsInNlY3JldEtleSIsImR1cmF0aW9uU2Vjb25kcyIsInNlc3Npb25Ub2tlbiIsInBvbGljeSIsInJlZ2lvbiIsInJvbGVBcm4iLCJyb2xlU2Vzc2lvbk5hbWUiLCJleHRlcm5hbElkIiwidG9rZW4iLCJ3ZWJJZGVudGl0eVRva2VuIiwiYWN0aW9uIiwidHJhbnNwb3J0QWdlbnQiLCJ1bmRlZmluZWQiLCJwYXJzZUludCIsImV4cGlyeVNlY29uZHMiLCJpc0h0dHAiLCJwcm90b2NvbCIsInRyYW5zcG9ydCIsIl9jcmVkZW50aWFscyIsImdldFJlcXVlc3RDb25maWciLCJob3N0VmFsdWUiLCJob3N0bmFtZSIsInBvcnRWYWx1ZSIsInBvcnQiLCJxcnlQYXJhbXMiLCJBY3Rpb24iLCJWZXJzaW9uIiwic2V0IiwidG9TdHJpbmciLCJ1cmxQYXJhbXMiLCJjb250ZW50U2hhMjU2IiwiZGF0ZSIsIkRhdGUiLCJyZXF1ZXN0T3B0aW9ucyIsInBhdGgiLCJtZXRob2QiLCJoZWFkZXJzIiwibGVuZ3RoIiwiaG9zdCIsImFnZW50IiwiYXV0aG9yaXphdGlvbiIsInJlcXVlc3REYXRhIiwicGVyZm9ybVJlcXVlc3QiLCJyZXMiLCJib2R5IiwicGFyc2VDcmVkZW50aWFscyIsInJlc3BPYmoiLCJFcnJvclJlc3BvbnNlIiwiX3Jlc3BPYmokRXJyb3JSZXNwb25zIiwiX3Jlc3BPYmokRXJyb3JSZXNwb25zMiIsIl9yZXNwT2JqJEVycm9yUmVzcG9uczMiLCJfcmVzcE9iaiRFcnJvclJlc3BvbnM0IiwiRXJyb3IiLCJDb2RlIiwiTWVzc2FnZSIsImNhdXNlIiwiQXNzdW1lUm9sZVJlc3BvbnNlIiwiQXNzdW1lUm9sZVJlc3VsdCIsIkFjY2Vzc0tleUlkIiwiU2VjcmV0QWNjZXNzS2V5IiwiU2Vzc2lvblRva2VuIiwiRXhwaXJhdGlvbiIsImV4cGlyZXNBdCIsInJlZnJlc2hDcmVkZW50aWFscyIsImFzc3VtZVJvbGVDcmVkZW50aWFscyIsImVyciIsImdldENyZWRlbnRpYWxzIiwiaXNBYm91dFRvRXhwaXJlIiwicHJvdmlzaW9uYWxFeHBpcnkiLCJub3ciXSwic291cmNlcyI6WyJBc3N1bWVSb2xlUHJvdmlkZXIudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgaHR0cCBmcm9tICdub2RlOmh0dHAnXG5pbXBvcnQgKiBhcyBodHRwcyBmcm9tICdub2RlOmh0dHBzJ1xuaW1wb3J0IHsgVVJMLCBVUkxTZWFyY2hQYXJhbXMgfSBmcm9tICdub2RlOnVybCdcblxuaW1wb3J0IHsgQ3JlZGVudGlhbFByb3ZpZGVyIH0gZnJvbSAnLi9DcmVkZW50aWFsUHJvdmlkZXIudHMnXG5pbXBvcnQgeyBDcmVkZW50aWFscyB9IGZyb20gJy4vQ3JlZGVudGlhbHMudHMnXG5pbXBvcnQgeyBtYWtlRGF0ZUxvbmcsIHBhcnNlWG1sLCB0b1NoYTI1NiB9IGZyb20gJy4vaW50ZXJuYWwvaGVscGVyLnRzJ1xuaW1wb3J0IHsgcmVxdWVzdCB9IGZyb20gJy4vaW50ZXJuYWwvcmVxdWVzdC50cydcbmltcG9ydCB7IHJlYWRBc1N0cmluZyB9IGZyb20gJy4vaW50ZXJuYWwvcmVzcG9uc2UudHMnXG5pbXBvcnQgdHlwZSB7IFRyYW5zcG9ydCB9IGZyb20gJy4vaW50ZXJuYWwvdHlwZS50cydcbmltcG9ydCB7IHNpZ25WNEJ5U2VydmljZU5hbWUgfSBmcm9tICcuL3NpZ25pbmcudHMnXG5cbi8qKlxuICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vU1RTL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0Fzc3VtZVJvbGUuaHRtbFxuICovXG50eXBlIENyZWRlbnRpYWxSZXNwb25zZSA9IHtcbiAgRXJyb3JSZXNwb25zZT86IHtcbiAgICBFcnJvcj86IHtcbiAgICAgIENvZGU/OiBzdHJpbmdcbiAgICAgIE1lc3NhZ2U/OiBzdHJpbmdcbiAgICB9XG4gIH1cblxuICBBc3N1bWVSb2xlUmVzcG9uc2U6IHtcbiAgICBBc3N1bWVSb2xlUmVzdWx0OiB7XG4gICAgICBDcmVkZW50aWFsczoge1xuICAgICAgICBBY2Nlc3NLZXlJZDogc3RyaW5nXG4gICAgICAgIFNlY3JldEFjY2Vzc0tleTogc3RyaW5nXG4gICAgICAgIFNlc3Npb25Ub2tlbjogc3RyaW5nXG4gICAgICAgIEV4cGlyYXRpb246IHN0cmluZ1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIEFzc3VtZVJvbGVQcm92aWRlck9wdGlvbnMge1xuICBzdHNFbmRwb2ludDogc3RyaW5nXG4gIGFjY2Vzc0tleTogc3RyaW5nXG4gIHNlY3JldEtleTogc3RyaW5nXG4gIGR1cmF0aW9uU2Vjb25kcz86IG51bWJlclxuICBzZXNzaW9uVG9rZW4/OiBzdHJpbmdcbiAgcG9saWN5Pzogc3RyaW5nXG4gIHJlZ2lvbj86IHN0cmluZ1xuICByb2xlQXJuPzogc3RyaW5nXG4gIHJvbGVTZXNzaW9uTmFtZT86IHN0cmluZ1xuICBleHRlcm5hbElkPzogc3RyaW5nXG4gIHRva2VuPzogc3RyaW5nXG4gIHdlYklkZW50aXR5VG9rZW4/OiBzdHJpbmdcbiAgYWN0aW9uPzogc3RyaW5nXG4gIHRyYW5zcG9ydEFnZW50PzogaHR0cC5BZ2VudFxufVxuXG5jb25zdCBkZWZhdWx0RXhwaXJ5U2Vjb25kcyA9IDkwMFxuXG5leHBvcnQgY2xhc3MgQXNzdW1lUm9sZVByb3ZpZGVyIGV4dGVuZHMgQ3JlZGVudGlhbFByb3ZpZGVyIHtcbiAgcHJpdmF0ZSByZWFkb25seSBzdHNFbmRwb2ludDogVVJMXG4gIHByaXZhdGUgcmVhZG9ubHkgYWNjZXNzS2V5OiBzdHJpbmdcbiAgcHJpdmF0ZSByZWFkb25seSBzZWNyZXRLZXk6IHN0cmluZ1xuICBwcml2YXRlIHJlYWRvbmx5IGR1cmF0aW9uU2Vjb25kczogbnVtYmVyXG4gIHByaXZhdGUgcmVhZG9ubHkgcG9saWN5Pzogc3RyaW5nXG4gIHByaXZhdGUgcmVhZG9ubHkgcmVnaW9uOiBzdHJpbmdcbiAgcHJpdmF0ZSByZWFkb25seSByb2xlQXJuPzogc3RyaW5nXG4gIHByaXZhdGUgcmVhZG9ubHkgcm9sZVNlc3Npb25OYW1lPzogc3RyaW5nXG4gIHByaXZhdGUgcmVhZG9ubHkgZXh0ZXJuYWxJZD86IHN0cmluZ1xuICBwcml2YXRlIHJlYWRvbmx5IHRva2VuPzogc3RyaW5nXG4gIHByaXZhdGUgcmVhZG9ubHkgd2ViSWRlbnRpdHlUb2tlbj86IHN0cmluZ1xuICBwcml2YXRlIHJlYWRvbmx5IGFjdGlvbjogc3RyaW5nXG5cbiAgcHJpdmF0ZSBfY3JlZGVudGlhbHM6IENyZWRlbnRpYWxzIHwgbnVsbFxuICBwcml2YXRlIHJlYWRvbmx5IGV4cGlyeVNlY29uZHM6IG51bWJlclxuICBwcml2YXRlIGFjY2Vzc0V4cGlyZXNBdCA9ICcnXG4gIHByaXZhdGUgcmVhZG9ubHkgdHJhbnNwb3J0QWdlbnQ/OiBodHRwLkFnZW50XG5cbiAgcHJpdmF0ZSByZWFkb25seSB0cmFuc3BvcnQ6IFRyYW5zcG9ydFxuXG4gIGNvbnN0cnVjdG9yKHtcbiAgICBzdHNFbmRwb2ludCxcbiAgICBhY2Nlc3NLZXksXG4gICAgc2VjcmV0S2V5LFxuICAgIGR1cmF0aW9uU2Vjb25kcyA9IGRlZmF1bHRFeHBpcnlTZWNvbmRzLFxuICAgIHNlc3Npb25Ub2tlbixcbiAgICBwb2xpY3ksXG4gICAgcmVnaW9uID0gJycsXG4gICAgcm9sZUFybixcbiAgICByb2xlU2Vzc2lvbk5hbWUsXG4gICAgZXh0ZXJuYWxJZCxcbiAgICB0b2tlbixcbiAgICB3ZWJJZGVudGl0eVRva2VuLFxuICAgIGFjdGlvbiA9ICdBc3N1bWVSb2xlJyxcbiAgICB0cmFuc3BvcnRBZ2VudCA9IHVuZGVmaW5lZCxcbiAgfTogQXNzdW1lUm9sZVByb3ZpZGVyT3B0aW9ucykge1xuICAgIHN1cGVyKHsgYWNjZXNzS2V5LCBzZWNyZXRLZXksIHNlc3Npb25Ub2tlbiB9KVxuXG4gICAgdGhpcy5zdHNFbmRwb2ludCA9IG5ldyBVUkwoc3RzRW5kcG9pbnQpXG4gICAgdGhpcy5hY2Nlc3NLZXkgPSBhY2Nlc3NLZXlcbiAgICB0aGlzLnNlY3JldEtleSA9IHNlY3JldEtleVxuICAgIHRoaXMucG9saWN5ID0gcG9saWN5XG4gICAgdGhpcy5yZWdpb24gPSByZWdpb25cbiAgICB0aGlzLnJvbGVBcm4gPSByb2xlQXJuXG4gICAgdGhpcy5yb2xlU2Vzc2lvbk5hbWUgPSByb2xlU2Vzc2lvbk5hbWVcbiAgICB0aGlzLmV4dGVybmFsSWQgPSBleHRlcm5hbElkXG4gICAgdGhpcy50b2tlbiA9IHRva2VuXG4gICAgdGhpcy53ZWJJZGVudGl0eVRva2VuID0gd2ViSWRlbnRpdHlUb2tlblxuICAgIHRoaXMuYWN0aW9uID0gYWN0aW9uXG5cbiAgICB0aGlzLmR1cmF0aW9uU2Vjb25kcyA9IHBhcnNlSW50KGR1cmF0aW9uU2Vjb25kcyBhcyB1bmtub3duIGFzIHN0cmluZylcblxuICAgIGxldCBleHBpcnlTZWNvbmRzID0gdGhpcy5kdXJhdGlvblNlY29uZHNcbiAgICBpZiAodGhpcy5kdXJhdGlvblNlY29uZHMgPCBkZWZhdWx0RXhwaXJ5U2Vjb25kcykge1xuICAgICAgZXhwaXJ5U2Vjb25kcyA9IGRlZmF1bHRFeHBpcnlTZWNvbmRzXG4gICAgfVxuICAgIHRoaXMuZXhwaXJ5U2Vjb25kcyA9IGV4cGlyeVNlY29uZHMgLy8gZm9yIGNhbGN1bGF0aW5nIHJlZnJlc2ggb2YgY3JlZGVudGlhbHMuXG5cbiAgICAvLyBCeSBkZWZhdWx0LCBub2RlanMgdXNlcyBhIGdsb2JhbCBhZ2VudCBpZiB0aGUgJ2FnZW50JyBwcm9wZXJ0eVxuICAgIC8vIGlzIHNldCB0byB1bmRlZmluZWQuIE90aGVyd2lzZSwgaXQncyBva2F5IHRvIGFzc3VtZSB0aGUgdXNlcnNcbiAgICAvLyBrbm93IHdoYXQgdGhleSdyZSBkb2luZyBpZiB0aGV5IHNwZWNpZnkgYSBjdXN0b20gdHJhbnNwb3J0IGFnZW50LlxuICAgIHRoaXMudHJhbnNwb3J0QWdlbnQgPSB0cmFuc3BvcnRBZ2VudFxuICAgIGNvbnN0IGlzSHR0cDogYm9vbGVhbiA9IHRoaXMuc3RzRW5kcG9pbnQucHJvdG9jb2wgPT09ICdodHRwOidcbiAgICB0aGlzLnRyYW5zcG9ydCA9IGlzSHR0cCA/IGh0dHAgOiBodHRwc1xuXG4gICAgLyoqXG4gICAgICogSW50ZXJuYWwgVHJhY2tpbmcgdmFyaWFibGVzXG4gICAgICovXG4gICAgdGhpcy5fY3JlZGVudGlhbHMgPSBudWxsXG4gIH1cblxuICBnZXRSZXF1ZXN0Q29uZmlnKCk6IHtcbiAgICByZXF1ZXN0T3B0aW9uczogaHR0cC5SZXF1ZXN0T3B0aW9uc1xuICAgIHJlcXVlc3REYXRhOiBzdHJpbmdcbiAgfSB7XG4gICAgY29uc3QgaG9zdFZhbHVlID0gdGhpcy5zdHNFbmRwb2ludC5ob3N0bmFtZVxuICAgIGNvbnN0IHBvcnRWYWx1ZSA9IHRoaXMuc3RzRW5kcG9pbnQucG9ydFxuICAgIGNvbnN0IHFyeVBhcmFtcyA9IG5ldyBVUkxTZWFyY2hQYXJhbXMoeyBBY3Rpb246IHRoaXMuYWN0aW9uLCBWZXJzaW9uOiAnMjAxMS0wNi0xNScgfSlcblxuICAgIHFyeVBhcmFtcy5zZXQoJ0R1cmF0aW9uU2Vjb25kcycsIHRoaXMuZXhwaXJ5U2Vjb25kcy50b1N0cmluZygpKVxuXG4gICAgaWYgKHRoaXMucG9saWN5KSB7XG4gICAgICBxcnlQYXJhbXMuc2V0KCdQb2xpY3knLCB0aGlzLnBvbGljeSlcbiAgICB9XG4gICAgaWYgKHRoaXMucm9sZUFybikge1xuICAgICAgcXJ5UGFyYW1zLnNldCgnUm9sZUFybicsIHRoaXMucm9sZUFybilcbiAgICB9XG5cbiAgICBpZiAodGhpcy5yb2xlU2Vzc2lvbk5hbWUgIT0gbnVsbCkge1xuICAgICAgcXJ5UGFyYW1zLnNldCgnUm9sZVNlc3Npb25OYW1lJywgdGhpcy5yb2xlU2Vzc2lvbk5hbWUpXG4gICAgfVxuICAgIGlmICh0aGlzLnRva2VuICE9IG51bGwpIHtcbiAgICAgIHFyeVBhcmFtcy5zZXQoJ1Rva2VuJywgdGhpcy50b2tlbilcbiAgICB9XG5cbiAgICBpZiAodGhpcy53ZWJJZGVudGl0eVRva2VuKSB7XG4gICAgICBxcnlQYXJhbXMuc2V0KCdXZWJJZGVudGl0eVRva2VuJywgdGhpcy53ZWJJZGVudGl0eVRva2VuKVxuICAgIH1cblxuICAgIGlmICh0aGlzLmV4dGVybmFsSWQpIHtcbiAgICAgIHFyeVBhcmFtcy5zZXQoJ0V4dGVybmFsSWQnLCB0aGlzLmV4dGVybmFsSWQpXG4gICAgfVxuXG4gICAgY29uc3QgdXJsUGFyYW1zID0gcXJ5UGFyYW1zLnRvU3RyaW5nKClcbiAgICBjb25zdCBjb250ZW50U2hhMjU2ID0gdG9TaGEyNTYodXJsUGFyYW1zKVxuXG4gICAgY29uc3QgZGF0ZSA9IG5ldyBEYXRlKClcblxuICAgIGNvbnN0IHJlcXVlc3RPcHRpb25zID0ge1xuICAgICAgaG9zdG5hbWU6IGhvc3RWYWx1ZSxcbiAgICAgIHBvcnQ6IHBvcnRWYWx1ZSxcbiAgICAgIHBhdGg6ICcvJyxcbiAgICAgIHByb3RvY29sOiB0aGlzLnN0c0VuZHBvaW50LnByb3RvY29sLFxuICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICBoZWFkZXJzOiB7XG4gICAgICAgICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJyxcbiAgICAgICAgJ2NvbnRlbnQtbGVuZ3RoJzogdXJsUGFyYW1zLmxlbmd0aC50b1N0cmluZygpLFxuICAgICAgICBob3N0OiBob3N0VmFsdWUsXG4gICAgICAgICd4LWFtei1kYXRlJzogbWFrZURhdGVMb25nKGRhdGUpLFxuICAgICAgICAneC1hbXotY29udGVudC1zaGEyNTYnOiBjb250ZW50U2hhMjU2LFxuICAgICAgfSBhcyBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+LFxuICAgICAgYWdlbnQ6IHRoaXMudHJhbnNwb3J0QWdlbnQsXG4gICAgfSBzYXRpc2ZpZXMgaHR0cC5SZXF1ZXN0T3B0aW9uc1xuXG4gICAgcmVxdWVzdE9wdGlvbnMuaGVhZGVycy5hdXRob3JpemF0aW9uID0gc2lnblY0QnlTZXJ2aWNlTmFtZShcbiAgICAgIHJlcXVlc3RPcHRpb25zLFxuICAgICAgdGhpcy5hY2Nlc3NLZXksXG4gICAgICB0aGlzLnNlY3JldEtleSxcbiAgICAgIHRoaXMucmVnaW9uLFxuICAgICAgZGF0ZSxcbiAgICAgIGNvbnRlbnRTaGEyNTYsXG4gICAgICAnc3RzJyxcbiAgICApXG5cbiAgICByZXR1cm4ge1xuICAgICAgcmVxdWVzdE9wdGlvbnMsXG4gICAgICByZXF1ZXN0RGF0YTogdXJsUGFyYW1zLFxuICAgIH1cbiAgfVxuXG4gIGFzeW5jIHBlcmZvcm1SZXF1ZXN0KCk6IFByb21pc2U8Q3JlZGVudGlhbFJlc3BvbnNlPiB7XG4gICAgY29uc3QgeyByZXF1ZXN0T3B0aW9ucywgcmVxdWVzdERhdGEgfSA9IHRoaXMuZ2V0UmVxdWVzdENvbmZpZygpXG5cbiAgICBjb25zdCByZXMgPSBhd2FpdCByZXF1ZXN0KHRoaXMudHJhbnNwb3J0LCByZXF1ZXN0T3B0aW9ucywgcmVxdWVzdERhdGEpXG5cbiAgICBjb25zdCBib2R5ID0gYXdhaXQgcmVhZEFzU3RyaW5nKHJlcylcblxuICAgIHJldHVybiBwYXJzZVhtbChib2R5KVxuICB9XG5cbiAgcGFyc2VDcmVkZW50aWFscyhyZXNwT2JqOiBDcmVkZW50aWFsUmVzcG9uc2UpOiBDcmVkZW50aWFscyB7XG4gICAgaWYgKHJlc3BPYmouRXJyb3JSZXNwb25zZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgVW5hYmxlIHRvIG9idGFpbiBjcmVkZW50aWFsczogJHtyZXNwT2JqLkVycm9yUmVzcG9uc2U/LkVycm9yPy5Db2RlfSAke3Jlc3BPYmouRXJyb3JSZXNwb25zZT8uRXJyb3I/Lk1lc3NhZ2V9YCxcbiAgICAgICAgeyBjYXVzZTogcmVzcE9iaiB9LFxuICAgICAgKVxuICAgIH1cblxuICAgIGNvbnN0IHtcbiAgICAgIEFzc3VtZVJvbGVSZXNwb25zZToge1xuICAgICAgICBBc3N1bWVSb2xlUmVzdWx0OiB7XG4gICAgICAgICAgQ3JlZGVudGlhbHM6IHtcbiAgICAgICAgICAgIEFjY2Vzc0tleUlkOiBhY2Nlc3NLZXksXG4gICAgICAgICAgICBTZWNyZXRBY2Nlc3NLZXk6IHNlY3JldEtleSxcbiAgICAgICAgICAgIFNlc3Npb25Ub2tlbjogc2Vzc2lvblRva2VuLFxuICAgICAgICAgICAgRXhwaXJhdGlvbjogZXhwaXJlc0F0LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH0gPSByZXNwT2JqXG5cbiAgICB0aGlzLmFjY2Vzc0V4cGlyZXNBdCA9IGV4cGlyZXNBdFxuXG4gICAgcmV0dXJuIG5ldyBDcmVkZW50aWFscyh7IGFjY2Vzc0tleSwgc2VjcmV0S2V5LCBzZXNzaW9uVG9rZW4gfSlcbiAgfVxuXG4gIGFzeW5jIHJlZnJlc2hDcmVkZW50aWFscygpOiBQcm9taXNlPENyZWRlbnRpYWxzPiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGFzc3VtZVJvbGVDcmVkZW50aWFscyA9IGF3YWl0IHRoaXMucGVyZm9ybVJlcXVlc3QoKVxuICAgICAgdGhpcy5fY3JlZGVudGlhbHMgPSB0aGlzLnBhcnNlQ3JlZGVudGlhbHMoYXNzdW1lUm9sZUNyZWRlbnRpYWxzKVxuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBGYWlsZWQgdG8gZ2V0IENyZWRlbnRpYWxzOiAke2Vycn1gLCB7IGNhdXNlOiBlcnIgfSlcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5fY3JlZGVudGlhbHNcbiAgfVxuXG4gIGFzeW5jIGdldENyZWRlbnRpYWxzKCk6IFByb21pc2U8Q3JlZGVudGlhbHM+IHtcbiAgICBpZiAodGhpcy5fY3JlZGVudGlhbHMgJiYgIXRoaXMuaXNBYm91dFRvRXhwaXJlKCkpIHtcbiAgICAgIHJldHVybiB0aGlzLl9jcmVkZW50aWFsc1xuICAgIH1cblxuICAgIHRoaXMuX2NyZWRlbnRpYWxzID0gYXdhaXQgdGhpcy5yZWZyZXNoQ3JlZGVudGlhbHMoKVxuICAgIHJldHVybiB0aGlzLl9jcmVkZW50aWFsc1xuICB9XG5cbiAgaXNBYm91dFRvRXhwaXJlKCkge1xuICAgIGNvbnN0IGV4cGlyZXNBdCA9IG5ldyBEYXRlKHRoaXMuYWNjZXNzRXhwaXJlc0F0KVxuICAgIGNvbnN0IHByb3Zpc2lvbmFsRXhwaXJ5ID0gbmV3IERhdGUoRGF0ZS5ub3coKSArIDEwMDAgKiAxMCkgLy8gY2hlY2sgYmVmb3JlIDEwIHNlY29uZHMuXG4gICAgcmV0dXJuIHByb3Zpc2lvbmFsRXhwaXJ5ID4gZXhwaXJlc0F0XG4gIH1cbn1cblxuLy8gZGVwcmVjYXRlZCBkZWZhdWx0IGV4cG9ydCwgcGxlYXNlIHVzZSBuYW1lZCBleHBvcnRzLlxuLy8ga2VlcCBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eS5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBpbXBvcnQvbm8tZGVmYXVsdC1leHBvcnRcbmV4cG9ydCBkZWZhdWx0IEFzc3VtZVJvbGVQcm92aWRlclxuIl0sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUtBLElBQUk7QUFDaEIsT0FBTyxLQUFLQyxLQUFLO0FBQ2pCLFNBQVNDLEdBQUcsRUFBRUMsZUFBZTtBQUU3QixTQUFTQyxrQkFBa0IsUUFBUSwwQkFBeUI7QUFDNUQsU0FBU0MsV0FBVyxRQUFRLG1CQUFrQjtBQUM5QyxTQUFTQyxZQUFZLEVBQUVDLFFBQVEsRUFBRUMsUUFBUSxRQUFRLHVCQUFzQjtBQUN2RSxTQUFTQyxPQUFPLFFBQVEsd0JBQXVCO0FBQy9DLFNBQVNDLFlBQVksUUFBUSx5QkFBd0I7QUFFckQsU0FB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