MySQL · 801 bytes Raw Blame History
1 -- SPDX-License-Identifier: AGPL-3.0-or-later
2 --
3 -- Password reset tokens. The token itself is high-entropy random; only its
4 -- sha256 hash is stored. used_at marks single-use consumption (replay
5 -- protection). expires_at is set to created_at + 1 hour at insert time.
6
7 -- +goose Up
8 CREATE TABLE password_resets (
9 id bigserial PRIMARY KEY,
10 user_id bigint NOT NULL REFERENCES users(id) ON DELETE CASCADE,
11 token_hash bytea NOT NULL UNIQUE,
12 expires_at timestamptz NOT NULL,
13 used_at timestamptz,
14 created_at timestamptz NOT NULL DEFAULT now()
15 );
16
17 CREATE INDEX password_resets_user_id_idx ON password_resets (user_id);
18 CREATE INDEX password_resets_expires_at_idx ON password_resets (expires_at);
19
20 -- +goose Down
21 DROP TABLE IF EXISTS password_resets;
22