-- 0003_hardening — надёжность и безопасность. -- -- 1) email сравнивается и хранится без учёта регистра: раньше -- Admin@x.ru и admin@x.ru считались разными пользователями. -- Перед созданием индекса дубликатов быть не должно -- (проверено: 0), иначе миграция откатится транзакцией. -- 2) refresh-токены: в БД хранится только sha256-хеш, сам секрет -- известен клиенту один раз. Выдача — с ротацией при каждом обновлении. -- -- Применённый файл не редактировать (checksum в schema_migrations). CREATE UNIQUE INDEX IF NOT EXISTS profiles_email_lower_key ON profiles (lower(email)); CREATE TABLE IF NOT EXISTS refresh_tokens ( id uuid PRIMARY KEY, user_id uuid NOT NULL REFERENCES profiles (id) ON DELETE CASCADE, token_hash text NOT NULL UNIQUE, expires_at timestamptz NOT NULL, revoked_at timestamptz, created_at timestamptz NOT NULL DEFAULT now(), user_agent text, ip text ); -- Сессии пользователя (для logout-all и отзыва при деактивации). CREATE INDEX IF NOT EXISTS refresh_tokens_user_idx ON refresh_tokens (user_id); -- Активные токены — для очистки протухших. CREATE INDEX IF NOT EXISTS refresh_tokens_live_idx ON refresh_tokens (expires_at) WHERE revoked_at IS NULL;