Files
ThreadNet-Web/apps/web/test/unit-tests/utils/AutoDiscoveryUtils-test.tsx
T

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

281 lines
11 KiB
TypeScript
Raw Normal View History

2023-04-05 08:49:24 +12:00
/*
2024-09-09 14:57:16 +01:00
Copyright 2024 New Vector Ltd.
2023-04-05 08:49:24 +12:00
Copyright 2023 The Matrix.org Foundation C.I.C.
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
2024-09-09 14:57:16 +01:00
Please see LICENSE files in the repository root for full details.
2023-04-05 08:49:24 +12:00
*/
2025-02-05 13:25:06 +00:00
import { AutoDiscovery, AutoDiscoveryAction, type ClientConfig } from "matrix-js-sdk/src/matrix";
2023-04-05 08:49:24 +12:00
import { logger } from "matrix-js-sdk/src/logger";
import fetchMock from "@fetch-mock/jest";
2023-04-05 08:49:24 +12:00
2024-10-15 14:57:26 +01:00
import AutoDiscoveryUtils from "../../../src/utils/AutoDiscoveryUtils";
import { makeDelegatedAuthMetadata } from "../../test-utils/auth";
2023-04-05 08:49:24 +12:00
describe("AutoDiscoveryUtils", () => {
beforeEach(() => {
fetchMock.catch({
status: 404,
body: '{"errcode": "M_UNRECOGNIZED", "error": "Unrecognized request"}',
headers: { "content-type": "application/json" },
});
});
2023-04-05 08:49:24 +12:00
describe("buildValidatedConfigFromDiscovery()", () => {
const serverName = "my-server";
beforeEach(() => {
// don't litter console with expected errors
jest.spyOn(logger, "error")
.mockClear()
.mockImplementation(() => {});
});
afterAll(() => {
jest.spyOn(logger, "error").mockRestore();
});
const validIsConfig = {
"m.identity_server": {
state: AutoDiscoveryAction.SUCCESS,
base_url: "identity.com",
},
};
const validHsConfig = {
"m.homeserver": {
state: AutoDiscoveryAction.SUCCESS,
base_url: "https://matrix.org",
},
};
const expectedValidatedConfig = {
hsName: serverName,
hsNameIsDifferent: true,
hsUrl: "https://matrix.org",
isDefault: false,
isNameResolvable: true,
isUrl: "identity.com",
};
it("throws an error when discovery result is falsy", async () => {
await expect(() =>
AutoDiscoveryUtils.buildValidatedConfigFromDiscovery(serverName, undefined as any),
).rejects.toThrow("Unexpected error resolving homeserver configuration");
2023-04-05 08:49:24 +12:00
expect(logger.error).toHaveBeenCalled();
});
it("throws an error when discovery result does not include homeserver config", async () => {
2023-04-05 08:49:24 +12:00
const discoveryResult = {
...validIsConfig,
} as unknown as ClientConfig;
await expect(() =>
AutoDiscoveryUtils.buildValidatedConfigFromDiscovery(serverName, discoveryResult),
).rejects.toThrow("Unexpected error resolving homeserver configuration");
2023-04-05 08:49:24 +12:00
expect(logger.error).toHaveBeenCalled();
});
it("throws an error when identity server config has fail error and recognised error string", async () => {
2023-04-05 08:49:24 +12:00
const discoveryResult = {
...validHsConfig,
"m.identity_server": {
state: AutoDiscoveryAction.FAIL_ERROR,
error: "GenericFailure",
},
};
await expect(() =>
AutoDiscoveryUtils.buildValidatedConfigFromDiscovery(serverName, discoveryResult),
).rejects.toThrow("Unexpected error resolving identity server configuration");
2023-04-05 08:49:24 +12:00
expect(logger.error).toHaveBeenCalled();
});
it("throws an error when homeserver config has fail error and recognised error string", async () => {
const discoveryResult = {
...validIsConfig,
"m.homeserver": {
state: AutoDiscoveryAction.FAIL_ERROR,
error: AutoDiscovery.ERROR_INVALID_HOMESERVER,
},
};
await expect(() =>
AutoDiscoveryUtils.buildValidatedConfigFromDiscovery(serverName, discoveryResult),
).rejects.toThrow("Homeserver URL does not appear to be a valid Matrix homeserver");
expect(logger.error).toHaveBeenCalled();
});
it("throws an error with fallback message identity server config has fail error", async () => {
2023-04-05 08:49:24 +12:00
const discoveryResult = {
...validHsConfig,
"m.identity_server": {
state: AutoDiscoveryAction.FAIL_ERROR,
},
};
await expect(() =>
AutoDiscoveryUtils.buildValidatedConfigFromDiscovery(serverName, discoveryResult),
).rejects.toThrow("Unexpected error resolving identity server configuration");
2023-04-05 08:49:24 +12:00
});
it("throws an error when error is ERROR_INVALID_HOMESERVER", async () => {
2023-04-05 08:49:24 +12:00
const discoveryResult = {
...validIsConfig,
"m.homeserver": {
state: AutoDiscoveryAction.FAIL_ERROR,
error: AutoDiscovery.ERROR_INVALID_HOMESERVER,
},
};
await expect(() =>
AutoDiscoveryUtils.buildValidatedConfigFromDiscovery(serverName, discoveryResult),
).rejects.toThrow("Homeserver URL does not appear to be a valid Matrix homeserver");
2023-04-05 08:49:24 +12:00
});
it("throws an error when homeserver base_url is falsy", async () => {
2023-04-05 08:49:24 +12:00
const discoveryResult = {
...validIsConfig,
"m.homeserver": {
state: AutoDiscoveryAction.SUCCESS,
base_url: "",
},
};
await expect(() =>
AutoDiscoveryUtils.buildValidatedConfigFromDiscovery(serverName, discoveryResult),
).rejects.toThrow("Unexpected error resolving homeserver configuration");
2023-04-05 08:49:24 +12:00
expect(logger.error).toHaveBeenCalledWith("No homeserver URL configured");
});
it("throws an error when homeserver base_url is not a valid URL", async () => {
2023-04-05 08:49:24 +12:00
const discoveryResult = {
...validIsConfig,
"m.homeserver": {
state: AutoDiscoveryAction.SUCCESS,
base_url: "banana",
},
};
await expect(() =>
AutoDiscoveryUtils.buildValidatedConfigFromDiscovery(serverName, discoveryResult),
).rejects.toThrow("Invalid URL");
2023-04-05 08:49:24 +12:00
});
it("uses hs url hostname when serverName is falsy in args and config", async () => {
2023-04-05 08:49:24 +12:00
const discoveryResult = {
...validIsConfig,
...validHsConfig,
};
await expect(AutoDiscoveryUtils.buildValidatedConfigFromDiscovery("", discoveryResult)).resolves.toEqual({
2023-04-05 08:49:24 +12:00
...expectedValidatedConfig,
hsNameIsDifferent: false,
hsName: "matrix.org",
warning: null,
2023-04-05 08:49:24 +12:00
});
});
it("uses serverName from props", async () => {
2023-04-05 08:49:24 +12:00
const discoveryResult = {
...validIsConfig,
"m.homeserver": {
...validHsConfig["m.homeserver"],
server_name: "should not use this name",
},
};
const syntaxOnly = true;
await expect(
2023-04-05 08:49:24 +12:00
AutoDiscoveryUtils.buildValidatedConfigFromDiscovery(serverName, discoveryResult, syntaxOnly),
).resolves.toEqual({
2023-04-05 08:49:24 +12:00
...expectedValidatedConfig,
hsNameIsDifferent: true,
hsName: serverName,
warning: null,
2023-04-05 08:49:24 +12:00
});
});
it("ignores liveliness error when checking syntax only", async () => {
2023-04-05 08:49:24 +12:00
const discoveryResult = {
...validIsConfig,
"m.homeserver": {
...validHsConfig["m.homeserver"],
state: AutoDiscoveryAction.FAIL_ERROR,
error: AutoDiscovery.ERROR_INVALID_HOMESERVER,
},
};
const syntaxOnly = true;
await expect(
2023-04-05 08:49:24 +12:00
AutoDiscoveryUtils.buildValidatedConfigFromDiscovery(serverName, discoveryResult, syntaxOnly),
).resolves.toEqual({
2023-04-05 08:49:24 +12:00
...expectedValidatedConfig,
warning: "Homeserver URL does not appear to be a valid Matrix homeserver",
});
});
it("handles homeserver too old error", async () => {
const discoveryResult: ClientConfig = {
...validIsConfig,
"m.homeserver": {
state: AutoDiscoveryAction.FAIL_ERROR,
error: AutoDiscovery.ERROR_UNSUPPORTED_HOMESERVER_SPEC_VERSION,
base_url: "https://matrix.org",
},
};
const syntaxOnly = true;
await expect(() =>
AutoDiscoveryUtils.buildValidatedConfigFromDiscovery(serverName, discoveryResult, syntaxOnly),
).rejects.toThrow(
"Your homeserver is too old and does not support the minimum API version required. Please contact your server owner, or upgrade your server.",
);
});
it("should validate delegated oidc auth", async () => {
const issuer = "https://auth.matrix.org/";
fetchMock.get(`${validHsConfig["m.homeserver"].base_url}/_matrix/client/versions`, { versions: ["v1.15"] });
fetchMock.get(`${validHsConfig["m.homeserver"].base_url}/_matrix/client/v1/auth_metadata`, {
...makeDelegatedAuthMetadata(issuer),
scopes_supported: ["email"],
response_modes_supported: ["query", "fragment"],
prompt_values_supported: ["none", "login", "create"],
device_authorization_endpoint: `${issuer}oauth2/device`,
account_management_uri: `${issuer}account/`,
account_management_actions_supported: [
"org.matrix.profile",
"org.matrix.sessions_list",
"org.matrix.session_view",
"org.matrix.session_end",
"org.matrix.cross_signing_reset",
],
});
const discoveryResult = {
...validIsConfig,
...validHsConfig,
};
await expect(
AutoDiscoveryUtils.buildValidatedConfigFromDiscovery(serverName, discoveryResult),
).resolves.toEqual({
...expectedValidatedConfig,
hsNameIsDifferent: true,
hsName: serverName,
delegatedAuthentication: expect.objectContaining({
issuer,
account_management_actions_supported: [
"org.matrix.profile",
"org.matrix.sessions_list",
"org.matrix.session_view",
"org.matrix.session_end",
"org.matrix.cross_signing_reset",
],
account_management_uri: "https://auth.matrix.org/account/",
authorization_endpoint: "https://auth.matrix.org/auth",
registration_endpoint: "https://auth.matrix.org/registration",
token_endpoint: "https://auth.matrix.org/token",
}),
warning: null,
});
});
2023-04-05 08:49:24 +12:00
});
describe("authComponentStateForError", () => {
const error = new Error("TEST");
it("should return expected error for the registration page", () => {
expect(AutoDiscoveryUtils.authComponentStateForError(error, "register")).toMatchSnapshot();
});
});
2023-04-05 08:49:24 +12:00
});