reworked admin auth to use form and cookie + adjusted oauth to support API and cookie-based auth

This commit is contained in:
dswbx
2024-11-23 18:12:19 +01:00
parent f70e2b2e10
commit 824ff40133
30 changed files with 630 additions and 483 deletions

View File

@@ -1,5 +1,6 @@
import { type NotificationData, notifications } from "@mantine/notifications";
import type { ModuleConfigs } from "../../../modules";
import { ucFirst } from "core/utils";
import type { ApiResponse, ModuleConfigs } from "../../../modules";
import type { AppQueryClient } from "../utils/AppQueryClient";
export type SchemaActionsProps = {
@@ -10,25 +11,53 @@ export type SchemaActionsProps = {
export type TSchemaActions = ReturnType<typeof getSchemaActions>;
export function getSchemaActions({ client, setSchema }: SchemaActionsProps) {
const baseUrl = client.baseUrl;
const token = client.auth().state()?.token;
const api = client.api;
async function displayError(action: string, module: string, res: Response, path?: string) {
const notification_data: NotificationData = {
id: "schema-error-" + [action, module, path].join("-"),
title: `Config update failed${path ? ": " + path : ""}`,
message: "Failed to complete config update",
color: "red",
async function handleConfigUpdate(
action: string,
module: string,
res: ApiResponse,
path?: string
): Promise<boolean> {
const base: Partial<NotificationData> = {
id: "schema-" + [action, module, path].join("-"),
position: "top-right",
withCloseButton: true,
autoClose: false
autoClose: 3000
};
try {
const { error } = (await res.json()) as any;
notifications.show({ ...notification_data, message: error });
} catch (e) {
notifications.show(notification_data);
if (res.res.ok && res.body.success) {
console.log("update config", action, module, path, res.body);
if (res.body.success) {
setSchema((prev) => {
if (!prev) return prev;
return {
...prev,
config: {
...prev.config,
[module]: res.body.config
}
};
});
}
notifications.show({
...base,
title: `Config updated: ${ucFirst(module)}`,
color: "blue",
message: `Operation ${action.toUpperCase()} at ${module}${path ? "." + path : ""}`
});
return true;
}
notifications.show({
...base,
title: `Config Update failed: ${ucFirst(module)}${path ? "." + path : ""}`,
color: "red",
withCloseButton: true,
autoClose: false,
message: res.body.error ?? "Failed to complete config update"
});
return false;
}
return {
@@ -37,183 +66,39 @@ export function getSchemaActions({ client, setSchema }: SchemaActionsProps) {
value: ModuleConfigs[Module],
force?: boolean
) => {
const res = await fetch(
`${baseUrl}/api/system/config/set/${module}?force=${force ? 1 : 0}`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`
},
body: JSON.stringify(value)
}
);
if (res.ok) {
const data = (await res.json()) as any;
console.log("update config set", module, data);
if (data.success) {
setSchema((prev) => {
if (!prev) return prev;
return {
...prev,
config: {
...prev.config,
[module]: data.config
}
};
});
}
return data.success;
} else {
await displayError("set", module, res);
}
return false;
const res = await api.system.setConfig(module, value, force);
return await handleConfigUpdate("set", module, res);
},
patch: async <Module extends keyof ModuleConfigs>(
module: keyof ModuleConfigs,
path: string,
value: any
): Promise<boolean> => {
const res = await fetch(`${baseUrl}/api/system/config/patch/${module}/${path}`, {
method: "PATCH",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`
},
body: JSON.stringify(value)
});
if (res.ok) {
const data = (await res.json()) as any;
console.log("update config patch", module, path, data);
if (data.success) {
setSchema((prev) => {
if (!prev) return prev;
return {
...prev,
config: {
...prev.config,
[module]: data.config
}
};
});
}
return data.success;
} else {
await displayError("patch", module, res, path);
}
return false;
const res = await api.system.patchConfig(module, path, value);
return await handleConfigUpdate("patch", module, res, path);
},
overwrite: async <Module extends keyof ModuleConfigs>(
module: keyof ModuleConfigs,
path: string,
value: any
) => {
const res = await fetch(`${baseUrl}/api/system/config/overwrite/${module}/${path}`, {
method: "PUT",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`
},
body: JSON.stringify(value)
});
if (res.ok) {
const data = (await res.json()) as any;
console.log("update config overwrite", module, path, data);
if (data.success) {
setSchema((prev) => {
if (!prev) return prev;
return {
...prev,
config: {
...prev.config,
[module]: data.config
}
};
});
}
return data.success;
} else {
await displayError("overwrite", module, res, path);
}
return false;
const res = await api.system.overwriteConfig(module, path, value);
return await handleConfigUpdate("overwrite", module, res, path);
},
add: async <Module extends keyof ModuleConfigs>(
module: keyof ModuleConfigs,
path: string,
value: any
) => {
const res = await fetch(`${baseUrl}/api/system/config/add/${module}/${path}`, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`
},
body: JSON.stringify(value)
});
if (res.ok) {
const data = (await res.json()) as any;
console.log("update config add", module, data);
if (data.success) {
setSchema((prev) => {
if (!prev) return prev;
return {
...prev,
config: {
...prev.config,
[module]: data.config
}
};
});
}
return data.success;
} else {
await displayError("add", module, res, path);
}
return false;
const res = await api.system.addConfig(module, path, value);
return await handleConfigUpdate("add", module, res, path);
},
remove: async <Module extends keyof ModuleConfigs>(
module: keyof ModuleConfigs,
path: string
) => {
const res = await fetch(`${baseUrl}/api/system/config/remove/${module}/${path}`, {
method: "DELETE",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`
}
});
if (res.ok) {
const data = (await res.json()) as any;
console.log("update config remove", module, data);
if (data.success) {
setSchema((prev) => {
if (!prev) return prev;
return {
...prev,
config: {
...prev.config,
[module]: data.config
}
};
});
}
return data.success;
} else {
await displayError("remove", module, res, path);
}
return false;
const res = await api.system.removeConfig(module, path);
return await handleConfigUpdate("remove", module, res, path);
}
};
}