fix auth refresh endpoint and quiet expected 401 on profile check #50

Merged
admin merged 1 commits from bugfix/getprofile-error into master 2026-06-26 18:01:16 +03:30
3 changed files with 52 additions and 3 deletions

View File

@@ -11,6 +11,7 @@ import {
HttpStatus,
Get,
Patch,
UnauthorizedException,
} from '@nestjs/common';
import type { Response } from 'express';
import {
@@ -173,6 +174,33 @@ export class AuthController {
);
}
// =========================
// REFRESH
// =========================
@Post('refresh')
@HttpCode(HttpStatus.OK)
@ApiOperation({ summary: 'Refresh access token using refresh cookie' })
@ApiResponse({ status: 200, description: 'Access token refreshed' })
@ApiUnauthorizedResponse({ description: 'Invalid or missing refresh token' })
async refresh(@Req() req, @Res({ passthrough: true }) res: Response) {
const refreshToken = req?.cookies?.refreshToken;
if (!refreshToken) {
throw new UnauthorizedException('Refresh token not found');
}
const result = await this.authService.refreshToken(refreshToken);
this.setAccessToken(res, result.data.accessToken);
return {
success: true,
data: {
accessToken: result.data.accessToken,
},
};
}
// =========================
// LOGOUT
// =========================

View File

@@ -26,6 +26,18 @@ function isPublicInvitationRequest(url: string | undefined): boolean {
);
}
/** Session bootstrap / auth endpoints where 401 means "not logged in", not "retry refresh". */
function shouldSkipRefreshRetry(url: string | undefined): boolean {
if (!url) return false;
return (
url.includes('/auth/profile') ||
url.includes('/auth/refresh') ||
url.includes('/auth/login') ||
url.includes('/auth/register') ||
url.includes('/auth/logout')
);
}
// ❌ REMOVE request interceptor completely (no Authorization header)
// ✅ Response interceptor
@@ -37,7 +49,8 @@ apiClient.interceptors.response.use(
if (
error.response?.status === 401 &&
!originalRequest._retry &&
!isPublicInvitationRequest(originalRequest.url)
!isPublicInvitationRequest(originalRequest.url) &&
!shouldSkipRefreshRetry(originalRequest.url)
) {
originalRequest._retry = true;

View File

@@ -107,8 +107,16 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
setCurrentOrganization(null);
}
}
} catch (err) {
console.error('Auth check failed:', err);
} catch (err: unknown) {
const status =
(err as { statusCode?: number })?.statusCode ??
(err as { response?: { status?: number } })?.response?.status;
// 401 on profile is expected when there is no session — not an application error.
if (status !== 401) {
console.error('Auth check failed:', err);
}
// Only clear state — DO NOT redirect here
setUser(null);
setOrganizations([]);