diff --git a/.env b/.env index 66ecf8a..eb17487 100644 --- a/.env +++ b/.env @@ -1,4 +1,4 @@ -MONGO_URI=mongodb://192.168.0.212/ +MONGO_URI=mongodb://192.168.0.213/ MONGO_USER=mydata MONGO_PASSWORD=mongodb@hexr2002 MONGO_AUTH_DB=admin diff --git a/src/api-server/controller/collectionNodeController.ts b/src/api-server/controller/collectionNodeController.ts index 4c2e076..4b00cd1 100644 --- a/src/api-server/controller/collectionNodeController.ts +++ b/src/api-server/controller/collectionNodeController.ts @@ -167,7 +167,7 @@ export const updateCollectionController = async ( break; case "Success": res.status(200).json({ - message: "collection name updated", + message: "collection updated successfully", }); break; default: diff --git a/src/api-server/controller/projectController.ts b/src/api-server/controller/projectController.ts index 0074ef3..11bc051 100644 --- a/src/api-server/controller/projectController.ts +++ b/src/api-server/controller/projectController.ts @@ -373,11 +373,6 @@ export const updateProjectController = async ( case "Project not found": res.status(404).json({ message: "Project not found" }); break; - case "No access granted to delete this project": - res - .status(200) - .json({ message: "No access granted to update this project" }); - break; case "Project update unsuccessfull": res.status(200).json({ message: "Project update unsuccessfull" }); break; diff --git a/src/shared/services/collectionService.ts b/src/shared/services/collectionService.ts index a92a6fb..2fd40a3 100644 --- a/src/shared/services/collectionService.ts +++ b/src/shared/services/collectionService.ts @@ -1401,6 +1401,7 @@ export const DelAttributes = async ( data: IAttributesDel ): Promise => { const { organization, userId, projectId, collectionNodeId, fieldId } = data; + console.log('data: ', data); try { const existingUser = await userModel(organization).findOne({ @@ -1421,6 +1422,7 @@ export const DelAttributes = async ( isArchive: false, "attributes._id": new mongoose.Types.ObjectId(fieldId), }); + console.log('existingCollection: ', existingCollection); if (!existingCollection) return { status: "Collection not found" }; const attribute = existingCollection.attributes.find( diff --git a/src/shared/services/projectService.ts b/src/shared/services/projectService.ts index df72276..776e146 100644 --- a/src/shared/services/projectService.ts +++ b/src/shared/services/projectService.ts @@ -164,7 +164,7 @@ export const projectCreationService = async ( } ); } - return { status: "Success", data: newProject._id }; + return { status: "Success", data: newProject }; } else { return { status: "Already MVC architecture assigned to this projectId", @@ -181,7 +181,7 @@ export const projectCreationService = async ( description, }); if (!newProject) return { status: "Project creation unsuccessfull" }; - return { status: "Success", data: newProject._id }; + return { status: "Success", data: newProject }; } } } catch (error: unknown) { @@ -466,7 +466,7 @@ export const projectModification = async ( { new: true } ); if (!updateProject) return { status: "Project updated unsuccessfull" }; - return { status: "Success" }; + return { status: "Success" ,data:updateProject}; } catch (error: unknown) { if (error instanceof Error) { return { diff --git a/src/socket-server/controllers/collectionNodeController.ts b/src/socket-server/controllers/collectionNodeController.ts index 69bbc7e..b37f526 100644 --- a/src/socket-server/controllers/collectionNodeController.ts +++ b/src/socket-server/controllers/collectionNodeController.ts @@ -13,8 +13,8 @@ import { delCollection, DuplicateCollection, Nodecreation, - SetCollectionName, UpdateAttributes, + updatecollection, } from "../../shared/services/collectionService"; export const CollectionHandleEvent = async ( @@ -76,7 +76,7 @@ export const CollectionHandleEvent = async ( connectedUsersByOrg ); }; -export const CollectioNamenHandleEvent = async ( +export const CollectionUpdateHandleEvent = async ( event: string, socket: Socket, io: Server, @@ -85,13 +85,8 @@ export const CollectioNamenHandleEvent = async ( [org: string]: { socketId: string; userId: string; role: string }[]; } ) => { - if (event !== EVENTS.collectionNameSet || !data?.organization) return; - const requiredFields = [ - "collectionName", - "collectionNodeId", - "projectId", - "organization", - ]; + if (event !== EVENTS.collectionUpdate || !data?.organization) return; + const requiredFields = ["collectionNodeId", "projectId", "organization"]; const missingFields = validateFields(data, requiredFields); if (missingFields.length > 0) { @@ -99,23 +94,24 @@ export const CollectioNamenHandleEvent = async ( io, socket, data.organization, - EVENTS.collectionNameSetResponse, + EVENTS.collectionUpdateResponse, ErrorResponse(missingFields, socket, data.organization), connectedUsersByOrg ); return; } - const result = await SetCollectionName(data); + const result = await updatecollection(data); console.log("result: ", result); const status = typeof result?.status === "string" ? result.status : "unknown"; const messages: Record = { - Success: { message: "collection name updated" }, - "Collection not found": { message: "Collection not found" }, + Success: { message: "collection updated successfully" }, "Project not found": { message: "Project not found" }, - }; + "User not found": { message: "User not found" }, + "Collection not found": { message: "Collection not found" }, + "Invalid ID": { message: "nvalid ID provided" }, - const msg = messages[status] || { message: "Internal server error" }; + }; const result_Datas = status === "Success" && result?.data ? result.data : undefined; console.log("result_Datas: ", result_Datas); @@ -133,11 +129,12 @@ export const CollectioNamenHandleEvent = async ( io, socket, data.organization, - EVENTS.collectionNameSetResponse, + EVENTS.collectionUpdateResponse, response, connectedUsersByOrg ); }; + export const CollectioDeleteHandleEvent = async ( event: string, socket: Socket, @@ -350,7 +347,9 @@ export const AttributesDeleteHandleEvent = async ( const messages: Record = { Success: { message: "Field deleted successfully" }, + "User not found": { message: "User not found" }, "Project not found": { message: "Project not found" }, + "Attribute not found": { message: "field not found" }, "Collection not found": { message: "Collection not found" }, }; @@ -358,7 +357,11 @@ export const AttributesDeleteHandleEvent = async ( const result_Datas = status === "Success" && result?.data ? result.data : undefined; console.log("result_Datas: ", result_Datas); - + const result1_Datas = + (status === "Success") && result?.data + ? result.data + : undefined; + console.log('result1_Datas: ', result1_Datas); const response = FinalResponse( status, socket, @@ -388,7 +391,6 @@ export const AttributesUpdateHandleEvent = async ( ) => { if (event !== EVENTS.collectionAttributeUpdate || !data?.organization) return; const requiredFields = [ - "fieldId", "collectionNodeId", "projectId", "organization", @@ -417,10 +419,11 @@ export const AttributesUpdateHandleEvent = async ( }; const msg = messages[status] || { message: "Internal server error" }; - const result_Datas = - status === "Success" && result?.data ? result.data : undefined; - console.log("result_Datas: ", result_Datas); + const result_Datas = + (status === "Success") && result?.data + ? result.data + : undefined; const response = FinalResponse( status, socket, diff --git a/src/socket-server/controllers/projectController.ts b/src/socket-server/controllers/projectController.ts index c5f7323..9af205f 100644 --- a/src/socket-server/controllers/projectController.ts +++ b/src/socket-server/controllers/projectController.ts @@ -6,7 +6,13 @@ import { validateFields, } from "../utils/socketfunctionHelpers"; import { emitToSenderAndAdmins } from "../utils/emitEventResponse"; -import { projectCreationService } from "../../shared/services/projectService"; +import { + DeleteProject, + projectClear, + projectCreationService, + projectModification, +} from "../../shared/services/projectService"; +import { updateProjectController } from "../../api-server/controller/projectController"; export const projectHandleEvent = async ( event: string, @@ -72,3 +78,166 @@ export const projectHandleEvent = async ( connectedUsersByOrg ); }; +export const projectUpdateHandleEvent = async ( + event: string, + socket: Socket, + io: Server, + data: any, + connectedUsersByOrg: { + [org: string]: { socketId: string; userId: string; role: string }[]; + } +) => { + if (event !== EVENTS.projectUpdate || !data?.organization) return; + const requiredFields = ["projectId", "organization"]; + const missingFields = validateFields(data, requiredFields); + + if (missingFields.length > 0) { + emitToSenderAndAdmins( + io, + socket, + data.organization, + EVENTS.projectUpdateResponse, + ErrorResponse(missingFields, socket, data.organization), + connectedUsersByOrg + ); + return; + } + const result = await projectModification(data); + const status = typeof result?.status === "string" ? result.status : "unknown"; + + const messages: Record = { + Success: { message: "Project updated successfully" }, + "Project not found": { message: "Project not found" }, + "Project update unsuccessfull": { + message: "Project update unsuccessfull", + }, + "User not found": { message: "User not found" }, + }; + + const result_Datas = + status === "Success" && result?.data ? result.data : undefined; + const response = FinalResponse( + status, + socket, + data.organization, + messages, + result_Datas + ); + emitToSenderAndAdmins( + io, + socket, + data.organization, + EVENTS.projectUpdateResponse, + response, + connectedUsersByOrg + ); +}; +export const projectDeleteHandleEvent = async ( + event: string, + socket: Socket, + io: Server, + data: any, + connectedUsersByOrg: { + [org: string]: { socketId: string; userId: string; role: string }[]; + } +) => { + if (event !== EVENTS.projectDelete || !data?.organization) return; + const requiredFields = ["projectId", "organization"]; + const missingFields = validateFields(data, requiredFields); + + if (missingFields.length > 0) { + emitToSenderAndAdmins( + io, + socket, + data.organization, + EVENTS.projectDeleteResponse, + ErrorResponse(missingFields, socket, data.organization), + connectedUsersByOrg + ); + return; + } + const result = await DeleteProject(data); + const status = typeof result?.status === "string" ? result.status : "unknown"; + + const messages: Record = { + Success: { message: "Project deleted successfully" }, + "Project not found": { message: "Project not found" }, + "User not found": { message: "User not found" }, + "No access granted to delete this project": { + message: "No access granted to delete this project", + }, + "Project Delete unsuccessfull": { + message: "Project Delete unsuccessfull", + }, + }; + + const result_Datas = + status === "Success" && result?.data ? result.data : undefined; + const response = FinalResponse( + status, + socket, + data.organization, + messages, + result_Datas + ); + emitToSenderAndAdmins( + io, + socket, + data.organization, + EVENTS.projectDeleteResponse, + response, + connectedUsersByOrg + ); +}; +export const projectClearHandleEvent = async ( + event: string, + socket: Socket, + io: Server, + data: any, + connectedUsersByOrg: { + [org: string]: { socketId: string; userId: string; role: string }[]; + } +) => { + if (event !== EVENTS.projectClear || !data?.organization) return; + const requiredFields = ["projectId", "organization"]; + const missingFields = validateFields(data, requiredFields); + + if (missingFields.length > 0) { + emitToSenderAndAdmins( + io, + socket, + data.organization, + EVENTS.projectClearResponse, + ErrorResponse(missingFields, socket, data.organization), + connectedUsersByOrg + ); + return; + } + const result = await projectClear(data); + const status = typeof result?.status === "string" ? result.status : "unknown"; + + const messages: Record = { + Success: { message: "Datas cleared successfully" }, + "Project not found": { message: "Project not found" }, + "User not found": { message: "User not found" }, + "Validation Error": { message: "Validation Error" }, + }; + + const result_Datas = + status === "Success" && result?.data ? result.data : undefined; + const response = FinalResponse( + status, + socket, + data.organization, + messages, + result_Datas + ); + emitToSenderAndAdmins( + io, + socket, + data.organization, + EVENTS.projectClearResponse, + response, + connectedUsersByOrg + ); +}; diff --git a/src/socket-server/events/eventHandaler.ts b/src/socket-server/events/eventHandaler.ts index d76778f..0e88b5a 100644 --- a/src/socket-server/events/eventHandaler.ts +++ b/src/socket-server/events/eventHandaler.ts @@ -1,17 +1,35 @@ -import { AttributesDeleteHandleEvent, AttributesUpdateHandleEvent, CollectioDeleteHandleEvent, CollectioDuplicateHandleEvent, CollectioNamenHandleEvent, CollectionHandleEvent, setAttributesHandleEvent } from "../controllers/collectionNodeController"; -import { edgeHandleEvent } from "../controllers/edgeController"; -import { projectHandleEvent } from "../controllers/projectController"; +import { + AttributesDeleteHandleEvent, + AttributesUpdateHandleEvent, + CollectioDeleteHandleEvent, + CollectioDuplicateHandleEvent, + CollectionHandleEvent, + CollectionUpdateHandleEvent, + setAttributesHandleEvent, +} from "../controllers/collectionNodeController"; +import { deleteEdgeHandleEvent, edgeHandleEvent } from "../controllers/edgeController"; +import { + projectClearHandleEvent, + projectDeleteHandleEvent, + projectHandleEvent, + projectUpdateHandleEvent, +} from "../controllers/projectController"; import { EVENTS } from "./events"; export const eventHandlerMap: Record = { - [EVENTS.edgeConnect]: edgeHandleEvent, - [EVENTS.projectCreate]: projectHandleEvent, + [EVENTS.projectCreate]: projectHandleEvent, + [EVENTS.projectUpdate]: projectUpdateHandleEvent, + [EVENTS.projectDelete]: projectDeleteHandleEvent, + [EVENTS.projectClear]: projectClearHandleEvent, - [EVENTS.collectionCreate]: CollectionHandleEvent, - [EVENTS.collectionNameSet]: CollectioNamenHandleEvent, - [EVENTS.collectionDelete]: CollectioDeleteHandleEvent, - [EVENTS.collectionDuplicate]: CollectioDuplicateHandleEvent, - [EVENTS.collectionAttributeSet]: setAttributesHandleEvent, - [EVENTS.collectionAttributeDelete]: AttributesDeleteHandleEvent, - [EVENTS.collectionAttributeUpdate]: AttributesUpdateHandleEvent, -}; \ No newline at end of file + [EVENTS.collectionCreate]: CollectionHandleEvent, + [EVENTS.collectionUpdate]: CollectionUpdateHandleEvent, + [EVENTS.collectionDelete]: CollectioDeleteHandleEvent, + [EVENTS.collectionDuplicate]: CollectioDuplicateHandleEvent, + [EVENTS.collectionAttributeSet]: setAttributesHandleEvent, + [EVENTS.collectionAttributeDelete]: AttributesDeleteHandleEvent, + [EVENTS.collectionAttributeUpdate]: AttributesUpdateHandleEvent, + + [EVENTS.edgeConnect]: edgeHandleEvent, + [EVENTS.deleteEdgeConnect]: deleteEdgeHandleEvent, +}; diff --git a/src/socket-server/events/events.ts b/src/socket-server/events/events.ts index 4b68f5b..420221b 100644 --- a/src/socket-server/events/events.ts +++ b/src/socket-server/events/events.ts @@ -12,21 +12,30 @@ export const EVENTS = { projectCreate: "v1:project:create", projectCreateResponse: "v1:response:project:create", + projectUpdate: "v1:project:update", + projectUpdateResponse: "v1:response:project:update", + projectDelete: "v1:project:delete", + projectDeleteResponse: "v1:response:project:delete", + projectClear: "v1:project:clear", + projectClearResponse: "v1:response:project:clear", - collectionCreate: "v1:collection:create", - collectionCreateResponse: "v1:response:collection:create", - collectionNameSet: "v1:collection:setName", - collectionNameSetResponse: "v1:response:collection:setName", - collectionDelete: "v1:collection:delete", - collectionDeleteResponse: "v1:response:collection:delete", - collectionDuplicate: "v1:collection:duplicate", - collectionDuplicateResponse: "v1:response:collection:duplicate", - collectionAttributeSet: "v1:collection:attributeSet", - collectionAttributeSetResponse: "v1:response:collection:attributeSet", - collectionAttributeUpdate: "v1:collection:attributeUpdate", - collectionAttributeUpdateResponse: "v1:response:collection:attributeUpdate", - collectionAttributeDelete: "v1:collection:attributeDelete", - collectionAttributeDeleteResponse: "v1:response:collection:attributeDelete", + collectionCreate: "v1:collection-node:create", + collectionCreateResponse: "v1:response:collection-node:create", + collectionUpdate: "v1:collection-node:update", + collectionUpdateResponse: "v1:response:collection-node:update", + collectionNameSet: "v1:collection-node:setName", + collectionNameSetResponse: "v1:response:collection-node:setName", + collectionDelete: "v1:collection-node:delete", + collectionDeleteResponse: "v1:response:collection-node:delete", + collectionDuplicate: "v1:collection-node:duplicate", + collectionDuplicateResponse: "v1:response:collection-node:duplicate", + + collectionAttributeSet: "v1:collection-node:attributeSet", + collectionAttributeSetResponse: "v1:response:collection-node:attributeSet", + collectionAttributeUpdate: "v1:collection-node:attributeUpdate", + collectionAttributeUpdateResponse: "v1:response:collection-node:attributeUpdate", + collectionAttributeDelete: "v1:collection-node:attributeDelete", + collectionAttributeDeleteResponse: "v1:response:collection-node:attributeDelete", edgeConnect: "v1:edge:connect", edgeConnectResponse: "v1:response:edge:connect", diff --git a/src/socket-server/manager/manager.ts b/src/socket-server/manager/manager.ts index cc01635..10a2369 100644 --- a/src/socket-server/manager/manager.ts +++ b/src/socket-server/manager/manager.ts @@ -18,42 +18,53 @@ interface UserSocketInfo { const connectedUsersByOrg: { [organization: string]: UserSocketInfo[] } = {}; export const SocketServer = async (io: Server) => { - const namespaceNames = ["/edge", "/project", "/collection"]; const onlineUsers: { [organization: string]: Set } = {}; - namespaceNames.forEach((nspName) => { const namespace = io.of(nspName); namespace.use(async (socket: Socket, next) => { try { - const accessToken = socket.handshake.auth.accessToken as string; - const refreshToken = socket.handshake.auth.refreshToken as string; + const accessToken = + socket.handshake.auth?.accessToken || + socket.handshake.headers?.accesstoken; + const refreshToken = + socket.handshake.auth?.refreshToken || + socket.handshake.headers?.refreshToken; if (!accessToken) return next(new Error("No access token provided")); const jwt_secret = process.env.JWT_SECRET as string; try { const decoded = jwt.verify(accessToken, jwt_secret) as UserPayload; - const mailExistance = await existingUserData(decoded.email, decoded.organization); + const mailExistance = await existingUserData( + decoded.email, + decoded.organization + ); if (!mailExistance) { return next(new Error("Unauthorized user - not in system")); } (socket as any).user = decoded; return next(); - } catch (err: any) { if (err.name === "TokenExpiredError") { if (!refreshToken) { - return next(new Error("Token expired and no refresh token provided")); - + return next( + new Error("Token expired and no refresh token provided") + ); } try { const refreshSecret = process.env.REFRESH_JWT_SECRET as string; - const decodedRefresh = jwt.verify(refreshToken, refreshSecret) as UserPayload; - const mailExistance = await existingUserData(decodedRefresh.email, decodedRefresh.organization); + const decodedRefresh = jwt.verify( + refreshToken, + refreshSecret + ) as UserPayload; + const mailExistance = await existingUserData( + decodedRefresh.email, + decodedRefresh.organization + ); if (!mailExistance) { return next(new Error("Unauthorized user - not in system")); @@ -61,9 +72,12 @@ export const SocketServer = async (io: Server) => { // Generate new access token const newAccessToken = jwt.sign( - { email: decodedRefresh.email, organization: decodedRefresh.organization }, + { + email: decodedRefresh.email, + organization: decodedRefresh.organization, + }, jwt_secret, - { expiresIn: "3h" } // adjust expiry + { expiresIn: "3h" } // adjust expiry ); socket.emit("newAccessToken", newAccessToken); @@ -88,8 +102,13 @@ export const SocketServer = async (io: Server) => { if (!onlineUsers[organization]) onlineUsers[organization] = new Set(); onlineUsers[organization].add(socket.id); - if (!connectedUsersByOrg[organization]) connectedUsersByOrg[organization] = []; - connectedUsersByOrg[organization].push({ socketId: socket.id, userId, organization }); + if (!connectedUsersByOrg[organization]) + connectedUsersByOrg[organization] = []; + connectedUsersByOrg[organization].push({ + socketId: socket.id, + userId, + organization, + }); console.log(`✅ Connected to namespace ${nspName}: ${socket.id}`); // Common event handler @@ -107,9 +126,9 @@ export const SocketServer = async (io: Server) => { if (onlineUsers[organization]?.size === 0) { delete onlineUsers[organization]; } - connectedUsersByOrg[organization] = connectedUsersByOrg[organization]?.filter( - (u) => u.socketId !== socket.id - ); + connectedUsersByOrg[organization] = connectedUsersByOrg[ + organization + ]?.filter((u) => u.socketId !== socket.id); }); }); });