docfast/src/services/db.ts
OpenClaw 9541ae1826
Some checks failed
Deploy to Production / Deploy to Server (push) Failing after 20s
Backend hardening: structured logging, timeouts, memory leak fixes, compression, XSS fix
- Add pino structured logging with request IDs (X-Request-Id header)
- Add 30s timeout to acquirePage() and renderPdf/renderUrlPdf
- Add verification cache cleanup (every 15min) and rate limit cleanup (every 60s)
- Read version from package.json in health endpoint
- Add compression middleware
- Escape currency in templates (XSS fix)
- Add static asset caching (1h maxAge)
- Remove deprecated docker-compose version field
- Replace all console.log/error with pino logger
2026-02-16 08:27:42 +00:00

66 lines
2 KiB
TypeScript

import pg from "pg";
import logger from "./logger.js";
const { Pool } = pg;
const pool = new Pool({
host: process.env.DATABASE_HOST || "172.17.0.1",
port: parseInt(process.env.DATABASE_PORT || "5432", 10),
database: process.env.DATABASE_NAME || "docfast",
user: process.env.DATABASE_USER || "docfast",
password: process.env.DATABASE_PASSWORD || "docfast",
max: 10,
idleTimeoutMillis: 30000,
});
pool.on("error", (err) => {
logger.error({ err }, "Unexpected PostgreSQL pool error");
});
export async function initDatabase(): Promise<void> {
const client = await pool.connect();
try {
await client.query(`
CREATE TABLE IF NOT EXISTS api_keys (
key TEXT PRIMARY KEY,
tier TEXT NOT NULL DEFAULT 'free',
email TEXT NOT NULL DEFAULT '',
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
stripe_customer_id TEXT
);
CREATE INDEX IF NOT EXISTS idx_api_keys_email ON api_keys(email);
CREATE INDEX IF NOT EXISTS idx_api_keys_stripe ON api_keys(stripe_customer_id);
CREATE TABLE IF NOT EXISTS verifications (
id SERIAL PRIMARY KEY,
email TEXT NOT NULL,
token TEXT NOT NULL UNIQUE,
api_key TEXT NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
verified_at TIMESTAMPTZ
);
CREATE INDEX IF NOT EXISTS idx_verifications_email ON verifications(email);
CREATE INDEX IF NOT EXISTS idx_verifications_token ON verifications(token);
CREATE TABLE IF NOT EXISTS pending_verifications (
email TEXT PRIMARY KEY,
code TEXT NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
expires_at TIMESTAMPTZ NOT NULL,
attempts INT NOT NULL DEFAULT 0
);
CREATE TABLE IF NOT EXISTS usage (
key TEXT PRIMARY KEY,
count INT NOT NULL DEFAULT 0,
month_key TEXT NOT NULL
);
`);
logger.info("PostgreSQL tables initialized");
} finally {
client.release();
}
}
export { pool };
export default pool;