111 lines · 4.1 KB
-- Identity and account security: email verification, 2FA, passkeys, scoped tokens, notification
-- preferences, follows, avatars and rename/transfer redirects.
ALTER TABLE users ADD COLUMN email_verified_at INTEGER;
ALTER TABLE users ADD COLUMN totp_secret TEXT;
ALTER TABLE users ADD COLUMN totp_iv TEXT;
ALTER TABLE users ADD COLUMN totp_enabled_at INTEGER;
ALTER TABLE users ADD COLUMN totp_last_step INTEGER;
ALTER TABLE users ADD COLUMN sessions_revoked_at INTEGER;
ALTER TABLE accounts ADD COLUMN avatar_key TEXT;

CREATE TABLE recovery_codes (
  user_id TEXT NOT NULL REFERENCES accounts(id) ON DELETE CASCADE,
  code_hash TEXT NOT NULL,
  used_at INTEGER,
  PRIMARY KEY (user_id, code_hash)
);

CREATE TABLE passkeys (
  id TEXT PRIMARY KEY,
  user_id TEXT NOT NULL REFERENCES accounts(id) ON DELETE CASCADE,
  name TEXT NOT NULL,
  public_key TEXT NOT NULL,
  algorithm INTEGER NOT NULL,
  sign_count INTEGER NOT NULL DEFAULT 0,
  transports TEXT NOT NULL DEFAULT '[]',
  last_used_at INTEGER,
  created_at INTEGER NOT NULL
);
CREATE INDEX passkeys_user ON passkeys(user_id);

-- Fine-grained personal access tokens: NULL permissions means a classic (full-access) token.
ALTER TABLE access_tokens ADD COLUMN permissions TEXT;
ALTER TABLE access_tokens ADD COLUMN all_repos INTEGER NOT NULL DEFAULT 1;
CREATE TABLE access_token_repos (
  token_id TEXT NOT NULL REFERENCES access_tokens(id) ON DELETE CASCADE,
  repo_id TEXT NOT NULL REFERENCES repos(id) ON DELETE CASCADE,
  PRIMARY KEY (token_id, repo_id)
);
CREATE INDEX access_token_repos_repo ON access_token_repos(repo_id);