From c73d57410a757c796e725c9ebae8accf397b8e3f Mon Sep 17 00:00:00 2001 From: Akhil Meka Date: Fri, 16 May 2025 17:25:39 +0530 Subject: [PATCH] update role claims, refactor getUniqueValues --- src/note/note.route.ts | 14 ++--- src/notification/notification.route.ts | 13 ++--- src/notification/notification.service.ts | 26 ---------- src/permit/permit.controller.ts | 15 ------ src/permit/permit.route.ts | 20 +++++--- src/permit/permit.service.ts | 23 --------- src/processed/processed.route.ts | 13 ++--- src/processed/processed.service.ts | 26 ---------- src/rts/rts.route.ts | 10 ++-- src/rts/rts.service.ts | 25 --------- src/task/task.route.ts | 13 ++--- src/task/task.service.ts | 25 --------- src/unique.ts | 65 ++++++++++++++++++++++++ src/utils/claims.ts | 5 +- src/utils/roles.ts | 12 +++++ 15 files changed, 114 insertions(+), 191 deletions(-) create mode 100644 src/unique.ts diff --git a/src/note/note.route.ts b/src/note/note.route.ts index 39d1fa6..9d0a2d8 100644 --- a/src/note/note.route.ts +++ b/src/note/note.route.ts @@ -5,12 +5,8 @@ import { deleteNoteHandler, updateNoteHandler, } from "./note.controller"; -import { Claim } from "../utils/claims"; -export async function noteRoutes( - fastify: FastifyInstance, - claims: { read: Claim; write: Claim; delete: Claim } -) { +export async function noteRoutes(fastify: FastifyInstance) { fastify.post( "/:resourceId/notes", { @@ -20,7 +16,7 @@ export async function noteRoutes( properties: { resourceId: { type: "string" } }, }, }, - config: { requiredClaims: [claims.write] }, + config: { requiredClaims: ["note:write"] }, preHandler: [fastify.authorize], }, createNoteHandler @@ -35,7 +31,7 @@ export async function noteRoutes( properties: { resourceId: { type: "string" } }, }, }, - config: { requiredClaims: [claims.read] }, + config: { requiredClaims: ["note:read"] }, preHandler: [fastify.authorize], }, listNotesHandler @@ -53,7 +49,7 @@ export async function noteRoutes( }, }, }, - config: { requiredClaims: [claims.write] }, + config: { requiredClaims: ["note:write"] }, preHandler: [fastify.authorize], }, updateNoteHandler @@ -71,7 +67,7 @@ export async function noteRoutes( }, }, }, - config: { requiredClaims: [claims.write] }, + config: { requiredClaims: ["note:delete"] }, preHandler: [fastify.authorize], }, deleteNoteHandler diff --git a/src/notification/notification.route.ts b/src/notification/notification.route.ts index 73bcbb8..1e91a77 100644 --- a/src/notification/notification.route.ts +++ b/src/notification/notification.route.ts @@ -6,8 +6,8 @@ import { listNotificationsHandler, updateNotificationHandler, } from "./notification.controller"; -import { getUniqueValuesNotification } from "./notification.service"; import { noteRoutes } from "../note/note.route"; +import { getUniqueFields } from "../unique"; export async function notificationRoutes(fastify: FastifyInstance) { fastify.post( @@ -95,9 +95,10 @@ export async function notificationRoutes(fastify: FastifyInstance) { const { field } = req.params as { field: string }; try { - const uniqueValues = await getUniqueValuesNotification( + const uniqueValues = await getUniqueFields( field, - req.user.tenantId + "notifications", + req.user ); return res.code(200).send(uniqueValues); } catch (err) { @@ -106,9 +107,5 @@ export async function notificationRoutes(fastify: FastifyInstance) { } ); - await noteRoutes(fastify, { - read: "rts:read", - write: "rts:write", - delete: "rts:delete", - }); + await noteRoutes(fastify); } diff --git a/src/notification/notification.service.ts b/src/notification/notification.service.ts index 5794a69..c393b70 100644 --- a/src/notification/notification.service.ts +++ b/src/notification/notification.service.ts @@ -139,29 +139,3 @@ export async function deleteNotification(notifId: string, tenantId: string) { $and: [{ tenantId: tenantId }, { pid: notifId }], }); } - -export async function getUniqueValuesNotification( - field: string, - tenenatId: string -) { - let values = await notificationModel.distinct(field, { tenantId: tenenatId }); - - let matchedValues = []; - if (field === "county.name") { - matchedValues = await orgModel.find().where("name").in(values).exec(); - } else if (field === "client") { - matchedValues = await orgModel.find().where("_id").in(values).exec(); - } else if (field === "assignedTo") { - matchedValues = await userModel.find().where("_id").in(values).exec(); - } - - if (matchedValues.length > 0) { - const newValues = {}; - for (const item of matchedValues) { - newValues[item.id] = item.name; - } - return newValues; - } - - return values; -} diff --git a/src/permit/permit.controller.ts b/src/permit/permit.controller.ts index a21ea63..a1cd75f 100644 --- a/src/permit/permit.controller.ts +++ b/src/permit/permit.controller.ts @@ -4,7 +4,6 @@ import { createPermit, deletePermit, getPermit, - getUniqueValuesPermit, listPermits, searchPermit, updatePermit, @@ -103,17 +102,3 @@ export async function searchPermitHandler( return err; } } - -export async function getUniqueFieldValuesPermit( - req: FastifyRequest, - res: FastifyReply -) { - const { field } = req.params as { field: string }; - - try { - const uniqueValues = await getUniqueValuesPermit(field, req.user.tenantId); - return res.code(200).send(uniqueValues); - } catch (err) { - return err; - } -} diff --git a/src/permit/permit.route.ts b/src/permit/permit.route.ts index 2a708d1..05e0886 100644 --- a/src/permit/permit.route.ts +++ b/src/permit/permit.route.ts @@ -1,9 +1,7 @@ import { FastifyInstance } from "fastify"; import { - createPermitHandler, deletePermitHandler, getPermitHandler, - getUniqueFieldValuesPermit, listPermitsHandler, searchPermitHandler, updatePermitHandler, @@ -11,6 +9,7 @@ import { import { $permit } from "./permit.schema"; import { hideFields } from "../auth"; import { noteRoutes } from "../note/note.route"; +import { getUniqueFields } from "../unique"; export async function permitRoutes(fastify: FastifyInstance) { /* fastify.post( @@ -109,14 +108,19 @@ export async function permitRoutes(fastify: FastifyInstance) { config: { requiredClaims: ["permit:read"] }, preHandler: [fastify.authorize], }, - getUniqueFieldValuesPermit + async (req, res) => { + const { field } = req.params as { field: string }; + + try { + const uniqueValues = await getUniqueFields(field, "permits", req.user); + return res.code(200).send(uniqueValues); + } catch (err) { + return err; + } + } ); - await noteRoutes(fastify, { - read: "permit:read", - write: "permit:write", - delete: "permit:delete", - }); + await noteRoutes(fastify); fastify.addHook("onSend", hideFields("permits")); } diff --git a/src/permit/permit.service.ts b/src/permit/permit.service.ts index 44b3acc..d5787be 100644 --- a/src/permit/permit.service.ts +++ b/src/permit/permit.service.ts @@ -324,26 +324,3 @@ export async function searchPermit( }, }; } - -export async function getUniqueValuesPermit(field: string, tenenatId: string) { - let values = await permitModel.distinct(field, { tenantId: tenenatId }); - - let matchedValues = []; - if (field === "county.name") { - matchedValues = await orgModel.find().where("name").in(values).exec(); - } else if (field === "client") { - matchedValues = await orgModel.find().where("_id").in(values).exec(); - } else if (field === "assignedTo") { - matchedValues = await userModel.find().where("_id").in(values).exec(); - } - - if (matchedValues.length > 0) { - const newValues = {}; - for (const item of matchedValues) { - newValues[item.id] = item.name; - } - return newValues; - } - - return values; -} diff --git a/src/processed/processed.route.ts b/src/processed/processed.route.ts index 7bdc2bd..eb747e9 100644 --- a/src/processed/processed.route.ts +++ b/src/processed/processed.route.ts @@ -2,12 +2,12 @@ import { FastifyInstance, FastifyReply, FastifyRequest } from "fastify"; import { PageQueryParams } from "../pagination"; import { getProcessedPermit, - getUniqueValuesProcessed, listProcessedPermits, updateProcessed, } from "./processed.service"; import { $processed, UpdateProcessedInput } from "./processed.schema"; import { noteRoutes } from "../note/note.route"; +import { getUniqueFields } from "../unique"; export async function processedRoutes(fastify: FastifyInstance) { fastify.get( @@ -120,9 +120,10 @@ export async function processedRoutes(fastify: FastifyInstance) { const { field } = req.params as { field: string }; try { - const uniqueValues = await getUniqueValuesProcessed( + const uniqueValues = await getUniqueFields( field, - req.user.tenantId + "processed", + req.user ); return res.code(200).send(uniqueValues); } catch (err) { @@ -131,9 +132,5 @@ export async function processedRoutes(fastify: FastifyInstance) { } ); - await noteRoutes(fastify, { - read: "permit:read", - write: "permit:write", - delete: "permit:delete", - }); + await noteRoutes(fastify); } diff --git a/src/processed/processed.service.ts b/src/processed/processed.service.ts index 1e426a3..e34777d 100644 --- a/src/processed/processed.service.ts +++ b/src/processed/processed.service.ts @@ -155,29 +155,3 @@ export async function listProcessedPermits( }, }; } - -export async function getUniqueValuesProcessed( - field: string, - tenenatId: string -) { - let values = await processedModel.distinct(field, { tenantId: tenenatId }); - - let matchedValues = []; - if (field === "county.name") { - matchedValues = await orgModel.find().where("name").in(values).exec(); - } else if (field === "client") { - matchedValues = await orgModel.find().where("_id").in(values).exec(); - } else if (field === "assignedTo") { - matchedValues = await userModel.find().where("_id").in(values).exec(); - } - - if (matchedValues.length > 0) { - const newValues = {}; - for (const item of matchedValues) { - newValues[item.id] = item.name; - } - return newValues; - } - - return values; -} diff --git a/src/rts/rts.route.ts b/src/rts/rts.route.ts index aec6359..579ef0e 100644 --- a/src/rts/rts.route.ts +++ b/src/rts/rts.route.ts @@ -10,7 +10,7 @@ import { } from "./rts.controller"; import { hideFields } from "../auth"; import { noteRoutes } from "../note/note.route"; -import { getUniqueValuesRTS } from "./rts.service"; +import { getUniqueFields } from "../unique"; export async function rtsRoutes(fastify: FastifyInstance) { fastify.post( @@ -114,7 +114,7 @@ export async function rtsRoutes(fastify: FastifyInstance) { const { field } = req.params as { field: string }; try { - const uniqueValues = await getUniqueValuesRTS(field, req.user.tenantId); + const uniqueValues = await getUniqueFields(field, "rts", req.user); return res.code(200).send(uniqueValues); } catch (err) { return err; @@ -122,11 +122,7 @@ export async function rtsRoutes(fastify: FastifyInstance) { } ); - await noteRoutes(fastify, { - read: "rts:read", - write: "rts:write", - delete: "rts:delete", - }); + await noteRoutes(fastify); fastify.addHook("onSend", hideFields("rts")); } diff --git a/src/rts/rts.service.ts b/src/rts/rts.service.ts index dcf906c..72f21ee 100644 --- a/src/rts/rts.service.ts +++ b/src/rts/rts.service.ts @@ -209,28 +209,3 @@ export async function newUpload( } ); } - -export async function getUniqueValuesRTS(field: string, tenenatId: string) { - let values = await rtsModel.distinct(field, { tenantId: tenenatId }); - - let matchedValues = []; - if (field === "county") { - matchedValues = await orgModel.find().where("_id").in(values).exec(); - } else if (field === "client") { - matchedValues = await orgModel.find().where("_id").in(values).exec(); - } else if (field === "createdBy") { - matchedValues = await userModel.find().where("_id").in(values).exec(); - } else if (field === "assignedTo") { - matchedValues = await userModel.find().where("_id").in(values).exec(); - } - - if (matchedValues.length > 0) { - const newValues = {}; - for (const item of matchedValues) { - newValues[item.id] = item.name; - } - return newValues; - } - - return values; -} diff --git a/src/task/task.route.ts b/src/task/task.route.ts index bdad36a..b7944ea 100644 --- a/src/task/task.route.ts +++ b/src/task/task.route.ts @@ -10,7 +10,7 @@ import { updateTaskHandler, } from "./task.controller"; import { noteRoutes } from "../note/note.route"; -import { getUniqueValuesTasks } from "./task.service"; +import { getUniqueFields } from "../unique"; export async function taskRoutes(fastify: FastifyInstance) { fastify.post( @@ -126,10 +126,7 @@ export async function taskRoutes(fastify: FastifyInstance) { const { field } = req.params as { field: string }; try { - const uniqueValues = await getUniqueValuesTasks( - field, - req.user.tenantId - ); + const uniqueValues = await getUniqueFields(field, "task", req.user); return res.code(200).send(uniqueValues); } catch (err) { return err; @@ -137,9 +134,5 @@ export async function taskRoutes(fastify: FastifyInstance) { } ); - await noteRoutes(fastify, { - read: "task:read", - write: "task:write", - delete: "task:delete", - }); + await noteRoutes(fastify); } diff --git a/src/task/task.service.ts b/src/task/task.service.ts index f941920..172da30 100644 --- a/src/task/task.service.ts +++ b/src/task/task.service.ts @@ -251,28 +251,3 @@ export async function newUpload( } ); } - -export async function getUniqueValuesTasks(field: string, tenenatId: string) { - let values = await taskModel.distinct(field, { tenantId: tenenatId }); - - let matchedValues = []; - if (field === "county") { - matchedValues = await orgModel.find().where("_id").in(values).exec(); - } else if (field === "client") { - matchedValues = await orgModel.find().where("_id").in(values).exec(); - } else if (field === "createdBy") { - matchedValues = await userModel.find().where("_id").in(values).exec(); - } else if (field === "assignedTo") { - matchedValues = await userModel.find().where("_id").in(values).exec(); - } - - if (matchedValues.length > 0) { - const newValues = {}; - for (const item of matchedValues) { - newValues[item.id] = item.name; - } - return newValues; - } - - return values; -} diff --git a/src/unique.ts b/src/unique.ts new file mode 100644 index 0000000..c5f5a8d --- /dev/null +++ b/src/unique.ts @@ -0,0 +1,65 @@ +import { orgModel } from "./organization/organization.schema"; +import { userModel } from "./user/user.schema"; +import { permitModel } from "./permit/permit.schema"; +import { processedModel } from "./processed/processed.schema"; +import { notificationModel } from "./notification/notification.schema"; +import { rtsModel } from "./rts/rts.schema"; +import { taskModel } from "./task/task.schema"; +import { AuthenticatedUser } from "./auth"; + +type Collection = + | "users" + | "permits" + | "organizations" + | "processed" + | "notifications" + | "rts" + | "task"; + +const modelMap = { + users: userModel, + permits: permitModel, + organizations: orgModel, + processed: processedModel, + notifications: notificationModel, + rts: rtsModel, + task: taskModel, +}; + +export async function getUniqueFields( + field: string, + collection: Collection, + user: AuthenticatedUser +) { + const model = modelMap[collection]; + if (!model) throw new Error("invalid collection"); + + let values = await model.distinct(field, { tenantId: user.tenantId }); + + let matchedValues = []; + if (field === "county.name") { + matchedValues = await orgModel.find().where("name").in(values).exec(); + } else if (field === "county") { + matchedValues = await orgModel.find().where("_id").in(values).exec(); + } else if (field === "client") { + if (user.role == "client") { + values = [user.orgId]; + } + + matchedValues = await orgModel.find().where("_id").in(values).exec(); + } else if (field === "createdBy") { + matchedValues = await userModel.find().where("_id").in(values).exec(); + } else if (field === "assignedTo") { + matchedValues = await userModel.find().where("_id").in(values).exec(); + } + + if (matchedValues.length > 0) { + const newValues = {}; + for (const item of matchedValues) { + newValues[item.id] = item.name; + } + return newValues; + } + + return values; +} diff --git a/src/utils/claims.ts b/src/utils/claims.ts index 280ae4b..3dcf97e 100644 --- a/src/utils/claims.ts +++ b/src/utils/claims.ts @@ -28,4 +28,7 @@ export type Claim = | "mail:all" | "view:read" | "view:write" - | "view:delete"; + | "view:delete" + | "note:read" + | "note:write" + | "note:delete"; diff --git a/src/utils/roles.ts b/src/utils/roles.ts index e3e18e5..ac74e7f 100644 --- a/src/utils/roles.ts +++ b/src/utils/roles.ts @@ -33,6 +33,9 @@ export const rules: Record< "view:read", "view:write", "view:delete", + "note:read", + "note:write", + "note:delete", ], hiddenFields: { orgs: ["__v"], @@ -67,6 +70,9 @@ export const rules: Record< "view:read", "view:write", "view:delete", + "note:read", + "note:write", + "note:delete", ], hiddenFields: { orgs: ["__v"], @@ -94,6 +100,9 @@ export const rules: Record< "view:read", "view:write", "view:delete", + "note:read", + "note:write", + "note:delete", ], hiddenFields: { orgs: ["__v"], @@ -114,6 +123,9 @@ export const rules: Record< "view:read", "view:write", "view:delete", + "note:read", + "note:write", + "note:delete", ], hiddenFields: { orgs: ["__v"],