ogrechkoandClaude Sonnet 5 1a31f72dd8 Extend TOTP 2FA to LDAP accounts; disable now requires a code, not a password
2FA was previously local-accounts-only, gated on the assumption that LDAP
already has its own MFA story — that's not actually guaranteed (depends on
what's behind the directory), so app-level TOTP is now available for LDAP
accounts too, as a second factor independent of whatever the directory does
or doesn't enforce. The login route's LDAP branch now checks
user.totpEnabled the same way the local branch already did, routing through
the same login-challenge flow before minting a session.

This forced a change to disabling 2FA: it used to require the current
password, but an LDAP-provisioned user has passwordHash: null — there's no
password to check. Disable now requires a live TOTP code or a recovery
code instead (same "prove you still hold the factor" idea, just checking
the right thing), which works identically for local and LDAP accounts.

Verified: re-ran the full local-account Playwright flow with the new
code-based disable (still passes end-to-end). For the LDAP path — no real
LDAP server available to log in through — flipped a throwaway test account
to authSource="ldap"/passwordHash=null directly in the DB and exercised the
setup/confirm/disable logic functions directly (same technique used
earlier in this session for testing mail ingestion without a live IMAP
server): setup no longer rejects it, confirm and disable both work correctly
with no password present. Test account fully deleted after.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GteWhnWKTmnXcsd5jx6H7u
2026-08-20 08:53:51 +00:00

top-tickets

Хелпдеск-система: тикеты, дашборд по статусам, канал Telegram, realtime-обновления без перезагрузки страницы, отдельный клиентский портал. MVP-1 — см. /root/.claude/plans/refactored-discovering-corbato.md за архитектурой и тем, что отложено на MVP-2 (email, встраиваемый виджет).

Запуск в Docker

cp .env.example .env
npm run generate-key   # вставить результат в CREDENTIALS_ENCRYPTION_KEY
# заполнить ADMIN_BOOTSTRAP_EMAIL / ADMIN_BOOTSTRAP_PASSWORD / TELEGRAM_BOT_TOKEN в .env

docker compose up --build -d

Приложение слушает :8081 (уже проброшено внешним nginx на help.top-sysops.ru). При первом старте контейнер сам применяет миграции и создаёт админ-аккаунт из .env.

Локальная разработка

npm install
cp .env.example .env   # + generate-key, как выше
npm run db:migrate
npm run bootstrap-admin
npm run dev

Telegram

Подключается через Настройки → Telegram в интерфейсе (или через TELEGRAM_BOT_TOKEN в .env — сработает только при первом старте, если бот ещё не настроен). Чтобы бот видел все сообщения в группе, а не только с упоминанием — @BotFather → /setprivacy → Disable.

Токен, который прислали в чат Claude Code, стоит перевыпустить (@BotFather → /revoke) — он засветился в истории сессии.

S
Description
No description provided
Readme
1.1 MiB
0 Stars 1 Watchers 0 Forks
Languages
TypeScript 95.9%
CSS 2.3%
JavaScript 1.2%
Dockerfile 0.6%