lapeh 2.4.12 → 2.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/index.js +669 -942
- package/dist/generated/prisma/internal/prismaNamespace.d.ts +21 -16
- package/dist/generated/prisma/internal/prismaNamespace.d.ts.map +1 -1
- package/dist/generated/prisma/internal/prismaNamespaceBrowser.d.ts +3 -3
- package/dist/generated/prisma/internal/prismaNamespaceBrowser.d.ts.map +1 -1
- package/dist/lib/bootstrap.d.ts.map +1 -1
- package/dist/lib/bootstrap.js +34 -11
- package/dist/lib/core/database.d.ts.map +1 -1
- package/dist/lib/core/database.js +7 -1
- package/dist/lib/utils/response.d.ts +1 -1
- package/dist/lib/utils/response.d.ts.map +1 -1
- package/dist/src/config/app.d.ts +10 -0
- package/dist/src/config/app.d.ts.map +1 -0
- package/dist/src/config/app.js +12 -0
- package/dist/src/config/cors.d.ts +6 -0
- package/dist/src/config/cors.d.ts.map +1 -0
- package/dist/src/config/cors.js +8 -0
- package/dist/src/modules/Auth/auth.controller.d.ts +11 -0
- package/dist/src/modules/Auth/auth.controller.d.ts.map +1 -0
- package/dist/src/modules/Auth/auth.controller.js +414 -0
- package/dist/src/modules/Pets/pets.controller.d.ts +7 -0
- package/dist/src/modules/Pets/pets.controller.d.ts.map +1 -0
- package/dist/src/modules/Pets/pets.controller.js +163 -0
- package/dist/src/modules/Rbac/rbac.controller.d.ts +16 -0
- package/dist/src/modules/Rbac/rbac.controller.d.ts.map +1 -0
- package/dist/src/modules/Rbac/rbac.controller.js +437 -0
- package/dist/src/routes/auth.js +9 -9
- package/dist/src/routes/pets.js +1 -1
- package/dist/src/routes/rbac.js +15 -15
- package/lib/bootstrap.ts +34 -13
- package/lib/core/database.ts +7 -1
- package/lib/utils/response.ts +4 -4
- package/package.json +4 -5
- package/prisma/base.prisma.template +0 -1
- package/prisma/schema.prisma +0 -1
- package/prisma.config.ts +14 -0
- package/scripts/compile-schema.js +28 -10
- package/scripts/make-module.js +100 -158
- package/src/config/app.ts +9 -0
- package/src/config/cors.ts +5 -0
- package/src/routes/auth.ts +1 -1
- package/src/routes/pets.ts +1 -1
- package/src/routes/rbac.ts +1 -1
- package/storage/logs/.0337f5062fe676994d1dc340156e089444e3d6e0-audit.json +5 -0
- package/storage/logs/lapeh-2025-12-29.log +94 -0
- package/scripts/make-controller.js +0 -205
- package/scripts/make-model.js +0 -42
- /package/src/{controllers/authController.ts → modules/Auth/auth.controller.ts} +0 -0
- /package/src/{models/core.prisma → modules/Auth/auth.prisma} +0 -0
- /package/src/{controllers/petController.ts → modules/Pets/pets.controller.ts} +0 -0
- /package/src/{models → modules/Pets}/pets.prisma +0 -0
- /package/src/{controllers/rbacController.ts → modules/Rbac/rbac.controller.ts} +0 -0
|
@@ -0,0 +1,437 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createRole = createRole;
|
|
4
|
+
exports.listRoles = listRoles;
|
|
5
|
+
exports.updateRole = updateRole;
|
|
6
|
+
exports.deleteRole = deleteRole;
|
|
7
|
+
exports.createPermission = createPermission;
|
|
8
|
+
exports.listPermissions = listPermissions;
|
|
9
|
+
exports.updatePermission = updatePermission;
|
|
10
|
+
exports.deletePermission = deletePermission;
|
|
11
|
+
exports.assignRoleToUser = assignRoleToUser;
|
|
12
|
+
exports.removeRoleFromUser = removeRoleFromUser;
|
|
13
|
+
exports.assignPermissionToRole = assignPermissionToRole;
|
|
14
|
+
exports.removePermissionFromRole = removePermissionFromRole;
|
|
15
|
+
exports.assignPermissionToUser = assignPermissionToUser;
|
|
16
|
+
exports.removePermissionFromUser = removePermissionFromUser;
|
|
17
|
+
const database_1 = require("../../../lib/core/database");
|
|
18
|
+
const response_1 = require("../../../lib/utils/response");
|
|
19
|
+
const validator_1 = require("../../../lib/utils/validator");
|
|
20
|
+
const zod_1 = require("zod");
|
|
21
|
+
const serializer_1 = require("../../../lib/core/serializer");
|
|
22
|
+
// --- Serializers ---
|
|
23
|
+
const roleSchema = {
|
|
24
|
+
type: "object",
|
|
25
|
+
properties: {
|
|
26
|
+
id: { type: "string" },
|
|
27
|
+
name: { type: "string" },
|
|
28
|
+
slug: { type: "string" },
|
|
29
|
+
description: { type: "string", nullable: true },
|
|
30
|
+
created_at: { type: "string", format: "date-time", nullable: true },
|
|
31
|
+
updated_at: { type: "string", format: "date-time", nullable: true },
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
const permissionSchema = {
|
|
35
|
+
type: "object",
|
|
36
|
+
properties: {
|
|
37
|
+
id: { type: "string" },
|
|
38
|
+
name: { type: "string" },
|
|
39
|
+
slug: { type: "string" },
|
|
40
|
+
description: { type: "string", nullable: true },
|
|
41
|
+
created_at: { type: "string", format: "date-time", nullable: true },
|
|
42
|
+
updated_at: { type: "string", format: "date-time", nullable: true },
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
const roleSerializer = (0, serializer_1.getSerializer)("role", (0, serializer_1.createResponseSchema)(roleSchema));
|
|
46
|
+
const roleListSerializer = (0, serializer_1.getSerializer)("role-list", (0, serializer_1.createResponseSchema)({ type: "array", items: roleSchema }));
|
|
47
|
+
const permissionSerializer = (0, serializer_1.getSerializer)("permission", (0, serializer_1.createResponseSchema)(permissionSchema));
|
|
48
|
+
const permissionListSerializer = (0, serializer_1.getSerializer)("permission-list", (0, serializer_1.createResponseSchema)({ type: "array", items: permissionSchema }));
|
|
49
|
+
const voidSerializer = (0, serializer_1.getSerializer)("void", (0, serializer_1.createResponseSchema)({ type: "null" }));
|
|
50
|
+
// --- Controllers ---
|
|
51
|
+
async function createRole(req, res) {
|
|
52
|
+
const validator = validator_1.Validator.make(req.body || {}, {
|
|
53
|
+
name: "required|string|min:1",
|
|
54
|
+
slug: "required|string|min:1|unique:roles,slug",
|
|
55
|
+
description: "string",
|
|
56
|
+
});
|
|
57
|
+
if (await validator.fails()) {
|
|
58
|
+
(0, response_1.sendError)(res, 422, "Validation error", validator.errors());
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
const { name, slug, description } = await validator.validated();
|
|
62
|
+
// Manual unique check removed as it is handled by validator
|
|
63
|
+
const role = await database_1.prisma.roles.create({
|
|
64
|
+
data: {
|
|
65
|
+
name,
|
|
66
|
+
slug,
|
|
67
|
+
description: description || null,
|
|
68
|
+
created_at: new Date(),
|
|
69
|
+
updated_at: new Date(),
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
(0, response_1.sendFastSuccess)(res, 201, roleSerializer, {
|
|
73
|
+
status: "success",
|
|
74
|
+
message: "Role created",
|
|
75
|
+
data: { ...role, id: role.id.toString() },
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
async function listRoles(_req, res) {
|
|
79
|
+
const roles = await database_1.prisma.roles.findMany({
|
|
80
|
+
orderBy: { id: "asc" },
|
|
81
|
+
});
|
|
82
|
+
const serialized = roles.map((r) => ({ ...r, id: r.id.toString() }));
|
|
83
|
+
(0, response_1.sendFastSuccess)(res, 200, roleListSerializer, {
|
|
84
|
+
status: "success",
|
|
85
|
+
message: "Roles list",
|
|
86
|
+
data: serialized,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
async function updateRole(req, res) {
|
|
90
|
+
const { id } = req.params;
|
|
91
|
+
const roleId = BigInt(id);
|
|
92
|
+
const validator = validator_1.Validator.make(req.body || {}, {
|
|
93
|
+
name: "string",
|
|
94
|
+
slug: `string|unique:roles,slug,${id}`,
|
|
95
|
+
description: "string",
|
|
96
|
+
});
|
|
97
|
+
if (await validator.fails()) {
|
|
98
|
+
(0, response_1.sendError)(res, 422, "Validation error", validator.errors());
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
const { name, slug, description } = await validator.validated();
|
|
102
|
+
const role = await database_1.prisma.roles.findUnique({ where: { id: roleId } });
|
|
103
|
+
if (!role) {
|
|
104
|
+
(0, response_1.sendError)(res, 404, "Role not found");
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
// Manual unique check removed as it is handled by validator
|
|
108
|
+
const updated = await database_1.prisma.roles.update({
|
|
109
|
+
where: { id: roleId },
|
|
110
|
+
data: {
|
|
111
|
+
name: name ?? role.name,
|
|
112
|
+
slug: slug ?? role.slug,
|
|
113
|
+
description: description ?? role.description,
|
|
114
|
+
updated_at: new Date(),
|
|
115
|
+
},
|
|
116
|
+
});
|
|
117
|
+
(0, response_1.sendFastSuccess)(res, 200, roleSerializer, {
|
|
118
|
+
status: "success",
|
|
119
|
+
message: "Role updated",
|
|
120
|
+
data: { ...updated, id: updated.id.toString() },
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
async function deleteRole(req, res) {
|
|
124
|
+
const { id } = req.params;
|
|
125
|
+
const roleId = BigInt(id);
|
|
126
|
+
const role = await database_1.prisma.roles.findUnique({ where: { id: roleId } });
|
|
127
|
+
if (!role) {
|
|
128
|
+
(0, response_1.sendError)(res, 404, "Role not found");
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
await database_1.prisma.role_permissions.deleteMany({ where: { role_id: roleId } });
|
|
132
|
+
await database_1.prisma.user_roles.deleteMany({ where: { role_id: roleId } });
|
|
133
|
+
await database_1.prisma.roles.delete({ where: { id: roleId } });
|
|
134
|
+
(0, response_1.sendFastSuccess)(res, 200, voidSerializer, {
|
|
135
|
+
status: "success",
|
|
136
|
+
message: "Role deleted",
|
|
137
|
+
data: null,
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
async function createPermission(req, res) {
|
|
141
|
+
const validator = validator_1.Validator.make(req.body || {}, {
|
|
142
|
+
name: "required|string|min:1",
|
|
143
|
+
slug: "required|string|min:1|unique:permissions,slug",
|
|
144
|
+
description: "string",
|
|
145
|
+
});
|
|
146
|
+
if (await validator.fails()) {
|
|
147
|
+
(0, response_1.sendError)(res, 422, "Validation error", validator.errors());
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
const { name, slug, description } = await validator.validated();
|
|
151
|
+
// Manual unique check removed as it is handled by validator
|
|
152
|
+
const permission = await database_1.prisma.permissions.create({
|
|
153
|
+
data: {
|
|
154
|
+
name,
|
|
155
|
+
slug,
|
|
156
|
+
description: description || null,
|
|
157
|
+
created_at: new Date(),
|
|
158
|
+
updated_at: new Date(),
|
|
159
|
+
},
|
|
160
|
+
});
|
|
161
|
+
(0, response_1.sendFastSuccess)(res, 201, permissionSerializer, {
|
|
162
|
+
status: "success",
|
|
163
|
+
message: "Permission created",
|
|
164
|
+
data: { ...permission, id: permission.id.toString() },
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
async function listPermissions(_req, res) {
|
|
168
|
+
const permissions = await database_1.prisma.permissions.findMany({
|
|
169
|
+
orderBy: { id: "asc" },
|
|
170
|
+
});
|
|
171
|
+
const serialized = permissions.map((p) => ({
|
|
172
|
+
...p,
|
|
173
|
+
id: p.id.toString(),
|
|
174
|
+
}));
|
|
175
|
+
(0, response_1.sendFastSuccess)(res, 200, permissionListSerializer, {
|
|
176
|
+
status: "success",
|
|
177
|
+
message: "Permissions list",
|
|
178
|
+
data: serialized,
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
async function updatePermission(req, res) {
|
|
182
|
+
const { id } = req.params;
|
|
183
|
+
const permissionId = BigInt(id);
|
|
184
|
+
const validator = validator_1.Validator.make(req.body || {}, {
|
|
185
|
+
name: "string",
|
|
186
|
+
slug: `string|unique:permissions,slug,${id}`,
|
|
187
|
+
description: "string",
|
|
188
|
+
});
|
|
189
|
+
if (await validator.fails()) {
|
|
190
|
+
(0, response_1.sendError)(res, 422, "Validation error", validator.errors());
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
const { name, slug, description } = await validator.validated();
|
|
194
|
+
const permission = await database_1.prisma.permissions.findUnique({
|
|
195
|
+
where: { id: permissionId },
|
|
196
|
+
});
|
|
197
|
+
if (!permission) {
|
|
198
|
+
(0, response_1.sendError)(res, 404, "Permission not found");
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
// Manual unique check removed as it is handled by validator
|
|
202
|
+
const updated = await database_1.prisma.permissions.update({
|
|
203
|
+
where: { id: permissionId },
|
|
204
|
+
data: {
|
|
205
|
+
name: name ?? permission.name,
|
|
206
|
+
slug: slug ?? permission.slug,
|
|
207
|
+
description: description ?? permission.description,
|
|
208
|
+
updated_at: new Date(),
|
|
209
|
+
},
|
|
210
|
+
});
|
|
211
|
+
(0, response_1.sendFastSuccess)(res, 200, permissionSerializer, {
|
|
212
|
+
status: "success",
|
|
213
|
+
message: "Permission updated",
|
|
214
|
+
data: { ...updated, id: updated.id.toString() },
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
async function deletePermission(req, res) {
|
|
218
|
+
const { id } = req.params;
|
|
219
|
+
const permissionId = BigInt(id);
|
|
220
|
+
const permission = await database_1.prisma.permissions.findUnique({
|
|
221
|
+
where: { id: permissionId },
|
|
222
|
+
});
|
|
223
|
+
if (!permission) {
|
|
224
|
+
(0, response_1.sendError)(res, 404, "Permission not found");
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
await database_1.prisma.role_permissions.deleteMany({
|
|
228
|
+
where: { permission_id: permissionId },
|
|
229
|
+
});
|
|
230
|
+
await database_1.prisma.user_permissions.deleteMany({
|
|
231
|
+
where: { permission_id: permissionId },
|
|
232
|
+
});
|
|
233
|
+
await database_1.prisma.permissions.delete({ where: { id: permissionId } });
|
|
234
|
+
(0, response_1.sendFastSuccess)(res, 200, voidSerializer, {
|
|
235
|
+
status: "success",
|
|
236
|
+
message: "Permission deleted",
|
|
237
|
+
data: null,
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
async function assignRoleToUser(req, res) {
|
|
241
|
+
const validator = validator_1.Validator.make(req.body || {}, {
|
|
242
|
+
userId: zod_1.z.string().min(1, "userId wajib diisi"),
|
|
243
|
+
roleId: zod_1.z.string().min(1, "roleId wajib diisi"),
|
|
244
|
+
});
|
|
245
|
+
if (await validator.fails()) {
|
|
246
|
+
(0, response_1.sendError)(res, 422, "Validation error", validator.errors());
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
const { userId, roleId } = await validator.validated();
|
|
250
|
+
const user = await database_1.prisma.users.findUnique({
|
|
251
|
+
where: { id: BigInt(userId) },
|
|
252
|
+
});
|
|
253
|
+
if (!user) {
|
|
254
|
+
(0, response_1.sendError)(res, 404, "User not found");
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
const role = await database_1.prisma.roles.findUnique({
|
|
258
|
+
where: { id: BigInt(roleId) },
|
|
259
|
+
});
|
|
260
|
+
if (!role) {
|
|
261
|
+
(0, response_1.sendError)(res, 404, "Role not found");
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
await database_1.prisma.user_roles.upsert({
|
|
265
|
+
where: {
|
|
266
|
+
user_id_role_id: {
|
|
267
|
+
user_id: BigInt(userId),
|
|
268
|
+
role_id: BigInt(roleId),
|
|
269
|
+
},
|
|
270
|
+
},
|
|
271
|
+
create: {
|
|
272
|
+
user_id: BigInt(userId),
|
|
273
|
+
role_id: BigInt(roleId),
|
|
274
|
+
created_at: new Date(),
|
|
275
|
+
},
|
|
276
|
+
update: {},
|
|
277
|
+
});
|
|
278
|
+
(0, response_1.sendFastSuccess)(res, 200, voidSerializer, {
|
|
279
|
+
status: "success",
|
|
280
|
+
message: "Role assigned to user",
|
|
281
|
+
data: null,
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
async function removeRoleFromUser(req, res) {
|
|
285
|
+
const validator = validator_1.Validator.make(req.body || {}, {
|
|
286
|
+
userId: zod_1.z.string().min(1, "userId wajib diisi"),
|
|
287
|
+
roleId: zod_1.z.string().min(1, "roleId wajib diisi"),
|
|
288
|
+
});
|
|
289
|
+
if (await validator.fails()) {
|
|
290
|
+
(0, response_1.sendError)(res, 422, "Validation error", validator.errors());
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
const { userId, roleId } = await validator.validated();
|
|
294
|
+
await database_1.prisma.user_roles.deleteMany({
|
|
295
|
+
where: {
|
|
296
|
+
user_id: BigInt(userId),
|
|
297
|
+
role_id: BigInt(roleId),
|
|
298
|
+
},
|
|
299
|
+
});
|
|
300
|
+
(0, response_1.sendFastSuccess)(res, 200, voidSerializer, {
|
|
301
|
+
status: "success",
|
|
302
|
+
message: "Role removed from user",
|
|
303
|
+
data: null,
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
async function assignPermissionToRole(req, res) {
|
|
307
|
+
const validator = validator_1.Validator.make(req.body || {}, {
|
|
308
|
+
roleId: zod_1.z.string().min(1, "roleId wajib diisi"),
|
|
309
|
+
permissionId: zod_1.z.string().min(1, "permissionId wajib diisi"),
|
|
310
|
+
});
|
|
311
|
+
if (await validator.fails()) {
|
|
312
|
+
(0, response_1.sendError)(res, 422, "Validation error", validator.errors());
|
|
313
|
+
return;
|
|
314
|
+
}
|
|
315
|
+
const { roleId, permissionId } = await validator.validated();
|
|
316
|
+
const role = await database_1.prisma.roles.findUnique({
|
|
317
|
+
where: { id: BigInt(roleId) },
|
|
318
|
+
});
|
|
319
|
+
if (!role) {
|
|
320
|
+
(0, response_1.sendError)(res, 404, "Role not found");
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
const permission = await database_1.prisma.permissions.findUnique({
|
|
324
|
+
where: { id: BigInt(permissionId) },
|
|
325
|
+
});
|
|
326
|
+
if (!permission) {
|
|
327
|
+
(0, response_1.sendError)(res, 404, "Permission not found");
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
await database_1.prisma.role_permissions.upsert({
|
|
331
|
+
where: {
|
|
332
|
+
role_id_permission_id: {
|
|
333
|
+
role_id: BigInt(roleId),
|
|
334
|
+
permission_id: BigInt(permissionId),
|
|
335
|
+
},
|
|
336
|
+
},
|
|
337
|
+
create: {
|
|
338
|
+
role_id: BigInt(roleId),
|
|
339
|
+
permission_id: BigInt(permissionId),
|
|
340
|
+
created_at: new Date(),
|
|
341
|
+
},
|
|
342
|
+
update: {},
|
|
343
|
+
});
|
|
344
|
+
(0, response_1.sendFastSuccess)(res, 200, voidSerializer, {
|
|
345
|
+
status: "success",
|
|
346
|
+
message: "Permission assigned to role",
|
|
347
|
+
data: null,
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
async function removePermissionFromRole(req, res) {
|
|
351
|
+
const validator = validator_1.Validator.make(req.body || {}, {
|
|
352
|
+
roleId: zod_1.z.string().min(1, "roleId wajib diisi"),
|
|
353
|
+
permissionId: zod_1.z.string().min(1, "permissionId wajib diisi"),
|
|
354
|
+
});
|
|
355
|
+
if (await validator.fails()) {
|
|
356
|
+
(0, response_1.sendError)(res, 422, "Validation error", validator.errors());
|
|
357
|
+
return;
|
|
358
|
+
}
|
|
359
|
+
const { roleId, permissionId } = await validator.validated();
|
|
360
|
+
await database_1.prisma.role_permissions.deleteMany({
|
|
361
|
+
where: {
|
|
362
|
+
role_id: BigInt(roleId),
|
|
363
|
+
permission_id: BigInt(permissionId),
|
|
364
|
+
},
|
|
365
|
+
});
|
|
366
|
+
(0, response_1.sendFastSuccess)(res, 200, voidSerializer, {
|
|
367
|
+
status: "success",
|
|
368
|
+
message: "Permission removed from role",
|
|
369
|
+
data: null,
|
|
370
|
+
});
|
|
371
|
+
}
|
|
372
|
+
async function assignPermissionToUser(req, res) {
|
|
373
|
+
const validator = validator_1.Validator.make(req.body || {}, {
|
|
374
|
+
userId: zod_1.z.string().min(1, "userId wajib diisi"),
|
|
375
|
+
permissionId: zod_1.z.string().min(1, "permissionId wajib diisi"),
|
|
376
|
+
});
|
|
377
|
+
if (await validator.fails()) {
|
|
378
|
+
(0, response_1.sendError)(res, 422, "Validation error", validator.errors());
|
|
379
|
+
return;
|
|
380
|
+
}
|
|
381
|
+
const { userId, permissionId } = await validator.validated();
|
|
382
|
+
const user = await database_1.prisma.users.findUnique({
|
|
383
|
+
where: { id: BigInt(userId) },
|
|
384
|
+
});
|
|
385
|
+
if (!user) {
|
|
386
|
+
(0, response_1.sendError)(res, 404, "User not found");
|
|
387
|
+
return;
|
|
388
|
+
}
|
|
389
|
+
const permission = await database_1.prisma.permissions.findUnique({
|
|
390
|
+
where: { id: BigInt(permissionId) },
|
|
391
|
+
});
|
|
392
|
+
if (!permission) {
|
|
393
|
+
(0, response_1.sendError)(res, 404, "Permission not found");
|
|
394
|
+
return;
|
|
395
|
+
}
|
|
396
|
+
await database_1.prisma.user_permissions.upsert({
|
|
397
|
+
where: {
|
|
398
|
+
user_id_permission_id: {
|
|
399
|
+
user_id: BigInt(userId),
|
|
400
|
+
permission_id: BigInt(permissionId),
|
|
401
|
+
},
|
|
402
|
+
},
|
|
403
|
+
create: {
|
|
404
|
+
user_id: BigInt(userId),
|
|
405
|
+
permission_id: BigInt(permissionId),
|
|
406
|
+
created_at: new Date(),
|
|
407
|
+
},
|
|
408
|
+
update: {},
|
|
409
|
+
});
|
|
410
|
+
(0, response_1.sendFastSuccess)(res, 200, voidSerializer, {
|
|
411
|
+
status: "success",
|
|
412
|
+
message: "Permission assigned to user",
|
|
413
|
+
data: null,
|
|
414
|
+
});
|
|
415
|
+
}
|
|
416
|
+
async function removePermissionFromUser(req, res) {
|
|
417
|
+
const validator = validator_1.Validator.make(req.body || {}, {
|
|
418
|
+
userId: zod_1.z.string().min(1, "userId wajib diisi"),
|
|
419
|
+
permissionId: zod_1.z.string().min(1, "permissionId wajib diisi"),
|
|
420
|
+
});
|
|
421
|
+
if (await validator.fails()) {
|
|
422
|
+
(0, response_1.sendError)(res, 422, "Validation error", validator.errors());
|
|
423
|
+
return;
|
|
424
|
+
}
|
|
425
|
+
const { userId, permissionId } = await validator.validated();
|
|
426
|
+
await database_1.prisma.user_permissions.deleteMany({
|
|
427
|
+
where: {
|
|
428
|
+
user_id: BigInt(userId),
|
|
429
|
+
permission_id: BigInt(permissionId),
|
|
430
|
+
},
|
|
431
|
+
});
|
|
432
|
+
(0, response_1.sendFastSuccess)(res, 200, voidSerializer, {
|
|
433
|
+
status: "success",
|
|
434
|
+
message: "Permission removed from user",
|
|
435
|
+
data: null,
|
|
436
|
+
});
|
|
437
|
+
}
|
package/dist/src/routes/auth.js
CHANGED
|
@@ -10,7 +10,7 @@ const express_rate_limit_1 = __importDefault(require("express-rate-limit"));
|
|
|
10
10
|
const multer = require("multer");
|
|
11
11
|
const path_1 = __importDefault(require("path"));
|
|
12
12
|
const fs_1 = __importDefault(require("fs"));
|
|
13
|
-
const
|
|
13
|
+
const auth_controller_1 = require("../modules/Auth/auth.controller");
|
|
14
14
|
const auth_1 = require("../../lib/middleware/auth");
|
|
15
15
|
const authLimiter = (0, express_rate_limit_1.default)({
|
|
16
16
|
windowMs: 15 * 60 * 1000,
|
|
@@ -35,11 +35,11 @@ const storage = multer.diskStorage({
|
|
|
35
35
|
});
|
|
36
36
|
const uploadAvatar = multer({ storage });
|
|
37
37
|
exports.authRouter = (0, express_1.Router)();
|
|
38
|
-
exports.authRouter.post("/register", authLimiter,
|
|
39
|
-
exports.authRouter.post("/login", authLimiter,
|
|
40
|
-
exports.authRouter.get("/me", auth_1.requireAuth,
|
|
41
|
-
exports.authRouter.post("/logout", auth_1.requireAuth,
|
|
42
|
-
exports.authRouter.post("/refresh", authLimiter,
|
|
43
|
-
exports.authRouter.put("/password", auth_1.requireAuth,
|
|
44
|
-
exports.authRouter.put("/profile", auth_1.requireAuth,
|
|
45
|
-
exports.authRouter.post("/avatar", auth_1.requireAuth, uploadAvatar.single("avatar"),
|
|
38
|
+
exports.authRouter.post("/register", authLimiter, auth_controller_1.register);
|
|
39
|
+
exports.authRouter.post("/login", authLimiter, auth_controller_1.login);
|
|
40
|
+
exports.authRouter.get("/me", auth_1.requireAuth, auth_controller_1.me);
|
|
41
|
+
exports.authRouter.post("/logout", auth_1.requireAuth, auth_controller_1.logout);
|
|
42
|
+
exports.authRouter.post("/refresh", authLimiter, auth_controller_1.refreshToken);
|
|
43
|
+
exports.authRouter.put("/password", auth_1.requireAuth, auth_controller_1.updatePassword);
|
|
44
|
+
exports.authRouter.put("/profile", auth_1.requireAuth, auth_controller_1.updateProfile);
|
|
45
|
+
exports.authRouter.post("/avatar", auth_1.requireAuth, uploadAvatar.single("avatar"), auth_controller_1.updateAvatar);
|
package/dist/src/routes/pets.js
CHANGED
|
@@ -34,7 +34,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
const express_1 = require("express");
|
|
37
|
-
const PetController = __importStar(require("../
|
|
37
|
+
const PetController = __importStar(require("../modules/Pets/pets.controller"));
|
|
38
38
|
const multipart_1 = require("../../lib/middleware/multipart");
|
|
39
39
|
const router = (0, express_1.Router)();
|
|
40
40
|
router.get("/", PetController.index);
|
package/dist/src/routes/rbac.js
CHANGED
|
@@ -3,21 +3,21 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.rbacRouter = void 0;
|
|
4
4
|
const express_1 = require("express");
|
|
5
5
|
const auth_1 = require("../../lib/middleware/auth");
|
|
6
|
-
const
|
|
6
|
+
const rbac_controller_1 = require("../modules/Rbac/rbac.controller");
|
|
7
7
|
exports.rbacRouter = (0, express_1.Router)();
|
|
8
8
|
exports.rbacRouter.use(auth_1.requireAuth);
|
|
9
9
|
exports.rbacRouter.use(auth_1.requireAdmin);
|
|
10
|
-
exports.rbacRouter.post("/roles",
|
|
11
|
-
exports.rbacRouter.get("/roles",
|
|
12
|
-
exports.rbacRouter.put("/roles/:id",
|
|
13
|
-
exports.rbacRouter.delete("/roles/:id",
|
|
14
|
-
exports.rbacRouter.post("/permissions",
|
|
15
|
-
exports.rbacRouter.get("/permissions",
|
|
16
|
-
exports.rbacRouter.put("/permissions/:id",
|
|
17
|
-
exports.rbacRouter.delete("/permissions/:id",
|
|
18
|
-
exports.rbacRouter.post("/users/assign-role",
|
|
19
|
-
exports.rbacRouter.post("/users/remove-role",
|
|
20
|
-
exports.rbacRouter.post("/roles/assign-permission",
|
|
21
|
-
exports.rbacRouter.post("/roles/remove-permission",
|
|
22
|
-
exports.rbacRouter.post("/users/assign-permission",
|
|
23
|
-
exports.rbacRouter.post("/users/remove-permission",
|
|
10
|
+
exports.rbacRouter.post("/roles", rbac_controller_1.createRole);
|
|
11
|
+
exports.rbacRouter.get("/roles", rbac_controller_1.listRoles);
|
|
12
|
+
exports.rbacRouter.put("/roles/:id", rbac_controller_1.updateRole);
|
|
13
|
+
exports.rbacRouter.delete("/roles/:id", rbac_controller_1.deleteRole);
|
|
14
|
+
exports.rbacRouter.post("/permissions", rbac_controller_1.createPermission);
|
|
15
|
+
exports.rbacRouter.get("/permissions", rbac_controller_1.listPermissions);
|
|
16
|
+
exports.rbacRouter.put("/permissions/:id", rbac_controller_1.updatePermission);
|
|
17
|
+
exports.rbacRouter.delete("/permissions/:id", rbac_controller_1.deletePermission);
|
|
18
|
+
exports.rbacRouter.post("/users/assign-role", rbac_controller_1.assignRoleToUser);
|
|
19
|
+
exports.rbacRouter.post("/users/remove-role", rbac_controller_1.removeRoleFromUser);
|
|
20
|
+
exports.rbacRouter.post("/roles/assign-permission", rbac_controller_1.assignPermissionToRole);
|
|
21
|
+
exports.rbacRouter.post("/roles/remove-permission", rbac_controller_1.removePermissionFromRole);
|
|
22
|
+
exports.rbacRouter.post("/users/assign-permission", rbac_controller_1.assignPermissionToUser);
|
|
23
|
+
exports.rbacRouter.post("/users/remove-permission", rbac_controller_1.removePermissionFromUser);
|
package/lib/bootstrap.ts
CHANGED
|
@@ -23,17 +23,45 @@ export async function createApp() {
|
|
|
23
23
|
// We map '@lapeh' to the directory containing this file (lib/ or dist/lib/)
|
|
24
24
|
moduleAlias.addAlias("@lapeh", __dirname);
|
|
25
25
|
|
|
26
|
+
// LOAD USER CONFIG
|
|
27
|
+
const isProduction = process.env.NODE_ENV === "production";
|
|
28
|
+
const configPath = isProduction
|
|
29
|
+
? path.join(process.cwd(), "dist", "src", "config")
|
|
30
|
+
: path.join(process.cwd(), "src", "config");
|
|
31
|
+
|
|
32
|
+
let appConfig: any = { timeout: 30000, jsonLimit: "10mb" };
|
|
33
|
+
let corsConfig: any = {
|
|
34
|
+
origin: process.env.CORS_ORIGIN || "*",
|
|
35
|
+
credentials: true,
|
|
36
|
+
exposedHeaders: ["x-access-token", "x-access-expires-at"],
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
try {
|
|
40
|
+
const appConfModule = require(path.join(configPath, "app"));
|
|
41
|
+
if (appConfModule.appConfig) appConfig = { ...appConfig, ...appConfModule.appConfig };
|
|
42
|
+
} catch (e) {
|
|
43
|
+
// ignore
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
try {
|
|
47
|
+
const corsConfModule = require(path.join(configPath, "cors"));
|
|
48
|
+
if (corsConfModule.corsConfig) corsConfig = { ...corsConfig, ...corsConfModule.corsConfig };
|
|
49
|
+
} catch (e) {
|
|
50
|
+
// ignore
|
|
51
|
+
}
|
|
52
|
+
|
|
26
53
|
const app = express();
|
|
27
54
|
|
|
28
55
|
app.disable("x-powered-by");
|
|
29
56
|
app.use(compression());
|
|
30
57
|
|
|
31
|
-
// Request Timeout Middleware
|
|
58
|
+
// Request Timeout Middleware
|
|
32
59
|
app.use((_req: Request, res: Response, next: NextFunction) => {
|
|
33
|
-
|
|
60
|
+
const timeout = appConfig.timeout || 30000;
|
|
61
|
+
res.setTimeout(timeout, () => {
|
|
34
62
|
res.status(408).send({
|
|
35
63
|
status: "error",
|
|
36
|
-
message:
|
|
64
|
+
message: `Request Timeout (${timeout/1000}s limit)`,
|
|
37
65
|
});
|
|
38
66
|
});
|
|
39
67
|
next();
|
|
@@ -46,18 +74,11 @@ export async function createApp() {
|
|
|
46
74
|
})
|
|
47
75
|
);
|
|
48
76
|
|
|
49
|
-
|
|
50
|
-
app.use(
|
|
51
|
-
cors({
|
|
52
|
-
origin: corsOrigin,
|
|
53
|
-
credentials: true,
|
|
54
|
-
exposedHeaders: ["x-access-token", "x-access-expires-at"],
|
|
55
|
-
})
|
|
56
|
-
);
|
|
77
|
+
app.use(cors(corsConfig));
|
|
57
78
|
|
|
58
79
|
app.use(requestLogger);
|
|
59
|
-
app.use(express.json({ limit: "10mb" }));
|
|
60
|
-
app.use(express.urlencoded({ extended: true, limit: "10mb" }));
|
|
80
|
+
app.use(express.json({ limit: appConfig.jsonLimit || "10mb" }));
|
|
81
|
+
app.use(express.urlencoded({ extended: true, limit: appConfig.jsonLimit || "10mb" }));
|
|
61
82
|
app.use(apiLimiter);
|
|
62
83
|
app.use(visitorCounter);
|
|
63
84
|
|
package/lib/core/database.ts
CHANGED
package/lib/utils/response.ts
CHANGED
|
@@ -7,7 +7,7 @@ type ErrorStatus = "error";
|
|
|
7
7
|
type SuccessBody<T> = {
|
|
8
8
|
status: SuccessStatus;
|
|
9
9
|
message: string;
|
|
10
|
-
data
|
|
10
|
+
data?: T;
|
|
11
11
|
};
|
|
12
12
|
|
|
13
13
|
type ErrorBody<T = unknown> = {
|
|
@@ -36,13 +36,13 @@ function toJsonSafe(value: unknown): unknown {
|
|
|
36
36
|
return value;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
export function sendSuccess<T>(
|
|
39
|
+
export function sendSuccess<T = any>(
|
|
40
40
|
res: Response,
|
|
41
41
|
statusCode: number,
|
|
42
42
|
message: string,
|
|
43
|
-
data
|
|
43
|
+
data?: T
|
|
44
44
|
) {
|
|
45
|
-
const body: SuccessBody<T> = { status: "success", message, data };
|
|
45
|
+
const body: SuccessBody<T | undefined> = { status: "success", message, data };
|
|
46
46
|
return res.status(statusCode).json(toJsonSafe(body));
|
|
47
47
|
}
|
|
48
48
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lapeh",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.6.2",
|
|
4
4
|
"description": "Framework API Express yang siap pakai (Standardized)",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=18.0.0",
|
|
@@ -61,8 +61,7 @@
|
|
|
61
61
|
"db:studio": "prisma studio",
|
|
62
62
|
"generate:jwt": "node scripts/generate-jwt-secret.js",
|
|
63
63
|
"make:module": "node scripts/make-module.js",
|
|
64
|
-
"make:
|
|
65
|
-
"make:controller": "node scripts/make-controller.js",
|
|
64
|
+
"make:modul": "node scripts/make-module.js",
|
|
66
65
|
"config:clear": "node scripts/config-clear.js",
|
|
67
66
|
"prepublishOnly": "npm run build"
|
|
68
67
|
},
|
|
@@ -89,7 +88,7 @@
|
|
|
89
88
|
"license": "MIT",
|
|
90
89
|
"type": "commonjs",
|
|
91
90
|
"dependencies": {
|
|
92
|
-
"@prisma/client": "
|
|
91
|
+
"@prisma/client": "7.2.0",
|
|
93
92
|
"@types/bcryptjs": "2.4.6",
|
|
94
93
|
"@types/compression": "^1.8.1",
|
|
95
94
|
"@types/cors": "2.8.19",
|
|
@@ -131,7 +130,7 @@
|
|
|
131
130
|
"eslint": "^9.39.2",
|
|
132
131
|
"globals": "^16.5.0",
|
|
133
132
|
"jest": "^30.2.0",
|
|
134
|
-
"prisma": "
|
|
133
|
+
"prisma": "7.2.0",
|
|
135
134
|
"supertest": "^7.1.4",
|
|
136
135
|
"ts-jest": "^29.4.6",
|
|
137
136
|
"typescript-eslint": "^8.50.1"
|