You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Resigned is a visibility flag, not an access flag. It gates ~15 pickers, lists and reports, and is read by zero authentication or authorisation code — grep -rni resigned over eFormAPI.Web, eFormApi.BasePn and eform-angular-frontend-base returns nothing.
Measured on tenant 1012: all four resigned workers still hold a working login (password set, no lockout, "Kun tid" group) and a live device Unit. One resigned seven weeks ago and can still log in today.
Worker
Resigned
Login
Password
Lockout
Erla Zachariasen
2026-07-30
Users 9
set
none
Cecilie Krakov Christensen
2026-01-07
Users 30
set
none
Camille Myken
2026-03-12
Users 42
set
none
Silje Aabenhus Madsen
2026-09-10
Users 48
set
none
Scope: the web login and the Flutter apps, which use the same endpoints. The legacy eForm device app is out of scope — it authenticates against the Microting cloud and has its own working kick-out.
Second problem, fixed in the same change
Login failures are fully distinguishable, so the login box is an account-enumeration oracle:
unknown account → User with username <what you typed> not found
wrong password → Incorrect password.
lockout → Locked Out. Please, try again after 10 min
Each is a hard-coded English literal the client toasts verbatim (apiBase.service.ts:253-263). All three of unknown / wrong-password / refused will return one identical message: "You have entered an invalid username or password", localised.
Approach
Give the login account its own state (EformUser.IsActive), written by the resign action — rather than deciding at login time by matching the submitted username to an SDK Worker via email. There is no FK between Users and the SDK; the join is an email string across two databases that FixUserToWorkerLinks() rewrites by name match on every boot (Startup.cs:492-519), so it is not a safe basis for an auth decision.
Full design: docs/superpowers/specs/2026-09-17-resigned-account-login-refusal-design.md (PR to follow).
Ending already-issued sessions is tracked separately in #8071.
Historical population backfilled 2026-09-18: 369 accounts across 81 tenants disabled by a one-off script run by hand, journalled and reversible — deliberately not a startup job, so a bulk lockout could not fire unattended on first boot. Twelve tenants were not migrated by the deploy; all of them either have no pod or run a different product image, and none has a resigned worker, so none is exposed.
Activity
docs(auth): correct the EF Core sentinel reasoning in the design (#8072)
feat(user): add EformUser.IsActive so a login can be disabled (#971) (#…
feat(auth): refuse login for disabled accounts, and stop leaking whic…
feat(auth): disable the login when a worker is resigned here, and ref…
feat(auth): disable the login when a worker is resigned, and refuse d…
docs(auth): design for refusing login to resigned accounts (#8072) (#…
renemadsen commentedon Sep 18, 2026
Done. Resigned workers can no longer log in — web, back office, or either Flutter app.
Shipped as four gated steps, each waiting on the previous package being released and restorable:
EformUser.IsActiveeFormApi.BasePn10.0.35Users.IsActivecolumnMicroting.EformAngularFrontendBase10.0.39Design:
docs/superpowers/specs/2026-09-17-resigned-account-login-refusal-design.md(#8073).Historical population backfilled 2026-09-18: 369 accounts across 81 tenants disabled by a one-off script run by hand, journalled and reversible — deliberately not a startup job, so a bulk lockout could not fire unattended on first boot. Twelve tenants were not migrated by the deploy; all of them either have no pod or run a different product image, and none has a resigned worker, so none is exposed.
Still open, each tracked on its own: #8071 session kill-out, #8076
ForgotPasswordenumeration, #8077 gRPC lockout parity, microting/eform-backendconfiguration-plugin#1285 (delete leaves a login enabled), #1286 (boot reconciliation), microting/eform-angular-timeplanning-plugin#1720 (PUT /assigned-siteauthorization).