MySQL · 825 bytes Raw Blame History
1 -- SPDX-License-Identifier: AGPL-3.0-or-later
2 --
3 -- Recovery codes. Generated when the user enrolls TOTP, regenerated on
4 -- demand. Stored as sha256 hashes — the plaintext is shown to the user
5 -- exactly once at generation time. Single-use via used_at.
6
7 -- +goose Up
8 CREATE TABLE user_recovery_codes (
9 id bigserial PRIMARY KEY,
10 user_id bigint NOT NULL REFERENCES users(id) ON DELETE CASCADE,
11 code_hash bytea NOT NULL,
12 used_at timestamptz,
13 generated_at timestamptz NOT NULL DEFAULT now(),
14 created_at timestamptz NOT NULL DEFAULT now()
15 );
16
17 CREATE INDEX user_recovery_codes_user_id_idx ON user_recovery_codes (user_id);
18 CREATE UNIQUE INDEX user_recovery_codes_hash_uidx ON user_recovery_codes (code_hash);
19
20 -- +goose Down
21 DROP TABLE IF EXISTS user_recovery_codes;
22