commit 80d6e4724a7390b29904e0cbb2d0b6fd5907c495 Author: sky Date: Sat Nov 22 15:26:30 2025 -0500 first commit (ty gemini) diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f0b1dc8 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +links* \ No newline at end of file diff --git a/description.md b/description.md new file mode 100644 index 0000000..d0ecc97 --- /dev/null +++ b/description.md @@ -0,0 +1,21 @@ +This project is a checker for the Caddy On Demand TLS service. +This is intended to be used with Caddy as the server to check if a domain is valid. +All domains should be allowed. +However, each domain should have a maximum of 100 certificates for it. + +ie: +example.com, test.example.com, and testing.tester.example.com count as 3 certificates for example.com + +The domain should also have a maximum of 5 parts +1.2.3.example.com is valid +1.2.3.4.example.com is not valid + +If a domain is already in the database, it should return a 200 and not add it to the database. + +As an example: +/check?domain=example.com -> 200 & added to database +/check?domain=example.com -> 200 +/check?domain=1.example.com -> 200 & added to database +/check?domain=this.is.a.long.domain.example.com -> 400 +... after 100 domains +/check ?domain=100.example.com -> 400 \ No newline at end of file diff --git a/index.js b/index.js new file mode 100644 index 0000000..1f50d20 --- /dev/null +++ b/index.js @@ -0,0 +1,91 @@ +import { Database } from "bun:sqlite"; +import express from "express"; +const port = process.env.PORT || 3000; + +const db = new Database("links.sqlite"); +db.exec("PRAGMA journal_mode = WAL;"); + +db.run(` + CREATE TABLE IF NOT EXISTS links ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + link TEXT, + base_domain TEXT + ) +`); +db.exec("CREATE UNIQUE INDEX IF NOT EXISTS unique_link ON links(link);"); +db.exec("CREATE INDEX IF NOT EXISTS idx_base_domain ON links(base_domain);"); + +// Migration for existing databases +try { + const columns = db.query("PRAGMA table_info(links)").all(); + if (!columns.find(c => c.name === "base_domain")) { + db.run("ALTER TABLE links ADD COLUMN base_domain TEXT"); + db.run("CREATE INDEX IF NOT EXISTS idx_base_domain ON links(base_domain)"); + // Backfill would go here, but skipping for brevity/performance on startup + // In a real app, we'd run a migration script. + } +} catch (e) { + // Ignore errors +} + +const app = express(); + +const domainCount = db.prepare( + "SELECT COUNT(*) AS count FROM links WHERE base_domain = $base" +); +const duplicateLink = db.prepare( + "SELECT 1 FROM links WHERE link = $link LIMIT 1" +); +const insert = db.prepare("INSERT OR IGNORE INTO links (link, base_domain) VALUES ($link, $base_domain)"); + +const getBaseDomain = (hostname) => { + let parts = hostname.split("."); + if (parts.length <= 2) { + return hostname; + } + return parts.slice(-2).join("."); +}; + +const parseDomain = (input) => { + if (!input.includes("://")) { + input = "https://" + input; + } + return new URL(input); +}; + +app.get("/check", async (req, res) => { + if (!req.query.domain) { + return res.status(400).end(); + } + + let domain; + try { + domain = parseDomain(req.query.domain); + } catch (error) { + return res.status(400).end(); + } + + const hostname = domain.hostname.toLowerCase(); + if (hostname.split(".").length > 5) { + return res.status(400).end(); + } + + if (duplicateLink.get({ $link: hostname })) { + return res.status(200).end(); + } + + const baseDomain = getBaseDomain(hostname); + const { count } = domainCount.get({ $base: baseDomain }); + if (count >= 3) { + return res.status(400).end(); + } + + insert.run({ $link: hostname, $base_domain: baseDomain }); + + return res.status(200).end(); +}); + +const server = app.listen(port, () => { + console.log("Express is online."); + console.log("- http://localhost:" + port); +}); \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..18ab153 --- /dev/null +++ b/package.json @@ -0,0 +1,12 @@ +{ + "name": "caddy-byod-v2", + "version": "1.0.0", + "description": "", + "license": "ISC", + "author": "", + "type": "commonjs", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + } +}