Skip to content

Conversation

@matteius
Copy link
Contributor

@matteius matteius commented Feb 9, 2026

Summary

Adds optional QR code-based TOTP (Time-based One-Time Password) multi-factor authentication for lightNVR users.

Changes

Database

  • Migration 0021_add_totp_mfa.sql — Adds totp_secret and totp_enabled columns to the users table

Backend (C)

  • TOTP algorithm (api_handlers_totp.c/.h) — RFC 6238 implementation using HMAC-SHA1 via mbedTLS, including base32 encoding/decoding, secret generation (160-bit), code generation (6-digit, 30s window), and verification with ±1 window tolerance
  • API endpoints:
    • POST /api/auth/users/:id/totp/setup — Generate secret, return otpauth:// URI
    • POST /api/auth/users/:id/totp/verify — Verify code & enable TOTP
    • POST /api/auth/users/:id/totp/disable — Disable TOTP
    • GET /api/auth/users/:id/totp/status — Check TOTP status
    • POST /api/auth/login/totp — Second-step TOTP login verification
  • Modified login flow — After password verification, if TOTP is enabled, returns a totp_required response with a short-lived pending token (5 min TTL) instead of a session cookie
  • Database functionsdb_auth_get_totp_info(), db_auth_set_totp_secret(), db_auth_enable_totp() with backward compatibility via cached_column_exists()
  • User list/get handlers — Fixed to include totp_enabled in SQL queries and zero-initialize user_t structs to prevent uninitialized memory from showing incorrect MFA status

Frontend (Preact/JSX)

  • Two-step login (LoginView.jsx) — After password success, shows TOTP code input with 6-digit field, back button, and auto-focus
  • TOTP Setup Modal (TotpSetupModal.jsx) — QR code display (via qrcode npm package), manual secret entry, verification code input, enable/disable functionality
  • Users Table (UsersTable.jsx) — Added MFA status column and MFA management button in actions
  • Users View (UsersView.jsx) — Integrated TOTP modal with state management

Design Decisions

  • Optional per-user — Users without TOTP enabled log in normally with no change
  • Client-side QR codes — No server-side image generation needed
  • Backward compatible — Uses cached_column_exists() throughout so databases without the migration still work
  • Admins can disable MFA for locked-out users via the user management UI
  • No new tables — Reuses existing sessions table with short TTL for pending MFA tokens

Pull Request opened by Augment Code with guidance from the PR author

@matteius matteius merged commit 5debbd1 into main Feb 9, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant