Phase 1 du portage mobile (#39) : purement additif côté navigateur, qui
continue d'utiliser le cookie `session` httpOnly inchangé.
- `POST /auth/login` et `POST /auth/signup` renvoient aussi le JWT dans le
corps de la réponse (`AuthResponse` = `SafeUserProfile` + `token`), en
plus de poser le cookie. Un client dont l'origine ne peut pas recevoir
un cookie `SameSite=Lax` (WebView Capacitor) le stocke et le renvoie.
- `requireAuth` lit le cookie en priorité, puis se rabat sur un en-tête
`Authorization: Bearer <jwt>` quand le cookie est absent. Les deux
mécanismes coexistent, aucun n'est retiré.
- `apps/web` : `ApiClient` gagne une abstraction `TokenStore`
(`get`/`set`/`clear`) ; l'implémentation par défaut est un no-op
navigateur (le cookie fait tout). `_request` ajoute l'en-tête
`Authorization` quand un jeton existe ; `login`/`signup` le stockent,
`logout`/`deleteAccount` l'effacent. `setTokenStore` est le point
d'injection de la version Capacitor (`@capacitor/preferences`), branchée
en phase 2 quand la dépendance sera ajoutée.
Tests Mocha : `requireAuth` authentifie via l'en-tête `Authorization` sans
cookie, rejette un jeton Bearer invalide ou un schéma non-Bearer ;
`login`/`signup` exposent bien le jeton dans le corps.
Refs #39
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>