Notechondria
Version: 0.1.64 Build Date: 2026-04-23T00:00
What's Changed
Bug (root-cause fix) — session probe no longer 401s on stale tokens
The 0.1.63 "Fresh token rejected by backend" SnackBar was me papering over the symptom. The real bug:
SessionApiViewatbackend/creators/api.pywas declaredpermission_classes = [permissions.AllowAny], so the view was correctly willing to handle anonymous callers and return{"authenticated": false}. But DRF's default authentication chain runs before any view:DEFAULT_AUTHENTICATION_CLASSES = [TokenAuthentication, ApiKeyAuthentication], andTokenAuthentication.authenticate_credentialsraisesAuthenticationFailed("Invalid token.")on any unknown token — even against anAllowAnyview. So every request carrying a stale saved token 401'd the session probe itself, making it impossible for the probe to tell the frontend "your token is stale" without simultaneously looking like a backend failure.- Fix:
SessionApiViewnow declaresauthentication_classes = []explicitly, and does a manualToken.objects.get(key=...)lookup inside the view. Response is always 200; body is{"authenticated": true, token, user, ...}when the token matches a row,{"authenticated": false}otherwise (missing header, malformed header, unknown token, or deactivated user). - Frontend revert: the 0.1.63
checkSession-based panic added tofrontend/editor_app/lib/app_shell.dartapplyAuthPayloadis removed. It was diagnosing a symptom the backend now prevents. The boot-time_restoreSessioninfrontend/editor_app/lib/core/auth_flows.dartalready handled{authenticated: false}correctly (it clears the persisted session silently) — no frontend change needed there.
Why tokens go stale in the first place
For the record (this is NOT a bug — just documentation of the legitimate reasons a saved token stops working):
- Backend swap. You point the frontend at a different backend
than the one that issued the token (Render ↔ Northflank, local
↔ cloud). The
authtoken_tokentable is per-DB; tokens are not portable. Every session probe against a new backend will return{authenticated: false}— that's correct behavior now. - Password change.
ChangePasswordApiViewatbackend/creators/api.py:714deletes and recreates the token explicitly. The response body includes the new token; the frontend saves it. Any OTHER device with the pre-change token becomes stale — by design. - Explicit logout.
LogoutApiViewatbackend/creators/api.py:836wipes the user's tokens. Same deal. - Database reset. If you re-provision the Postgres addon (new
Render DB, reset Northflank addon), the
authtoken_tokentable is empty on the new DB. All prior tokens are orphaned. This is a platform/ops action, not a code bug.
We do NOT need to "refresh tokens on each redeploy" — the DB is persistent across redeploys on both Render and Northflank, so tokens survive. If the user sees 401s after a code redeploy (not a DB rebuild), the likely cause is #1 or #2 above, not a platform issue. With the SessionApiView fix, the frontend can correctly detect and recover from all four cases silently.
Files Changed
VERSION— bumped 0.1.63 → 0.1.64.backend/creators/api.py—SessionApiViewgetsauthentication_classes = []and an explicitToken.objects.getlookup so invalid/stale tokens yield 200 with{"authenticated": false}instead of 401.frontend/editor_app/lib/app_shell.dart— reverted the 0.1.63checkSession-on-applyAuthPayloadblock. The saved-token probe path in_restoreSessionnow handles stale tokens without surfacing an error.
Notes
- Only
SessionApiViewgets theauthentication_classes = []treatment. OtherAllowAnyviews (FrontPageApiView,NoteListCreateApiViewwith scope='all', …) keep DRF's default auth chain — a stale token sent to those still 401s. That's correct: for those endpoints, if you sent an Authorization header, you meant to authenticate, and a hard 401 is the right response. The session probe is the ONE endpoint where the whole point is "is my saved credential valid?" and for that endpoint the probe itself must not be gated on the credential being valid. - Planner and portal apps still have their own
applyAuthPayloadinlined. They never had the 0.1.63checkSessionpanic so they need no revert — tracked indocs/TODO.mdas the broader "replicate auth fixes across all three apps" item.