refactor(user-tokens): migrate from server - #2279
Conversation
a9a75b7 to
64a5234
Compare
b37e308 to
0331d48
Compare
0331d48 to
c53cb23
Compare
09f3402 to
b667443
Compare
1b31261 to
f16a730
Compare
cecad1b to
10b4770
Compare
|
🤖 Hey ! The security scan report for the current pull request is available here. |
0eb3e93 to
43d21dc
Compare
|
🤖 Hey ! The security scan report for the current pull request is available here. |
1 similar comment
|
🤖 Hey ! The security scan report for the current pull request is available here. |
|
🤖 Hey ! The security scan report for the current pull request is available here. |
4 similar comments
|
🤖 Hey ! The security scan report for the current pull request is available here. |
|
🤖 Hey ! The security scan report for the current pull request is available here. |
|
🤖 Hey ! The security scan report for the current pull request is available here. |
|
🤖 Hey ! The security scan report for the current pull request is available here. |
|
Review: REQUEST CHANGES (posted as comment — GitHub does not allow the author to submit a formal review on their own PR). Contract regressions in the token migration: BLOCKER B1 — BLOCKER B2 — date parsing path ( WARNINGS
NITS
Good: token hash never selected/exposed, authz parity preserved, tests are meaningful (25/25). |
|
🤖 Hey ! The security scan report for the current pull request is available here. |
shikanime
left a comment
There was a problem hiding this comment.
Review: #2279 — refactor(user-tokens): migrate from server
Verdict: REQUEST CHANGES (dead crypto export; strong authz parity + tests)
Findings
[blocker] apps/server-nestjs/src/utils/crypto.ts:46 verifyTokenHash is exported but never imported anywhere (verified: zero usages outside its own def + spec). Dead code in a security-sensitive file. Either wire it into the token-login validation path or drop it from this PR.
[warning] admin-token/admin-token.service.ts:58 BigInt(data.permissions) — permissionLevelSchema is z.coerce.string(), so permissions is a string. BigInt("chocapics") throws a raw SyntaxError → 500, not a BadRequestException. Validate with z.coerce.bigint() or wrap in a typed parse. (Latent in the Fastify version too; you're rewriting, so fix it.)
[warning] admin-token.service.ts:39 / user-tokens.service.ts — z.coerce.date().parse("toto") returns Invalid Date (not a ZodError), and isAtLeastTomorrow then yields a confusing "trop courte" message. Add explicit Number.isNaN(date.getTime()) → BadRequestException('Date d\'expiration invalide'). (Aligns with StephaneTrebel's still-open "la date peut aussi être invalide".)
[resolved/non-issue] Items from StephaneTrebel's review:
RequireUserType('human')— the repo has noHUMAN_KINDconstant; literal'human'matches the Prisma enum and existing usage. No change needed.withRevoked="chocapics"—ZodValidationPipe+CoerceBooleanSchemarejects non-boolean with 400. Already mitigated.
Compliance checklist
- Conventional title
- Authz preserved: admin routes use
RequireAdminPermission; user routesUserGuard+RequireUserType('human')— mirrors FastifyAdminAuthorized/ProjectAuthorized - No secret leakage:
hashomitted from all selects/responses - Tests present (service specs + crypto specs + gated e2e)
- Remove dead
verifyTokenHashexport before merge
|
🤖 Hey ! The security scan report for the current pull request is available here. |
3 similar comments
|
🤖 Hey ! The security scan report for the current pull request is available here. |
|
🤖 Hey ! The security scan report for the current pull request is available here. |
|
🤖 Hey ! The security scan report for the current pull request is available here. |
Review: refactor(user-tokens): migrate from server — REQUEST CHANGESMigrates admin + personal-access tokens from Fastify 🔴 blockersB1 —
then call 🟡 warningsW1 — admin list does N+1 + unbatched reads, no controller/HTTP e2e 🟢 nitsN1 — coverage reporter changed from N2 — Verified OK
CI is green, but CI's unit suite never exercises the param pipe on a missing query string, so B1 slipped through. Fix B1 (and ideally add the HTTP e2e from W1), then re-request review. |
Review: #2279 — refactor(user-tokens): migrate from serverVerdict: REQUEST CHANGES (reviewer agent) Re-verified against head Two latent trust-boundary validation bugs remain from the Fastify→NestJS rewrite (fix before cutover):
Fix these two, then approve. |
| constructor(@Inject(PrismaService) private readonly prisma: PrismaService) {} | ||
|
|
||
| @StartActiveSpan() | ||
| async list(withRevoked = false) { |
There was a problem hiding this comment.
thought: Hmm ok, pas déconnant que par défaut on ne ramène pas tout 🤔
| } | ||
|
|
||
| @StartActiveSpan() | ||
| async create(data: CreateAdminTokenBody) { |
There was a problem hiding this comment.
issue: arrêtez de me mettre du data partout 😅
Les choses ont un nom. ici on a un CreateAdminTokenBody
Sinon on renomme toutes les variables en data1, data2, foo, bar… 😁
| expect(found).toBeTruthy() | ||
| expect(found).not.toHaveProperty('hash') | ||
| }) | ||
| }) |
There was a problem hiding this comment.
praise: Bon, c'est pas mal sur le reste 👍
| it('should create a personal access token with plaintext password', async () => { | ||
| const result = await service.create({ | ||
| name: `e2e-pat-${faker.string.uuid()}`, | ||
| expirationDate: new Date(Date.now() + 86400000), |
There was a problem hiding this comment.
nitpick: Come on, un const ONE_DAY_IN_MILLISECONDS = 86400000, ça ne coûte pas bien cher 😅
| select: { hash: true }, | ||
| }) | ||
|
|
||
| const expectedHash = createHash('sha256').update(created.password).digest('hex') |
There was a problem hiding this comment.
issue: Là on n'est même plus "trop proches de l'implémentation", on copie-colle l'implémentation, avec tous les soucis que ça peut poser...à ce niveau-là appelle carrément la fonction de hashage.
| coverage: { | ||
| provider: 'v8', | ||
| reporter: ['text', 'json', 'html'], | ||
| reporter: ['text', 'lcov'], |
There was a problem hiding this comment.
nitpick: Limite on les mets tous. Et un commit dédié ça pourrait être pas mal (non aux Cavaliers Législatifs !)
| @@ -1,3 +1,4 @@ | |||
| export * from './_utils.js' | |||
There was a problem hiding this comment.
question: Ça vient d'où, ça ? 🤔
Signed-off-by: William Phetsinorath <william.phetsinorath-open@interieur.gouv.fr> Change-Id: I00a18a853330301a735cdfcf3fb6955a6a6a6964
Signed-off-by: William Phetsinorath <william.phetsinorath-open@interieur.gouv.fr> Change-Id: Ib1b5cbbfcd8274912ed9ffb20d60cbed6a6a6964
|

0 New Issues
0 Fixed Issues
0 Accepted Issues
Issues liées
Issues numéro: #1889
Quel est le comportement actuel ?
Quel est le nouveau comportement ?
Cette PR introduit-elle un breaking change ?
Autres informations