Skip to content

Edit-token SHA-256 hashing is duplicated inline across six files #31

Description

@royalpinto007

What is wrong

Edit tokens are hashed with an inline createHash("sha256").update(token).digest("hex") in six separate files. There is no shared helper, so the hashing scheme for a security-relevant value is copy-pasted:

  • app/api/posts/route.ts line ~98, inline in the submit handler
  • app/api/status/[token]/route.ts lines 5 to 7, local hashToken()
  • app/api/edit/[token]/route.ts lines 7 to 9, local hashToken(), called twice (lines ~19 and ~61)
  • app/api/posts/edit/[token]/route.ts line ~29, another local helper
  • app/api/admin/posts/[id]/resend-token/route.ts line ~27, inline
  • app/edit/[token]/page.tsx line ~34, another local helper

lib/utils/hash.ts is already the home for hashing helpers. It exports hashIp() and getClientIp() but nothing for tokens.

Why it matters

Every one of these must produce byte-identical output or an edit link silently stops resolving. Six copies means a future change (adding a pepper, switching algorithm, trimming input) has to be made in six places, and missing one breaks edit access for real submitters with no error message.

What to change

  1. In lib/utils/hash.ts, add and document an exported hashEditToken(token: string): string that does exactly what the existing copies do today. Do not change the algorithm in this PR: keeping the output identical is the whole point, since existing rows in posts.edit_token_hash were written with it.
  2. Replace all six inline implementations with imports of the new helper, deleting the now-unused local hashToken functions and the now-unused createHash imports.
  3. Add a small test in lib/utils/hash.test.ts asserting hashEditToken is deterministic and that it matches a known hex digest for a fixed input, so a future refactor cannot silently change the scheme. Copy the shape from lib/utils/urls.test.ts.

Note that app/api/posts/route.ts and app/api/admin/posts/[id]/resend-token/route.ts also import randomBytes for token generation. Leave that alone, this issue is only about hashing.

Verify

npx tsc --noEmit
npm run lint
npm test
npm run format

Mechanical and self-contained, a good first change in this codebase.

Comment here to claim it and ask anything you are unsure about. You will usually get a reply within a day.

Metadata

Metadata

Assignees

Labels

claimedSomeone asked first and is working on thisenhancementNew feature or requestgood first issueGood for newcomers

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions