Repository navigation
feat(admin): poser le socle, la connexion, les rôles et le journal - #363
Nascimento95 wants to merge 24 commits into
Conversation
|
Trois corrections poussées après le premier passage de la CI :
|
|
Revue du 13 octobre 2026 — session d'Ilan, relecture par un agent du code au commit Contrôle d'accès : rien à redire. Le rôle est relu en base à chaque appel, le second facteur est exigé par l'API hors émulateur, l'émulateur est refusé en production, pas de redirection ouverte par À faire avant fusion
Écarts mineurs
Durcissements conseillés, non bloquants
En attente d'une décision d'Ilan : la fermeture de #52 alors que le retour à la connexion après 12 h, la nouvelle vérification avant une action sensible et la preuve du journal ne sont pas faits ; la façon de nommer le premier admin en staging puis en production. |
3bdf63e to
03d6216
Compare
|
Réponse à la revue du 13 octobre, point par point. Branche rebasée sur À faire avant fusion
Écarts mineurs (
Durcissements (
Vérification humaine : Marco a testé le 2026-10-14 en local (base locale, connexion par le Firebase de staging, commit
Toujours en attente de ta décision : la fermeture de #52 sans la nouvelle vérification avant une action sensible (aucune n'existe encore dans le socle) et sans la preuve du journal ; la façon de nommer le premier admin en staging puis en production. |
|
Complément à la vérification humaine : Marco a aussi testé le 2026-10-14 en local, au commit |
03d6216 to
a850abb
Compare
|
Branche remise à jour sur Autres adaptations au rebase, sans changement de comportement :
|
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…the tokens Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…urn to Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…d the API Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…account Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…_suspended codes Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…account Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… counters Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ed account Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…oasts Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…d ask for a reason Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…at typecheck Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
next 16.3.6 has a high advisory (GHSA-cjq9-62q9-8jv4), and the firebase meta-package pulls @grpc/grpc-js through Firestore (GHSA-m9gg-hp2v-232j). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…y provider Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…087) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…dmin tests Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… deleted account Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…TP factor only Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…team Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
a850abb to
b181be3
Compare
|
Branche remise à jour sur Autres adaptations au rebase, sans changement de comportement : la garde d'authentification reprend la version de |
|
Chef de projet (16/10/2026) : Ilan désigne Paul (@PaulThiberville) comme relecteur des PR de Marco. Ordre proposé : PR #363 (#52) d'abord, puis la pile du site depuis PR #256 (PR #270 à #276), puis les PR empilées de l'admin (#365, #398, #479, #499, #500, #501). Paul traite aussi les PR Dependabot #252 à #255 (fusionner ou fermer). |
Résultat et problème
L'admin web n'existait pas (
apps/adminétait une coquille vide). Cette PR pose son socle : app Next.js, connexion, rôles, coque, journal des actions, compteurs et composants communs.Les quatre critères d'acceptation sont tenus. La double authentification a été ajoutée le 2026-10-13, une fois le projet
widoo-stagingconfiguré (détail sur le ticket).Ce qui est fait :
packages/shared: les 12 sections de l'admin et la matrice des rôles du wiki, source unique pour le menu et l'API ; codesmfa_requiredetaccount_suspended.packages/ui(nouveau) : thème shadcn tiré detokens.json, bouton, champs, encadré, menu, info-bulle, tableau, tri, pagination, filtre, pastille, panneau de détail, confirmation, toasts.apps/admin: socle Next.js repris des choix du site, en-têtesnoindexetno-store, connexion Google et lien par e-mail (A-01), refus d'un compte sans rôle ou suspendu, retour à la page demandée, double authentification TOTP (activation et saisie du code), coque avec menu par rôle et compteurs, état d'une liste dans l'adresse, dates relatives.apps/api: garderequireAdminSection(rôle par section, session de 12 h, second facteur), compte suspendu refusé partout, tableadmin_actionsetrecordAdminAction,GET /admin/counters.infra/admin.Dockerfile: image Cloud Run, construite et lancée en local.Limites :
isSecondFactorRequiredest faux seulement quandFIREBASE_AUTH_EMULATOR_HOSTest défini, ce que la config refuse déjà en production. Choix à valider.recordAdminActionest testé seul, son premier appelant arrive avec Construire la file de modération et ses endpoints (A-02) #53.routes.updated_aten attendantmoderation_actions(Construire la file de modération et ses endpoints (A-02) #53). Signalements, support, brouillons IA et traductions viendront avec leurs tables.tokens.json: menu 248 et 72 px, en-tête 64 px, champ 40 px, panneau 400 px, fenêtre 520 px, carte de connexion 440 px, deux tailles de texte et l'ombre flottante sont dans le preset depackages/ui, marquées « à reporter dans tokens.json », comme le fait le site.Fixes #52
Écrans : A-01, coque et modèles communs
Dépendance : #364 (environnement du build de l'admin en CI), à fusionner avant. Le site (#256) n'est pas fusionné :
.gitignore,.prettierignore,.dockerignore,eslint.config.jsetpackage.jsonreçoivent ici des lignes proches des siennes, conflits à prévoir sur la seconde PR fusionnée.Comment vérifier
En local, sans toucher au projet Firebase ni à la base de Widoo :
Se connecter crée un compte
user; lui donner un rôle dans la base locale (update users set role = 'admin' where email = '…'). Le lien de connexion par e-mail se lit danshttp://127.0.0.1:9099/emulator/v1/projects/demo-widoo/oobCodes.Testé à la main avec quatre comptes fictifs, face aux planches du wiki (Marco dans Chrome, et l'agent dans son navigateur de test) :
/moderationsans session : renvoi vers A-01, puis retour à la page demandée ;Testé par Marco le 2026-10-13, dans Chrome, admin et API en local (commit
2d93ecc) branchés sur le projet Firebasewidoo-staging, base de données locale :Non vérifié contre le vrai projet : le lien de connexion par e-mail (testé seulement avec l'émulateur), la saisie de la clé à la main à la place du QR code, et tout déploiement.
pnpm lint && pnpm typecheck && pnpm testverts en local (1 075 tests, dont 372 pour l'API)Formatage mécanique : non
Risque
Niveau : 2 — migration additive (
admin_actions, deux colonnes surusers), nouvel endpoint authentifié, garde d'accès par rôle et configuration de dépendances ; réversible et borné.Taille : cinq commits entre 400 et 460 lignes utiles, tests compris.
efb4cc5(460) et22ee626(433) : composants depackages/ui, un fichier par composant, sans découpage plus fin qui tienne debout seul.fa2a3d6(456) : fichiers de configuration du socle et leurs tests.7bad428(415) etc68d3e2(428) : écran de connexion et coque, composants d'affichage et leurs conteneurs. Fichiers générés à part : migration0015_add_admin_actions.sqlet son instantané.Revue OWASP (Top 10) :
requireAdminSectionapplique la matrice du wiki ; un compte hors équipe reçoit 403 sans rien apprendre du second facteur. L'admin ne fait que cacher. Tests :routes/admin.test.ts,admin-sections.test.ts.auth_time), second facteur TOTP exigé hors émulateur et activé avant toute entrée, compte suspendu refusé partout. Le secret TOTP n'est ni stocké ni journalisé par l'admin : il vit le temps de l'écran d'activation. Le lien de connexion ne s'ouvre que sur l'appareil qui l'a demandé, et son code quitte l'adresse après usage.return-path.test.ts).frame-ancestors 'none',noindex,no-store; l'émulateur n'est accepté qu'avec un projetdemo-*. Aucun secret : seules des valeursNEXT_PUBLIC_.admin_actionsne reçoit que des insertions, dans la transaction du changement ; l'acteur purgé laisse la ligne.Changement de configuration à relire : la règle pnpm
react-dom: '-'interdisaitreact-domdans tout le dépôt ; elle est limitée à@rnmapbox/maps, sans quoi aucune app web ne s'installe. Le lockfile du mobile bouge ; ses 269 tests passent. Le site aura le même besoin.Nouvelles dépendances :
next16.3.8 (le site est en 16.3.6, qui porte l'alerte haute GHSA-cjq9-62q9-8jv4),react-dom,tailwindcss3.4.19,autoprefixer,postcss,@next/eslint-plugin-next: mêmes choix que le site.@firebase/appet@firebase/auth: connexion Google et lien par e-mail, client officiel de Firebase Auth ; le méta-paquetfirebaseest écarté, il tire Firestore et@grpc/grpc-js(alerte haute GHSA-m9gg-hp2v-232j).@radix-ui/react-slot(1.4, la 1.5 avait moins d'un jour),react-dropdown-menu,react-tooltip,react-dialog: primitives accessibles sur lesquelles shadcn/ui est bâti ; écarté : les réécrire.class-variance-authority,clsx: variantes de composants, comme shadcn/ui ;tailwind-mergeécarté, il ne connaît pas les classes des tokens.sonner: le toast demandé par la planche.qrcode: dessine le QR code de l'activation du second facteur dans le navigateur, sans appel à un service externe ; écarté : un service d'images de QR code, qui recevrait le secret.@phosphor-icons/react: les icônes du design system, version web du paquet du mobile.Retour arrière
Le revert de la PR suffit pour le code. La migration
0015est additive : après un revert, la tableadmin_actionset les colonnesusers.suspended_atetusers.suspension_reasonrestent en base sans effet ; les supprimer demande une migration à part et perd les lignes du journal déjà écrites.🤖 Generated with Claude Code