Авторизация
August 27, 2026 · View on GitHub
Часть документации Runit. Оглавление — в README.
Авторизация
Процедуры auth.*: register, login, logout, refresh, me, changePassword.
Как это устроено:
- пароли хранятся как bcrypt-хеши (cost 12), плюс политика сложности и проверка по списку частых паролей —
src/auth/password.ts; - сессия — два JWT в
httpOnly-cookie: короткоживущий access (15 минут) и refresh (30 дней). Refresh-токены лежат в БД в виде sha256-хешей, поэтому их можно отзывать: смена пароля гасит все прежние сессии; - история паролей (последние 5) не даёт вернуть недавно использованный;
- CSRF — double-submit: сервер отдаёт токен в ответе
login/register/refresh, клиент присылает его обратно в заголовкеcsrf-tokenна мутациях. Проверка применяется к запросам, у которых есть cookie сессии; запуск кода (runner.run) от неё освобождён — он доступен гостям и ничего не меняет.
Права доступа к процедурам:
| Тип процедуры | Кто может вызвать |
|---|---|
publicProcedure | все, включая гостей |
protectedProcedure | только с сессией; чужие объекты недоступны |
adminProcedure | только isAdmin |
Правила, которые важно не потерять при добавлении процедур:
- владелец берётся из
ctx.user, а не из тела запроса — иначе сниппет создаётся от чужого имени; - ответы не содержат
passwordиrecoverHash— для проекций естьsafeUserColumns(БД) иtoPublicUser/toPublicProfile(роутеры). Публичная карточка пользователя не содержит email: иначе перебором имён собирается таблица «username → email»; - на попытку тронуть чужой объект отвечаем
NOT_FOUND, а неFORBIDDEN: второй код подтверждает, что объект существует.
Тесты прав доступа. Docker не нужен, но нужна запущенная PostgreSQL: каждый тестовый файл создаёт себе отдельную базу и удаляет её после прогона (jest запускает файлы параллельно, и общая база означала бы, что тесты видят чужие строки).
npm run test:unit
src/router/authorization.test.ts проверяет права на уровне процедур, src/router/authFlow.test.ts — полный цикл по HTTP: регистрация, вход, cookie, CSRF, смена пароля, выход.