matrix-react-sdk
Version:
SDK for matrix.org using React
589 lines (580 loc) • 110 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 _matrix = require("matrix-js-sdk/src/matrix");
var _react = _interopRequireWildcard(require("react"));
var _classnames = _interopRequireDefault(require("classnames"));
var _logger = require("matrix-js-sdk/src/logger");
var _languageHandler = require("../../../languageHandler");
var _ErrorUtils = require("../../../utils/ErrorUtils");
var _AutoDiscoveryUtils = _interopRequireDefault(require("../../../utils/AutoDiscoveryUtils"));
var Lifecycle = _interopRequireWildcard(require("../../../Lifecycle"));
var _MatrixClientPeg = require("../../../MatrixClientPeg");
var _AuthPage = _interopRequireDefault(require("../../views/auth/AuthPage"));
var _Login = _interopRequireDefault(require("../../../Login"));
var _dispatcher = _interopRequireDefault(require("../../../dispatcher/dispatcher"));
var _SSOButtons = _interopRequireDefault(require("../../views/elements/SSOButtons"));
var _ServerPicker = _interopRequireDefault(require("../../views/elements/ServerPicker"));
var _RegistrationForm = _interopRequireDefault(require("../../views/auth/RegistrationForm"));
var _AccessibleButton = _interopRequireDefault(require("../../views/elements/AccessibleButton"));
var _AuthBody = _interopRequireDefault(require("../../views/auth/AuthBody"));
var _AuthHeader = _interopRequireDefault(require("../../views/auth/AuthHeader"));
var _InteractiveAuth = _interopRequireDefault(require("../InteractiveAuth"));
var _Spinner = _interopRequireDefault(require("../../views/elements/Spinner"));
var _AuthHeaderDisplay = require("./header/AuthHeaderDisplay");
var _AuthHeaderProvider = require("./header/AuthHeaderProvider");
var _SettingsStore = _interopRequireDefault(require("../../../settings/SettingsStore"));
var _Settings = require("../../../settings/Settings");
var _authorize = require("../../../utils/oidc/authorize");
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
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 2015-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.
*/
const debuglog = (...args) => {
if (_SettingsStore.default.getValue("debug_registration")) {
_logger.logger.log.call(console, "Registration debuglog:", ...args);
}
};
class Registration extends _react.default.Component {
constructor(props) {
super(props);
(0, _defineProperty2.default)(this, "loginLogic", void 0);
// `replaceClient` tracks latest serverConfig to spot when it changes under the async method which fetches flows
(0, _defineProperty2.default)(this, "latestServerConfig", void 0);
// cache value from settings store
(0, _defineProperty2.default)(this, "oidcNativeFlowEnabled", false);
(0, _defineProperty2.default)(this, "unloadCallback", event => {
if (this.state.doingUIAuth) {
event.preventDefault();
event.returnValue = "";
return "";
}
});
(0, _defineProperty2.default)(this, "onFormSubmit", async formVals => {
this.setState({
errorText: "",
busy: true,
formVals,
doingUIAuth: true
});
});
(0, _defineProperty2.default)(this, "requestEmailToken", (emailAddress, clientSecret, sendAttempt, sessionId) => {
if (!this.state.matrixClient) throw new Error("Matrix client has not yet been loaded");
return this.state.matrixClient.requestRegisterEmailToken(emailAddress, clientSecret, sendAttempt);
});
(0, _defineProperty2.default)(this, "onUIAuthFinished", async (success, response) => {
if (!this.state.matrixClient) throw new Error("Matrix client has not yet been loaded");
debuglog("Registration: ui authentication finished: ", {
success,
response
});
if (!success) {
let errorText = response.message || response.toString();
// can we give a better error message?
if (response instanceof _matrix.MatrixError && response.errcode === "M_RESOURCE_LIMIT_EXCEEDED") {
const errorTop = (0, _ErrorUtils.messageForResourceLimitError)(response.data.limit_type, response.data.admin_contact, _ErrorUtils.resourceLimitStrings);
const errorDetail = (0, _ErrorUtils.messageForResourceLimitError)(response.data.limit_type, response.data.admin_contact, _ErrorUtils.adminContactStrings);
errorText = /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("p", null, errorTop), /*#__PURE__*/_react.default.createElement("p", null, errorDetail));
} else if (response.flows?.some(flow => flow.stages.includes(_matrix.AuthType.Msisdn))) {
const flows = response.flows ?? [];
const msisdnAvailable = flows.some(flow => flow.stages.includes(_matrix.AuthType.Msisdn));
if (!msisdnAvailable) {
errorText = (0, _languageHandler._t)("auth|unsupported_auth_msisdn");
}
} else if (response instanceof _matrix.MatrixError && response.errcode === "M_USER_IN_USE") {
errorText = (0, _languageHandler._t)("auth|username_in_use");
} else if (response instanceof _matrix.MatrixError && response.errcode === "M_THREEPID_IN_USE") {
errorText = (0, _languageHandler._t)("auth|3pid_in_use");
}
this.setState({
busy: false,
doingUIAuth: false,
errorText
});
return;
}
const userId = response.user_id;
const accessToken = response.access_token;
if (!userId || !accessToken) throw new Error("Registration failed");
_MatrixClientPeg.MatrixClientPeg.setJustRegisteredUserId(userId);
const newState = {
doingUIAuth: false,
registeredUsername: userId,
differentLoggedInUserId: undefined,
completedNoSignin: false,
// we're still busy until we get unmounted: don't show the registration form again
busy: true
};
// The user came in through an email validation link. To avoid overwriting
// their session, check to make sure the session isn't someone else, and
// isn't a guest user since we'll usually have set a guest user session before
// starting the registration process. This isn't perfect since it's possible
// the user had a separate guest session they didn't actually mean to replace.
const [sessionOwner, sessionIsGuest] = await Lifecycle.getStoredSessionOwner();
if (sessionOwner && !sessionIsGuest && sessionOwner !== userId) {
_logger.logger.log(`Found a session for ${sessionOwner} but ${userId} has just registered.`);
newState.differentLoggedInUserId = sessionOwner;
}
// if we don't have an email at all, only one client can be involved in this flow, and we can directly log in.
//
// if we've got an email, it needs to be verified. in that case, two clients can be involved in this flow, the
// original client starting the process and the client that submitted the verification token. After the token
// has been submitted, it can not be used again.
//
// we can distinguish them based on whether the client has form values saved (if so, it's the one that started
// the registration), or whether it doesn't have any form values saved (in which case it's the client that
// verified the email address)
//
// as the client that started registration may be gone by the time we've verified the email, and only the client
// that verified the email is guaranteed to exist, we'll always do the login in that client.
const hasEmail = Boolean(this.state.formVals.email);
const hasAccessToken = Boolean(accessToken);
debuglog("Registration: ui auth finished:", {
hasEmail,
hasAccessToken
});
// don’t log in if we found a session for a different user
if (hasAccessToken && !newState.differentLoggedInUserId) {
if (this.props.mobileRegister) {
const mobileResponse = {
user_id: userId,
home_server: this.state.matrixClient.getHomeserverUrl(),
access_token: accessToken,
device_id: response.device_id
};
const event = new CustomEvent("mobileregistrationresponse", {
detail: mobileResponse
});
window.dispatchEvent(event);
newState.busy = false;
newState.completedNoSignin = true;
} else {
await this.props.onLoggedIn({
userId,
deviceId: response.device_id,
homeserverUrl: this.state.matrixClient.getHomeserverUrl(),
identityServerUrl: this.state.matrixClient.getIdentityServerUrl(),
accessToken
}, this.state.formVals.password);
this.setupPushers();
}
} else {
newState.busy = false;
newState.completedNoSignin = true;
}
this.setState(newState);
});
(0, _defineProperty2.default)(this, "onLoginClick", ev => {
ev.preventDefault();
ev.stopPropagation();
this.props.onLoginClick();
});
(0, _defineProperty2.default)(this, "onGoToFormClicked", ev => {
ev.preventDefault();
ev.stopPropagation();
this.replaceClient(this.props.serverConfig);
this.setState({
busy: false,
doingUIAuth: false
});
});
(0, _defineProperty2.default)(this, "makeRegisterRequest", auth => {
if (!this.state.matrixClient) throw new Error("Matrix client has not yet been loaded");
const registerParams = {
username: this.state.formVals.username,
password: this.state.formVals.password,
initial_device_display_name: this.props.defaultDeviceDisplayName,
auth: undefined,
// we still want to avoid the race conditions involved with multiple clients handling registration, but
// we'll handle these after we've received the access_token in onUIAuthFinished
inhibit_login: undefined
};
if (auth) registerParams.auth = auth;
debuglog("Registration: sending registration request:", auth);
return this.state.matrixClient.registerRequest(registerParams);
});
// Links to the login page shown after registration is completed are routed through this
// which checks the user hasn't already logged in somewhere else (perhaps we should do
// this more generally?)
(0, _defineProperty2.default)(this, "onLoginClickWithCheck", async ev => {
ev.preventDefault();
const sessionLoaded = await Lifecycle.loadSession({
ignoreGuest: true
});
if (!sessionLoaded) {
// ok fine, there's still no session: really go to the login page
this.props.onLoginClick();
}
return sessionLoaded;
});
this.state = {
busy: false,
errorText: null,
formVals: {
email: this.props.email
},
doingUIAuth: Boolean(this.props.sessionId),
flows: null,
completedNoSignin: false,
serverIsAlive: true,
serverErrorIsFatal: false,
serverDeadError: ""
};
// only set on a config level, so we don't need to watch
this.oidcNativeFlowEnabled = _SettingsStore.default.getValue(_Settings.Features.OidcNativeFlow);
const {
hsUrl,
isUrl,
delegatedAuthentication
} = this.props.serverConfig;
this.loginLogic = new _Login.default(hsUrl, isUrl, null, {
defaultDeviceDisplayName: "Element login check",
// We shouldn't ever be used
// if native OIDC is enabled in the client pass the server's delegated auth settings
delegatedAuthentication: this.oidcNativeFlowEnabled ? delegatedAuthentication : undefined
});
}
componentDidMount() {
this.replaceClient(this.props.serverConfig);
//triggers a confirmation dialog for data loss before page unloads/refreshes
window.addEventListener("beforeunload", this.unloadCallback);
}
componentWillUnmount() {
window.removeEventListener("beforeunload", this.unloadCallback);
}
componentDidUpdate(prevProps) {
if (prevProps.serverConfig.hsUrl !== this.props.serverConfig.hsUrl || prevProps.serverConfig.isUrl !== this.props.serverConfig.isUrl) {
this.replaceClient(this.props.serverConfig);
}
}
async replaceClient(serverConfig) {
this.latestServerConfig = serverConfig;
const {
hsUrl,
isUrl
} = serverConfig;
this.setState({
errorText: null,
serverDeadError: null,
serverErrorIsFatal: false,
// busy while we do live-ness check (we need to avoid trying to render
// the UI auth component while we don't have a matrix client)
busy: true
});
// Do a liveliness check on the URLs
try {
await _AutoDiscoveryUtils.default.validateServerConfigWithStaticUrls(hsUrl, isUrl);
if (serverConfig !== this.latestServerConfig) return; // discard, serverConfig changed from under us
this.setState({
serverIsAlive: true,
serverErrorIsFatal: false
});
} catch (e) {
if (serverConfig !== this.latestServerConfig) return; // discard, serverConfig changed from under us
this.setState(_objectSpread({
busy: false
}, _AutoDiscoveryUtils.default.authComponentStateForError(e, "register")));
if (this.state.serverErrorIsFatal) {
return; // Server is dead - do not continue.
}
}
const cli = (0, _matrix.createClient)({
baseUrl: hsUrl,
idBaseUrl: isUrl
});
this.loginLogic.setHomeserverUrl(hsUrl);
this.loginLogic.setIdentityServerUrl(isUrl);
// if native OIDC is enabled in the client pass the server's delegated auth settings
const delegatedAuthentication = this.oidcNativeFlowEnabled ? serverConfig.delegatedAuthentication : undefined;
this.loginLogic.setDelegatedAuthentication(delegatedAuthentication);
let ssoFlow;
let oidcNativeFlow;
try {
const loginFlows = await this.loginLogic.getFlows(true);
if (serverConfig !== this.latestServerConfig) return; // discard, serverConfig changed from under us
ssoFlow = loginFlows.find(f => f.type === "m.login.sso" || f.type === "m.login.cas");
oidcNativeFlow = loginFlows.find(f => f.type === "oidcNativeFlow");
} catch (e) {
if (serverConfig !== this.latestServerConfig) return; // discard, serverConfig changed from under us
_logger.logger.error("Failed to get login flows to check for SSO support", e);
}
await new Promise(resolve => {
this.setState(({
flows
}) => ({
matrixClient: cli,
ssoFlow,
oidcNativeFlow,
// if we are using oidc native we won't continue with flow discovery on HS
// so set an empty array to indicate flows are no longer loading
flows: oidcNativeFlow ? [] : flows,
busy: false
}), resolve);
});
// don't need to check with homeserver for login flows
// since we are going to use OIDC native flow
if (oidcNativeFlow) {
return;
}
try {
// We do the first registration request ourselves to discover whether we need to
// do SSO instead. If we've already started the UI Auth process though, we don't
// need to.
if (!this.state.doingUIAuth) {
await this.makeRegisterRequest(null);
if (serverConfig !== this.latestServerConfig) return; // discard, serverConfig changed from under us
// This should never succeed since we specified no auth object.
_logger.logger.log("Expecting 401 from register request but got success!");
}
} catch (e) {
if (serverConfig !== this.latestServerConfig) return; // discard, serverConfig changed from under us
if (e instanceof _matrix.MatrixError && e.httpStatus === 401) {
this.setState({
flows: e.data.flows
});
} else if (e instanceof _matrix.MatrixError && (e.httpStatus === 403 || e.errcode === "M_FORBIDDEN")) {
// Check for 403 or M_FORBIDDEN, Synapse used to send 403 M_UNKNOWN but now sends 403 M_FORBIDDEN.
// At this point registration is pretty much disabled, but before we do that let's
// quickly check to see if the server supports SSO instead. If it does, we'll send
// the user off to the login page to figure their account out.
if (ssoFlow) {
// Redirect to login page - server probably expects SSO only
_dispatcher.default.dispatch({
action: "start_login"
});
} else {
this.setState({
serverErrorIsFatal: true,
// fatal because user cannot continue on this server
errorText: (0, _languageHandler._t)("auth|registration_disabled"),
// add empty flows array to get rid of spinner
flows: []
});
}
} else {
_logger.logger.log("Unable to query for supported registration methods.", e);
this.setState({
errorText: (0, _languageHandler._t)("auth|failed_query_registration_methods"),
// add empty flows array to get rid of spinner
flows: []
});
}
}
}
setupPushers() {
if (!this.props.brand) {
return Promise.resolve();
}
const matrixClient = _MatrixClientPeg.MatrixClientPeg.safeGet();
return matrixClient.getPushers().then(resp => {
const pushers = resp.pushers;
for (let i = 0; i < pushers.length; ++i) {
if (pushers[i].kind === "email") {
const emailPusher = pushers[i];
emailPusher.data = {
brand: this.props.brand
};
matrixClient.setPusher(emailPusher).then(() => {
_logger.logger.log("Set email branding to " + this.props.brand);
}, error => {
_logger.logger.error("Couldn't set email branding: " + error);
});
}
}
}, error => {
_logger.logger.error("Couldn't get pushers: " + error);
});
}
getUIAuthInputs() {
return {
emailAddress: this.state.formVals.email,
phoneCountry: this.state.formVals.phoneCountry,
phoneNumber: this.state.formVals.phoneNumber
};
}
renderRegisterComponent() {
if (this.state.matrixClient && this.state.doingUIAuth) {
return /*#__PURE__*/_react.default.createElement(_InteractiveAuth.default, {
matrixClient: this.state.matrixClient,
makeRequest: this.makeRegisterRequest,
onAuthFinished: this.onUIAuthFinished,
inputs: this.getUIAuthInputs(),
requestEmailToken: this.requestEmailToken,
sessionId: this.props.sessionId,
clientSecret: this.props.clientSecret,
emailSid: this.props.idSid,
poll: true
});
} else if (!this.state.matrixClient && !this.state.busy) {
return null;
} else if (this.state.busy || !this.state.flows) {
return /*#__PURE__*/_react.default.createElement("div", {
className: "mx_AuthBody_spinner"
}, /*#__PURE__*/_react.default.createElement(_Spinner.default, null));
} else if (this.state.matrixClient && this.state.oidcNativeFlow) {
return /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, {
className: "mx_Login_fullWidthButton",
kind: "primary",
onClick: async () => {
await (0, _authorize.startOidcLogin)(this.props.serverConfig.delegatedAuthentication, this.state.oidcNativeFlow.clientId, this.props.serverConfig.hsUrl, this.props.serverConfig.isUrl, true /* isRegistration */);
}
}, (0, _languageHandler._t)("action|continue"));
} else if (this.state.matrixClient && this.state.flows.length) {
let ssoSection;
if (!this.props.mobileRegister && this.state.ssoFlow) {
let continueWithSection;
const providers = this.state.ssoFlow.identity_providers || [];
// when there is only a single (or 0) providers we show a wide button with `Continue with X` text
if (providers.length > 1) {
// i18n: ssoButtons is a placeholder to help translators understand context
continueWithSection = /*#__PURE__*/_react.default.createElement("h2", {
className: "mx_AuthBody_centered"
}, (0, _languageHandler._t)("auth|continue_with_sso", {
ssoButtons: ""
}).trim());
}
// i18n: ssoButtons & usernamePassword are placeholders to help translators understand context
ssoSection = /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, continueWithSection, /*#__PURE__*/_react.default.createElement(_SSOButtons.default, {
matrixClient: this.loginLogic.createTemporaryClient(),
flow: this.state.ssoFlow,
loginType: this.state.ssoFlow.type === "m.login.sso" ? "sso" : "cas",
fragmentAfterLogin: this.props.fragmentAfterLogin,
action: _matrix.SSOAction.REGISTER
}), /*#__PURE__*/_react.default.createElement("h2", {
className: "mx_AuthBody_centered"
}, (0, _languageHandler._t)("auth|sso_or_username_password", {
ssoButtons: "",
usernamePassword: ""
}).trim()));
}
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, ssoSection, /*#__PURE__*/_react.default.createElement(_RegistrationForm.default, {
defaultUsername: this.state.formVals.username,
defaultEmail: this.state.formVals.email,
defaultPhoneCountry: this.state.formVals.phoneCountry,
defaultPhoneNumber: this.state.formVals.phoneNumber,
defaultPassword: this.state.formVals.password,
onRegisterClick: this.onFormSubmit,
flows: this.state.flows,
serverConfig: this.props.serverConfig,
canSubmit: !this.state.serverErrorIsFatal,
matrixClient: this.state.matrixClient,
mobileRegister: this.props.mobileRegister
}));
}
return null;
}
render() {
let errorText;
const err = this.state.errorText;
if (err) {
errorText = /*#__PURE__*/_react.default.createElement("div", {
className: "mx_Login_error"
}, err);
}
let serverDeadSection;
if (!this.state.serverIsAlive) {
const classes = (0, _classnames.default)({
mx_Login_error: true,
mx_Login_serverError: true,
mx_Login_serverErrorNonFatal: !this.state.serverErrorIsFatal
});
serverDeadSection = /*#__PURE__*/_react.default.createElement("div", {
className: classes
}, this.state.serverDeadError);
}
const signIn = /*#__PURE__*/_react.default.createElement("span", {
className: "mx_AuthBody_changeFlow"
}, (0, _languageHandler._t)("auth|sign_in_instead_prompt", {}, {
a: sub => /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, {
kind: "link_inline",
onClick: this.onLoginClick
}, sub)
}));
// Only show the 'go back' button if you're not looking at the form
let goBack;
if (this.state.doingUIAuth) {
goBack = /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, {
kind: "link",
className: "mx_AuthBody_changeFlow",
onClick: this.onGoToFormClicked
}, (0, _languageHandler._t)("action|go_back"));
}
let body;
if (this.state.completedNoSignin) {
let regDoneText;
if (this.props.mobileRegister) {
regDoneText = undefined;
} else if (this.state.differentLoggedInUserId) {
regDoneText = /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("p", null, (0, _languageHandler._t)("auth|account_clash", {
newAccountId: this.state.registeredUsername,
loggedInUserId: this.state.differentLoggedInUserId
})), /*#__PURE__*/_react.default.createElement("p", null, /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, {
kind: "link_inline",
onClick: async event => {
const sessionLoaded = await this.onLoginClickWithCheck(event);
if (sessionLoaded) {
_dispatcher.default.dispatch({
action: "view_welcome_page"
});
}
}
}, (0, _languageHandler._t)("auth|account_clash_previous_account"))));
} else {
// regardless of whether we're the client that started the registration or not, we should
// try our credentials anyway
regDoneText = /*#__PURE__*/_react.default.createElement("h2", null, (0, _languageHandler._t)("auth|log_in_new_account", {}, {
a: sub => /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, {
kind: "link_inline",
onClick: async event => {
const sessionLoaded = await this.onLoginClickWithCheck(event);
if (sessionLoaded) {
_dispatcher.default.dispatch({
action: "view_home_page"
});
}
}
}, sub)
}));
}
body = /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("h1", null, (0, _languageHandler._t)("auth|registration_successful")), regDoneText);
} else if (this.props.mobileRegister) {
body = /*#__PURE__*/_react.default.createElement(_react.Fragment, null, /*#__PURE__*/_react.default.createElement("h1", null, (0, _languageHandler._t)("auth|mobile_create_account_title", {
hsName: this.props.serverConfig.hsName
})), errorText, serverDeadSection, this.renderRegisterComponent());
} else {
body = /*#__PURE__*/_react.default.createElement(_react.Fragment, null, /*#__PURE__*/_react.default.createElement("div", {
className: "mx_Register_mainContent"
}, /*#__PURE__*/_react.default.createElement(_AuthHeaderDisplay.AuthHeaderDisplay, {
title: (0, _languageHandler._t)("auth|create_account_title"),
serverPicker: /*#__PURE__*/_react.default.createElement(_ServerPicker.default, {
title: (0, _languageHandler._t)("auth|server_picker_title_registration"),
dialogTitle: (0, _languageHandler._t)("auth|server_picker_dialog_title"),
serverConfig: this.props.serverConfig,
onServerConfigChange: this.state.doingUIAuth ? undefined : this.props.onServerConfigChange
})
}, errorText, serverDeadSection), this.renderRegisterComponent()), /*#__PURE__*/_react.default.createElement("div", {
className: "mx_Register_footerActions"
}, goBack, signIn));
}
if (this.props.mobileRegister) {
return /*#__PURE__*/_react.default.createElement("div", {
className: "mx_MobileRegister_body",
"data-testid": "mobile-register"
}, body);
}
return /*#__PURE__*/_react.default.createElement(_AuthPage.default, null, /*#__PURE__*/_react.default.createElement(_AuthHeader.default, null), /*#__PURE__*/_react.default.createElement(_AuthHeaderProvider.AuthHeaderProvider, null, /*#__PURE__*/_react.default.createElement(_AuthBody.default, {
flex: true
}, body)));
}
}
exports.default = Registration;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfbWF0cml4IiwicmVxdWlyZSIsIl9yZWFjdCIsIl9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkIiwiX2NsYXNzbmFtZXMiLCJfaW50ZXJvcFJlcXVpcmVEZWZhdWx0IiwiX2xvZ2dlciIsIl9sYW5ndWFnZUhhbmRsZXIiLCJfRXJyb3JVdGlscyIsIl9BdXRvRGlzY292ZXJ5VXRpbHMiLCJMaWZlY3ljbGUiLCJfTWF0cml4Q2xpZW50UGVnIiwiX0F1dGhQYWdlIiwiX0xvZ2luIiwiX2Rpc3BhdGNoZXIiLCJfU1NPQnV0dG9ucyIsIl9TZXJ2ZXJQaWNrZXIiLCJfUmVnaXN0cmF0aW9uRm9ybSIsIl9BY2Nlc3NpYmxlQnV0dG9uIiwiX0F1dGhCb2R5IiwiX0F1dGhIZWFkZXIiLCJfSW50ZXJhY3RpdmVBdXRoIiwiX1NwaW5uZXIiLCJfQXV0aEhlYWRlckRpc3BsYXkiLCJfQXV0aEhlYWRlclByb3ZpZGVyIiwiX1NldHRpbmdzU3RvcmUiLCJfU2V0dGluZ3MiLCJfYXV0aG9yaXplIiwiX2dldFJlcXVpcmVXaWxkY2FyZENhY2hlIiwiZSIsIldlYWtNYXAiLCJyIiwidCIsIl9fZXNNb2R1bGUiLCJkZWZhdWx0IiwiaGFzIiwiZ2V0IiwibiIsIl9fcHJvdG9fXyIsImEiLCJPYmplY3QiLCJkZWZpbmVQcm9wZXJ0eSIsImdldE93blByb3BlcnR5RGVzY3JpcHRvciIsInUiLCJoYXNPd25Qcm9wZXJ0eSIsImNhbGwiLCJpIiwic2V0Iiwib3duS2V5cyIsImtleXMiLCJnZXRPd25Qcm9wZXJ0eVN5bWJvbHMiLCJvIiwiZmlsdGVyIiwiZW51bWVyYWJsZSIsInB1c2giLCJhcHBseSIsIl9vYmplY3RTcHJlYWQiLCJhcmd1bWVudHMiLCJsZW5ndGgiLCJmb3JFYWNoIiwiX2RlZmluZVByb3BlcnR5MiIsImdldE93blByb3BlcnR5RGVzY3JpcHRvcnMiLCJkZWZpbmVQcm9wZXJ0aWVzIiwiZGVidWdsb2ciLCJhcmdzIiwiU2V0dGluZ3NTdG9yZSIsImdldFZhbHVlIiwibG9nZ2VyIiwibG9nIiwiY29uc29sZSIsIlJlZ2lzdHJhdGlvbiIsIlJlYWN0IiwiQ29tcG9uZW50IiwiY29uc3RydWN0b3IiLCJwcm9wcyIsImV2ZW50Iiwic3RhdGUiLCJkb2luZ1VJQXV0aCIsInByZXZlbnREZWZhdWx0IiwicmV0dXJuVmFsdWUiLCJmb3JtVmFscyIsInNldFN0YXRlIiwiZXJyb3JUZXh0IiwiYnVzeSIsImVtYWlsQWRkcmVzcyIsImNsaWVudFNlY3JldCIsInNlbmRBdHRlbXB0Iiwic2Vzc2lvbklkIiwibWF0cml4Q2xpZW50IiwiRXJyb3IiLCJyZXF1ZXN0UmVnaXN0ZXJFbWFpbFRva2VuIiwic3VjY2VzcyIsInJlc3BvbnNlIiwibWVzc2FnZSIsInRvU3RyaW5nIiwiTWF0cml4RXJyb3IiLCJlcnJjb2RlIiwiZXJyb3JUb3AiLCJtZXNzYWdlRm9yUmVzb3VyY2VMaW1pdEVycm9yIiwiZGF0YSIsImxpbWl0X3R5cGUiLCJhZG1pbl9jb250YWN0IiwicmVzb3VyY2VMaW1pdFN0cmluZ3MiLCJlcnJvckRldGFpbCIsImFkbWluQ29udGFjdFN0cmluZ3MiLCJjcmVhdGVFbGVtZW50IiwiZmxvd3MiLCJzb21lIiwiZmxvdyIsInN0YWdlcyIsImluY2x1ZGVzIiwiQXV0aFR5cGUiLCJNc2lzZG4iLCJtc2lzZG5BdmFpbGFibGUiLCJfdCIsInVzZXJJZCIsInVzZXJfaWQiLCJhY2Nlc3NUb2tlbiIsImFjY2Vzc190b2tlbiIsIk1hdHJpeENsaWVudFBlZyIsInNldEp1c3RSZWdpc3RlcmVkVXNlcklkIiwibmV3U3RhdGUiLCJyZWdpc3RlcmVkVXNlcm5hbWUiLCJkaWZmZXJlbnRMb2dnZWRJblVzZXJJZCIsInVuZGVmaW5lZCIsImNvbXBsZXRlZE5vU2lnbmluIiwic2Vzc2lvbk93bmVyIiwic2Vzc2lvbklzR3Vlc3QiLCJnZXRTdG9yZWRTZXNzaW9uT3duZXIiLCJoYXNFbWFpbCIsIkJvb2xlYW4iLCJlbWFpbCIsImhhc0FjY2Vzc1Rva2VuIiwibW9iaWxlUmVnaXN0ZXIiLCJtb2JpbGVSZXNwb25zZSIsImhvbWVfc2VydmVyIiwiZ2V0SG9tZXNlcnZlclVybCIsImRldmljZV9pZCIsIkN1c3RvbUV2ZW50IiwiZGV0YWlsIiwid2luZG93IiwiZGlzcGF0Y2hFdmVudCIsIm9uTG9nZ2VkSW4iLCJkZXZpY2VJZCIsImhvbWVzZXJ2ZXJVcmwiLCJpZGVudGl0eVNlcnZlclVybCIsImdldElkZW50aXR5U2VydmVyVXJsIiwicGFzc3dvcmQiLCJzZXR1cFB1c2hlcnMiLCJldiIsInN0b3BQcm9wYWdhdGlvbiIsIm9uTG9naW5DbGljayIsInJlcGxhY2VDbGllbnQiLCJzZXJ2ZXJDb25maWciLCJhdXRoIiwicmVnaXN0ZXJQYXJhbXMiLCJ1c2VybmFtZSIsImluaXRpYWxfZGV2aWNlX2Rpc3BsYXlfbmFtZSIsImRlZmF1bHREZXZpY2VEaXNwbGF5TmFtZSIsImluaGliaXRfbG9naW4iLCJyZWdpc3RlclJlcXVlc3QiLCJzZXNzaW9uTG9hZGVkIiwibG9hZFNlc3Npb24iLCJpZ25vcmVHdWVzdCIsInNlcnZlcklzQWxpdmUiLCJzZXJ2ZXJFcnJvcklzRmF0YWwiLCJzZXJ2ZXJEZWFkRXJyb3IiLCJvaWRjTmF0aXZlRmxvd0VuYWJsZWQiLCJGZWF0dXJlcyIsIk9pZGNOYXRpdmVGbG93IiwiaHNVcmwiLCJpc1VybCIsImRlbGVnYXRlZEF1dGhlbnRpY2F0aW9uIiwibG9naW5Mb2dpYyIsIkxvZ2luIiwiY29tcG9uZW50RGlkTW91bnQiLCJhZGRFdmVudExpc3RlbmVyIiwidW5sb2FkQ2FsbGJhY2siLCJjb21wb25lbnRXaWxsVW5tb3VudCIsInJlbW92ZUV2ZW50TGlzdGVuZXIiLCJjb21wb25lbnREaWRVcGRhdGUiLCJwcmV2UHJvcHMiLCJsYXRlc3RTZXJ2ZXJDb25maWciLCJBdXRvRGlzY292ZXJ5VXRpbHMiLCJ2YWxpZGF0ZVNlcnZlckNvbmZpZ1dpdGhTdGF0aWNVcmxzIiwiYXV0aENvbXBvbmVudFN0YXRlRm9yRXJyb3IiLCJjbGkiLCJjcmVhdGVDbGllbnQiLCJiYXNlVXJsIiwiaWRCYXNlVXJsIiwic2V0SG9tZXNlcnZlclVybCIsInNldElkZW50aXR5U2VydmVyVXJsIiwic2V0RGVsZWdhdGVkQXV0aGVudGljYXRpb24iLCJzc29GbG93Iiwib2lkY05hdGl2ZUZsb3ciLCJsb2dpbkZsb3dzIiwiZ2V0Rmxvd3MiLCJmaW5kIiwiZiIsInR5cGUiLCJlcnJvciIsIlByb21pc2UiLCJyZXNvbHZlIiwibWFrZVJlZ2lzdGVyUmVxdWVzdCIsImh0dHBTdGF0dXMiLCJkaXMiLCJkaXNwYXRjaCIsImFjdGlvbiIsImJyYW5kIiwic2FmZUdldCIsImdldFB1c2hlcnMiLCJ0aGVuIiwicmVzcCIsInB1c2hlcnMiLCJraW5kIiwiZW1haWxQdXNoZXIiLCJzZXRQdXNoZXIiLCJnZXRVSUF1dGhJbnB1dHMiLCJwaG9uZUNvdW50cnkiLCJwaG9uZU51bWJlciIsInJlbmRlclJlZ2lzdGVyQ29tcG9uZW50IiwibWFrZVJlcXVlc3QiLCJvbkF1dGhGaW5pc2hlZCIsIm9uVUlBdXRoRmluaXNoZWQiLCJpbnB1dHMiLCJyZXF1ZXN0RW1haWxUb2tlbiIsImVtYWlsU2lkIiwiaWRTaWQiLCJwb2xsIiwiY2xhc3NOYW1lIiwib25DbGljayIsInN0YXJ0T2lkY0xvZ2luIiwiY2xpZW50SWQiLCJzc29TZWN0aW9uIiwiY29udGludWVXaXRoU2VjdGlvbiIsInByb3ZpZGVycyIsImlkZW50aXR5X3Byb3ZpZGVycyIsInNzb0J1dHRvbnMiLCJ0cmltIiwiRnJhZ21lbnQiLCJjcmVhdGVUZW1wb3JhcnlDbGllbnQiLCJsb2dpblR5cGUiLCJmcmFnbWVudEFmdGVyTG9naW4iLCJTU09BY3Rpb24iLCJSRUdJU1RFUiIsInVzZXJuYW1lUGFzc3dvcmQiLCJkZWZhdWx0VXNlcm5hbWUiLCJkZWZhdWx0RW1haWwiLCJkZWZhdWx0UGhvbmVDb3VudHJ5IiwiZGVmYXVsdFBob25lTnVtYmVyIiwiZGVmYXVsdFBhc3N3b3JkIiwib25SZWdpc3RlckNsaWNrIiwib25Gb3JtU3VibWl0IiwiY2FuU3VibWl0IiwicmVuZGVyIiwiZXJyIiwic2VydmVyRGVhZFNlY3Rpb24iLCJjbGFzc2VzIiwiY2xhc3NOYW1lcyIsIm14X0xvZ2luX2Vycm9yIiwibXhfTG9naW5fc2VydmVyRXJyb3IiLCJteF9Mb2dpbl9zZXJ2ZXJFcnJvck5vbkZhdGFsIiwic2lnbkluIiwic3ViIiwiZ29CYWNrIiwib25Hb1RvRm9ybUNsaWNrZWQiLCJib2R5IiwicmVnRG9uZVRleHQiLCJuZXdBY2NvdW50SWQiLCJsb2dnZWRJblVzZXJJZCIsIm9uTG9naW5DbGlja1dpdGhDaGVjayIsImhzTmFtZSIsIkF1dGhIZWFkZXJEaXNwbGF5IiwidGl0bGUiLCJzZXJ2ZXJQaWNrZXIiLCJkaWFsb2dUaXRsZSIsIm9uU2VydmVyQ29uZmlnQ2hhbmdlIiwiQXV0aEhlYWRlclByb3ZpZGVyIiwiZmxleCIsImV4cG9ydHMiXSwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29tcG9uZW50cy9zdHJ1Y3R1cmVzL2F1dGgvUmVnaXN0cmF0aW9uLnRzeCJdLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuQ29weXJpZ2h0IDIwMjQgTmV3IFZlY3RvciBMdGQuXG5Db3B5cmlnaHQgMjAxNS0yMDIxIFRoZSBNYXRyaXgub3JnIEZvdW5kYXRpb24gQy5JLkMuXG5cblNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBR1BMLTMuMC1vbmx5IE9SIEdQTC0zLjAtb25seVxuUGxlYXNlIHNlZSBMSUNFTlNFIGZpbGVzIGluIHRoZSByZXBvc2l0b3J5IHJvb3QgZm9yIGZ1bGwgZGV0YWlscy5cbiovXG5cbmltcG9ydCB7XG4gICAgQXV0aFR5cGUsXG4gICAgY3JlYXRlQ2xpZW50LFxuICAgIElBdXRoRGF0YSxcbiAgICBBdXRoRGljdCxcbiAgICBJSW5wdXRzLFxuICAgIE1hdHJpeEVycm9yLFxuICAgIElSZWdpc3RlclJlcXVlc3RQYXJhbXMsXG4gICAgSVJlcXVlc3RUb2tlblJlc3BvbnNlLFxuICAgIE1hdHJpeENsaWVudCxcbiAgICBTU09GbG93LFxuICAgIFNTT0FjdGlvbixcbiAgICBSZWdpc3RlclJlc3BvbnNlLFxufSBmcm9tIFwibWF0cml4LWpzLXNkay9zcmMvbWF0cml4XCI7XG5pbXBvcnQgUmVhY3QsIHsgRnJhZ21lbnQsIFJlYWN0Tm9kZSB9IGZyb20gXCJyZWFjdFwiO1xuaW1wb3J0IGNsYXNzTmFtZXMgZnJvbSBcImNsYXNzbmFtZXNcIjtcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gXCJtYXRyaXgtanMtc2RrL3NyYy9sb2dnZXJcIjtcblxuaW1wb3J0IHsgX3QgfSBmcm9tIFwiLi4vLi4vLi4vbGFuZ3VhZ2VIYW5kbGVyXCI7XG5pbXBvcnQgeyBhZG1pbkNvbnRhY3RTdHJpbmdzLCBtZXNzYWdlRm9yUmVzb3VyY2VMaW1pdEVycm9yLCByZXNvdXJjZUxpbWl0U3RyaW5ncyB9IGZyb20gXCIuLi8uLi8uLi91dGlscy9FcnJvclV0aWxzXCI7XG5pbXBvcnQgQXV0b0Rpc2NvdmVyeVV0aWxzIGZyb20gXCIuLi8uLi8uLi91dGlscy9BdXRvRGlzY292ZXJ5VXRpbHNcIjtcbmltcG9ydCAqIGFzIExpZmVjeWNsZSBmcm9tIFwiLi4vLi4vLi4vTGlmZWN5Y2xlXCI7XG5pbXBvcnQgeyBJTWF0cml4Q2xpZW50Q3JlZHMsIE1hdHJpeENsaWVudFBlZyB9IGZyb20gXCIuLi8uLi8uLi9NYXRyaXhDbGllbnRQZWdcIjtcbmltcG9ydCBBdXRoUGFnZSBmcm9tIFwiLi4vLi4vdmlld3MvYXV0aC9BdXRoUGFnZVwiO1xuaW1wb3J0IExvZ2luLCB7IE9pZGNOYXRpdmVGbG93IH0gZnJvbSBcIi4uLy4uLy4uL0xvZ2luXCI7XG5pbXBvcnQgZGlzIGZyb20gXCIuLi8uLi8uLi9kaXNwYXRjaGVyL2Rpc3BhdGNoZXJcIjtcbmltcG9ydCBTU09CdXR0b25zIGZyb20gXCIuLi8uLi92aWV3cy9lbGVtZW50cy9TU09CdXR0b25zXCI7XG5pbXBvcnQgU2VydmVyUGlja2VyIGZyb20gXCIuLi8uLi92aWV3cy9lbGVtZW50cy9TZXJ2ZXJQaWNrZXJcIjtcbmltcG9ydCBSZWdpc3RyYXRpb25Gb3JtIGZyb20gXCIuLi8uLi92aWV3cy9hdXRoL1JlZ2lzdHJhdGlvbkZvcm1cIjtcbmltcG9ydCBBY2Nlc3NpYmxlQnV0dG9uLCB7IEJ1dHRvbkV2ZW50IH0gZnJvbSBcIi4uLy4uL3ZpZXdzL2VsZW1lbnRzL0FjY2Vzc2libGVCdXR0b25cIjtcbmltcG9ydCBBdXRoQm9keSBmcm9tIFwiLi4vLi4vdmlld3MvYXV0aC9BdXRoQm9keVwiO1xuaW1wb3J0IEF1dGhIZWFkZXIgZnJvbSBcIi4uLy4uL3ZpZXdzL2F1dGgvQXV0aEhlYWRlclwiO1xuaW1wb3J0IEludGVyYWN0aXZlQXV0aCwgeyBJbnRlcmFjdGl2ZUF1dGhDYWxsYmFjayB9IGZyb20gXCIuLi9JbnRlcmFjdGl2ZUF1dGhcIjtcbmltcG9ydCBTcGlubmVyIGZyb20gXCIuLi8uLi92aWV3cy9lbGVtZW50cy9TcGlubmVyXCI7XG5pbXBvcnQgeyBBdXRoSGVhZGVyRGlzcGxheSB9IGZyb20gXCIuL2hlYWRlci9BdXRoSGVhZGVyRGlzcGxheVwiO1xuaW1wb3J0IHsgQXV0aEhlYWRlclByb3ZpZGVyIH0gZnJvbSBcIi4vaGVhZGVyL0F1dGhIZWFkZXJQcm92aWRlclwiO1xuaW1wb3J0IFNldHRpbmdzU3RvcmUgZnJvbSBcIi4uLy4uLy4uL3NldHRpbmdzL1NldHRpbmdzU3RvcmVcIjtcbmltcG9ydCB7IFZhbGlkYXRlZFNlcnZlckNvbmZpZyB9IGZyb20gXCIuLi8uLi8uLi91dGlscy9WYWxpZGF0ZWRTZXJ2ZXJDb25maWdcIjtcbmltcG9ydCB7IEZlYXR1cmVzIH0gZnJvbSBcIi4uLy4uLy4uL3NldHRpbmdzL1NldHRpbmdzXCI7XG5pbXBvcnQgeyBzdGFydE9pZGNMb2dpbiB9IGZyb20gXCIuLi8uLi8uLi91dGlscy9vaWRjL2F1dGhvcml6ZVwiO1xuXG5jb25zdCBkZWJ1Z2xvZyA9ICguLi5hcmdzOiBhbnlbXSk6IHZvaWQgPT4ge1xuICAgIGlmIChTZXR0aW5nc1N0b3JlLmdldFZhbHVlKFwiZGVidWdfcmVnaXN0cmF0aW9uXCIpKSB7XG4gICAgICAgIGxvZ2dlci5sb2cuY2FsbChjb25zb2xlLCBcIlJlZ2lzdHJhdGlvbiBkZWJ1Z2xvZzpcIiwgLi4uYXJncyk7XG4gICAgfVxufTtcblxuZXhwb3J0IGludGVyZmFjZSBNb2JpbGVSZWdpc3RyYXRpb25SZXNwb25zZSB7XG4gICAgdXNlcl9pZDogc3RyaW5nO1xuICAgIGhvbWVfc2VydmVyOiBzdHJpbmc7XG4gICAgYWNjZXNzX3Rva2VuOiBzdHJpbmc7XG4gICAgZGV2aWNlX2lkOiBzdHJpbmc7XG59XG5cbmludGVyZmFjZSBJUHJvcHMge1xuICAgIHNlcnZlckNvbmZpZzogVmFsaWRhdGVkU2VydmVyQ29uZmlnO1xuICAgIGRlZmF1bHREZXZpY2VEaXNwbGF5TmFtZT86IHN0cmluZztcbiAgICBlbWFpbD86IHN0cmluZztcbiAgICBicmFuZD86IHN0cmluZztcbiAgICBjbGllbnRTZWNyZXQ/OiBzdHJpbmc7XG4gICAgc2Vzc2lvbklkPzogc3RyaW5nO1xuICAgIGlkU2lkPzogc3RyaW5nO1xuICAgIGZyYWdtZW50QWZ0ZXJMb2dpbj86IHN0cmluZztcbiAgICBtb2JpbGVSZWdpc3Rlcj86IGJvb2xlYW47XG4gICAgLy8gQ2FsbGVkIHdoZW4gdGhlIHVzZXIgaGFzIGxvZ2dlZCBpbi4gUGFyYW1zOlxuICAgIC8vIC0gb2JqZWN0IHdpdGggdXNlcklkLCBkZXZpY2VJZCwgaG9tZXNlcnZlclVybCwgaWRlbnRpdHlTZXJ2ZXJVcmwsIGFjY2Vzc1Rva2VuXG4gICAgLy8gLSBUaGUgdXNlcidzIHBhc3N3b3JkLCBpZiBhdmFpbGFibGUgYW5kIGFwcGxpY2FibGUgKG1heSBiZSBjYWNoZWQgaW4gbWVtb3J5XG4gICAgLy8gICBmb3IgYSBzaG9ydCB0aW1lIHNvIHRoZSB1c2VyIGlzIG5vdCByZXF1aXJlZCB0byByZS1lbnRlciB0aGVpciBwYXNzd29yZFxuICAgIC8vICAgZm9yIG9wZXJhdGlvbnMgbGlrZSB1cGxvYWRpbmcgY3Jvc3Mtc2lnbmluZyBrZXlzKS5cbiAgICBvbkxvZ2dlZEluKHBhcmFtczogSU1hdHJpeENsaWVudENyZWRzLCBwYXNzd29yZDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPjtcbiAgICAvLyByZWdpc3RyYXRpb24gc2hvdWxkbid0IGtub3cgb3IgY2FyZSBob3cgbG9naW4gaXMgZG9uZS5cbiAgICBvbkxvZ2luQ2xpY2soKTogdm9pZDtcbiAgICBvblNlcnZlckNvbmZpZ0NoYW5nZShjb25maWc6IFZhbGlkYXRlZFNlcnZlckNvbmZpZyk6IHZvaWQ7XG59XG5cbmludGVyZmFjZSBJU3RhdGUge1xuICAgIC8vIHRydWUgaWYgd2UncmUgd2FpdGluZyBmb3IgdGhlIHVzZXIgdG8gY29tcGxldGVcbiAgICBidXN5OiBib29sZWFuO1xuICAgIGVycm9yVGV4dD86IFJlYWN0Tm9kZTtcbiAgICAvLyBXZSByZW1lbWJlciB0aGUgdmFsdWVzIGVudGVyZWQgYnkgdGhlIHVzZXIgYmVjYXVzZVxuICAgIC8vIHRoZSByZWdpc3RyYXRpb24gZm9ybSB3aWxsIGJlIHVubW91bnRlZCBkdXJpbmcgdGhlXG4gICAgLy8gY291cnNlIG9mIHJlZ2lzdHJhdGlvbiwgYnV0IGlmIHRoZXJlJ3MgYW4gZXJyb3Igd2VcbiAgICAvLyB3YW50IHRvIGJyaW5nIGJhY2sgdGhlIHJlZ2lzdHJhdGlvbiBmb3JtIHdpdGggdGhlXG4gICAgLy8gdmFsdWVzIHRoZSB1c2VyIGVudGVyZWQgc3RpbGwgaW4gaXQuIFdlIGNhbiBrZWVwXG4gICAgLy8gdGhlbSBpbiB0aGlzIGNvbXBvbmVudCdzIHN0YXRlIHNpbmNlIHRoaXMgY29tcG9uZW50XG4gICAgLy8gcGVyc2lzdCBmb3IgdGhlIGR1cmF0aW9uIG9mIHRoZSByZWdpc3RyYXRpb24gcHJvY2Vzcy5cbiAgICBmb3JtVmFsczogUmVjb3JkPHN0cmluZywgc3RyaW5nIHwgdW5kZWZpbmVkPjtcbiAgICAvLyB1c2VyLWludGVyYWN0aXZlIGF1dGhcbiAgICAvLyBJZiB3ZSd2ZSBiZWVuIGdpdmVuIGEgc2Vzc2lvbiBJRCwgd2UncmUgcmVzdW1pbmdcbiAgICAvLyBzdHJhaWdodCBiYWNrIGludG8gVUkgYXV0aFxuICAgIGRvaW5nVUlBdXRoOiBib29sZWFuO1xuICAgIC8vIElmIHNldCwgd2UndmUgcmVnaXN0ZXJlZCBidXQgYXJlIG5vdCBnb2luZyB0byBsb2dcbiAgICAvLyB0aGUgdXNlciBpbiB0byB0aGVpciBuZXcgYWNjb3VudCBhdXRvbWF0aWNhbGx5LlxuICAgIGNvbXBsZXRlZE5vU2lnbmluOiBib29sZWFuO1xuICAgIGZsb3dzOlxuICAgICAgICB8IHtcbiAgICAgICAgICAgICAgc3RhZ2VzOiBzdHJpbmdbXTtcbiAgICAgICAgICB9W11cbiAgICAgICAgfCBudWxsO1xuICAgIC8vIFdlIHBlcmZvcm0gbGl2ZWxpbmVzcyBjaGVja3MgbGF0ZXIsIGJ1dCBmb3Igbm93IHN1cHByZXNzIHRoZSBlcnJvcnMuXG4gICAgLy8gV2UgYWxzbyB0cmFjayB0aGUgc2VydmVyIGRlYWQgZXJyb3JzIGluZGVwZW5kZW50bHkgb2YgdGhlIHJlZ3VsYXIgZXJyb3JzIHNvXG4gICAgLy8gdGhhdCB3ZSBjYW4gcmVuZGVyIGl0IGRpZmZlcmVudGx5LCBhbmQgb3ZlcnJpZGUgYW55IG90aGVyIGVycm9yIHRoZSB1c2VyIG1heVxuICAgIC8vIGJlIHNlZWluZy5cbiAgICBzZXJ2ZXJJc0FsaXZlOiBib29sZWFuO1xuICAgIHNlcnZlckVycm9ySXNGYXRhbDogYm9vbGVhbjtcbiAgICBzZXJ2ZXJEZWFkRXJyb3I/OiBSZWFjdE5vZGU7XG5cbiAgICAvLyBPdXIgbWF0cml4IGNsaWVudCAtIHBhcnQgb2Ygc3RhdGUgYmVjYXVzZSB3ZSBjYW4ndCByZW5kZXIgdGhlIFVJIGF1dGhcbiAgICAvLyBjb21wb25lbnQgd2l0aG91dCBpdC5cbiAgICBtYXRyaXhDbGllbnQ/OiBNYXRyaXhDbGllbnQ7XG4gICAgLy8gVGhlIHVzZXIgSUQgd2UndmUganVzdCByZWdpc3RlcmVkXG4gICAgcmVnaXN0ZXJlZFVzZXJuYW1lPzogc3RyaW5nO1xuICAgIC8vIGlmIGEgZGlmZmVyZW50IHVzZXIgSUQgdG8gdGhlIG9uZSB3ZSBqdXN0IHJlZ2lzdGVyZWQgaXMgbG9nZ2VkIGluLFxuICAgIC8vIHRoaXMgaXMgdGhlIHVzZXIgSUQgdGhhdCdzIGxvZ2dlZCBpbi5cbiAgICBkaWZmZXJlbnRMb2dnZWRJblVzZXJJZD86IHN0cmluZztcbiAgICAvLyB0aGUgU1NPIGZsb3cgZGVmaW5pdGlvbiwgdGhpcyBpcyBmZXRjaGVkIGZyb20gL2xvZ2luIGFzIHRoYXQncyB0aGUgb25seVxuICAgIC8vIHBsYWNlIGl0IGlzIGV4cG9zZWQuXG4gICAgc3NvRmxvdz86IFNTT0Zsb3c7XG4gICAgLy8gdGhlIE9JREMgbmF0aXZlIGxvZ2luIGZsb3csIHdoZW4gc3VwcG9ydGVkIGFuZCBlbmFibGVkXG4gICAgLy8gaWYgcHJlc2VudCwgbXVzdCBiZSB1c2VkIGZvciByZWdpc3RyYXRpb25cbiAgICBvaWRjTmF0aXZlRmxvdz86IE9pZGNOYXRpdmVGbG93O1xufVxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBSZWdpc3RyYXRpb24gZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQ8SVByb3BzLCBJU3RhdGU+IHtcbiAgICBwcml2YXRlIHJlYWRvbmx5IGxvZ2luTG9naWM6IExvZ2luO1xuICAgIC8vIGByZXBsYWNlQ2xpZW50YCB0cmFja3MgbGF0ZXN0IHNlcnZlckNvbmZpZyB0byBzcG90IHdoZW4gaXQgY2hhbmdlcyB1bmRlciB0aGUgYXN5bmMgbWV0aG9kIHdoaWNoIGZldGNoZXMgZmxvd3NcbiAgICBwcml2YXRlIGxhdGVzdFNlcnZlckNvbmZpZz86IFZhbGlkYXRlZFNlcnZlckNvbmZpZztcbiAgICAvLyBjYWNoZSB2YWx1ZSBmcm9tIHNldHRpbmdzIHN0b3JlXG4gICAgcHJpdmF0ZSBvaWRjTmF0aXZlRmxvd0VuYWJsZWQgPSBmYWxzZTtcblxuICAgIHB1YmxpYyBjb25zdHJ1Y3Rvcihwcm9wczogSVByb3BzKSB7XG4gICAgICAgIHN1cGVyKHByb3BzKTtcblxuICAgICAgICB0aGlzLnN0YXRlID0ge1xuICAgICAgICAgICAgYnVzeTogZmFsc2UsXG4gICAgICAgICAgICBlcnJvclRleHQ6IG51bGwsXG4gICAgICAgICAgICBmb3JtVmFsczoge1xuICAgICAgICAgICAgICAgIGVtYWlsOiB0aGlzLnByb3BzLmVtYWlsLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGRvaW5nVUlBdXRoOiBCb29sZWFuKHRoaXMucHJvcHMuc2Vzc2lvbklkKSxcbiAgICAgICAgICAgIGZsb3dzOiBudWxsLFxuICAgICAgICAgICAgY29tcGxldGVkTm9TaWduaW46IGZhbHNlLFxuICAgICAgICAgICAgc2VydmVySXNBbGl2ZTogdHJ1ZSxcbiAgICAgICAgICAgIHNlcnZlckVycm9ySXNGYXRhbDogZmFsc2UsXG4gICAgICAgICAgICBzZXJ2ZXJEZWFkRXJyb3I6IFwiXCIsXG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gb25seSBzZXQgb24gYSBjb25maWcgbGV2ZWwsIHNvIHdlIGRvbid0IG5lZWQgdG8gd2F0Y2hcbiAgICAgICAgdGhpcy5vaWRjTmF0aXZlRmxvd0VuYWJsZWQgPSBTZXR0aW5nc1N0b3JlLmdldFZhbHVlKEZlYXR1cmVzLk9pZGNOYXRpdmVGbG93KTtcblxuICAgICAgICBjb25zdCB7IGhzVXJsLCBpc1VybCwgZGVsZWdhdGVkQXV0aGVudGljYXRpb24gfSA9IHRoaXMucHJvcHMuc2VydmVyQ29uZmlnO1xuICAgICAgICB0aGlzLmxvZ2luTG9naWMgPSBuZXcgTG9naW4oaHNVcmwsIGlzVXJsLCBudWxsLCB7XG4gICAgICAgICAgICBkZWZhdWx0RGV2aWNlRGlzcGxheU5hbWU6IFwiRWxlbWVudCBsb2dpbiBjaGVja1wiLCAvLyBXZSBzaG91bGRuJ3QgZXZlciBiZSB1c2VkXG4gICAgICAgICAgICAvLyBpZiBuYXRpdmUgT0lEQyBpcyBlbmFibGVkIGluIHRoZSBjbGllbnQgcGFzcyB0aGUgc2VydmVyJ3MgZGVsZWdhdGVkIGF1dGggc2V0dGluZ3NcbiAgICAgICAgICAgIGRlbGVnYXRlZEF1dGhlbnRpY2F0aW9uOiB0aGlzLm9pZGNOYXRpdmVGbG93RW5hYmxlZCA/IGRlbGVnYXRlZEF1dGhlbnRpY2F0aW9uIDogdW5kZWZpbmVkLFxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgY29tcG9uZW50RGlkTW91bnQoKTogdm9pZCB7XG4gICAgICAgIHRoaXMucmVwbGFjZUNsaWVudCh0aGlzLnByb3BzLnNlcnZlckNvbmZpZyk7XG4gICAgICAgIC8vdHJpZ2dlcnMgYSBjb25maXJtYXRpb24gZGlhbG9nIGZvciBkYXRhIGxvc3MgYmVmb3JlIHBhZ2UgdW5sb2Fkcy9yZWZyZXNoZXNcbiAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJiZWZvcmV1bmxvYWRcIiwgdGhpcy51bmxvYWRDYWxsYmFjayk7XG4gICAgfVxuXG4gICAgcHVibGljIGNvbXBvbmVudFdpbGxVbm1vdW50KCk6IHZvaWQge1xuICAgICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImJlZm9yZXVubG9hZFwiLCB0aGlzLnVubG9hZENhbGxiYWNrKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHVubG9hZENhbGxiYWNrID0gKGV2ZW50OiBCZWZvcmVVbmxvYWRFdmVudCk6IHN0cmluZyB8IHVuZGVmaW5lZCA9PiB7XG4gICAgICAgIGlmICh0aGlzLnN0YXRlLmRvaW5nVUlBdXRoKSB7XG4gICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgZXZlbnQucmV0dXJuVmFsdWUgPSBcIlwiO1xuICAgICAgICAgICAgcmV0dXJuIFwiXCI7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgcHVibGljIGNvbXBvbmVudERpZFVwZGF0ZShwcmV2UHJvcHM6IElQcm9wcyk6IHZvaWQge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgICBwcmV2UHJvcHMuc2VydmVyQ29uZmlnLmhzVXJsICE9PSB0aGlzLnByb3BzLnNlcnZlckNvbmZpZy5oc1VybCB8fFxuICAgICAgICAgICAgcHJldlByb3BzLnNlcnZlckNvbmZpZy5pc1VybCAhPT0gdGhpcy5wcm9wcy5zZXJ2ZXJDb25maWcuaXNVcmxcbiAgICAgICAgKSB7XG4gICAgICAgICAgICB0aGlzLnJlcGxhY2VDbGllbnQodGhpcy5wcm9wcy5zZXJ2ZXJDb25maWcpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyByZXBsYWNlQ2xpZW50KHNlcnZlckNvbmZpZzogVmFsaWRhdGVkU2VydmVyQ29uZmlnKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHRoaXMubGF0ZXN0U2VydmVyQ29uZmlnID0gc2VydmVyQ29uZmlnO1xuICAgICAgICBjb25zdCB7IGhzVXJsLCBpc1VybCB9ID0gc2VydmVyQ29uZmlnO1xuXG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgZXJyb3JUZXh0OiBudWxsLFxuICAgICAgICAgICAgc2VydmVyRGVhZEVycm9yOiBudWxsLFxuICAgICAgICAgICAgc2VydmVyRXJyb3JJc0ZhdGFsOiBmYWxzZSxcbiAgICAgICAgICAgIC8vIGJ1c3kgd2hpbGUgd2UgZG8gbGl2ZS1uZXNzIGNoZWNrICh3ZSBuZWVkIHRvIGF2b2lkIHRyeWluZyB0byByZW5kZXJcbiAgICAgICAgICAgIC8vIHRoZSBVSSBhdXRoIGNvbXBvbmVudCB3aGlsZSB3ZSBkb24ndCBoYXZlIGEgbWF0cml4IGNsaWVudClcbiAgICAgICAgICAgIGJ1c3k6IHRydWUsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIERvIGEgbGl2ZWxpbmVzcyBjaGVjayBvbiB0aGUgVVJMc1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgYXdhaXQgQXV0b0Rpc2NvdmVyeVV0aWxzLnZhbGlkYXRlU2VydmVyQ29uZmlnV2l0aFN0YXRpY1VybHMoaHNVcmwsIGlzVXJsKTtcbiAgICAgICAgICAgIGlmIChzZXJ2ZXJDb25maWcgIT09IHRoaXMubGF0ZXN0U2VydmVyQ29uZmlnKSByZXR1cm47IC8vIGRpc2NhcmQsIHNlcnZlckNvbmZpZyBjaGFuZ2VkIGZyb20gdW5kZXIgdXNcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgICAgIHNlcnZlcklzQWxpdmU6IHRydWUsXG4gICAgICAgICAgICAgICAgc2VydmVyRXJyb3JJc0ZhdGFsOiBmYWxzZSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICBpZiAoc2VydmVyQ29uZmlnICE9PSB0aGlzLmxhdGVzdFNlcnZlckNvbmZpZykgcmV0dXJuOyAvLyBkaXNjYXJkLCBzZXJ2ZXJDb25maWcgY2hhbmdlZCBmcm9tIHVuZGVyIHVzXG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgICAgICBidXN5OiBmYWxzZSxcbiAgICAgICAgICAgICAgICAuLi5BdXRvRGlzY292ZXJ5VXRpbHMuYXV0aENvbXBvbmVudFN0YXRlRm9yRXJyb3IoZSwgXCJyZWdpc3RlclwiKSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUuc2VydmVyRXJyb3JJc0ZhdGFsKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuOyAvLyBTZXJ2ZXIgaXMgZGVhZCAtIGRvIG5vdCBjb250aW51ZS5cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGNsaSA9IGNyZWF0ZUNsaWVudCh7XG4gICAgICAgICAgICBiYXNlVXJsOiBoc1VybCxcbiAgICAgICAgICAgIGlkQmFzZVVybDogaXNVcmwsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMubG9naW5Mb2dpYy5zZXRIb21lc2VydmVyVXJsKGhzVXJsKTtcbiAgICAgICAgdGhpcy5sb2dpbkxvZ2ljLnNldElkZW50aXR5U2VydmVyVXJsKGlzVXJsKTtcbiAgICAgICAgLy8gaWYgbmF0aXZlIE9JREMgaXMgZW5hYmxlZCBpbiB0aGUgY2xpZW50IHBhc3MgdGhlIHNlcnZlcidzIGRlbGVnYXRlZCBhdXRoIHNldHRpbmdzXG4gICAgICAgIGNvbnN0IGRlbGVnYXRlZEF1dGhlbnRpY2F0aW9uID0gdGhpcy5vaWRjTmF0aXZlRmxvd0VuYWJsZWQgPyBzZXJ2ZXJDb25maWcuZGVsZWdhdGVkQXV0aGVudGljYXRpb24gOiB1bmRlZmluZWQ7XG5cbiAgICAgICAgdGhpcy5sb2dpbkxvZ2ljLnNldERlbGVnYXRlZEF1dGhlbnRpY2F0aW9uKGRlbGVnYXRlZEF1dGhlbnRpY2F0aW9uKTtcblxuICAgICAgICBsZXQgc3NvRmxvdzogU1NPRmxvdyB8IHVuZGVmaW5lZDtcbiAgICAgICAgbGV0IG9pZGNOYXRpdmVGbG93OiBPaWRjTmF0aXZlRmxvdyB8IHVuZGVmaW5lZDtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IGxvZ2luRmxvd3MgPSBhd2FpdCB0aGlzLmxvZ2luTG9naWMuZ2V0Rmxvd3ModHJ1ZSk7XG4gICAgICAgICAgICBpZiAoc2VydmVyQ29uZmlnICE9PSB0aGlzLmxhdGVzdFNlcnZlckNvbmZpZykgcmV0dXJuOyAvLyBkaXNjYXJkLCBzZXJ2ZXJDb25maWcgY2hhbmdlZCBmcm9tIHVuZGVyIHVzXG4gICAgICAgICAgICBzc29GbG93ID0gbG9naW5GbG93cy5maW5kKChmKSA9PiBmLnR5cGUgPT09IFwibS5sb2dpbi5zc29cIiB8fCBmLnR5cGUgPT09IFwibS5sb2dpbi5jYXNcIikgYXMgU1NPRmxvdztcbiAgICAgICAgICAgIG9pZGNOYXRpdmVGbG93ID0gbG9naW5GbG93cy5maW5kKChmKSA9PiBmLnR5cGUgPT09IFwib2lkY05hdGl2ZUZsb3dcIikgYXMgT2lkY05hdGl2ZUZsb3c7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIGlmIChzZXJ2ZXJDb25maWcgIT09IHRoaXMubGF0ZXN0U2VydmVyQ29uZmlnKSByZXR1cm47IC8vIGRpc2NhcmQsIHNlcnZlckNvbmZpZyBjaGFuZ2VkIGZyb20gdW5kZXIgdXNcbiAgICAgICAgICAgIGxvZ2dlci5lcnJvcihcIkZhaWxlZCB0byBnZXQgbG9naW4gZmxvd3MgdG8gY2hlY2sgZm9yIFNTTyBzdXBwb3J0XCIsIGUpO1xuICAgICAgICB9XG5cbiAgICAgICAgYXdhaXQgbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUpID0+IHtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoXG4gICAgICAgICAgICAgICAgKHsgZmxvd3MgfSkgPT4gKHtcbiAgICAgICAgICAgICAgICAgICAgbWF0cml4Q2xpZW50OiBjbGksXG4gICAgICAgICAgICAgICAgICAgIHNzb0Zsb3csXG4gICAgICAgICAgICAgICAgICAgIG9pZGNOYXRpdmVGbG93LFxuICAgICAgICAgICAgICAgICAgICAvLyBpZiB3ZSBhcmUgdXNpbmcgb2lkYyBuYXRpdmUgd2Ugd29uJ3QgY29udGludWUgd2l0aCBmbG93IGRpc2NvdmVyeSBvbiBIU1xuICAgICAgICAgICAgICAgICAgICAvLyBzbyBzZXQgYW4gZW1wdHkgYXJyYXkgdG8gaW5kaWNhdGUgZmxvd3MgYXJlIG5vIGxvbmdlciBsb2FkaW5nXG4gICAgICAgICAgICAgICAgICAgIGZsb3dzOiBvaWRjTmF0aXZlRmxvdyA/IFtdIDogZmxvd3MsXG4gICAgICAgICAgICAgICAgICAgIGJ1c3k6IGZhbHNlLFxuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgIHJlc29sdmUsXG4gICAgICAgICAgICApO1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyBkb24ndCBuZWVkIHRvIGNoZWNrIHdpdGggaG9tZXNlcnZlciBmb3IgbG9naW4gZmxvd3NcbiAgICAgICAgLy8gc2luY2Ugd2UgYXJlIGdvaW5nIHRvIHVzZSBPSURDIG5hdGl2ZSBmbG93XG4gICAgICAgIGlmIChvaWRjTmF0aXZlRmxvdykge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIC8vIFdlIGRvIHRoZSBmaXJzdCByZWdpc3RyYXRpb24gcmVxdWVzdCBvdXJzZWx2ZXMgdG8gZGlzY292ZXIgd2hldGhlciB3ZSBuZWVkIHRvXG4gICAgICAgICAgICAvLyBkbyBTU08gaW5zdGVhZC4gSWYgd2UndmUgYWxyZWFkeSBzdGFydGVkIHRoZSBVSSBBdXRoIHByb2Nlc3MgdGhvdWdoLCB3ZSBkb24ndFxuICAgICAgICAgICAgLy8gbmVlZCB0by5cbiAgICAgICAgICAgIGlmICghdGhpcy5zdGF0ZS5kb2luZ1VJQXV0aCkge1xuICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMubWFrZVJlZ2lzdGVyUmVxdWVzdChudWxsKTtcbiAgICAgICAgICAgICAgICBpZiAoc2VydmVyQ29uZmlnICE9PSB0aGlzLmxhdGVzdFNlcnZlckNvbmZpZykgcmV0dXJuOyAvLyBkaXNjYXJkLCBzZXJ2ZXJDb25maWcgY2hhbmdlZCBmcm9tIHVuZGVyIHVzXG4gICAgICAgICAgICAgICAgLy8gVGhpcyBzaG91bGQgbmV2ZXIgc3VjY2VlZCBzaW5jZSB3ZSBzcGVjaWZpZWQgbm8gYXV0aCBvYmplY3QuXG4gICAgICAgICAgICAgICAgbG9nZ2VyLmxvZyhcIkV4cGVjdGluZyA0MDEgZnJvbSByZWdpc3RlciByZXF1ZXN0IGJ1dCBnb3Qgc3VjY2VzcyFcIik7XG4gICA