0.1.108 — Inbox always visible + Casdoor login always available
Two follow-ups directly from the latest user-supplied log dump:
pin_diagnosticswarning showedtotal=1 pinned=0 signedIn=false. Rows: #-1777869322101000 "?" plain/local/drag.repeatedly — the user's only visible category was a stale local row, while_loadInitialDatahad successfully loaded 4 cloud categories (one of them their real "Inbox") at the same time.- The Casdoor probe was 404'ing against
https://notechondria.trance-0.com/api/v1/auth/casdoor/config/, flipping_casdoorConfiguredtofalse, which hid the SSO button on every login surface.
User directives verbatim: "I need to keep inbox always visible in categories. And the primary login option for casdoor is always available and as default."
1. _allCategories no longer gates on _token
The 0.1.105 pin_diagnostics upgrade in 0.1.107 finally surfaced
the real bug: _allCategories was returning only
[..._localCourses] whenever _token == null || _token!.isEmpty,
so the user's cloud _courses (which had the real Inbox row in it)
never reached the sidebar.
This gate predates the Casdoor cutover. In the post-0.1.106 world
the legacy DRF _token field is dead weight: the backend doesn't
issue DRF tokens anymore, the frontend's cloud GETs succeed via
session cookies / Casdoor JWT regardless, but the editor's
_token field can stay empty forever. The gate produced a
guaranteed false negative — "Inbox vanished" — for every user on
the new auth path.
Fix in editor_app/lib/app_shell.dart:
List<Map<String, dynamic>> get _allCategories {
return [..._localCourses, ..._courses];
}
Whatever's loaded in _courses is shown. Post-logout the existing
flow (session_mixin.logout() → loadInitialData()) re-fetches
courses for an unauthenticated user, so the signed-out end state
is whatever the backend's public catalog returns — same as
before.
The user-visible effect: the cloud "Inbox" pins to the top of the
sidebar (it has is_default == true and / or matches the title-
casefold check), the local "?"-titled garbage row drops to
draggable, and the diagnostic re-emits with total=N pinned=1
(plus the rich row dump from 0.1.107).
2. Casdoor login button no longer gates on _casdoorConfigured
Before: every app rendered the Casdoor SSO button only when
_casdoorConfigured == true. That flag is set by the boot probe
of /api/v1/auth/casdoor/config/. When production hadn't been
redeployed yet (or any operator hits a stale Render slot), the
probe 404'd, the flag stayed false, and the user saw no
Casdoor button anywhere — no way to log in.
After: all three apps (editor, portal, planner) always pass
the onCasdoorLogin callback through to the signed-out auth
surface:
onCasdoorLogin: () => launchOAuth('casdoor', intent: 'login'),
launchOAuth itself already does the right thing on each click:
it re-fetches /auth/casdoor/config/, and if the response says
configured: false (or 404s), it logs a warning to the debug log
and bails without redirecting — no crash, no broken redirect.
That means the worst case is "tap does nothing visible, debug log
shows a single warning" — strictly better than "no button at
all."
_casdoorConfigured still gates bind and unlink in the
signed-in account card, since those are post-login operations
that genuinely need the backend to be wired before they make
sense. Probe success still updates _casdoorOrgLoginUrl so the
"Login via third party" deep-link to Casdoor's hosted login page
keeps working.
Files changed:
frontend/editor_app/lib/core/build_helpers.dartfrontend/portal_app/lib/app_shell.dartfrontend/planner_app/lib/app_shell.dart
Verification
flutter analyzeclean for the four touched files (only pre- existing info-level lints remain —prefer_single_quotes,use_string_in_part_of_directives,deprecated_member_usefromsurfaceVariant/withOpacityelsewhere inportal/planner)._allCategorieschange is purely additive on the cloud branch (the original gate already returned[..._localCourses, ..._courses]for the signed-in case — we just collapse both branches into the same shape).- The Casdoor button change is also purely additive at the gate;
the actual click-handler (
launchOAuth) is unchanged and already handles the misconfigured-backend case gracefully.
Operator follow-up
If the production backend at notechondria.trance-0.com is still
returning 404 on /api/v1/auth/casdoor/config/, that's a deploy
freshness issue, not a code bug — the route is wired in
backend/notechondria/api_urls.py:65. Redeploy the backend with
the post-0.1.96 codebase and the probe will start succeeding. The
SSO button stays visible whether you redeploy or not.