0.1.106 — drop invitation codes, email-verification codes, sessions, change-password / change-email; SMTP code path retired
The Casdoor cutover is functionally complete. With Casdoor handling
signup, password reset, and session management at
auth.trance-0.com, the Notechondria-side equivalents became dead
weight. This round deletes them.
User's directive verbatim: "since we move the full auth cycle process to casdoor, there is no need for invitation codes and auth codes, remove those and try to integrate session management with casdoor integration, if it is too complicated or not supported by casdoor offical api, just remove the function."
Decision: sessions removed, not integrated
Casdoor's admin SDK exposes get_sessions(user_owner) but its
response shape is incompatible with the existing Notechondria
Session model + per-app Active Sessions card. Integrating would
mean rewriting both ends — and Casdoor's user portal already lets
users view + revoke their own sessions. Per the user's "just remove
if complicated" hint, the whole Notechondria-side session surface
is gone. Sessions live on Casdoor's side now.
Backend — what's deleted
backend/creators/models.py
InvitationCode— class + every field. Was the gate for legacy email-based signup.VerificationCode+VerificationChoices— the 6-digit-code records that backed email verification, password reset, and identity confirmation.Session+ theSESSION_IDLE_TIMEOUT/SESSION_ABSOLUTE_TIMEOUTconstants — the per-device session table thatMultiSessionAuthenticationused to validate DRF tokens against.
backend/creators/migrations/0031_drop_invitation_verification_session.py (new)
DeleteModel("InvitationCode"), DeleteModel("VerificationCode"),
DeleteModel("Session"), depending on 0030_creator_casdoor_sub.
Existing migration history is preserved — Django needs the original
CreateModel migrations to apply on a fresh DB before the new
DeleteModel rolls them back, so production deploys with an
existing DB run all 31 migrations and end up with the same
final schema.
backend/creators/api.py
Deleted endpoints (and their serializers, where serializer classes were used only by the deleted view):
RegisterApiView,ValidateInvitationApiView,VerifyEmailApiView,ResendVerificationApiViewLoginApiView— Casdoor handles login now via theCasdoorJWTAuthenticationclass + thecasdoor/exchange/endpoint. The frontend's legacyclient.login()method will now 404 if any code path still calls it.LogoutApiView— only existed to revoke aSessionrow; with noSessionmodel, the endpoint is meaningless. Frontend logout state-clears client-side regardless.PasswordResetRequestApiView,PasswordResetConfirmApiView,SendIdentityCodeApiView,ChangePasswordApiView,ChangeEmailApiView— all four backed byVerificationCode+ the_send_code_emailhelper, all dead now.SessionApiView,SessionListApiView,SessionRevokeApiView.
backend/creators/authentication.py
MultiSessionAuthentication deleted (it only existed to validate
Session model rows). DRF stock TokenAuthentication plus
ApiKeyAuthentication plus CasdoorJWTAuthentication cover every
remaining auth path.
backend/creators/utils.py
Email-send helpers deleted: _send_code_email,
send_registration_email, send_password_reset_email,
issue_registration_code, issue_password_reset_code,
smtp_is_configured, log_manual_verification_code. The
from django.core.mail import send_mail import comes out too;
nothing in creators/ imports it now.
Avatar / ensure_creator / etc. all preserved.
backend/notechondria/api_urls.py
14 dead URL routes pruned. Only auth/rotate-api-key/ and the four
auth/casdoor/* routes survive on the auth surface.
backend/notechondria/settings.py
- SMTP env-var loads gone (
SMTP_HOST,SMTP_PORT,SMTP_USERNAME,SMTP_PASSWORD,SMTP_USE_TLS,SMTP_USE_SSL,SMTP_FROM_EMAIL,SMTP_EMAIL_VERIFICATION_TTL_HOURS) and theEMAIL_*Django settings derived from them. FRONTEND_VERIFY_URLenv-var load gone — was the verification- email link target.MultiSessionAuthenticationremoved fromDEFAULT_AUTHENTICATION_CLASSES. New order:ApiKeyAuthentication→CasdoorJWTAuthentication→ DRF stockTokenAuthentication.
backend/creators/forms.py, backend/creators/views.py, backend/creators/urls.py, backend/creators/admin.py
RegisterForm, validate_registration_code, register_request
view, creators:register URL, and InvitationCodeAdmin /
VerificationCodeAdmin / ActivationCodeInline — all the
dependent classic-Django (non-DRF) plumbing — deleted. The
creators:register link in notechondria/templates/navbar.html
removed too so template rendering doesn't NoReverseMatch.
backend/creators/tests.py
Test cases that exercised the removed surfaces deleted in full:
AuthApiTests login coverage, RegistrationFlowTests,
InvitationCodeTests, PasswordResetFlowTests,
VerificationCodeModelTests, OAuthBindRejectionTests. The
remaining fixtures (GithubSyncTests, CasdoorAuthTests) had
their Session.create_for_user calls swapped for DRF
Token.objects.create since the in-test session was just a way to
make a request authenticated.
Frontend — what's deleted
frontend/notechondria_shared/
lib/src/components/auth_dialogs_wizard.dart— file deleted. Held onlyRegistrationWizard; no remaining callers since 0.1.103.lib/src/components/active_sessions_card.dart— file deleted. Held onlyActiveSessionsCard+_ActiveSessionRow; no remaining callers post-Active-Sessions removal.lib/src/components/auth_dialogs.dart—EmailCodeDialogandPasswordResetDialogclasses + their states deleted. KeptEmailPasswordDialog(still backs the legacy email/password Login fallback expander),FeedbackText,AuthHub.lib/notechondria_shared.dart— exports trimmed to dropEmailCodeDialog,PasswordResetDialog,RegistrationWizard,ActiveSessionsCard.lib/src/app_shell/auth_client.dart— abstract methods reduced tologin,getCasdoorConfig,casdoorExchange,casdoorBind,casdoorUnlink,checkSession,logout,getSettings,updateSettings. Droppedregister,verifyEmail,resendVerification,requestPasswordReset,confirmPasswordReset,listSessions,revokeSession.lib/src/app_shell/app_shell_auth_actions_mixin.dart— keptloginonly. Dropped the five register / verify / reset helpers.
Per-app cascade (editor / planner / portal)
lib/core/client.dart(+client_base.dart/http_client.dart) — abstract method declarations + concrete implementations dropped:register,validateInvitation,verifyEmail,resendVerification,requestPasswordReset,confirmPasswordReset,sendIdentityCode,listSessions,revokeSession,changePassword,changeEmailRequest,changeEmailConfirm.loginandcheckSessionretained (the latter will 404 against the new backend, which the boot- restore flow already treats as "anonymous").lib/app_shell.dart—_SettingsPage(...)named-arg passthroughs trimmed to match. Dropped_currentSessionId,_multiDevice,_otherSessionsCountfields.applySessionMetadata/clearSessionMetadatacollapsed to the mixin's no-op default.lib/modules/settings.dart—_SettingsPageconstructor + field declarations stripped of every dropped callback.lib/modules/settings_pages.dart(editor, portal) —_SignInSecurityPageshrank to the Casdoor bind/unlink card + related plumbing; Active Sessions row + Change Email / Change Password rows gone. Multi-device banner gone.frontend/editor_app/lib/modules/settings_build.dart— dropped_openChangePasswordDialogand_openChangeEmailDialogextension methods.frontend/portal_app/lib/modules/settings_dialogs.dart— file deleted (held the_openChangePasswordDialog/_openChangeEmailDialogextension that wrapped the dropped endpoints).frontend/portal_app/lib/main.dart— dropped thepart 'modules/settings_dialogs.dart'directive.
migrate_users_to_casdoor flag trim
The --invitation-code flag added in 0.1.105 came back out — with
invitation codes deleted, the flag had no semantic anchor.
--admin-password-from-env stays.
Verification
python -m py_compileon every modified backend file → exit 0.DJANGO_SECRET_KEY=test python manage.py check→System check identified no issues (0 silenced).DJANGO_SECRET_KEY=test python manage.py makemigrations --dry-run→ reports only the same pre-existingnotes/0019_alter_noteattachment_id.pythat has been pending since 0.1.101. No new pending migrations introduced.flutter analyzefromfrontend/notechondria_shared/,frontend/editor_app/,frontend/planner_app/,frontend/portal_app/→ 0 errors each.
Operator runbook (after 0.1.106 deploys)
git push— deploy 0.1.106 to Northflank. The build picks up the new_drop_invitation_verification_sessionmigration on first boot and drops the three tables. Existing data in those tables is wiped — confirm before deploying that you don't want any of it (you almost certainly don't, since it's all dead auth state).- Confirm
https://notechondria.trance-0.com/api/v1/handshake/reportsversion: "0.1.106"and a realcommit/build_time. - Confirm
/api/v1/auth/casdoor/config/returns{configured: true, ...}(assuming the backend has theCASDOOR_*env vars — the frontend now logs a debug-log warning if it doesn't). - From the Northflank shell, run the user migration if not
already done — see
docs/versions/0.1.105.mdfor the runbook. - After deploy, log in once via Casdoor SSO. Check that:
- Sign-up button is gone from the auth surface.
- "Forgot password" is gone from the legacy login dialog.
- "Active Sessions" card is gone from the Settings page.
- "Change password" / "Change email" rows are gone from
_SignInSecurityPage.
Carryover
client.login()andclient.logout()Dart methods stay in the per-app client classes for now. They'll 404 against the new backend; the legacyEmailPasswordDialogLogin fallback inAuthHubstill callslogin(). Since Casdoor SSO is the primary path and the fallback only matters for un-migrated accounts, a follow-up round can dropEmailPasswordDialog+ the matchinglogin()plumbing once you've confirmed every active user is in Casdoor.docker-compose.ymlstill references the droppedSMTP_*andFRONTEND_VERIFY_URLenv vars. Harmless — Django no longer reads them.entrypoint.sh's legacy 0.1.65 wipe block doesfrom creators.models import Sessioninside a try/except; after the migration runs, the import fails and theexceptbranch logs "Skipped session wipe: ...". Functionally fine; cleanup deferred.