mkdir apps/web/scripts
mv scripts/{cleanup.sh,ci_package.sh,copy-res.ts,deploy.py,package.sh} apps/web/scripts
And a couple of gitignore tweaks
Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
221 lines
7.3 KiB
TypeScript
221 lines
7.3 KiB
TypeScript
/*
|
|
Copyright 2024 New Vector Ltd.
|
|
Copyright 2018-2021 The Matrix.org Foundation C.I.C.
|
|
|
|
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
|
|
Please see LICENSE files in the repository root for full details.
|
|
*/
|
|
|
|
import React, { type ReactNode } from "react";
|
|
import { MatrixError, ConnectionError } from "matrix-js-sdk/src/matrix";
|
|
import { logger } from "matrix-js-sdk/src/logger";
|
|
|
|
import { _t, _td, lookupString, type Tags, type TranslatedString } from "../languageHandler";
|
|
import SdkConfig from "../SdkConfig";
|
|
import { type ValidatedServerConfig } from "./ValidatedServerConfig";
|
|
import ExternalLink from "../components/views/elements/ExternalLink";
|
|
import Modal from "../Modal.tsx";
|
|
import ErrorDialog from "../components/views/dialogs/ErrorDialog.tsx";
|
|
|
|
export const resourceLimitStrings = {
|
|
"monthly_active_user": _td("error|mau"),
|
|
"hs_blocked": _td("error|hs_blocked"),
|
|
"": _td("error|resource_limits"),
|
|
};
|
|
|
|
export const adminContactStrings = {
|
|
"": _td("error|admin_contact"),
|
|
};
|
|
|
|
/**
|
|
* Produce a translated error message for a
|
|
* M_RESOURCE_LIMIT_EXCEEDED error
|
|
*
|
|
* @param {string} limitType The limit_type from the error
|
|
* @param {string} adminContact The admin_contact from the error
|
|
* @param {Object} strings Translatable string for different
|
|
* limit_type. Must include at least the empty string key
|
|
* which is the default. Strings may include an 'a' tag
|
|
* for the admin contact link.
|
|
* @param {Object} extraTranslations Extra translation substitution functions
|
|
* for any tags in the strings apart from 'a'
|
|
* @returns {*} Translated string or react component
|
|
*/
|
|
export function messageForResourceLimitError(
|
|
limitType: string | undefined,
|
|
adminContact: string | undefined,
|
|
strings: Record<string, TranslationKey>,
|
|
extraTranslations?: Tags,
|
|
): TranslatedString {
|
|
let errString = limitType ? strings[limitType] : undefined;
|
|
if (errString === undefined) errString = strings[""];
|
|
|
|
const linkSub = (sub: string): ReactNode => {
|
|
if (adminContact) {
|
|
return (
|
|
<a href={adminContact} target="_blank" rel="noreferrer noopener">
|
|
{sub}
|
|
</a>
|
|
);
|
|
} else {
|
|
return sub;
|
|
}
|
|
};
|
|
|
|
if (lookupString(errString).includes("<a>")) {
|
|
return _t(errString, {}, Object.assign({ a: linkSub }, extraTranslations));
|
|
} else {
|
|
return _t(errString, {}, extraTranslations!);
|
|
}
|
|
}
|
|
|
|
export function messageForSyncError(err: Error): ReactNode {
|
|
if (err instanceof MatrixError && err.errcode === "M_RESOURCE_LIMIT_EXCEEDED") {
|
|
const limitError = messageForResourceLimitError(
|
|
err.data.limit_type,
|
|
err.data.admin_contact,
|
|
resourceLimitStrings,
|
|
);
|
|
const adminContact = messageForResourceLimitError(
|
|
err.data.limit_type,
|
|
err.data.admin_contact,
|
|
adminContactStrings,
|
|
);
|
|
return (
|
|
<div>
|
|
<div>{limitError}</div>
|
|
<div>{adminContact}</div>
|
|
</div>
|
|
);
|
|
} else {
|
|
return <div>{_t("error|sync")}</div>;
|
|
}
|
|
}
|
|
|
|
export function messageForLoginError(
|
|
err: MatrixError,
|
|
serverConfig: Pick<ValidatedServerConfig, "hsName" | "hsUrl">,
|
|
): ReactNode {
|
|
if (err.errcode === "M_RESOURCE_LIMIT_EXCEEDED") {
|
|
const errorTop = messageForResourceLimitError(
|
|
err.data.limit_type,
|
|
err.data.admin_contact,
|
|
resourceLimitStrings,
|
|
);
|
|
const errorDetail = messageForResourceLimitError(
|
|
err.data.limit_type,
|
|
err.data.admin_contact,
|
|
adminContactStrings,
|
|
);
|
|
return (
|
|
<div>
|
|
<div>{errorTop}</div>
|
|
<div className="mx_Login_smallError">{errorDetail}</div>
|
|
</div>
|
|
);
|
|
} else if (err.httpStatus === 401 || err.httpStatus === 403) {
|
|
if (err.errcode === "M_USER_DEACTIVATED") {
|
|
return _t("auth|account_deactivated");
|
|
} else if (SdkConfig.get("disable_custom_urls")) {
|
|
return (
|
|
<div>
|
|
<div>{_t("auth|incorrect_credentials")}</div>
|
|
<div className="mx_Login_smallError">
|
|
{_t("auth|incorrect_credentials_detail", {
|
|
hs: serverConfig.hsName,
|
|
})}
|
|
</div>
|
|
</div>
|
|
);
|
|
} else {
|
|
return _t("auth|incorrect_credentials");
|
|
}
|
|
} else {
|
|
return messageForConnectionError(err, serverConfig);
|
|
}
|
|
}
|
|
|
|
export function messageForConnectionError(
|
|
err: Error,
|
|
serverConfig: Pick<ValidatedServerConfig, "hsName" | "hsUrl">,
|
|
): ReactNode {
|
|
let errorText = _t("error|connection");
|
|
|
|
if (err instanceof ConnectionError) {
|
|
if (
|
|
window.location.protocol === "https:" &&
|
|
(serverConfig.hsUrl.startsWith("http:") || !serverConfig.hsUrl.startsWith("http"))
|
|
) {
|
|
return (
|
|
<span>
|
|
{_t(
|
|
"error|mixed_content",
|
|
{},
|
|
{
|
|
a: (sub) => {
|
|
return (
|
|
<a
|
|
target="_blank"
|
|
rel="noreferrer noopener"
|
|
href="https://www.google.com/search?&q=enable%20unsafe%20scripts"
|
|
>
|
|
{sub}
|
|
</a>
|
|
);
|
|
},
|
|
},
|
|
)}
|
|
</span>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<span>
|
|
{_t(
|
|
"error|tls",
|
|
{},
|
|
{
|
|
a: (sub) => (
|
|
<ExternalLink target="_blank" rel="noreferrer noopener" href={serverConfig.hsUrl}>
|
|
{sub}
|
|
</ExternalLink>
|
|
),
|
|
},
|
|
)}
|
|
</span>
|
|
);
|
|
} else if (err instanceof MatrixError) {
|
|
if (err.errcode) {
|
|
errorText += `(${err.errcode})`;
|
|
} else if (err.httpStatus) {
|
|
errorText += ` (HTTP ${err.httpStatus})`;
|
|
}
|
|
}
|
|
|
|
return errorText;
|
|
}
|
|
|
|
/**
|
|
* Utility for handling unexpected errors: pops up the error dialog.
|
|
*
|
|
* Example usage:
|
|
* ```
|
|
* try {
|
|
* /// complicated operation
|
|
* } catch (e) {
|
|
* logErrorAndShowErrorDialog("Failed complicated operation", e);
|
|
* }
|
|
* ```
|
|
*
|
|
* This isn't particularly intended to be pretty; rather it lets the user know that *something* has gone wrong so that
|
|
* they can report a bug. The general idea is that it's better to let the user know of a failure, even if they
|
|
* can't do anything about it, than it is to fail silently with the appearance of success.
|
|
*
|
|
* @param title - Title for the error dialog.
|
|
* @param error - The thrown error. Becomes the content of the error dialog.
|
|
*/
|
|
export function logErrorAndShowErrorDialog(title: string, error: any): void {
|
|
logger.error(`${title}:`, error);
|
|
Modal.createDialog(ErrorDialog, { title, description: `${error}` });
|
|
}
|