Skip to content

Commit 57d829a

Browse files
committed
feat: add document permission management with CRUD operations
1 parent 4439aef commit 57d829a

File tree

4 files changed

+161
-10
lines changed

4 files changed

+161
-10
lines changed

src/app.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import userRoutes from "./routes/user.routes";
88
import documentCategoryRoutes from "./routes/document-category.routes";
99
import documentRoutes from "./routes/document.routes";
1010
import projectMemberRoutes from "./routes/project-member.routes";
11+
import documentPermissions from "./routes/document-permission.routes";
1112

1213
import { auth } from "./middleware/auth.middleware";
1314

@@ -35,5 +36,6 @@ app.use("/api/projects", projectRoutes);
3536
app.use("/api/document-categories", documentCategoryRoutes);
3637
app.use("/api/documents", documentRoutes);
3738
app.use("/api/project-members", projectMemberRoutes);
39+
app.use("/api/document-permissions", documentPermissions);
3840

3941
export default app;
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
import { Request, Response, NextFunction } from "express";
2+
import prisma from "../db/prisma";
3+
import * as response from "../utils/response";
4+
5+
export const addDocumentPermission = async (
6+
req: Request,
7+
res: Response,
8+
next: NextFunction
9+
): Promise<void> => {
10+
try {
11+
const { documentId, userId } = req.body;
12+
13+
const existingPermission = await prisma.documentPermission.findUnique({
14+
where: {
15+
documentId_userId: {
16+
documentId,
17+
userId,
18+
},
19+
},
20+
});
21+
22+
if (existingPermission) {
23+
return response.errorResponse(
24+
res,
25+
"Permission already exists for this user on this document."
26+
);
27+
}
28+
29+
const documentPermission = await prisma.documentPermission.create({
30+
data: {
31+
documentId,
32+
userId,
33+
},
34+
});
35+
36+
return response.successResponse(
37+
res,
38+
"Document permission added successfully.",
39+
{ documentPermission }
40+
);
41+
} catch (error) {
42+
console.error(error);
43+
response.errorResponse(res, "Internal server error.");
44+
}
45+
};
46+
47+
// Get all permissions for a document
48+
export const getDocumentPermissions = async (
49+
req: Request,
50+
res: Response,
51+
next: NextFunction
52+
): Promise<void> => {
53+
try {
54+
const { documentId } = req.params;
55+
56+
const permissions = await prisma.documentPermission.findMany({
57+
where: { documentId },
58+
include: {
59+
user: true, // Include user details
60+
},
61+
});
62+
63+
if (permissions.length === 0) {
64+
return response.errorResponse(
65+
res,
66+
"No permissions found for this document."
67+
);
68+
}
69+
70+
return response.successResponse(
71+
res,
72+
"Document permissions fetched successfully.",
73+
{ permissions }
74+
);
75+
} catch (error) {
76+
console.error(error);
77+
response.errorResponse(res, "Internal server error.");
78+
}
79+
};
80+
81+
// Remove a permission from a document
82+
export const removeDocumentPermission = async (
83+
req: Request,
84+
res: Response,
85+
next: NextFunction
86+
): Promise<void> => {
87+
try {
88+
const { documentId, userId } = req.params;
89+
90+
const documentPermission = await prisma.documentPermission.findUnique({
91+
where: {
92+
documentId_userId: {
93+
documentId,
94+
userId,
95+
},
96+
},
97+
});
98+
99+
if (!documentPermission) {
100+
return response.errorResponse(res, "Document permission not found.");
101+
}
102+
103+
await prisma.documentPermission.delete({
104+
where: {
105+
id: documentPermission.id,
106+
},
107+
});
108+
109+
return response.successResponse(
110+
res,
111+
"Document permission removed successfully."
112+
);
113+
} catch (error) {
114+
console.error(error);
115+
response.errorResponse(res, "Internal server error.");
116+
}
117+
};

src/controllers/user.controller.ts

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@ import { nodeEnv } from "../config";
55
import prisma from "../db/prisma";
66
import * as response from "../utils/response";
77

8-
export const register = async (req: Request, res: Response, next: NextFunction): Promise<void> => {
8+
export const register = async (
9+
req: Request,
10+
res: Response,
11+
next: NextFunction
12+
): Promise<void> => {
913
try {
1014
const { email, password, fullName } = req.body;
1115

@@ -34,12 +38,15 @@ export const register = async (req: Request, res: Response, next: NextFunction):
3438
});
3539
} catch (error) {
3640
console.error(error);
37-
res.status(500).json({ message: "Internal server error." });
41+
return response.errorResponse(res, "Internal server error.");
3842
}
3943
};
4044

41-
42-
export const login = async (req: Request, res: Response, next: NextFunction): Promise<void> => {
45+
export const login = async (
46+
req: Request,
47+
res: Response,
48+
next: NextFunction
49+
): Promise<void> => {
4350
try {
4451
const { email, password } = req.body;
4552

@@ -63,7 +70,7 @@ export const login = async (req: Request, res: Response, next: NextFunction): Pr
6370
secure: nodeEnv === "production",
6471
sameSite: "lax",
6572
path: "/",
66-
expires: new Date(Date.now() + 1000 * 60 * 60 * 24), // 1 day
73+
expires: new Date(Date.now() + 1000 * 60 * 60 * 24),
6774
});
6875

6976
return response.successResponse(res, "Logged in successfully.", {
@@ -73,21 +80,29 @@ export const login = async (req: Request, res: Response, next: NextFunction): Pr
7380
});
7481
} catch (error) {
7582
console.error(error);
76-
res.status(500).json({ message: "Internal server error." });
83+
return response.errorResponse(res, "Internal server error.");
7784
}
7885
};
7986

80-
export const logout = async (req: Request, res: Response, next: NextFunction): Promise<void> => {
87+
export const logout = async (
88+
req: Request,
89+
res: Response,
90+
next: NextFunction
91+
): Promise<void> => {
8192
try {
8293
res.clearCookie("token");
8394
return response.successResponse(res, "Logged out successfully.");
8495
} catch (error) {
8596
console.error(error);
86-
res.status(500).json({ message: "Internal server error." });
97+
return response.errorResponse(res, "Internal server error.");
8798
}
8899
};
89100

90-
export const getMe = async (req: Request, res: Response, next: NextFunction): Promise<void> => {
101+
export const getMe = async (
102+
req: Request,
103+
res: Response,
104+
next: NextFunction
105+
): Promise<void> => {
91106
try {
92107
const userId = (req as any).user?.id;
93108

@@ -110,6 +125,6 @@ export const getMe = async (req: Request, res: Response, next: NextFunction): Pr
110125
});
111126
} catch (error) {
112127
console.error(error);
113-
res.status(500).json({ message: "Internal server error." });
128+
return response.errorResponse(res, "Internal server error.");
114129
}
115130
};
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import express from "express";
2+
import {
3+
addDocumentPermission,
4+
getDocumentPermissions,
5+
removeDocumentPermission,
6+
} from "../controllers/document-permission.controller";
7+
8+
const router = express.Router();
9+
10+
router.post("/document-permissions", addDocumentPermission);
11+
router.get("/document-permissions/:documentId", getDocumentPermissions);
12+
router.delete(
13+
"/document-permissions/:documentId/:userId",
14+
removeDocumentPermission
15+
);
16+
17+
export default router;

0 commit comments

Comments
 (0)