Skip to content

Commit 2849460

Browse files
committed
Added auth to the branch
1 parent c9e21e1 commit 2849460

File tree

3 files changed

+106
-18
lines changed

3 files changed

+106
-18
lines changed

server/src/auth/jwt-auth.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import jwt from "jsonwebtoken";
2+
import { Request, Response, NextFunction } from "express";
3+
4+
const authenticateJWT = (req: Request, res: Response, next: NextFunction) => {
5+
const authHeader = req.headers.authorization;
6+
7+
if (authHeader) {
8+
const token = authHeader.split(" ")[1];
9+
jwt.verify(token, process.env.JWT_SECRET!, (err, user) => {
10+
if (err) {
11+
return res.status(403).json({ error: "Forbidden" });
12+
}
13+
req.user = user;
14+
next();
15+
});
16+
} else {
17+
res.status(401).json({ error: "Unauthorized" });
18+
}
19+
};
20+
21+
export default authenticateJWT;

server/src/routes/admin-router.ts

Lines changed: 76 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
import express, { Request, Response, Router } from "express";
1+
import express, { Request, Response, Router, NextFunction } from "express";
22
import { DatabaseController } from "../database-controller";
33
import { GetQuery, InsertData, RadData, Testing } from "../types";
4-
5-
const router = express.Router();
4+
import axios from "axios";
5+
import jwt from "jsonwebtoken";
6+
import authenticateJWT from "../auth/jwt-auth";
67

78
export default function adminRouter(dbController: DatabaseController): Router {
89
const router = Router();
@@ -11,25 +12,82 @@ export default function adminRouter(dbController: DatabaseController): Router {
1112
// The data is in the correct format and ready to be input.
1213

1314
// THIS WILL NOT WORK WITH RAW PAPERS, Data MUST be in InsertData format
14-
router.post("/insertPapers", (req: Request, res: Response) => {
15-
try {
16-
insertRows(requestFromJSON(req.body), dbController).then(() => {
17-
// 201: The request was successful, and a new resource was created
18-
res.send(201);
19-
});
20-
} catch (error) {
21-
console.error(`${error}`);
15+
router.post(
16+
"/insertPapers",
17+
authenticateJWT,
18+
async (req: Request, res: Response) => {
19+
try {
20+
await insertRows(requestFromJSON(req.body), dbController).then(() => {
21+
// 201: The request was successful, and a new resource was created
22+
res.send(201);
23+
});
24+
} catch (error) {
25+
console.error(`${error}`);
26+
}
27+
},
28+
);
29+
30+
router.post(
31+
"/parseRequest",
32+
authenticateJWT,
33+
(req: Request, res: Response) => {
34+
try {
35+
// TODO
36+
parsePapers(req.body).then((result: InsertData[]) => {
37+
res.send(responseToJSON(result));
38+
});
39+
} catch (error) {
40+
console.error(``);
41+
}
42+
},
43+
);
44+
45+
// Example list of allowed NSIDs (replace with database table in the future)
46+
const allowedNSIDs = [
47+
"mrm322",
48+
"nec314",
49+
"stm875",
50+
"cmh860",
51+
"ara258",
52+
"xgr074",
53+
];
54+
55+
router.get("/auth/cas-validate", async (req: Request, res: Response) => {
56+
const { ticket, service } = req.query;
57+
58+
if (!ticket || !service) {
59+
res.status(400).json({ error: "Missing ticket or service" });
2260
}
23-
});
2461

25-
router.post("/parseRequest", (req: Request, res: Response) => {
2662
try {
27-
// TODO
28-
parsePapers(req.body).then((result: InsertData[]) => {
29-
res.send(responseToJSON(result));
30-
});
63+
// Validate CAS ticket
64+
const casResponse = await axios.get(
65+
`https://cas.usask.ca/serviceValidate`,
66+
{
67+
params: { ticket, service },
68+
},
69+
);
70+
71+
const casData = casResponse.data; // assumed user CAS info, need to test to see
72+
const nsid = casData.user; // Potentally the nsid of the user. Again need to test
73+
74+
if (!nsid) {
75+
res.status(401).json({ error: "Invalid CAS Ticket" });
76+
}
77+
78+
if (!allowedNSIDs.includes(nsid)) {
79+
res.status(403).json({ error: "Access denied" });
80+
}
81+
82+
const token = jwt.sign(
83+
{ username: casData.user, roles: casData.roles },
84+
process.env.JWT_SECRET!,
85+
{ expiresIn: "3h" },
86+
);
87+
88+
res.json({ token });
3189
} catch (error) {
32-
console.error(``);
90+
res.status(500).json({ error: "CAS validation failed" });
3391
}
3492
});
3593

server/src/types/express.d.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import * as express from "express";
2+
3+
declare global {
4+
namespace Express {
5+
interface Request {
6+
user?: any; // Adjust the type as needed, e.g., `Record<string, any>` or a custom User type
7+
}
8+
}
9+
}

0 commit comments

Comments
 (0)