-
Notifications
You must be signed in to change notification settings - Fork 0
/
server.js
129 lines (115 loc) · 3.88 KB
/
server.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
import express from "express";
import { fileURLToPath } from "url";
import { dirname, join } from "path";
import { createRequestHandler } from "@remix-run/express";
import * as build from "./build/server/index.js"; // Import the build object
import cors from "cors";
import helmet from "helmet";
import { xss } from "express-xss-sanitizer";
import hpp from "hpp";
import dotenv from "dotenv";
import trackingRouter from "./server_routes/trackingRouter.js";
import crypto from "crypto"; // For generating nonces
dotenv.config({ path: "./.env" });
const apiVersion = "v1";
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const app = express();
const port = process.env.PORT || 3300;
// Middleware to generate nonce for each request
app.use((req, res, next) => {
res.locals.nonce = crypto.randomBytes(16).toString("base64");
next();
});
// Set security HTTP headers with relaxed CSP, allowing everything from specified domains
app.use(
helmet({
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'", "*"], // Allow everything from specified domains
scriptSrc: [
"'self'",
"*", // Allow all scripts from specified domains
"'unsafe-inline'", // Allow inline scripts (for testing)
"'unsafe-eval'", // Allow eval() (for testing)
],
styleSrc: [
"'self'",
"*", // Allow all styles from specified domains
"'unsafe-inline'", // Allow inline styles
],
imgSrc: [
"'self'",
"*", // Allow all images from specified domains
"data:", // Allow data URIs for images
],
connectSrc: [
"'self'",
"*", // Allow all connections from specified domains
],
fontSrc: [
"'self'",
"*", // Allow all fonts from specified domains
],
frameSrc: ["'self'"],
objectSrc: ["'self'"],
mediaSrc: ["'self'"],
childSrc: ["'self'"],
manifestSrc: ["'self'"],
workerSrc: ["'self'"],
scriptSrcElem: [
"'self'",
"*", // Allow all scripts from specified domains
"'unsafe-inline'", // Allow inline scripts in script elements
"'unsafe-eval'", // Allow eval() (for testing)
],
styleSrcElem: [
"'self'",
"*", // Allow all styles from specified domains
"'unsafe-inline'", // Allow inline styles in style elements
],
upgradeInsecureRequests: [], // Allow mixed content
},
},
crossOriginEmbedderPolicy: false,
crossOriginOpenerPolicy: false,
crossOriginResourcePolicy: false,
})
);
// Middleware for CORS configuration
app.use(
cors({
origin: [
"http://localhost:5173",
"https://emojikitchengame.com",
"https://www.emojikitchengame.com",
"emojikitchengame.com",
"www.emojikitchengame.com",
],
methods: ["GET", "POST", "PATCH", "PUT", "DELETE"],
credentials: true,
allowedHeaders: ["*"], // Allow all headers
})
);
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
// Data sanitization against XSS
app.use(xss());
// Removes duplicate fields from HTTP parameters to prevent HTTP parameter pollution
app.use(hpp());
// Serve static files from 'build/client'
app.use(express.static(join(__dirname, "build/client")));
// Routes
app.use(`/${apiVersion}/api/tracking`, trackingRouter);
// Handle all other routes using the Remix request handler
app.all("*", createRequestHandler({ build })); // Use the build object
// Error handling middleware to be triggered if all of the above routes fail
// eslint-disable-next-line no-unused-vars
app.use((err, req, res, next) => {
console.error("Server error:", err);
res.status(500).send("Internal Server Error");
});
// Start the server
app.listen(port, () => {
console.log(`App listening on http://localhost:${port}`);
});