Skip to content

Commit 5123eee

Browse files
committed
merge conflict resolution in server
1 parent a4bdfa8 commit 5123eee

File tree

2 files changed

+132
-104
lines changed

2 files changed

+132
-104
lines changed

backend/src/app.ts

Lines changed: 127 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,36 @@
1-
import express, { Application } from 'express';
1+
// import express, { Application } from 'express';
2+
// import cors from 'cors';
3+
// import morgan from 'morgan';
4+
// import bodyParser from 'body-parser';
5+
// import healthRoutes from './routes/healthRoutes';
6+
7+
// const app: Application = express();
8+
9+
10+
// // Middleware setup
11+
// app.use(cors());
12+
// app.use(morgan('dev'));
13+
// app.use(bodyParser.json());
14+
// app.use(bodyParser.urlencoded({ extended: true }));
15+
16+
17+
// // API Routes
18+
// app.use('/api/health', healthRoutes);
19+
20+
// export default app;
21+
22+
import express, { Application, Request, Response } from 'express';
223
import cors from 'cors';
324
import morgan from 'morgan';
425
import bodyParser from 'body-parser';
526
import healthRoutes from './routes/healthRoutes';
627

28+
// 1. Imports needed for JWT/Auth
29+
import bcrypt from "bcryptjs";
30+
import cookieParser from "cookie-parser";
31+
import { signAccessToken, signRefreshToken, verifyRefreshToken } from "./controllers/auth";
32+
import { authenticate, AuthRequest } from "./middleware/authMiddleware";
33+
734
const app: Application = express();
835

936

@@ -12,9 +39,107 @@ app.use(cors());
1239
app.use(morgan('dev'));
1340
app.use(bodyParser.json());
1441
app.use(bodyParser.urlencoded({ extended: true }));
42+
// 2. Middleware needed for Auth
43+
app.use(cookieParser());
44+
45+
46+
// 3. User Interface and Mock Data
47+
interface User {
48+
id: string;
49+
username: string;
50+
passwordHash: string;
51+
role: string;
52+
}
53+
54+
const users: User[] = [
55+
{ id: "1", username: "alice", passwordHash: bcrypt.hashSync("password", 8), role: "admin" },
56+
];
57+
58+
const refreshTokens = new Map<string, string>()
59+
60+
61+
// 4. Authentication API Routes
62+
app.post("/login", async (req: Request, res: Response) => {
63+
const { username, password } = req.body;
64+
const user = users.find((u) => u.username === username);
65+
if (!user) return res.status(401).json({ error: "Invalid credentials" });
66+
67+
const match = await bcrypt.compare(password, user.passwordHash);
68+
if (!match) return res.status(401).json({ error: "Invalid credentials" });
69+
70+
const payload = { sub: user.id, username: user.username, role: user.role };
71+
const accessToken = signAccessToken(payload);
72+
const refreshToken = signRefreshToken(payload);
73+
74+
refreshTokens.set(user.id, refreshToken);
75+
76+
res.cookie("refreshToken", refreshToken, {
77+
httpOnly: true,
78+
sameSite: "strict",
79+
secure: process.env.NODE_ENV === "production",
80+
maxAge: 7 * 24 * 60 * 60 * 1000,
81+
});
82+
83+
res.json({ accessToken });
84+
});
85+
86+
app.post("/refresh", (req: Request, res: Response) => {
87+
const token = req.cookies?.refreshToken || req.body.refreshToken;
88+
89+
if (!token) {
90+
return res.status(401).json({ error: "Refresh token is missing" });
91+
}
92+
93+
try {
94+
const payload = verifyRefreshToken(token);
95+
const storedToken = refreshTokens.get(payload.sub);
96+
97+
if (!storedToken) {
98+
return res.status(401).json({ error: "Session not found or already logged out" });
99+
}
100+
101+
if (storedToken !== token) {
102+
return res.status(401).json({ error: "Token used is not the latest valid token" });
103+
}
104+
105+
const cleanPayload = {
106+
sub: payload.sub,
107+
username: payload.username,
108+
role: payload.role
109+
};
110+
111+
const newAccess = signAccessToken(cleanPayload);
112+
const newRefresh = signRefreshToken(cleanPayload);
113+
114+
refreshTokens.set(cleanPayload.sub, newRefresh);
115+
116+
res.cookie("refreshToken", newRefresh, {
117+
httpOnly: true,
118+
sameSite: "strict",
119+
secure: process.env.NODE_ENV === "production",
120+
maxAge: 7 * 24 * 60 * 60 * 1000,
121+
});
122+
123+
res.json({ accessToken: newAccess });
124+
125+
} catch (error) {
126+
console.error("Refresh token verification failed:", error);
127+
res.status(401).json({ error: "Refresh token is expired or invalid" });
128+
}
129+
});
130+
131+
app.post("/logout", authenticate, (req: AuthRequest, res: Response) => {
132+
// req.user is guaranteed to exist by the 'authenticate' middleware
133+
refreshTokens.delete(req.user!.sub);
134+
res.clearCookie("refreshToken");
135+
res.status(204).send();
136+
});
15137

138+
app.get("/protected", authenticate, (req: AuthRequest, res: Response) => {
139+
res.json({ message: "Protected route accessed", user: req.user });
140+
});
16141

17-
// API Routes
142+
// Existing API Routes
18143
app.use('/api/health', healthRoutes);
19144

20145
export default app;

backend/src/server.ts

Lines changed: 5 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -1,108 +1,11 @@
1-
import express from "express";
21
import dotenv from "dotenv";
3-
import bcrypt from "bcryptjs";
4-
import cookieParser from "cookie-parser";
5-
import { signAccessToken, signRefreshToken, verifyRefreshToken } from "./controllers/auth";
6-
import { authenticate, AuthRequest } from "./middleware/authMiddleware";
72

83
dotenv.config();
94

10-
const app = express();
11-
app.use(express.json());
12-
app.use(cookieParser());
5+
import app from './app';
136

7+
const PORT = process.env.PORT ? Number(process.env.PORT) : 4000;
148

15-
interface User {
16-
id: string;
17-
username: string;
18-
passwordHash: string;
19-
role: string;
20-
}
21-
22-
const users: User[] = [
23-
{ id: "1", username: "alice", passwordHash: bcrypt.hashSync("password", 8), role: "admin" },
24-
];
25-
26-
const refreshTokens = new Map<string, string>()
27-
28-
app.post("/login", async (req, res) => {
29-
const { username, password } = req.body;
30-
const user = users.find((u) => u.username === username);
31-
if (!user) return res.status(401).json({ error: "Invalid credentials" });
32-
33-
const match = await bcrypt.compare(password, user.passwordHash);
34-
if (!match) return res.status(401).json({ error: "Invalid credentials" });
35-
36-
const payload = { sub: user.id, username: user.username, role: user.role };
37-
const accessToken = signAccessToken(payload);
38-
const refreshToken = signRefreshToken(payload);
39-
40-
refreshTokens.set(user.id, refreshToken);
41-
42-
res.cookie("refreshToken", refreshToken, {
43-
httpOnly: true,
44-
sameSite: "strict",
45-
secure: process.env.NODE_ENV === "production",
46-
maxAge: 7 * 24 * 60 * 60 * 1000,
47-
});
48-
49-
res.json({ accessToken });
50-
});
51-
52-
app.post("/refresh", (req, res) => {
53-
const token = req.cookies?.refreshToken || req.body.refreshToken;
54-
55-
if (!token) {
56-
return res.status(401).json({ error: "Refresh token is missing" });
57-
}
58-
59-
try {
60-
const payload = verifyRefreshToken(token);
61-
const storedToken = refreshTokens.get(payload.sub);
62-
63-
if (!storedToken) {
64-
return res.status(401).json({ error: "Session not found or already logged out" });
65-
}
66-
67-
if (storedToken !== token) {
68-
return res.status(401).json({ error: "Token used is not the latest valid token" });
69-
}
70-
71-
const cleanPayload = {
72-
sub: payload.sub,
73-
username: payload.username,
74-
role: payload.role
75-
};
76-
77-
const newAccess = signAccessToken(cleanPayload);
78-
const newRefresh = signRefreshToken(cleanPayload);
79-
80-
refreshTokens.set(cleanPayload.sub, newRefresh);
81-
82-
res.cookie("refreshToken", newRefresh, {
83-
httpOnly: true,
84-
sameSite: "strict",
85-
secure: process.env.NODE_ENV === "production",
86-
maxAge: 7 * 24 * 60 * 60 * 1000,
87-
});
88-
89-
res.json({ accessToken: newAccess });
90-
91-
} catch (error) {
92-
console.error("Refresh token verification failed:", error);
93-
res.status(401).json({ error: "Refresh token is expired or invalid" });
94-
}
95-
});
96-
97-
app.post("/logout", authenticate, (req: AuthRequest, res) => {
98-
refreshTokens.delete(req.user!.sub);
99-
res.clearCookie("refreshToken");
100-
res.status(204).send();
101-
});
102-
103-
app.get("/protected", authenticate, (req: AuthRequest, res) => {
104-
res.json({ message: "Protected route accessed", user: req.user });
105-
});
106-
107-
const PORT = process.env.PORT || 4000;
108-
app.listen(PORT, () => console.log(`Server running on port ${PORT}`));
9+
app.listen(PORT, () => {
10+
console.log(`Server running on port ${PORT}`);
11+
});

0 commit comments

Comments
 (0)