mirror of
https://github.com/chillpadclub/bedolaga-cabinet.git
synced 2026-07-30 02:23:47 +00:00
@@ -291,7 +291,17 @@ export const authApi = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
pollDeepLinkToken: async (token: string): Promise<AuthResponse> => {
|
pollDeepLinkToken: async (token: string): Promise<AuthResponse> => {
|
||||||
const response = await apiClient.post<AuthResponse>('/cabinet/auth/deeplink/poll', { token });
|
// validateStatus: only treat 200 as success.
|
||||||
|
// Server returns 202 for "pending" and 410 for "expired" —
|
||||||
|
// these must reject so the polling catch-block can handle them.
|
||||||
|
// Without this, axios resolves on 202 (it's 2xx), causing
|
||||||
|
// loginWithDeepLink to set undefined tokens + isAuthenticated=true,
|
||||||
|
// which triggers checkAdminStatus() → 401 → safeRedirectToLogin() → infinite reload.
|
||||||
|
const response = await apiClient.post<AuthResponse>(
|
||||||
|
'/cabinet/auth/deeplink/poll',
|
||||||
|
{ token },
|
||||||
|
{ validateStatus: (status) => status === 200 },
|
||||||
|
);
|
||||||
return response.data;
|
return response.data;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -71,6 +71,8 @@ const AUTH_ENDPOINTS = [
|
|||||||
'/cabinet/auth/oauth/',
|
'/cabinet/auth/oauth/',
|
||||||
'/cabinet/auth/merge/',
|
'/cabinet/auth/merge/',
|
||||||
'/cabinet/auth/account/link/server-complete',
|
'/cabinet/auth/account/link/server-complete',
|
||||||
|
'/cabinet/auth/deeplink/',
|
||||||
|
'/cabinet/auth/login/auto',
|
||||||
'/cabinet/landing/',
|
'/cabinet/landing/',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -74,6 +74,9 @@ export const useAuthStore = create<AuthState>()(
|
|||||||
clearCampaignBonus: () => set({ pendingCampaignBonus: null }),
|
clearCampaignBonus: () => set({ pendingCampaignBonus: null }),
|
||||||
|
|
||||||
setTokens: (accessToken, refreshToken) => {
|
setTokens: (accessToken, refreshToken) => {
|
||||||
|
if (!accessToken || !refreshToken) {
|
||||||
|
throw new Error('Invalid tokens: cannot store empty credentials');
|
||||||
|
}
|
||||||
tokenStorage.setTokens(accessToken, refreshToken);
|
tokenStorage.setTokens(accessToken, refreshToken);
|
||||||
set({
|
set({
|
||||||
accessToken,
|
accessToken,
|
||||||
@@ -321,6 +324,9 @@ export const useAuthStore = create<AuthState>()(
|
|||||||
|
|
||||||
loginWithDeepLink: async (token) => {
|
loginWithDeepLink: async (token) => {
|
||||||
const response = await authApi.pollDeepLinkToken(token);
|
const response = await authApi.pollDeepLinkToken(token);
|
||||||
|
if (!response.access_token || !response.refresh_token) {
|
||||||
|
throw new Error('Invalid auth response: missing tokens');
|
||||||
|
}
|
||||||
tokenStorage.setTokens(response.access_token, response.refresh_token);
|
tokenStorage.setTokens(response.access_token, response.refresh_token);
|
||||||
set({
|
set({
|
||||||
accessToken: response.access_token,
|
accessToken: response.access_token,
|
||||||
|
|||||||
@@ -258,6 +258,8 @@ export function getAndClearReturnUrl(): string | null {
|
|||||||
|
|
||||||
export function safeRedirectToLogin(): void {
|
export function safeRedirectToLogin(): void {
|
||||||
if (typeof window !== 'undefined') {
|
if (typeof window !== 'undefined') {
|
||||||
|
// Guard: don't redirect if already on /login to prevent infinite reload loops
|
||||||
|
if (window.location.pathname === '/login') return;
|
||||||
saveReturnUrl();
|
saveReturnUrl();
|
||||||
window.location.href = '/login';
|
window.location.href = '/login';
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user