0.1.103 — in-app signup gone; "Login via third party" + Casdoor signup link
The signed-out auth surface across all three apps is now: Casdoor SSO pill (existing OAuth code flow) → outlined "Login via third party" button (browser redirect to the Casdoor org-login page) → "No account? Sign up via Casdoor" text link (same redirect) → email / password Login behind the existing fallback expander (no signup, no "Forgot password" — admins handle resets).
Operators must:
- Have
CASDOOR_*env vars populated so/api/v1/auth/casdoor/config/returnsconfigured: trueplusendpointandorganization. - In the Casdoor admin UI for the
notechondriaapplication, allow self-registration on the org login page (Organization → Settings → "Account items" → enable signup). - Ensure
https://auth.trance-0.com/login/notechondriais reachable.
If signup is disabled at the Casdoor side, the "Sign up via Casdoor" link still works as a destination but the user lands on a login-only page. That's a Casdoor-config decision, not a Notechondria bug.
Shared library — AuthHub rewritten
frontend/notechondria_shared/lib/src/components/auth_dialogs.dart
trimmed AuthHub from a six-callback "everything" widget to a four-
field hub: onLogin, onCasdoorLogin, casdoorOrgLoginUrl,
apiBaseUrl. The body now renders, in priority order:
- Continue with Casdoor SSO — the existing OAuth code flow via
AppShellOAuthMixin.launchOAuth. Auto-redirects back. Rendered only whenonCasdoorLogin != null(backend is in shadow mode otherwise). - Login via third party — direct browser redirect (via the
shared
url_strategy.browserRedirecthelper) tocasdoorOrgLoginUrl. Rendered only when that URL is non-empty. Use this when the user wants Casdoor's hosted login page (Google / GitHub / etc., configured on the Casdoor application's Providers tab). - No account? Sign up via Casdoor — text link below the third-
party button, same destination. The in-app
RegistrationWizardis gone. - Use email / password instead — the existing expander; now contains only a Login button + a small caption telling un-migrated users to contact the administrator for password resets.
EmailPasswordDialog's onForgotPassword parameter was dropped —
the in-app password-reset flow is gone.
The shared RegistrationWizard, EmailCodeDialog, and
PasswordResetDialog widgets remain in the package as dead code
for now (no callers); they'll come out in a follow-up dead-code
cleanup round so this round's diff stays focused on the user-visible
behavior change.
Editor app — local copy of the signed-out auth surface
The editor app has its own copy of the signed-out auth UI in
frontend/editor_app/lib/modules/settings_build.dart (it doesn't go
through AuthHub). It received the same restructure:
_buildSignedOutAccount— adds the "Login via third party" outlined button + "No account? Sign up via Casdoor" text link wheneverwidget.casdoorOrgLoginUrlis populated. Both navigate the browser viaurl_strategy.browserRedirect._legacyAuthBlock— drops the in-app Sign-up button. Now just a Login button + the contact-administrator caption._openSignUpDialog— deleted entirely (no callers)._openLoginDialog— drops theonForgotPasswordclosure that used to openPasswordResetDialog.
Casdoor org-login URL plumbing
The URL ${endpoint}/login/${organization} is derived from the
/api/v1/auth/casdoor/config/ response (which already returned both
fields — see backend/creators/api.py:1372-1379). Each _AppShellState
gains a String? _casdoorOrgLoginUrl field, populated inside the
existing unawaited(getCasdoorConfig) probe in core/initial_data.dart,
and threaded through to the per-app _SettingsPage(...) constructor
as casdoorOrgLoginUrl. Editor passes it to its local
_buildSignedOutAccount; planner and portal pass it to AuthHub.
String? so a backend in shadow mode (no CASDOOR_* env vars) keeps
both the third-party CTAs collapsed.
Verification
flutter analyzefromfrontend/notechondria_shared/,frontend/editor_app/,frontend/planner_app/,frontend/portal_app/— zero new errors / warnings (only the same pre-existing info-lints).
Carryover
RegistrationWizard,EmailCodeDialog,PasswordResetDialogremain innotechondria_sharedas dead code. Their per-app callback fields (onRegister,onValidateInvitation,onVerify,onResendVerification,onRequestPasswordReset,onConfirmPasswordReset) also remain on each app's_SettingsPageconstructor (unrendered, but still threaded through fromapp_shell.dart). A follow-up cleanup round can drop them — and the matching backend views increators/api.pyplus the matchingAuthClientmethods — once we're confident no out-of-tree client still calls the legacy register / verify / password-reset endpoints.- The
BACKEND_VERSION/ handshake readout placeholder on portal's_BackendSettingsPage(carryover from 0.1.101) is unchanged.
Operator runbook
After deploying 0.1.103:
- Sign in to
https://auth.trance-0.comwith the bootstrap admin. - Open Organizations →
notechondria→ ensure "Account items" includes a signup-enabled email field, OR add at least one provider on the application's Providers tab so the org login page has a signup affordance. - Visit any Notechondria frontend signed out — confirm the auth card now shows: Casdoor SSO pill, "Login via third party", "Sign up via Casdoor", and the email / password expander collapsed by default.