"/auth/account":
    get:
        tags: [Accounts]
        operationId: getFullUserProfile
        summary: Caller's full profile
        description: |
            Returns the full self-shape of the authenticated account —
            `SanitizedLocalAccount` (admin-only fields stripped). Aliased
            by `/auth/profile`.
        responses:
            "200":
                description: Full profile.
                content:
                    application/json:
                        schema: { $ref: "../components/schemas/SelfAccount.yaml" }
            "401": { $ref: "../auth-api.yaml#/components/responses/Unauthorized" }
    put:
        tags: [Accounts]
        operationId: updateAccount
        summary: Update caller's account
        description: |
            Updates mutable fields on the authenticated account
            (`username`, `email`, marketing preferences, etc.). On success
            returns the same shape as `GET /auth/account`. Validation
            failures return `422` with the validator's failure record.
            Username changes are rate-limited to once per 24h.
        requestBody:
            required: true
            content:
                application/json:
                    schema: { $ref: "../components/schemas/AccountUpdateRequest.yaml" }
        responses:
            "200":
                description: Updated profile.
                content:
                    application/json:
                        schema: { $ref: "../components/schemas/SelfAccount.yaml" }
            "401": { $ref: "../auth-api.yaml#/components/responses/Unauthorized" }
            "409":
                description: |
                    Identity-attach conflict — Steam / Oculus auth verification
                    failed, or the identity is already attached.
                content:
                    application/json:
                        schema: { $ref: "../auth-api.yaml#/components/schemas/Error" }
            "422":
                description: Validation failed (bad email, taken username, banned word, rate-limited rename).
                content:
                    application/json:
                        schema:
                            type: object
                            description: Validator failure record (express-validator output).
                            additionalProperties: true
    post:
        tags: [Accounts]
        operationId: createAccountFromEmailPassword
        summary: Create account from email + password
        description: |
            Creates a new Bigscreen account using an email address and
            password. Sends a verification email; the account is created
            in an unverified state. Tokens travel via response headers —
            see `/auth/login`.
        security:
            - apiKey: []
        requestBody:
            required: true
            content:
                application/json:
                    schema: { $ref: "../components/schemas/CreateEmailAccountRequest.yaml" }
        responses:
            "200":
                description: Account created. Tokens are emitted via response headers — see below.
                headers:
                    x-access-token: { $ref: "../auth-api.yaml#/components/headers/AccessToken" }
                    x-refresh-token: { $ref: "../auth-api.yaml#/components/headers/RefreshToken" }
                    x-timestamp: { $ref: "../auth-api.yaml#/components/headers/Timestamp" }
                    x-nonce: { $ref: "../auth-api.yaml#/components/headers/Nonce" }
                content:
                    application/json:
                        schema: { $ref: "../components/schemas/AccessTokenBundle.yaml" }
            "409":
                description: Email already in use.
                content:
                    application/json:
                        schema: { $ref: "../auth-api.yaml#/components/schemas/Error" }
            "422":
                description: Validation failed (bad email, weak password, taken username, banned word).
                content:
                    application/json:
                        schema:
                            type: object
                            additionalProperties: true

"/auth/profile":
    get:
        tags: [Accounts]
        operationId: getFullUserProfileAlias
        summary: Caller's full profile (alias)
        description: Identical to `GET /auth/account`.
        responses:
            "200":
                description: Full profile.
                content:
                    application/json:
                        schema: { $ref: "../components/schemas/SelfAccount.yaml" }
            "401": { $ref: "../auth-api.yaml#/components/responses/Unauthorized" }

"/auth/account/attach":
    post:
        tags: [Accounts]
        operationId: attachEmailPasswordToExistingAccount
        summary: Attach email / password to current account
        description: |
            Adds an email/password identity to the caller's account when
            it does not already have one (typically used by accounts
            created through Steam or Oculus that later want a password
            login). Sends a verification email.

            **Returns plain text `OK`** — not JSON.
        requestBody:
            required: true
            content:
                application/json:
                    schema: { $ref: "../components/schemas/CreateEmailAccountRequest.yaml" }
        responses:
            "200":
                description: Attached. Body is the literal string `OK`.
                content:
                    text/plain:
                        schema: { type: string, example: OK }
            "401":
                description: Caller already has an email/password identity, or auth failed.
                content:
                    application/json:
                        schema: { $ref: "../auth-api.yaml#/components/schemas/Error" }
            "409":
                description: Email already in use elsewhere.
                content:
                    application/json:
                        schema: { $ref: "../auth-api.yaml#/components/schemas/Error" }
            "422":
                description: Validation failed (bad email, weak password).
                content:
                    application/json:
                        schema:
                            type: object
                            additionalProperties: true

"/auth/steam/account":
    post:
        tags: [Accounts]
        operationId: createAccountFromSteamId
        summary: Create account from Steam credentials
        description: |
            Creates a new Bigscreen account bound to a verified Steam id.
            Tokens travel via response headers — see `/auth/login`.
        security:
            - apiKey: []
        requestBody:
            required: true
            content:
                application/json:
                    schema: { $ref: "../components/schemas/SteamLoginRequest.yaml" }
        responses:
            "200":
                description: Account created. Tokens are emitted via response headers — see below.
                headers:
                    x-access-token: { $ref: "../auth-api.yaml#/components/headers/AccessToken" }
                    x-refresh-token: { $ref: "../auth-api.yaml#/components/headers/RefreshToken" }
                    x-timestamp: { $ref: "../auth-api.yaml#/components/headers/Timestamp" }
                    x-nonce: { $ref: "../auth-api.yaml#/components/headers/Nonce" }
                content:
                    application/json:
                        schema: { $ref: "../components/schemas/AccessTokenBundle.yaml" }
            "401":
                description: Invalid Steam credentials.
                content:
                    application/json:
                        schema: { $ref: "../auth-api.yaml#/components/schemas/Error" }
            "409":
                description: Steam id already attached to another account.
                content:
                    application/json:
                        schema: { $ref: "../auth-api.yaml#/components/schemas/Error" }

"/auth/oculus/account":
    post:
        tags: [Accounts]
        operationId: createAccountFromOculusId
        summary: Create account from Oculus credentials
        description: |
            Creates a new Bigscreen account bound to a verified Oculus
            user token. Tokens travel via response headers — see
            `/auth/login`.
        security:
            - apiKey: []
        requestBody:
            required: true
            content:
                application/json:
                    schema: { $ref: "../components/schemas/OculusLoginRequest.yaml" }
        responses:
            "200":
                description: Account created. Tokens are emitted via response headers — see below.
                headers:
                    x-access-token: { $ref: "../auth-api.yaml#/components/headers/AccessToken" }
                    x-refresh-token: { $ref: "../auth-api.yaml#/components/headers/RefreshToken" }
                    x-timestamp: { $ref: "../auth-api.yaml#/components/headers/Timestamp" }
                    x-nonce: { $ref: "../auth-api.yaml#/components/headers/Nonce" }
                content:
                    application/json:
                        schema: { $ref: "../components/schemas/AccessTokenBundle.yaml" }
            "401":
                description: Invalid Oculus credentials.
                content:
                    application/json:
                        schema: { $ref: "../auth-api.yaml#/components/schemas/Error" }
            "409":
                description: Oculus id already attached to another account.
                content:
                    application/json:
                        schema: { $ref: "../auth-api.yaml#/components/schemas/Error" }

"/auth/steam/attach":
    post:
        tags: [Accounts]
        operationId: attachSteamAccount
        summary: Attach Steam identity to current account
        description: |
            Binds a verified Steam id to the caller's account. Refused if
            the Steam id is already attached elsewhere or if the caller
            already has a Steam identity.

            **Returns plain text `OK`** — not JSON.
        requestBody:
            required: true
            content:
                application/json:
                    schema: { $ref: "../components/schemas/SteamLoginRequest.yaml" }
        responses:
            "200":
                description: Attached. Body is the literal string `OK`.
                content:
                    text/plain:
                        schema: { type: string, example: OK }
            "401": { $ref: "../auth-api.yaml#/components/responses/Unauthorized" }
            "409":
                description: Conflict — Steam id in use, or caller already has Steam attached.
                content:
                    application/json:
                        schema: { $ref: "../auth-api.yaml#/components/schemas/Error" }

"/auth/steam/detach":
    post:
        tags: [Accounts]
        operationId: detachSteamAccount
        summary: Detach Steam identity from current account
        description: |
            Removes the Steam identity from the caller's account, but only
            when the identity is verified.

            **Returns plain text `OK`** — not JSON.
        responses:
            "200":
                description: Detached. Body is the literal string `OK`.
                content:
                    text/plain:
                        schema: { type: string, example: OK }
            "401": { $ref: "../auth-api.yaml#/components/responses/Unauthorized" }
            "409":
                description: Steam identity is not verified, or no Steam identity attached.
                content:
                    application/json:
                        schema: { $ref: "../auth-api.yaml#/components/schemas/Error" }

"/auth/email/verify/{token}":
    parameters:
        - in: path
          name: token
          required: true
          schema: { type: string }
    get:
        tags: [Accounts]
        operationId: checkEmailVerificationTicket
        summary: Confirm email verification
        description: |
            Confirms an email-verification ticket. Marks the account's
            primary email as verified on success. Reached from the magic
            link in the verification email.
        security:
            - apiKey: []
        responses:
            "200":
                description: Email verified.
                content:
                    application/json:
                        schema:
                            type: object
                            required: [result]
                            properties:
                                result: { type: string, example: OK }
            "401": { $ref: "../auth-api.yaml#/components/responses/Unauthorized" }
            "404":
                description: Ticket unknown / consumed / expired.

"/auth/email/update/{emailUpdateToken}":
    parameters:
        - in: path
          name: emailUpdateToken
          required: true
          schema: { type: string }
    get:
        tags: [Accounts]
        operationId: handleConfirmEmailUpdate
        summary: Confirm an email-address change
        description: |
            Confirms a pending email-update ticket. Used when an existing
            account changes its email — the new address must be verified
            before the change applies. The handler also enforces a
            staff-domain guard: privileged accounts cannot change their
            email to a non-staff domain.
        security:
            - apiKey: []
        responses:
            "200":
                description: Email updated.
                content:
                    application/json:
                        schema:
                            type: object
                            required: [result]
                            properties:
                                result: { type: string, example: OK }
            "401": { $ref: "../auth-api.yaml#/components/responses/Unauthorized" }
            "403":
                description: Refused by the staff-domain guard.
                content:
                    application/json:
                        schema: { $ref: "../auth-api.yaml#/components/schemas/Error" }
            "404":
                description: Ticket unknown / consumed / expired.

"/auth/device/{deviceUniqueIdentifier}":
    parameters:
        - in: path
          name: deviceUniqueIdentifier
          required: true
          schema: { type: string }
    get:
        tags: [Accounts]
        operationId: getAccountDeviceStatus
        summary: Per-device status for the caller
        description: |
            Returns the status of a device attached to the caller's
            account — registration state, last-seen, ban / restriction
            flags. Reuses `DeviceStatus` from the admin spec.
        responses:
            "200":
                description: Device status.
                content:
                    application/json:
                        schema: { $ref: "../components/schemas/DeviceStatus.yaml" }
            "401": { $ref: "../auth-api.yaml#/components/responses/Unauthorized" }
            "404":
                description: Device not on this account.

"/auth/account/flags":
    get:
        tags: [Accounts]
        operationId: getFeatureFlags
        summary: Feature flags for the current account
        description: |
            Returns the per-account feature flags (rollout / experiment
            assignments). The VR client and website call this on launch
            to decide which features to expose.
        responses:
            "200":
                description: Feature flags.
                content:
                    application/json:
                        schema: { $ref: "../components/schemas/FeatureFlags.yaml" }
            "401": { $ref: "../auth-api.yaml#/components/responses/Unauthorized" }
