92 lines
4.5 KiB
SQL
92 lines
4.5 KiB
SQL
-- Ginxsom Blossom Server Database Schema
|
|
-- SQLite database for blob metadata and server configuration
|
|
|
|
-- Enable foreign key constraints
|
|
PRAGMA foreign_keys = ON;
|
|
|
|
-- Main blobs table for storing blob metadata
|
|
CREATE TABLE IF NOT EXISTS blobs (
|
|
sha256 TEXT PRIMARY KEY NOT NULL, -- SHA-256 hash (64 hex chars)
|
|
size INTEGER NOT NULL, -- File size in bytes
|
|
type TEXT NOT NULL, -- MIME type
|
|
uploaded_at INTEGER NOT NULL, -- Unix timestamp
|
|
uploader_pubkey TEXT, -- Nostr public key (optional)
|
|
filename TEXT, -- Original filename (optional)
|
|
CHECK (length(sha256) = 64), -- Ensure valid SHA-256 hash length
|
|
CHECK (size >= 0), -- Ensure non-negative size
|
|
CHECK (uploaded_at > 0) -- Ensure valid timestamp
|
|
);
|
|
|
|
-- Unified configuration table (replaces server_config and auth_config)
|
|
CREATE TABLE IF NOT EXISTS config (
|
|
key TEXT PRIMARY KEY NOT NULL, -- Configuration key
|
|
value TEXT NOT NULL, -- Configuration value
|
|
description TEXT, -- Human-readable description
|
|
created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now')), -- Creation timestamp
|
|
updated_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now')) -- Last update timestamp
|
|
);
|
|
|
|
-- Indexes for performance optimization
|
|
CREATE INDEX IF NOT EXISTS idx_blobs_uploaded_at ON blobs(uploaded_at);
|
|
CREATE INDEX IF NOT EXISTS idx_blobs_uploader_pubkey ON blobs(uploader_pubkey);
|
|
CREATE INDEX IF NOT EXISTS idx_blobs_type ON blobs(type);
|
|
CREATE INDEX IF NOT EXISTS idx_config_updated_at ON config(updated_at);
|
|
|
|
-- Insert default unified configuration
|
|
INSERT OR IGNORE INTO config (key, value, description) VALUES
|
|
('max_file_size', '104857600', 'Maximum file size in bytes (100MB)'),
|
|
('auth_rules_enabled', 'false', 'Whether authentication rules are enabled for uploads'),
|
|
('server_name', 'ginxsom', 'Server name for responses'),
|
|
('admin_pubkey', '', 'Admin public key for API access'),
|
|
('admin_enabled', 'false', 'Whether admin API is enabled'),
|
|
('nip42_require_auth', 'false', 'Enable NIP-42 challenge/response authentication'),
|
|
('nip42_challenge_timeout', '600', 'NIP-42 challenge timeout in seconds'),
|
|
('nip42_time_tolerance', '300', 'NIP-42 timestamp tolerance in seconds');
|
|
|
|
-- Authentication rules table for whitelist/blacklist functionality
|
|
CREATE TABLE IF NOT EXISTS auth_rules (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
rule_type TEXT NOT NULL, -- 'pubkey_blacklist', 'pubkey_whitelist',
|
|
-- 'hash_blacklist', 'mime_blacklist', 'mime_whitelist'
|
|
rule_target TEXT NOT NULL, -- The pubkey, hash, or MIME type to match
|
|
operation TEXT NOT NULL DEFAULT '*', -- 'upload', 'delete', 'list', or '*' for all
|
|
enabled INTEGER NOT NULL DEFAULT 1, -- 1 = enabled, 0 = disabled
|
|
priority INTEGER NOT NULL DEFAULT 100,-- Lower number = higher priority
|
|
description TEXT, -- Human-readable description
|
|
created_by TEXT, -- Admin pubkey who created the rule
|
|
created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now')),
|
|
updated_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now')),
|
|
|
|
-- Constraints
|
|
CHECK (rule_type IN ('pubkey_blacklist', 'pubkey_whitelist',
|
|
'hash_blacklist', 'mime_blacklist', 'mime_whitelist')),
|
|
CHECK (operation IN ('upload', 'delete', 'list', '*')),
|
|
CHECK (enabled IN (0, 1)),
|
|
CHECK (priority >= 0),
|
|
|
|
-- Unique constraint: one rule per type/target/operation combination
|
|
UNIQUE(rule_type, rule_target, operation)
|
|
);
|
|
|
|
|
|
-- Indexes for performance optimization
|
|
CREATE INDEX IF NOT EXISTS idx_auth_rules_type_target ON auth_rules(rule_type, rule_target);
|
|
CREATE INDEX IF NOT EXISTS idx_auth_rules_operation ON auth_rules(operation);
|
|
CREATE INDEX IF NOT EXISTS idx_auth_rules_enabled ON auth_rules(enabled);
|
|
CREATE INDEX IF NOT EXISTS idx_auth_rules_priority ON auth_rules(priority);
|
|
CREATE INDEX IF NOT EXISTS idx_auth_rules_type_operation ON auth_rules(rule_type, operation, enabled);
|
|
|
|
|
|
-- View for storage statistics
|
|
CREATE VIEW IF NOT EXISTS storage_stats AS
|
|
SELECT
|
|
COUNT(*) as total_blobs,
|
|
SUM(size) as total_bytes,
|
|
AVG(size) as avg_blob_size,
|
|
MIN(uploaded_at) as first_upload,
|
|
MAX(uploaded_at) as last_upload,
|
|
COUNT(DISTINCT uploader_pubkey) as unique_uploaders
|
|
FROM blobs;
|
|
|
|
|