diff --git a/migrations/0002_ddns_rate_limits.sql b/migrations/0002_ddns_rate_limits.sql new file mode 100644 index 0000000..0c79e52 --- /dev/null +++ b/migrations/0002_ddns_rate_limits.sql @@ -0,0 +1,12 @@ +-- Fixed-window rate limit state for DDNS update requests. +-- One row is stored per client key so the worker can slow down runaway +-- clients, password guessing, or compromised automation. + +CREATE TABLE IF NOT EXISTS ddns_rate_limits ( + key TEXT PRIMARY KEY NOT NULL, + window_started_at INTEGER NOT NULL, + request_count INTEGER NOT NULL, + updated_at INTEGER NOT NULL +); + +CREATE INDEX IF NOT EXISTS idx_ddns_rate_limits_updated_at ON ddns_rate_limits (updated_at); \ No newline at end of file diff --git a/src/logging.ts b/src/logging.ts index 8edf4a2..bc48c3a 100644 --- a/src/logging.ts +++ b/src/logging.ts @@ -10,6 +10,9 @@ import type { UpdateAction } from "./types"; +// The Worker may need to recreate this table lazily on first write. Migration +// files live on disk for operator and test workflows, but the runtime bundle +// cannot read them from the filesystem inside Workers. const LOG_SCHEMA_STATEMENTS = [ `CREATE TABLE IF NOT EXISTS ddns_logs ( id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, diff --git a/src/rate-limit.ts b/src/rate-limit.ts index 3e48038..373a6fd 100644 --- a/src/rate-limit.ts +++ b/src/rate-limit.ts @@ -1,3 +1,6 @@ +// The Worker may need to recreate this table lazily when rate limiting is hit +// before remote migrations have run. Migration files exist for operator and +// test workflows, but the runtime bundle cannot load SQL files from disk. const RATE_LIMIT_SCHEMA_STATEMENTS = [ `CREATE TABLE IF NOT EXISTS ddns_rate_limits ( key TEXT PRIMARY KEY NOT NULL,