tight
This commit is contained in:
parent
44020d24e4
commit
07fb985a3a
1 changed files with 46 additions and 3 deletions
|
|
@ -8,19 +8,53 @@ import { readFileSync } from "node:fs";
|
|||
import { minify } from "uglify-js";
|
||||
const app = express();
|
||||
|
||||
const allowedSites = new Set(
|
||||
(process.env.ALLOWED_SITES || "")
|
||||
.split(",")
|
||||
.map(s => s.trim().toLowerCase())
|
||||
.filter(Boolean)
|
||||
);
|
||||
|
||||
const clientJS =
|
||||
minify(readFileSync("src/clientAnalytics.js", "utf8")).code;
|
||||
|
||||
app.use(bodyParser.json({ limit: "512kb" }));
|
||||
app.use(
|
||||
cors()
|
||||
cors({
|
||||
origin: (origin, callback) => {
|
||||
if (!origin) return callback(null, true);
|
||||
try {
|
||||
const host = new URL(origin).hostname.toLowerCase();
|
||||
if (allowedSites.size === 0 || allowedSites.has(host)) {
|
||||
return callback(null, true);
|
||||
}
|
||||
return callback(new Error("Not allowed by CORS"));
|
||||
} catch {
|
||||
return callback(new Error("Invalid Origin"));
|
||||
}
|
||||
},
|
||||
methods: ["GET", "POST", "OPTIONS"],
|
||||
allowedHeaders: ["Content-Type"],
|
||||
})
|
||||
);
|
||||
|
||||
if (process.env.TRUST_PROXY) {
|
||||
app.set("trust proxy", true);
|
||||
}
|
||||
app.options("*path", (req, res) => {
|
||||
res.set("Access-Control-Allow-Origin", "*");
|
||||
const origin = req.get("Origin") || "";
|
||||
let ok = true;
|
||||
if (allowedSites.size > 0) {
|
||||
try {
|
||||
const host = new URL(origin).hostname.toLowerCase();
|
||||
ok = allowedSites.has(host);
|
||||
} catch {
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
if (!ok) return res.sendStatus(403);
|
||||
res.set("Vary", "Origin");
|
||||
res.set("Access-Control-Allow-Origin", origin || "*");
|
||||
res.set("Access-Control-Allow-Methods", "GET,POST,OPTIONS");
|
||||
res.set("Access-Control-Allow-Headers", "Content-Type");
|
||||
res.sendStatus(204);
|
||||
|
|
@ -108,6 +142,10 @@ app.post("/some-cool-endpoint", (req, res) => {
|
|||
} catch (err) {
|
||||
}
|
||||
}
|
||||
site = (site || "").toLowerCase();
|
||||
if (allowedSites.size > 0 && !allowedSites.has(site)) {
|
||||
return res.sendStatus(403);
|
||||
}
|
||||
|
||||
eventCounter.labels(site, e.type, country, device, browser, os).inc();
|
||||
|
||||
|
|
@ -136,9 +174,14 @@ app.get("/js", async (req, res) => {
|
|||
const partial_url = req.protocol + "://" + req.get("host");
|
||||
|
||||
const url = new URL(partial_url + req.url);
|
||||
const id = url.searchParams.get("site") || url.hostname;
|
||||
const id = (url.searchParams.get("site") || url.hostname || "").toLowerCase();
|
||||
if (allowedSites.size > 0 && !allowedSites.has(id)) {
|
||||
res.status(403).send("site not allowed");
|
||||
return;
|
||||
}
|
||||
|
||||
res.set('Content-Type', 'text/javascript')
|
||||
res.set('Vary', 'Origin')
|
||||
res.end(clientJS.replace(
|
||||
"some_misc_string", partial_url
|
||||
).replace("some_site_string", id)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue