matrix-react-sdk
Version:
SDK for matrix.org using React
214 lines (210 loc) • 38.1 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _react = _interopRequireDefault(require("react"));
var _logger = require("matrix-js-sdk/src/logger");
var _languageHandler = require("../../../languageHandler");
var _MatrixClientPeg = require("../../../MatrixClientPeg");
var _Modal = _interopRequireDefault(require("../../../Modal"));
var _VerificationRequestDialog = _interopRequireDefault(require("../../views/dialogs/VerificationRequestDialog"));
var _SetupEncryptionStore = require("../../../stores/SetupEncryptionStore");
var _EncryptionPanel = _interopRequireDefault(require("../../views/right_panel/EncryptionPanel"));
var _AccessibleButton = _interopRequireDefault(require("../../views/elements/AccessibleButton"));
var _Spinner = _interopRequireDefault(require("../../views/elements/Spinner"));
/*
Copyright 2024 New Vector Ltd.
Copyright 2020, 2021 The Matrix.org Foundation C.I.C.
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details.
*/
function keyHasPassphrase(keyInfo) {
return Boolean(keyInfo.passphrase && keyInfo.passphrase.salt && keyInfo.passphrase.iterations);
}
class SetupEncryptionBody extends _react.default.Component {
constructor(props) {
super(props);
(0, _defineProperty2.default)(this, "onStoreUpdate", () => {
const store = _SetupEncryptionStore.SetupEncryptionStore.sharedInstance();
if (store.phase === _SetupEncryptionStore.Phase.Finished) {
this.props.onFinished();
return;
}
this.setState({
phase: store.phase,
verificationRequest: store.verificationRequest,
backupInfo: store.backupInfo,
lostKeys: store.lostKeys()
});
});
(0, _defineProperty2.default)(this, "onUsePassphraseClick", async () => {
const store = _SetupEncryptionStore.SetupEncryptionStore.sharedInstance();
store.usePassPhrase();
});
(0, _defineProperty2.default)(this, "onVerifyClick", () => {
const cli = _MatrixClientPeg.MatrixClientPeg.safeGet();
const userId = cli.getSafeUserId();
const requestPromise = cli.getCrypto().requestOwnUserVerification();
// We need to call onFinished now to close this dialog, and
// again later to signal that the verification is complete.
this.props.onFinished();
_Modal.default.createDialog(_VerificationRequestDialog.default, {
verificationRequestPromise: requestPromise,
member: cli.getUser(userId) ?? undefined,
onFinished: async () => {
const request = await requestPromise;
request.cancel();
this.props.onFinished();
}
});
});
(0, _defineProperty2.default)(this, "onSkipConfirmClick", () => {
const store = _SetupEncryptionStore.SetupEncryptionStore.sharedInstance();
store.skipConfirm();
});
(0, _defineProperty2.default)(this, "onSkipBackClick", () => {
const store = _SetupEncryptionStore.SetupEncryptionStore.sharedInstance();
store.returnAfterSkip();
});
(0, _defineProperty2.default)(this, "onResetClick", ev => {
ev.preventDefault();
const store = _SetupEncryptionStore.SetupEncryptionStore.sharedInstance();
store.reset();
});
(0, _defineProperty2.default)(this, "onResetConfirmClick", () => {
this.props.onFinished();
const store = _SetupEncryptionStore.SetupEncryptionStore.sharedInstance();
store.resetConfirm();
});
(0, _defineProperty2.default)(this, "onResetBackClick", () => {
const store = _SetupEncryptionStore.SetupEncryptionStore.sharedInstance();
store.returnAfterReset();
});
(0, _defineProperty2.default)(this, "onDoneClick", () => {
const store = _SetupEncryptionStore.SetupEncryptionStore.sharedInstance();
store.done();
});
(0, _defineProperty2.default)(this, "onEncryptionPanelClose", () => {
this.props.onFinished();
});
const _store = _SetupEncryptionStore.SetupEncryptionStore.sharedInstance();
_store.on("update", this.onStoreUpdate);
_store.start();
this.state = {
phase: _store.phase,
// this serves dual purpose as the object for the request logic and
// the presence of it indicating that we're in 'verify mode'.
// Because of the latter, it lives in the state.
verificationRequest: _store.verificationRequest,
backupInfo: _store.backupInfo,
lostKeys: _store.lostKeys()
};
}
componentWillUnmount() {
const store = _SetupEncryptionStore.SetupEncryptionStore.sharedInstance();
store.off("update", this.onStoreUpdate);
store.stop();
}
render() {
const cli = _MatrixClientPeg.MatrixClientPeg.safeGet();
const {
phase,
lostKeys
} = this.state;
if (this.state.verificationRequest && cli.getUser(this.state.verificationRequest.otherUserId)) {
return /*#__PURE__*/_react.default.createElement(_EncryptionPanel.default, {
layout: "dialog",
verificationRequest: this.state.verificationRequest,
onClose: this.onEncryptionPanelClose,
member: cli.getUser(this.state.verificationRequest.otherUserId),
isRoomEncrypted: false
});
} else if (phase === _SetupEncryptionStore.Phase.Intro) {
if (lostKeys) {
return /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("p", null, (0, _languageHandler._t)("encryption|verification|no_key_or_device")), /*#__PURE__*/_react.default.createElement("div", {
className: "mx_CompleteSecurity_actionRow"
}, /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, {
kind: "primary",
onClick: this.onResetConfirmClick
}, (0, _languageHandler._t)("encryption|verification|reset_proceed_prompt"))));
} else {
const store = _SetupEncryptionStore.SetupEncryptionStore.sharedInstance();
let recoveryKeyPrompt;
if (store.keyInfo && keyHasPassphrase(store.keyInfo)) {
recoveryKeyPrompt = (0, _languageHandler._t)("encryption|verification|verify_using_key_or_phrase");
} else if (store.keyInfo) {
recoveryKeyPrompt = (0, _languageHandler._t)("encryption|verification|verify_using_key");
}
let useRecoveryKeyButton;
if (recoveryKeyPrompt) {
useRecoveryKeyButton = /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, {
kind: "primary",
onClick: this.onUsePassphraseClick
}, recoveryKeyPrompt);
}
let verifyButton;
if (store.hasDevicesToVerifyAgainst) {
verifyButton = /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, {
kind: "primary",
onClick: this.onVerifyClick
}, (0, _languageHandler._t)("encryption|verification|verify_using_device"));
}
return /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("p", null, (0, _languageHandler._t)("encryption|verification|verification_description")), /*#__PURE__*/_react.default.createElement("div", {
className: "mx_CompleteSecurity_actionRow"
}, verifyButton, useRecoveryKeyButton), /*#__PURE__*/_react.default.createElement("div", {
className: "mx_SetupEncryptionBody_reset"
}, (0, _languageHandler._t)("encryption|reset_all_button", undefined, {
a: sub => /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, {
kind: "link_inline",
className: "mx_SetupEncryptionBody_reset_link",
onClick: this.onResetClick
}, sub)
})));
}
} else if (phase === _SetupEncryptionStore.Phase.Done) {
let message;
if (this.state.backupInfo) {
message = /*#__PURE__*/_react.default.createElement("p", null, (0, _languageHandler._t)("encryption|verification|verification_success_with_backup"));
} else {
message = /*#__PURE__*/_react.default.createElement("p", null, (0, _languageHandler._t)("encryption|verification|verification_success_without_backup"));
}
return /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("div", {
className: "mx_CompleteSecurity_heroIcon mx_E2EIcon_verified"
}), message, /*#__PURE__*/_react.default.createElement("div", {
className: "mx_CompleteSecurity_actionRow"
}, /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, {
kind: "primary",
onClick: this.onDoneClick
}, (0, _languageHandler._t)("action|done"))));
} else if (phase === _SetupEncryptionStore.Phase.ConfirmSkip) {
return /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("p", null, (0, _languageHandler._t)("encryption|verification|verification_skip_warning")), /*#__PURE__*/_react.default.createElement("div", {
className: "mx_CompleteSecurity_actionRow"
}, /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, {
kind: "danger_outline",
onClick: this.onSkipConfirmClick
}, (0, _languageHandler._t)("encryption|verification|verify_later")), /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, {
kind: "primary",
onClick: this.onSkipBackClick
}, (0, _languageHandler._t)("action|go_back"))));
} else if (phase === _SetupEncryptionStore.Phase.ConfirmReset) {
return /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("p", null, (0, _languageHandler._t)("encryption|verification|verify_reset_warning_1")), /*#__PURE__*/_react.default.createElement("p", null, (0, _languageHandler._t)("encryption|verification|verify_reset_warning_2")), /*#__PURE__*/_react.default.createElement("div", {
className: "mx_CompleteSecurity_actionRow"
}, /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, {
kind: "danger_outline",
onClick: this.onResetConfirmClick
}, (0, _languageHandler._t)("encryption|verification|reset_proceed_prompt")), /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, {
kind: "primary",
onClick: this.onResetBackClick
}, (0, _languageHandler._t)("action|go_back"))));
} else if (phase === _SetupEncryptionStore.Phase.Busy || phase === _SetupEncryptionStore.Phase.Loading) {
return /*#__PURE__*/_react.default.createElement(_Spinner.default, null);
} else {
_logger.logger.log(`SetupEncryptionBody: Unknown phase ${phase}`);
}
}
}
exports.default = SetupEncryptionBody;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfcmVhY3QiLCJfaW50ZXJvcFJlcXVpcmVEZWZhdWx0IiwicmVxdWlyZSIsIl9sb2dnZXIiLCJfbGFuZ3VhZ2VIYW5kbGVyIiwiX01hdHJpeENsaWVudFBlZyIsIl9Nb2RhbCIsIl9WZXJpZmljYXRpb25SZXF1ZXN0RGlhbG9nIiwiX1NldHVwRW5jcnlwdGlvblN0b3JlIiwiX0VuY3J5cHRpb25QYW5lbCIsIl9BY2Nlc3NpYmxlQnV0dG9uIiwiX1NwaW5uZXIiLCJrZXlIYXNQYXNzcGhyYXNlIiwia2V5SW5mbyIsIkJvb2xlYW4iLCJwYXNzcGhyYXNlIiwic2FsdCIsIml0ZXJhdGlvbnMiLCJTZXR1cEVuY3J5cHRpb25Cb2R5IiwiUmVhY3QiLCJDb21wb25lbnQiLCJjb25zdHJ1Y3RvciIsInByb3BzIiwiX2RlZmluZVByb3BlcnR5MiIsImRlZmF1bHQiLCJzdG9yZSIsIlNldHVwRW5jcnlwdGlvblN0b3JlIiwic2hhcmVkSW5zdGFuY2UiLCJwaGFzZSIsIlBoYXNlIiwiRmluaXNoZWQiLCJvbkZpbmlzaGVkIiwic2V0U3RhdGUiLCJ2ZXJpZmljYXRpb25SZXF1ZXN0IiwiYmFja3VwSW5mbyIsImxvc3RLZXlzIiwidXNlUGFzc1BocmFzZSIsImNsaSIsIk1hdHJpeENsaWVudFBlZyIsInNhZmVHZXQiLCJ1c2VySWQiLCJnZXRTYWZlVXNlcklkIiwicmVxdWVzdFByb21pc2UiLCJnZXRDcnlwdG8iLCJyZXF1ZXN0T3duVXNlclZlcmlmaWNhdGlvbiIsIk1vZGFsIiwiY3JlYXRlRGlhbG9nIiwiVmVyaWZpY2F0aW9uUmVxdWVzdERpYWxvZyIsInZlcmlmaWNhdGlvblJlcXVlc3RQcm9taXNlIiwibWVtYmVyIiwiZ2V0VXNlciIsInVuZGVmaW5lZCIsInJlcXVlc3QiLCJjYW5jZWwiLCJza2lwQ29uZmlybSIsInJldHVybkFmdGVyU2tpcCIsImV2IiwicHJldmVudERlZmF1bHQiLCJyZXNldCIsInJlc2V0Q29uZmlybSIsInJldHVybkFmdGVyUmVzZXQiLCJkb25lIiwib24iLCJvblN0b3JlVXBkYXRlIiwic3RhcnQiLCJzdGF0ZSIsImNvbXBvbmVudFdpbGxVbm1vdW50Iiwib2ZmIiwic3RvcCIsInJlbmRlciIsIm90aGVyVXNlcklkIiwiY3JlYXRlRWxlbWVudCIsImxheW91dCIsIm9uQ2xvc2UiLCJvbkVuY3J5cHRpb25QYW5lbENsb3NlIiwiaXNSb29tRW5jcnlwdGVkIiwiSW50cm8iLCJfdCIsImNsYXNzTmFtZSIsImtpbmQiLCJvbkNsaWNrIiwib25SZXNldENvbmZpcm1DbGljayIsInJlY292ZXJ5S2V5UHJvbXB0IiwidXNlUmVjb3ZlcnlLZXlCdXR0b24iLCJvblVzZVBhc3NwaHJhc2VDbGljayIsInZlcmlmeUJ1dHRvbiIsImhhc0RldmljZXNUb1ZlcmlmeUFnYWluc3QiLCJvblZlcmlmeUNsaWNrIiwiYSIsInN1YiIsIm9uUmVzZXRDbGljayIsIkRvbmUiLCJtZXNzYWdlIiwib25Eb25lQ2xpY2siLCJDb25maXJtU2tpcCIsIm9uU2tpcENvbmZpcm1DbGljayIsIm9uU2tpcEJhY2tDbGljayIsIkNvbmZpcm1SZXNldCIsIm9uUmVzZXRCYWNrQ2xpY2siLCJCdXN5IiwiTG9hZGluZyIsImxvZ2dlciIsImxvZyIsImV4cG9ydHMiXSwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29tcG9uZW50cy9zdHJ1Y3R1cmVzL2F1dGgvU2V0dXBFbmNyeXB0aW9uQm9keS50c3giXSwic291cmNlc0NvbnRlbnQiOlsiLypcbkNvcHlyaWdodCAyMDI0IE5ldyBWZWN0b3IgTHRkLlxuQ29weXJpZ2h0IDIwMjAsIDIwMjEgVGhlIE1hdHJpeC5vcmcgRm91bmRhdGlvbiBDLkkuQy5cblxuU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFHUEwtMy4wLW9ubHkgT1IgR1BMLTMuMC1vbmx5XG5QbGVhc2Ugc2VlIExJQ0VOU0UgZmlsZXMgaW4gdGhlIHJlcG9zaXRvcnkgcm9vdCBmb3IgZnVsbCBkZXRhaWxzLlxuKi9cblxuaW1wb3J0IFJlYWN0IGZyb20gXCJyZWFjdFwiO1xuaW1wb3J0IHsgS2V5QmFja3VwSW5mbywgVmVyaWZpY2F0aW9uUmVxdWVzdCB9IGZyb20gXCJtYXRyaXgtanMtc2RrL3NyYy9jcnlwdG8tYXBpXCI7XG5pbXBvcnQgeyBsb2dnZXIgfSBmcm9tIFwibWF0cml4LWpzLXNkay9zcmMvbG9nZ2VyXCI7XG5pbXBvcnQgeyBTZWNyZXRTdG9yYWdlS2V5RGVzY3JpcHRpb24gfSBmcm9tIFwibWF0cml4LWpzLXNkay9zcmMvc2VjcmV0LXN0b3JhZ2VcIjtcblxuaW1wb3J0IHsgX3QgfSBmcm9tIFwiLi4vLi4vLi4vbGFuZ3VhZ2VIYW5kbGVyXCI7XG5pbXBvcnQgeyBNYXRyaXhDbGllbnRQZWcgfSBmcm9tIFwiLi4vLi4vLi4vTWF0cml4Q2xpZW50UGVnXCI7XG5pbXBvcnQgTW9kYWwgZnJvbSBcIi4uLy4uLy4uL01vZGFsXCI7XG5pbXBvcnQgVmVyaWZpY2F0aW9uUmVxdWVzdERpYWxvZyBmcm9tIFwiLi4vLi4vdmlld3MvZGlhbG9ncy9WZXJpZmljYXRpb25SZXF1ZXN0RGlhbG9nXCI7XG5pbXBvcnQgeyBTZXR1cEVuY3J5cHRpb25TdG9yZSwgUGhhc2UgfSBmcm9tIFwiLi4vLi4vLi4vc3RvcmVzL1NldHVwRW5jcnlwdGlvblN0b3JlXCI7XG5pbXBvcnQgRW5jcnlwdGlvblBhbmVsIGZyb20gXCIuLi8uLi92aWV3cy9yaWdodF9wYW5lbC9FbmNyeXB0aW9uUGFuZWxcIjtcbmltcG9ydCBBY2Nlc3NpYmxlQnV0dG9uLCB7IEJ1dHRvbkV2ZW50IH0gZnJvbSBcIi4uLy4uL3ZpZXdzL2VsZW1lbnRzL0FjY2Vzc2libGVCdXR0b25cIjtcbmltcG9ydCBTcGlubmVyIGZyb20gXCIuLi8uLi92aWV3cy9lbGVtZW50cy9TcGlubmVyXCI7XG5cbmZ1bmN0aW9uIGtleUhhc1Bhc3NwaHJhc2Uoa2V5SW5mbzogU2VjcmV0U3RvcmFnZUtleURlc2NyaXB0aW9uKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIEJvb2xlYW4oa2V5SW5mby5wYXNzcGhyYXNlICYmIGtleUluZm8ucGFzc3BocmFzZS5zYWx0ICYmIGtleUluZm8ucGFzc3BocmFzZS5pdGVyYXRpb25zKTtcbn1cblxuaW50ZXJmYWNlIElQcm9wcyB7XG4gICAgb25GaW5pc2hlZDogKCkgPT4gdm9pZDtcbn1cblxuaW50ZXJmYWNlIElTdGF0ZSB7XG4gICAgcGhhc2U/OiBQaGFzZTtcbiAgICB2ZXJpZmljYXRpb25SZXF1ZXN0OiBWZXJpZmljYXRpb25SZXF1ZXN0IHwgbnVsbDtcbiAgICBiYWNrdXBJbmZvOiBLZXlCYWNrdXBJbmZvIHwgbnVsbDtcbiAgICBsb3N0S2V5czogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgU2V0dXBFbmNyeXB0aW9uQm9keSBleHRlbmRzIFJlYWN0LkNvbXBvbmVudDxJUHJvcHMsIElTdGF0ZT4ge1xuICAgIHB1YmxpYyBjb25zdHJ1Y3Rvcihwcm9wczogSVByb3BzKSB7XG4gICAgICAgIHN1cGVyKHByb3BzKTtcbiAgICAgICAgY29uc3Qgc3RvcmUgPSBTZXR1cEVuY3J5cHRpb25TdG9yZS5zaGFyZWRJbnN0YW5jZSgpO1xuICAgICAgICBzdG9yZS5vbihcInVwZGF0ZVwiLCB0aGlzLm9uU3RvcmVVcGRhdGUpO1xuICAgICAgICBzdG9yZS5zdGFydCgpO1xuICAgICAgICB0aGlzLnN0YXRlID0ge1xuICAgICAgICAgICAgcGhhc2U6IHN0b3JlLnBoYXNlLFxuICAgICAgICAgICAgLy8gdGhpcyBzZXJ2ZXMgZHVhbCBwdXJwb3NlIGFzIHRoZSBvYmplY3QgZm9yIHRoZSByZXF1ZXN0IGxvZ2ljIGFuZFxuICAgICAgICAgICAgLy8gdGhlIHByZXNlbmNlIG9mIGl0IGluZGljYXRpbmcgdGhhdCB3ZSdyZSBpbiAndmVyaWZ5IG1vZGUnLlxuICAgICAgICAgICAgLy8gQmVjYXVzZSBvZiB0aGUgbGF0dGVyLCBpdCBsaXZlcyBpbiB0aGUgc3RhdGUuXG4gICAgICAgICAgICB2ZXJpZmljYXRpb25SZXF1ZXN0OiBzdG9yZS52ZXJpZmljYXRpb25SZXF1ZXN0LFxuICAgICAgICAgICAgYmFja3VwSW5mbzogc3RvcmUuYmFja3VwSW5mbyxcbiAgICAgICAgICAgIGxvc3RLZXlzOiBzdG9yZS5sb3N0S2V5cygpLFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIHByaXZhdGUgb25TdG9yZVVwZGF0ZSA9ICgpOiB2b2lkID0+IHtcbiAgICAgICAgY29uc3Qgc3RvcmUgPSBTZXR1cEVuY3J5cHRpb25TdG9yZS5zaGFyZWRJbnN0YW5jZSgpO1xuICAgICAgICBpZiAoc3RvcmUucGhhc2UgPT09IFBoYXNlLkZpbmlzaGVkKSB7XG4gICAgICAgICAgICB0aGlzLnByb3BzLm9uRmluaXNoZWQoKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgIHBoYXNlOiBzdG9yZS5waGFzZSxcbiAgICAgICAgICAgIHZlcmlmaWNhdGlvblJlcXVlc3Q6IHN0b3JlLnZlcmlmaWNhdGlvblJlcXVlc3QsXG4gICAgICAgICAgICBiYWNrdXBJbmZvOiBzdG9yZS5iYWNrdXBJbmZvLFxuICAgICAgICAgICAgbG9zdEtleXM6IHN0b3JlLmxvc3RLZXlzKCksXG4gICAgICAgIH0pO1xuICAgIH07XG5cbiAgICBwdWJsaWMgY29tcG9uZW50V2lsbFVubW91bnQoKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IHN0b3JlID0gU2V0dXBFbmNyeXB0aW9uU3RvcmUuc2hhcmVkSW5zdGFuY2UoKTtcbiAgICAgICAgc3RvcmUub2ZmKFwidXBkYXRlXCIsIHRoaXMub25TdG9yZVVwZGF0ZSk7XG4gICAgICAgIHN0b3JlLnN0b3AoKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIG9uVXNlUGFzc3BocmFzZUNsaWNrID0gYXN5bmMgKCk6IFByb21pc2U8dm9pZD4gPT4ge1xuICAgICAgICBjb25zdCBzdG9yZSA9IFNldHVwRW5jcnlwdGlvblN0b3JlLnNoYXJlZEluc3RhbmNlKCk7XG4gICAgICAgIHN0b3JlLnVzZVBhc3NQaHJhc2UoKTtcbiAgICB9O1xuXG4gICAgcHJpdmF0ZSBvblZlcmlmeUNsaWNrID0gKCk6IHZvaWQgPT4ge1xuICAgICAgICBjb25zdCBjbGkgPSBNYXRyaXhDbGllbnRQZWcuc2FmZUdldCgpO1xuICAgICAgICBjb25zdCB1c2VySWQgPSBjbGkuZ2V0U2FmZVVzZXJJZCgpO1xuICAgICAgICBjb25zdCByZXF1ZXN0UHJvbWlzZSA9IGNsaS5nZXRDcnlwdG8oKSEucmVxdWVzdE93blVzZXJWZXJpZmljYXRpb24oKTtcblxuICAgICAgICAvLyBXZSBuZWVkIHRvIGNhbGwgb25GaW5pc2hlZCBub3cgdG8gY2xvc2UgdGhpcyBkaWFsb2csIGFuZFxuICAgICAgICAvLyBhZ2FpbiBsYXRlciB0byBzaWduYWwgdGhhdCB0aGUgdmVyaWZpY2F0aW9uIGlzIGNvbXBsZXRlLlxuICAgICAgICB0aGlzLnByb3BzLm9uRmluaXNoZWQoKTtcbiAgICAgICAgTW9kYWwuY3JlYXRlRGlhbG9nKFZlcmlmaWNhdGlvblJlcXVlc3REaWFsb2csIHtcbiAgICAgICAgICAgIHZlcmlmaWNhdGlvblJlcXVlc3RQcm9taXNlOiByZXF1ZXN0UHJvbWlzZSxcbiAgICAgICAgICAgIG1lbWJlcjogY2xpLmdldFVzZXIodXNlcklkKSA/PyB1bmRlZmluZWQsXG4gICAgICAgICAgICBvbkZpbmlzaGVkOiBhc3luYyAoKTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVxdWVzdCA9IGF3YWl0IHJlcXVlc3RQcm9taXNlO1xuICAgICAgICAgICAgICAgIHJlcXVlc3QuY2FuY2VsKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5vbkZpbmlzaGVkKCk7XG4gICAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgcHJpdmF0ZSBvblNraXBDb25maXJtQ2xpY2sgPSAoKTogdm9pZCA9PiB7XG4gICAgICAgIGNvbnN0IHN0b3JlID0gU2V0dXBFbmNyeXB0aW9uU3RvcmUuc2hhcmVkSW5zdGFuY2UoKTtcbiAgICAgICAgc3RvcmUuc2tpcENvbmZpcm0oKTtcbiAgICB9O1xuXG4gICAgcHJpdmF0ZSBvblNraXBCYWNrQ2xpY2sgPSAoKTogdm9pZCA9PiB7XG4gICAgICAgIGNvbnN0IHN0b3JlID0gU2V0dXBFbmNyeXB0aW9uU3RvcmUuc2hhcmVkSW5zdGFuY2UoKTtcbiAgICAgICAgc3RvcmUucmV0dXJuQWZ0ZXJTa2lwKCk7XG4gICAgfTtcblxuICAgIHByaXZhdGUgb25SZXNldENsaWNrID0gKGV2OiBCdXR0b25FdmVudCk6IHZvaWQgPT4ge1xuICAgICAgICBldi5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBjb25zdCBzdG9yZSA9IFNldHVwRW5jcnlwdGlvblN0b3JlLnNoYXJlZEluc3RhbmNlKCk7XG4gICAgICAgIHN0b3JlLnJlc2V0KCk7XG4gICAgfTtcblxuICAgIHByaXZhdGUgb25SZXNldENvbmZpcm1DbGljayA9ICgpOiB2b2lkID0+IHtcbiAgICAgICAgdGhpcy5wcm9wcy5vbkZpbmlzaGVkKCk7XG4gICAgICAgIGNvbnN0IHN0b3JlID0gU2V0dXBFbmNyeXB0aW9uU3RvcmUuc2hhcmVkSW5zdGFuY2UoKTtcbiAgICAgICAgc3RvcmUucmVzZXRDb25maXJtKCk7XG4gICAgfTtcblxuICAgIHByaXZhdGUgb25SZXNldEJhY2tDbGljayA9ICgpOiB2b2lkID0+IHtcbiAgICAgICAgY29uc3Qgc3RvcmUgPSBTZXR1cEVuY3J5cHRpb25TdG9yZS5zaGFyZWRJbnN0YW5jZSgpO1xuICAgICAgICBzdG9yZS5yZXR1cm5BZnRlclJlc2V0KCk7XG4gICAgfTtcblxuICAgIHByaXZhdGUgb25Eb25lQ2xpY2sgPSAoKTogdm9pZCA9PiB7XG4gICAgICAgIGNvbnN0IHN0b3JlID0gU2V0dXBFbmNyeXB0aW9uU3RvcmUuc2hhcmVkSW5zdGFuY2UoKTtcbiAgICAgICAgc3RvcmUuZG9uZSgpO1xuICAgIH07XG5cbiAgICBwcml2YXRlIG9uRW5jcnlwdGlvblBhbmVsQ2xvc2UgPSAoKTogdm9pZCA9PiB7XG4gICAgICAgIHRoaXMucHJvcHMub25GaW5pc2hlZCgpO1xuICAgIH07XG5cbiAgICBwdWJsaWMgcmVuZGVyKCk6IFJlYWN0LlJlYWN0Tm9kZSB7XG4gICAgICAgIGNvbnN0IGNsaSA9IE1hdHJpeENsaWVudFBlZy5zYWZlR2V0KCk7XG4gICAgICAgIGNvbnN0IHsgcGhhc2UsIGxvc3RLZXlzIH0gPSB0aGlzLnN0YXRlO1xuXG4gICAgICAgIGlmICh0aGlzLnN0YXRlLnZlcmlmaWNhdGlvblJlcXVlc3QgJiYgY2xpLmdldFVzZXIodGhpcy5zdGF0ZS52ZXJpZmljYXRpb25SZXF1ZXN0Lm90aGVyVXNlcklkKSkge1xuICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICAgICA8RW5jcnlwdGlvblBhbmVsXG4gICAgICAgICAgICAgICAgICAgIGxheW91dD1cImRpYWxvZ1wiXG4gICAgICAgICAgICAgICAgICAgIHZlcmlmaWNhdGlvblJlcXVlc3Q9e3RoaXMuc3RhdGUudmVyaWZpY2F0aW9uUmVxdWVzdH1cbiAgICAgICAgICAgICAgICAgICAgb25DbG9zZT17dGhpcy5vbkVuY3J5cHRpb25QYW5lbENsb3NlfVxuICAgICAgICAgICAgICAgICAgICBtZW1iZXI9e2NsaS5nZXRVc2VyKHRoaXMuc3RhdGUudmVyaWZpY2F0aW9uUmVxdWVzdC5vdGhlclVzZXJJZCkhfVxuICAgICAgICAgICAgICAgICAgICBpc1Jvb21FbmNyeXB0ZWQ9e2ZhbHNlfVxuICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICApO1xuICAgICAgICB9IGVsc2UgaWYgKHBoYXNlID09PSBQaGFzZS5JbnRybykge1xuICAgICAgICAgICAgaWYgKGxvc3RLZXlzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxwPntfdChcImVuY3J5cHRpb258dmVyaWZpY2F0aW9ufG5vX2tleV9vcl9kZXZpY2VcIil9PC9wPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cIm14X0NvbXBsZXRlU2VjdXJpdHlfYWN0aW9uUm93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPEFjY2Vzc2libGVCdXR0b24ga2luZD1cInByaW1hcnlcIiBvbkNsaWNrPXt0aGlzLm9uUmVzZXRDb25maXJtQ2xpY2t9PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7X3QoXCJlbmNyeXB0aW9ufHZlcmlmaWNhdGlvbnxyZXNldF9wcm9jZWVkX3Byb21wdFwiKX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L0FjY2Vzc2libGVCdXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc3RvcmUgPSBTZXR1cEVuY3J5cHRpb25TdG9yZS5zaGFyZWRJbnN0YW5jZSgpO1xuICAgICAgICAgICAgICAgIGxldCByZWNvdmVyeUtleVByb21wdDtcbiAgICAgICAgICAgICAgICBpZiAoc3RvcmUua2V5SW5mbyAmJiBrZXlIYXNQYXNzcGhyYXNlKHN0b3JlLmtleUluZm8pKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlY292ZXJ5S2V5UHJvbXB0ID0gX3QoXCJlbmNyeXB0aW9ufHZlcmlmaWNhdGlvbnx2ZXJpZnlfdXNpbmdfa2V5X29yX3BocmFzZVwiKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHN0b3JlLmtleUluZm8pIHtcbiAgICAgICAgICAgICAgICAgICAgcmVjb3ZlcnlLZXlQcm9tcHQgPSBfdChcImVuY3J5cHRpb258dmVyaWZpY2F0aW9ufHZlcmlmeV91c2luZ19rZXlcIik7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgbGV0IHVzZVJlY292ZXJ5S2V5QnV0dG9uO1xuICAgICAgICAgICAgICAgIGlmIChyZWNvdmVyeUtleVByb21wdCkge1xuICAgICAgICAgICAgICAgICAgICB1c2VSZWNvdmVyeUtleUJ1dHRvbiA9IChcbiAgICAgICAgICAgICAgICAgICAgICAgIDxBY2Nlc3NpYmxlQnV0dG9uIGtpbmQ9XCJwcmltYXJ5XCIgb25DbGljaz17dGhpcy5vblVzZVBhc3NwaHJhc2VDbGlja30+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge3JlY292ZXJ5S2V5UHJvbXB0fVxuICAgICAgICAgICAgICAgICAgICAgICAgPC9BY2Nlc3NpYmxlQnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGxldCB2ZXJpZnlCdXR0b247XG4gICAgICAgICAgICAgICAgaWYgKHN0b3JlLmhhc0RldmljZXNUb1ZlcmlmeUFnYWluc3QpIHtcbiAgICAgICAgICAgICAgICAgICAgdmVyaWZ5QnV0dG9uID0gKFxuICAgICAgICAgICAgICAgICAgICAgICAgPEFjY2Vzc2libGVCdXR0b24ga2luZD1cInByaW1hcnlcIiBvbkNsaWNrPXt0aGlzLm9uVmVyaWZ5Q2xpY2t9PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtfdChcImVuY3J5cHRpb258dmVyaWZpY2F0aW9ufHZlcmlmeV91c2luZ19kZXZpY2VcIil9XG4gICAgICAgICAgICAgICAgICAgICAgICA8L0FjY2Vzc2libGVCdXR0b24+XG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxwPntfdChcImVuY3J5cHRpb258dmVyaWZpY2F0aW9ufHZlcmlmaWNhdGlvbl9kZXNjcmlwdGlvblwiKX08L3A+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwibXhfQ29tcGxldGVTZWN1cml0eV9hY3Rpb25Sb3dcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7dmVyaWZ5QnV0dG9ufVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt1c2VSZWNvdmVyeUtleUJ1dHRvbn1cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJteF9TZXR1cEVuY3J5cHRpb25Cb2R5X3Jlc2V0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge190KFwiZW5jcnlwdGlvbnxyZXNldF9hbGxfYnV0dG9uXCIsIHVuZGVmaW5lZCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhOiAoc3ViKSA9PiAoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8QWNjZXNzaWJsZUJ1dHRvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtpbmQ9XCJsaW5rX2lubGluZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lPVwibXhfU2V0dXBFbmNyeXB0aW9uQm9keV9yZXNldF9saW5rXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbkNsaWNrPXt0aGlzLm9uUmVzZXRDbGlja31cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7c3VifVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9BY2Nlc3NpYmxlQnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pfVxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAocGhhc2UgPT09IFBoYXNlLkRvbmUpIHtcbiAgICAgICAgICAgIGxldCBtZXNzYWdlOiBKU1guRWxlbWVudDtcbiAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlLmJhY2t1cEluZm8pIHtcbiAgICAgICAgICAgICAgICBtZXNzYWdlID0gPHA+e190KFwiZW5jcnlwdGlvbnx2ZXJpZmljYXRpb258dmVyaWZpY2F0aW9uX3N1Y2Nlc3Nfd2l0aF9iYWNrdXBcIil9PC9wPjtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgbWVzc2FnZSA9IDxwPntfdChcImVuY3J5cHRpb258dmVyaWZpY2F0aW9ufHZlcmlmaWNhdGlvbl9zdWNjZXNzX3dpdGhvdXRfYmFja3VwXCIpfTwvcD47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwibXhfQ29tcGxldGVTZWN1cml0eV9oZXJvSWNvbiBteF9FMkVJY29uX3ZlcmlmaWVkXCIgLz5cbiAgICAgICAgICAgICAgICAgICAge21lc3NhZ2V9XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwibXhfQ29tcGxldGVTZWN1cml0eV9hY3Rpb25Sb3dcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxBY2Nlc3NpYmxlQnV0dG9uIGtpbmQ9XCJwcmltYXJ5XCIgb25DbGljaz17dGhpcy5vbkRvbmVDbGlja30+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge190KFwiYWN0aW9ufGRvbmVcIil9XG4gICAgICAgICAgICAgICAgICAgICAgICA8L0FjY2Vzc2libGVCdXR0b24+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIGlmIChwaGFzZSA9PT0gUGhhc2UuQ29uZmlybVNraXApIHtcbiAgICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgICAgICAgPHA+e190KFwiZW5jcnlwdGlvbnx2ZXJpZmljYXRpb258dmVyaWZpY2F0aW9uX3NraXBfd2FybmluZ1wiKX08L3A+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwibXhfQ29tcGxldGVTZWN1cml0eV9hY3Rpb25Sb3dcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxBY2Nlc3NpYmxlQnV0dG9uIGtpbmQ9XCJkYW5nZXJfb3V0bGluZVwiIG9uQ2xpY2s9e3RoaXMub25Ta2lwQ29uZmlybUNsaWNrfT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7X3QoXCJlbmNyeXB0aW9ufHZlcmlmaWNhdGlvbnx2ZXJpZnlfbGF0ZXJcIil9XG4gICAgICAgICAgICAgICAgICAgICAgICA8L0FjY2Vzc2libGVCdXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICA8QWNjZXNzaWJsZUJ1dHRvbiBraW5kPVwicHJpbWFyeVwiIG9uQ2xpY2s9e3RoaXMub25Ta2lwQmFja0NsaWNrfT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7X3QoXCJhY3Rpb258Z29fYmFja1wiKX1cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvQWNjZXNzaWJsZUJ1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICApO1xuICAgICAgICB9IGVsc2UgaWYgKHBoYXNlID09PSBQaGFzZS5Db25maXJtUmVzZXQpIHtcbiAgICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgICAgICAgPHA+e190KFwiZW5jcnlwdGlvbnx2ZXJpZmljYXRpb258dmVyaWZ5X3Jlc2V0X3dhcm5pbmdfMVwiKX08L3A+XG4gICAgICAgICAgICAgICAgICAgIDxwPntfdChcImVuY3J5cHRpb258dmVyaWZpY2F0aW9ufHZlcmlmeV9yZXNldF93YXJuaW5nXzJcIil9PC9wPlxuXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwibXhfQ29tcGxldGVTZWN1cml0eV9hY3Rpb25Sb3dcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxBY2Nlc3NpYmxlQnV0dG9uIGtpbmQ9XCJkYW5nZXJfb3V0bGluZVwiIG9uQ2xpY2s9e3RoaXMub25SZXNldENvbmZpcm1DbGlja30+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge190KFwiZW5jcnlwdGlvbnx2ZXJpZmljYXRpb258cmVzZXRfcHJvY2VlZF9wcm9tcHRcIil9XG4gICAgICAgICAgICAgICAgICAgICAgICA8L0FjY2Vzc2libGVCdXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICA8QWNjZXNzaWJsZUJ1dHRvbiBraW5kPVwicHJpbWFyeVwiIG9uQ2xpY2s9e3RoaXMub25SZXNldEJhY2tDbGlja30+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge190KFwiYWN0aW9ufGdvX2JhY2tcIil9XG4gICAgICAgICAgICAgICAgICAgICAgICA8L0FjY2Vzc2libGVCdXR0b24+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIGlmIChwaGFzZSA9PT0gUGhhc2UuQnVzeSB8fCBwaGFzZSA9PT0gUGhhc2UuTG9hZGluZykge1xuICAgICAgICAgICAgcmV0dXJuIDxTcGlubmVyIC8+O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbG9nZ2VyLmxvZyhgU2V0dXBFbmNyeXB0aW9uQm9keTogVW5rbm93biBwaGFzZSAke3BoYXNlfWApO1xuICAgICAgICB9XG4gICAgfVxufVxuIl0sIm1hcHBpbmdz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