Files
FlowReader/web/src/api/auth.ts
T
MichaelandClaude Opus 4.8 3402e53954 sécurité : correctifs XSS, SSRF, CSWSH, rate-limit et durcissement
- XSS stocké (critique) : sanitisation bluemonday sur tous les endpoints
  d'articles (List, ListByFeed, Favorites, Search, Get), pas seulement Get
- SSRF (élevé) : nouveau utils/safehttp.go (ValidateExternalURL + client durci
  via Dialer.Control, bloque IP privées/loopback/link-local/metadata,
  anti-DNS-rebinding et limite de redirections) appliqué à l'extracteur et au parser
- WebSocket CSWSH (élevé) : politique same-origin + override WS_ALLOWED_ORIGINS
- rate-limiting (moyen) : token-bucket en mémoire sur /auth/*
- token de session retiré du corps JSON (json:"-"), livré uniquement par le
  cookie HttpOnly
- cookie Secure correct derrière un reverse-proxy (X-Forwarded-Proto +
  override COOKIE_SECURE)
- admin : interdiction de supprimer son propre compte
- en-têtes de sécurité (nosniff, X-Frame-Options, Referrer-Policy,
  Permissions-Policy)

Note : backend non compilé localement (pas de toolchain Go) ; à valider via Docker.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 13:21:43 +02:00

66 lines
1.7 KiB
TypeScript

import { API_BASE, handleResponse } from './client';
export interface User {
id: string;
email: string;
is_admin: boolean;
}
export interface RegisterRequest {
email: string;
password: string;
}
export interface LoginRequest {
email: string;
password: string;
}
export interface LoginResponse {
// The session token is delivered via an HttpOnly cookie, not the JSON body.
expires_at: string;
user: User;
}
export interface RegisterResponse {
id: string;
email: string;
created_at: string;
}
export const authApi = {
async register(data: RegisterRequest): Promise<RegisterResponse> {
const response = await fetch(`${API_BASE}/auth/register`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
credentials: 'include',
body: JSON.stringify(data),
});
return handleResponse<RegisterResponse>(response);
},
async login(data: LoginRequest): Promise<LoginResponse> {
const response = await fetch(`${API_BASE}/auth/login`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
credentials: 'include',
body: JSON.stringify(data),
});
return handleResponse<LoginResponse>(response);
},
async logout(): Promise<void> {
await fetch(`${API_BASE}/auth/logout`, {
method: 'POST',
credentials: 'include',
});
},
async getMe(): Promise<User> {
const response = await fetch(`${API_BASE}/users/me`, {
credentials: 'include',
});
return handleResponse<User>(response);
},
};