refactored nginx.conf

This commit is contained in:
Your Name
2025-09-02 15:22:15 -04:00
parent db3f078583
commit 4412317ddb
40 changed files with 5076 additions and 1343 deletions

BIN
Trash/ginxsom.db Normal file

Binary file not shown.

View File

@@ -1,6 +1,6 @@
Test blob content for Ginxsom Blossom server
Timestamp: 2025-08-19T10:34:57-04:00
Random data: 52bea9fe68b05eeeee258ae97cdcf8d9e7abbc13e67d61f681927250daef6e56
Timestamp: 2025-09-02T15:17:47-04:00
Random data: 4e8fefec3104b88408f0c71a73e97ba176846747e5577334d42be314839a9bba
Test message: Hello from put_test.sh!
This file is used to test the upload functionality

View File

@@ -1 +0,0 @@
This is a set file to test. Don't edit.

View File

@@ -1,6 +1,6 @@
Test blob content for Ginxsom Blossom server
Timestamp: 2025-08-19T09:58:19-04:00
Random data: faafb490d178139a95368b519dd836ef835b488da9324ab5387299654f294826
Timestamp: 2025-09-02T14:22:55-04:00
Random data: 952a584d8f3fc6b5e49b1dfabbf68d76385d6d51142aa07170c71897ea861c03
Test message: Hello from put_test.sh!
This file is used to test the upload functionality

View File

@@ -1,7 +0,0 @@
Test blob content for Ginxsom Blossom server
Timestamp: 2025-08-19T10:34:52-04:00
Random data: 340fc3549683d7c208ffa373d5932551f9b2e53cc1a5713b55c934403d9640a2
Test message: Hello from put_test.sh!
This file is used to test the upload functionality
of the Ginxsom Blossom server implementation.

View File

@@ -1,7 +0,0 @@
Test blob content for Ginxsom Blossom server
Timestamp: 2025-09-02T12:45:42-04:00
Random data: d29860f9b375c2f964dd3bcb4466fa018fe70ac6335b4ee79cec000c4f7de1e9
Test message: Hello from put_test.sh!
This file is used to test the upload functionality
of the Ginxsom Blossom server implementation.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 199 KiB

View File

@@ -1,7 +0,0 @@
Test blob content for Ginxsom Blossom server
Timestamp: 2025-08-19T10:10:05-04:00
Random data: 0dbb5e8f50695faa4f8bc3a5369d21fca51c98fda6be69520a6bfe6160bd55ca
Test message: Hello from put_test.sh!
This file is used to test the upload functionality
of the Ginxsom Blossom server implementation.

View File

@@ -1,7 +0,0 @@
Test blob content for Ginxsom Blossom server
Timestamp: 2025-09-02T12:45:28-04:00
Random data: 8d599bd3356624fcb782f832b8f03d9a53972b8472a1bdcac83eae353e722621
Test message: Hello from put_test.sh!
This file is used to test the upload functionality
of the Ginxsom Blossom server implementation.

View File

@@ -1,7 +0,0 @@
Test blob content for Ginxsom Blossom server
Timestamp: 2025-09-02T12:46:50-04:00
Random data: 4f03071e8de671359cc9f2d4c868825c597601a3224c924c16ac63d31222595e
Test message: Hello from put_test.sh!
This file is used to test the upload functionality
of the Ginxsom Blossom server implementation.

View File

@@ -1,7 +0,0 @@
Test blob content for Ginxsom Blossom server
Timestamp: 2025-08-19T09:49:32-04:00
Random data: 5fc993875e7b145b161463e2250f7b7d4be0428fca7a91a40a843b25d594eb2d
Test message: Hello from put_test.sh!
This file is used to test the upload functionality
of the Ginxsom Blossom server implementation.

View File

@@ -1,7 +0,0 @@
Test blob content for Ginxsom Blossom server
Timestamp: 2025-08-19T10:34:56-04:00
Random data: 52e5fee5b2f73c73ed388c9df9f74c58117b5f93982c5e6202951fd9fd90b626
Test message: Hello from put_test.sh!
This file is used to test the upload functionality
of the Ginxsom Blossom server implementation.

View File

@@ -1,7 +0,0 @@
Test blob content for Ginxsom Blossom server
Timestamp: 2025-08-19T10:07:52-04:00
Random data: f1690ecb249bb7499e997e47b515e0f067dc0fffa13f4265f497b87166799187
Test message: Hello from put_test.sh!
This file is used to test the upload functionality
of the Ginxsom Blossom server implementation.

View File

@@ -1,7 +0,0 @@
Test blob content for Ginxsom Blossom server
Timestamp: 2025-09-02T12:45:33-04:00
Random data: 0d4dce455f8a7bdfb8bd1cc8e90c2546fcb71f0689c3774530adfa718014c905
Test message: Hello from put_test.sh!
This file is used to test the upload functionality
of the Ginxsom Blossom server implementation.

View File

@@ -1,7 +0,0 @@
Test blob content for Ginxsom Blossom server
Timestamp: 2025-08-19T10:11:22-04:00
Random data: 97e6573bd31c5dd5dc1f3fd7ed6e7d94898959af435556879a648f83b62267e7
Test message: Hello from put_test.sh!
This file is used to test the upload functionality
of the Ginxsom Blossom server implementation.

View File

@@ -1,7 +0,0 @@
Test blob content for Ginxsom Blossom server
Timestamp: 2025-08-19T10:44:56-04:00
Random data: 162b8c0930df1f600ddd936e99ecce0866ab82a436f545d2187ba56726f0df4f
Test message: Hello from put_test.sh!
This file is used to test the upload functionality
of the Ginxsom Blossom server implementation.

View File

@@ -1,7 +0,0 @@
Test blob content for Ginxsom Blossom server
Timestamp: 2025-08-19T09:23:37-04:00
Random data: 91175d5c0a2465bb69dabfa79d822054cbc8c00cc05cc551b1ed69b5f619631a
Test message: Hello from put_test.sh!
This file is used to test the upload functionality
of the Ginxsom Blossom server implementation.

View File

@@ -1,7 +0,0 @@
Test blob content for Ginxsom Blossom server
Timestamp: 2025-08-19T09:53:53-04:00
Random data: e4170eb6a32ff51102a2e154ec96dd4c769b3033f92b2bdb68fe4b835ec42d8f
Test message: Hello from put_test.sh!
This file is used to test the upload functionality
of the Ginxsom Blossom server implementation.

View File

@@ -1,6 +1,6 @@
Test blob content for Ginxsom Blossom server
Timestamp: 2025-08-19T10:06:44-04:00
Random data: a0100362b9eb683a4bf49f49b8b6597490142d2a2d2543e7d500f371f0a1f052
Timestamp: 2025-09-02T13:59:11-04:00
Random data: 77050ac92e48c47746e1d90541d99079e811c59fdd109491165b6d310ef8da76
Test message: Hello from put_test.sh!
This file is used to test the upload functionality

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Binary file not shown.

View File

@@ -1,5 +1,5 @@
# Local Ginxsom Development Server Configuration
# This configuration serves files directly from the local repo directory
# Comprehensive Blossom Protocol Implementation
# Main context - specify error log here to override system default
error_log logs/error.log debug;
@@ -41,47 +41,206 @@ http {
# Maximum upload size (adjust as needed)
client_max_body_size 100M;
# Security headers
# Security headers (applied to all responses)
add_header X-Content-Type-Options nosniff;
add_header X-Frame-Options DENY;
add_header X-XSS-Protection "1; mode=block";
# Delete blob endpoint - DELETE /<sha256> (must come first)
location ~ "^/([a-f0-9]{64}).*$" {
# Only handle DELETE method for this pattern
if ($request_method != DELETE) {
# Let other patterns handle non-DELETE requests for this path
return 404;
# 1. SPECIFIC ENDPOINTS (most specific first)
# PUT /upload (BUD-02) - File uploads
location = /upload {
if ($request_method !~ ^(PUT|HEAD)$) {
return 405;
}
# Pass to FastCGI application for processing
include fastcgi_params;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param REQUEST_SCHEME $scheme;
fastcgi_param HTTPS $https if_not_empty;
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
fastcgi_param REDIRECT_STATUS 200;
fastcgi_param SCRIPT_FILENAME $document_root/ginxsom.fcgi;
fastcgi_pass fastcgi_backend;
}
# Old working regex pattern - testing rollback
# GET /list/<pubkey> (BUD-02) - List user's blobs
location ~ "^/list/([a-f0-9]{64})$" {
if ($request_method !~ ^(GET)$) {
return 405;
}
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param REQUEST_SCHEME $scheme;
fastcgi_param HTTPS $https if_not_empty;
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
fastcgi_param REDIRECT_STATUS 200;
fastcgi_param SCRIPT_FILENAME $document_root/ginxsom.fcgi;
fastcgi_pass fastcgi_backend;
}
# PUT /mirror (BUD-04) - Mirror content
location = /mirror {
if ($request_method !~ ^(PUT)$) {
return 405;
}
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param REQUEST_SCHEME $scheme;
fastcgi_param HTTPS $https if_not_empty;
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
fastcgi_param REDIRECT_STATUS 200;
fastcgi_param SCRIPT_FILENAME $document_root/ginxsom.fcgi;
fastcgi_pass fastcgi_backend;
}
# HEAD/PUT /media (BUD-05) - Media operations
location = /media {
if ($request_method !~ ^(HEAD|PUT)$) {
return 405;
}
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param REQUEST_SCHEME $scheme;
fastcgi_param HTTPS $https if_not_empty;
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
fastcgi_param REDIRECT_STATUS 200;
fastcgi_param SCRIPT_FILENAME $document_root/ginxsom.fcgi;
fastcgi_pass fastcgi_backend;
}
# PUT /report (BUD-09) - Report content
location = /report {
if ($request_method !~ ^(PUT)$) {
return 405;
}
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param REQUEST_SCHEME $scheme;
fastcgi_param HTTPS $https if_not_empty;
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
fastcgi_param REDIRECT_STATUS 200;
fastcgi_param SCRIPT_FILENAME $document_root/ginxsom.fcgi;
fastcgi_pass fastcgi_backend;
}
# 2. BLOB OPERATIONS (SHA256 patterns)
# GET/HEAD/DELETE /<sha256> (BUD-01) - Blob operations with optional file extensions
location ~ "^/([a-f0-9]{64})(\.[a-zA-Z0-9]+)?$" {
limit_except HEAD GET {
deny all;
# Handle DELETE method via rewrite to avoid fastcgi_param in if block
if ($request_method = DELETE) {
rewrite ^/(.*)$ /fcgi-delete/$1 last;
}
# Route HEAD requests to FastCGI via rewrite
# Route HEAD requests to FastCGI for metadata
if ($request_method = HEAD) {
rewrite ^/(.*)$ /fcgi-head/$1 last;
}
# GET requests served directly with explicit file extensions
# Potentially in the future look at a LUA extension
try_files /$1.jpg /$1.jpeg /$1.png /$1.webp /$1.gif /$1.pdf /$1.mp4 /$1.mp3 /$1.txt /$1.md=404;
# Set appropriate headers for blobs
# Only allow GET for file serving at this point
if ($request_method != GET) {
return 405;
}
# GET requests - serve files directly with extension fallback
try_files /$1.txt /$1.jpg /$1.jpeg /$1.png /$1.webp /$1.gif /$1.pdf /$1.mp4 /$1.mp3 /$1.md =404;
# Cache headers for blob content
add_header Cache-Control "public, max-age=31536000, immutable";
add_header X-Content-Type-Options nosniff;
add_header X-Frame-Options DENY;
add_header X-XSS-Protection "1; mode=block";
}
# Internal handler for DELETE operations
location ~ "^/fcgi-delete/([a-f0-9]{64}).*$" {
internal;
fastcgi_pass fastcgi_backend;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD DELETE;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param REQUEST_URI /$1;
fastcgi_param DOCUMENT_URI /$1;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param REQUEST_SCHEME $scheme;
fastcgi_param HTTPS $https if_not_empty;
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
fastcgi_param REDIRECT_STATUS 200;
fastcgi_param SCRIPT_FILENAME $document_root/ginxsom.fcgi;
}
# 3. INTERNAL HANDLERS
# FastCGI handler for HEAD requests
location ~ "^/fcgi-head/([a-f0-9]{64}).*$" {
@@ -102,32 +261,7 @@ http {
fastcgi_param SERVER_NAME $server_name;
}
# Upload endpoint - requires authentication
location /upload {
# Pass to FastCGI application for processing
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root/ginxsom.fcgi;
fastcgi_pass fastcgi_backend;
# Only allow PUT method for uploads
if ($request_method !~ ^(PUT)$ ) {
return 405;
}
}
# List blobs endpoint - GET /list/<pubkey>
location ~ "^/list/([a-f0-9]{64}).*$" {
# Pass to FastCGI application for processing
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root/ginxsom.fcgi;
fastcgi_pass fastcgi_backend;
# Only allow GET method for list requests
if ($request_method !~ ^(GET)$ ) {
return 405;
}
}
# 4. UTILITY ENDPOINTS
# Health check endpoint
location /health {
@@ -144,7 +278,7 @@ http {
# Root redirect
location = / {
return 200 "Ginxsom Local Development Server\nTry: GET /<sha256>\nHealth: GET /health\n";
return 200 "Ginxsom Blossom Server\nEndpoints: GET /<sha256>, PUT /upload, GET /list/<pubkey>\nHealth: GET /health\n";
add_header Content-Type text/plain;
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -29,17 +29,13 @@ CREATE TABLE IF NOT EXISTS server_config (
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_blobs_size ON blobs(size);
-- Insert default server configuration
-- Insert basic server configuration
INSERT OR IGNORE INTO server_config (key, value, description) VALUES
('max_file_size', '104857600', 'Maximum file size in bytes (100MB)'),
('require_auth', 'false', 'Whether authentication is required for uploads'),
('allowed_types', '*', 'Allowed MIME types (* for all)'),
('server_name', 'ginxsom', 'Server name for responses'),
('storage_quota', '10737418240', 'Total storage quota in bytes (10GB)'),
('cleanup_interval', '86400', 'Cleanup interval in seconds (daily)'),
('max_upload_rate', '1048576', 'Max upload rate per client in bytes/sec (1MB/s)');
('server_name', 'ginxsom', 'Server name for responses');
-- View for storage statistics
CREATE VIEW IF NOT EXISTS storage_stats AS
@@ -52,186 +48,4 @@ SELECT
COUNT(DISTINCT uploader_pubkey) as unique_uploaders
FROM blobs;
-- View for recent uploads (last 24 hours)
CREATE VIEW IF NOT EXISTS recent_uploads AS
SELECT
sha256,
size,
type,
uploaded_at,
uploader_pubkey,
filename,
datetime(uploaded_at, 'unixepoch') as uploaded_datetime
FROM blobs
WHERE uploaded_at > (strftime('%s', 'now') - 86400)
ORDER BY uploaded_at DESC;
-- ============================================================================
-- AUTHENTICATION RULES SYSTEM
-- ============================================================================
-- Authentication rules table for flexible access control
CREATE TABLE IF NOT EXISTS auth_rules (
id INTEGER PRIMARY KEY AUTOINCREMENT,
rule_type TEXT NOT NULL, -- 'whitelist', 'blacklist', 'hash_blacklist', 'rate_limit', etc.
rule_target TEXT NOT NULL, -- pubkey, hash, IP, MIME type, etc.
rule_value TEXT, -- JSON for complex rules (optional)
operation TEXT NOT NULL DEFAULT '*', -- 'upload', 'delete', 'list', '*' (all operations)
enabled INTEGER NOT NULL DEFAULT 1, -- 0 = disabled, 1 = enabled
priority INTEGER NOT NULL DEFAULT 100, -- Lower numbers = higher priority (for conflict resolution)
expires_at INTEGER, -- Optional expiration timestamp
created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now')),
updated_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now')),
created_by TEXT, -- Admin pubkey who created this rule (optional)
description TEXT, -- Human-readable rule description
CHECK (enabled IN (0, 1)), -- Boolean constraint
CHECK (priority >= 0), -- Priority must be non-negative
CHECK (expires_at IS NULL OR expires_at > created_at) -- Expiration must be in future
);
-- Rule evaluation cache for performance optimization
CREATE TABLE IF NOT EXISTS auth_cache (
cache_key TEXT PRIMARY KEY, -- SHA-256 hash of request parameters
allowed INTEGER NOT NULL, -- 0 = denied, 1 = allowed
rule_id INTEGER, -- Which rule made the decision (optional)
rule_reason TEXT, -- Human-readable reason for decision
expires_at INTEGER NOT NULL, -- Cache entry expiration
created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now')),
CHECK (allowed IN (0, 1)), -- Boolean constraint
FOREIGN KEY (rule_id) REFERENCES auth_rules(id) ON DELETE SET NULL
);
-- Indexes for authentication system performance
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_expires ON auth_rules(expires_at);
CREATE INDEX IF NOT EXISTS idx_auth_cache_expires ON auth_cache(expires_at);
-- ============================================================================
-- ADMINISTRATIVE SYSTEM
-- ============================================================================
-- Administrators table for nostr-based server administration
CREATE TABLE IF NOT EXISTS administrators (
pubkey TEXT PRIMARY KEY NOT NULL, -- Nostr public key (64 hex chars)
permissions TEXT NOT NULL DEFAULT '[]', -- JSON array of permissions
added_by TEXT, -- Pubkey of admin who added this admin
added_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now')),
expires_at INTEGER, -- Optional expiration timestamp
enabled INTEGER NOT NULL DEFAULT 1, -- 0 = disabled, 1 = enabled
description TEXT, -- Human-readable description
last_seen INTEGER, -- Last administrative action timestamp
CHECK (length(pubkey) = 64), -- Ensure valid pubkey length
CHECK (enabled IN (0, 1)), -- Boolean constraint
CHECK (expires_at IS NULL OR expires_at > added_at), -- Expiration must be in future
FOREIGN KEY (added_by) REFERENCES administrators(pubkey) ON DELETE SET NULL
);
-- Administrative actions audit log
CREATE TABLE IF NOT EXISTS admin_log (
id INTEGER PRIMARY KEY AUTOINCREMENT,
admin_pubkey TEXT NOT NULL, -- Which admin performed the action
command TEXT NOT NULL, -- Administrative command executed
parameters TEXT, -- JSON command parameters
result TEXT, -- Success/failure result and details
timestamp INTEGER NOT NULL DEFAULT (strftime('%s', 'now')),
event_id TEXT, -- Reference to nostr event (optional)
target_table TEXT, -- Which table was affected (optional)
target_id TEXT, -- Which record was affected (optional)
ip_address TEXT, -- Client IP address (optional)
user_agent TEXT, -- Client user agent (optional)
FOREIGN KEY (admin_pubkey) REFERENCES administrators(pubkey) ON DELETE CASCADE
);
-- Server identity and administrative configuration
INSERT OR IGNORE INTO server_config (key, value, description) VALUES
('server_pubkey', '', 'Server nostr public key (generated on first run)'),
('server_privkey_file', 'keys/server.key', 'Path to encrypted server private key file'),
('admin_relays', '[]', 'JSON array of relay URLs for administrative events'),
('admin_event_processing', 'true', 'Enable nostr-based administrative event processing'),
('require_admin_auth', 'true', 'Require admin authorization for sensitive operations'),
('auth_rules_enabled', 'true', 'Enable flexible authentication rules system'),
('auth_cache_ttl', '300', 'Authentication cache TTL in seconds (5 minutes)'),
('admin_session_timeout', '3600', 'Administrative session timeout in seconds (1 hour)'),
('max_admin_log_entries', '10000', 'Maximum administrative log entries to retain');
-- Indexes for administrative system performance
CREATE INDEX IF NOT EXISTS idx_administrators_enabled ON administrators(enabled);
CREATE INDEX IF NOT EXISTS idx_administrators_expires ON administrators(expires_at);
CREATE INDEX IF NOT EXISTS idx_admin_log_timestamp ON admin_log(timestamp);
CREATE INDEX IF NOT EXISTS idx_admin_log_admin_pubkey ON admin_log(admin_pubkey);
CREATE INDEX IF NOT EXISTS idx_admin_log_command ON admin_log(command);
-- ============================================================================
-- VIEWS FOR ADMINISTRATIVE QUERIES
-- ============================================================================
-- View for active authentication rules
CREATE VIEW IF NOT EXISTS active_auth_rules AS
SELECT
id,
rule_type,
rule_target,
rule_value,
operation,
priority,
expires_at,
created_at,
created_by,
description,
CASE
WHEN expires_at IS NULL THEN 'never'
WHEN expires_at > strftime('%s', 'now') THEN 'active'
ELSE 'expired'
END as status
FROM auth_rules
WHERE enabled = 1
ORDER BY priority ASC, created_at ASC;
-- View for active administrators
CREATE VIEW IF NOT EXISTS active_administrators AS
SELECT
pubkey,
permissions,
added_by,
added_at,
expires_at,
description,
last_seen,
CASE
WHEN expires_at IS NULL THEN 'never'
WHEN expires_at > strftime('%s', 'now') THEN 'active'
ELSE 'expired'
END as status,
datetime(added_at, 'unixepoch') as added_datetime,
datetime(last_seen, 'unixepoch') as last_seen_datetime
FROM administrators
WHERE enabled = 1;
-- View for recent administrative actions (last 7 days)
CREATE VIEW IF NOT EXISTS recent_admin_actions AS
SELECT
id,
admin_pubkey,
command,
parameters,
result,
timestamp,
event_id,
target_table,
target_id,
datetime(timestamp, 'unixepoch') as action_datetime
FROM admin_log
WHERE timestamp > (strftime('%s', 'now') - 604800) -- 7 days
ORDER BY timestamp DESC;
-- View for authentication statistics
CREATE VIEW IF NOT EXISTS auth_stats AS
SELECT
(SELECT COUNT(*) FROM auth_rules WHERE enabled = 1) as active_rules,
(SELECT COUNT(*) FROM auth_rules WHERE enabled = 1 AND expires_at > strftime('%s', 'now')) as non_expired_rules,
(SELECT COUNT(*) FROM auth_cache WHERE expires_at > strftime('%s', 'now')) as cached_decisions,
(SELECT COUNT(*) FROM administrators WHERE enabled = 1) as active_admins,
(SELECT COUNT(*) FROM admin_log WHERE timestamp > (strftime('%s', 'now') - 86400)) as daily_admin_actions;

42
debug_hash_data.log Normal file
View File

@@ -0,0 +1,42 @@
=== HASH DEBUG SESSION ===
Content length: 296
File data to hash: 5465737420626c6f6220636f6e74656e7420666f722047696e78736f6d20426c6f73736f6d207365727665720a54696d657374616d703a20323032352d30392d30325431333a35393a31312d30343a30300a52616e646f6d20646174613a20373730353061633932653438633437373436653164393035343164393930373965383131633539666464313039343931313635623664333130656638646137360a54657374206d6573736167653a2048656c6c6f2066726f6d207075745f746573742e7368210a0a546869732066696c65206973207573656420746f2074657374207468652075706c6f61642066756e6374696f6e616c6974790a6f66207468652047696e78736f6d20426c6f73736f6d2073657276657220696d706c656d656e746174696f6e2e0a
File data as string: Test blob content for Ginxsom Blossom server
Timestamp: 2025-09-02T13:59:11-04:00
Random data: 77050ac92e48c47746e1d90541d99079e811c59fdd109491165b6d310ef8da76
Test message: Hello from put_test.sh!
This file is used to test the upload functionality
of the Ginxsom Blossom server implementation.
Calculated SHA-256: e6bdc6b5336072dc05e1a6eea68c75110cbd6c1994f5dbfe75c5880a8b43dcf4
=== END DEBUG SESSION ===
=== HASH DEBUG SESSION ===
Content length: 296
File data to hash: 5465737420626c6f6220636f6e74656e7420666f722047696e78736f6d20426c6f73736f6d207365727665720a54696d657374616d703a20323032352d30392d30325431343a32323a35352d30343a30300a52616e646f6d20646174613a20393532613538346438663366633662356534396231646661626266363864373633383564366435313134326161303731373063373138393765613836316330330a54657374206d6573736167653a2048656c6c6f2066726f6d207075745f746573742e7368210a0a546869732066696c65206973207573656420746f2074657374207468652075706c6f61642066756e6374696f6e616c6974790a6f66207468652047696e78736f6d20426c6f73736f6d2073657276657220696d706c656d656e746174696f6e2e0a
File data as string: Test blob content for Ginxsom Blossom server
Timestamp: 2025-09-02T14:22:55-04:00
Random data: 952a584d8f3fc6b5e49b1dfabbf68d76385d6d51142aa07170c71897ea861c03
Test message: Hello from put_test.sh!
This file is used to test the upload functionality
of the Ginxsom Blossom server implementation.
Calculated SHA-256: 52d7920725bbbd86d54a7802a45c0c39fa8158705436fc57d7c4fb4be1ce75f1
=== END DEBUG SESSION ===
=== HASH DEBUG SESSION ===
Content length: 296
File data to hash: 5465737420626c6f6220636f6e74656e7420666f722047696e78736f6d20426c6f73736f6d207365727665720a54696d657374616d703a20323032352d30392d30325431353a31373a34372d30343a30300a52616e646f6d20646174613a20346538666566656333313034623838343038663063373161373365393762613137363834363734376535353737333334643432626533313438333961396262610a54657374206d6573736167653a2048656c6c6f2066726f6d207075745f746573742e7368210a0a546869732066696c65206973207573656420746f2074657374207468652075706c6f61642066756e6374696f6e616c6974790a6f66207468652047696e78736f6d20426c6f73736f6d2073657276657220696d706c656d656e746174696f6e2e0a
File data as string: Test blob content for Ginxsom Blossom server
Timestamp: 2025-09-02T15:17:47-04:00
Random data: 4e8fefec3104b88408f0c71a73e97ba176846747e5577334d42be314839a9bba
Test message: Hello from put_test.sh!
This file is used to test the upload functionality
of the Ginxsom Blossom server implementation.
Calculated SHA-256: 115c440bf5b69015f8b844d325ae33458a555b463d5d53e4dfe2d24cd740c5bc
=== END DEBUG SESSION ===

36
debug_validation.log Normal file
View File

@@ -0,0 +1,36 @@
=== STRUCTURE VALIDATION DEBUG ===
nostr_validate_event_structure result: 0 (Success)
=== END STRUCTURE DEBUG ===
=== CRYPTO VALIDATION DEBUG ===
nostr_verify_event_signature result: 0 (Success)
=== END CRYPTO DEBUG ===
=== COMPLETE VALIDATION DEBUG ===
nostr_validate_event result: 0 (Success)
=== END COMPLETE DEBUG ===
=== STRUCTURE VALIDATION DEBUG ===
nostr_validate_event_structure result: 0 (Success)
=== END STRUCTURE DEBUG ===
=== CRYPTO VALIDATION DEBUG ===
nostr_verify_event_signature result: 0 (Success)
=== END CRYPTO DEBUG ===
=== COMPLETE VALIDATION DEBUG ===
nostr_validate_event result: 0 (Success)
=== END COMPLETE DEBUG ===
=== STRUCTURE VALIDATION DEBUG ===
nostr_validate_event_structure result: 0 (Success)
=== END STRUCTURE DEBUG ===
=== CRYPTO VALIDATION DEBUG ===
nostr_verify_event_signature result: 0 (Success)
=== END CRYPTO DEBUG ===
=== COMPLETE VALIDATION DEBUG ===
nostr_validate_event result: 0 (Success)
=== END COMPLETE DEBUG ===

View File

@@ -12,3 +12,17 @@
127.0.0.1 - - [02/Sep/2025:12:45:42 -0400] "PUT /upload HTTP/1.1" 200 262 "-" "curl/8.15.0"
127.0.0.1 - - [02/Sep/2025:12:46:50 -0400] "PUT /upload HTTP/1.1" 200 262 "-" "curl/8.15.0"
127.0.0.1 - - [02/Sep/2025:12:49:20 -0400] "GET /list/79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 HTTP/1.1" 200 1520 "-" "curl/8.15.0"
127.0.0.1 - - [02/Sep/2025:13:59:11 -0400] "PUT /upload HTTP/1.1" 200 262 "-" "curl/8.15.0"
127.0.0.1 - - [02/Sep/2025:13:59:38 -0400] "GET /e6bdc6b5336072dc05e1a6eea68c75110cbd6c1994f5dbfe75c5880a8b43dcf4.txt HTTP/1.1" 404 162 "-" "curl/8.15.0"
127.0.0.1 - - [02/Sep/2025:14:03:38 -0400] "GET /e6bdc6b5336072dc05e1a6eea68c75110cbd6c1994f5dbfe75c5880a8b43dcf4.txt HTTP/1.1" 404 162 "-" "curl/8.15.0"
127.0.0.1 - - [02/Sep/2025:14:05:11 -0400] "GET /e6bdc6b5336072dc05e1a6eea68c75110cbd6c1994f5dbfe75c5880a8b43dcf4.txt HTTP/1.1" 404 162 "-" "curl/8.15.0"
127.0.0.1 - - [02/Sep/2025:14:22:56 -0400] "PUT /upload HTTP/1.1" 200 262 "-" "curl/8.15.0"
127.0.0.1 - - [02/Sep/2025:14:23:24 -0400] "GET /e6bdc6b5336072dc05e1a6eea68c75110cbd6c1994f5dbfe75c5880a8b43dcf4.txt HTTP/1.1" 404 162 "-" "curl/8.15.0"
127.0.0.1 - - [02/Sep/2025:14:24:38 -0400] "GET /list/79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 HTTP/1.1" 200 635 "-" "curl/8.15.0"
127.0.0.1 - - [02/Sep/2025:14:25:06 -0400] "GET /e6bdc6b5336072dc05e1a6eea68c75110cbd6c1994f5dbfe75c5880a8b43dcf4 HTTP/1.1" 404 162 "-" "curl/8.15.0"
127.0.0.1 - - [02/Sep/2025:14:25:10 -0400] "GET /e6bdc6b5336072dc05e1a6eea68c75110cbd6c1994f5dbfe75c5880a8b43dcf4.txt HTTP/1.1" 404 162 "-" "curl/8.15.0"
127.0.0.1 - - [02/Sep/2025:15:17:32 -0400] "GET /list/79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 HTTP/1.1" 200 635 "-" "curl/8.15.0"
127.0.0.1 - - [02/Sep/2025:15:17:47 -0400] "PUT /upload HTTP/1.1" 200 262 "-" "curl/8.15.0"
127.0.0.1 - - [02/Sep/2025:15:18:08 -0400] "GET /e6bdc6b5336072dc05e1a6eea68c75110cbd6c1994f5dbfe75c5880a8b43dcf4.txt HTTP/1.1" 404 162 "-" "curl/8.15.0"
127.0.0.1 - - [02/Sep/2025:15:20:15 -0400] "GET /e6bdc6b5336072dc05e1a6eea68c75110cbd6c1994f5dbfe75c5880a8b43dcf4.txt HTTP/1.1" 200 296 "-" "curl/8.15.0"
127.0.0.1 - - [02/Sep/2025:15:20:49 -0400] "GET /e6bdc6b5336072dc05e1a6eea68c75110cbd6c1994f5dbfe75c5880a8b43dcf4 HTTP/1.1" 200 296 "-" "curl/8.15.0"

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1 +1 @@
176726
189132

View File

@@ -0,0 +1 @@
spawn-fcgi: child exited with: 127

View File

@@ -141,8 +141,10 @@ if ! command -v spawn-fcgi &> /dev/null; then
exit 1
fi
# Start FastCGI application with stderr logging using wrapper
spawn-fcgi -s "$SOCKET_PATH" -M 666 -u "$USER" -g "$USER" -f "./fcgi-wrapper.sh" -P "$PID_FILE" 2>logs/spawn-fcgi.log
# Start FastCGI application with stderr logging (no wrapper needed)
# Create stderr log with timestamp
echo "FastCGI starting at $(date)" > logs/fcgi-stderr.log
spawn-fcgi -s "$SOCKET_PATH" -M 666 -u "$USER" -g "$USER" -f "$FCGI_BINARY" -P "$PID_FILE" 2>>logs/fcgi-stderr.log
if [ $? -eq 0 ] && [ -f "$PID_FILE" ]; then
PID=$(cat "$PID_FILE")

View File

@@ -2489,6 +2489,14 @@ void handle_upload_request(void) {
size_t bytes_written = fwrite(file_data, 1, content_length, outfile);
fclose(outfile);
// Set file permissions to 644 (owner read/write, group/others read) - standard for web files
if (chmod(filepath, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) != 0) {
fprintf(stderr, "WARNING: Failed to set file permissions for %s\r\n", filepath);
// Continue anyway - this is not a fatal error
} else {
fprintf(stderr, "DEBUG: File permissions set to 644 for %s\r\n", filepath);
}
free(file_data);
if (bytes_written != (size_t)content_length) {