Files
galaxy-game/authsession/docs/flows.md
T
2026-04-08 16:23:07 +02:00

4.1 KiB

Auth, Revoke, and Repair Flows

Public Auth Flow

sequenceDiagram
    participant Client
    participant Gateway
    participant Auth
    participant Abuse as Resend throttle
    participant User as UserDirectory
    participant Mail as MailSender
    participant Challenge as ChallengeStore
    participant Session as SessionStore
    participant Config as ConfigProvider
    participant Projection as Gateway projection publisher

    Client->>Gateway: POST /api/v1/public/auth/send-email-code
    Gateway->>Auth: POST /api/v1/public/auth/send-email-code
    Auth->>Abuse: check and reserve cooldown
    alt throttled
        Abuse-->>Auth: throttled
        Auth->>Challenge: create delivery_throttled challenge
        Auth-->>Gateway: 200 {challenge_id}
    else allowed
        Abuse-->>Auth: allowed
        Auth->>User: ResolveByEmail(email)
        User-->>Auth: existing / creatable / blocked
        Auth->>Challenge: create pending challenge
        alt blocked
            Auth->>Challenge: mark delivery_suppressed
        else not blocked
            Auth->>Mail: SendLoginCode(email, code)
            Mail-->>Auth: sent / suppressed / failure
            Auth->>Challenge: persist final delivery outcome
        end
        Auth-->>Gateway: 200 {challenge_id}
    end

    Client->>Gateway: POST /api/v1/public/auth/confirm-email-code
    Gateway->>Auth: POST /api/v1/public/auth/confirm-email-code
    Auth->>Challenge: load and validate challenge
    Auth->>User: EnsureUserByEmail(email)
    User-->>Auth: existing / created / blocked
    Auth->>Config: LoadSessionLimit()
    Auth->>Session: CountActiveByUserID(user_id)
    Auth->>Session: create device session
    Auth->>Challenge: CAS to confirmed_pending_expire
    Auth->>Session: reread current stored session view
    Auth->>Projection: publish gateway snapshot
    Auth-->>Gateway: 200 {device_session_id}

Revoke and Block Flow

sequenceDiagram
    participant Caller as Trusted internal caller
    participant Auth
    participant User as UserDirectory
    participant Session as SessionStore
    participant Projection as Gateway projection publisher
    participant Gateway

    Caller->>Auth: revoke or block request
    alt block by user or email
        Auth->>User: apply block mutation
        User-->>Auth: blocked / already_blocked
    end
    Auth->>Session: revoke one or many sessions
    Session-->>Auth: updated source-of-truth sessions
    loop each affected session
        Auth->>Projection: publish revoked snapshot
    end
    Auth-->>Caller: 200 acknowledgement
    Projection-->>Gateway: revoked session snapshot

Projection Repair On Retry

Projection writes happen after source-of-truth updates. If projection publish fails after state is already stored, the caller sees service_unavailable, and the repair path is to repeat the same request.

sequenceDiagram
    participant Client
    participant Auth
    participant Challenge as ChallengeStore
    participant Session as SessionStore
    participant Projection as Gateway projection publisher

    Client->>Auth: confirm-email-code
    Auth->>Challenge: validate challenge
    Auth->>Session: create session
    Auth->>Challenge: persist confirmed_pending_expire
    Auth->>Projection: publish snapshot
    Projection-->>Auth: failure
    Auth-->>Client: 503 service_unavailable

    Client->>Auth: repeat same confirm-email-code
    Auth->>Challenge: load confirmed_pending_expire challenge
    Auth->>Session: load stored session from confirmation metadata
    Auth->>Projection: republish current stored session view
    Projection-->>Auth: success
    Auth-->>Client: 200 {device_session_id}

Confirm-Race Cleanup

Concurrent identical confirms are allowed to race at the store level, but the service converges them back to one surviving active session.

  • the winning CAS stores challenge confirmation metadata and publishes the surviving session snapshot
  • a superseded session created by a losing racing request is revoked best-effort with reason_code=confirm_race_repair
  • cleanup uses the same projection helper, but cleanup failure is not part of the caller-visible success contract