test(auth): cover the 401 gate on all four read routes (#12) #19
No reviewers
Labels
No labels
autopilot:pending-human
source:analyste
source:defenseur
source:human
source:medic
status:approved
status:blocked
status:in-progress
status:needs-clarification
status:needs-fix
status:ready
status:review
status:triage
type:bug
type:feature
type:infra
type:refactor
type:schema
type:security
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: maximus/vps-health-api#19
Loading…
Reference in a new issue
No description provided.
Delete branch "issue-12-auth-tests"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Ajoute
__tests__/auth.test.js— 19 tests qui verrouillent la porte d'authentification des quatre routes de lecture.Maillon 2 d'une pile chainee. Base :
issue-11-extract-metrics(PR #18), pasmain. A relire apres #18.Pourquoi maintenant
C'est un filet pose avant le refactor de routage/auth de l'issue #13, pas une tache de finition. Les 14 tests existants frappent tous
/defenseurs/findings:/health,/defenseurset/reports/scansn'avaient aucune couverture d'authentification. Sans ce filet, un cablage manque dans #13 pourrait exposer publiquement les rapports Defenseurs de tout le parc sans faire echouer un seul test.Ce que couvrent les 19 tests
Authorizationabsenttest.each)test.each)/defenseurs: token brut sans schema,bearerminuscule, schema sans tokenHEALTH_TOKENn'est pas defini, meme avec un bearer bien formePOSTdes 4 routes, + 2 cas non authentifiesPatron repris de
findings.test.js: serveurhttpreel sur port ephemere, repertoire temporaire, re-import frais deindex.jsa chaquebeforeEach.index.jsn'est pas touchegit diff origin/issue-11-extract-metricsne contient que le nouveau fichier de test. Ces tests decrivent le comportement actuel.Suite complete : 39 tests (19 auth + 14 findings + 6 health), tous verts.
Deux points a savoir
Le 404 precede l'authentification. La validation route/methode s'execute avant la verification du token (
index.js:190puis:196). Une requete sans token sur une route inconnue — ou avec une mauvaise methode sur une route existante — recoit 404, pas 401 : l'existence des routes est enumerable sans jeton. C'est le comportement actuel, encode tel quel dans deux tests nommes404 (not 401) .... Le critere de l'issue (404) est respecte ; l'ordre auth/routage, lui, n'y etait pas specifie. A garder en tete pendant #13 : si le refactor inverse l'ordre, ces deux tests virent au rouge volontairement.Chevauchement assume avec l'existant.
findings.test.jscouvre deja no-header + mauvais token sur/defenseurs/findings, ethealth.test.jsle mauvais token sur/health— 3 cellules sur 8 se recoupent. Retirer ces cellules aurait laisse une matrice trouee et manque deux criteres d'acceptation ecrits « sur les quatre routes ». La valeur du filet vient de la table complete au meme endroit. Le chevauchement est reduit a une lignetest.eachpar mode d'echec et documente en tete de fichier. Aucun test existant n'est modifie.Verification
Mutation test execute sur une copie hors depot : en neutralisant la comparaison de token, 11 des 19 tests virent au rouge. Les 8 autres (routage + fail-closed) ne dependent pas de cette ligne — attendu. Le filet mord donc bien sur la regression qu'il est cense attraper.
Resolves #12
Generated autonomously by /autopilot run of 2026-08-16
Verdict : APPROVE
Ajout de tests pur, zero ligne de production. Fige l'ordre routage -> auth avant que #20 ne reecrive le dispatch — c'est exactement le bon moment pour poser ce filet.
Verifie
CLAUDE.md.404 (not 401)figent l'invariant que #20 devra preserver.HEALTH_TOKENabsent -> 401HEALTH_TOKEN not configured).LOGTO_HEALTH_URLvers un port ferme : une auth qui s'ouvrirait ne peut pas atteindre le vrai IdP depuis les tests.Suggestions (non bloquantes)
Aucun controle positif pour
/defenseurset/reports/scans. Verifie sur les trois fichiers de test a ce maillon : rien n'affirme nulle part que ces deux routes repondent 200 avec un token valide. Un refactor qui les casserait en 401 inconditionnel laisserait toute la suite verte. Le fichier se presente comme « la matrice complete route x mode d'echec » — une matrice de modes d'echec sans cas d'ancrage ne sait pas distinguer « refuse correctement » de « refuse tout ».Le commentaire du port ferme decrit un mecanisme qui n'existe pas. « If the auth gate ever fails open, the request errors out fast » : non —
getLogtoHealth()avale toutes les erreurs et retourne{status:"down"}, donc un/healthqui s'ouvrirait repondrait 200, pas une erreur. Le test attrape quand meme la regression (il attend 401), et le port ferme reste utile pour ne pas taper le vrai IdP — c'est la justification ecrite qui est fausse, pas la garde.Couverture de methode limitee a POST. HEAD/PUT/DELETE ne sont exerces nulle part a ce maillon (#21 les ajoutera, mais pour
/hosts/<id>seulement).Revue adversariale — maillon 2/5, revu contre sa base
issue-11-extract-metrics.Mergee localement sur
mainen fast-forward (pile chainee : l API de merge Forgejo ne peut pas traiter une pile dont la base n est pasmain). Tip integre :e181a96. Forgejo ne detecte pas un merge ff local, donc cette PR est fermee a la main — le code EST surmain.Pull request closed