Use relay and refacto public trust center

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
This commit is contained in:
Sacha Al Himdani
2025-08-20 23:34:50 +02:00
parent 5db9b9f787
commit d31f611e63
19 changed files with 982 additions and 498 deletions

View File

@@ -8,6 +8,7 @@ import {
import type { PropsWithChildren } from "react";
import { RelayEnvironmentProvider } from "react-relay";
import { createContext, useContext, useState, useRef } from "react";
import { buildEndpoint } from "./RelayProviders";
export class TrustCenterError extends Error {
@@ -17,7 +18,22 @@ export class TrustCenterError extends Error {
}
}
const fetchTrustRelay: FetchFunction = async (request, variables) => {
type TrustAuthContextType = {
isAuthenticated: boolean;
setAuthenticated: (auth: boolean) => void;
};
const TrustAuthContext = createContext<TrustAuthContextType | null>(null);
export function useTrustAuth() {
const context = useContext(TrustAuthContext);
if (!context) {
throw new Error('useTrustAuth must be used within a TrustRelayProvider');
}
return context;
}
const createFetchTrustRelay = (setAuthenticated: (auth: boolean) => void): FetchFunction => async (request, variables) => {
const requestInit: RequestInit = {
method: "POST",
headers: {
@@ -25,7 +41,7 @@ const fetchTrustRelay: FetchFunction = async (request, variables) => {
"application/graphql-response+json; charset=utf-8, application/json; charset=utf-8",
"Content-Type": "application/json",
},
credentials: "include", // Include cookies for authentication
credentials: "include",
body: JSON.stringify({
operationName: request.name,
query: request.text,
@@ -44,37 +60,58 @@ const fetchTrustRelay: FetchFunction = async (request, variables) => {
const json = await response.json();
if (json.errors) {
throw new TrustCenterError(
`Error fetching GraphQL query '${
request.name
}' with variables '${JSON.stringify(variables)}': ${JSON.stringify(
json.errors
)}`
if (json.errors?.length > 0) {
const hasAccessDeniedErrors = json.errors.some((error: any) =>
error.message.toLowerCase().includes("access denied") ||
error.message.toLowerCase().includes("unauthorized") ||
error.extensions?.code === "UNAUTHENTICATED"
);
if (hasAccessDeniedErrors) {
setAuthenticated(false);
} else {
throw new TrustCenterError(
`Error fetching GraphQL query '${
request.name
}' with variables '${JSON.stringify(variables)}': ${JSON.stringify(
json.errors
)}`
);
}
} else {
setAuthenticated(true);
}
return json;
};
const trustSource = new RecordSource();
const trustStore = new Store(trustSource, {
queryCacheExpirationTime: 5 * 60 * 1000, // 5 minutes for trust center content
gcReleaseBufferSize: 10,
});
export const trustRelayEnvironment = new Environment({
network: Network.create(fetchTrustRelay),
store: trustStore,
});
/**
* Provider for trust center Relay environment (public API)
*/
export function TrustRelayProvider({ children }: PropsWithChildren) {
const [isAuthenticated, setIsAuthenticated] = useState(true);
const environmentRef = useRef<Environment | null>(null);
if (!environmentRef.current) {
const trustSource = new RecordSource();
const trustStore = new Store(trustSource, {
queryCacheExpirationTime: 5 * 60 * 1000, // 5 minutes
gcReleaseBufferSize: 10,
});
environmentRef.current = new Environment({
network: Network.create(createFetchTrustRelay(setIsAuthenticated)),
store: trustStore,
});
}
const authContextValue: TrustAuthContextType = {
isAuthenticated,
setAuthenticated: setIsAuthenticated,
};
return (
<RelayEnvironmentProvider environment={trustRelayEnvironment}>
{children}
</RelayEnvironmentProvider>
<TrustAuthContext.Provider value={authContextValue}>
<RelayEnvironmentProvider environment={environmentRef.current}>
{children}
</RelayEnvironmentProvider>
</TrustAuthContext.Provider>
);
}