UNPKG

matrix-react-sdk

Version:
163 lines (157 loc) 23.4 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.OidcClientStore = void 0; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _matrix = require("matrix-js-sdk/src/matrix"); var _logger = require("matrix-js-sdk/src/logger"); var _oidcClientTs = require("oidc-client-ts"); var _persistOidcSettings = require("../../utils/oidc/persistOidcSettings"); var _PlatformPeg = _interopRequireDefault(require("../../PlatformPeg")); function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } /* Copyright 2024 New Vector Ltd. Copyright 2023 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. */ /** * @experimental * Stores information about configured OIDC provider * * In OIDC Native mode the client is registered with OIDC directly and maintains an OIDC token. * * In OIDC Aware mode, the client is aware that the Server is using OIDC, but is using the standard Matrix APIs for most things. * (Notable exceptions are account management, where a link to the account management endpoint will be provided instead.) * * Otherwise, the store is not operating. Auth is then in Legacy mode and everything uses normal Matrix APIs. */ class OidcClientStore { constructor(matrixClient) { (0, _defineProperty2.default)(this, "oidcClient", void 0); (0, _defineProperty2.default)(this, "initialisingOidcClientPromise", void 0); (0, _defineProperty2.default)(this, "authenticatedIssuer", void 0); // set only in OIDC-native mode (0, _defineProperty2.default)(this, "_accountManagementEndpoint", void 0); /** * Promise which resolves once this store is read to use, which may mean there is no OIDC client if we're in legacy mode, * or we just have the account management endpoint if running in OIDC-aware mode. */ (0, _defineProperty2.default)(this, "readyPromise", void 0); this.matrixClient = matrixClient; this.readyPromise = this.init(); } async init() { this.authenticatedIssuer = (0, _persistOidcSettings.getStoredOidcTokenIssuer)(); if (this.authenticatedIssuer) { await this.getOidcClient(); } else { // We are not in OIDC Native mode, as we have no locally stored issuer. Check if the server delegates auth to OIDC. try { const authIssuer = await this.matrixClient.getAuthIssuer(); const { accountManagementEndpoint, metadata } = await (0, _matrix.discoverAndValidateOIDCIssuerWellKnown)(authIssuer.issuer); this.setAccountManagementEndpoint(accountManagementEndpoint, metadata.issuer); } catch (e) { console.log("Auth issuer not found", e); } } } /** * True when the active user is authenticated via OIDC */ get isUserAuthenticatedWithOidc() { return !!this.authenticatedIssuer; } setAccountManagementEndpoint(endpoint, issuer) { // if no account endpoint is configured default to the issuer const url = new URL(endpoint ?? issuer); const idToken = (0, _persistOidcSettings.getStoredOidcIdToken)(); if (idToken) { url.searchParams.set("id_token_hint", idToken); } this._accountManagementEndpoint = url.toString(); } get accountManagementEndpoint() { return this._accountManagementEndpoint; } /** * Revokes provided access and refresh tokens with the configured OIDC provider * @param accessToken * @param refreshToken * @returns Promise that resolves when tokens have been revoked * @throws when OidcClient cannot be initialised, or revoking either token fails */ async revokeTokens(accessToken, refreshToken) { const client = await this.getOidcClient(); if (!client) { throw new Error("No OIDC client"); } const results = await Promise.all([this.tryRevokeToken(client, accessToken, "access_token"), this.tryRevokeToken(client, refreshToken, "refresh_token")]); if (results.some(success => !success)) { throw new Error("Failed to revoke tokens"); } } /** * Try to revoke a given token * @param oidcClient * @param token * @param tokenType passed to revocation endpoint as token type hint * @returns Promise that resolved with boolean whether the token revocation succeeded or not */ async tryRevokeToken(oidcClient, token, tokenType) { try { if (!token) { return false; } await oidcClient.revokeToken(token, tokenType); return true; } catch (error) { _logger.logger.error(`Failed to revoke ${tokenType}`, error); return false; } } async getOidcClient() { if (!this.oidcClient && !this.initialisingOidcClientPromise) { this.initialisingOidcClientPromise = this.initOidcClient(); } await this.initialisingOidcClientPromise; this.initialisingOidcClientPromise = undefined; return this.oidcClient; } /** * Tries to initialise an OidcClient using stored clientId and OIDC discovery. * Assigns this.oidcClient and accountManagement endpoint. * Logs errors and does not throw when oidc client cannot be initialised. * @returns promise that resolves when initialising OidcClient succeeds or fails */ async initOidcClient() { if (!this.authenticatedIssuer) { _logger.logger.error("Cannot initialise OIDC client without issuer."); return; } try { const clientId = (0, _persistOidcSettings.getStoredOidcClientId)(); const { accountManagementEndpoint, metadata, signingKeys } = await (0, _matrix.discoverAndValidateOIDCIssuerWellKnown)(this.authenticatedIssuer); this.setAccountManagementEndpoint(accountManagementEndpoint, metadata.issuer); this.oidcClient = new _oidcClientTs.OidcClient(_objectSpread(_objectSpread({}, metadata), {}, { authority: metadata.issuer, signingKeys, redirect_uri: _PlatformPeg.default.get().getOidcCallbackUrl().href, client_id: clientId })); } catch (error) { _logger.logger.error("Failed to initialise OidcClientStore", error); } } } exports.OidcClientStore = OidcClientStore; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfbWF0cml4IiwicmVxdWlyZSIsIl9sb2dnZXIiLCJfb2lkY0NsaWVudFRzIiwiX3BlcnNpc3RPaWRjU2V0dGluZ3MiLCJfUGxhdGZvcm1QZWciLCJfaW50ZXJvcFJlcXVpcmVEZWZhdWx0Iiwib3duS2V5cyIsImUiLCJyIiwidCIsIk9iamVjdCIsImtleXMiLCJnZXRPd25Qcm9wZXJ0eVN5bWJvbHMiLCJvIiwiZmlsdGVyIiwiZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yIiwiZW51bWVyYWJsZSIsInB1c2giLCJhcHBseSIsIl9vYmplY3RTcHJlYWQiLCJhcmd1bWVudHMiLCJsZW5ndGgiLCJmb3JFYWNoIiwiX2RlZmluZVByb3BlcnR5MiIsImRlZmF1bHQiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzIiwiZGVmaW5lUHJvcGVydGllcyIsImRlZmluZVByb3BlcnR5IiwiT2lkY0NsaWVudFN0b3JlIiwiY29uc3RydWN0b3IiLCJtYXRyaXhDbGllbnQiLCJyZWFkeVByb21pc2UiLCJpbml0IiwiYXV0aGVudGljYXRlZElzc3VlciIsImdldFN0b3JlZE9pZGNUb2tlbklzc3VlciIsImdldE9pZGNDbGllbnQiLCJhdXRoSXNzdWVyIiwiZ2V0QXV0aElzc3VlciIsImFjY291bnRNYW5hZ2VtZW50RW5kcG9pbnQiLCJtZXRhZGF0YSIsImRpc2NvdmVyQW5kVmFsaWRhdGVPSURDSXNzdWVyV2VsbEtub3duIiwiaXNzdWVyIiwic2V0QWNjb3VudE1hbmFnZW1lbnRFbmRwb2ludCIsImNvbnNvbGUiLCJsb2ciLCJpc1VzZXJBdXRoZW50aWNhdGVkV2l0aE9pZGMiLCJlbmRwb2ludCIsInVybCIsIlVSTCIsImlkVG9rZW4iLCJnZXRTdG9yZWRPaWRjSWRUb2tlbiIsInNlYXJjaFBhcmFtcyIsInNldCIsIl9hY2NvdW50TWFuYWdlbWVudEVuZHBvaW50IiwidG9TdHJpbmciLCJyZXZva2VUb2tlbnMiLCJhY2Nlc3NUb2tlbiIsInJlZnJlc2hUb2tlbiIsImNsaWVudCIsIkVycm9yIiwicmVzdWx0cyIsIlByb21pc2UiLCJhbGwiLCJ0cnlSZXZva2VUb2tlbiIsInNvbWUiLCJzdWNjZXNzIiwib2lkY0NsaWVudCIsInRva2VuIiwidG9rZW5UeXBlIiwicmV2b2tlVG9rZW4iLCJlcnJvciIsImxvZ2dlciIsImluaXRpYWxpc2luZ09pZGNDbGllbnRQcm9taXNlIiwiaW5pdE9pZGNDbGllbnQiLCJ1bmRlZmluZWQiLCJjbGllbnRJZCIsImdldFN0b3JlZE9pZGNDbGllbnRJZCIsInNpZ25pbmdLZXlzIiwiT2lkY0NsaWVudCIsImF1dGhvcml0eSIsInJlZGlyZWN0X3VyaSIsIlBsYXRmb3JtUGVnIiwiZ2V0IiwiZ2V0T2lkY0NhbGxiYWNrVXJsIiwiaHJlZiIsImNsaWVudF9pZCIsImV4cG9ydHMiXSwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvc3RvcmVzL29pZGMvT2lkY0NsaWVudFN0b3JlLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qXG5Db3B5cmlnaHQgMjAyNCBOZXcgVmVjdG9yIEx0ZC5cbkNvcHlyaWdodCAyMDIzIFRoZSBNYXRyaXgub3JnIEZvdW5kYXRpb24gQy5JLkMuXG5cblNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBR1BMLTMuMC1vbmx5IE9SIEdQTC0zLjAtb25seVxuUGxlYXNlIHNlZSBMSUNFTlNFIGZpbGVzIGluIHRoZSByZXBvc2l0b3J5IHJvb3QgZm9yIGZ1bGwgZGV0YWlscy5cbiovXG5cbmltcG9ydCB7IE1hdHJpeENsaWVudCwgZGlzY292ZXJBbmRWYWxpZGF0ZU9JRENJc3N1ZXJXZWxsS25vd24gfSBmcm9tIFwibWF0cml4LWpzLXNkay9zcmMvbWF0cml4XCI7XG5pbXBvcnQgeyBsb2dnZXIgfSBmcm9tIFwibWF0cml4LWpzLXNkay9zcmMvbG9nZ2VyXCI7XG5pbXBvcnQgeyBPaWRjQ2xpZW50IH0gZnJvbSBcIm9pZGMtY2xpZW50LXRzXCI7XG5cbmltcG9ydCB7XG4gICAgZ2V0U3RvcmVkT2lkY1Rva2VuSXNzdWVyLFxuICAgIGdldFN0b3JlZE9pZGNDbGllbnRJZCxcbiAgICBnZXRTdG9yZWRPaWRjSWRUb2tlbixcbn0gZnJvbSBcIi4uLy4uL3V0aWxzL29pZGMvcGVyc2lzdE9pZGNTZXR0aW5nc1wiO1xuaW1wb3J0IFBsYXRmb3JtUGVnIGZyb20gXCIuLi8uLi9QbGF0Zm9ybVBlZ1wiO1xuXG4vKipcbiAqIEBleHBlcmltZW50YWxcbiAqIFN0b3JlcyBpbmZvcm1hdGlvbiBhYm91dCBjb25maWd1cmVkIE9JREMgcHJvdmlkZXJcbiAqXG4gKiBJbiBPSURDIE5hdGl2ZSBtb2RlIHRoZSBjbGllbnQgaXMgcmVnaXN0ZXJlZCB3aXRoIE9JREMgZGlyZWN0bHkgYW5kIG1haW50YWlucyBhbiBPSURDIHRva2VuLlxuICpcbiAqIEluIE9JREMgQXdhcmUgbW9kZSwgdGhlIGNsaWVudCBpcyBhd2FyZSB0aGF0IHRoZSBTZXJ2ZXIgaXMgdXNpbmcgT0lEQywgYnV0IGlzIHVzaW5nIHRoZSBzdGFuZGFyZCBNYXRyaXggQVBJcyBmb3IgbW9zdCB0aGluZ3MuXG4gKiAoTm90YWJsZSBleGNlcHRpb25zIGFyZSBhY2NvdW50IG1hbmFnZW1lbnQsIHdoZXJlIGEgbGluayB0byB0aGUgYWNjb3VudCBtYW5hZ2VtZW50IGVuZHBvaW50IHdpbGwgYmUgcHJvdmlkZWQgaW5zdGVhZC4pXG4gKlxuICogT3RoZXJ3aXNlLCB0aGUgc3RvcmUgaXMgbm90IG9wZXJhdGluZy4gQXV0aCBpcyB0aGVuIGluIExlZ2FjeSBtb2RlIGFuZCBldmVyeXRoaW5nIHVzZXMgbm9ybWFsIE1hdHJpeCBBUElzLlxuICovXG5leHBvcnQgY2xhc3MgT2lkY0NsaWVudFN0b3JlIHtcbiAgICBwcml2YXRlIG9pZGNDbGllbnQ/OiBPaWRjQ2xpZW50O1xuICAgIHByaXZhdGUgaW5pdGlhbGlzaW5nT2lkY0NsaWVudFByb21pc2U6IFByb21pc2U8dm9pZD4gfCB1bmRlZmluZWQ7XG4gICAgcHJpdmF0ZSBhdXRoZW50aWNhdGVkSXNzdWVyPzogc3RyaW5nOyAvLyBzZXQgb25seSBpbiBPSURDLW5hdGl2ZSBtb2RlXG4gICAgcHJpdmF0ZSBfYWNjb3VudE1hbmFnZW1lbnRFbmRwb2ludD86IHN0cmluZztcbiAgICAvKipcbiAgICAgKiBQcm9taXNlIHdoaWNoIHJlc29sdmVzIG9uY2UgdGhpcyBzdG9yZSBpcyByZWFkIHRvIHVzZSwgd2hpY2ggbWF5IG1lYW4gdGhlcmUgaXMgbm8gT0lEQyBjbGllbnQgaWYgd2UncmUgaW4gbGVnYWN5IG1vZGUsXG4gICAgICogb3Igd2UganVzdCBoYXZlIHRoZSBhY2NvdW50IG1hbmFnZW1lbnQgZW5kcG9pbnQgaWYgcnVubmluZyBpbiBPSURDLWF3YXJlIG1vZGUuXG4gICAgICovXG4gICAgcHVibGljIHJlYWRvbmx5IHJlYWR5UHJvbWlzZTogUHJvbWlzZTx2b2lkPjtcblxuICAgIHB1YmxpYyBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IG1hdHJpeENsaWVudDogTWF0cml4Q2xpZW50KSB7XG4gICAgICAgIHRoaXMucmVhZHlQcm9taXNlID0gdGhpcy5pbml0KCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBpbml0KCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICB0aGlzLmF1dGhlbnRpY2F0ZWRJc3N1ZXIgPSBnZXRTdG9yZWRPaWRjVG9rZW5Jc3N1ZXIoKTtcbiAgICAgICAgaWYgKHRoaXMuYXV0aGVudGljYXRlZElzc3Vlcikge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5nZXRPaWRjQ2xpZW50KCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBXZSBhcmUgbm90IGluIE9JREMgTmF0aXZlIG1vZGUsIGFzIHdlIGhhdmUgbm8gbG9jYWxseSBzdG9yZWQgaXNzdWVyLiBDaGVjayBpZiB0aGUgc2VydmVyIGRlbGVnYXRlcyBhdXRoIHRvIE9JREMuXG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGF1dGhJc3N1ZXIgPSBhd2FpdCB0aGlzLm1hdHJpeENsaWVudC5nZXRBdXRoSXNzdWVyKCk7XG4gICAgICAgICAgICAgICAgY29uc3QgeyBhY2NvdW50TWFuYWdlbWVudEVuZHBvaW50LCBtZXRhZGF0YSB9ID0gYXdhaXQgZGlzY292ZXJBbmRWYWxpZGF0ZU9JRENJc3N1ZXJXZWxsS25vd24oXG4gICAgICAgICAgICAgICAgICAgIGF1dGhJc3N1ZXIuaXNzdWVyLFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXRBY2NvdW50TWFuYWdlbWVudEVuZHBvaW50KGFjY291bnRNYW5hZ2VtZW50RW5kcG9pbnQsIG1ldGFkYXRhLmlzc3Vlcik7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coXCJBdXRoIGlzc3VlciBub3QgZm91bmRcIiwgZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUcnVlIHdoZW4gdGhlIGFjdGl2ZSB1c2VyIGlzIGF1dGhlbnRpY2F0ZWQgdmlhIE9JRENcbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0IGlzVXNlckF1dGhlbnRpY2F0ZWRXaXRoT2lkYygpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuICEhdGhpcy5hdXRoZW50aWNhdGVkSXNzdWVyO1xuICAgIH1cblxuICAgIHByaXZhdGUgc2V0QWNjb3VudE1hbmFnZW1lbnRFbmRwb2ludChlbmRwb2ludDogc3RyaW5nIHwgdW5kZWZpbmVkLCBpc3N1ZXI6IHN0cmluZyk6IHZvaWQge1xuICAgICAgICAvLyBpZiBubyBhY2NvdW50IGVuZHBvaW50IGlzIGNvbmZpZ3VyZWQgZGVmYXVsdCB0byB0aGUgaXNzdWVyXG4gICAgICAgIGNvbnN0IHVybCA9IG5ldyBVUkwoZW5kcG9pbnQgPz8gaXNzdWVyKTtcbiAgICAgICAgY29uc3QgaWRUb2tlbiA9IGdldFN0b3JlZE9pZGNJZFRva2VuKCk7XG4gICAgICAgIGlmIChpZFRva2VuKSB7XG4gICAgICAgICAgICB1cmwuc2VhcmNoUGFyYW1zLnNldChcImlkX3Rva2VuX2hpbnRcIiwgaWRUb2tlbik7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fYWNjb3VudE1hbmFnZW1lbnRFbmRwb2ludCA9IHVybC50b1N0cmluZygpO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXQgYWNjb3VudE1hbmFnZW1lbnRFbmRwb2ludCgpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgICAgICByZXR1cm4gdGhpcy5fYWNjb3VudE1hbmFnZW1lbnRFbmRwb2ludDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXZva2VzIHByb3ZpZGVkIGFjY2VzcyBhbmQgcmVmcmVzaCB0b2tlbnMgd2l0aCB0aGUgY29uZmlndXJlZCBPSURDIHByb3ZpZGVyXG4gICAgICogQHBhcmFtIGFjY2Vzc1Rva2VuXG4gICAgICogQHBhcmFtIHJlZnJlc2hUb2tlblxuICAgICAqIEByZXR1cm5zIFByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIHRva2VucyBoYXZlIGJlZW4gcmV2b2tlZFxuICAgICAqIEB0aHJvd3Mgd2hlbiBPaWRjQ2xpZW50IGNhbm5vdCBiZSBpbml0aWFsaXNlZCwgb3IgcmV2b2tpbmcgZWl0aGVyIHRva2VuIGZhaWxzXG4gICAgICovXG4gICAgcHVibGljIGFzeW5jIHJldm9rZVRva2VucyhhY2Nlc3NUb2tlbj86IHN0cmluZywgcmVmcmVzaFRva2VuPzogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGNvbnN0IGNsaWVudCA9IGF3YWl0IHRoaXMuZ2V0T2lkY0NsaWVudCgpO1xuXG4gICAgICAgIGlmICghY2xpZW50KSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJObyBPSURDIGNsaWVudFwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBQcm9taXNlLmFsbChbXG4gICAgICAgICAgICB0aGlzLnRyeVJldm9rZVRva2VuKGNsaWVudCwgYWNjZXNzVG9rZW4sIFwiYWNjZXNzX3Rva2VuXCIpLFxuICAgICAgICAgICAgdGhpcy50cnlSZXZva2VUb2tlbihjbGllbnQsIHJlZnJlc2hUb2tlbiwgXCJyZWZyZXNoX3Rva2VuXCIpLFxuICAgICAgICBdKTtcblxuICAgICAgICBpZiAocmVzdWx0cy5zb21lKChzdWNjZXNzKSA9PiAhc3VjY2VzcykpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkZhaWxlZCB0byByZXZva2UgdG9rZW5zXCIpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVHJ5IHRvIHJldm9rZSBhIGdpdmVuIHRva2VuXG4gICAgICogQHBhcmFtIG9pZGNDbGllbnRcbiAgICAgKiBAcGFyYW0gdG9rZW5cbiAgICAgKiBAcGFyYW0gdG9rZW5UeXBlIHBhc3NlZCB0byByZXZvY2F0aW9uIGVuZHBvaW50IGFzIHRva2VuIHR5cGUgaGludFxuICAgICAqIEByZXR1cm5zIFByb21pc2UgdGhhdCByZXNvbHZlZCB3aXRoIGJvb2xlYW4gd2hldGhlciB0aGUgdG9rZW4gcmV2b2NhdGlvbiBzdWNjZWVkZWQgb3Igbm90XG4gICAgICovXG4gICAgcHJpdmF0ZSBhc3luYyB0cnlSZXZva2VUb2tlbihcbiAgICAgICAgb2lkY0NsaWVudDogT2lkY0NsaWVudCxcbiAgICAgICAgdG9rZW46IHN0cmluZyB8IHVuZGVmaW5lZCxcbiAgICAgICAgdG9rZW5UeXBlOiBcImFjY2Vzc190b2tlblwiIHwgXCJyZWZyZXNoX3Rva2VuXCIsXG4gICAgKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBpZiAoIXRva2VuKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYXdhaXQgb2lkY0NsaWVudC5yZXZva2VUb2tlbih0b2tlbiwgdG9rZW5UeXBlKTtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgbG9nZ2VyLmVycm9yKGBGYWlsZWQgdG8gcmV2b2tlICR7dG9rZW5UeXBlfWAsIGVycm9yKTtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgZ2V0T2lkY0NsaWVudCgpOiBQcm9taXNlPE9pZGNDbGllbnQgfCB1bmRlZmluZWQ+IHtcbiAgICAgICAgaWYgKCF0aGlzLm9pZGNDbGllbnQgJiYgIXRoaXMuaW5pdGlhbGlzaW5nT2lkY0NsaWVudFByb21pc2UpIHtcbiAgICAgICAgICAgIHRoaXMuaW5pdGlhbGlzaW5nT2lkY0NsaWVudFByb21pc2UgPSB0aGlzLmluaXRPaWRjQ2xpZW50KCk7XG4gICAgICAgIH1cbiAgICAgICAgYXdhaXQgdGhpcy5pbml0aWFsaXNpbmdPaWRjQ2xpZW50UHJvbWlzZTtcbiAgICAgICAgdGhpcy5pbml0aWFsaXNpbmdPaWRjQ2xpZW50UHJvbWlzZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgcmV0dXJuIHRoaXMub2lkY0NsaWVudDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUcmllcyB0byBpbml0aWFsaXNlIGFuIE9pZGNDbGllbnQgdXNpbmcgc3RvcmVkIGNsaWVudElkIGFuZCBPSURDIGRpc2NvdmVyeS5cbiAgICAgKiBBc3NpZ25zIHRoaXMub2lkY0NsaWVudCBhbmQgYWNjb3VudE1hbmFnZW1lbnQgZW5kcG9pbnQuXG4gICAgICogTG9ncyBlcnJvcnMgYW5kIGRvZXMgbm90IHRocm93IHdoZW4gb2lkYyBjbGllbnQgY2Fubm90IGJlIGluaXRpYWxpc2VkLlxuICAgICAqIEByZXR1cm5zIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIGluaXRpYWxpc2luZyBPaWRjQ2xpZW50IHN1Y2NlZWRzIG9yIGZhaWxzXG4gICAgICovXG4gICAgcHJpdmF0ZSBhc3luYyBpbml0T2lkY0NsaWVudCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgaWYgKCF0aGlzLmF1dGhlbnRpY2F0ZWRJc3N1ZXIpIHtcbiAgICAgICAgICAgIGxvZ2dlci5lcnJvcihcIkNhbm5vdCBpbml0aWFsaXNlIE9JREMgY2xpZW50IHdpdGhvdXQgaXNzdWVyLlwiKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBjbGllbnRJZCA9IGdldFN0b3JlZE9pZGNDbGllbnRJZCgpO1xuICAgICAgICAgICAgY29uc3QgeyBhY2NvdW50TWFuYWdlbWVudEVuZHBvaW50LCBtZXRhZGF0YSwgc2lnbmluZ0tleXMgfSA9IGF3YWl0IGRpc2NvdmVyQW5kVmFsaWRhdGVPSURDSXNzdWVyV2VsbEtub3duKFxuICAgICAgICAgICAgICAgIHRoaXMuYXV0aGVudGljYXRlZElzc3VlcixcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICB0aGlzLnNldEFjY291bnRNYW5hZ2VtZW50RW5kcG9pbnQoYWNjb3VudE1hbmFnZW1lbnRFbmRwb2ludCwgbWV0YWRhdGEuaXNzdWVyKTtcbiAgICAgICAgICAgIHRoaXMub2lkY0NsaWVudCA9IG5ldyBPaWRjQ2xpZW50KHtcbiAgICAgICAgICAgICAgICAuLi5tZXRhZGF0YSxcbiAgICAgICAgICAgICAgICBhdXRob3JpdHk6IG1ldGFkYXRhLmlzc3VlcixcbiAgICAgICAgICAgICAgICBzaWduaW5nS2V5cyxcbiAgICAgICAgICAgICAgICByZWRpcmVjdF91cmk6IFBsYXRmb3JtUGVnLmdldCgpIS5nZXRPaWRjQ2FsbGJhY2tVcmwoKS5ocmVmLFxuICAgICAgICAgICAgICAgIGNsaWVudF9pZDogY2xpZW50SWQsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGxvZ2dlci5lcnJvcihcIkZhaWxlZCB0byBpbml0aWFsaXNlIE9pZGNDbGllbnRTdG9yZVwiLCBlcnJvcik7XG4gICAgICAgIH1cbiAgICB9XG59XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7O0FBUUEsSUFBQUEs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