fix(auth): magic link points at /verify.html SPA, not /auth/verify JSON #46

Merged
libretech merged 1 commits from fix/magic-link-points-to-spa into main 2026-04-29 17:13:35 +02:00
Owner

The link inside the magic-link email pointed at /auth/verify, the JSON API endpoint, so anyone clicking the link saw the raw {"jwt":"…","user_id":"…","email":"…"} body in the browser. The frontend already ships the wrapper page (web/public/verify.html + verify.js) that reads ?token= from the URL, POSTs /auth/verify, stores the JWT via authClient.saveSession(), and redirects to /app.html. Backend just built the wrong URL.

One-line change in internal/auth/service.go plus a longer comment explaining why. Verified locally with the dev binary:

$ tail -1 ln.log
magic link for test@example.com: http://localhost:18080/verify.html?token=…
$ curl /verify.html?token=… → 200 text/html (the SPA wrapper)
$ curl -X POST /auth/verify?token=… → 200 application/json (jwt + user_id + email)

Existing unit tests still pass (they parse the token from the email body via extractToken, which finds token= regardless of the path prefix). Reported by the operator after seeing the JSON page on first click in production at https://ln.cloud.librete.ch/.

The link inside the magic-link email pointed at `/auth/verify`, the JSON API endpoint, so anyone clicking the link saw the raw `{"jwt":"…","user_id":"…","email":"…"}` body in the browser. The frontend already ships the wrapper page (`web/public/verify.html` + `verify.js`) that reads `?token=` from the URL, POSTs `/auth/verify`, stores the JWT via `authClient.saveSession()`, and redirects to `/app.html`. Backend just built the wrong URL. One-line change in `internal/auth/service.go` plus a longer comment explaining why. Verified locally with the dev binary: ``` $ tail -1 ln.log magic link for test@example.com: http://localhost:18080/verify.html?token=… $ curl /verify.html?token=… → 200 text/html (the SPA wrapper) $ curl -X POST /auth/verify?token=… → 200 application/json (jwt + user_id + email) ``` Existing unit tests still pass (they parse the token from the email body via `extractToken`, which finds `token=` regardless of the path prefix). Reported by the operator after seeing the JSON page on first click in production at `https://ln.cloud.librete.ch/`.
libretech added 1 commit 2026-04-29 17:13:23 +02:00
The link in the magic-link email landed users on the JSON API
endpoint /auth/verify, exposing the raw response body in the
browser. The SPA already ships the wrapper page (verify.html +
verify.js) — it reads the token, POSTs to /auth/verify itself,
saves the JWT, and redirects to /app.html.

Pointing the email at /verify.html restores the intended flow:
operator clicks link → verifying… → 'Signed in as <email>' →
'Go to your notes'.

Verified locally: the LogMailer now emits
http://localhost:18080/verify.html?token=…, GET /verify.html
returns the SPA HTML, and POST /auth/verify still returns the
JWT JSON (unchanged).
libretech merged commit 942a888242 into main 2026-04-29 17:13:35 +02:00
libretech deleted branch fix/magic-link-points-to-spa 2026-04-29 17:14:01 +02:00
Sign in to join this conversation.