M4-T05: add TOTP service and setup/enable/disable/status API

This commit is contained in:
2026-06-21 21:55:17 +02:00
parent 5026967cee
commit ee3031013e
10 changed files with 1301 additions and 1 deletions
+216
View File
@@ -577,6 +577,157 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
/api/auth/totp/setup:
post:
tags:
- api-session
summary: Post Totp Setup
description: 'Generate a new pending TOTP secret, otpauth URI, and one-time
recovery codes.
The secret is stored in the DB but TOTP is NOT yet enabled (totp_enabled stays
False until the user confirms with POST /api/auth/totp/enable).
Recovery codes are returned here as plaintext exactly once; their Argon2 hashes
are persisted immediately so enable only needs to flip the enabled flag.
Repeating this call replaces any prior pending secret and regenerates codes.
Requires: session cookie + X-CSRF-Token.'
operationId: post_totp_setup_api_auth_totp_setup_post
parameters:
- name: X-CSRF-Token
in: header
required: false
schema:
anyOf:
- type: string
- type: 'null'
title: X-Csrf-Token
responses:
'200':
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/TotpSetupResponse'
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
/api/auth/totp/enable:
post:
tags:
- api-session
summary: Post Totp Enable
description: 'Enable TOTP by confirming with the current 6-digit code from the
authenticator app.
Requires a prior call to POST /api/auth/totp/setup (so that a pending secret
exists). On success, totp_enabled becomes True.
Returns 400 if the code is wrong or there is no pending secret.
Requires: session cookie + X-CSRF-Token.'
operationId: post_totp_enable_api_auth_totp_enable_post
parameters:
- name: X-CSRF-Token
in: header
required: false
schema:
anyOf:
- type: string
- type: 'null'
title: X-Csrf-Token
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/TotpEnableRequest'
responses:
'204':
description: Successful Response
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
/api/auth/totp/disable:
post:
tags:
- api-session
summary: Post Totp Disable
description: 'Disable TOTP. The caller must provide exactly one of:
- ``password``: the user''s current login password, OR
- ``code``: the current 6-digit TOTP code.
On success: totp_enabled=False, totp_secret cleared, all recovery codes deleted.
Returns 400 if neither credential matches or neither is provided.
Requires: session cookie + X-CSRF-Token.'
operationId: post_totp_disable_api_auth_totp_disable_post
parameters:
- name: X-CSRF-Token
in: header
required: false
schema:
anyOf:
- type: string
- type: 'null'
title: X-Csrf-Token
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/TotpDisableRequest'
responses:
'204':
description: Successful Response
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
/api/auth/totp:
get:
tags:
- api-session
summary: Get Totp Status
description: 'Return the current TOTP status for the authenticated user.
Response contains only ``{"enabled": bool}``.
Secret and recovery codes are NEVER returned here.
Requires: session cookie only (no CSRF — read-only).'
operationId: get_totp_status_api_auth_totp_get
responses:
'200':
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/TotpStatusResponse'
/homeassistant/publish:
post:
tags:
@@ -1079,6 +1230,71 @@ components:
required:
- status
title: StatusResponse
TotpDisableRequest:
properties:
password:
anyOf:
- type: string
- type: 'null'
title: Password
code:
anyOf:
- type: string
- type: 'null'
title: Code
type: object
title: TotpDisableRequest
description: 'Disable TOTP by proving identity.
Exactly one of ``password`` or ``code`` must be provided.'
TotpEnableRequest:
properties:
code:
type: string
title: Code
type: object
required:
- code
title: TotpEnableRequest
description: The user confirms setup by providing the 6-digit TOTP code.
TotpSetupResponse:
properties:
secret:
type: string
title: Secret
otpauth_uri:
type: string
title: Otpauth Uri
recovery_codes:
items:
type: string
type: array
title: Recovery Codes
type: object
required:
- secret
- otpauth_uri
- recovery_codes
title: TotpSetupResponse
description: 'Returned once after a setup call.
``secret`` and ``recovery_codes`` are **one-time plaintext values**.
They are never returned again by any subsequent API call.
The frontend must display and instruct the user to save them before confirming.'
TotpStatusResponse:
properties:
enabled:
type: boolean
title: Enabled
type: object
required:
- enabled
title: TotpStatusResponse
description: Minimal status response — never exposes secret or recovery codes.
ValidationError:
properties:
loc: