Integration (QuickLoginTests.cs):
- Options_effective_matrix: Enabled=false → off; пустой/мусорный Issuer → off;
Issuer=admin.food-market.kz → off (прод); любой другой host (включая
test.admin.*) → on.
- Disabled_returns_404_and_rejects_master_password: default-factory
(Enabled=false) /accounts → 404, master-пароль → 400 invalid_grant,
обычный Admin12345! → 200 (sanity check).
- Enabled_at_runtime_...: мутируем IOptions<QuickLoginOptions>.Value +
IConfiguration в живом сервис-провайдере (так как WithWebHostBuilder на
уже-построенной parent-factory даёт ObjectDisposedException). Проверяем:
/accounts → 200 + SuperAdmin в списке; master-пароль пускает активного
SuperAdmin'а; НЕ пускает деактивированного; смена Issuer на прод
переключает всё в safety-off.
Также фикс в QuickLoginOptions: прод-хост теперь СТРОГО 'admin.food-market.kz'
без suffix-match (раньше test.admin.food-market.kz тоже считался прод-ом).
E2E (tests/e2e/scenarios/stage-quick-login.{yml,steps.ts}): 4 шага —
GET /accounts на стенде → 200 + демо-trio; master-пароль пускает
demo-cashier → /api/me role=Cashier; GET на прод → 404; Playwright: клик
по карточке demo-cashier → редирект с /login + нет ссылки /products
в sidebar (меню кассира).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
67 lines
5.4 KiB
Markdown
67 lines
5.4 KiB
Markdown
# Quick Login — прогресс
|
||
|
||
Задача владельца: на `test.admin.food-market.kz` не набирать логин/пароль руками.
|
||
Выбрать аккаунт из списка, пароль у всех один — `123456`. На `admin.food-market.kz`
|
||
этого нет никогда (несколько независимых предохранителей).
|
||
|
||
Координатор отдельно проверил: на стейдже нет реальных секретов (МойСклад
|
||
токенов нет, ОФД-ключей нет, Telegram не привязан, SMTP пустой) — потому
|
||
открытый мастер-пароль на стенде безопасен.
|
||
|
||
## Чек-лист
|
||
|
||
- [x] 1. **Флаг конфигурации** — `QuickLogin:Enabled` (default false) +
|
||
`QuickLogin:MasterPassword` (default `123456`). Включается только через
|
||
env-переменные `QuickLogin__Enabled=true` в stage-compose. Жёсткий
|
||
предохранитель: если `OpenIddict:Issuer` указывает на admin.food-market.kz —
|
||
быстрый вход принудительно выключен и в лог Warning.
|
||
- [x] 2. **Мастер-пароль** — password-grant: `QuickLogin:MasterPassword`
|
||
работает как второй вход рядом со своим паролем. Неактивные/без-org
|
||
пользователи — отшиваются как раньше. Rate-limit не ослаблять.
|
||
- [x] 3. **API списка аккаунтов** — `GET /api/dev/quick-login/accounts`
|
||
(анонимный, 404 если выключен). Порядок: SuperAdmin → демо-* → остальные
|
||
«человеческие». Autotest-патéрны (cat31-*, visual-*, factory-smoke-*, mt6*,
|
||
quality-*, i18n*-*, auth2*-*, doc4*-*, rep5*-*, rt8*-*, twofa*-*, wiz9*-*,
|
||
a11y-*, mob1*-*, isoB*-*, axdet-*, smoke-*, ratetest-*, perf-*, probe-*,
|
||
load-*, s19-test-* и всё с суффиксом из ≥10 цифр) — скрыты. Лимит 50 + `?q=`.
|
||
- [x] 4. **Демо-аккаунты** — идемпотентный сид «Демо-магазин» (через
|
||
существующий `DemoTenantSeeder`) + сотрудники с ролями Admin / Cashier /
|
||
Storekeeper (`demo-admin@food-market.local`, `demo-cashier@...`,
|
||
`demo-keeper@...`). Запускается только при Enabled=true.
|
||
- [x] 5. **Страница входа (web)** — если `GET .../accounts` вернул 200 — над
|
||
обычной формой блок «Быстрый вход (тестовый стенд)» с карточками + поиск.
|
||
Клик — моментальный логин через мастер-пароль. На проде блока нет.
|
||
- [x] 6. **Плашка «ТЕСТОВЫЙ СТЕНД»** — при Enabled=true жёлтая полоса
|
||
сверху + `<meta robots="noindex,nofollow">` в index.html стенда.
|
||
- [x] 7. **Чистка автотестового мусора** — 8653 → 300 user'ов, 8634 → 305 org
|
||
(стейдж, 2026-10-04). Протестирован на существующей БД: SuperAdmin / admin@
|
||
demo-market.local / market@email.com остались, свежие прогоны (<3д) сохранены. SQL-скрипт для стейджа + расширение
|
||
`HousekeepingJobs.PruneQualityTestOrgsAsync` на новые autotest-патéрны,
|
||
чтобы cron 02:30 UTC гасил новые юзеры сам. Не трогать: SuperAdmin,
|
||
admin@demo-market.local, market@email.com, demo-* аккаунты.
|
||
- [x] 8. **Тесты** — integration 3/3 green (QuickLoginTests: options matrix,
|
||
disabled→404+rejects, enabled→master pass для активного/отшивает неактивного +
|
||
prod issuer выключает). E2E scenario `stage-quick-login` (4 шага) ждёт
|
||
deploy'а на стенд. Прод 404-проверка в ql03. integration (3): Enabled=false → эндпоинт 404 + мастер-
|
||
пароль отвергается; Issuer=admin.food-market.kz → выключен даже с
|
||
Enabled=true; Enabled=true → мастер-пароль пускает активного и не пускает
|
||
неактивного. E2E stage: клик по демо-кассиру → меню кассира. Прод: `curl
|
||
https://admin.food-market.kz/api/dev/quick-login/accounts` → 404.
|
||
- [ ] 9. **Деплой + документация** — поднять env в stage-compose
|
||
(локальный репо + prod-vm `~/food-market-stage/deploy/docker-compose.yml`),
|
||
`~/deploy-stage.sh`, ретест, `docs/quick-login.md`.
|
||
|
||
## Правила (сам себе)
|
||
|
||
- Мастер-пароль и список аккаунтов — **никогда не на проде**. По умолчанию
|
||
выключено, Issuer=admin.* — выключено независимо от флага.
|
||
- После каждого пункта: build + соответствующие тесты + коммит порцией +
|
||
`[x]` в этом файле.
|
||
- Не трогать: прод admin.food-market.kz (кроме read-only проверки 404),
|
||
`global.json`, POS WPF, gateway nginx.
|
||
|
||
## Условие остановки
|
||
|
||
9 пунктов `[x]`, тесты зелёные, стейдж задеплоен, прод-эндпоинт 404 →
|
||
итог в этом файле + `touch ~/.fm-watchdog/DONE`.
|