remove unused eslint plugin, run eslint --fix, rollback node memory workaround in ci

This commit is contained in:
Aine
2025-04-05 21:37:31 +03:00
parent 738685c599
commit bac962c127
62 changed files with 1782 additions and 1502 deletions

View File

@@ -1,7 +1,7 @@
import fetchMock from "jest-fetch-mock";
import { HttpError } from "ra-core";
import authProvider from "./authProvider";
import { HttpError } from "ra-core";
fetchMock.enableMocks();
@@ -28,7 +28,7 @@ describe("authProvider", () => {
password: "secret",
});
expect(ret).toEqual({redirectTo: "/"});
expect(ret).toEqual({ redirectTo: "/" });
expect(fetch).toHaveBeenCalledWith("http://example.com/_matrix/client/v3/login", {
body: '{"device_id":null,"initial_device_display_name":"Synapse Admin","type":"m.login.password","identifier":{"type":"m.id.user","user":"@user:example.com"},"password":"secret"}',
headers: new Headers({
@@ -60,7 +60,7 @@ describe("authProvider", () => {
loginToken: "login_token",
});
expect(ret).toEqual({redirectTo: "/"});
expect(ret).toEqual({ redirectTo: "/" });
expect(fetch).toHaveBeenCalledWith("https://example.com/_matrix/client/v3/login", {
body: '{"device_id":null,"initial_device_display_name":"Synapse Admin","type":"m.login.token","token":"login_token"}',
headers: new Headers({
@@ -103,11 +103,15 @@ describe("authProvider", () => {
});
it("should reject if error.status is 401", async () => {
await expect(authProvider.checkError(new HttpError("test-error", 401, {errcode: "test-errcode", error: "test-error"}))).rejects.toBeDefined();
await expect(
authProvider.checkError(new HttpError("test-error", 401, { errcode: "test-errcode", error: "test-error" }))
).rejects.toBeDefined();
});
it("should reject if error.status is 403", async () => {
await expect(authProvider.checkError(new HttpError("test-error", 403, {errcode: "test-errcode", error: "test-error"}))).rejects.toBeDefined();
await expect(
authProvider.checkError(new HttpError("test-error", 403, { errcode: "test-errcode", error: "test-error" }))
).rejects.toBeDefined();
});
});

View File

@@ -1,9 +1,9 @@
import { AuthProvider, HttpError, Options, fetchUtils } from "react-admin";
import { MatrixError, displayError } from "../utils/error";
import { fetchAuthenticatedMedia } from "../utils/fetchMedia";
import { FetchConfig, ClearConfig, GetConfig } from "../utils/config";
import decodeURLComponent from "../utils/decodeURLComponent";
import { MatrixError, displayError } from "../utils/error";
import { fetchAuthenticatedMedia } from "../utils/fetchMedia";
const authProvider: AuthProvider = {
// called when the user attempts to log in
@@ -53,14 +53,15 @@ const authProvider: AuthProvider = {
if (!base_url) {
// there is some kind of bug with base_url being present in the form, but not submitted
// ref: https://github.com/etkecc/synapse-admin/issues/14
localStorage.removeItem("base_url")
localStorage.removeItem("base_url");
throw new Error("Homeserver URL is required.");
}
base_url = base_url.replace(/\/+$/g, "");
localStorage.setItem("base_url", base_url);
const decoded_base_url = decodeURLComponent(base_url);
let login_api_url = decoded_base_url + (accessToken ? "/_matrix/client/v3/account/whoami" : "/_matrix/client/v3/login");
const login_api_url =
decoded_base_url + (accessToken ? "/_matrix/client/v3/account/whoami" : "/_matrix/client/v3/login");
let response;
@@ -69,7 +70,7 @@ const authProvider: AuthProvider = {
// this a login with an already obtained access token, let's just validate it
options = {
headers: new Headers({
Accept: 'application/json',
Accept: "application/json",
Authorization: `Bearer ${accessToken}`,
}),
};
@@ -91,19 +92,16 @@ const authProvider: AuthProvider = {
pageToRedirectTo = "/server_status";
}
return Promise.resolve({redirectTo: pageToRedirectTo});
} catch(err) {
return Promise.resolve({ redirectTo: pageToRedirectTo });
} catch (err) {
const error = err as HttpError;
const errorStatus = error.status;
const errorBody = error.body as MatrixError;
const errMsg = !!errorBody?.errcode ? displayError(errorBody.errcode, errorStatus, errorBody.error) : displayError("M_INVALID", errorStatus, error.message);
const errMsg = errorBody?.errcode
? displayError(errorBody.errcode, errorStatus, errorBody.error)
: displayError("M_INVALID", errorStatus, error.message);
return Promise.reject(
new HttpError(
errMsg,
errorStatus,
)
);
return Promise.reject(new HttpError(errMsg, errorStatus));
}
},
getIdentity: async () => {
@@ -175,7 +173,7 @@ const authProvider: AuthProvider = {
const status = err.status;
if (status === 401 || status === 403) {
return Promise.reject({message: displayError(errorBody.errcode, status, errorBody.error)});
return Promise.reject({ message: displayError(errorBody.errcode, status, errorBody.error) });
}
return Promise.resolve();
},

View File

@@ -13,9 +13,9 @@ import {
withLifecycleCallbacks,
} from "react-admin";
import { returnMXID } from "../utils/mxid";
import { GetConfig } from "../utils/config";
import { MatrixError, displayError } from "../utils/error";
import { returnMXID } from "../utils/mxid";
const CACHED_MANY_REF: Record<string, any> = {};
@@ -37,7 +37,7 @@ const jsonClient = async (url: string, options: Options = {}) => {
const error = err as HttpError;
const errorStatus = error.status;
const errorBody = error.body as MatrixError;
const errMsg = !!errorBody?.errcode
const errMsg = errorBody?.errcode
? displayError(errorBody.errcode, errorStatus, errorBody.error)
: displayError("M_INVALID", errorStatus, error.message);
@@ -254,9 +254,7 @@ export interface UploadMediaResult {
}
export interface ExperimentalFeaturesModel {
features: {
[key: string]: boolean;
};
features: Record<string, boolean>;
}
export interface RateLimitsModel {
@@ -266,13 +264,9 @@ export interface RateLimitsModel {
export interface AccountDataModel {
account_data: {
global: {
[key: string]: object;
},
rooms: {
[key: string]: object;
};
}
global: Record<string, object>;
rooms: Record<string, object>;
};
}
export interface UsernameAvailabilityResult {
@@ -291,7 +285,7 @@ export interface ServerStatusComponent {
url: string;
icon: string;
text: string;
}
};
}
export interface ServerStatusResponse {
@@ -326,9 +320,7 @@ export interface ServerCommand {
additionalArgs?: string;
}
export interface ServerCommandsResponse {
[command: string]: ServerCommand;
}
export type ServerCommandsResponse = Record<string, ServerCommand>;
export interface SynapseDataProvider extends DataProvider {
deleteMedia: (params: DeleteMediaParams) => Promise<DeleteMediaResult>;
@@ -691,21 +683,23 @@ const baseDataProvider: SynapseDataProvider = {
const res = resourceMap[resource];
const endpoint_url = base_url + res.path;
const responses = await Promise.all(params.ids.map(id => {
// edge case: when user is external / federated, homeserver will return error, as querying external users via
// /_synapse/admin/v2/users is not allowed.
// That leads to an issue when a user is referenced (e.g., in room state datagrid) - the user cell is just empty.
// To avoid that, we fake the response with one specific field (name) which is used in the datagrid.
if (homeserver && resource === "users") {
if (!(<string>id).endsWith(homeserver)) {
const json = {
const responses = await Promise.all(
params.ids.map(id => {
// edge case: when user is external / federated, homeserver will return error, as querying external users via
// /_synapse/admin/v2/users is not allowed.
// That leads to an issue when a user is referenced (e.g., in room state datagrid) - the user cell is just empty.
// To avoid that, we fake the response with one specific field (name) which is used in the datagrid.
if (homeserver && resource === "users") {
if (!(id as string).endsWith(homeserver)) {
const json = {
name: id,
};
return Promise.resolve({ json });
};
return Promise.resolve({ json });
}
}
}
return jsonClient(`${endpoint_url}/${encodeURIComponent(id)}`);
}));
return jsonClient(`${endpoint_url}/${encodeURIComponent(id)}`);
})
);
return {
data: responses.map(({ json }) => res.map(json)),
total: responses.length,
@@ -724,8 +718,6 @@ const baseDataProvider: SynapseDataProvider = {
dir: getSearchOrder(order),
};
const homeserver = localStorage.getItem("base_url");
if (!homeserver || !(resource in resourceMap)) throw Error("Homeserver not set");
@@ -734,16 +726,16 @@ const baseDataProvider: SynapseDataProvider = {
const ref = res.reference(params.id);
const endpoint_url = `${homeserver}${ref.endpoint}?${new URLSearchParams(filterUndefined(query)).toString()}`;
let CACHE_KEY = ref.endpoint;
const CACHE_KEY = ref.endpoint;
let jsonData = [];
let total = 0;
if (CACHED_MANY_REF[CACHE_KEY]) {
jsonData = CACHED_MANY_REF[CACHE_KEY]["data"].slice(from, from + perPage);
total = CACHED_MANY_REF[CACHE_KEY]["total"];
jsonData = CACHED_MANY_REF[CACHE_KEY]["data"].slice(from, from + perPage);
total = CACHED_MANY_REF[CACHE_KEY]["total"];
} else {
const { json } = await jsonClient(endpoint_url);
jsonData = json[res.data]
jsonData = json[res.data];
total = res.total(json, from, perPage);
if (resource === "joined_rooms") {
// cache will be applied only for joined_rooms
@@ -967,9 +959,9 @@ const baseDataProvider: SynapseDataProvider = {
return json as AccountDataModel;
},
setRateLimits: async (id: Identifier, rateLimits: RateLimitsModel) => {
const filtered = Object.entries(rateLimits).
filter(([key, value]) => value !== null && value !== undefined).
reduce((obj, [key, value]) => {
const filtered = Object.entries(rateLimits)
.filter(([key, value]) => value !== null && value !== undefined)
.reduce((obj, [key, value]) => {
obj[key] = value;
return obj;
}, {});
@@ -978,7 +970,7 @@ const baseDataProvider: SynapseDataProvider = {
const endpoint_url = `${base_url}/_synapse/admin/v1/users/${encodeURIComponent(returnMXID(id))}/override_ratelimit`;
if (Object.keys(filtered).length === 0) {
await jsonClient(endpoint_url, { method: "DELETE" });
return
return;
}
await jsonClient(endpoint_url, { method: "POST", body: JSON.stringify(filtered) });
@@ -1010,7 +1002,7 @@ const baseDataProvider: SynapseDataProvider = {
throw error;
}
},
getServerRunningProcess: async (etkeAdminUrl: string, burstCache: boolean = false): Promise<ServerProcessResponse> => {
getServerRunningProcess: async (etkeAdminUrl: string, burstCache = false): Promise<ServerProcessResponse> => {
const locked_at = "";
const command = "";
@@ -1022,8 +1014,8 @@ const baseDataProvider: SynapseDataProvider = {
try {
const response = await fetch(serverURL, {
headers: {
"Authorization": `Bearer ${localStorage.getItem("access_token")}`
}
Authorization: `Bearer ${localStorage.getItem("access_token")}`,
},
});
if (!response.ok) {
@@ -1045,7 +1037,7 @@ const baseDataProvider: SynapseDataProvider = {
return { locked_at, command };
},
getServerStatus: async (etkeAdminUrl: string, burstCache: boolean = false): Promise<ServerStatusResponse> => {
getServerStatus: async (etkeAdminUrl: string, burstCache = false): Promise<ServerStatusResponse> => {
let serverURL = `${etkeAdminUrl}/status`;
if (burstCache) {
serverURL += `?time=${new Date().getTime()}`;
@@ -1054,8 +1046,8 @@ const baseDataProvider: SynapseDataProvider = {
try {
const response = await fetch(serverURL, {
headers: {
"Authorization": `Bearer ${localStorage.getItem("access_token")}`
}
Authorization: `Bearer ${localStorage.getItem("access_token")}`,
},
});
if (!response.ok) {
console.error(`Error getting server status: ${response.status} ${response.statusText}`);
@@ -1074,7 +1066,10 @@ const baseDataProvider: SynapseDataProvider = {
return { success: false, ok: false, host: "", results: [] };
},
getServerNotifications: async (serverNotificationsUrl: string, burstCache: boolean = false): Promise<ServerNotificationsResponse> => {
getServerNotifications: async (
serverNotificationsUrl: string,
burstCache = false
): Promise<ServerNotificationsResponse> => {
let serverURL = `${serverNotificationsUrl}/notifications`;
if (burstCache) {
serverURL += `?time=${new Date().getTime()}`;
@@ -1083,8 +1078,8 @@ const baseDataProvider: SynapseDataProvider = {
try {
const response = await fetch(serverURL, {
headers: {
"Authorization": `Bearer ${localStorage.getItem("access_token")}`
}
Authorization: `Bearer ${localStorage.getItem("access_token")}`,
},
});
if (!response.ok) {
console.error(`Error getting server notifications: ${response.status} ${response.statusText}`);
@@ -1113,9 +1108,9 @@ const baseDataProvider: SynapseDataProvider = {
try {
const response = await fetch(`${serverNotificationsUrl}/notifications`, {
headers: {
"Authorization": `Bearer ${localStorage.getItem("access_token")}`
Authorization: `Bearer ${localStorage.getItem("access_token")}`,
},
method: "DELETE"
method: "DELETE",
});
if (!response.ok) {
console.error(`Error deleting server notifications: ${response.status} ${response.statusText}`);
@@ -1124,7 +1119,7 @@ const baseDataProvider: SynapseDataProvider = {
const status = response.status;
if (status === 204) {
const result = { success: true }
const result = { success: true };
return result;
}
} catch (error) {
@@ -1137,8 +1132,8 @@ const baseDataProvider: SynapseDataProvider = {
try {
const response = await fetch(`${serverCommandsUrl}/commands`, {
headers: {
"Authorization": `Bearer ${localStorage.getItem("access_token")}`
}
Authorization: `Bearer ${localStorage.getItem("access_token")}`,
},
});
if (!response.ok) {
console.error(`Error fetching server commands: ${response.status} ${response.statusText}`);
@@ -1163,15 +1158,15 @@ const baseDataProvider: SynapseDataProvider = {
const endpoint_url = `${serverCommandsUrl}/commands`;
const body = {
command: command,
...additionalArgs
}
...additionalArgs,
};
const response = await fetch(endpoint_url, {
method: "POST",
body: JSON.stringify(body),
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${localStorage.getItem("access_token")}`
}
method: "POST",
body: JSON.stringify(body),
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${localStorage.getItem("access_token")}`,
},
});
if (!response.ok) {
@@ -1186,13 +1181,13 @@ const baseDataProvider: SynapseDataProvider = {
if (status === 204) {
return {
success: true,
}
};
}
return {
success: false,
}
}
};
},
};
const dataProvider = withLifecycleCallbacks(baseDataProvider, [