revert
All checks were successful
Deploy Production (qr.crewsportswear.app) / deploy (push) Successful in 35s
All checks were successful
Deploy Production (qr.crewsportswear.app) / deploy (push) Successful in 35s
This commit is contained in:
52
server.js
52
server.js
@@ -3,57 +3,9 @@ const QRCode = require("qrcode");
|
||||
|
||||
const app = express();
|
||||
const PORT = process.env.PORT || 3000;
|
||||
const TRUST_PROXY = process.env.TRUST_PROXY !== "false";
|
||||
const ALLOWED_QR_IPS = new Set(
|
||||
(process.env.ALLOWED_QR_IPS || "")
|
||||
.split(",")
|
||||
.map((ip) => ip.trim())
|
||||
.filter(Boolean)
|
||||
.map((ip) => normalizeIp(ip))
|
||||
);
|
||||
|
||||
app.set("trust proxy", TRUST_PROXY);
|
||||
|
||||
app.use(express.json({ limit: "100kb" }));
|
||||
|
||||
function normalizeIp(ip) {
|
||||
if (!ip || typeof ip !== "string") {
|
||||
return "";
|
||||
}
|
||||
|
||||
const trimmed = ip.trim();
|
||||
const withoutMappedV4Prefix = trimmed.startsWith("::ffff:") ? trimmed.slice(7) : trimmed;
|
||||
|
||||
const ipv4WithPortMatch = withoutMappedV4Prefix.match(/^(\d+\.\d+\.\d+\.\d+):(\d+)$/);
|
||||
if (ipv4WithPortMatch) {
|
||||
return ipv4WithPortMatch[1];
|
||||
}
|
||||
|
||||
return withoutMappedV4Prefix;
|
||||
}
|
||||
|
||||
function getClientIp(req) {
|
||||
const forwardedFor = req.headers["x-forwarded-for"];
|
||||
if (typeof forwardedFor === "string" && forwardedFor.trim()) {
|
||||
return normalizeIp(forwardedFor.split(",")[0]);
|
||||
}
|
||||
|
||||
return normalizeIp(req.ip || req.socket?.remoteAddress || "");
|
||||
}
|
||||
|
||||
function enforceQrIpAllowlist(req, res, next) {
|
||||
if (ALLOWED_QR_IPS.size === 0) {
|
||||
return next();
|
||||
}
|
||||
|
||||
const clientIp = getClientIp(req);
|
||||
if (ALLOWED_QR_IPS.has(clientIp)) {
|
||||
return next();
|
||||
}
|
||||
|
||||
return res.status(403).json({ error: "Access denied for this IP address" });
|
||||
}
|
||||
|
||||
function parseIntWithBounds(value, fallback, min, max) {
|
||||
const parsed = Number.parseInt(value, 10);
|
||||
if (!Number.isFinite(parsed)) {
|
||||
@@ -118,8 +70,8 @@ app.get("/health", (_req, res) => {
|
||||
res.json({ status: "ok" });
|
||||
});
|
||||
|
||||
app.get("/api/qr", enforceQrIpAllowlist, (req, res, next) => sendQrPng(req.query, res, next));
|
||||
app.post("/api/qr", enforceQrIpAllowlist, (req, res, next) => sendQrPng(req.body, res, next));
|
||||
app.get("/api/qr", (req, res, next) => sendQrPng(req.query, res, next));
|
||||
app.post("/api/qr", (req, res, next) => sendQrPng(req.body, res, next));
|
||||
|
||||
app.use((err, _req, res, _next) => {
|
||||
console.error(err);
|
||||
|
||||
Reference in New Issue
Block a user