mirror of
https://github.com/shuaiplus/nodewarden.git
synced 2026-06-20 13:00:39 +00:00
68ded534a4
- Implemented a backup runner lease mechanism to prevent concurrent backup executions. - Added `deleteAllAttachmentsForCiphers` function to delete attachments for multiple ciphers efficiently. - Introduced `bulkDeleteAttachmentsByIds` method in storage to handle batch deletion of attachments. - Updated backup execution logic to utilize the new lease management and ensure timely updates during the backup process. - Refactored cipher deletion to handle attachments more effectively. - Improved website icon loading with a dedicated caching mechanism for better performance. - Added new index on `ciphers` table for `folder_id` to optimize queries related to folder management. - Enhanced response handling for CORS policy to allow credentials for specific origins.
190 lines
5.9 KiB
SQL
190 lines
5.9 KiB
SQL
PRAGMA foreign_keys = ON;
|
|
|
|
-- IMPORTANT:
|
|
-- Keep this file in sync with src/services/storage.ts (SCHEMA_STATEMENTS).
|
|
-- Any new table/column/index must be added to both places together.
|
|
|
|
CREATE TABLE IF NOT EXISTS config (
|
|
key TEXT PRIMARY KEY,
|
|
value TEXT NOT NULL
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS users (
|
|
id TEXT PRIMARY KEY,
|
|
email TEXT NOT NULL UNIQUE,
|
|
name TEXT,
|
|
master_password_hint TEXT,
|
|
master_password_hash TEXT NOT NULL,
|
|
key TEXT NOT NULL,
|
|
private_key TEXT,
|
|
public_key TEXT,
|
|
kdf_type INTEGER NOT NULL,
|
|
kdf_iterations INTEGER NOT NULL,
|
|
kdf_memory INTEGER,
|
|
kdf_parallelism INTEGER,
|
|
security_stamp TEXT NOT NULL,
|
|
role TEXT NOT NULL DEFAULT 'user',
|
|
status TEXT NOT NULL DEFAULT 'active',
|
|
verify_devices INTEGER NOT NULL DEFAULT 1,
|
|
totp_secret TEXT,
|
|
totp_recovery_code TEXT,
|
|
api_key TEXT,
|
|
created_at TEXT NOT NULL,
|
|
updated_at TEXT NOT NULL
|
|
);
|
|
|
|
-- Per-user sync revision date
|
|
CREATE TABLE IF NOT EXISTS user_revisions (
|
|
user_id TEXT PRIMARY KEY,
|
|
revision_date TEXT NOT NULL,
|
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS ciphers (
|
|
id TEXT PRIMARY KEY,
|
|
user_id TEXT NOT NULL,
|
|
type INTEGER NOT NULL,
|
|
folder_id TEXT,
|
|
name TEXT,
|
|
notes TEXT,
|
|
favorite INTEGER NOT NULL DEFAULT 0,
|
|
data TEXT NOT NULL,
|
|
reprompt INTEGER,
|
|
key TEXT,
|
|
created_at TEXT NOT NULL,
|
|
updated_at TEXT NOT NULL,
|
|
archived_at TEXT,
|
|
deleted_at TEXT,
|
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
|
);
|
|
CREATE INDEX IF NOT EXISTS idx_ciphers_user_updated ON ciphers(user_id, updated_at);
|
|
CREATE INDEX IF NOT EXISTS idx_ciphers_user_archived ON ciphers(user_id, archived_at);
|
|
CREATE INDEX IF NOT EXISTS idx_ciphers_user_deleted ON ciphers(user_id, deleted_at);
|
|
CREATE INDEX IF NOT EXISTS idx_ciphers_user_deleted_updated ON ciphers(user_id, deleted_at, updated_at);
|
|
CREATE INDEX IF NOT EXISTS idx_ciphers_user_folder ON ciphers(user_id, folder_id);
|
|
|
|
CREATE TABLE IF NOT EXISTS folders (
|
|
id TEXT PRIMARY KEY,
|
|
user_id TEXT NOT NULL,
|
|
name TEXT NOT NULL,
|
|
created_at TEXT NOT NULL,
|
|
updated_at TEXT NOT NULL,
|
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
|
);
|
|
CREATE INDEX IF NOT EXISTS idx_folders_user_updated ON folders(user_id, updated_at);
|
|
|
|
CREATE TABLE IF NOT EXISTS attachments (
|
|
id TEXT PRIMARY KEY,
|
|
cipher_id TEXT NOT NULL,
|
|
file_name TEXT NOT NULL,
|
|
size INTEGER NOT NULL,
|
|
size_name TEXT NOT NULL,
|
|
key TEXT,
|
|
FOREIGN KEY (cipher_id) REFERENCES ciphers(id) ON DELETE CASCADE
|
|
);
|
|
CREATE INDEX IF NOT EXISTS idx_attachments_cipher ON attachments(cipher_id);
|
|
|
|
CREATE TABLE IF NOT EXISTS sends (
|
|
id TEXT PRIMARY KEY,
|
|
user_id TEXT NOT NULL,
|
|
type INTEGER NOT NULL,
|
|
name TEXT NOT NULL,
|
|
notes TEXT,
|
|
data TEXT NOT NULL,
|
|
key TEXT NOT NULL,
|
|
password_hash TEXT,
|
|
password_salt TEXT,
|
|
password_iterations INTEGER,
|
|
auth_type INTEGER NOT NULL DEFAULT 2,
|
|
emails TEXT,
|
|
max_access_count INTEGER,
|
|
access_count INTEGER NOT NULL DEFAULT 0,
|
|
disabled INTEGER NOT NULL DEFAULT 0,
|
|
hide_email INTEGER,
|
|
created_at TEXT NOT NULL,
|
|
updated_at TEXT NOT NULL,
|
|
expiration_date TEXT,
|
|
deletion_date TEXT NOT NULL,
|
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
|
);
|
|
CREATE INDEX IF NOT EXISTS idx_sends_user_updated ON sends(user_id, updated_at);
|
|
CREATE INDEX IF NOT EXISTS idx_sends_user_deletion ON sends(user_id, deletion_date);
|
|
CREATE INDEX IF NOT EXISTS idx_sends_user_updated_id ON sends(user_id, updated_at, id);
|
|
|
|
CREATE TABLE IF NOT EXISTS refresh_tokens (
|
|
token TEXT PRIMARY KEY,
|
|
user_id TEXT NOT NULL,
|
|
expires_at INTEGER NOT NULL,
|
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
|
);
|
|
CREATE INDEX IF NOT EXISTS idx_refresh_tokens_user ON refresh_tokens(user_id);
|
|
|
|
CREATE TABLE IF NOT EXISTS invites (
|
|
code TEXT PRIMARY KEY,
|
|
created_by TEXT NOT NULL,
|
|
used_by TEXT,
|
|
expires_at TEXT NOT NULL,
|
|
status TEXT NOT NULL,
|
|
created_at TEXT NOT NULL,
|
|
updated_at TEXT NOT NULL,
|
|
FOREIGN KEY (created_by) REFERENCES users(id) ON DELETE CASCADE,
|
|
FOREIGN KEY (used_by) REFERENCES users(id) ON DELETE SET NULL
|
|
);
|
|
CREATE INDEX IF NOT EXISTS idx_invites_status_expires ON invites(status, expires_at);
|
|
CREATE INDEX IF NOT EXISTS idx_invites_created_by ON invites(created_by, created_at);
|
|
|
|
CREATE TABLE IF NOT EXISTS audit_logs (
|
|
id TEXT PRIMARY KEY,
|
|
actor_user_id TEXT,
|
|
action TEXT NOT NULL,
|
|
target_type TEXT,
|
|
target_id TEXT,
|
|
metadata TEXT,
|
|
created_at TEXT NOT NULL,
|
|
FOREIGN KEY (actor_user_id) REFERENCES users(id) ON DELETE SET NULL
|
|
);
|
|
CREATE INDEX IF NOT EXISTS idx_audit_logs_created_at ON audit_logs(created_at);
|
|
CREATE INDEX IF NOT EXISTS idx_audit_logs_actor_created ON audit_logs(actor_user_id, created_at);
|
|
|
|
CREATE TABLE IF NOT EXISTS devices (
|
|
user_id TEXT NOT NULL,
|
|
device_identifier TEXT NOT NULL,
|
|
name TEXT NOT NULL,
|
|
type INTEGER NOT NULL,
|
|
session_stamp TEXT,
|
|
encrypted_user_key TEXT,
|
|
encrypted_public_key TEXT,
|
|
encrypted_private_key TEXT,
|
|
device_note TEXT,
|
|
last_seen_at TEXT,
|
|
created_at TEXT NOT NULL,
|
|
updated_at TEXT NOT NULL,
|
|
PRIMARY KEY (user_id, device_identifier),
|
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
|
);
|
|
CREATE INDEX IF NOT EXISTS idx_devices_user_updated ON devices(user_id, updated_at);
|
|
CREATE INDEX IF NOT EXISTS idx_devices_user_last_seen ON devices(user_id, last_seen_at);
|
|
|
|
CREATE TABLE IF NOT EXISTS trusted_two_factor_device_tokens (
|
|
token TEXT PRIMARY KEY,
|
|
user_id TEXT NOT NULL,
|
|
device_identifier TEXT NOT NULL,
|
|
expires_at INTEGER NOT NULL,
|
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
|
);
|
|
CREATE INDEX IF NOT EXISTS idx_trusted_two_factor_device_tokens_user_device
|
|
ON trusted_two_factor_device_tokens(user_id, device_identifier);
|
|
|
|
-- Rate limiting
|
|
CREATE TABLE IF NOT EXISTS login_attempts_ip (
|
|
ip TEXT PRIMARY KEY,
|
|
attempts INTEGER NOT NULL,
|
|
locked_until INTEGER,
|
|
updated_at INTEGER NOT NULL
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS used_attachment_download_tokens (
|
|
jti TEXT PRIMARY KEY,
|
|
expires_at INTEGER NOT NULL
|
|
);
|