spec: align user-authentication password requirement with ASCII 8-72 policy (WealthLedger/specs#46) (#47)
Specs security / security (push) Successful in 8s
Specs verify / verify (push) Successful in 10s

This commit was merged in pull request #47.
This commit is contained in:
2026-10-16 10:47:41 +03:00
parent 0a1db52baf
commit 1bd6181585
+22 -2
View File
@@ -7,7 +7,7 @@
## Requirements
### Requirement: Регистрация пользователя
Система SHALL позволять зарегистрировать User по уникальному нормализованному email и паролю. Email MUST нормализоваться удалением внешних пробелов и приведением к нижнему регистру; он MUST содержать не более 254 символов, ровно один `@`, непустые local и domain части и не содержать пробельных или управляющих символов. Пароль MUST передаваться без изменения, содержать от 12 до 72 UTF-8 байтов и не иметь требований к составу символов. Успешная регистрация MUST создать первую Session и вернуть профиль `{ id, email }` и access token.
Система SHALL позволять зарегистрировать User по уникальному нормализованному email и паролю. Email MUST нормализоваться удалением внешних пробелов и приведением к нижнему регистру; он MUST содержать не более 254 символов, ровно один `@`, непустые local и domain части и не содержать пробельных или управляющих символов. Пароль MUST передаваться без изменения (без trim и нормализации) и состоять из 8–72 печатных ASCII-символов U+0020–U+007E (латинские буквы, цифры, спецсимволы и пробел); другие символы, включая не-ASCII и управляющие, MUST отвергаться. Требований к составу символов (обязательных классов) нет. Успешная регистрация MUST создать первую Session и вернуть профиль `{ id, email }` и access token.
#### Scenario: Успешная регистрация
- **WHEN** пользователь отправляет новый email и валидный пароль
@@ -29,8 +29,20 @@
- **WHEN** пользователь отправляет email или пароль, не соответствующий правилам регистрации
- **THEN** система отвечает `400` Problem Details с code `VALIDATION_ERROR` и указателями на невалидные поля
#### Scenario: Границы длины пароля при регистрации
- **WHEN** пользователь регистрируется с паролем из 7, 8, 72 или 73 печатных ASCII-символов
- **THEN** пароли из 8 и 72 символов принимаются, а из 7 и 73 отвергаются `400` Problem Details с code `VALIDATION_ERROR` и указателем `#/password`
#### Scenario: Недопустимые символы пароля при регистрации
- **WHEN** пользователь регистрирует пароль с кириллицей, emoji, табуляцией, переводом строки или DEL
- **THEN** система отвечает `400` Problem Details с code `VALIDATION_ERROR` и указателем `#/password`, не создавая User
#### Scenario: Пробелы пароля не изменяются
- **WHEN** пользователь регистрирует пароль с пробелами в начале или конце
- **THEN** система принимает пароль как есть, а вход требует тот же пароль с теми же пробелами
### Requirement: Вход пользователя
Система SHALL позволять User начать новую независимую Session по нормализованному email и паролю. Успешный вход MUST вернуть `{ id, email }`, access token и установить refresh-cookie. Неверный пароль и неизвестный email MUST иметь одинаковый ответ, не раскрывающий наличие User.
Система SHALL позволять User начать новую независимую Session по нормализованному email и паролю. Успешный вход MUST вернуть `{ id, email }`, access token и установить refresh-cookie. Неверный пароль и неизвестный email MUST иметь одинаковый ответ, не раскрывающий наличие User. Пароль при входе MUST быть непустой строкой не длиннее 72 UTF-8 байтов; минимальная длина и набор символов при входе MUST NOT проверяться, чтобы User, зарегистрированный по прежним правилам (в том числе с не-ASCII паролем), мог войти.
#### Scenario: Успешный вход
- **WHEN** пользователь отправляет зарегистрированный email и правильный пароль
@@ -40,6 +52,14 @@
- **WHEN** пользователь отправляет неизвестный email или неверный пароль
- **THEN** система отвечает `401` Problem Details с code `INVALID_CREDENTIALS`
#### Scenario: Вход с прежним паролем
- **WHEN** User, зарегистрированный по прежним правилам с не-ASCII паролем, отправляет правильный пароль
- **THEN** система выполняет вход, не применяя к паролю правила регистрации
#### Scenario: Пароль при входе длиннее 72 байтов
- **WHEN** пользователь отправляет пароль длиннее 72 UTF-8 байтов
- **THEN** система отвечает `400` Problem Details с code `VALIDATION_ERROR` и указателем `#/password`
### Requirement: Access и refresh сессии
Система SHALL выдавать access token сроком 15 минут и refresh token сроком 7 дней. Access token MUST передаваться клиенту только в ответе API и использоваться как Bearer token. Refresh token MUST передаваться только в `httpOnly`, `SameSite=Lax`, host-only cookie `refresh_token` с path `/api/v1/auth`; в HTTPS-среде cookie MUST иметь атрибут `Secure`. Каждый новый refresh token MUST иметь уникальный JWT ID и ротироваться при успешном обновлении Session; Session MUST оставаться активной 7 дней после последнего успешного обновления. Одновременные Session одного User MUST быть независимы и не иметь числового лимита.