31 lines
1.6 KiB
MySQL
31 lines
1.6 KiB
MySQL
|
|
-- 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;
|