Skip to content

Commit 0ba9a76

Browse files
committed
Add Room Fetching Based on Rest
1 parent 02446a3 commit 0ba9a76

File tree

15 files changed

+277
-41
lines changed

15 files changed

+277
-41
lines changed

backend/api-gateway/nginx.conf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ http {
6363
proxy_send_timeout 60s;
6464
}
6565

66-
# Proxy for /api/categories to service running on port 3002
66+
# Proxy for /api/history to service running on port 3002
6767
location /api/history/ {
6868
proxy_pass http://host.docker.internal:3002/api/history/;
6969
proxy_set_header Host $host;

backend/matching-service/app.ts

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,15 @@ const server = http.createServer(app);
2525

2626
initSocket(server);
2727

28+
app.use(cors({
29+
origin: true,
30+
credentials: true,
31+
}));
32+
2833
app.use(express.json());
2934

3035
app.use("/api/match", matchingRoutes);
3136

32-
app.use(
33-
cors({
34-
origin: "*",
35-
credentials: true,
36-
})
37-
);
38-
3937
app.use(errorHandler);
4038

4139
server.listen(port, async () => {
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import roomModel from "../models/RoomSchema";
2+
import { Request, Response, NextFunction } from "express";
3+
4+
export async function getRoomDetails(
5+
request: Request,
6+
response: Response,
7+
next: NextFunction
8+
) {
9+
const { roomId } = request.params
10+
try {
11+
console.log(roomId)
12+
const room = await roomModel.findOne({ roomId });
13+
if (!room) {
14+
throw new Error("Room not found");
15+
}
16+
response.status(200).json({
17+
roomId,
18+
attemptStartedAt: room.createdAt.getTime(),
19+
userIdOne: room.participants[0],
20+
userIdTwo: room.participants[1],
21+
questionId: room.questionId,
22+
});
23+
} catch (error) {
24+
next(error);
25+
}
26+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { Request, Response, NextFunction } from 'express';
2+
import jwt from 'jsonwebtoken';
3+
4+
export interface AuthenticatedRequest extends Request {
5+
userId?: string;
6+
}
7+
8+
export const authenticateToken = (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
9+
const authHeader = req.headers['authorization'];
10+
11+
if (!authHeader) return res.status(401).json({ error: 'Authorization header missing' });
12+
13+
const token = authHeader.split(' ')[1];
14+
15+
if (!token) return res.status(401).json({ error: 'Token missing' });
16+
17+
jwt.verify(token, process.env.JWT_ACCESS_TOKEN_SECRET as string, (err, decoded: any) => {
18+
if (err) return res.status(403).json({ error: 'Invalid token' });
19+
20+
req.userId = decoded.id;
21+
next();
22+
});
23+
};
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import jwt from "jsonwebtoken";
2+
export function verifyIsAdmin(req: any, res: any, next: any) {
3+
if (req.isAdmin) {
4+
next();
5+
} else {
6+
return res.status(403).json({ message: "Not authorized to access this resource" });
7+
}
8+
}
9+
export function verifyAccessToken(req: any, res: any, next: any) {
10+
const authHeader = req.headers.authorization || req.header.Authorization;
11+
if (!authHeader) {
12+
return res.status(401).json({ message: "Authentication failed" });
13+
}
14+
15+
if (!authHeader?.startsWith("Bearer ")) {
16+
return res.status(401).json({ message: "Unauthorized: no token" });
17+
}
18+
const token = authHeader.split(" ")[1];
19+
20+
const secret = process.env.JWT_ACCESS_TOKEN_SECRET;
21+
if (!secret) {
22+
return res.status(500).json({ message: "Internal server error" });
23+
}
24+
jwt.verify(token, secret, async (err: any, user: any) => {
25+
if (err) {
26+
return res.status(401).json({ message: `Unauthorized: ${err.message}` });
27+
}
28+
req.isAdmin = user.isAdmin;
29+
next();
30+
});
31+
}
Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,17 @@
1-
import mongoose from "mongoose";
1+
import mongoose, { Schema, Types } from "mongoose";
22

3-
const roomSchema = new mongoose.Schema({
3+
export interface Room extends mongoose.Document {
4+
_id: Types.ObjectId;
5+
participants: string[];
6+
category: string;
7+
difficulty: string;
8+
roomId: string;
9+
questionId: string;
10+
createdAt: Date;
11+
}
12+
13+
14+
const roomSchema: Schema<Room> = new mongoose.Schema<Room>({
415
participants: [{ userId: String }],
516
category: { type: String, default: 'Any' },
617
difficulty: { type: String, default: 'Any' },
@@ -9,6 +20,6 @@ const roomSchema = new mongoose.Schema({
920
createdAt: { type: Date, default: Date.now }
1021
});
1122

12-
const Room = mongoose.model('Room', roomSchema);
23+
const roomModel = mongoose.model<Room>('Room', roomSchema);
1324

14-
export default Room;
25+
export default roomModel;
Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
1+
import { getRoomDetails } from '../controllers/roomController';
12
import { cancelMatch, startMatching } from '../controllers/matchingController';
23
import express from 'express';
4+
import { verifyAccessToken } from '../middlewares/basic-access-control';
5+
import { authenticateToken } from 'middlewares/auth';
36

47
const router = express.Router();
58

6-
router.post('/', startMatching);
7-
router.delete('/:socketId', cancelMatch)
9+
router.post('/', authenticateToken, startMatching);
10+
router.delete('/:socketId', authenticateToken, cancelMatch)
11+
router.get('/room/:roomId', authenticateToken, getRoomDetails)
812

913
export default router;

frontend/src/data/repositories/HistoryRemoteDataSource.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ export class HistoryRemoteDataSource extends BaseApi {
1818
}
1919

2020
async deleteSelectedHistories(selectedHistoryIds: string[]): Promise<void> {
21-
console.log("Delete")
2221
selectedHistoryIds.forEach(async (id) => {
2322
console.log(id);
2423
await this.protectedDelete<void>(`/user/${id}`);
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { BaseApi } from "../../infrastructure/Api/BaseApi";
2+
import { Room } from "../../domain/entities/Room";
3+
4+
const API_URL = "/api/match";
5+
6+
export class RoomRemoteDataSource extends BaseApi {
7+
constructor() {
8+
super(API_URL);
9+
}
10+
11+
async getRoomDetails(roomId: string): Promise<Room> {
12+
return await this.protectedGet<Room>(`/room/${roomId}`);
13+
}
14+
}
15+
16+
export const roomRemoteDataSource = new RoomRemoteDataSource();
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { roomRemoteDataSource } from './RoomRemoteDataSource';
2+
import { Room } from '../../domain/entities/Room';
3+
import { IRoomRepository } from 'domain/repositories/IRoomRepository';
4+
5+
export class RoomRepositoryImpl implements IRoomRepository {
6+
private dataSource = roomRemoteDataSource;
7+
8+
async getRoomDetails(roomId: string): Promise<Room> {
9+
return this.dataSource.getRoomDetails(roomId);
10+
}
11+
}
12+
13+
export const roomRepository = new RoomRepositoryImpl();

0 commit comments

Comments
 (0)