webupdate

This commit is contained in:
Local Server
2026-01-18 02:22:05 -06:00
parent 6fc159051a
commit 2a2a3d99e5
135 changed files with 54897 additions and 9825 deletions

View File

@@ -138,34 +138,38 @@ app.get("/index", (req, res) => {
app.use(
express.static(path.join(baseDir, "public"), {
index: false,
maxAge: "30d", // Cache static files for 30 days
etag: true,
lastModified: true,
setHeaders: (res, filepath) => {
// Aggressive caching for versioned files
if (
filepath.includes("?v=") ||
filepath.match(/\.(\w+)\.[a-f0-9]{8,}\./)
) {
res.setHeader("Cache-Control", "public, max-age=31536000, immutable");
// Short cache for CSS/JS files (use cache busting for updates)
if (filepath.endsWith(".css") || filepath.endsWith(".js")) {
res.setHeader("Cache-Control", "public, max-age=300"); // 5 minutes
} else if (filepath.endsWith(".html")) {
res.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
} else {
res.setHeader("Cache-Control", "public, max-age=86400"); // 1 day default
}
},
})
);
app.use(
"/assets",
express.static(path.join(baseDir, "assets"), {
maxAge: "365d", // Cache assets for 1 year
express.static(path.join(baseDir, "public", "assets"), {
etag: true,
lastModified: true,
immutable: true,
setHeaders: (res, filepath) => {
// Add immutable for all asset files
res.setHeader("Cache-Control", "public, max-age=31536000, immutable");
// Add resource hints for fonts
if (filepath.endsWith(".woff2") || filepath.endsWith(".woff")) {
// Very short cache for CSS/JS to see changes quickly (with cache busting)
if (filepath.endsWith(".css") || filepath.endsWith(".js")) {
res.setHeader("Cache-Control", "public, max-age=300"); // 5 minutes
} else if (
filepath.endsWith(".woff2") ||
filepath.endsWith(".woff") ||
filepath.endsWith(".ttf")
) {
res.setHeader("Cache-Control", "public, max-age=31536000, immutable");
res.setHeader("Access-Control-Allow-Origin", "*");
} else {
res.setHeader("Cache-Control", "public, max-age=86400"); // 1 day for images
}
},
})
@@ -183,6 +187,22 @@ app.use(
);
// Session middleware
// SECURITY: Ensure SESSION_SECRET is set - fail fast if missing
if (
!process.env.SESSION_SECRET ||
process.env.SESSION_SECRET === "change-this-secret"
) {
if (!isDevelopment()) {
logger.error(
"CRITICAL: SESSION_SECRET environment variable must be set in production!"
);
process.exit(1);
}
logger.warn(
"WARNING: Using insecure session secret. Set SESSION_SECRET in production!"
);
}
app.use(
session({
store: new pgSession({
@@ -190,7 +210,9 @@ app.use(
tableName: "session",
createTableIfMissing: true,
}),
secret: process.env.SESSION_SECRET || "change-this-secret",
secret:
process.env.SESSION_SECRET ||
(isDevelopment() ? "dev-secret-change-in-production" : ""),
resave: false,
saveUninitialized: false,
cookie: {
@@ -227,6 +249,8 @@ const adminRoutes = require("./routes/admin");
const publicRoutes = require("./routes/public");
const usersRoutes = require("./routes/users");
const uploadRoutes = require("./routes/upload");
const customerAuthRoutes = require("./routes/customer-auth");
const customerCartRoutes = require("./routes/customer-cart");
// Admin redirect - handle /admin to redirect to login (must be before static files)
app.get("/admin", (req, res) => {
@@ -259,6 +283,14 @@ app.use((req, res, next) => {
}
}
// Handle dynamic product pages: /product/:slug -> product.html
if (req.path.startsWith("/product/")) {
const productHtmlPath = path.join(baseDir, "public", "product.html");
if (fs.existsSync(productHtmlPath)) {
return res.sendFile(productHtmlPath);
}
}
// Check if path is for public pages (root level pages)
if (!req.path.includes("/admin/")) {
let cleanPath = req.path.replace(/^\//, "").replace(/\.html$/, "");
@@ -281,6 +313,8 @@ app.use((req, res, next) => {
// Apply rate limiting to API routes
app.use("/api/admin/login", authLimiter);
app.use("/api/admin/logout", authLimiter);
app.use("/api/customers/login", authLimiter);
app.use("/api/customers/signup", authLimiter);
app.use("/api", apiLimiter);
// API Routes
@@ -288,6 +322,8 @@ app.use("/api/admin", authRoutes);
app.use("/api/admin", adminRoutes);
app.use("/api/admin/users", usersRoutes);
app.use("/api/admin", uploadRoutes);
app.use("/api/customers", customerAuthRoutes);
app.use("/api/customers", customerCartRoutes);
app.use("/api", publicRoutes);
// Admin static files (must be after URL rewriting)