Move default homeserver to config file
This commit is contained in:
parent
282a4853cf
commit
96de515e56
13 changed files with 69 additions and 54 deletions
|
@ -32,7 +32,6 @@ import { useTranslation } from "react-i18next";
|
|||
import { ErrorView } from "./FullScreenView";
|
||||
import {
|
||||
initClient,
|
||||
defaultHomeserver,
|
||||
CryptoStoreIntegrityError,
|
||||
fallbackICEServerAllowed,
|
||||
} from "./matrix-utils";
|
||||
|
@ -40,6 +39,7 @@ import { widget } from "./widget";
|
|||
import { PosthogAnalytics, RegistrationType } from "./PosthogAnalytics";
|
||||
import { translatedError } from "./TranslatedError";
|
||||
import { useEventTarget } from "./useEvents";
|
||||
import { Config } from "./config/Config";
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
|
@ -139,7 +139,7 @@ export const ClientProvider: FC<Props> = ({ children }) => {
|
|||
return {
|
||||
client: await initClient(
|
||||
{
|
||||
baseUrl: defaultHomeserver,
|
||||
baseUrl: Config.defaultHomeserverUrl(),
|
||||
accessToken: access_token,
|
||||
userId: user_id,
|
||||
deviceId: device_id,
|
||||
|
@ -155,7 +155,7 @@ export const ClientProvider: FC<Props> = ({ children }) => {
|
|||
try {
|
||||
const client = await initClient(
|
||||
{
|
||||
baseUrl: defaultHomeserver,
|
||||
baseUrl: Config.defaultHomeserverUrl(),
|
||||
accessToken: access_token,
|
||||
userId: user_id,
|
||||
deviceId: device_id,
|
||||
|
|
|
@ -29,11 +29,11 @@ import { ReactComponent as Logo } from "../icons/LogoLarge.svg";
|
|||
import { useClient } from "../ClientContext";
|
||||
import { FieldRow, InputField, ErrorMessage } from "../input/Input";
|
||||
import { Button } from "../button";
|
||||
import { defaultHomeserver, defaultHomeserverHost } from "../matrix-utils";
|
||||
import styles from "./LoginPage.module.css";
|
||||
import { useInteractiveLogin } from "./useInteractiveLogin";
|
||||
import { usePageTitle } from "../usePageTitle";
|
||||
import { PosthogAnalytics } from "../PosthogAnalytics";
|
||||
import { Config } from "../config/Config";
|
||||
|
||||
export const LoginPage: FC = () => {
|
||||
const { t } = useTranslation();
|
||||
|
@ -41,7 +41,7 @@ export const LoginPage: FC = () => {
|
|||
|
||||
const { setClient } = useClient();
|
||||
const login = useInteractiveLogin();
|
||||
const homeserver = defaultHomeserver; // TODO: Make this configurable
|
||||
const homeserver = Config.defaultHomeserverUrl(); // TODO: Make this configurable
|
||||
const usernameRef = useRef<HTMLInputElement>();
|
||||
const passwordRef = useRef<HTMLInputElement>();
|
||||
const history = useHistory();
|
||||
|
@ -76,11 +76,9 @@ export const LoginPage: FC = () => {
|
|||
);
|
||||
|
||||
const homeserverHost = useMemo(() => {
|
||||
try {
|
||||
return new URL(homeserver).host;
|
||||
} catch (error) {
|
||||
return defaultHomeserverHost;
|
||||
}
|
||||
// XXX: This isn't really correct: the server name of an HS may not
|
||||
// be the same as the hostname of the client API endpoint.
|
||||
return new URL(homeserver).host;
|
||||
}, [homeserver]);
|
||||
|
||||
return (
|
||||
|
|
|
@ -31,7 +31,6 @@ import { Trans, useTranslation } from "react-i18next";
|
|||
import { FieldRow, InputField, ErrorMessage } from "../input/Input";
|
||||
import { Button } from "../button";
|
||||
import { useClient } from "../ClientContext";
|
||||
import { defaultHomeserverHost } from "../matrix-utils";
|
||||
import { useInteractiveRegistration } from "./useInteractiveRegistration";
|
||||
import styles from "./LoginPage.module.css";
|
||||
import { ReactComponent as Logo } from "../icons/LogoLarge.svg";
|
||||
|
@ -40,6 +39,7 @@ import { useRecaptcha } from "./useRecaptcha";
|
|||
import { Caption, Link } from "../typography/Typography";
|
||||
import { usePageTitle } from "../usePageTitle";
|
||||
import { PosthogAnalytics } from "../PosthogAnalytics";
|
||||
import { Config } from "../config/Config";
|
||||
|
||||
export const RegisterPage: FC = () => {
|
||||
const { t } = useTranslation();
|
||||
|
@ -165,7 +165,7 @@ export const RegisterPage: FC = () => {
|
|||
autoCorrect="off"
|
||||
autoCapitalize="none"
|
||||
prefix="@"
|
||||
suffix={`:${defaultHomeserverHost}`}
|
||||
suffix={`:${Config.defaultServerName()}`}
|
||||
/>
|
||||
</FieldRow>
|
||||
<FieldRow>
|
||||
|
|
|
@ -18,7 +18,7 @@ import { useCallback } from "react";
|
|||
import { InteractiveAuth } from "matrix-js-sdk/src/interactive-auth";
|
||||
import { createClient, MatrixClient } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
import { initClient, defaultHomeserver } from "../matrix-utils";
|
||||
import { initClient } from "../matrix-utils";
|
||||
import { Session } from "../ClientContext";
|
||||
|
||||
export const useInteractiveLogin = () =>
|
||||
|
@ -59,7 +59,7 @@ export const useInteractiveLogin = () =>
|
|||
|
||||
const client = await initClient(
|
||||
{
|
||||
baseUrl: defaultHomeserver,
|
||||
baseUrl: homeserver,
|
||||
accessToken: access_token,
|
||||
userId: user_id,
|
||||
deviceId: device_id,
|
||||
|
|
|
@ -18,8 +18,9 @@ import { useState, useEffect, useCallback, useRef } from "react";
|
|||
import { InteractiveAuth } from "matrix-js-sdk/src/interactive-auth";
|
||||
import { createClient, MatrixClient } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
import { initClient, defaultHomeserver } from "../matrix-utils";
|
||||
import { initClient } from "../matrix-utils";
|
||||
import { Session } from "../ClientContext";
|
||||
import { Config } from "../config/Config";
|
||||
|
||||
export const useInteractiveRegistration = (): [
|
||||
string,
|
||||
|
@ -37,7 +38,9 @@ export const useInteractiveRegistration = (): [
|
|||
|
||||
const authClient = useRef<MatrixClient>();
|
||||
if (!authClient.current) {
|
||||
authClient.current = createClient({ baseUrl: defaultHomeserver });
|
||||
authClient.current = createClient({
|
||||
baseUrl: Config.defaultHomeserverUrl(),
|
||||
});
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -92,7 +95,7 @@ export const useInteractiveRegistration = (): [
|
|||
|
||||
const client = await initClient(
|
||||
{
|
||||
baseUrl: defaultHomeserver,
|
||||
baseUrl: Config.defaultHomeserverUrl(),
|
||||
accessToken: access_token,
|
||||
userId: user_id,
|
||||
deviceId: device_id,
|
||||
|
|
|
@ -14,11 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
DEFAULT_CONFIG,
|
||||
ConfigOptions,
|
||||
ResolvedConfigOptions,
|
||||
} from "./ConfigOptions";
|
||||
import { DEFAULT_CONFIG, ConfigOptions } from "./ConfigOptions";
|
||||
|
||||
export class Config {
|
||||
private static internalInstance: Config;
|
||||
|
@ -41,7 +37,26 @@ export class Config {
|
|||
return Config.internalInstance.initPromise;
|
||||
}
|
||||
|
||||
public config: ResolvedConfigOptions;
|
||||
// Convenience accessors
|
||||
public static defaultHomeserverUrl(): string | undefined {
|
||||
const defaultServerConfig = Config.instance.config.default_server_config;
|
||||
if (!defaultServerConfig) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return defaultServerConfig["m.homeserver"]?.base_url;
|
||||
}
|
||||
|
||||
public static defaultServerName(): string | undefined {
|
||||
const defaultServerConfig = Config.instance.config.default_server_config;
|
||||
if (!defaultServerConfig) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return defaultServerConfig["m.homeserver"]?.server_name;
|
||||
}
|
||||
|
||||
public config: ConfigOptions;
|
||||
private initPromise: Promise<void>;
|
||||
}
|
||||
|
||||
|
@ -59,7 +74,7 @@ async function downloadConfig(
|
|||
// Lack of a config isn't an error, we should just use the defaults.
|
||||
// Also treat a blank config as no config, assuming the status code is 0, because we don't get 404s from file:
|
||||
// URIs so this is the only way we can not fail if the file doesn't exist when loading from a file:// URI.
|
||||
return {};
|
||||
return DEFAULT_CONFIG;
|
||||
}
|
||||
|
||||
return res.json();
|
||||
|
|
|
@ -19,21 +19,24 @@ export interface ConfigOptions {
|
|||
rageshake?: {
|
||||
submit_url: string;
|
||||
};
|
||||
}
|
||||
|
||||
export interface ResolvedConfigOptions extends ConfigOptions {
|
||||
sentry: {
|
||||
DSN: string;
|
||||
environment: string;
|
||||
};
|
||||
rageshake: {
|
||||
submit_url: string;
|
||||
// Describes the default homeserver to use. The same format as Element Web
|
||||
// (without identity servers as we don't use them).
|
||||
default_server_config: {
|
||||
["m.homeserver"]: {
|
||||
base_url: string;
|
||||
server_name: string;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export const DEFAULT_CONFIG: ResolvedConfigOptions = {
|
||||
sentry: { DSN: "", environment: "production" },
|
||||
rageshake: {
|
||||
submit_url: "https://element.io/bugreports/submit",
|
||||
export const DEFAULT_CONFIG: ConfigOptions = {
|
||||
default_server_config: {
|
||||
["m.homeserver"]: {
|
||||
// These are probably poor guesses - we may want to just not work without
|
||||
// a config file.
|
||||
base_url: `${window.location.protocol}//${window.location.host}`,
|
||||
server_name: window.location.host,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -23,7 +23,6 @@ import * as Sentry from "@sentry/react";
|
|||
|
||||
import { getUrlParams } from "./UrlParams";
|
||||
import { Config } from "./config/Config";
|
||||
import { DEFAULT_CONFIG } from "./config/ConfigOptions";
|
||||
|
||||
enum LoadState {
|
||||
None,
|
||||
|
@ -193,10 +192,8 @@ export class Initializer {
|
|||
this.loadStates.config === LoadState.Loaded
|
||||
) {
|
||||
Sentry.init({
|
||||
dsn: Config.instance.config.sentry?.DSN ?? DEFAULT_CONFIG.sentry.DSN,
|
||||
environment:
|
||||
Config.instance.config.sentry.environment ??
|
||||
DEFAULT_CONFIG.sentry.environment,
|
||||
dsn: Config.instance.config.sentry?.DSN,
|
||||
environment: Config.instance.config.sentry?.environment,
|
||||
integrations: [
|
||||
new Integrations.BrowserTracing({
|
||||
routingInstrumentation:
|
||||
|
|
|
@ -19,15 +19,11 @@ import type { Room } from "matrix-js-sdk/src/models/room";
|
|||
import IndexedDBWorker from "./IndexedDBWorker?worker";
|
||||
import { getUrlParams } from "./UrlParams";
|
||||
import { loadOlm } from "./olm";
|
||||
import { Config } from "./config/Config";
|
||||
|
||||
export const defaultHomeserver =
|
||||
(import.meta.env.VITE_DEFAULT_HOMESERVER as string) ??
|
||||
`${window.location.protocol}//${window.location.host}`;
|
||||
export const fallbackICEServerAllowed =
|
||||
import.meta.env.VITE_FALLBACK_STUN_ALLOWED === "true";
|
||||
|
||||
export const defaultHomeserverHost = new URL(defaultHomeserver).host;
|
||||
|
||||
export class CryptoStoreIntegrityError extends Error {
|
||||
constructor() {
|
||||
super("Crypto store data was expected, but none was found");
|
||||
|
@ -206,7 +202,7 @@ export function roomNameFromRoomId(roomId: string): string {
|
|||
.toLowerCase();
|
||||
}
|
||||
|
||||
export function isLocalRoomId(roomId: string): boolean {
|
||||
export function isLocalRoomId(roomId: string, client: MatrixClient): boolean {
|
||||
if (!roomId) {
|
||||
return false;
|
||||
}
|
||||
|
@ -217,7 +213,7 @@ export function isLocalRoomId(roomId: string): boolean {
|
|||
return false;
|
||||
}
|
||||
|
||||
return parts[1] === defaultHomeserverHost;
|
||||
return parts[1] === client.getDomain();
|
||||
}
|
||||
|
||||
export async function createRoom(
|
||||
|
@ -291,11 +287,12 @@ export async function createRoom(
|
|||
return [fullAliasFromRoomName(name, client), result.room_id];
|
||||
}
|
||||
|
||||
// Returns a URL to that will load Element Call with the given room
|
||||
export function getRoomUrl(roomIdOrAlias: string): string {
|
||||
if (roomIdOrAlias.startsWith("#")) {
|
||||
const [localPart, host] = roomIdOrAlias.replace("#", "").split(":");
|
||||
|
||||
if (host !== defaultHomeserverHost) {
|
||||
if (host !== Config.defaultServerName()) {
|
||||
return `${window.location.protocol}//${window.location.host}/room/${roomIdOrAlias}`;
|
||||
} else {
|
||||
return `${window.location.protocol}//${window.location.host}/${localPart}`;
|
||||
|
|
|
@ -17,9 +17,11 @@ limitations under the License.
|
|||
import React, { useEffect } from "react";
|
||||
import { useLocation, useHistory } from "react-router-dom";
|
||||
|
||||
import { defaultHomeserverHost } from "../matrix-utils";
|
||||
import { Config } from "../config/Config";
|
||||
import { LoadingView } from "../FullScreenView";
|
||||
|
||||
// A component that, when loaded, redirects the client to a full room URL
|
||||
// based on the current URL being an abbreviated room URL
|
||||
export function RoomRedirect() {
|
||||
const { pathname } = useLocation();
|
||||
const history = useHistory();
|
||||
|
@ -32,7 +34,7 @@ export function RoomRedirect() {
|
|||
}
|
||||
|
||||
if (!roomId.startsWith("#") && !roomId.startsWith("!")) {
|
||||
roomId = `#${roomId}:${defaultHomeserverHost}`;
|
||||
roomId = `#${roomId}:${Config.defaultServerName()}`;
|
||||
}
|
||||
|
||||
history.replace(`/room/${roomId.toLowerCase()}`);
|
||||
|
|
|
@ -61,7 +61,7 @@ export const useLoadGroupCall = (
|
|||
return room;
|
||||
} catch (error) {
|
||||
if (
|
||||
isLocalRoomId(roomIdOrAlias) &&
|
||||
isLocalRoomId(roomIdOrAlias, client) &&
|
||||
(error.errcode === "M_NOT_FOUND" ||
|
||||
(error.message &&
|
||||
error.message.indexOf("Failed to fetch alias") !== -1))
|
||||
|
|
|
@ -18,7 +18,7 @@ import { useEffect } from "react";
|
|||
|
||||
export function usePageTitle(title: string): void {
|
||||
useEffect(() => {
|
||||
const productName = import.meta.env.VITE_PRODUCT_NAME || "Element Call";
|
||||
const productName = "Element Call";
|
||||
document.title = title ? `${productName} | ${title}` : productName;
|
||||
}, [title]);
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ export default defineConfig(({ mode }) => {
|
|||
svgrPlugin(),
|
||||
htmlTemplate.default({
|
||||
data: {
|
||||
title: env.VITE_PRODUCT_NAME || "Element Call",
|
||||
title: "Element Call",
|
||||
},
|
||||
}),
|
||||
],
|
||||
|
|
Loading…
Reference in a new issue