Skip to content

Refuse login for disabled accounts, and stop leaking which accounts exist #8074

Description

@renemadsen

Step 3 of #8072 — design: docs/superpowers/specs/2026-09-17-resigned-account-login-refusal-design.md (PR #8073).

Steps 1 and 2 shipped: EformUser.IsActive in Microting.eFormApi.BasePn 10.0.35, and the Users.IsActive column in Microting.EformAngularFrontendBase 10.0.39. Nothing reads the flag yet.

This issue

  1. Refuse login when IsActive == false on every surface in this repo:

    • AuthService.AuthenticateUser (REST POST /api/auth/token; the core gRPC service delegates here, so it inherits the check)
    • AuthService.RefreshToken — today it mints a fresh 24h token on nothing more than "the row still exists", so a disabled account could otherwise roll its session forward indefinitely
    • AuthService.GetGoogleAuthenticator — anonymous, and a second credential-verification oracle
  2. One identical failure message for unknown account, wrong password and disabled account:

    You have entered an invalid username or password

    Today they are three distinguishable hard-coded English literals, and the unknown-account one echoes the submitted username back:

    Case Today
    unknown account User with username <what you typed> not found
    wrong password Incorrect password.
    disabled did not exist

    The client toasts body.message verbatim (apiBase.service.ts:257-261), so the login box currently tells any visitor which emails have accounts. The UserNameOrPasswordIncorrect resource key already exists in all 25 .resx files and is already used by GetGoogleAuthenticator — reuse it rather than adding a near-duplicate.

    Brute-force lockout keeps its own distinct message: it is temporary and self-resolving, users need to understand it, and it reveals nothing the generic message hides.

  3. Bump Microting.eFormApi.BasePn to 10.0.35 and Microting.EformAngularFrontendBase to 10.0.39.

Deploy note

Program.cs:214 runs Database.Migrate() per tenant at startup, so deploying this applies the IsActive column automatically. Deploy the host before any plugin bumps BasePn: the property maps by convention, so a plugin dragging BasePn ≥ 10.0.35 onto a host without the column makes every query against Users fail.

Not in this issue

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions