import assert from "node:assert/strict"; import { mkdtemp, readFile } from "node:fs/promises"; import os from "node:os"; import path from "node:path"; import test from "node:test"; import { DatabaseClient, normalizeSqlForMysql } from "../lib/database.ts"; import { LocalObjectStore, normalizeObjectKey } from "../lib/object-store.ts"; import { requestUsesHttps } from "../lib/user-auth.ts"; test("normalizes the limited SQLite syntax still used by business queries", () => { assert.match( normalizeSqlForMysql("INSERT OR IGNORE INTO collection_runs (id) VALUES (?)"), /^INSERT IGNORE INTO/, ); const upsert = normalizeSqlForMysql( "INSERT INTO accounts (id, nickname) VALUES (?, ?) ON CONFLICT(id) DO UPDATE SET nickname = excluded.nickname", ); assert.match(upsert, /ON DUPLICATE KEY UPDATE/); assert.match(upsert, /nickname = VALUES\(nickname\)/); assert.equal( normalizeSqlForMysql("SELECT datetime(publish_time, '+7 days')"), "SELECT DATE_ADD(publish_time, INTERVAL 7 DAY)", ); }); test("normalizes ISO timestamps before binding to MySQL DATETIME", async () => { let receivedParams; const database = new DatabaseClient({ async execute(_sql, params) { receivedParams = params; return [{ affectedRows: 1, insertId: 0 }]; }, }); await database .prepare("INSERT INTO auth_sessions (expires_at) VALUES (?)") .bind("2026-08-11T02:03:04.567Z") .run(); assert.deepEqual(receivedParams, ["2026-08-11 02:03:04.567"]); }); test("marks login cookies secure behind the Nginx HTTPS proxy", () => { assert.equal( requestUsesHttps( new Request("http://app:3000/api/auth/login", { headers: { "x-forwarded-proto": "https" }, }), ), true, ); assert.equal(requestUsesHttps(new Request("http://localhost/login")), false); }); test("stores uploaded objects under a safe persistent directory", async () => { const directory = await mkdtemp(path.join(os.tmpdir(), "koc-object-store-")); const store = new LocalObjectStore(directory); await store.put("creator-center/dist-1/shot.png", Uint8Array.from([1, 2, 3]), { httpMetadata: { contentType: "image/png" }, }); const object = await store.get("creator-center/dist-1/shot.png"); assert.ok(object); assert.deepEqual([...new Uint8Array(await object.arrayBuffer())], [1, 2, 3]); const headers = new Headers(); object.writeHttpMetadata(headers); assert.equal(headers.get("Content-Type"), "image/png"); assert.equal( JSON.parse( await readFile( path.join(directory, "creator-center/dist-1/shot.png.metadata.json"), "utf8", ), ).contentType, "image/png", ); assert.throws(() => normalizeObjectKey("../secret"), /不安全/); });