91 lines
2.4 KiB
JavaScript
91 lines
2.4 KiB
JavaScript
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);
|
|
}); |