Skip to content

Commit b771ef6

Browse files
authored
Merge pull request #164 from cuappdev/ashley/overall-cleanup
Overall Cleanup
2 parents 484153b + 198ffd4 commit b771ef6

5 files changed

Lines changed: 320 additions & 256 deletions

File tree

src/api/middlewares/ErrorHandler.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ function handleError(
3131
error: message,
3232
httpCode: httpCode,
3333
};
34-
console.log(message);
34+
console.error(`[${httpCode}] ${message}`);
3535
response.status(httpCode).json(errorResponse);
3636
next();
3737
}

src/app.ts

Lines changed: 140 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,146 @@ async function main() {
7070
throw new Error("Connection to DB failed. Check console output");
7171
});
7272

73-
// Start server
73+
const app: Express = createExpressServer({
74+
cors: true,
75+
routePrefix: "/api/",
76+
controllers: controllers,
77+
middlewares: middlewares,
78+
currentUserChecker: async (action: any) => {
79+
const authHeader = action.request.headers["authorization"];
80+
if (!authHeader) {
81+
throw new ForbiddenError("No authorization token provided");
82+
}
83+
const token = authHeader.split(" ")[1];
84+
if (!token) {
85+
throw new ForbiddenError("Invalid authorization token format");
86+
}
87+
try {
88+
// Verify the token using Firebase Admin SDK
89+
const decodedToken = await admin.auth().verifyIdToken(token);
90+
// Check if the email is a Cornell email
91+
const email = decodedToken.email;
92+
const userId = decodedToken.uid;
93+
action.request.email = email;
94+
action.request.firebaseUid = userId;
95+
if (!email || !email.endsWith("@cornell.edu")) {
96+
throw new ForbiddenError("Only Cornell email addresses are allowed");
97+
}
98+
// Find or create user in your database using Firebase UID
99+
const manager = getManager();
100+
const user = await manager.findOne(
101+
UserModel,
102+
{ firebaseUid: userId },
103+
{ relations: ["posts", "saved", "feedbacks", "requests"] },
104+
);
105+
if (!user) {
106+
// Check if this is the user creation route or authorization route
107+
const isUserCreateRoute =
108+
action.request.path === "/api/user/create/" ||
109+
action.request.path === "/api/user/create" ||
110+
action.request.path === "/api/authorize" ||
111+
action.request.path === "api/authorize";
112+
console.log(
113+
`User not found for path: ${action.request.path}, isUserCreateRoute: ${isUserCreateRoute}`,
114+
);
115+
if (!isUserCreateRoute) {
116+
throw new ForbiddenError(
117+
"User not found. Please create an account first.",
118+
);
119+
}
120+
// For user creation routes, return a minimal UserModel
121+
const tempUser = new UserModel();
122+
tempUser.googleId = email;
123+
tempUser.firebaseUid = decodedToken.uid;
124+
tempUser.email = email;
125+
tempUser.username = `temp_${decodedToken.uid}`;
126+
tempUser.isActive = true;
127+
tempUser.admin = false;
128+
tempUser.isNewUser = true;
129+
return tempUser;
130+
}
131+
if (!user) {
132+
throw new ForbiddenError("User authentication failed");
133+
}
134+
return user;
135+
} catch (error) {
136+
if (error instanceof ForbiddenError) {
137+
throw error;
138+
}
139+
if (error.code == "auth/argument-error") {
140+
throw new HttpError(
141+
408,
142+
"Request timed out while waiting for response",
143+
);
144+
}
145+
if (error.code === "auth/id-token-expired") {
146+
throw new UnauthorizedError("Token has expired");
147+
}
148+
throw new UnauthorizedError("Invalid authorization token");
149+
}
150+
},
151+
defaults: {
152+
paramOptions: {
153+
required: true,
154+
},
155+
},
156+
validation: {
157+
whitelist: true,
158+
skipMissingProperties: true,
159+
forbidUnknownValues: true,
160+
},
161+
defaultErrorHandler: false,
162+
});
163+
164+
const port = process.env.PORT ?? 3000;
165+
166+
const swaggerDocument = require(path.join(__dirname, "../swagger.json"));
167+
app.use("/api-docs", swaggerUi.serve, swaggerUi.setup(swaggerDocument));
168+
console.log(
169+
`Swagger documentation available at http://localhost:${port}/api-docs`,
170+
);
171+
172+
const entityManager = getManager();
173+
const reportService = new ReportService(entityManager);
174+
const reportController = new ReportController(reportService);
175+
176+
app.get("/api/reports/admin/", async (req: any, res: any) => {
177+
const userCheck = async (action: any) => {
178+
const authHeader = req.headers["authorization"];
179+
if (!authHeader) {
180+
throw new ForbiddenError("No authorization token provided");
181+
}
182+
const token = authHeader.split(" ")[1];
183+
if (!token) {
184+
throw new ForbiddenError("Invalid authorization token format");
185+
}
186+
187+
try {
188+
const userId = action.request.firebaseUid;
189+
// Find or create user in your database using Firebase UID
190+
const manager = getManager();
191+
const user = await manager.findOne(UserModel, { firebaseUid: userId });
192+
if (!user || !user.admin) throw new ForbiddenError("User unauthorized");
193+
return user;
194+
} catch (error) {
195+
if (error.code === "auth/id-token-expired") {
196+
throw new UnauthorizedError("Token has expired");
197+
}
198+
throw new UnauthorizedError("Invalid authorization token");
199+
}
200+
};
201+
const user = await userCheck(req);
202+
user.admin = true;
203+
const postReports = await reportController.getAllPostReports(user);
204+
const profileReports = await reportController.getAllProfileReports(user);
205+
const messageReports = await reportController.getAllMessageReports(user);
206+
res.render("admin", {
207+
postReports: reportToString(postReports),
208+
profileReports: reportToString(profileReports),
209+
messageReports: reportToString(messageReports),
210+
});
211+
});
212+
74213
app.listen(port, () => {
75214
console.log(`Resell backend bartering on http://localhost:${port}`);
76215
});

0 commit comments

Comments
 (0)