UNPKG

matrix-react-sdk

Version:
239 lines (196 loc) 35.4 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _react = _interopRequireDefault(require("react")); var _MatrixClientPeg = require("../../../MatrixClientPeg"); var _languageHandler = require("../../../languageHandler"); var sdk = _interopRequireWildcard(require("../../../index")); var _Modal = _interopRequireDefault(require("../../../Modal")); var _Spinner = _interopRequireDefault(require("../elements/Spinner")); var _InteractiveAuthDialog = _interopRequireDefault(require("../dialogs/InteractiveAuthDialog")); var _ConfirmDestroyCrossSigningDialog = _interopRequireDefault(require("../dialogs/security/ConfirmDestroyCrossSigningDialog")); var _replaceableComponent = require("../../../utils/replaceableComponent"); var _dec, _class, _temp; let CrossSigningPanel = (_dec = (0, _replaceableComponent.replaceableComponent)("views.settings.CrossSigningPanel"), _dec(_class = (_temp = class CrossSigningPanel extends _react.default.PureComponent { constructor(props) { super(props); (0, _defineProperty2.default)(this, "onAccountData", event => { const type = event.getType(); if (type.startsWith("m.cross_signing") || type.startsWith("m.secret_storage")) { this._getUpdatedStatus(); } }); (0, _defineProperty2.default)(this, "_onBootstrapClick", () => { this._bootstrapCrossSigning({ forceReset: false }); }); (0, _defineProperty2.default)(this, "onStatusChanged", () => { this._getUpdatedStatus(); }); (0, _defineProperty2.default)(this, "_bootstrapCrossSigning", async ({ forceReset = false }) => { this.setState({ error: null }); try { const cli = _MatrixClientPeg.MatrixClientPeg.get(); await cli.bootstrapCrossSigning({ authUploadDeviceSigningKeys: async makeRequest => { const { finished } = _Modal.default.createTrackedDialog('Cross-signing keys dialog', '', _InteractiveAuthDialog.default, { title: (0, _languageHandler._t)("Setting up keys"), matrixClient: cli, makeRequest }); const [confirmed] = await finished; if (!confirmed) { throw new Error("Cross-signing key upload auth canceled"); } }, setupNewCrossSigning: forceReset }); } catch (e) { this.setState({ error: e }); console.error("Error bootstrapping cross-signing", e); } if (this._unmounted) return; this._getUpdatedStatus(); }); (0, _defineProperty2.default)(this, "_resetCrossSigning", () => { _Modal.default.createDialog(_ConfirmDestroyCrossSigningDialog.default, { onFinished: act => { if (!act) return; this._bootstrapCrossSigning({ forceReset: true }); } }); }); this._unmounted = false; this.state = { error: null, crossSigningPublicKeysOnDevice: null, crossSigningPrivateKeysInStorage: null, masterPrivateKeyCached: null, selfSigningPrivateKeyCached: null, userSigningPrivateKeyCached: null, homeserverSupportsCrossSigning: null, crossSigningReady: null }; } componentDidMount() { const cli = _MatrixClientPeg.MatrixClientPeg.get(); cli.on("accountData", this.onAccountData); cli.on("userTrustStatusChanged", this.onStatusChanged); cli.on("crossSigning.keysChanged", this.onStatusChanged); this._getUpdatedStatus(); } componentWillUnmount() { this._unmounted = true; const cli = _MatrixClientPeg.MatrixClientPeg.get(); if (!cli) return; cli.removeListener("accountData", this.onAccountData); cli.removeListener("userTrustStatusChanged", this.onStatusChanged); cli.removeListener("crossSigning.keysChanged", this.onStatusChanged); } async _getUpdatedStatus() { const cli = _MatrixClientPeg.MatrixClientPeg.get(); const pkCache = cli.getCrossSigningCacheCallbacks(); const crossSigning = cli._crypto._crossSigningInfo; const secretStorage = cli._crypto._secretStorage; const crossSigningPublicKeysOnDevice = crossSigning.getId(); const crossSigningPrivateKeysInStorage = await crossSigning.isStoredInSecretStorage(secretStorage); const masterPrivateKeyCached = !!(pkCache && (await pkCache.getCrossSigningKeyCache("master"))); const selfSigningPrivateKeyCached = !!(pkCache && (await pkCache.getCrossSigningKeyCache("self_signing"))); const userSigningPrivateKeyCached = !!(pkCache && (await pkCache.getCrossSigningKeyCache("user_signing"))); const homeserverSupportsCrossSigning = await cli.doesServerSupportUnstableFeature("org.matrix.e2e_cross_signing"); const crossSigningReady = await cli.isCrossSigningReady(); this.setState({ crossSigningPublicKeysOnDevice, crossSigningPrivateKeysInStorage, masterPrivateKeyCached, selfSigningPrivateKeyCached, userSigningPrivateKeyCached, homeserverSupportsCrossSigning, crossSigningReady }); } /** * Bootstrapping cross-signing take one of these paths: * 1. Create cross-signing keys locally and store in secret storage (if it * already exists on the account). * 2. Access existing secret storage by requesting passphrase and accessing * cross-signing keys as needed. * 3. All keys are loaded and there's nothing to do. * @param {bool} [forceReset] Bootstrap again even if keys already present */ render() { const AccessibleButton = sdk.getComponent("elements.AccessibleButton"); const { error, crossSigningPublicKeysOnDevice, crossSigningPrivateKeysInStorage, masterPrivateKeyCached, selfSigningPrivateKeyCached, userSigningPrivateKeyCached, homeserverSupportsCrossSigning, crossSigningReady } = this.state; let errorSection; if (error) { errorSection = /*#__PURE__*/_react.default.createElement("div", { className: "error" }, error.toString()); } let summarisedStatus; if (homeserverSupportsCrossSigning === undefined) { summarisedStatus = /*#__PURE__*/_react.default.createElement(_Spinner.default, null); } else if (!homeserverSupportsCrossSigning) { summarisedStatus = /*#__PURE__*/_react.default.createElement("p", null, (0, _languageHandler._t)("Your homeserver does not support cross-signing.")); } else if (crossSigningReady) { summarisedStatus = /*#__PURE__*/_react.default.createElement("p", null, "\u2705 ", (0, _languageHandler._t)("Cross-signing is ready for use.")); } else if (crossSigningPrivateKeysInStorage) { summarisedStatus = /*#__PURE__*/_react.default.createElement("p", null, (0, _languageHandler._t)("Your account has a cross-signing identity in secret storage, " + "but it is not yet trusted by this session.")); } else { summarisedStatus = /*#__PURE__*/_react.default.createElement("p", null, (0, _languageHandler._t)("Cross-signing is not set up.")); } const keysExistAnywhere = crossSigningPublicKeysOnDevice || crossSigningPrivateKeysInStorage || masterPrivateKeyCached || selfSigningPrivateKeyCached || userSigningPrivateKeyCached; const keysExistEverywhere = crossSigningPublicKeysOnDevice && crossSigningPrivateKeysInStorage && masterPrivateKeyCached && selfSigningPrivateKeyCached && userSigningPrivateKeyCached; const actions = []; // TODO: determine how better to expose this to users in addition to prompts at login/toast if (!keysExistEverywhere && homeserverSupportsCrossSigning) { actions.push( /*#__PURE__*/_react.default.createElement(AccessibleButton, { key: "setup", kind: "primary", onClick: this._onBootstrapClick }, (0, _languageHandler._t)("Set up"))); } if (keysExistAnywhere) { actions.push( /*#__PURE__*/_react.default.createElement(AccessibleButton, { key: "reset", kind: "danger", onClick: this._resetCrossSigning }, (0, _languageHandler._t)("Reset"))); } let actionRow; if (actions.length) { actionRow = /*#__PURE__*/_react.default.createElement("div", { className: "mx_CrossSigningPanel_buttonRow" }, actions); } return /*#__PURE__*/_react.default.createElement("div", null, summarisedStatus, /*#__PURE__*/_react.default.createElement("details", null, /*#__PURE__*/_react.default.createElement("summary", null, (0, _languageHandler._t)("Advanced")), /*#__PURE__*/_react.default.createElement("table", { className: "mx_CrossSigningPanel_statusList" }, /*#__PURE__*/_react.default.createElement("tbody", null, /*#__PURE__*/_react.default.createElement("tr", null, /*#__PURE__*/_react.default.createElement("td", null, (0, _languageHandler._t)("Cross-signing public keys:")), /*#__PURE__*/_react.default.createElement("td", null, crossSigningPublicKeysOnDevice ? (0, _languageHandler._t)("in memory") : (0, _languageHandler._t)("not found"))), /*#__PURE__*/_react.default.createElement("tr", null, /*#__PURE__*/_react.default.createElement("td", null, (0, _languageHandler._t)("Cross-signing private keys:")), /*#__PURE__*/_react.default.createElement("td", null, crossSigningPrivateKeysInStorage ? (0, _languageHandler._t)("in secret storage") : (0, _languageHandler._t)("not found in storage"))), /*#__PURE__*/_react.default.createElement("tr", null, /*#__PURE__*/_react.default.createElement("td", null, (0, _languageHandler._t)("Master private key:")), /*#__PURE__*/_react.default.createElement("td", null, masterPrivateKeyCached ? (0, _languageHandler._t)("cached locally") : (0, _languageHandler._t)("not found locally"))), /*#__PURE__*/_react.default.createElement("tr", null, /*#__PURE__*/_react.default.createElement("td", null, (0, _languageHandler._t)("Self signing private key:")), /*#__PURE__*/_react.default.createElement("td", null, selfSigningPrivateKeyCached ? (0, _languageHandler._t)("cached locally") : (0, _languageHandler._t)("not found locally"))), /*#__PURE__*/_react.default.createElement("tr", null, /*#__PURE__*/_react.default.createElement("td", null, (0, _languageHandler._t)("User signing private key:")), /*#__PURE__*/_react.default.createElement("td", null, userSigningPrivateKeyCached ? (0, _languageHandler._t)("cached locally") : (0, _languageHandler._t)("not found locally"))), /*#__PURE__*/_react.default.createElement("tr", null, /*#__PURE__*/_react.default.createElement("td", null, (0, _languageHandler._t)("Homeserver feature support:")), /*#__PURE__*/_react.default.createElement("td", null, homeserverSupportsCrossSigning ? (0, _languageHandler._t)("exists") : (0, _languageHandler._t)("not found")))))), errorSection, actionRow); } }, _temp)) || _class); exports.default = CrossSigningPanel; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb21wb25lbnRzL3ZpZXdzL3NldHRpbmdzL0Nyb3NzU2lnbmluZ1BhbmVsLmpzIl0sIm5hbWVzIjpbIkNyb3NzU2lnbmluZ1BhbmVsIiwiUmVhY3QiLCJQdXJlQ29tcG9uZW50IiwiY29uc3RydWN0b3IiLCJwcm9wcyIsImV2ZW50IiwidHlwZSIsImdldFR5cGUiLCJzdGFydHNXaXRoIiwiX2dldFVwZGF0ZWRTdGF0dXMiLCJfYm9vdHN0cmFwQ3Jvc3NTaWduaW5nIiwiZm9yY2VSZXNldCIsInNldFN0YXRlIiwiZXJyb3IiLCJjbGkiLCJNYXRyaXhDbGllbnRQZWciLCJnZXQiLCJib290c3RyYXBDcm9zc1NpZ25pbmciLCJhdXRoVXBsb2FkRGV2aWNlU2lnbmluZ0tleXMiLCJtYWtlUmVxdWVzdCIsImZpbmlzaGVkIiwiTW9kYWwiLCJjcmVhdGVUcmFja2VkRGlhbG9nIiwiSW50ZXJhY3RpdmVBdXRoRGlhbG9nIiwidGl0bGUiLCJtYXRyaXhDbGllbnQiLCJjb25maXJtZWQiLCJFcnJvciIsInNldHVwTmV3Q3Jvc3NTaWduaW5nIiwiZSIsImNvbnNvbGUiLCJfdW5tb3VudGVkIiwiY3JlYXRlRGlhbG9nIiwiQ29uZmlybURlc3Ryb3lDcm9zc1NpZ25pbmdEaWFsb2ciLCJvbkZpbmlzaGVkIiwiYWN0Iiwic3RhdGUiLCJjcm9zc1NpZ25pbmdQdWJsaWNLZXlzT25EZXZpY2UiLCJjcm9zc1NpZ25pbmdQcml2YXRlS2V5c0luU3RvcmFnZSIsIm1hc3RlclByaXZhdGVLZXlDYWNoZWQiLCJzZWxmU2lnbmluZ1ByaXZhdGVLZXlDYWNoZWQiLCJ1c2VyU2lnbmluZ1ByaXZhdGVLZXlDYWNoZWQiLCJob21lc2VydmVyU3VwcG9ydHNDcm9zc1NpZ25pbmciLCJjcm9zc1NpZ25pbmdSZWFkeSIsImNvbXBvbmVudERpZE1vdW50Iiwib24iLCJvbkFjY291bnREYXRhIiwib25TdGF0dXNDaGFuZ2VkIiwiY29tcG9uZW50V2lsbFVubW91bnQiLCJyZW1vdmVMaXN0ZW5lciIsInBrQ2FjaGUiLCJnZXRDcm9zc1NpZ25pbmdDYWNoZUNhbGxiYWNrcyIsImNyb3NzU2lnbmluZyIsIl9jcnlwdG8iLCJfY3Jvc3NTaWduaW5nSW5mbyIsInNlY3JldFN0b3JhZ2UiLCJfc2VjcmV0U3RvcmFnZSIsImdldElkIiwiaXNTdG9yZWRJblNlY3JldFN0b3JhZ2UiLCJnZXRDcm9zc1NpZ25pbmdLZXlDYWNoZSIsImRvZXNTZXJ2ZXJTdXBwb3J0VW5zdGFibGVGZWF0dXJlIiwiaXNDcm9zc1NpZ25pbmdSZWFkeSIsInJlbmRlciIsIkFjY2Vzc2libGVCdXR0b24iLCJzZGsiLCJnZXRDb21wb25lbnQiLCJlcnJvclNlY3Rpb24iLCJ0b1N0cmluZyIsInN1bW1hcmlzZWRTdGF0dXMiLCJ1bmRlZmluZWQiLCJrZXlzRXhpc3RBbnl3aGVyZSIsImtleXNFeGlzdEV2ZXJ5d2hlcmUiLCJhY3Rpb25zIiwicHVzaCIsIl9vbkJvb3RzdHJhcENsaWNrIiwiX3Jlc2V0Q3Jvc3NTaWduaW5nIiwiYWN0aW9uUm93IiwibGVuZ3RoIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7O0FBZ0JBOztBQUVBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOzs7O0lBR3FCQSxpQixXQURwQixnREFBcUIsa0NBQXJCLEMseUJBQUQsTUFDcUJBLGlCQURyQixTQUMrQ0MsZUFBTUMsYUFEckQsQ0FDbUU7QUFDL0RDLEVBQUFBLFdBQVcsQ0FBQ0MsS0FBRCxFQUFRO0FBQ2YsVUFBTUEsS0FBTjtBQURlLHlEQWtDRkMsS0FBRCxJQUFXO0FBQ3ZCLFlBQU1DLElBQUksR0FBR0QsS0FBSyxDQUFDRSxPQUFOLEVBQWI7O0FBQ0EsVUFBSUQsSUFBSSxDQUFDRSxVQUFMLENBQWdCLGlCQUFoQixLQUFzQ0YsSUFBSSxDQUFDRSxVQUFMLENBQWdCLGtCQUFoQixDQUExQyxFQUErRTtBQUMzRSxhQUFLQyxpQkFBTDtBQUNIO0FBQ0osS0F2Q2tCO0FBQUEsNkRBeUNDLE1BQU07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IjpbIi8qXG5Db3B5cmlnaHQgMjAxOSwgMjAyMCBUaGUgTWF0cml4Lm9yZyBGb3VuZGF0aW9uIEMuSS5DLlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiovXG5cbmltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5cbmltcG9ydCB7TWF0cml4Q2xpZW50UGVnfSBmcm9tICcuLi8uLi8uLi9NYXRyaXhDbGllbnRQZWcnO1xuaW1wb3J0IHsgX3QgfSBmcm9tICcuLi8uLi8uLi9sYW5ndWFnZUhhbmRsZXInO1xuaW1wb3J0ICogYXMgc2RrIGZyb20gJy4uLy4uLy4uL2luZGV4JztcbmltcG9ydCBNb2RhbCBmcm9tICcuLi8uLi8uLi9Nb2RhbCc7XG5pbXBvcnQgU3Bpbm5lciBmcm9tICcuLi9lbGVtZW50cy9TcGlubmVyJztcbmltcG9ydCBJbnRlcmFjdGl2ZUF1dGhEaWFsb2cgZnJvbSAnLi4vZGlhbG9ncy9JbnRlcmFjdGl2ZUF1dGhEaWFsb2cnO1xuaW1wb3J0IENvbmZpcm1EZXN0cm95Q3Jvc3NTaWduaW5nRGlhbG9nIGZyb20gJy4uL2RpYWxvZ3Mvc2VjdXJpdHkvQ29uZmlybURlc3Ryb3lDcm9zc1NpZ25pbmdEaWFsb2cnO1xuaW1wb3J0IHtyZXBsYWNlYWJsZUNvbXBvbmVudH0gZnJvbSBcIi4uLy4uLy4uL3V0aWxzL3JlcGxhY2VhYmxlQ29tcG9uZW50XCI7XG5cbkByZXBsYWNlYWJsZUNvbXBvbmVudChcInZpZXdzLnNldHRpbmdzLkNyb3NzU2lnbmluZ1BhbmVsXCIpXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBDcm9zc1NpZ25pbmdQYW5lbCBleHRlbmRzIFJlYWN0LlB1cmVDb21wb25lbnQge1xuICAgIGNvbnN0cnVjdG9yKHByb3BzKSB7XG4gICAgICAgIHN1cGVyKHByb3BzKTtcblxuICAgICAgICB0aGlzLl91bm1vdW50ZWQgPSBmYWxzZTtcblxuICAgICAgICB0aGlzLnN0YXRlID0ge1xuICAgICAgICAgICAgZXJyb3I6IG51bGwsXG4gICAgICAgICAgICBjcm9zc1NpZ25pbmdQdWJsaWNLZXlzT25EZXZpY2U6IG51bGwsXG4gICAgICAgICAgICBjcm9zc1NpZ25pbmdQcml2YXRlS2V5c0luU3RvcmFnZTogbnVsbCxcbiAgICAgICAgICAgIG1hc3RlclByaXZhdGVLZXlDYWNoZWQ6IG51bGwsXG4gICAgICAgICAgICBzZWxmU2lnbmluZ1ByaXZhdGVLZXlDYWNoZWQ6IG51bGwsXG4gICAgICAgICAgICB1c2VyU2lnbmluZ1ByaXZhdGVLZXlDYWNoZWQ6IG51bGwsXG4gICAgICAgICAgICBob21lc2VydmVyU3VwcG9ydHNDcm9zc1NpZ25pbmc6IG51bGwsXG4gICAgICAgICAgICBjcm9zc1NpZ25pbmdSZWFkeTogbnVsbCxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBjb21wb25lbnREaWRNb3VudCgpIHtcbiAgICAgICAgY29uc3QgY2xpID0gTWF0cml4Q2xpZW50UGVnLmdldCgpO1xuICAgICAgICBjbGkub24oXCJhY2NvdW50RGF0YVwiLCB0aGlzLm9uQWNjb3VudERhdGEpO1xuICAgICAgICBjbGkub24oXCJ1c2VyVHJ1c3RTdGF0dXNDaGFuZ2VkXCIsIHRoaXMub25TdGF0dXNDaGFuZ2VkKTtcbiAgICAgICAgY2xpLm9uKFwiY3Jvc3NTaWduaW5nLmtleXNDaGFuZ2VkXCIsIHRoaXMub25TdGF0dXNDaGFuZ2VkKTtcbiAgICAgICAgdGhpcy5fZ2V0VXBkYXRlZFN0YXR1cygpO1xuICAgIH1cblxuICAgIGNvbXBvbmVudFdpbGxVbm1vdW50KCkge1xuICAgICAgICB0aGlzLl91bm1vdW50ZWQgPSB0cnVlO1xuICAgICAgICBjb25zdCBjbGkgPSBNYXRyaXhDbGllbnRQZWcuZ2V0KCk7XG4gICAgICAgIGlmICghY2xpKSByZXR1cm47XG4gICAgICAgIGNsaS5yZW1vdmVMaXN0ZW5lcihcImFjY291bnREYXRhXCIsIHRoaXMub25BY2NvdW50RGF0YSk7XG4gICAgICAgIGNsaS5yZW1vdmVMaXN0ZW5lcihcInVzZXJUcnVzdFN0YXR1c0NoYW5nZWRcIiwgdGhpcy5vblN0YXR1c0NoYW5nZWQpO1xuICAgICAgICBjbGkucmVtb3ZlTGlzdGVuZXIoXCJjcm9zc1NpZ25pbmcua2V5c0NoYW5nZWRcIiwgdGhpcy5vblN0YXR1c0NoYW5nZWQpO1xuICAgIH1cblxuICAgIG9uQWNjb3VudERhdGEgPSAoZXZlbnQpID0+IHtcbiAgICAgICAgY29uc3QgdHlwZSA9IGV2ZW50LmdldFR5cGUoKTtcbiAgICAgICAgaWYgKHR5cGUuc3RhcnRzV2l0aChcIm0uY3Jvc3Nfc2lnbmluZ1wiKSB8fCB0eXBlLnN0YXJ0c1dpdGgoXCJtLnNlY3JldF9zdG9yYWdlXCIpKSB7XG4gICAgICAgICAgICB0aGlzLl9nZXRVcGRhdGVkU3RhdHVzKCk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgX29uQm9vdHN0cmFwQ2xpY2sgPSAoKSA9PiB7XG4gICAgICAgIHRoaXMuX2Jvb3RzdHJhcENyb3NzU2lnbmluZyh7IGZvcmNlUmVzZXQ6IGZhbHNlIH0pO1xuICAgIH07XG5cbiAgICBvblN0YXR1c0NoYW5nZWQgPSAoKSA9PiB7XG4gICAgICAgIHRoaXMuX2dldFVwZGF0ZWRTdGF0dXMoKTtcbiAgICB9O1xuXG4gICAgYXN5bmMgX2dldFVwZGF0ZWRTdGF0dXMoKSB7XG4gICAgICAgIGNvbnN0IGNsaSA9IE1hdHJpeENsaWVudFBlZy5nZXQoKTtcbiAgICAgICAgY29uc3QgcGtDYWNoZSA9IGNsaS5nZXRDcm9zc1NpZ25pbmdDYWNoZUNhbGxiYWNrcygpO1xuICAgICAgICBjb25zdCBjcm9zc1NpZ25pbmcgPSBjbGkuX2NyeXB0by5fY3Jvc3NTaWduaW5nSW5mbztcbiAgICAgICAgY29uc3Qgc2VjcmV0U3RvcmFnZSA9IGNsaS5fY3J5cHRvLl9zZWNyZXRTdG9yYWdlO1xuICAgICAgICBjb25zdCBjcm9zc1NpZ25pbmdQdWJsaWNLZXlzT25EZXZpY2UgPSBjcm9zc1NpZ25pbmcuZ2V0SWQoKTtcbiAgICAgICAgY29uc3QgY3Jvc3NTaWduaW5nUHJpdmF0ZUtleXNJblN0b3JhZ2UgPSBhd2FpdCBjcm9zc1NpZ25pbmcuaXNTdG9yZWRJblNlY3JldFN0b3JhZ2Uoc2VjcmV0U3RvcmFnZSk7XG4gICAgICAgIGNvbnN0IG1hc3RlclByaXZhdGVLZXlDYWNoZWQgPSAhIShwa0NhY2hlICYmIGF3YWl0IHBrQ2FjaGUuZ2V0Q3Jvc3NTaWduaW5nS2V5Q2FjaGUoXCJtYXN0ZXJcIikpO1xuICAgICAgICBjb25zdCBzZWxmU2lnbmluZ1ByaXZhdGVLZXlDYWNoZWQgPSAhIShwa0NhY2hlICYmIGF3YWl0IHBrQ2FjaGUuZ2V0Q3Jvc3NTaWduaW5nS2V5Q2FjaGUoXCJzZWxmX3NpZ25pbmdcIikpO1xuICAgICAgICBjb25zdCB1c2VyU2lnbmluZ1ByaXZhdGVLZXlDYWNoZWQgPSAhIShwa0NhY2hlICYmIGF3YWl0IHBrQ2FjaGUuZ2V0Q3Jvc3NTaWduaW5nS2V5Q2FjaGUoXCJ1c2VyX3NpZ25pbmdcIikpO1xuICAgICAgICBjb25zdCBob21lc2VydmVyU3VwcG9ydHNDcm9zc1NpZ25pbmcgPVxuICAgICAgICAgICAgYXdhaXQgY2xpLmRvZXNTZXJ2ZXJTdXBwb3J0VW5zdGFibGVGZWF0dXJlKFwib3JnLm1hdHJpeC5lMmVfY3Jvc3Nfc2lnbmluZ1wiKTtcbiAgICAgICAgY29uc3QgY3Jvc3NTaWduaW5nUmVhZHkgPSBhd2FpdCBjbGkuaXNDcm9zc1NpZ25pbmdSZWFkeSgpO1xuXG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgY3Jvc3NTaWduaW5nUHVibGljS2V5c09uRGV2aWNlLFxuICAgICAgICAgICAgY3Jvc3NTaWduaW5nUHJpdmF0ZUtleXNJblN0b3JhZ2UsXG4gICAgICAgICAgICBtYXN0ZXJQcml2YXRlS2V5Q2FjaGVkLFxuICAgICAgICAgICAgc2VsZlNpZ25pbmdQcml2YXRlS2V5Q2FjaGVkLFxuICAgICAgICAgICAgdXNlclNpZ25pbmdQcml2YXRlS2V5Q2FjaGVkLFxuICAgICAgICAgICAgaG9tZXNlcnZlclN1cHBvcnRzQ3Jvc3NTaWduaW5nLFxuICAgICAgICAgICAgY3Jvc3NTaWduaW5nUmVhZHksXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEJvb3RzdHJhcHBpbmcgY3Jvc3Mtc2lnbmluZyB0YWtlIG9uZSBvZiB0aGVzZSBwYXRoczpcbiAgICAgKiAxLiBDcmVhdGUgY3Jvc3Mtc2lnbmluZyBrZXlzIGxvY2FsbHkgYW5kIHN0b3JlIGluIHNlY3JldCBzdG9yYWdlIChpZiBpdFxuICAgICAqICAgIGFscmVhZHkgZXhpc3RzIG9uIHRoZSBhY2NvdW50KS5cbiAgICAgKiAyLiBBY2Nlc3MgZXhpc3Rpbmcgc2VjcmV0IHN0b3JhZ2UgYnkgcmVxdWVzdGluZyBwYXNzcGhyYXNlIGFuZCBhY2Nlc3NpbmdcbiAgICAgKiAgICBjcm9zcy1zaWduaW5nIGtleXMgYXMgbmVlZGVkLlxuICAgICAqIDMuIEFsbCBrZXlzIGFyZSBsb2FkZWQgYW5kIHRoZXJlJ3Mgbm90aGluZyB0byBkby5cbiAgICAgKiBAcGFyYW0ge2Jvb2x9IFtmb3JjZVJlc2V0XSBCb290c3RyYXAgYWdhaW4gZXZlbiBpZiBrZXlzIGFscmVhZHkgcHJlc2VudFxuICAgICAqL1xuICAgIF9ib290c3RyYXBDcm9zc1NpZ25pbmcgPSBhc3luYyAoeyBmb3JjZVJlc2V0ID0gZmFsc2UgfSkgPT4ge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgZXJyb3I6IG51bGwgfSk7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBjbGkgPSBNYXRyaXhDbGllbnRQZWcuZ2V0KCk7XG4gICAgICAgICAgICBhd2FpdCBjbGkuYm9vdHN0cmFwQ3Jvc3NTaWduaW5nKHtcbiAgICAgICAgICAgICAgICBhdXRoVXBsb2FkRGV2aWNlU2lnbmluZ0tleXM6IGFzeW5jIChtYWtlUmVxdWVzdCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB7IGZpbmlzaGVkIH0gPSBNb2RhbC5jcmVhdGVUcmFja2VkRGlhbG9nKFxuICAgICAgICAgICAgICAgICAgICAgICAgJ0Nyb3NzLXNpZ25pbmcga2V5cyBkaWFsb2cnLCAnJywgSW50ZXJhY3RpdmVBdXRoRGlhbG9nLFxuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlOiBfdChcIlNldHRpbmcgdXAga2V5c1wiKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRyaXhDbGllbnQ6IGNsaSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYWtlUmVxdWVzdCxcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IFtjb25maXJtZWRdID0gYXdhaXQgZmluaXNoZWQ7XG4gICAgICAgICAgICAgICAgICAgIGlmICghY29uZmlybWVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDcm9zcy1zaWduaW5nIGtleSB1cGxvYWQgYXV0aCBjYW5jZWxlZFwiKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgc2V0dXBOZXdDcm9zc1NpZ25pbmc6IGZvcmNlUmVzZXQsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGVycm9yOiBlIH0pO1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIkVycm9yIGJvb3RzdHJhcHBpbmcgY3Jvc3Mtc2lnbmluZ1wiLCBlKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5fdW5tb3VudGVkKSByZXR1cm47XG4gICAgICAgIHRoaXMuX2dldFVwZGF0ZWRTdGF0dXMoKTtcbiAgICB9XG5cbiAgICBfcmVzZXRDcm9zc1NpZ25pbmcgPSAoKSA9PiB7XG4gICAgICAgIE1vZGFsLmNyZWF0ZURpYWxvZyhDb25maXJtRGVzdHJveUNyb3NzU2lnbmluZ0RpYWxvZywge1xuICAgICAgICAgICAgb25GaW5pc2hlZDogKGFjdCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghYWN0KSByZXR1cm47XG4gICAgICAgICAgICAgICAgdGhpcy5fYm9vdHN0cmFwQ3Jvc3NTaWduaW5nKHsgZm9yY2VSZXNldDogdHJ1ZSB9KTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHJlbmRlcigpIHtcbiAgICAgICAgY29uc3QgQWNjZXNzaWJsZUJ1dHRvbiA9IHNkay5nZXRDb21wb25lbnQoXCJlbGVtZW50cy5BY2Nlc3NpYmxlQnV0dG9uXCIpO1xuICAgICAgICBjb25zdCB7XG4gICAgICAgICAgICBlcnJvcixcbiAgICAgICAgICAgIGNyb3NzU2lnbmluZ1B1YmxpY0tleXNPbkRldmljZSxcbiAgICAgICAgICAgIGNyb3NzU2lnbmluZ1ByaXZhdGVLZXlzSW5TdG9yYWdlLFxuICAgICAgICAgICAgbWFzdGVyUHJpdmF0ZUtleUNhY2hlZCxcbiAgICAgICAgICAgIHNlbGZTaWduaW5nUHJpdmF0ZUtleUNhY2hlZCxcbiAgICAgICAgICAgIHVzZXJTaWduaW5nUHJpdmF0ZUtleUNhY2hlZCxcbiAgICAgICAgICAgIGhvbWVzZXJ2ZXJTdXBwb3J0c0Nyb3NzU2lnbmluZyxcbiAgICAgICAgICAgIGNyb3NzU2lnbmluZ1JlYWR5LFxuICAgICAgICB9ID0gdGhpcy5zdGF0ZTtcblxuICAgICAgICBsZXQgZXJyb3JTZWN0aW9uO1xuICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgIGVycm9yU2VjdGlvbiA9IDxkaXYgY2xhc3NOYW1lPVwiZXJyb3JcIj57ZXJyb3IudG9TdHJpbmcoKX08L2Rpdj47XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgc3VtbWFyaXNlZFN0YXR1cztcbiAgICAgICAgaWYgKGhvbWVzZXJ2ZXJTdXBwb3J0c0Nyb3NzU2lnbmluZyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBzdW1tYXJpc2VkU3RhdHVzID0gPFNwaW5uZXIgLz47XG4gICAgICAgIH0gZWxzZSBpZiAoIWhvbWVzZXJ2ZXJTdXBwb3J0c0Nyb3NzU2lnbmluZykge1xuICAgICAgICAgICAgc3VtbWFyaXNlZFN0YXR1cyA9IDxwPntfdChcbiAgICAgICAgICAgICAgICBcIllvdXIgaG9tZXNlcnZlciBkb2VzIG5vdCBzdXBwb3J0IGNyb3NzLXNpZ25pbmcuXCIsXG4gICAgICAgICAgICApfTwvcD47XG4gICAgICAgIH0gZWxzZSBpZiAoY3Jvc3NTaWduaW5nUmVhZHkpIHtcbiAgICAgICAgICAgIHN1bW1hcmlzZWRTdGF0dXMgPSA8cD7inIUge190KFxuICAgICAgICAgICAgICAgIFwiQ3Jvc3Mtc2lnbmluZyBpcyByZWFkeSBmb3IgdXNlLlwiLFxuICAgICAgICAgICAgKX08L3A+O1xuICAgICAgICB9IGVsc2UgaWYgKGNyb3NzU2lnbmluZ1ByaXZhdGVLZXlzSW5TdG9yYWdlKSB7XG4gICAgICAgICAgICBzdW1tYXJpc2VkU3RhdHVzID0gPHA+e190KFxuICAgICAgICAgICAgICAgIFwiWW91ciBhY2NvdW50IGhhcyBhIGNyb3NzLXNpZ25pbmcgaWRlbnRpdHkgaW4gc2VjcmV0IHN0b3JhZ2UsIFwiICtcbiAgICAgICAgICAgICAgICBcImJ1dCBpdCBpcyBub3QgeWV0IHRydXN0ZWQgYnkgdGhpcyBzZXNzaW9uLlwiLFxuICAgICAgICAgICAgKX08L3A+O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc3VtbWFyaXNlZFN0YXR1cyA9IDxwPntfdChcbiAgICAgICAgICAgICAgICBcIkNyb3NzLXNpZ25pbmcgaXMgbm90IHNldCB1cC5cIixcbiAgICAgICAgICAgICl9PC9wPjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGtleXNFeGlzdEFueXdoZXJlID0gKFxuICAgICAgICAgICAgY3Jvc3NTaWduaW5nUHVibGljS2V5c09uRGV2aWNlIHx8XG4gICAgICAgICAgICBjcm9zc1NpZ25pbmdQcml2YXRlS2V5c0luU3RvcmFnZSB8fFxuICAgICAgICAgICAgbWFzdGVyUHJpdmF0ZUtleUNhY2hlZCB8fFxuICAgICAgICAgICAgc2VsZlNpZ25pbmdQcml2YXRlS2V5Q2FjaGVkIHx8XG4gICAgICAgICAgICB1c2VyU2lnbmluZ1ByaXZhdGVLZXlDYWNoZWRcbiAgICAgICAgKTtcbiAgICAgICAgY29uc3Qga2V5c0V4aXN0RXZlcnl3aGVyZSA9IChcbiAgICAgICAgICAgIGNyb3NzU2lnbmluZ1B1YmxpY0tleXNPbkRldmljZSAmJlxuICAgICAgICAgICAgY3Jvc3NTaWduaW5nUHJpdmF0ZUtleXNJblN0b3JhZ2UgJiZcbiAgICAgICAgICAgIG1hc3RlclByaXZhdGVLZXlDYWNoZWQgJiZcbiAgICAgICAgICAgIHNlbGZTaWduaW5nUHJpdmF0ZUtleUNhY2hlZCAmJlxuICAgICAgICAgICAgdXNlclNpZ25pbmdQcml2YXRlS2V5Q2FjaGVkXG4gICAgICAgICk7XG5cbiAgICAgICAgY29uc3QgYWN0aW9ucyA9IFtdO1xuXG4gICAgICAgIC8vIFRPRE86IGRldGVybWluZSBob3cgYmV0dGVyIHRvIGV4cG9zZSB0aGlzIHRvIHVzZXJzIGluIGFkZGl0aW9uIHRvIHByb21wdHMgYXQgbG9naW4vdG9hc3RcbiAgICAgICAgaWYgKCFrZXlzRXhpc3RFdmVyeXdoZXJlICYmIGhvbWVzZXJ2ZXJTdXBwb3J0c0Nyb3NzU2lnbmluZykge1xuICAgICAgICAgICAgYWN0aW9ucy5wdXNoKFxuICAgICAgICAgICAgICAgIDxBY2Nlc3NpYmxlQnV0dG9uIGtleT1cInNldHVwXCIga2luZD1cInByaW1hcnlcIiBvbkNsaWNrPXt0aGlzLl9vbkJvb3RzdHJhcENsaWNrfT5cbiAgICAgICAgICAgICAgICAgICAge190KFwiU2V0IHVwXCIpfVxuICAgICAgICAgICAgICAgIDwvQWNjZXNzaWJsZUJ1dHRvbj4sXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGtleXNFeGlzdEFueXdoZXJlKSB7XG4gICAgICAgICAgICBhY3Rpb25zLnB1c2goXG4gICAgICAgICAgICAgICAgPEFjY2Vzc2libGVCdXR0b24ga2V5PVwicmVzZXRcIiBraW5kPVwiZGFuZ2VyXCIgb25DbGljaz17dGhpcy5fcmVzZXRDcm9zc1NpZ25pbmd9PlxuICAgICAgICAgICAgICAgICAgICB7X3QoXCJSZXNldFwiKX1cbiAgICAgICAgICAgICAgICA8L0FjY2Vzc2libGVCdXR0b24+LFxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBhY3Rpb25Sb3c7XG4gICAgICAgIGlmIChhY3Rpb25zLmxlbmd0aCkge1xuICAgICAgICAgICAgYWN0aW9uUm93ID0gPGRpdiBjbGFzc05hbWU9XCJteF9Dcm9zc1NpZ25pbmdQYW5lbF9idXR0b25Sb3dcIj5cbiAgICAgICAgICAgICAgICB7YWN0aW9uc31cbiAgICAgICAgICAgIDwvZGl2PjtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICAgIHtzdW1tYXJpc2VkU3RhdHVzfVxuICAgICAgICAgICAgICAgIDxkZXRhaWxzPlxuICAgICAgICAgICAgICAgICAgICA8c3VtbWFyeT57X3QoXCJBZHZhbmNlZFwiKX08L3N1bW1hcnk+XG4gICAgICAgICAgICAgICAgICAgIDx0YWJsZSBjbGFzc05hbWU9XCJteF9Dcm9zc1NpZ25pbmdQYW5lbF9zdGF0dXNMaXN0XCI+PHRib2R5PlxuICAgICAgICAgICAgICAgICAgICAgICAgPHRyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZD57X3QoXCJDcm9zcy1zaWduaW5nIHB1YmxpYyBrZXlzOlwiKX08L3RkPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZD57Y3Jvc3NTaWduaW5nUHVibGljS2V5c09uRGV2aWNlID8gX3QoXCJpbiBtZW1vcnlcIikgOiBfdChcIm5vdCBmb3VuZFwiKX08L3RkPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC90cj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDx0cj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQ+e190KFwiQ3Jvc3Mtc2lnbmluZyBwcml2YXRlIGtleXM6XCIpfTwvdGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkPntjcm9zc1NpZ25pbmdQcml2YXRlS2V5c0luU3RvcmFnZSA/IF90KFwiaW4gc2VjcmV0IHN0b3JhZ2VcIikgOiBfdChcIm5vdCBmb3VuZCBpbiBzdG9yYWdlXCIpfTwvdGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L3RyPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHRyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZD57X3QoXCJNYXN0ZXIgcHJpdmF0ZSBrZXk6XCIpfTwvdGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkPnttYXN0ZXJQcml2YXRlS2V5Q2FjaGVkID8gX3QoXCJjYWNoZWQgbG9jYWxseVwiKSA6IF90KFwibm90IGZvdW5kIGxvY2FsbHlcIil9PC90ZD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8dHI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkPntfdChcIlNlbGYgc2lnbmluZyBwcml2YXRlIGtleTpcIil9PC90ZD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQ+e3NlbGZTaWduaW5nUHJpdmF0ZUtleUNhY2hlZCA/IF90KFwiY2FjaGVkIGxvY2FsbHlcIikgOiBfdChcIm5vdCBmb3VuZCBsb2NhbGx5XCIpfTwvdGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L3RyPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHRyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZD57X3QoXCJVc2VyIHNpZ25pbmcgcHJpdmF0ZSBrZXk6XCIpfTwvdGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkPnt1c2VyU2lnbmluZ1ByaXZhdGVLZXlDYWNoZWQgPyBfdChcImNhY2hlZCBsb2NhbGx5XCIpIDogX3QoXCJub3QgZm91bmQgbG9jYWxseVwiKX08L3RkPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC90cj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDx0cj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQ+e190KFwiSG9tZXNlcnZlciBmZWF0dXJlIHN1cHBvcnQ6XCIpfTwvdGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkPntob21lc2VydmVyU3VwcG9ydHNDcm9zc1NpZ25pbmcgPyBfdChcImV4aXN0c1wiKSA6IF90KFwibm90IGZvdW5kXCIpfTwvdGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L3RyPlxuICAgICAgICAgICAgICAgICAgICA8L3Rib2R5PjwvdGFibGU+XG4gICAgICAgICAgICAgICAgPC9kZXRhaWxzPlxuICAgICAgICAgICAgICAgIHtlcnJvclNlY3Rpb259XG4gICAgICAgICAgICAgICAge2FjdGlvblJvd31cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICApO1xuICAgIH1cbn1cbiJdfQ==