Skip to content

Commit

Permalink
Fix endpoints not checking the token user ID
Browse files Browse the repository at this point in the history
  • Loading branch information
gf-rog committed May 16, 2024
1 parent 165317d commit fa21c27
Show file tree
Hide file tree
Showing 13 changed files with 358 additions and 119 deletions.
6 changes: 6 additions & 0 deletions backend/src/models/Response.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import Message from "./Message.js";
import User from "./User.js";

import { Response } from "express";
Expand Down Expand Up @@ -60,6 +61,11 @@ export interface UsersSearchResponse {
users: User[];
}

export interface MessagesResponse {
status: "ok";
messages: Message[];
}

export interface JWTResponse extends OkResponse {
token: string;
}
Expand Down
78 changes: 50 additions & 28 deletions backend/src/routes/chatRoute.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,58 @@
import { Router } from "express";
import Message from "../models/Message.js";
import MessageModel from "../mongoDB/MessageModel.js";
import { authenticateToken } from "../misc/jwt.js";
import { JWTRequest, authenticateToken } from "../misc/jwt.js";
import { AuthMessagesErrorResponse } from "../types/userResponse.js";
import { Errors } from "../models/Response.js";
import { getTokenDbUser } from "../users.js";
import driver from "../driver.js";
import { userNotFoundRes } from "./usersRoute.js";

const chatRouter = Router();

chatRouter.get("/:user1Id/:user2Id", authenticateToken, async (req, res) => {
try {
const { user1Id, user2Id } = req.params;
const messageRequest = await MessageModel.find({
$or: [
{ fromUserId: user1Id, toUserId: user2Id },
{ fromUserId: user2Id, toUserId: user1Id },
],
}).sort({ created_date: "asc" });

const messages = messageRequest.map((m: Message) => {
const { sentDate, fromUserId, toUserId, content } = m;
return {
type: fromUserId === user1Id ? "sent" : "received",
sentDate,
fromUserId,
toUserId,
content,
};
});

return res.json({ status: "ok", messages });
} catch (err) {
console.log("Error:", err);
return res.status(404).json({ status: "error", errors: err as object });
}
});
chatRouter.get(
"/:user1Id/:user2Id",
authenticateToken,
async (req: JWTRequest, res: AuthMessagesErrorResponse) => {
const session = driver.session();
try {
const { user1Id, user2Id } = req.params;
const user = await getTokenDbUser(session, req.token!);

if (!user) {
return userNotFoundRes(res);
}

if (user.id != user1Id) {
return res.status(403).json({ status: "forbidden" });
}

const messageRequest = await MessageModel.find({
$or: [
{ fromUserId: user1Id, toUserId: user2Id },
{ fromUserId: user2Id, toUserId: user1Id },
],
}).sort({ created_date: "asc" });

const messages = messageRequest.map((m: Message) => {
const { sentDate, fromUserId, toUserId, content } = m;
return {
type: fromUserId === user1Id ? "sent" : "received",
sentDate,
fromUserId,
toUserId,
content,
} as Message;
});

return res.json({ status: "ok", messages });
} catch (err) {
console.log("Error:", err);
return res.status(404).json({ status: "error", errors: err as Errors });
} finally {
session.close();
}
},
);

export default chatRouter;
83 changes: 67 additions & 16 deletions backend/src/routes/userFriendsRoute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
FriendsPageErrorResponse,
FriendRequestsPageErrorResponse,
FriendSuggestionsPageErrorResponse,
AuthOkErrorResponse,
} from "../types/userResponse.js";
import { deleteFriend } from "../userFriends.js";
import { declineFriendRequest } from "../userFriends.js";
Expand All @@ -22,27 +23,37 @@ import { userNotFoundRes } from "./usersRoute.js";
import { Errors } from "../models/Response.js";
import Page, { pageSchema } from "../models/routes/Page.js";
import { formatError } from "../misc/formatError.js";
import { authenticateToken } from "../misc/jwt.js";
import { JWTRequest, authenticateToken } from "../misc/jwt.js";
import { getDbUser, getTokenDbUser } from "../users.js";

const friendsRouter = Router();

friendsRouter.get(
"/:userId/friends",
authenticateToken,
async (req: Request, res: FriendsPageErrorResponse) => {
const userId = req.params.userId;
async (req: JWTRequest, res: FriendsPageErrorResponse) => {
const session = driver.session();
try {
const userId = req.params.userId;
const user = await getTokenDbUser(session, req.token!);

const pageParse = pageSchema.safeParse(req.query);
if (!pageParse.success) {
const errors = formatError(pageParse.error);
return res.status(400).json({ status: "error", errors });
}
if (!user) {
return userNotFoundRes(res);
}

const { page, maxUsers }: Page = pageParse.data;
const maxUsersBig = BigInt(maxUsers);
if (user.id != userId) {
return res.status(403).json({ status: "forbidden" });
}

const pageParse = pageSchema.safeParse(req.query);
if (!pageParse.success) {
const errors = formatError(pageParse.error);
return res.status(400).json({ status: "error", errors });
}

const { page, maxUsers }: Page = pageParse.data;
const maxUsersBig = BigInt(maxUsers);

const session = driver.session();
try {
const friends = await getFriends(session, userId, page - 1, maxUsers);
if (friends === null) {
console.log(friends);
Expand Down Expand Up @@ -162,12 +173,22 @@ friendsRouter.get(
friendsRouter.post(
"/:userId1/send-friend-request/:userId2",
authenticateToken,
async (req: Request, res: OkErrorResponse) => {
async (req: JWTRequest, res: AuthOkErrorResponse) => {
const session = driver.session();
const userId1 = req.params.userId1;
const userId2 = req.params.userId2;

try {
const user = await getTokenDbUser(session, req.token!);

if (!user) {
return userNotFoundRes(res);
}

if (user.id != userId1) {
return res.status(403).json({ status: "forbidden" });
}

const requestResult = await sendFriendRequest(session, userId1, userId2);
if (!requestResult.success) {
const { firstUserExists, secondUserExists } = requestResult;
Expand Down Expand Up @@ -197,12 +218,22 @@ friendsRouter.post(
friendsRouter.post(
"/:userId1/accept-friend-request/:userId2",
authenticateToken,
async (req: Request, res: OkErrorResponse) => {
async (req: JWTRequest, res: AuthOkErrorResponse) => {
const session = driver.session();
const userId1 = req.params.userId1;
const userId2 = req.params.userId2;

try {
const user = await getTokenDbUser(session, req.token!);

if (!user) {
return userNotFoundRes(res);
}

if (user.id != userId1) {
return res.status(403).json({ status: "forbidden" });
}

const requestResult = await acceptFriendRequest(
session,
userId1,
Expand Down Expand Up @@ -249,12 +280,22 @@ friendsRouter.post(
friendsRouter.post(
"/:userId1/decline-friend-request/:userId2",
authenticateToken,
async (req: Request, res: OkErrorResponse) => {
async (req: JWTRequest, res: AuthOkErrorResponse) => {
const session = driver.session();
const userId1 = req.params.userId1;
const userId2 = req.params.userId2;

try {
const user = await getTokenDbUser(session, req.token!);

if (!user) {
return userNotFoundRes(res);
}

if (user.id != userId1) {
return res.status(403).json({ status: "forbidden" });
}

const requestResult = await declineFriendRequest(
session,
userId1,
Expand Down Expand Up @@ -297,12 +338,22 @@ friendsRouter.post(
friendsRouter.delete(
"/:userId1/delete-friend/:userId2",
authenticateToken,
async (req: Request, res: OkErrorResponse) => {
async (req: JWTRequest, res: AuthOkErrorResponse) => {
const session = driver.session();
const userId1 = req.params.userId1;
const userId2 = req.params.userId2;

try {
const user = await getTokenDbUser(session, req.token!);

if (!user) {
return userNotFoundRes(res);
}

if (user.id != userId1) {
return res.status(403).json({ status: "forbidden" });
}

const requestResult = await deleteFriend(session, userId1, userId2);
if (!requestResult.success) {
const { firstUserExists, secondUserExists, wasFriend } = requestResult;
Expand Down
46 changes: 33 additions & 13 deletions backend/src/routes/usersRoute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
RegisterUser,
updateUserSchema,
UpdateUser,
getTokenDbUser,
} from "../users.js";
import DbUser from "../models/DbUser.js";
import { changePasswordReqSchema } from "../models/ChangePasswordReq.js";
Expand Down Expand Up @@ -172,18 +173,28 @@ usersRouter.post("/", async (req: Request, res: UserErrorResponse) => {
usersRouter.put(
"/:userId",
authenticateToken,
async (req: Request, res: OkErrorResponse) => {
const userParse = updateUserSchema.safeParse(req.body);
if (!userParse.success) {
const errors = formatError(userParse.error);
return res.status(400).json({ status: "error", errors });
}

const parsedUser: UpdateUser = userParse.data;
const userId = req.params.userId;

async (req: JWTRequest, res: AuthOkErrorResponse) => {
const session = driver.session();
try {
const userId = req.params.userId;
const user = await getTokenDbUser(session, req.token!);

if (!user) {
return userNotFoundRes(res);
}

if (user.id != userId) {
return res.status(403).json({ status: "forbidden" });
}

const userParse = updateUserSchema.safeParse(req.body);
if (!userParse.success) {
const errors = formatError(userParse.error);
return res.status(400).json({ status: "error", errors });
}

const parsedUser: UpdateUser = userParse.data;

const newUser = await updateUser(session, userId, parsedUser);
if (!newUser) {
return userNotFoundRes(res);
Expand Down Expand Up @@ -254,11 +265,20 @@ usersRouter.post(
usersRouter.delete(
"/:userId",
authenticateToken,
async (req: Request, res: OkErrorResponse) => {
const userId = req.params.userId;

async (req: JWTRequest, res: AuthOkErrorResponse) => {
const session = driver.session();
try {
const userId = req.params.userId;
const user = await getTokenDbUser(session, req.token!);

if (!user) {
return userNotFoundRes(res);
}

if (user.id != userId) {
return res.status(403).json({ status: "forbidden" });
}

const isDeleted = await deleteUser(session, userId);
if (!isDeleted) {
return userNotFoundRes(res);
Expand Down
7 changes: 6 additions & 1 deletion backend/src/types/userResponse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
FriendsPageResponse,
FriendRequestsPageResponse,
FriendSuggestionsPageResponse,
MessagesResponse,
} from "../models/Response.js";

export type UsersErrorResponse = CustomResponse<UsersResponse | ErrorResponse>;
Expand All @@ -28,8 +29,12 @@ export type FriendSuggestionsPageErrorResponse = CustomResponse<
FriendSuggestionsPageResponse | ErrorResponse
>;
export type FriendsPageErrorResponse = CustomResponse<
FriendsPageResponse | ErrorResponse
AuthResponse | FriendsPageResponse | ErrorResponse
>;
export type UsersSearchErrorResponse = CustomResponse<
UsersSearchResponse | ErrorResponse
>;

export type AuthMessagesErrorResponse = CustomResponse<
AuthResponse | MessagesResponse | ErrorResponse
>;
Loading

0 comments on commit fa21c27

Please sign in to comment.