Commit a5729e5c authored by BangNSK's avatar BangNSK

Merge branch 'fix/cross-site-auth-fallback' into 'develop'

fix(auth): implement localStorage bearer token fallback to resolve cross-site redirect loop

See merge request !4
parents 87194288 f3bdc18e
...@@ -30,13 +30,17 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children ...@@ -30,13 +30,17 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children
const login = async (email: string, password: string) => { const login = async (email: string, password: string) => {
const response = await api.post('/auth/login', { email, password }); const response = await api.post('/auth/login', { email, password });
if (response.data.success) { if (response.data.success) {
setUser(response.data.data.user); const { user, accessToken, refreshToken } = response.data.data;
if (accessToken) localStorage.setItem('accessToken', accessToken);
if (refreshToken) localStorage.setItem('refreshToken', refreshToken);
setUser(user);
} }
}; };
const logout = async () => { const logout = async () => {
try { try {
await api.post('/auth/logout', {}); const refreshToken = localStorage.getItem('refreshToken');
await api.post('/auth/logout', { refreshToken });
} catch (error) { } catch (error) {
console.error('Logout error', error); console.error('Logout error', error);
} finally { } finally {
...@@ -60,7 +64,12 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children ...@@ -60,7 +64,12 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children
newPassword: string; newPassword: string;
confirmPassword: string; confirmPassword: string;
}) => { }) => {
await api.post('/auth/change-password', data); const response = await api.post('/auth/change-password', data);
if (response.data.success && response.data.data) {
const { accessToken, refreshToken } = response.data.data;
if (accessToken) localStorage.setItem('accessToken', accessToken);
if (refreshToken) localStorage.setItem('refreshToken', refreshToken);
}
}; };
const isAdmin = user?.role === 'ADMIN'; const isAdmin = user?.role === 'ADMIN';
......
...@@ -49,6 +49,16 @@ const processQueue = (error?: unknown) => { ...@@ -49,6 +49,16 @@ const processQueue = (error?: unknown) => {
failedQueue = []; failedQueue = [];
}; };
api.interceptors.request.use(
(config) => {
const accessToken = localStorage.getItem('accessToken');
if (accessToken) {
config.headers.Authorization = `Bearer ${accessToken}`;
}
return config;
},
(error) => Promise.reject(error)
);
api.interceptors.response.use( api.interceptors.response.use(
(response) => response, (response) => response,
async (error) => { async (error) => {
...@@ -75,7 +85,15 @@ api.interceptors.response.use( ...@@ -75,7 +85,15 @@ api.interceptors.response.use(
isRefreshing = true; isRefreshing = true;
try { try {
await api.post('/auth/refresh', {}); const refreshToken = localStorage.getItem('refreshToken');
const refreshResponse = await api.post('/auth/refresh', { refreshToken });
if (refreshResponse.data.success && refreshResponse.data.data) {
const { accessToken: newAccess, refreshToken: newRefresh } = refreshResponse.data.data;
if (newAccess) localStorage.setItem('accessToken', newAccess);
if (newRefresh) localStorage.setItem('refreshToken', newRefresh);
}
processQueue(); processQueue();
return api(originalRequest); return api(originalRequest);
} catch (refreshError) { } catch (refreshError) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment