Frontend: - Creiez frontend/lib/auth.ts cu saveToken, getToken, getAuthHeader, clearAuth - Modific api.ts: axiosInstance cu interceptor Bearer token + 401 → /login redirect - Modific login page: salveaza JWT token din response Backend: - [H-02] Integrez slowapi rate limiting: 10 req/minute pe /items/extract-label - [M-01] CORS: ALLOWED_ORIGINS din env (dev fallback: localhost:3000, localhost:3002) - [C-01] JWT_SECRET_KEY din env (dev fallback: ephemeral key) docker-compose.yml: - Adaug ALLOWED_ORIGINS env var (dev: localhost) - Adaug JWT_SECRET_KEY env var cu fallback warning Status: - ✅ JWT backend: complet - ✅ JWT frontend: token save + attach + 401 handling - ✅ Rate limiting: 10/min pe extract-label - ✅ CORS: configurable via env Gata pentru dev + testing local. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
80 lines
1.6 KiB
TypeScript
80 lines
1.6 KiB
TypeScript
/**
|
|
* [C-01] JWT Authentication Utilities
|
|
* Handle token storage, retrieval, and expiration
|
|
*/
|
|
|
|
const TOKEN_KEY = 'inventory_token';
|
|
const USER_KEY = 'inventory_user';
|
|
|
|
export interface AuthToken {
|
|
access_token: string;
|
|
token_type: string;
|
|
user_id: number;
|
|
username: string;
|
|
role: string;
|
|
}
|
|
|
|
export interface AuthUser {
|
|
id: number;
|
|
username: string;
|
|
role: string;
|
|
}
|
|
|
|
/**
|
|
* Save JWT token to localStorage
|
|
*/
|
|
export const saveToken = (token: AuthToken): void => {
|
|
localStorage.setItem(TOKEN_KEY, token.access_token);
|
|
localStorage.setItem(USER_KEY, JSON.stringify({
|
|
id: token.user_id,
|
|
username: token.username,
|
|
role: token.role
|
|
}));
|
|
};
|
|
|
|
/**
|
|
* Get JWT token from localStorage
|
|
*/
|
|
export const getToken = (): string | null => {
|
|
if (typeof window === 'undefined') return null;
|
|
return localStorage.getItem(TOKEN_KEY);
|
|
};
|
|
|
|
/**
|
|
* Get current user info from localStorage
|
|
*/
|
|
export const getCurrentUser = (): AuthUser | null => {
|
|
if (typeof window === 'undefined') return null;
|
|
const userJson = localStorage.getItem(USER_KEY);
|
|
if (!userJson) return null;
|
|
try {
|
|
return JSON.parse(userJson);
|
|
} catch {
|
|
return null;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Check if user is authenticated (token exists)
|
|
*/
|
|
export const isAuthenticated = (): boolean => {
|
|
return !!getToken();
|
|
};
|
|
|
|
/**
|
|
* Clear token and user data (logout)
|
|
*/
|
|
export const clearAuth = (): void => {
|
|
localStorage.removeItem(TOKEN_KEY);
|
|
localStorage.removeItem(USER_KEY);
|
|
};
|
|
|
|
/**
|
|
* Get Bearer token for API requests
|
|
*/
|
|
export const getAuthHeader = (): { Authorization: string } | {} => {
|
|
const token = getToken();
|
|
if (!token) return {};
|
|
return { Authorization: `Bearer ${token}` };
|
|
};
|