M4-T08: add two-step login and TOTP settings panel (qrcode.react)
This commit is contained in:
Vendored
+270
@@ -245,6 +245,7 @@ export interface paths {
|
||||
*
|
||||
* On success, sets an HttpOnly session cookie and returns the session user + CSRF token.
|
||||
* On failure, returns 401 with no cookie set.
|
||||
* Repeated failures trigger exponential back-off (429 + Retry-After).
|
||||
* No X-CSRF-Token required (unauthenticated endpoint).
|
||||
*/
|
||||
post: operations["post_login_api_auth_login_post"];
|
||||
@@ -300,6 +301,112 @@ export interface paths {
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
"/api/auth/totp/setup": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
get?: never;
|
||||
put?: never;
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
post: operations["post_totp_setup_api_auth_totp_setup_post"];
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
"/api/auth/totp/enable": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
get?: never;
|
||||
put?: never;
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
post: operations["post_totp_enable_api_auth_totp_enable_post"];
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
"/api/auth/totp/disable": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
get?: never;
|
||||
put?: never;
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
post: operations["post_totp_disable_api_auth_totp_disable_post"];
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
"/api/auth/totp": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
/**
|
||||
* 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).
|
||||
*/
|
||||
get: operations["get_totp_status_api_auth_totp_get"];
|
||||
put?: never;
|
||||
post?: never;
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
"/homeassistant/publish": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
@@ -510,6 +617,8 @@ export interface components {
|
||||
username: string;
|
||||
/** Password */
|
||||
password: string;
|
||||
/** Totp Code */
|
||||
totp_code?: string | null;
|
||||
};
|
||||
/** PasswordChangeRequest */
|
||||
PasswordChangeRequest: {
|
||||
@@ -647,6 +756,50 @@ export interface components {
|
||||
/** Status */
|
||||
status: string;
|
||||
};
|
||||
/**
|
||||
* TotpDisableRequest
|
||||
* @description Disable TOTP by proving identity.
|
||||
*
|
||||
* Exactly one of ``password`` or ``code`` must be provided.
|
||||
*/
|
||||
TotpDisableRequest: {
|
||||
/** Password */
|
||||
password?: string | null;
|
||||
/** Code */
|
||||
code?: string | null;
|
||||
};
|
||||
/**
|
||||
* TotpEnableRequest
|
||||
* @description The user confirms setup by providing the 6-digit TOTP code.
|
||||
*/
|
||||
TotpEnableRequest: {
|
||||
/** Code */
|
||||
code: string;
|
||||
};
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
TotpSetupResponse: {
|
||||
/** Secret */
|
||||
secret: string;
|
||||
/** Otpauth Uri */
|
||||
otpauth_uri: string;
|
||||
/** Recovery Codes */
|
||||
recovery_codes: string[];
|
||||
};
|
||||
/**
|
||||
* TotpStatusResponse
|
||||
* @description Minimal status response — never exposes secret or recovery codes.
|
||||
*/
|
||||
TotpStatusResponse: {
|
||||
/** Enabled */
|
||||
enabled: boolean;
|
||||
};
|
||||
/** ValidationError */
|
||||
ValidationError: {
|
||||
/** Location */
|
||||
@@ -1143,6 +1296,123 @@ export interface operations {
|
||||
};
|
||||
};
|
||||
};
|
||||
post_totp_setup_api_auth_totp_setup_post: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: {
|
||||
"X-CSRF-Token"?: string | null;
|
||||
};
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody?: never;
|
||||
responses: {
|
||||
/** @description Successful Response */
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["TotpSetupResponse"];
|
||||
};
|
||||
};
|
||||
/** @description Validation Error */
|
||||
422: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["HTTPValidationError"];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
post_totp_enable_api_auth_totp_enable_post: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: {
|
||||
"X-CSRF-Token"?: string | null;
|
||||
};
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody: {
|
||||
content: {
|
||||
"application/json": components["schemas"]["TotpEnableRequest"];
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
/** @description Successful Response */
|
||||
204: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
/** @description Validation Error */
|
||||
422: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["HTTPValidationError"];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
post_totp_disable_api_auth_totp_disable_post: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: {
|
||||
"X-CSRF-Token"?: string | null;
|
||||
};
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody: {
|
||||
content: {
|
||||
"application/json": components["schemas"]["TotpDisableRequest"];
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
/** @description Successful Response */
|
||||
204: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
/** @description Validation Error */
|
||||
422: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["HTTPValidationError"];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
get_totp_status_api_auth_totp_get: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody?: never;
|
||||
responses: {
|
||||
/** @description Successful Response */
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["TotpStatusResponse"];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
publish_from_homeassistant_homeassistant_publish_post: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
|
||||
Reference in New Issue
Block a user