- setWiFi() now throws detailed errors instead of returning false - Shows specific error messages: "WiFi credentials rejected", timeout etc. - Added logging throughout BLE WiFi configuration flow - Fixed WiFi network deduplication (keeps strongest signal) - Ignore "Operation cancelled" error (normal cleanup behavior) - BatchSetupProgress shows actual error in hint field 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
77 lines
4.5 KiB
Markdown
77 lines
4.5 KiB
Markdown
# PRD — WellNuo Security Audit Fix
|
||
|
||
## Описание
|
||
|
||
Исправление 6 критичных уязвимостей из Security Audit перед релизом.
|
||
Все задачи независимы друг от друга — можно выполнять параллельно.
|
||
|
||
**Общее время:** ~11 часов
|
||
**Источник:** `AUDIT_REPORT.md`
|
||
|
||
---
|
||
|
||
## Задачи
|
||
|
||
### Backend Security (worker1)
|
||
|
||
- [x] @worker1 **VULN-001: Stripe Webhook Required** — В файле `backend/src/routes/webhook.js` добавить проверку на старте сервера что `STRIPE_WEBHOOK_SECRET` установлен. Если не установлен — выбросить ошибку и остановить сервер: `if (!process.env.STRIPE_WEBHOOK_SECRET) { console.error('STRIPE_WEBHOOK_SECRET is required!'); process.exit(1); }`. Убрать fallback на `JSON.parse` без проверки подписи.
|
||
|
||
- [x] @worker1 **VULN-003: JWT Secret Validation** — В файле `backend/src/index.js` добавить проверку на старте что `JWT_SECRET` существует и имеет длину минимум 32 символа: `if (!process.env.JWT_SECRET || process.env.JWT_SECRET.length < 32) { console.error('JWT_SECRET must be at least 32 characters!'); process.exit(1); }`.
|
||
|
||
- [x] @worker1 **VULN-008: npm audit fix** — Выполнить `cd backend && npm update qs && npm audit fix` для исправления известной DoS уязвимости в пакете `qs`.
|
||
|
||
### Auth Security (worker2)
|
||
|
||
- [x] @worker2 **VULN-004: OTP Rate Limiting** — В файле `backend/src/routes/auth.js` добавить rate limiting для endpoint `/verify-otp`. Установить пакет `express-rate-limit`. Создать limiter: 5 попыток за 15 минут, ключ по email или IP. Применить к роуту `router.post('/verify-otp', otpLimiter, ...)`. Также добавить rate limit на `/send-otp`: 3 попытки за 15 минут.
|
||
|
||
### Input Validation (worker3)
|
||
|
||
- [x] @worker3 **VULN-005: Input Validation** — Установить пакет `express-validator`. Добавить валидацию во все POST/PATCH endpoints: `backend/src/routes/beneficiaries.js` (name: string 1-200, email: optional email), `backend/src/routes/stripe.js` (priceId: string), `backend/src/routes/invitations.js` (email: valid email, role: enum). Использовать паттерн: `body('field').isString().trim()...`, затем `validationResult(req)` для проверки ошибок.
|
||
|
||
### Secrets Management (worker4)
|
||
|
||
- [x] @worker4 **VULN-007: Doppler Setup** — НЕ ВЫПОЛНЯТЬ АВТОМАТИЧЕСКИ! Это требует ручной работы. Создать файл `backend/DOPPLER_SETUP.md` с инструкцией: 1) Зарегистрироваться на doppler.com, 2) Создать проект WellNuo, 3) Добавить все секреты (DB_PASSWORD, JWT_SECRET, BREVO_API_KEY, STRIPE_SECRET_KEY, STRIPE_WEBHOOK_SECRET, ADMIN_API_KEY, LEGACY_API_PASSWORD, LIVEKIT_API_KEY, LIVEKIT_API_SECRET), 4) Установить CLI: `curl -Ls https://cli.doppler.com/install.sh | sh`, 5) Изменить запуск в PM2: `doppler run -- node index.js`, 6) Удалить .env файл после миграции.
|
||
|
||
---
|
||
|
||
## Контекст
|
||
|
||
### Файлы для изменения
|
||
|
||
| Worker | Файлы |
|
||
|--------|-------|
|
||
| worker1 | `backend/src/routes/webhook.js`, `backend/src/index.js`, `backend/package.json` |
|
||
| worker2 | `backend/src/routes/auth.js`, `backend/package.json` |
|
||
| worker3 | `backend/src/routes/beneficiaries.js`, `backend/src/routes/stripe.js`, `backend/src/routes/invitations.js`, `backend/package.json` |
|
||
| worker4 | Создать `backend/DOPPLER_SETUP.md` |
|
||
|
||
### Зависимости для установки
|
||
|
||
```bash
|
||
# worker2: rate limiting
|
||
npm install express-rate-limit
|
||
|
||
# worker3: validation
|
||
npm install express-validator
|
||
```
|
||
|
||
### Важно
|
||
|
||
1. **НЕ трогать legacy API интеграцию** — это заблокировано, ждём Phase 1/2
|
||
2. **Проверить что сервер запускается** после каждого изменения
|
||
3. **Не ломать существующую логику** — только добавляем проверки
|
||
|
||
---
|
||
|
||
## После выполнения
|
||
|
||
Задеплоить на сервер:
|
||
```bash
|
||
ssh root@91.98.205.156
|
||
cd /var/www/wellnuo-api
|
||
git pull origin main
|
||
npm install
|
||
pm2 restart wellnuo-api
|
||
pm2 logs wellnuo-api --lines 30
|
||
```
|