reworked html serving, added new permissions for api/auth, updated adapters

This commit is contained in:
dswbx
2024-11-23 11:21:09 +01:00
parent 6077f0e64f
commit 2433833ad0
30 changed files with 418 additions and 298 deletions

View File

@@ -1,4 +1,6 @@
import { createContext, useContext, useEffect, useRef, useState } from "react";
import { notifications } from "@mantine/notifications";
import { getDefaultConfig, getDefaultSchema } from "modules/ModuleManager";
import { createContext, startTransition, useContext, useEffect, useRef, useState } from "react";
import type { ModuleConfigs, ModuleSchemas } from "../../modules";
import { useClient } from "./ClientProvider";
import { type TSchemaActions, getSchemaActions } from "./schema/actions";
@@ -22,18 +24,47 @@ export function BkndProvider({
children
}: { includeSecrets?: boolean; children: any }) {
const [withSecrets, setWithSecrets] = useState<boolean>(includeSecrets);
const [schema, setSchema] = useState<BkndContext>();
const [schema, setSchema] =
useState<Pick<BkndContext, "version" | "schema" | "config" | "permissions">>();
const [fetched, setFetched] = useState(false);
const errorShown = useRef<boolean>();
const client = useClient();
async function fetchSchema(_includeSecrets: boolean = false) {
if (withSecrets) return;
const { body } = await client.api.system.readSchema({
const { body, res } = await client.api.system.readSchema({
config: true,
secrets: _includeSecrets
});
console.log("--schema fetched", body);
setSchema(body as any);
setWithSecrets(_includeSecrets);
if (!res.ok) {
if (errorShown.current) return;
errorShown.current = true;
notifications.show({
title: "Failed to fetch schema",
// @ts-ignore
message: body.error,
color: "red",
position: "top-right",
autoClose: false,
withCloseButton: true
});
}
const schema = res.ok
? body
: ({
version: 0,
schema: getDefaultSchema(),
config: getDefaultConfig(),
permissions: []
} as any);
startTransition(() => {
setSchema(schema);
setWithSecrets(_includeSecrets);
setFetched(true);
});
}
async function requireSecrets() {
@@ -46,8 +77,8 @@ export function BkndProvider({
fetchSchema(includeSecrets);
}, []);
if (!schema?.schema) return null;
const app = new AppReduced(schema.config as any);
if (!fetched || !schema) return null;
const app = new AppReduced(schema?.config as any);
const actions = getSchemaActions({ client, setSchema });
@@ -64,20 +95,3 @@ export function useBknd({ withSecrets }: { withSecrets?: boolean } = {}): BkndCo
return ctx;
}
/*
type UseSchemaForType<Key extends keyof ModuleSchemas> = {
version: number;
schema: ModuleSchemas[Key];
config: ModuleConfigs[Key];
};
export function useSchemaFor<Key extends keyof ModuleConfigs>(module: Key): UseSchemaForType<Key> {
//const app = useApp();
const { version, schema, config } = useSchema();
return {
version,
schema: schema[module],
config: config[module]
};
}*/

View File

@@ -82,11 +82,11 @@ export const useAuth = (options?: { baseUrl?: string }): UseAuth => {
};
};
export const useAuthStrategies = (options?: { baseUrl?: string }): {
strategies: AppAuthSchema["strategies"];
type AuthStrategyData = Pick<AppAuthSchema, "strategies" | "basepath">;
export const useAuthStrategies = (options?: { baseUrl?: string }): Partial<AuthStrategyData> & {
loading: boolean;
} => {
const [strategies, setStrategies] = useState<AppAuthSchema["strategies"]>();
const [data, setData] = useState<AuthStrategyData>();
const ctxBaseUrl = useBaseUrl();
const api = new Api({
host: options?.baseUrl ? options?.baseUrl : ctxBaseUrl,
@@ -98,10 +98,10 @@ export const useAuthStrategies = (options?: { baseUrl?: string }): {
const res = await api.auth.strategies();
console.log("res", res);
if (res.res.ok) {
setStrategies(res.body.strategies);
setData(res.body);
}
})();
}, [options?.baseUrl]);
return { strategies, loading: !strategies };
return { strategies: data?.strategies, basepath: data?.basepath, loading: !data };
};

View File

@@ -50,14 +50,18 @@ export class AppQueryClient {
return this.api.getAuthState();
},
verify: async () => {
console.log("verifiying");
const res = await this.api.auth.me();
console.log("verifying result", res);
if (!res.res.ok) {
try {
//console.log("verifiying");
const res = await this.api.auth.me();
//console.log("verifying result", res);
if (!res.res.ok || !res.body.user) {
throw new Error();
}
this.api.markAuthVerified(true);
} catch (e) {
this.api.markAuthVerified(false);
this.api.updateToken(undefined);
} else {
this.api.markAuthVerified(true);
}
}
};

View File

@@ -8,6 +8,7 @@ export type AppType = ReturnType<App["toJSON"]>;
/**
* Reduced version of the App class for frontend use
* @todo: remove this class
*/
export class AppReduced {
// @todo: change to record
@@ -16,7 +17,7 @@ export class AppReduced {
private _flows: Flow[] = [];
constructor(protected appJson: AppType) {
console.log("received appjson", appJson);
//console.log("received appjson", appJson);
this._entities = Object.entries(this.appJson.data.entities ?? {}).map(([name, entity]) => {
return AppData.constructEntity(name, entity);

View File

@@ -25,7 +25,7 @@ export function AuthLogin() {
//console.log("search", token, "/api/auth/google?redirect=" + window.location.href);
const auth = useAuth();
const { strategies, loading } = useAuthStrategies();
const { strategies, basepath, loading } = useAuthStrategies();
const [error, setError] = useState<string | null>(null);
useEffect(() => {
@@ -92,7 +92,7 @@ export function AuthLogin() {
variant="outline"
className="justify-center"
onClick={() => {
window.location.href = `/api/auth/${name}/login?redirect=${window.location.href}`;
window.location.href = `${basepath}/${name}/login?redirect=${window.location.href}`;
}}
>
Continue with {ucFirstAllSnakeToPascalWithSpaces(oauth.name)}