-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathserver.js
More file actions
217 lines (170 loc) · 6.63 KB
/
server.js
File metadata and controls
217 lines (170 loc) · 6.63 KB
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
// Import the Express framework
import express from "express";
// Import the Mongoose library for MongoDB
import mongoose from "mongoose";
// Import cookie-parser middleware for parsing cookies
import cookieParser from "cookie-parser";
// Import morgan for logging requests
import morgan from "morgan";
// Import authentication routes
import authRoutes from "./routes/userAuthRoutes/userAuthRoutes.js";
// Import image handling routes
import imageRoutes from "./routes/imageRoutes/imageRoutes.js";
// Import order handling routes
import orderRoutes from "./routes/orderRoutes/orderRoutes.js";
// Import admin authentication/protected routes
import adminAuthRoutes from "./routes/admin-userAuthRoutes/admin-userAuthRoutes.js";
// Import the new web donations routes (platform-only)
import webDonationsRoutes from "./routes/webDonationsRoutes/webDonationsRoutes.js";
// Notifications routes
import notificationRoutes from "./routes/notificationRoutes/notificationRoutes.js";
// Report and Block routes (Apple Guideline 1.2 compliance)
import reportRoutes from "./routes/reportRoutes/reportRoutes.js";
import blockRoutes from "./routes/blockRoutes/blockRoutes.js";
import adminReportRoutes from "./routes/admin-userAuthRoutes/admin-reportRoutes.js";
import adminAnalyticsRoutes from "./routes/admin-userAuthRoutes/admin-analyticsRoutes.js";
import adminSearchConsoleRoutes from "./routes/admin-userAuthRoutes/admin-searchConsoleRoutes.js";
import adminSettingsRoutes from "./routes/admin-userAuthRoutes/admin-settingsRoutes.js";
// Public domain art (proxy layer — no DB interaction)
import publicArtRoutes from "./routes/publicArtRoutes/publicArtRoutes.js";
// Contact form
import contactRoutes from "./routes/contactRoutes/contactRoutes.js";
// Sitemap
import sitemapRoutes from "./routes/sitemapRoutes/sitemapRoutes.js";
// SLA Monitor service
import { startSLAMonitor } from "./services/slaMonitor.js";
// Import the MongoDB connection URL from config file
import { MONGO_URL } from "./config/config.js";
// Import body-parser (only for urlencoded forms)
import bodyParser from "body-parser";
// Import cors
import cors from "cors";
// Import dotenv
import dotenv from "dotenv";
// JWT for refresh endpoint
import jwt from "jsonwebtoken";
// Load environment variables
dotenv.config();
// Build acceptable origins dynamically
const corsOrigins = [
`http://admin:${process.env.VITE_APP_ADMIN_PORT}`, // Admin service
`http://localhost:${process.env.VITE_APP_WEB_PORT}`, // Web service
`http://${process.env.HOST_IP}:19000`, // Expo Go
`http://${process.env.HOST_IP}:8081`, // Expo Development Build
`http://${process.env.HOST_IP}:8083`,
"http://localhost:5173", // Admin Locally
"http://localhost:3000", // Admin Locally
"https://immpression-admin.vercel.app", // Admin Online
"https://www.immpression.art", // Website
];
// Create an Express application
const app = express();
// Simple request logger (in addition to morgan) for quick visibility
app.use((req, _res, next) => {
console.log(`Incoming request: ${req.method} ${req.url}`);
console.log(`Origin: ${req.headers.origin}`);
next();
});
/**
* Keep Stripe webhook bodies RAW where needed:
* - /api/web/donations/webhook (handled inside webDonationsRoutes with express.raw)
* - /webhook (orders webhook defined inside orderRoutes)
*
* Everything else gets JSON parsing.
*/
app.use((req, res, next) => {
const rawPaths = new Set([
"/api/web/donations/webhook",
"/webhook",
]);
if (rawPaths.has(req.originalUrl)) return next(); // route-level express.raw() will handle it
return express.json()(req, res, next);
});
// Middleware to parse cookies in incoming requests
app.use(cookieParser());
// Middleware to allow cross-origin requests
app.use(
cors({
origin: (origin, callback) => {
// Allow requests with no origin (e.g., mobile apps, Postman)
if (!origin || corsOrigins.includes(origin)) {
callback(null, true);
} else {
callback(new Error("Not allowed by CORS"));
}
},
credentials: true, // Allow cookies
})
);
// Define a custom log format for Morgan
const customFormat =
"[:date[clf]] :method :url :status :res[content-length] - :response-time ms";
// Use Morgan middleware to log HTTP requests with the defined custom format
app.use(morgan(customFormat));
/**
* Optional: URL-encoded forms (if you need them elsewhere).
* Do NOT add another JSON parser here—already handled above.
*/
app.use(bodyParser.urlencoded({ extended: false }));
// ----- Auth token refresh -----
app.post("/refresh-token", (req, res) => {
const { token: oldToken } = req.body;
if (!oldToken)
return res.status(401).json({ success: false, error: "No token provided" });
jwt.verify(oldToken, process.env.JWT_SECRET, (err, decoded) => {
if (err)
return res
.status(403)
.json({ success: false, error: "Invalid or expired token" });
const newToken = jwt.sign({ _id: decoded._id }, process.env.JWT_SECRET, {
expiresIn: "1h",
});
res.json({ success: true, token: newToken });
});
});
// ----- Routes -----
// User auth / images / orders on root
app.use("/", authRoutes);
app.use("/", imageRoutes);
app.use("/", orderRoutes);
// Notifications at /notifications (avoids clobbering "/")
app.use("/notifications", notificationRoutes);
// Report and Block routes (Apple Guideline 1.2 compliance)
app.use("/reports", reportRoutes);
app.use("/blocks", blockRoutes);
// Admin routes
app.use("/api/admin", adminAuthRoutes);
// Admin report management routes
app.use("/api/admin/reports", adminReportRoutes);
app.use("/api/admin/analytics/web", adminAnalyticsRoutes);
app.use("/api/admin/analytics/search-console", adminSearchConsoleRoutes);
app.use("/api/admin/settings", adminSettingsRoutes);
// Web donations (platform-only; includes /donations/create-checkout-session and /donations/webhook)
app.use("/api/web", webDonationsRoutes);
// Public domain art (proxy — no DB)
app.use("/public-art", publicArtRoutes);
// Contact form
app.use("/", contactRoutes);
// Sitemap
app.use("/", sitemapRoutes);
// ----- Database connection -----
const PORT = process.env.BACKEND_PORT || 4000;
mongoose
.connect(MONGO_URL)
.then(() => {
console.log("MongoDB connection successful");
// Start SLA Monitor for report deadline tracking (Apple Guideline 1.2)
startSLAMonitor(15); // Check every 15 minutes
})
.catch((error) => {
console.error("Error connecting to MongoDB:", error);
process.exit(1);
});
// Default server route
app.get("/", (_req, res) => {
res.send({ status: "Server is running" });
});
// Start the server
app.listen(PORT, () => {
console.log(`Server running at http://localhost:${PORT}`);
});