Backend: - Add Literal types for status/priority fields (project_task, todo, project schemas) - Add AccentColor Literal validation to prevent CSS injection (settings schema) - Add PIN max-length (72 char bcrypt limit) validation - Fix event date filtering to use correct range overlap logic - Add revocation check to auth_status endpoint for consistency - Config: env-aware SECRET_KEY fail-fast, configurable COOKIE_SECURE Frontend: - Add withCredentials to axios for cross-origin cookie support - Replace .toISOString() with local date formatter in DashboardPage - Replace `as any` casts with proper indexed type access in forms - Nginx: add CSP, Referrer-Policy headers; remove deprecated X-XSS-Protection - Nginx: duplicate security headers in static asset location block Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
31 lines
749 B
TypeScript
31 lines
749 B
TypeScript
import axios from 'axios';
|
|
|
|
const api = axios.create({
|
|
baseURL: '/api',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
withCredentials: true,
|
|
});
|
|
|
|
api.interceptors.response.use(
|
|
(response) => response,
|
|
(error) => {
|
|
if (error.response?.status === 401) {
|
|
window.location.href = '/login';
|
|
}
|
|
return Promise.reject(error);
|
|
}
|
|
);
|
|
|
|
export function getErrorMessage(error: unknown, fallback: string): string {
|
|
if (axios.isAxiosError(error) && error.response?.data?.detail) {
|
|
const detail = error.response.data.detail;
|
|
if (typeof detail === 'string') return detail;
|
|
if (Array.isArray(detail)) return detail.map((d: { msg?: string }) => d.msg || '').join(', ');
|
|
}
|
|
return fallback;
|
|
}
|
|
|
|
export default api;
|