* feat(mfa): auto-submit 6-digit TOTPs and normalize pasted backup codes Match the UX every major MFA prompt has (GitHub, GitLab, 1Password): the challenge screen and every code-entry dialog now submit automatically once the sixth TOTP digit lands, and the backup-code input accepts pastes with smart-dashes, trailing whitespace, or mixed case without silently truncating the value. Also caps the backup-code input at the correct 11 characters (10 plus a single separator) instead of 12. Shared normalization helpers live in frontend/src/lib/mfa.ts so the challenge and the three account-settings dialogs stay in lockstep. * feat(mfa): warn users when backup codes run low The Account & Security card silently showed a dim count of backup codes remaining, which meant users could drift toward zero without noticing until their phone was already lost. The card now surfaces a warning tone with an alert icon when 1 or 2 codes remain, and swaps to a dedicated destructive warning card with a "Regenerate now" action when the user has used every code. * feat(mfa): gate diagnostic logs behind developer mode Reuses the existing isDebugEnabled() gate so operators investigating a 2FA support ticket can flip Developer Mode on to get per-branch diagnostics (login path taken, replay check outcome, failure counter after a verify, replay-table purge counts), and flip it back off when they are done. Standard lifecycle logs stay on by default: enrolment completed, 2FA disabled, backup codes regenerated, admin reset, SSO bypass toggled, lockout engaged. Nothing that could reveal a TOTP code, base32 secret, backup-code cleartext, or partial-auth JWT is ever logged. * test(mfa): cover drift, invalid formats, lockout recovery, and paste normalization Backend: a TOTP generated for a window that has already slid out is rejected, malformed backup codes (too short, non-alphanumeric, 11-char alphanumeric that matches no hash) all increment failed_attempts, a successful verify clears a below-threshold failure streak, a successful verify after locked_until has passed clears the lockout, a second enroll/start overwrites the prior pending secret, and the backup-code normalizer treats en-dash/em-dash/figure-dash with stray whitespace the same as the canonical form. E2E: low-backup-codes warning renders in the warning tone and the exhausted-codes state flips to the dedicated warning card, a 6-digit TOTP auto-submits without a button click, and a backup code pasted without the separator still signs in. * docs(mfa): auto-submit, paste guidance, and expanded troubleshooting Document that the challenge screen submits automatically on the sixth digit, that backup codes accept the separator and any case, and that the Account & Security card nudges at low code counts. Expands the troubleshooting section with entries for lost or exhausted backup codes and adds a short note to the admin guide about surfacing auth diagnostics via Developer Mode.
Sencho
A self-hosted Docker Compose management dashboard. Manage your stacks, containers, images, volumes, and networks through a modern web UI.
Features
- Stack Management - Create, edit, start, stop, and remove Docker Compose stacks with a built-in Monaco code editor
- Multi-Node Support - Manage remote Sencho instances through a transparent HTTP/WebSocket proxy (Distributed API model)
- App Store - One-click deployment from LinuxServer.io templates with editable ports, volumes, and environment variables
- Resource Hub - Browse and manage images, volumes, and networks with managed/external/unused classification
- Live Logs - Aggregated real-time log streaming across all containers with search and filtering
- Dashboard - Container stats, CPU/RAM metrics, health checks, and image update notifications
- Alerts - Configurable threshold alerts for CPU, RAM, and disk usage
- Terminal - In-browser host console and container exec via WebSocket
Quick Start
services:
sencho:
image: saelix/sencho:latest
container_name: sencho
restart: unless-stopped
ports:
- "3000:3000"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./data:/app/data
# 1:1 Compose Path Rule: host path MUST match container path
- /opt/docker:/opt/docker
environment:
- COMPOSE_DIR=/opt/docker
- DATA_DIR=/app/data
docker compose up -d
Then open http://your-server:3000 and create your admin account.
See the full documentation for configuration details, multi-node setup, and more.
Development
# Backend (Express + TypeScript)
cd backend && npm install && npm run dev
# Frontend (React + Vite)
cd frontend && npm install && npm run dev
The frontend dev server proxies /api requests to the backend on port 3000.
Contributing
See CONTRIBUTING.md for development setup and PR guidelines.
Security
See SECURITY.md for vulnerability reporting. Do not open public issues for security vulnerabilities.
License
Sencho is licensed under the Business Source License 1.1. You may use, modify, and redistribute the code freely, including for production use. The only restriction is offering Sencho as a competing hosted or managed service. On 2030-03-25, the license automatically converts to Apache 2.0.
