mirror of
https://github.com/Monadical-SAS/reflector.git
synced 2025-12-21 04:39:06 +00:00
fix: authentication flow with React Query migration
- Fix middleware management in apiClient to properly handle auth tokens - Update ApiAuthProvider to correctly configure base URL and auth - Add missing NextAuth API route handler at app/api/auth/[...nextauth]/route.ts - Remove middleware ejection attempts (not supported by openapi-fetch) - Use global variables to store current auth token and API URL - Setup middleware once on initialization instead of repeatedly adding This fixes the login/logout flow that was broken after migrating from the useApi compatibility layer to native React Query hooks.
This commit is contained in:
6
www/app/api/auth/[...nextauth]/route.ts
Normal file
6
www/app/api/auth/[...nextauth]/route.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import NextAuth from "next-auth";
|
||||||
|
import { authOptions } from "../../../lib/auth";
|
||||||
|
|
||||||
|
const handler = NextAuth(authOptions);
|
||||||
|
|
||||||
|
export { handler as GET, handler as POST };
|
||||||
@@ -1,33 +1,58 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { useEffect, useContext } from "react";
|
import { useEffect, useContext, useRef } from "react";
|
||||||
import { client, configureApiAuth } from "./apiClient";
|
import { client, configureApiAuth } from "./apiClient";
|
||||||
import useSessionAccessToken from "./useSessionAccessToken";
|
import useSessionAccessToken from "./useSessionAccessToken";
|
||||||
import { DomainContext } from "../domainContext";
|
import { DomainContext } from "../domainContext";
|
||||||
|
|
||||||
|
// Store the current API URL globally
|
||||||
|
let currentApiUrl: string | null = null;
|
||||||
|
|
||||||
|
// Set up base URL middleware once
|
||||||
|
const baseUrlMiddlewareSetup = () => {
|
||||||
|
client.use({
|
||||||
|
onRequest({ request }) {
|
||||||
|
if (currentApiUrl) {
|
||||||
|
// Update the base URL for all requests
|
||||||
|
const url = new URL(request.url);
|
||||||
|
const apiUrl = new URL(currentApiUrl);
|
||||||
|
url.protocol = apiUrl.protocol;
|
||||||
|
url.host = apiUrl.host;
|
||||||
|
url.port = apiUrl.port;
|
||||||
|
return new Request(url.toString(), request);
|
||||||
|
}
|
||||||
|
return request;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Initialize base URL middleware once
|
||||||
|
if (typeof window !== "undefined") {
|
||||||
|
baseUrlMiddlewareSetup();
|
||||||
|
}
|
||||||
|
|
||||||
export function ApiAuthProvider({ children }: { children: React.ReactNode }) {
|
export function ApiAuthProvider({ children }: { children: React.ReactNode }) {
|
||||||
const { accessToken } = useSessionAccessToken();
|
const { accessToken } = useSessionAccessToken();
|
||||||
const { api_url } = useContext(DomainContext);
|
const { api_url } = useContext(DomainContext);
|
||||||
|
const initialized = useRef(false);
|
||||||
|
|
||||||
|
// Initialize middleware once on client side
|
||||||
|
useEffect(() => {
|
||||||
|
if (!initialized.current && typeof window !== "undefined") {
|
||||||
|
baseUrlMiddlewareSetup();
|
||||||
|
initialized.current = true;
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// Configure base URL
|
// Update the global API URL
|
||||||
if (api_url) {
|
currentApiUrl = api_url;
|
||||||
client.use({
|
}, [api_url]);
|
||||||
onRequest({ request }) {
|
|
||||||
// Update the base URL for all requests
|
|
||||||
const url = new URL(request.url);
|
|
||||||
const apiUrl = new URL(api_url);
|
|
||||||
url.protocol = apiUrl.protocol;
|
|
||||||
url.host = apiUrl.host;
|
|
||||||
url.port = apiUrl.port;
|
|
||||||
return new Request(url.toString(), request);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
// Configure authentication
|
// Configure authentication
|
||||||
configureApiAuth(accessToken);
|
configureApiAuth(accessToken);
|
||||||
}, [accessToken, api_url]);
|
}, [accessToken]);
|
||||||
|
|
||||||
return <>{children}</>;
|
return <>{children}</>;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,16 +22,22 @@ export const client = createClient<paths>({
|
|||||||
// Create the React Query client wrapper
|
// Create the React Query client wrapper
|
||||||
export const $api = createFetchClient<paths>(client);
|
export const $api = createFetchClient<paths>(client);
|
||||||
|
|
||||||
// Configure authentication
|
// Store the current auth token
|
||||||
|
let currentAuthToken: string | null | undefined = null;
|
||||||
|
|
||||||
|
// Set up authentication middleware once
|
||||||
|
client.use({
|
||||||
|
onRequest({ request }) {
|
||||||
|
if (currentAuthToken) {
|
||||||
|
request.headers.set("Authorization", `Bearer ${currentAuthToken}`);
|
||||||
|
}
|
||||||
|
return request;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Configure authentication by updating the token
|
||||||
export const configureApiAuth = (token: string | null | undefined) => {
|
export const configureApiAuth = (token: string | null | undefined) => {
|
||||||
if (token) {
|
currentAuthToken = token;
|
||||||
client.use({
|
|
||||||
onRequest({ request }) {
|
|
||||||
request.headers.set("Authorization", `Bearer ${token}`);
|
|
||||||
return request;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Export typed hooks for convenience
|
// Export typed hooks for convenience
|
||||||
|
|||||||
Reference in New Issue
Block a user