Skip to content

fix(auth): disable unsafe legacy account merge flow #634

Description

@XiaoSeS

Parent

Problem

The current account merge flow returns a verification token to the already-authenticated primary-account session. The same session can then submit that token and confirm the merge, so the flow does not independently prove control of the secondary account. A primary account that can identify a secondary local username or provider:subject can therefore complete a destructive cross-account migration without authenticating as the secondary account.

The current confirmation path also migrates identity bindings, API tokens, platform roles, namespace memberships, and local credentials before marking the secondary account MERGED. This high-impact operation must not remain reachable until the safe merge design provides two independent proofs, replay protection, conflict preview, session revocation, and explicit API-token policy.

Proposed solution

Temporarily isolate the legacy account merge flow while preserving predictable API behavior for deployed clients. Authenticated calls to the existing initiate, verify, and confirm routes return one stable localized 503 Service Unavailable response. They must not resolve a secondary identifier, create or mutate a merge request, return a verification token, or migrate account data.

Replace the current account settings controls with an unavailable notice. Preserve existing database rows without completing or deleting them, and document the operator behavior. Add an independent acceptance design for the future safe Account Merge implementation tracked as PR 6 in the unified identity plan.

Acceptance criteria

  • Authenticated calls with valid CSRF and request bodies to all three legacy merge routes fail closed with the same stable localized 503 error.
  • Unauthenticated calls remain 401; requests without valid CSRF are rejected by the existing security chain before the controller (currently 401).
  • No response returns a verification token, secondary account identifier, or merge request details.
  • The disabled routes perform no repository reads/writes and no identity, token, role, membership, credential, account, or session mutation.
  • The unsafe legacy orchestration code is no longer a callable Spring service.
  • Existing account_merge_request rows and schema are retained for forward migration/forensics; this PR does not delete or complete them.
  • The account settings UI does not render initiate, verification-token, or confirmation controls and explains that merging is temporarily unavailable.
  • English and Chinese operator/authentication documentation describes the temporary isolation and explicitly forbids manual database completion.
  • A separate safe Account Merge acceptance design covers independent primary/secondary control proofs, request/session binding, short TTL, one-time consumption, conflict preview, atomic migration, secondary-session revocation, API-token policy, audit, replay, concurrency, upgrade, and rollback tests.
  • Controller and frontend tests cover the disabled behavior.

Compatibility and rollout

  • No database migration.
  • Existing route paths and request/response schemas remain published for compatibility, but successful merge behavior is intentionally unavailable.
  • Rollback to an older image would re-enable the unsafe implementation; operators must not roll back this security fix without an equivalent route-level block.

Blocked by

None - this is a P0 containment change and should land before the unified identity core.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingeffort/m中等改动,存在一定协同成本 / Medium change with noticeable coordination cost.priority/p1高优先级 / High priority triage bucket.risk/high涉及安全、鉴权、迁移或公共契约 / Touches security, auth, migrations, or public contracts.triage/needs-info需要补充更多信息后才能分流 / Issue needs more detail before it can be routed.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions