Skip to content

Commit

Permalink
Ban moderator moved to separate thread for better response, Posts now…
Browse files Browse the repository at this point in the history
… take less time to upload and get verified

This is also included for stories upload
  • Loading branch information
nidhish-nayak committed Apr 9, 2024
1 parent f007b1a commit b831cd8
Show file tree
Hide file tree
Showing 10 changed files with 144 additions and 132 deletions.
2 changes: 1 addition & 1 deletion server/src/controllers/like/addLike.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export const addLike = async (req: Request, res: Response) => {
.insert({ postId: postId, userId: userId })
.select();

if (error) res.status(400).json("Adding like to DB failed!");
if (error) return res.status(400).json("Adding like to DB failed!");

return res.status(200).json(data);
}
Expand Down
2 changes: 2 additions & 0 deletions server/src/controllers/post/addPost.controller.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { supabase } from "$/db/connect";
import moderatorCheck from "$/middlewares/moderator.middleware";
import { getUserIdFromCookie } from "$/utils/getUserId.util";
import { prefix } from "$/utils/prefix.util";
import { AddPostSchema } from "$/validations/post.validation";
Expand Down Expand Up @@ -38,6 +39,7 @@ export const addPost = async (req: Request, res: Response) => {

if (error) return res.status(400).json("Post upload to DB has failed!");

if (img) moderatorCheck(res, userId, data[0].id, true, img);
return res.status(200).json(data);
} catch (error) {
return res.status(401).json(error);
Expand Down
3 changes: 3 additions & 0 deletions server/src/controllers/story/postStory.controller.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { supabase } from "$/db/connect";
import moderatorCheck from "$/middlewares/moderator.middleware";
import { getUserIdFromCookie } from "$/utils/getUserId.util";
import { prefix } from "$/utils/prefix.util";
import { StorySchema } from "$/validations/story.validation";
Expand Down Expand Up @@ -32,5 +33,7 @@ export const postStory = async (req: Request, res: Response) => {
if (error) {
return res.status(500).json("Story data upload to DB failed!");
}

moderatorCheck(res, userId, data[0].id, false, img);
return res.status(200).json(data);
};
6 changes: 3 additions & 3 deletions server/src/controllers/upload/upload.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ export const uploadFile = (req: Request, res: Response) => {
try {
const file = req.file as Express.MulterS3.File;
if (!file) return res.status(401).send("File not found in server!");
return res
.status(200)
.json(config.s3Config.cloudfrontLink + "/" + file.key);

const link = config.s3Config.cloudfrontLink + "/" + file.key;
return res.status(200).json(link);
} catch (error) {
return res.status(500).send("File upload failed!");
}
Expand Down
124 changes: 74 additions & 50 deletions server/src/db/database.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,30 @@ export type Database = {
},
];
};
logs: {
Row: {
created_at: string;
id: number;
img: string;
type: string;
user_id: number;
};
Insert: {
created_at?: string;
id?: number;
img: string;
type: string;
user_id: number;
};
Update: {
created_at?: string;
id?: number;
img?: string;
type?: string;
user_id?: number;
};
Relationships: [];
};
posts: {
Row: {
createdAt: string | null;
Expand Down Expand Up @@ -441,86 +465,86 @@ type PublicSchema = Database[Extract<keyof Database, "public">];

export type Tables<
PublicTableNameOrOptions extends
| keyof (PublicSchema["Tables"] & PublicSchema["Views"])
| { schema: keyof Database },
| keyof (PublicSchema["Tables"] & PublicSchema["Views"])
| { schema: keyof Database },
TableName extends PublicTableNameOrOptions extends {
schema: keyof Database;
}
? keyof (Database[PublicTableNameOrOptions["schema"]]["Tables"] &
Database[PublicTableNameOrOptions["schema"]]["Views"])
: never = never,
? keyof (Database[PublicTableNameOrOptions["schema"]]["Tables"] &
Database[PublicTableNameOrOptions["schema"]]["Views"])
: never = never,
> = PublicTableNameOrOptions extends { schema: keyof Database }
? (Database[PublicTableNameOrOptions["schema"]]["Tables"] &
Database[PublicTableNameOrOptions["schema"]]["Views"])[TableName] extends {
Row: infer R;
}
? R
: never
Database[PublicTableNameOrOptions["schema"]]["Views"])[TableName] extends {
Row: infer R;
}
? R
: never
: PublicTableNameOrOptions extends keyof (PublicSchema["Tables"] &
PublicSchema["Views"])
? (PublicSchema["Tables"] &
PublicSchema["Views"])[PublicTableNameOrOptions] extends {
PublicSchema["Views"])
? (PublicSchema["Tables"] &
PublicSchema["Views"])[PublicTableNameOrOptions] extends {
Row: infer R;
}
? R
: never
: never;
? R
: never
: never;

export type TablesInsert<
PublicTableNameOrOptions extends
| keyof PublicSchema["Tables"]
| { schema: keyof Database },
| keyof PublicSchema["Tables"]
| { schema: keyof Database },
TableName extends PublicTableNameOrOptions extends {
schema: keyof Database;
}
? keyof Database[PublicTableNameOrOptions["schema"]]["Tables"]
: never = never,
? keyof Database[PublicTableNameOrOptions["schema"]]["Tables"]
: never = never,
> = PublicTableNameOrOptions extends { schema: keyof Database }
? Database[PublicTableNameOrOptions["schema"]]["Tables"][TableName] extends {
Insert: infer I;
}
? I
: never
Insert: infer I;
}
? I
: never
: PublicTableNameOrOptions extends keyof PublicSchema["Tables"]
? PublicSchema["Tables"][PublicTableNameOrOptions] extends {
Insert: infer I;
}
? I
: never
: never;
? PublicSchema["Tables"][PublicTableNameOrOptions] extends {
Insert: infer I;
}
? I
: never
: never;

export type TablesUpdate<
PublicTableNameOrOptions extends
| keyof PublicSchema["Tables"]
| { schema: keyof Database },
| keyof PublicSchema["Tables"]
| { schema: keyof Database },
TableName extends PublicTableNameOrOptions extends {
schema: keyof Database;
}
? keyof Database[PublicTableNameOrOptions["schema"]]["Tables"]
: never = never,
? keyof Database[PublicTableNameOrOptions["schema"]]["Tables"]
: never = never,
> = PublicTableNameOrOptions extends { schema: keyof Database }
? Database[PublicTableNameOrOptions["schema"]]["Tables"][TableName] extends {
Update: infer U;
}
? U
: never
Update: infer U;
}
? U
: never
: PublicTableNameOrOptions extends keyof PublicSchema["Tables"]
? PublicSchema["Tables"][PublicTableNameOrOptions] extends {
Update: infer U;
}
? U
: never
: never;
? PublicSchema["Tables"][PublicTableNameOrOptions] extends {
Update: infer U;
}
? U
: never
: never;

export type Enums<
PublicEnumNameOrOptions extends
| keyof PublicSchema["Enums"]
| { schema: keyof Database },
| keyof PublicSchema["Enums"]
| { schema: keyof Database },
EnumName extends PublicEnumNameOrOptions extends { schema: keyof Database }
? keyof Database[PublicEnumNameOrOptions["schema"]]["Enums"]
: never = never,
? keyof Database[PublicEnumNameOrOptions["schema"]]["Enums"]
: never = never,
> = PublicEnumNameOrOptions extends { schema: keyof Database }
? Database[PublicEnumNameOrOptions["schema"]]["Enums"][EnumName]
: PublicEnumNameOrOptions extends keyof PublicSchema["Enums"]
? PublicSchema["Enums"][PublicEnumNameOrOptions]
: never;
? PublicSchema["Enums"][PublicEnumNameOrOptions]
: never;
12 changes: 6 additions & 6 deletions server/src/middlewares/auth.middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,14 @@ const authMiddleware = async (
if (error) return res.status(400).send("Auth check failed!");

if (data.length >= 1) {
res.clearCookie("accessToken", {
httpOnly: true,
secure: true,
sameSite: "none",
})
return res
.clearCookie("accessToken", {
httpOnly: true,
secure: true,
sameSite: "none",
})
.status(200)
.send("You are banned!");
return res.status(401).send("You are banned!");
}

const verified = jwt.verify(token, key);
Expand Down
119 changes: 52 additions & 67 deletions server/src/middlewares/moderator.middleware.ts
Original file line number Diff line number Diff line change
@@ -1,88 +1,73 @@
import config from "$/config/config";
import { Response } from "express";
import axios from "axios";
import { NextFunction, Request, Response } from "express";

import { addBan, getModerationAxiosConfig } from "$/utils/axios.util";
import clearAllCookies from "$/utils/cookie.util";
import { getUserIdFromCookie } from "$/utils/getUserId.util";
import { prefix } from "$/utils/prefix.util";
import { AddPostSchema } from "$/validations/post.validation";
import { StorySchema } from "$/validations/story.validation";
import { supabase } from "$/db/connect";

const moderatorMiddleware = async (
req: Request,
const moderatorCheck = async (
res: Response,
next: NextFunction
userId: number,
id: number,
post: boolean,
imageUrl: string
) => {
// Toggle moderator on/off as per config
if (config.modOptions.modStatus === false) {
return next();
if (config.modOptions.modStatus === false || !imageUrl) {
return;
}

let validationResult;
const user_id = getUserIdFromCookie(req);
validationResult = AddPostSchema.safeParse(req);

if (!validationResult.success) {
// STORY VALIDATION
validationResult = StorySchema.safeParse(req);

if (!validationResult.success) {
return res.status(401).json("Unauthorized!");
}

const { img } = validationResult.data.body;
const options = getModerationAxiosConfig(img);

try {
const response = await axios.request(options);
if (response.data.unsafe === true) {
const banAdded = await addBan(user_id);
if (banAdded === false)
return res.status(400).json("Ban failed!");

// Clear cookies on ban
return clearAllCookies(res).status(403).send("You are banned!");
}
return next();
} catch (error) {
return res.status(400).send("Failed!");
}
}

// POSTS VALIDATION
const { userId, img, filename } = validationResult.data.body;

if (img) {
if (!filename) return res.status(401).send("Unauthorized!");
if (!img.includes(prefix.prefixPosts) || !img.includes(filename)) {
return res.status(401).send("Unauthorized!");
}
}

if (user_id !== userId) {
return res.status(401).send("Unauthorized");
}

if (!img) return next();

const options = getModerationAxiosConfig(img);
// Get axios headers setup
const options = getModerationAxiosConfig(imageUrl);

try {
const response = await axios.request(options);
if (response.data.unsafe === true) {
const banAdded = await addBan(user_id);
if (banAdded === false) return res.status(400).json("Ban failed!");
const banAdded = await addBan(userId);
if (banAdded === false)
return console.log("User ban failed upon unsafe upload!");

// Delete post or story if user banned
if (post) {
// Add logs of images for unban requests
const { error: logError } = await supabase
.from("logs")
.insert({ user_id: userId, img: imageUrl, type: "post" });
if (logError) return console.log("Error during post log!");

// Remove actual post
const { error } = await supabase
.from("posts")
.delete()
.eq("userId", userId)
.eq("id", id);
if (error) return console.log("Error during post delete!");
} else {
const { error: logError } = await supabase
.from("logs")
.insert({ user_id: userId, img: imageUrl, type: "story" });
if (logError) return console.log("Error logging story delete!");

// Remove actual story
const { error } = await supabase
.from("stories")
.delete()
.eq("userId", userId)
.eq("id", id);
if (error) return console.log("Error during Story delete!");
}

// Clear cookie on ban
return clearAllCookies(res).status(403).send("You are banned!");
} else if (response.data.unsafe === false) {
return next();
// Logout user on ban
clearAllCookies(res);
}
return res.status(401).send("Invalid imagelink for mod!");
return;
} catch (error) {
return res.status(400).send("Failed!");
if (error.code === "ERR_HTTP_HEADERS_SENT") {
return console.log("User was banned, cookie was cleared");
}
return console.log("Failed to request ban check from API!");
}
};

export default moderatorMiddleware;
export default moderatorCheck;
3 changes: 1 addition & 2 deletions server/src/routes/post.route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,12 @@ import getExplore from "$/controllers/post/getExplore.controller";
import { getPosts } from "$/controllers/post/getPosts.controller";
import { getSinglePosts } from "$/controllers/post/getSinglePost.controller";
import authMiddleware from "$/middlewares/auth.middleware";
import moderatorMiddleware from "$/middlewares/moderator.middleware";
import express from "express";

const router = express.Router();

router.get("/", authMiddleware, getPosts);
router.post("/", authMiddleware, moderatorMiddleware, addPost);
router.post("/", authMiddleware, addPost);
router.delete("/:postId", authMiddleware, deletePost);

// Get posts for explore
Expand Down
Loading

0 comments on commit b831cd8

Please sign in to comment.