Skip to content

fix(auth): decode the JWT payload as UTF-8 in both React apps - #1439

Merged
iammukeshm merged 2 commits into
fullstackhero:mainfrom
marcelo-maciel:fix/jwt-utf8-claims
Nov 3, 2026
Merged

iammukeshm merged 2 commits into
fullstackhero:mainfrom
marcelo-maciel:fix/jwt-utf8-claims

Conversation

@marcelo-maciel

Copy link
Copy Markdown
Contributor

Fixes #1438

What

decodeJwt (dashboard and admin) now decodes the base64url payload as UTF-8 with TextDecoder instead of a bare atob. atob returns one character per byte, so a non-ASCII claim such as the display name "Comitê de Ética" rendered as "Comitê de Ética" in the user menu and the overview greeting.

Tests

  • New tests/auth/jwt-utf8.spec.ts in each app seeds an accented name and asserts it renders intact and that no à appears.
  • The fakeJwt helpers in tests/helpers/auth-seed.ts now emit UTF-8 bytes like the server. The old btoa(JSON.stringify(...)) helper could not produce a UTF-8 token, which is why the bug was invisible.
  • Mutation gate: with jwt.ts reverted to atob the new spec fails in both apps; with the fix it passes in both.
  • tsc -b --noEmit clean in both apps, lint has 0 errors.
  • Full Playwright suites: a few unrelated specs fail intermittently on cold runs (also on a clean upstream/main, with different specs each time) and pass when re-run alone.

Docs: fullstackhero/docs PR follows (changelog entry).

decodeJwt used a bare atob, which returns one char per byte. The token
payload is UTF-8, so non-ASCII claims rendered as mojibake: a display name
"Comitê de Ética" showed as "Comitê de Ética" in the user menu and the
overview greeting. The token and the database were correct.

Decode the bytes with TextDecoder. The test fakeJwt helpers now emit UTF-8
like the server, and one spec per app covers an accented name.
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ⚠️ Failed 2026-10-14T21:24:24.633195Z 36491c8 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@iammukeshm iammukeshm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. TextDecoder over the atob bytes is the correct fix, and updating the fakeJwt helpers so the tests actually emit UTF-8 is what makes this regression-proof. Thanks!

@iammukeshm
iammukeshm merged commit 8f6ee28 into fullstackhero:main Nov 3, 2026
18 checks passed
marcelo-maciel added a commit to marcelo-maciel/dotnet-starter-kit that referenced this pull request Nov 4, 2026
O atob devolve um caractere por byte (Latin-1) e o servidor assina o
payload em UTF-8, então "João Conceição" aparecia como "João
Conceição". Os bytes passam pelo TextDecoder, como no upstream
fullstackhero fullstackhero#1439.

Spec nos dois apps decodifica um token montado em UTF-8 pelo próprio
módulo do app; com o decodificador anterior ele falha.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Non-ASCII JWT claims render as mojibake in both React apps

2 participants