diff --git a/src/api-server/controller/authController.ts b/src/api-server/controller/authController.ts index f614fd6..d91cffc 100644 --- a/src/api-server/controller/authController.ts +++ b/src/api-server/controller/authController.ts @@ -1,155 +1,155 @@ -import { Request, Response } from "express"; -import { - forgetPassword, - signinService, - signupService, -} from "../../shared/services/AuthService"; - -export const signupController = async ( - req: Request, - res: Response -): Promise => { - try { - const { userName, email, password, confirmPassword } = req.body; - if (!userName || !email || !password || !confirmPassword) { - res.status(400).json({ - message: "All fields are required", - }); - return; - } - const data = { - userName, - email, - password, - confirmPassword, - }; - const result = await signupService(data); - - switch (result.status) { - case "User Already exists": - res.status(403).json({ - message: "User Already exists", - }); - break; - case "Passwords do not match": - res.status(200).json({ - message: "Passwords do not match", - }); - break; - case "Signup unsuccessfull": - res.status(200).json({ - message: "Signup unsuccessfull", - }); - break; - case "Success": - res.status(200).json({ - message: "Signup Successfull", - }); - break; - default: - res.status(500).json({ - message: "Internal server error", - }); - break; - } - } catch (error) { - res.status(500).json({ - message: "Unknown error", - }); - } -}; -export const signinController = async ( - req: Request, - res: Response -): Promise => { - try { - const { email, password } = req.body; - if (!email || !password) { - res.status(400).json({ - message: "All fields are required", - }); - return; - } - const data = { - email, - password, - }; - const result = await signinService(data); - - switch (result.status) { - case "User not found!!! Kindly Signup": - res.status(403).json({ - message: "User not found!!! Kindly Signup", - }); - break; - case "Password is invalid...Check the credentials": - res.status(200).json({ - message: "Password is invalid...Check the credentials", - }); - break; - - case "Success": - res.status(200).json({ - message: "Signup Successfull", - data: result.data, - }); - break; - default: - res.status(500).json({ - message: "Internal server error", - }); - break; - } - } catch (error) { - res.status(500).json({ - message: "Unknown error", - }); - } -}; -export const forgetPasswordController = async ( - req: Request, - res: Response -): Promise => { - try { - const { email } = req.body; - if (!email) { - res.status(400).json({ - message: "All fields are required", - }); - return; - } - const data = { - email, - }; - const result = await forgetPassword(data); - - switch (result.status) { - case "User not found!!! Kindly Signup": - res.status(403).json({ - message: "User not found!!! Kindly Signup", - }); - break; - case "Password is invalid...Check the credentials": - res.status(200).json({ - message: "Password is invalid...Check the credentials", - }); - break; - - case "Success": - res.status(200).json({ - message: "Signup Successfull", - // data: result.data, - }); - break; - default: - res.status(500).json({ - message: "Internal server error", - }); - break; - } - } catch (error) { - res.status(500).json({ - message: "Unknown error", - }); - } -}; +import { Request, Response } from "express"; +import { + forgetPassword, + signinService, + signupService, +} from "../../shared/services/AuthService"; + +export const signupController = async ( + req: Request, + res: Response +): Promise => { + try { + const { userName, email, password, confirmPassword } = req.body; + if (!userName || !email || !password || !confirmPassword) { + res.status(400).json({ + message: "All fields are required", + }); + return; + } + const data = { + userName, + email, + password, + confirmPassword, + }; + const result = await signupService(data); + + switch (result.status) { + case "User Already exists": + res.status(403).json({ + message: "User Already exists", + }); + break; + case "Passwords do not match": + res.status(200).json({ + message: "Passwords do not match", + }); + break; + case "Signup unsuccessfull": + res.status(200).json({ + message: "Signup unsuccessfull", + }); + break; + case "Success": + res.status(200).json({ + message: "Signup Successfull", + }); + break; + default: + res.status(500).json({ + message: "Internal server error", + }); + break; + } + } catch (error) { + res.status(500).json({ + message: "Unknown error", + }); + } +}; +export const signinController = async ( + req: Request, + res: Response +): Promise => { + try { + const { email, password } = req.body; + if (!email || !password) { + res.status(400).json({ + message: "All fields are required", + }); + return; + } + const data = { + email, + password, + }; + const result = await signinService(data); + + switch (result.status) { + case "User not found!!! Kindly Signup": + res.status(403).json({ + message: "User not found!!! Kindly Signup", + }); + break; + case "Password is invalid...Check the credentials": + res.status(200).json({ + message: "Password is invalid...Check the credentials", + }); + break; + + case "Success": + res.status(200).json({ + message: "Signup Successfull", + data: result.data, + }); + break; + default: + res.status(500).json({ + message: "Internal server error", + }); + break; + } + } catch (error) { + res.status(500).json({ + message: "Unknown error", + }); + } +}; +export const forgetPasswordController = async ( + req: Request, + res: Response +): Promise => { + try { + const { email } = req.body; + if (!email) { + res.status(400).json({ + message: "All fields are required", + }); + return; + } + const data = { + email, + }; + const result = await forgetPassword(data); + + switch (result.status) { + case "User not found!!! Kindly Signup": + res.status(403).json({ + message: "User not found!!! Kindly Signup", + }); + break; + case "Password is invalid...Check the credentials": + res.status(200).json({ + message: "Password is invalid...Check the credentials", + }); + break; + + case "Success": + res.status(200).json({ + message: "Signup Successfull", + // data: result.data, + }); + break; + default: + res.status(500).json({ + message: "Internal server error", + }); + break; + } + } catch (error) { + res.status(500).json({ + message: "Unknown error", + }); + } +}; diff --git a/src/api-server/controller/homePageController.ts b/src/api-server/controller/homePageController.ts index 82541cf..6d5df2f 100644 --- a/src/api-server/controller/homePageController.ts +++ b/src/api-server/controller/homePageController.ts @@ -1,45 +1,45 @@ -import { Request, Response } from "express"; -import { AuthenticatedRequest } from "../../shared/utils/token"; -import { recentlyViewedServices } from "../../shared/services/homePageService"; - -export const homePageRecentlyViewedController = async ( - req: AuthenticatedRequest, - res: Response -): Promise => { - try { - const { organization, userId } = req.user || {}; - if (!organization || !userId) { - res.status(400).json({ - message: "All fields are required", - }); - return; - } - const data = { - organization, - userId, - }; - const result = await recentlyViewedServices(data); - - switch (result.status) { - case "User not found": - res.status(403).json({ - message: "User not found", - }); - break; - case "Success": - res.status(200).json({ - datas: result.data, - }); - break; - default: - res.status(500).json({ - message: "Internal server error", - }); - break; - } - } catch (error) { - res.status(500).json({ - message: "Unknown error", - }); - } -}; +import { Request, Response } from "express"; +import { AuthenticatedRequest } from "../../shared/utils/token"; +import { recentlyViewedServices } from "../../shared/services/homePageService"; + +export const homePageRecentlyViewedController = async ( + req: AuthenticatedRequest, + res: Response +): Promise => { + try { + const { organization, userId } = req.user || {}; + if (!organization || !userId) { + res.status(400).json({ + message: "All fields are required", + }); + return; + } + const data = { + organization, + userId, + }; + const result = await recentlyViewedServices(data); + + switch (result.status) { + case "User not found": + res.status(403).json({ + message: "User not found", + }); + break; + case "Success": + res.status(200).json({ + datas: result.data, + }); + break; + default: + res.status(500).json({ + message: "Internal server error", + }); + break; + } + } catch (error) { + res.status(500).json({ + message: "Unknown error", + }); + } +}; diff --git a/src/api-server/routes/authRoutes.ts b/src/api-server/routes/authRoutes.ts index 23321dc..5a21422 100644 --- a/src/api-server/routes/authRoutes.ts +++ b/src/api-server/routes/authRoutes.ts @@ -1,9 +1,9 @@ -import express from "express"; -import { forgetPasswordController, signinController, signupController } from "../controller/authController"; - -const authRoutes = express.Router(); - -authRoutes.post("/signup", signupController); -authRoutes.post("/signIn", signinController); -authRoutes.post("/forget", forgetPasswordController); -export default authRoutes; +import express from "express"; +import { forgetPasswordController, signinController, signupController } from "../controller/authController"; + +const authRoutes = express.Router(); + +authRoutes.post("/signup", signupController); +authRoutes.post("/signIn", signinController); +authRoutes.post("/forget", forgetPasswordController); +export default authRoutes; diff --git a/src/api-server/routes/homeRoutes.ts b/src/api-server/routes/homeRoutes.ts index 5012e21..6724e4a 100644 --- a/src/api-server/routes/homeRoutes.ts +++ b/src/api-server/routes/homeRoutes.ts @@ -1,8 +1,8 @@ -import express from "express"; -import { homePageRecentlyViewedController } from "../controller/homePageController"; -import { tokenValidator } from "../../shared/utils/token"; -import authorizedRoles from "../../shared/middleware/rbacMiddleware"; -const homeRoutes = express.Router(); - -homeRoutes.get("/home",tokenValidator,authorizedRoles("Admin","Editor","Viewer"), homePageRecentlyViewedController); -export default homeRoutes; +import express from "express"; +import { homePageRecentlyViewedController } from "../controller/homePageController"; +import { tokenValidator } from "../../shared/utils/token"; +import authorizedRoles from "../../shared/middleware/rbacMiddleware"; +const homeRoutes = express.Router(); + +homeRoutes.get("/home",tokenValidator,authorizedRoles("Admin","Editor","Viewer"), homePageRecentlyViewedController); +export default homeRoutes; diff --git a/src/shared/connection/redis.ts b/src/shared/connection/redis.ts index 3998da0..ac2f2da 100644 --- a/src/shared/connection/redis.ts +++ b/src/shared/connection/redis.ts @@ -1,21 +1,21 @@ -import Redis from "ioredis"; -import * as dotenv from "dotenv"; -dotenv.config({}); -const redis = new Redis({ - host: - process.env.REDIS_ENV === "true" - ? process.env.REDIS_DOCKER - : process.env.REDIS_LOCAL, - port: parseInt(process.env.REDIS_PORT || "6379"), - password: "", - db: 0, -}); -redis.on("connect", () => { - console.log(`Connected to Redis to ${redis.options.port}`); -}); - -redis.on("error", (err: unknown) => { - console.error("Redis connection error:", err); -}); - -export default redis; +import Redis from "ioredis"; +import * as dotenv from "dotenv"; +dotenv.config({}); +const redis = new Redis({ + host: + process.env.REDIS_ENV === "true" + ? process.env.REDIS_DOCKER + : process.env.REDIS_LOCAL, + port: parseInt(process.env.REDIS_PORT || "6379"), + password: "", + db: 0, +}); +redis.on("connect", () => { + console.log(`Connected to Redis to ${redis.options.port}`); +}); + +redis.on("error", (err: unknown) => { + console.error("Redis connection error:", err); +}); + +export default redis; diff --git a/src/shared/middleware/rbacMiddleware.ts b/src/shared/middleware/rbacMiddleware.ts index bed5380..1a8776e 100644 --- a/src/shared/middleware/rbacMiddleware.ts +++ b/src/shared/middleware/rbacMiddleware.ts @@ -1,13 +1,13 @@ -import { Response, NextFunction } from "express"; -import { AuthenticatedRequest } from "../../shared/utils/token"; -type Role = "Admin" | "Viewer" | "Editor"; -const authorizedRoles = (...allowedRoles: Role[]) => { - return (req: AuthenticatedRequest, res: Response, next: NextFunction) => { - if (!req.user || !allowedRoles.includes(req.user.role as Role)) { - res.status(403).json({ message: "Access Denied" }); - return; - } - next(); - }; -}; -export default authorizedRoles; +import { Response, NextFunction } from "express"; +import { AuthenticatedRequest } from "../../shared/utils/token"; +type Role = "Admin" | "Viewer" | "Editor"; +const authorizedRoles = (...allowedRoles: Role[]) => { + return (req: AuthenticatedRequest, res: Response, next: NextFunction) => { + if (!req.user || !allowedRoles.includes(req.user.role as Role)) { + res.status(403).json({ message: "Access Denied" }); + return; + } + next(); + }; +}; +export default authorizedRoles; diff --git a/src/shared/model/shareModel.ts b/src/shared/model/shareModel.ts index 4e73beb..b2b6485 100644 --- a/src/shared/model/shareModel.ts +++ b/src/shared/model/shareModel.ts @@ -1,61 +1,61 @@ -import mongoose, { Document, Schema } from "mongoose"; -import MainModel from "../connection/connection"; -import { IProject } from "./projectmodel"; -import { User } from "./userModel"; - -export interface ISharedUser { - userId: User["_id"]; - accessLevel: "Viewer" | "Editor" | "Admin"; -} - -export interface IShare extends Document { - projectId: IProject["_id"]; - sharedBy: mongoose.Types.ObjectId; - sharedWith: ISharedUser[]; - description?: string; - isArchived: boolean; - createdAt: Date; - updatedAt: Date; -} - -const shareSchema = new Schema( - { - projectId: { - type: mongoose.Schema.Types.ObjectId, - ref: "Project", - }, - sharedBy: { - type: mongoose.Schema.Types.ObjectId, - ref: "User", - }, - sharedWith: [ - { - userId: { - type: mongoose.Schema.Types.ObjectId, - ref: "User", - }, - accessLevel: { - type: String, - enum: ["Viewer", "Editor", "Admin"], - default: "Viewer", - }, - }, - ], - description: { - type: String, - }, - isArchived: { - type: Boolean, - default: false, - }, - }, - { - timestamps: true, - } -); - -const shareModel = (db: any) => { - return MainModel(db, "Share", shareSchema, "Share"); -}; - -export default shareModel; +import mongoose, { Document, Schema } from "mongoose"; +import MainModel from "../connection/connection"; +import { IProject } from "./projectmodel"; +import { User } from "./userModel"; + +export interface ISharedUser { + userId: User["_id"]; + accessLevel: "Viewer" | "Editor" | "Admin"; +} + +export interface IShare extends Document { + projectId: IProject["_id"]; + sharedBy: mongoose.Types.ObjectId; + sharedWith: ISharedUser[]; + description?: string; + isArchived: boolean; + createdAt: Date; + updatedAt: Date; +} + +const shareSchema = new Schema( + { + projectId: { + type: mongoose.Schema.Types.ObjectId, + ref: "Project", + }, + sharedBy: { + type: mongoose.Schema.Types.ObjectId, + ref: "User", + }, + sharedWith: [ + { + userId: { + type: mongoose.Schema.Types.ObjectId, + ref: "User", + }, + accessLevel: { + type: String, + enum: ["Viewer", "Editor", "Admin"], + default: "Viewer", + }, + }, + ], + description: { + type: String, + }, + isArchived: { + type: Boolean, + default: false, + }, + }, + { + timestamps: true, + } +); + +const shareModel = (db: any) => { + return MainModel(db, "Share", shareSchema, "Share"); +}; + +export default shareModel; diff --git a/src/shared/model/tokenModel.ts b/src/shared/model/tokenModel.ts index ec801fb..224a0ba 100644 --- a/src/shared/model/tokenModel.ts +++ b/src/shared/model/tokenModel.ts @@ -1,22 +1,22 @@ -import { Schema, Document } from "mongoose"; -import MainModel from "../connection/connection"; -import { User } from "./userModel"; -export interface IUserToken extends Document { - userId: User["_id"]; - isArchive: boolean; - refreshToken: string; - resetTokenExpiry?: Date; - resetToken: string; -} -const tokenSchema: Schema = new Schema({ - userId: { type: Schema.Types.ObjectId, ref: "User" }, - isArchive: { type: Boolean, default: false }, - refreshToken: { type: String }, - resetToken: { type: String }, - resetTokenExpiry: { type: Date }, -}); - -const tokenModel = (db: any) => { - return MainModel(db, "Token", tokenSchema, "Token"); -}; -export default tokenModel; +import { Schema, Document } from "mongoose"; +import MainModel from "../connection/connection"; +import { User } from "./userModel"; +export interface IUserToken extends Document { + userId: User["_id"]; + isArchive: boolean; + refreshToken: string; + resetTokenExpiry?: Date; + resetToken: string; +} +const tokenSchema: Schema = new Schema({ + userId: { type: Schema.Types.ObjectId, ref: "User" }, + isArchive: { type: Boolean, default: false }, + refreshToken: { type: String }, + resetToken: { type: String }, + resetTokenExpiry: { type: Date }, +}); + +const tokenModel = (db: any) => { + return MainModel(db, "Token", tokenSchema, "Token"); +}; +export default tokenModel; diff --git a/src/shared/model/userDataModel.ts b/src/shared/model/userDataModel.ts index aafcb2e..0f70780 100644 --- a/src/shared/model/userDataModel.ts +++ b/src/shared/model/userDataModel.ts @@ -1,25 +1,25 @@ -import { Schema, Document } from "mongoose"; -import MainModel from "../connection/connection"; -import { User } from "./userModel"; -export interface IUserData extends Document { - userId: User["_id"]; - isArchive: boolean; - profilePicture: string; - recentlyViewed: string[]; -} -const userDataSchema: Schema = new Schema({ - userId: { type: Schema.Types.ObjectId, ref: "User" }, - isArchive: { type: Boolean, default: false }, - recentlyViewed: { - type: [String], - default: [], - }, - profilePicture: { - type: String, - }, -}); - -const userDataModel = (db: any) => { - return MainModel(db, "userData", userDataSchema, "userData"); -}; -export default userDataModel; +import { Schema, Document } from "mongoose"; +import MainModel from "../connection/connection"; +import { User } from "./userModel"; +export interface IUserData extends Document { + userId: User["_id"]; + isArchive: boolean; + profilePicture: string; + recentlyViewed: string[]; +} +const userDataSchema: Schema = new Schema({ + userId: { type: Schema.Types.ObjectId, ref: "User" }, + isArchive: { type: Boolean, default: false }, + recentlyViewed: { + type: [String], + default: [], + }, + profilePicture: { + type: String, + }, +}); + +const userDataModel = (db: any) => { + return MainModel(db, "userData", userDataSchema, "userData"); +}; +export default userDataModel; diff --git a/src/shared/model/userModel.ts b/src/shared/model/userModel.ts index 2fc5101..22a6e9d 100644 --- a/src/shared/model/userModel.ts +++ b/src/shared/model/userModel.ts @@ -1,36 +1,36 @@ -import { Schema, Document } from "mongoose"; -import MainModel from "../connection/connection"; -export interface User extends Document { - userName: string; - email: string; - password: string; - isArchive: boolean; - visitorBrowserId: string; - role: string; -} -const UserSchema: Schema = new Schema({ - userName: { - type: String, - required: true, - }, - role: { - type: String, - default: "Viewer", - enum: ["Editor", "Admin", "Viewer"], - }, - email: { - type: String, - required: true, - }, - password: { - type: String, - min: 8, - }, - isArchive: { type: Boolean, default: false }, - visitorBrowserId: { type: String }, -}); - -const userModel = (db: any) => { - return MainModel(db, "Users", UserSchema, "Users"); -}; -export default userModel; +import { Schema, Document } from "mongoose"; +import MainModel from "../connection/connection"; +export interface User extends Document { + userName: string; + email: string; + password: string; + isArchive: boolean; + visitorBrowserId: string; + role: string; +} +const UserSchema: Schema = new Schema({ + userName: { + type: String, + required: true, + }, + role: { + type: String, + default: "Viewer", + enum: ["Editor", "Admin", "Viewer"], + }, + email: { + type: String, + required: true, + }, + password: { + type: String, + min: 8, + }, + isArchive: { type: Boolean, default: false }, + visitorBrowserId: { type: String }, +}); + +const userModel = (db: any) => { + return MainModel(db, "Users", UserSchema, "Users"); +}; +export default userModel; diff --git a/src/shared/services/AuthService.ts b/src/shared/services/AuthService.ts index 7b4fa7d..3f202df 100644 --- a/src/shared/services/AuthService.ts +++ b/src/shared/services/AuthService.ts @@ -1,232 +1,232 @@ -import redis from "../connection/redis"; -import tokenModel from "../model/tokenModel"; -import nodemailer from "nodemailer"; -import userModel from "../model/userModel"; -import { hashGenerate, hashValidator } from "../utils/hashing"; -import { tokenGenerator, tokenRefreshGenerator } from "../utils/token"; -import userDataModel from "../model/userDataModel"; - -interface Iresponse { - status: string; - data?: any; -} -interface Isignup { - userName: string; - email: string; - password: string; - confirmPassword: string; -} -interface Isignin { - email: string; - password: string; -} -interface IforGotPassword { - email: string; -} - -export async function existingUserData(email: string, organization: string) { - const existingData = await userModel(organization).findOne({ - email: email, - isArchive: false, - }); - return existingData; -} -export const signupService = async (data: Isignup): Promise => { - const { userName, email, password, confirmPassword } = data; - try { - const mailCaseChange = email.toLocaleLowerCase(); - const organization = email.split("@")[1].split(".")[0]; - const mailExistance = await existingUserData(mailCaseChange, organization); - if (mailExistance !== null) return { status: "User Already exists" }; - if (password !== confirmPassword) { - return { status: "Passwords do not match" }; - } - let role; - const passwordHashed = await hashGenerate(password); - const userCount = await userModel(organization).countDocuments({}); - role = userCount === 0 ? "Admin" : "Viewer"; - const newUser = await userModel(organization).create({ - userName, - email: mailCaseChange, - password: passwordHashed, - role, - }); - if (!newUser) return { status: "Signup unsuccessfull" }; - return { status: "Success" }; - } catch (error: unknown) { - if (error instanceof Error) { - return { - status: error.message, - }; - } else { - return { - status: "An unexpected error occurred", - }; - } - } -}; - -export const signinService = async (data: Isignin): Promise => { - const { email, password } = data; - try { - const mailCaseChange = email.toLocaleLowerCase(); - const organization = email.split("@")[1].split(".")[0]; - const mailExistance = await existingUserData(mailCaseChange, organization); - if (mailExistance == null) - return { status: "User not found!!! Kindly Signup" }; - const comparePassword = await hashValidator( - password, - mailExistance.password - ); - if (!comparePassword) - return { status: "Password is invalid...Check the credentials" }; - const userDataExistence = await userDataModel(organization).findOne({ - userId: mailExistance._id, - isArchive: false, - }); - if (!userDataExistence) { - const userDatacreation = await userDataModel(organization).create({ - userId: mailExistance._id, - }); - } - const tokenValidation = tokenGenerator( - mailExistance.email, - mailExistance.role, - mailExistance._id, - organization - ); - const refreshTokenvalidation = tokenRefreshGenerator( - mailExistance.email, - mailExistance.role, - mailExistance._id, - organization - ); - const existingToken = await tokenModel(organization).findOne({ - userId: mailExistance._id, - isArchive: false, - }); - let finalResult; - if (!existingToken) { - const tokenSave = await tokenModel(organization).create({ - userId: mailExistance._id, - isArchive: false, - refreshToken: refreshTokenvalidation, - }); - // await redis.setex( - // `user:${mailExistance.Email}`, - // 3600, - // JSON.stringify(tokenSave) - // ); - finalResult = { - message: "login successfull", - email: mailExistance.email, - name: mailExistance.userName, - userId: mailExistance._id, - token: tokenValidation, - refreshToken: refreshTokenvalidation, - }; - } else { - finalResult = { - message: "login successfull", - email: mailExistance.email, - name: mailExistance.userName, - userId: mailExistance._id, - token: tokenValidation, - refreshToken: existingToken.refreshToken, - }; - } - return { status: "Success", data: finalResult }; - } catch (error: unknown) { - if (error instanceof Error) { - return { - status: error.message, - }; - } else { - return { - status: "An unexpected error occurred", - }; - } - } -}; - -export const forgetPassword = async ({ - email, -}: IforGotPassword): Promise<{ status: string }> => { - try { - const mailCaseChange = email.toLocaleLowerCase(); - const organization = email.split("@")[1].split(".")[0]; - const Existing_User = await existingUserData(mailCaseChange, organization); - if (Existing_User) { - // if (Existing_User.lastPasswordReset) { - // console.log("if2"); - // const lastPasswordReset = Existing_User.lastPasswordReset; - // const now = Date.now(); - // const timeDiff = now - lastPasswordReset; - // const diffInHours = Math.floor(timeDiff / (1000 * 60 * 60)); - // if (diffInHours < 24) - // return { - // status: "You can only reset your password once every 24 hours.", - // }; - // } - const transport = nodemailer.createTransport({ - service: "gmail", - secure: true, - auth: { - user: process.env.EMAIL_USER, - pass: process.env.EMAIL_PASS, - }, - }); - // const resetToken = tokenGenerator( - // email, - // Existing_User.Role as string, - // Existing_User._id as string, - // organization - // ); - // const userTokenData = await tokenModel(organization).findOne({ - // userId: Existing_User._id, - // isArchive: false, - // }); - // if (!userTokenData) { - // await tokenModel(organization).create({ - // // Email: Existing_User.Email, - // userId: Existing_User._id, - // resetToken: resetToken, - // resetTokenExpiry: Date.now(), - // }); - // } else { - // userTokenData.resetToken = resetToken; - // userTokenData.resetTokenExpiry = new Date(); - // await userTokenData.save(); - // } - const Receiver = { - from: process.env.EMAIL_USER, - to: email, - subject: "Password Reset Request", - // text: "test mail", - text: `Click the below link to generate the new password \n ${ - process.env.CLIENT_URL - }/reset-password/${tokenGenerator( - email, - Existing_User.Role as string, - Existing_User._id as string, - organization - )}`, - }; - await transport.sendMail(Receiver); - - return { status: "Success" }; - } else { - return { status: "Email not found" }; - } - } catch (error: unknown) { - if (error instanceof Error) { - return { - status: error.message, - }; - } else { - return { - status: "An unexpected error occurred", - }; - } - } -}; +import redis from "../connection/redis"; +import tokenModel from "../model/tokenModel"; +import nodemailer from "nodemailer"; +import userModel from "../model/userModel"; +import { hashGenerate, hashValidator } from "../utils/hashing"; +import { tokenGenerator, tokenRefreshGenerator } from "../utils/token"; +import userDataModel from "../model/userDataModel"; + +interface Iresponse { + status: string; + data?: any; +} +interface Isignup { + userName: string; + email: string; + password: string; + confirmPassword: string; +} +interface Isignin { + email: string; + password: string; +} +interface IforGotPassword { + email: string; +} + +export async function existingUserData(email: string, organization: string) { + const existingData = await userModel(organization).findOne({ + email: email, + isArchive: false, + }); + return existingData; +} +export const signupService = async (data: Isignup): Promise => { + const { userName, email, password, confirmPassword } = data; + try { + const mailCaseChange = email.toLocaleLowerCase(); + const organization = email.split("@")[1].split(".")[0]; + const mailExistance = await existingUserData(mailCaseChange, organization); + if (mailExistance !== null) return { status: "User Already exists" }; + if (password !== confirmPassword) { + return { status: "Passwords do not match" }; + } + let role; + const passwordHashed = await hashGenerate(password); + const userCount = await userModel(organization).countDocuments({}); + role = userCount === 0 ? "Admin" : "Viewer"; + const newUser = await userModel(organization).create({ + userName, + email: mailCaseChange, + password: passwordHashed, + role, + }); + if (!newUser) return { status: "Signup unsuccessfull" }; + return { status: "Success" }; + } catch (error: unknown) { + if (error instanceof Error) { + return { + status: error.message, + }; + } else { + return { + status: "An unexpected error occurred", + }; + } + } +}; + +export const signinService = async (data: Isignin): Promise => { + const { email, password } = data; + try { + const mailCaseChange = email.toLocaleLowerCase(); + const organization = email.split("@")[1].split(".")[0]; + const mailExistance = await existingUserData(mailCaseChange, organization); + if (mailExistance == null) + return { status: "User not found!!! Kindly Signup" }; + const comparePassword = await hashValidator( + password, + mailExistance.password + ); + if (!comparePassword) + return { status: "Password is invalid...Check the credentials" }; + const userDataExistence = await userDataModel(organization).findOne({ + userId: mailExistance._id, + isArchive: false, + }); + if (!userDataExistence) { + const userDatacreation = await userDataModel(organization).create({ + userId: mailExistance._id, + }); + } + const tokenValidation = tokenGenerator( + mailExistance.email, + mailExistance.role, + mailExistance._id, + organization + ); + const refreshTokenvalidation = tokenRefreshGenerator( + mailExistance.email, + mailExistance.role, + mailExistance._id, + organization + ); + const existingToken = await tokenModel(organization).findOne({ + userId: mailExistance._id, + isArchive: false, + }); + let finalResult; + if (!existingToken) { + const tokenSave = await tokenModel(organization).create({ + userId: mailExistance._id, + isArchive: false, + refreshToken: refreshTokenvalidation, + }); + // await redis.setex( + // `user:${mailExistance.Email}`, + // 3600, + // JSON.stringify(tokenSave) + // ); + finalResult = { + message: "login successfull", + email: mailExistance.email, + name: mailExistance.userName, + userId: mailExistance._id, + token: tokenValidation, + refreshToken: refreshTokenvalidation, + }; + } else { + finalResult = { + message: "login successfull", + email: mailExistance.email, + name: mailExistance.userName, + userId: mailExistance._id, + token: tokenValidation, + refreshToken: existingToken.refreshToken, + }; + } + return { status: "Success", data: finalResult }; + } catch (error: unknown) { + if (error instanceof Error) { + return { + status: error.message, + }; + } else { + return { + status: "An unexpected error occurred", + }; + } + } +}; + +export const forgetPassword = async ({ + email, +}: IforGotPassword): Promise<{ status: string }> => { + try { + const mailCaseChange = email.toLocaleLowerCase(); + const organization = email.split("@")[1].split(".")[0]; + const Existing_User = await existingUserData(mailCaseChange, organization); + if (Existing_User) { + // if (Existing_User.lastPasswordReset) { + // console.log("if2"); + // const lastPasswordReset = Existing_User.lastPasswordReset; + // const now = Date.now(); + // const timeDiff = now - lastPasswordReset; + // const diffInHours = Math.floor(timeDiff / (1000 * 60 * 60)); + // if (diffInHours < 24) + // return { + // status: "You can only reset your password once every 24 hours.", + // }; + // } + const transport = nodemailer.createTransport({ + service: "gmail", + secure: true, + auth: { + user: process.env.EMAIL_USER, + pass: process.env.EMAIL_PASS, + }, + }); + // const resetToken = tokenGenerator( + // email, + // Existing_User.Role as string, + // Existing_User._id as string, + // organization + // ); + // const userTokenData = await tokenModel(organization).findOne({ + // userId: Existing_User._id, + // isArchive: false, + // }); + // if (!userTokenData) { + // await tokenModel(organization).create({ + // // Email: Existing_User.Email, + // userId: Existing_User._id, + // resetToken: resetToken, + // resetTokenExpiry: Date.now(), + // }); + // } else { + // userTokenData.resetToken = resetToken; + // userTokenData.resetTokenExpiry = new Date(); + // await userTokenData.save(); + // } + const Receiver = { + from: process.env.EMAIL_USER, + to: email, + subject: "Password Reset Request", + // text: "test mail", + text: `Click the below link to generate the new password \n ${ + process.env.CLIENT_URL + }/reset-password/${tokenGenerator( + email, + Existing_User.Role as string, + Existing_User._id as string, + organization + )}`, + }; + await transport.sendMail(Receiver); + + return { status: "Success" }; + } else { + return { status: "Email not found" }; + } + } catch (error: unknown) { + if (error instanceof Error) { + return { + status: error.message, + }; + } else { + return { + status: "An unexpected error occurred", + }; + } + } +}; diff --git a/src/shared/services/homePageService.ts b/src/shared/services/homePageService.ts index 4a6332a..1c7b4d7 100644 --- a/src/shared/services/homePageService.ts +++ b/src/shared/services/homePageService.ts @@ -1,51 +1,51 @@ -import ProjectType from "../../shared/model/projectmodel"; -import userDataModel from "../model/userDataModel"; -import userModel from "../model/userModel"; - -interface IrecentlyViewed { - organization: string; - userId: string; -} -interface Iresponse { - status: string; - data?: any; -} -export const recentlyViewedServices = async ( - data: IrecentlyViewed -): Promise => { - const { organization, userId } = data; - try { - const ExistingUser = await userModel(organization).findOne({ - _id: userId, - isArchive: false, - }); - if (!ExistingUser) return { status: "User not found" }; - const userDatas = await userDataModel(organization) - .findOne({ userId: userId, isArchive: false }) - .select("recentlyViewed userId"); - const populatedProjects = userDatas.recentlyViewed; - const RecentDatas = await Promise.all( - populatedProjects.map(async (projectId: any) => { - const projectExisting = await ProjectType(organization) - .findOne({ - _id: projectId, - isArchive: false, - }) - .select("_id projectName createdBy thumbnail createdAt isViewed"); - return projectExisting; - }) - ); - const filteredProjects = RecentDatas.filter(Boolean); - return { status: "Success", data: filteredProjects }; - } catch (error: unknown) { - if (error instanceof Error) { - return { - status: error.message, - }; - } else { - return { - status: "An unexpected error occurred", - }; - } - } -}; +import ProjectType from "../../shared/model/projectmodel"; +import userDataModel from "../model/userDataModel"; +import userModel from "../model/userModel"; + +interface IrecentlyViewed { + organization: string; + userId: string; +} +interface Iresponse { + status: string; + data?: any; +} +export const recentlyViewedServices = async ( + data: IrecentlyViewed +): Promise => { + const { organization, userId } = data; + try { + const ExistingUser = await userModel(organization).findOne({ + _id: userId, + isArchive: false, + }); + if (!ExistingUser) return { status: "User not found" }; + const userDatas = await userDataModel(organization) + .findOne({ userId: userId, isArchive: false }) + .select("recentlyViewed userId"); + const populatedProjects = userDatas.recentlyViewed; + const RecentDatas = await Promise.all( + populatedProjects.map(async (projectId: any) => { + const projectExisting = await ProjectType(organization) + .findOne({ + _id: projectId, + isArchive: false, + }) + .select("_id projectName createdBy thumbnail createdAt isViewed"); + return projectExisting; + }) + ); + const filteredProjects = RecentDatas.filter(Boolean); + return { status: "Success", data: filteredProjects }; + } catch (error: unknown) { + if (error instanceof Error) { + return { + status: error.message, + }; + } else { + return { + status: "An unexpected error occurred", + }; + } + } +}; diff --git a/src/shared/utils/hashing.ts b/src/shared/utils/hashing.ts index b36740e..6f62019 100644 --- a/src/shared/utils/hashing.ts +++ b/src/shared/utils/hashing.ts @@ -1,24 +1,24 @@ -import bcrypt from "bcryptjs"; - -const saltRounds = 10; -export const hashGenerate = async (Password: string) => { - try { - const salt = await bcrypt.genSalt(saltRounds); - const hash = await bcrypt.hash(Password, salt); - - return hash; - } catch (error) { - return error; - } -}; -export const hashValidator = async ( - password: string, - hashedPassword: string -) => { - try { - const result = await bcrypt.compare(password, hashedPassword); - return result; - } catch (error) { - return false; - } -}; +import bcrypt from "bcryptjs"; + +const saltRounds = 10; +export const hashGenerate = async (Password: string) => { + try { + const salt = await bcrypt.genSalt(saltRounds); + const hash = await bcrypt.hash(Password, salt); + + return hash; + } catch (error) { + return error; + } +}; +export const hashValidator = async ( + password: string, + hashedPassword: string +) => { + try { + const result = await bcrypt.compare(password, hashedPassword); + return result; + } catch (error) { + return false; + } +}; diff --git a/src/shared/utils/token.ts b/src/shared/utils/token.ts index caf376d..9a40a75 100644 --- a/src/shared/utils/token.ts +++ b/src/shared/utils/token.ts @@ -1,139 +1,139 @@ -import { Request, Response, NextFunction } from "express"; -import Jwt from "jsonwebtoken"; -import dotenv from "dotenv"; -import userModel from "../model/userModel"; -dotenv.config(); - -export interface AuthenticatedRequest extends Request { - user?: { - email: string; - role: string; - userId: string; - organization: string; - }; -} -const jwt_secret = process.env.JWT_SECRET as string; -const refresh_jwt_secret = process.env.REFRESH_JWT_SECRET as string; -const tokenGenerator = ( - email: string, - role: string, - userId: string, - organization: string -) => { - const token = Jwt.sign( - { email: email, role: role, userId: userId, organization: organization }, - jwt_secret, - { - expiresIn: "3h", - } - ); - return token; -}; -const tokenRefreshGenerator = ( - email: string, - role: string, - userId: string, - organization: string -) => { - const token = Jwt.sign( - { email: email, role: role, userId: userId, organization: organization }, - refresh_jwt_secret, - { - expiresIn: "7d", - } - ); - return token; -}; -const tokenValidator = async ( - req: AuthenticatedRequest, - res: Response, - next: NextFunction -): Promise => { - const token: string | undefined = req.headers.token as string | undefined; - const refresh_token = req.headers["refresh_token"] as string | undefined; - if (!token) { - res.status(403).json({ - msg: "No token present", - }); - return; - } - - try { - const decoded = Jwt.verify(token, jwt_secret) as { - email: string; - role: string; - userId: string; - organization: string; - }; - if (!decoded) { - res.status(403).json({ - success: false, - status: 403, - message: "Invalid Token", - }); - return; - } - req.user = decoded; - next(); - } catch (err) { - if (!refresh_token) { - res.status(403).json({ - success: false, - status: 403, - message: "No refresh token present", - }); - return; - } - try { - const decodedRefresh = Jwt.verify(refresh_token, refresh_jwt_secret) as { - email: string; - role: string; - userId: string; - organization: string; - }; - if (!decodedRefresh) { - res.status(403).json({ - success: false, - status: 403, - message: "Invalid Token", - }); - return; - } - const newAccessToken = tokenGenerator( - decodedRefresh.email, - decodedRefresh.role, - decodedRefresh.userId, - decodedRefresh.organization - ); - res.setHeader("x-access-token", newAccessToken); - req.user = decodedRefresh; - return next(); - } catch (err) { - const decodedAny = Jwt.decode(token || refresh_token) as { - email?: string; - role: string; - userId: string; - organization: string; - }; - if (decodedAny?.email) { - const organization = decodedAny?.email.split("@")[1].split(".")[0]; - const user = await userModel(organization).findOne({ - email: decodedAny.email, - isArchieve: false, - }); - if (user) { - user.visitorBrowserID = ""; - await user.save(); - } - } - res.status(403).json({ - success: false, - status: 403, - message: "Invalid Token", - }); - return; - } - } -}; - -export { tokenValidator, tokenGenerator, tokenRefreshGenerator }; +import { Request, Response, NextFunction } from "express"; +import Jwt from "jsonwebtoken"; +import dotenv from "dotenv"; +import userModel from "../model/userModel"; +dotenv.config(); + +export interface AuthenticatedRequest extends Request { + user?: { + email: string; + role: string; + userId: string; + organization: string; + }; +} +const jwt_secret = process.env.JWT_SECRET as string; +const refresh_jwt_secret = process.env.REFRESH_JWT_SECRET as string; +const tokenGenerator = ( + email: string, + role: string, + userId: string, + organization: string +) => { + const token = Jwt.sign( + { email: email, role: role, userId: userId, organization: organization }, + jwt_secret, + { + expiresIn: "3h", + } + ); + return token; +}; +const tokenRefreshGenerator = ( + email: string, + role: string, + userId: string, + organization: string +) => { + const token = Jwt.sign( + { email: email, role: role, userId: userId, organization: organization }, + refresh_jwt_secret, + { + expiresIn: "7d", + } + ); + return token; +}; +const tokenValidator = async ( + req: AuthenticatedRequest, + res: Response, + next: NextFunction +): Promise => { + const token: string | undefined = req.headers.token as string | undefined; + const refresh_token = req.headers["refresh_token"] as string | undefined; + if (!token) { + res.status(403).json({ + msg: "No token present", + }); + return; + } + + try { + const decoded = Jwt.verify(token, jwt_secret) as { + email: string; + role: string; + userId: string; + organization: string; + }; + if (!decoded) { + res.status(403).json({ + success: false, + status: 403, + message: "Invalid Token", + }); + return; + } + req.user = decoded; + next(); + } catch (err) { + if (!refresh_token) { + res.status(403).json({ + success: false, + status: 403, + message: "No refresh token present", + }); + return; + } + try { + const decodedRefresh = Jwt.verify(refresh_token, refresh_jwt_secret) as { + email: string; + role: string; + userId: string; + organization: string; + }; + if (!decodedRefresh) { + res.status(403).json({ + success: false, + status: 403, + message: "Invalid Token", + }); + return; + } + const newAccessToken = tokenGenerator( + decodedRefresh.email, + decodedRefresh.role, + decodedRefresh.userId, + decodedRefresh.organization + ); + res.setHeader("x-access-token", newAccessToken); + req.user = decodedRefresh; + return next(); + } catch (err) { + const decodedAny = Jwt.decode(token || refresh_token) as { + email?: string; + role: string; + userId: string; + organization: string; + }; + if (decodedAny?.email) { + const organization = decodedAny?.email.split("@")[1].split(".")[0]; + const user = await userModel(organization).findOne({ + email: decodedAny.email, + isArchieve: false, + }); + if (user) { + user.visitorBrowserID = ""; + await user.save(); + } + } + res.status(403).json({ + success: false, + status: 403, + message: "Invalid Token", + }); + return; + } + } +}; + +export { tokenValidator, tokenGenerator, tokenRefreshGenerator }; diff --git a/src/socket-server/controllers/collectionNodeController.ts b/src/socket-server/controllers/collectionNodeController.ts index dd96b3d..3346149 100644 --- a/src/socket-server/controllers/collectionNodeController.ts +++ b/src/socket-server/controllers/collectionNodeController.ts @@ -1,450 +1,450 @@ -import { Socket, Server } from "socket.io"; -import { EVENTS } from "../events/events"; -import { ErrorResponse, FinalResponse, validateFields } from "../utils/socketfunctionHelpers"; -import { emitToSenderAndAdmins } from "../utils/emitEventResponse"; -import { deleteEdge, edgecreation } from "../../shared/services/edgeService"; -import { addAttributes, DelAttributes, delCollection, DuplicateCollection, Nodecreation, SetCollectionName, UpdateAttributes } from "../../shared/services/collectionService"; - - - -export const CollectionHandleEvent = async ( - event: string, - socket: Socket, - io: Server, - data: any, - connectedUsersByOrg: { - [org: string]: { socketId: string; userId: string; role: string }[]; - } -) => { - if (event !== EVENTS.collectionCreate || !data?.organization) return; - const requiredFields = [ - "position", - "projectId", - "organization", - ]; - const missingFields = validateFields(data, requiredFields); - - if (missingFields.length > 0) { - emitToSenderAndAdmins( - io, - socket, - data.organization, - EVENTS.collectionCreateResponse, - ErrorResponse(missingFields, socket, data.organization), - connectedUsersByOrg - ); - return; - } - const result = await Nodecreation(data); - console.log('result: ', result); - const status = typeof result?.status === "string" ? result.status : "unknown"; - - const messages: Record = { - Success: { message: "Node created successfully" }, - "Collection node creation unsuccessfull": { message: "Collection node creation unsuccessfull" }, - "Project not found": { message: "Project not found" }, - }; - - 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 response = FinalResponse( - status, - socket, - data.organization, - messages, - result_Datas - ); - console.log('response: ', response); - - emitToSenderAndAdmins( - io, - socket, - data.organization, - EVENTS.collectionCreateResponse, - response, - connectedUsersByOrg - ); -}; -export const CollectioNamenHandleEvent = async ( - event: string, - socket: Socket, - io: Server, - data: any, - connectedUsersByOrg: { - [org: string]: { socketId: string; userId: string; role: string }[]; - } -) => { - if (event !== EVENTS.collectionNameSet || !data?.organization) return; - const requiredFields = [ - "collectionName", - "collectionNodeId", - "projectId", - "organization", - ]; - const missingFields = validateFields(data, requiredFields); - - if (missingFields.length > 0) { - emitToSenderAndAdmins( - io, - socket, - data.organization, - EVENTS.collectionNameSetResponse, - ErrorResponse(missingFields, socket, data.organization), - connectedUsersByOrg - ); - return; - } - const result = await SetCollectionName(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" }, - "Project not found": { message: "Project not found" }, - - }; - - 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 response = FinalResponse( - status, - socket, - data.organization, - messages, - result_Datas - ); - console.log('response: ', response); - - emitToSenderAndAdmins( - io, - socket, - data.organization, - EVENTS.collectionNameSetResponse, - response, - connectedUsersByOrg - ); -}; -export const CollectioDeleteHandleEvent = async ( - event: string, - socket: Socket, - io: Server, - data: any, - connectedUsersByOrg: { - [org: string]: { socketId: string; userId: string; role: string }[]; - } -) => { - if (event !== EVENTS.collectionDelete || !data?.organization) return; - const requiredFields = [ - "collectionNodeId", - "projectId", - "organization", - ]; - const missingFields = validateFields(data, requiredFields); - - if (missingFields.length > 0) { - emitToSenderAndAdmins( - io, - socket, - data.organization, - EVENTS.collectionDeleteResponse, - ErrorResponse(missingFields, socket, data.organization), - connectedUsersByOrg - ); - return; - } - const result = await delCollection(data); - console.log('result: ', result); - const status = typeof result?.status === "string" ? result.status : "unknown"; - - const messages: Record = { - Success: { message: "Collection deleted successfully" }, - "Project not found": { message: "Project not found" }, - "Collection not found": { message: "Collection not found" }, - - }; - - 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 response = FinalResponse( - status, - socket, - data.organization, - messages, - result_Datas - ); - console.log('response: ', response); - - emitToSenderAndAdmins( - io, - socket, - data.organization, - EVENTS.collectionDeleteResponse, - response, - connectedUsersByOrg - ); -}; -export const CollectioDuplicateHandleEvent = async ( - event: string, - socket: Socket, - io: Server, - data: any, - connectedUsersByOrg: { - [org: string]: { socketId: string; userId: string; role: string }[]; - } -) => { - if (event !== EVENTS.collectionDuplicate || !data?.organization) return; - const requiredFields = [ - "collectionNodeId", - "projectId", - "organization", - ]; - const missingFields = validateFields(data, requiredFields); - - if (missingFields.length > 0) { - emitToSenderAndAdmins( - io, - socket, - data.organization, - EVENTS.collectionDeleteResponse, - ErrorResponse(missingFields, socket, data.organization), - connectedUsersByOrg - ); - return; - } - const result = await DuplicateCollection(data); - console.log('result: ', result); - const status = typeof result?.status === "string" ? result.status : "unknown"; - - const messages: Record = { - Success: { message: "Collection deleted successfully" }, - "Project not found": { message: "Project not found" }, - "Collection not found": { message: "Collection not found" }, - "Duplication unsuccessfull": { message: "Duplication unsuccessfull" }, - - }; - - 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 response = FinalResponse( - status, - socket, - data.organization, - messages, - result_Datas - ); - console.log('response: ', response); - - emitToSenderAndAdmins( - io, - socket, - data.organization, - EVENTS.collectionDuplicateResponse, - response, - connectedUsersByOrg - ); -}; -export const setAttributesHandleEvent = async ( - event: string, - socket: Socket, - io: Server, - data: any, - connectedUsersByOrg: { - [org: string]: { socketId: string; userId: string; role: string }[]; - } -) => { - if (event !== EVENTS.collectionAttributeSet || !data?.organization) return; - const requiredFields = [ - "attributes", - "collectionNodeId", - "projectId", - "organization", - ]; - const missingFields = validateFields(data, requiredFields); - - if (missingFields.length > 0) { - emitToSenderAndAdmins( - io, - socket, - data.organization, - EVENTS.collectionAttributeSetResponse, - ErrorResponse(missingFields, socket, data.organization), - connectedUsersByOrg - ); - return; - } - const result = await addAttributes(data); - console.log('result: ', result); - const status = typeof result?.status === "string" ? result.status : "unknown"; - - const messages: Record = { - Success: { message: "Collection Attributes Added" }, - "Project not found": { message: "Project not found" }, - "Collection not found": { message: "Collection not found" }, - - - }; - - 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 response = FinalResponse( - status, - socket, - data.organization, - messages, - result_Datas - ); - console.log('response: ', response); - - emitToSenderAndAdmins( - io, - socket, - data.organization, - EVENTS.collectionAttributeSetResponse, - response, - connectedUsersByOrg - ); -}; -export const AttributesDeleteHandleEvent = async ( - event: string, - socket: Socket, - io: Server, - data: any, - connectedUsersByOrg: { - [org: string]: { socketId: string; userId: string; role: string }[]; - } -) => { - if (event !== EVENTS.collectionAttributeDelete || !data?.organization) return; - const requiredFields = [ - "attributeId", - "collectionNodeId", - "projectId", - "organization", - ]; - const missingFields = validateFields(data, requiredFields); - - if (missingFields.length > 0) { - emitToSenderAndAdmins( - io, - socket, - data.organization, - EVENTS.collectionAttributeDeleteResponse, - ErrorResponse(missingFields, socket, data.organization), - connectedUsersByOrg - ); - return; - } - const result = await DelAttributes(data); - console.log('result: ', result); - const status = typeof result?.status === "string" ? result.status : "unknown"; - - const messages: Record = { - Success: { message: "Field deleted successfully" }, - "Project not found": { message: "Project not found" }, - "Collection not found": { message: "Collection not found" }, - - - }; - - 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 response = FinalResponse( - status, - socket, - data.organization, - messages, - result_Datas - ); - console.log('response: ', response); - - emitToSenderAndAdmins( - io, - socket, - data.organization, - EVENTS.collectionAttributeDeleteResponse, - response, - connectedUsersByOrg - ); -}; -export const AttributesUpdateHandleEvent = async ( - event: string, - socket: Socket, - io: Server, - data: any, - connectedUsersByOrg: { - [org: string]: { socketId: string; userId: string; role: string }[]; - } -) => { - if (event !== EVENTS.collectionAttributeUpdate || !data?.organization) return; - const requiredFields = [ - "attributeId", - "collectionNodeId", - "projectId", - "organization", - ]; - const missingFields = validateFields(data, requiredFields); - - if (missingFields.length > 0) { - emitToSenderAndAdmins( - io, - socket, - data.organization, - EVENTS.collectionAttributeUpdateResponse, - ErrorResponse(missingFields, socket, data.organization), - connectedUsersByOrg - ); - return; - } - const result = await UpdateAttributes(data); - console.log('result: ', result); - const status = typeof result?.status === "string" ? result.status : "unknown"; - - const messages: Record = { - Success: { message: "Field updated successfully" }, - "Project not found": { message: "Project not found" }, - "Collection not found": { message: "Collection not found" }, - - - }; - - 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 response = FinalResponse( - status, - socket, - data.organization, - messages, - result_Datas - ); - console.log('response: ', response); - - emitToSenderAndAdmins( - io, - socket, - data.organization, - EVENTS.collectionAttributeUpdateResponse, - response, - connectedUsersByOrg - ); +import { Socket, Server } from "socket.io"; +import { EVENTS } from "../events/events"; +import { ErrorResponse, FinalResponse, validateFields } from "../utils/socketfunctionHelpers"; +import { emitToSenderAndAdmins } from "../utils/emitEventResponse"; +import { deleteEdge, edgecreation } from "../../shared/services/edgeService"; +import { addAttributes, DelAttributes, delCollection, DuplicateCollection, Nodecreation, SetCollectionName, UpdateAttributes } from "../../shared/services/collectionService"; + + + +export const CollectionHandleEvent = async ( + event: string, + socket: Socket, + io: Server, + data: any, + connectedUsersByOrg: { + [org: string]: { socketId: string; userId: string; role: string }[]; + } +) => { + if (event !== EVENTS.collectionCreate || !data?.organization) return; + const requiredFields = [ + "position", + "projectId", + "organization", + ]; + const missingFields = validateFields(data, requiredFields); + + if (missingFields.length > 0) { + emitToSenderAndAdmins( + io, + socket, + data.organization, + EVENTS.collectionCreateResponse, + ErrorResponse(missingFields, socket, data.organization), + connectedUsersByOrg + ); + return; + } + const result = await Nodecreation(data); + console.log('result: ', result); + const status = typeof result?.status === "string" ? result.status : "unknown"; + + const messages: Record = { + Success: { message: "Node created successfully" }, + "Collection node creation unsuccessfull": { message: "Collection node creation unsuccessfull" }, + "Project not found": { message: "Project not found" }, + }; + + 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 response = FinalResponse( + status, + socket, + data.organization, + messages, + result_Datas + ); + console.log('response: ', response); + + emitToSenderAndAdmins( + io, + socket, + data.organization, + EVENTS.collectionCreateResponse, + response, + connectedUsersByOrg + ); +}; +export const CollectioNamenHandleEvent = async ( + event: string, + socket: Socket, + io: Server, + data: any, + connectedUsersByOrg: { + [org: string]: { socketId: string; userId: string; role: string }[]; + } +) => { + if (event !== EVENTS.collectionNameSet || !data?.organization) return; + const requiredFields = [ + "collectionName", + "collectionNodeId", + "projectId", + "organization", + ]; + const missingFields = validateFields(data, requiredFields); + + if (missingFields.length > 0) { + emitToSenderAndAdmins( + io, + socket, + data.organization, + EVENTS.collectionNameSetResponse, + ErrorResponse(missingFields, socket, data.organization), + connectedUsersByOrg + ); + return; + } + const result = await SetCollectionName(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" }, + "Project not found": { message: "Project not found" }, + + }; + + 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 response = FinalResponse( + status, + socket, + data.organization, + messages, + result_Datas + ); + console.log('response: ', response); + + emitToSenderAndAdmins( + io, + socket, + data.organization, + EVENTS.collectionNameSetResponse, + response, + connectedUsersByOrg + ); +}; +export const CollectioDeleteHandleEvent = async ( + event: string, + socket: Socket, + io: Server, + data: any, + connectedUsersByOrg: { + [org: string]: { socketId: string; userId: string; role: string }[]; + } +) => { + if (event !== EVENTS.collectionDelete || !data?.organization) return; + const requiredFields = [ + "collectionNodeId", + "projectId", + "organization", + ]; + const missingFields = validateFields(data, requiredFields); + + if (missingFields.length > 0) { + emitToSenderAndAdmins( + io, + socket, + data.organization, + EVENTS.collectionDeleteResponse, + ErrorResponse(missingFields, socket, data.organization), + connectedUsersByOrg + ); + return; + } + const result = await delCollection(data); + console.log('result: ', result); + const status = typeof result?.status === "string" ? result.status : "unknown"; + + const messages: Record = { + Success: { message: "Collection deleted successfully" }, + "Project not found": { message: "Project not found" }, + "Collection not found": { message: "Collection not found" }, + + }; + + 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 response = FinalResponse( + status, + socket, + data.organization, + messages, + result_Datas + ); + console.log('response: ', response); + + emitToSenderAndAdmins( + io, + socket, + data.organization, + EVENTS.collectionDeleteResponse, + response, + connectedUsersByOrg + ); +}; +export const CollectioDuplicateHandleEvent = async ( + event: string, + socket: Socket, + io: Server, + data: any, + connectedUsersByOrg: { + [org: string]: { socketId: string; userId: string; role: string }[]; + } +) => { + if (event !== EVENTS.collectionDuplicate || !data?.organization) return; + const requiredFields = [ + "collectionNodeId", + "projectId", + "organization", + ]; + const missingFields = validateFields(data, requiredFields); + + if (missingFields.length > 0) { + emitToSenderAndAdmins( + io, + socket, + data.organization, + EVENTS.collectionDeleteResponse, + ErrorResponse(missingFields, socket, data.organization), + connectedUsersByOrg + ); + return; + } + const result = await DuplicateCollection(data); + console.log('result: ', result); + const status = typeof result?.status === "string" ? result.status : "unknown"; + + const messages: Record = { + Success: { message: "Collection deleted successfully" }, + "Project not found": { message: "Project not found" }, + "Collection not found": { message: "Collection not found" }, + "Duplication unsuccessfull": { message: "Duplication unsuccessfull" }, + + }; + + 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 response = FinalResponse( + status, + socket, + data.organization, + messages, + result_Datas + ); + console.log('response: ', response); + + emitToSenderAndAdmins( + io, + socket, + data.organization, + EVENTS.collectionDuplicateResponse, + response, + connectedUsersByOrg + ); +}; +export const setAttributesHandleEvent = async ( + event: string, + socket: Socket, + io: Server, + data: any, + connectedUsersByOrg: { + [org: string]: { socketId: string; userId: string; role: string }[]; + } +) => { + if (event !== EVENTS.collectionAttributeSet || !data?.organization) return; + const requiredFields = [ + "attributes", + "collectionNodeId", + "projectId", + "organization", + ]; + const missingFields = validateFields(data, requiredFields); + + if (missingFields.length > 0) { + emitToSenderAndAdmins( + io, + socket, + data.organization, + EVENTS.collectionAttributeSetResponse, + ErrorResponse(missingFields, socket, data.organization), + connectedUsersByOrg + ); + return; + } + const result = await addAttributes(data); + console.log('result: ', result); + const status = typeof result?.status === "string" ? result.status : "unknown"; + + const messages: Record = { + Success: { message: "Collection Attributes Added" }, + "Project not found": { message: "Project not found" }, + "Collection not found": { message: "Collection not found" }, + + + }; + + 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 response = FinalResponse( + status, + socket, + data.organization, + messages, + result_Datas + ); + console.log('response: ', response); + + emitToSenderAndAdmins( + io, + socket, + data.organization, + EVENTS.collectionAttributeSetResponse, + response, + connectedUsersByOrg + ); +}; +export const AttributesDeleteHandleEvent = async ( + event: string, + socket: Socket, + io: Server, + data: any, + connectedUsersByOrg: { + [org: string]: { socketId: string; userId: string; role: string }[]; + } +) => { + if (event !== EVENTS.collectionAttributeDelete || !data?.organization) return; + const requiredFields = [ + "attributeId", + "collectionNodeId", + "projectId", + "organization", + ]; + const missingFields = validateFields(data, requiredFields); + + if (missingFields.length > 0) { + emitToSenderAndAdmins( + io, + socket, + data.organization, + EVENTS.collectionAttributeDeleteResponse, + ErrorResponse(missingFields, socket, data.organization), + connectedUsersByOrg + ); + return; + } + const result = await DelAttributes(data); + console.log('result: ', result); + const status = typeof result?.status === "string" ? result.status : "unknown"; + + const messages: Record = { + Success: { message: "Field deleted successfully" }, + "Project not found": { message: "Project not found" }, + "Collection not found": { message: "Collection not found" }, + + + }; + + 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 response = FinalResponse( + status, + socket, + data.organization, + messages, + result_Datas + ); + console.log('response: ', response); + + emitToSenderAndAdmins( + io, + socket, + data.organization, + EVENTS.collectionAttributeDeleteResponse, + response, + connectedUsersByOrg + ); +}; +export const AttributesUpdateHandleEvent = async ( + event: string, + socket: Socket, + io: Server, + data: any, + connectedUsersByOrg: { + [org: string]: { socketId: string; userId: string; role: string }[]; + } +) => { + if (event !== EVENTS.collectionAttributeUpdate || !data?.organization) return; + const requiredFields = [ + "attributeId", + "collectionNodeId", + "projectId", + "organization", + ]; + const missingFields = validateFields(data, requiredFields); + + if (missingFields.length > 0) { + emitToSenderAndAdmins( + io, + socket, + data.organization, + EVENTS.collectionAttributeUpdateResponse, + ErrorResponse(missingFields, socket, data.organization), + connectedUsersByOrg + ); + return; + } + const result = await UpdateAttributes(data); + console.log('result: ', result); + const status = typeof result?.status === "string" ? result.status : "unknown"; + + const messages: Record = { + Success: { message: "Field updated successfully" }, + "Project not found": { message: "Project not found" }, + "Collection not found": { message: "Collection not found" }, + + + }; + + 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 response = FinalResponse( + status, + socket, + data.organization, + messages, + result_Datas + ); + console.log('response: ', response); + + emitToSenderAndAdmins( + io, + socket, + data.organization, + EVENTS.collectionAttributeUpdateResponse, + response, + connectedUsersByOrg + ); }; \ No newline at end of file diff --git a/src/socket-server/controllers/edgeController.ts b/src/socket-server/controllers/edgeController.ts index 550987f..48d4106 100644 --- a/src/socket-server/controllers/edgeController.ts +++ b/src/socket-server/controllers/edgeController.ts @@ -1,134 +1,134 @@ -import { Socket, Server } from "socket.io"; -import { EVENTS } from "../events/events"; -import { ErrorResponse, FinalResponse, validateFields } from "../utils/socketfunctionHelpers"; -import { emitToSenderAndAdmins } from "../utils/emitEventResponse"; -import { deleteEdge, edgecreation } from "../../shared/services/edgeService"; - - - -export const edgeHandleEvent = async ( - event: string, - socket: Socket, - io: Server, - data: any, - connectedUsersByOrg: { - [org: string]: { socketId: string; userId: string; role: string }[]; - } -) => { - if (event !== EVENTS.edgeConnect || !data?.organization) return; - const requiredFields = [ - "from", - "to", - "projectId", - "organization", - ]; - const missingFields = validateFields(data, requiredFields); - - if (missingFields.length > 0) { - emitToSenderAndAdmins( - io, - socket, - data.organization, - EVENTS.edgeConnectResponse, - ErrorResponse(missingFields, socket, data.organization), - connectedUsersByOrg - ); - return; - } - const result = await edgecreation(data); - console.log('result: ', result); - const status = typeof result?.status === "string" ? result.status : "unknown"; - - const messages: Record = { - Success: { message: "edge Created Successfully" }, - "User not found": { message: "User not found" }, - "Project not found": { message: "Project not found" }, - "From collection not found": { - message: "From collection not found", - }, - "To collection not found": { message: "To collection not found" }, - "Field already exists": { message: "Field already exists" }, - - }; - - 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 response = FinalResponse( - status, - socket, - data.organization, - messages, - result_Datas - ); - console.log('response: ', response); - - emitToSenderAndAdmins( - io, - socket, - data.organization, - EVENTS.edgeConnectResponse, - response, - connectedUsersByOrg - ); -}; -export const deleteEdgeHandleEvent = async ( - event: string, - socket: Socket, - io: Server, - data: any, - connectedUsersByOrg: { - [org: string]: { socketId: string; userId: string; role: string }[]; - } -) => { - if (event !== EVENTS.deleteEdgeConnect || !data?.organization) return; - const requiredFields = [ - "edgeId", - "projectId", - "organization", - ]; - const missingFields = validateFields(data, requiredFields); - - if (missingFields.length > 0) { - emitToSenderAndAdmins( - io, - socket, - data.organization, - EVENTS.deleteEdgeConnectResponse, - ErrorResponse(missingFields, socket, data.organization), - connectedUsersByOrg - ); - return; - } - const result = await deleteEdge(data); - console.log('result: ', result); - const status = typeof result?.status === "string" ? result.status : "unknown"; - - const messages: Record = { - Success: { message: "edge deleted Successfully" }, - "edge not found": { message: "edge not found" }, - "Project not found": { message: "Project not found" }, - - }; - - const result_Datas = status === "Success" && result?.data ? result.data : undefined; - const response = FinalResponse( - status, - socket, - data.organization, - messages, - result_Datas - ); - console.log('response: ', response); - - emitToSenderAndAdmins( - io, - socket, - data.organization, - EVENTS.edgeConnectResponse, - response, - connectedUsersByOrg - ); +import { Socket, Server } from "socket.io"; +import { EVENTS } from "../events/events"; +import { ErrorResponse, FinalResponse, validateFields } from "../utils/socketfunctionHelpers"; +import { emitToSenderAndAdmins } from "../utils/emitEventResponse"; +import { deleteEdge, edgecreation } from "../../shared/services/edgeService"; + + + +export const edgeHandleEvent = async ( + event: string, + socket: Socket, + io: Server, + data: any, + connectedUsersByOrg: { + [org: string]: { socketId: string; userId: string; role: string }[]; + } +) => { + if (event !== EVENTS.edgeConnect || !data?.organization) return; + const requiredFields = [ + "from", + "to", + "projectId", + "organization", + ]; + const missingFields = validateFields(data, requiredFields); + + if (missingFields.length > 0) { + emitToSenderAndAdmins( + io, + socket, + data.organization, + EVENTS.edgeConnectResponse, + ErrorResponse(missingFields, socket, data.organization), + connectedUsersByOrg + ); + return; + } + const result = await edgecreation(data); + console.log('result: ', result); + const status = typeof result?.status === "string" ? result.status : "unknown"; + + const messages: Record = { + Success: { message: "edge Created Successfully" }, + "User not found": { message: "User not found" }, + "Project not found": { message: "Project not found" }, + "From collection not found": { + message: "From collection not found", + }, + "To collection not found": { message: "To collection not found" }, + "Field already exists": { message: "Field already exists" }, + + }; + + 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 response = FinalResponse( + status, + socket, + data.organization, + messages, + result_Datas + ); + console.log('response: ', response); + + emitToSenderAndAdmins( + io, + socket, + data.organization, + EVENTS.edgeConnectResponse, + response, + connectedUsersByOrg + ); +}; +export const deleteEdgeHandleEvent = async ( + event: string, + socket: Socket, + io: Server, + data: any, + connectedUsersByOrg: { + [org: string]: { socketId: string; userId: string; role: string }[]; + } +) => { + if (event !== EVENTS.deleteEdgeConnect || !data?.organization) return; + const requiredFields = [ + "edgeId", + "projectId", + "organization", + ]; + const missingFields = validateFields(data, requiredFields); + + if (missingFields.length > 0) { + emitToSenderAndAdmins( + io, + socket, + data.organization, + EVENTS.deleteEdgeConnectResponse, + ErrorResponse(missingFields, socket, data.organization), + connectedUsersByOrg + ); + return; + } + const result = await deleteEdge(data); + console.log('result: ', result); + const status = typeof result?.status === "string" ? result.status : "unknown"; + + const messages: Record = { + Success: { message: "edge deleted Successfully" }, + "edge not found": { message: "edge not found" }, + "Project not found": { message: "Project not found" }, + + }; + + const result_Datas = status === "Success" && result?.data ? result.data : undefined; + const response = FinalResponse( + status, + socket, + data.organization, + messages, + result_Datas + ); + console.log('response: ', response); + + emitToSenderAndAdmins( + io, + socket, + data.organization, + EVENTS.edgeConnectResponse, + response, + connectedUsersByOrg + ); }; \ No newline at end of file diff --git a/src/socket-server/controllers/projectController.ts b/src/socket-server/controllers/projectController.ts index 8d8841a..7b24f30 100644 --- a/src/socket-server/controllers/projectController.ts +++ b/src/socket-server/controllers/projectController.ts @@ -1,70 +1,70 @@ -import { Socket, Server } from "socket.io"; -import { EVENTS } from "../events/events"; -import { ErrorResponse, FinalResponse, validateFields } from "../utils/socketfunctionHelpers"; -import { emitToSenderAndAdmins } from "../utils/emitEventResponse"; -import { projectCreationService } from "../../shared/services/projectService"; - -export const projectHandleEvent = async ( - event: string, - socket: Socket, - io: Server, - data: any, - connectedUsersByOrg: { - [org: string]: { socketId: string; userId: string; role: string }[]; - } -) => { - if (event !== EVENTS.projectCreate || !data?.organization) return; - const requiredFields = [ - "application", - "architecture", - "apiType", - "projectName", - "useableLanguage", - "organization", - ]; - const missingFields = validateFields(data, requiredFields); - - if (missingFields.length > 0) { - emitToSenderAndAdmins( - io, - socket, - data.organization, - EVENTS.projectCreateResponse, - ErrorResponse(missingFields, socket, data.organization), - connectedUsersByOrg - ); - return; - } - const result = await projectCreationService(data); - const status = typeof result?.status === "string" ? result.status : "unknown"; - - const messages: Record = { - Success: { message: "Project Created Successfully" }, - "Project Already Exists": { message: "Project Already Exists" }, - "Already MVC architecture assigned to this projectId": { message: "Already MVC architecture assigned to this projectId" }, - "Project creation unsuccessfull": { - message: "Project creation unsuccessfull", - }, - "New architecture": { message: "New architecture" }, - - - }; - - 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.projectCreateResponse, - response, - connectedUsersByOrg - ); +import { Socket, Server } from "socket.io"; +import { EVENTS } from "../events/events"; +import { ErrorResponse, FinalResponse, validateFields } from "../utils/socketfunctionHelpers"; +import { emitToSenderAndAdmins } from "../utils/emitEventResponse"; +import { projectCreationService } from "../../shared/services/projectService"; + +export const projectHandleEvent = async ( + event: string, + socket: Socket, + io: Server, + data: any, + connectedUsersByOrg: { + [org: string]: { socketId: string; userId: string; role: string }[]; + } +) => { + if (event !== EVENTS.projectCreate || !data?.organization) return; + const requiredFields = [ + "application", + "architecture", + "apiType", + "projectName", + "useableLanguage", + "organization", + ]; + const missingFields = validateFields(data, requiredFields); + + if (missingFields.length > 0) { + emitToSenderAndAdmins( + io, + socket, + data.organization, + EVENTS.projectCreateResponse, + ErrorResponse(missingFields, socket, data.organization), + connectedUsersByOrg + ); + return; + } + const result = await projectCreationService(data); + const status = typeof result?.status === "string" ? result.status : "unknown"; + + const messages: Record = { + Success: { message: "Project Created Successfully" }, + "Project Already Exists": { message: "Project Already Exists" }, + "Already MVC architecture assigned to this projectId": { message: "Already MVC architecture assigned to this projectId" }, + "Project creation unsuccessfull": { + message: "Project creation unsuccessfull", + }, + "New architecture": { message: "New architecture" }, + + + }; + + 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.projectCreateResponse, + response, + connectedUsersByOrg + ); }; \ No newline at end of file diff --git a/src/socket-server/events/eventHandaler.ts b/src/socket-server/events/eventHandaler.ts index 14735b6..d76778f 100644 --- a/src/socket-server/events/eventHandaler.ts +++ b/src/socket-server/events/eventHandaler.ts @@ -1,17 +1,17 @@ -import { AttributesDeleteHandleEvent, AttributesUpdateHandleEvent, CollectioDeleteHandleEvent, CollectioDuplicateHandleEvent, CollectioNamenHandleEvent, CollectionHandleEvent, setAttributesHandleEvent } from "../controllers/collectionNodeController"; -import { edgeHandleEvent } from "../controllers/edgeController"; -import { projectHandleEvent } from "../controllers/projectController"; -import { EVENTS } from "./events"; - -export const eventHandlerMap: Record = { - [EVENTS.edgeConnect]: edgeHandleEvent, - [EVENTS.projectCreate]: projectHandleEvent, - - [EVENTS.collectionCreate]: CollectionHandleEvent, - [EVENTS.collectionNameSet]: CollectioNamenHandleEvent, - [EVENTS.collectionDelete]: CollectioDeleteHandleEvent, - [EVENTS.collectionDuplicate]: CollectioDuplicateHandleEvent, - [EVENTS.collectionAttributeSet]: setAttributesHandleEvent, - [EVENTS.collectionAttributeDelete]: AttributesDeleteHandleEvent, - [EVENTS.collectionAttributeUpdate]: AttributesUpdateHandleEvent, +import { AttributesDeleteHandleEvent, AttributesUpdateHandleEvent, CollectioDeleteHandleEvent, CollectioDuplicateHandleEvent, CollectioNamenHandleEvent, CollectionHandleEvent, setAttributesHandleEvent } from "../controllers/collectionNodeController"; +import { edgeHandleEvent } from "../controllers/edgeController"; +import { projectHandleEvent } from "../controllers/projectController"; +import { EVENTS } from "./events"; + +export const eventHandlerMap: Record = { + [EVENTS.edgeConnect]: edgeHandleEvent, + [EVENTS.projectCreate]: projectHandleEvent, + + [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 diff --git a/src/socket-server/events/events.ts b/src/socket-server/events/events.ts index 948023d..4b68f5b 100644 --- a/src/socket-server/events/events.ts +++ b/src/socket-server/events/events.ts @@ -1,35 +1,35 @@ -export const EVENTS = { - connection: "connection", - disconnect: "disconnect", - userConnect: "userConnectResponse", - userDisConnect: "userDisConnectResponse", - joinRoom: "joinRoom", - createroom: "createRoom", - leaveRoom: "leaveRoom", - roomCreated: "roomCreated", - roomDeleted: "roomDeleted", - - - projectCreate: "v1:project:create", - projectCreateResponse: "v1:response:project:create", - - 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", - - edgeConnect: "v1:edge:connect", - edgeConnectResponse: "v1:response:edge:connect", - deleteEdgeConnect: "v1:edge:deleteConnect", - deleteEdgeConnectResponse: "v1:response:edge:deleteConnect", +export const EVENTS = { + connection: "connection", + disconnect: "disconnect", + userConnect: "userConnectResponse", + userDisConnect: "userDisConnectResponse", + joinRoom: "joinRoom", + createroom: "createRoom", + leaveRoom: "leaveRoom", + roomCreated: "roomCreated", + roomDeleted: "roomDeleted", + + + projectCreate: "v1:project:create", + projectCreateResponse: "v1:response:project:create", + + 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", + + edgeConnect: "v1:edge:connect", + edgeConnectResponse: "v1:response:edge:connect", + deleteEdgeConnect: "v1:edge:deleteConnect", + deleteEdgeConnectResponse: "v1:response:edge:deleteConnect", } \ No newline at end of file diff --git a/src/socket-server/index.ts b/src/socket-server/index.ts index 6e3eff0..6d628c6 100644 --- a/src/socket-server/index.ts +++ b/src/socket-server/index.ts @@ -1,32 +1,32 @@ -import express, { Response, Request } from "express"; -import http from "http"; -import dotenv from "dotenv"; -import { Server } from "socket.io"; -import cors from "cors"; -import { SocketServer } from "./manager/manager"; - -dotenv.config(); - -const app = express(); -const PORT = process.env.SOCKET_PORT; -const server = http.createServer(app); - -app.use(cors()); -app.use(express.json()); - - - - -app.get("/", (req: Request, res: Response) => { - res.send("Hello, I am autoCode RealTime!"); -}); -const io = new Server(server, { - cors: { - origin: "*", - methods: ["GET", "POST"], - }, -}); -SocketServer(io); -server.listen(PORT, () => { - console.log(`socket-Server is running on http://localhost:${PORT}`); -}); +import express, { Response, Request } from "express"; +import http from "http"; +import dotenv from "dotenv"; +import { Server } from "socket.io"; +import cors from "cors"; +import { SocketServer } from "./manager/manager"; + +dotenv.config(); + +const app = express(); +const PORT = process.env.SOCKET_PORT; +const server = http.createServer(app); + +app.use(cors()); +app.use(express.json()); + + + + +app.get("/", (req: Request, res: Response) => { + res.send("Hello, I am autoCode RealTime!"); +}); +const io = new Server(server, { + cors: { + origin: "*", + methods: ["GET", "POST"], + }, +}); +SocketServer(io); +server.listen(PORT, () => { + console.log(`socket-Server is running on http://localhost:${PORT}`); +}); diff --git a/src/socket-server/manager/manager.ts b/src/socket-server/manager/manager.ts index ccf5751..cc01635 100644 --- a/src/socket-server/manager/manager.ts +++ b/src/socket-server/manager/manager.ts @@ -1,118 +1,118 @@ -import { Server, Socket } from "socket.io"; -import jwt from "jsonwebtoken"; -import { eventHandlerMap } from "../events/eventHandaler"; -import { existingUserData } from "../../shared/services/AuthService"; - -interface UserPayload { - userId: string; - organization: string; - [key: string]: any; -} - -interface UserSocketInfo { - socketId: string; - userId: string; - organization: string; -} - -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; - 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); - 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")); - - } - - 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); - - if (!mailExistance) { - return next(new Error("Unauthorized user - not in system")); - } - - // Generate new access token - const newAccessToken = jwt.sign( - { email: decodedRefresh.email, organization: decodedRefresh.organization }, - jwt_secret, - { expiresIn: "3h" } // adjust expiry - ); - - socket.emit("newAccessToken", newAccessToken); - - (socket as any).user = decodedRefresh; - return next(); - } catch (refreshErr) { - return next(new Error("Refresh token expired or invalid")); - } - } - - return next(new Error("Invalid token")); - } - } catch (err) { - return next(new Error("Authentication error")); - } - }); - namespace.on("connection", (socket: Socket) => { - const user = (socket as any).user as UserPayload; - const { organization, userId } = user; - - 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 }); - console.log(`✅ Connected to namespace ${nspName}: ${socket.id}`); - - // Common event handler - socket.onAny((event: string, data: any, callback: any) => { - const handler = eventHandlerMap[event]; - if (handler) { - handler(event, socket, io, data, connectedUsersByOrg, callback); - } else { - console.warn(` No handler found for event: ${event}`); - } - }); - - socket.on("disconnect", () => { - onlineUsers[organization]?.delete(socket.id); - if (onlineUsers[organization]?.size === 0) { - delete onlineUsers[organization]; - } - connectedUsersByOrg[organization] = connectedUsersByOrg[organization]?.filter( - (u) => u.socketId !== socket.id - ); - }); - }); - }); - - return io; -}; +import { Server, Socket } from "socket.io"; +import jwt from "jsonwebtoken"; +import { eventHandlerMap } from "../events/eventHandaler"; +import { existingUserData } from "../../shared/services/AuthService"; + +interface UserPayload { + userId: string; + organization: string; + [key: string]: any; +} + +interface UserSocketInfo { + socketId: string; + userId: string; + organization: string; +} + +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; + 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); + 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")); + + } + + 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); + + if (!mailExistance) { + return next(new Error("Unauthorized user - not in system")); + } + + // Generate new access token + const newAccessToken = jwt.sign( + { email: decodedRefresh.email, organization: decodedRefresh.organization }, + jwt_secret, + { expiresIn: "3h" } // adjust expiry + ); + + socket.emit("newAccessToken", newAccessToken); + + (socket as any).user = decodedRefresh; + return next(); + } catch (refreshErr) { + return next(new Error("Refresh token expired or invalid")); + } + } + + return next(new Error("Invalid token")); + } + } catch (err) { + return next(new Error("Authentication error")); + } + }); + namespace.on("connection", (socket: Socket) => { + const user = (socket as any).user as UserPayload; + const { organization, userId } = user; + + 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 }); + console.log(`✅ Connected to namespace ${nspName}: ${socket.id}`); + + // Common event handler + socket.onAny((event: string, data: any, callback: any) => { + const handler = eventHandlerMap[event]; + if (handler) { + handler(event, socket, io, data, connectedUsersByOrg, callback); + } else { + console.warn(` No handler found for event: ${event}`); + } + }); + + socket.on("disconnect", () => { + onlineUsers[organization]?.delete(socket.id); + if (onlineUsers[organization]?.size === 0) { + delete onlineUsers[organization]; + } + connectedUsersByOrg[organization] = connectedUsersByOrg[organization]?.filter( + (u) => u.socketId !== socket.id + ); + }); + }); + }); + + return io; +}; diff --git a/src/socket-server/utils/emitEventResponse.ts b/src/socket-server/utils/emitEventResponse.ts index 56e1ed2..ae5f8c8 100644 --- a/src/socket-server/utils/emitEventResponse.ts +++ b/src/socket-server/utils/emitEventResponse.ts @@ -1,104 +1,104 @@ -import { Socket, Server } from "socket.io"; - -interface EmitOptions { - success: boolean; - message: string; - data?: any; - error?: any; - organization: string; - socketId: string; - status?: string; -} - -export const emitEventResponse = ( - socket: Socket, - organization: string, - event: string, - result: EmitOptions -) => { - if (!organization) { - console.log(`Organization missing in response for event: ${event}`); - return; - } - - socket.to(organization).emit(event, { - // success: result.success, - message: result.message, - data: result.data, - error: result.error, - socketId: result.socketId, - organization, - }); -}; - -export const emitToSenderAndAdmins = ( - io: Server, - socket: Socket, - organization: string, - event: string, - result: EmitOptions, - connectedUsersByOrg: { - [org: string]: { socketId: string; userId: string; role: string }[]; - } -) => { - - console.log('result.data: ', result.data); - socket.emit(event, { - message: result.message, - data: result.data, - error: result.error, - socketId: result.socketId, - organization, - }); - socket.to(`${organization}_admins`).emit(event, { - message: result.message, - data: result.data, - error: result.error, - socketId: result.socketId, - organization, - }); -}; -// export const emitToRoom = ( -// io: Server, -// socket: Socket, -// room: string, -// event: string, -// result: EmitOptions -// ) => { -// const payload = { -// message: result.message, -// data: result.data, -// socketId: result.socketId, -// organization: result.organization, -// }; - -// console.log("event: ", event); -// console.log("payload: ", payload); -// console.log("room: ", room); -// socket.emit(event, payload); // ✅ FIXED: sends to all in room including sender -// }; -export const emitToRoom = ( - io: Server, - socket: Socket, - room: string, - event: string, - result: EmitOptions -) => { - const payload = { - message: result.message, - data: result.data, - socketId: result.socketId, - organization: result.organization, - }; - - console.log("🔥 EMIT TO ROOM:"); - console.log("➡️ Event: ", event); - console.log("📦 Full result input: ", result); // 👉 what you passed from observer - console.log("📤 Final payload being emitted: ", payload); // 👉 actual emitted payload - console.log("🏠 Room: ", room); - - socket.to(room).emit(event, payload); - - // ✅ Optional: Emit to sender too (if needed) - socket.emit(event, payload); -}; +import { Socket, Server } from "socket.io"; + +interface EmitOptions { + success: boolean; + message: string; + data?: any; + error?: any; + organization: string; + socketId: string; + status?: string; +} + +export const emitEventResponse = ( + socket: Socket, + organization: string, + event: string, + result: EmitOptions +) => { + if (!organization) { + console.log(`Organization missing in response for event: ${event}`); + return; + } + + socket.to(organization).emit(event, { + // success: result.success, + message: result.message, + data: result.data, + error: result.error, + socketId: result.socketId, + organization, + }); +}; + +export const emitToSenderAndAdmins = ( + io: Server, + socket: Socket, + organization: string, + event: string, + result: EmitOptions, + connectedUsersByOrg: { + [org: string]: { socketId: string; userId: string; role: string }[]; + } +) => { + + console.log('result.data: ', result.data); + socket.emit(event, { + message: result.message, + data: result.data, + error: result.error, + socketId: result.socketId, + organization, + }); + socket.to(`${organization}_admins`).emit(event, { + message: result.message, + data: result.data, + error: result.error, + socketId: result.socketId, + organization, + }); +}; +// export const emitToRoom = ( +// io: Server, +// socket: Socket, +// room: string, +// event: string, +// result: EmitOptions +// ) => { +// const payload = { +// message: result.message, +// data: result.data, +// socketId: result.socketId, +// organization: result.organization, +// }; + +// console.log("event: ", event); +// console.log("payload: ", payload); +// console.log("room: ", room); +// socket.emit(event, payload); // ✅ FIXED: sends to all in room including sender +// }; +export const emitToRoom = ( + io: Server, + socket: Socket, + room: string, + event: string, + result: EmitOptions +) => { + const payload = { + message: result.message, + data: result.data, + socketId: result.socketId, + organization: result.organization, + }; + + console.log("🔥 EMIT TO ROOM:"); + console.log("➡️ Event: ", event); + console.log("📦 Full result input: ", result); // 👉 what you passed from observer + console.log("📤 Final payload being emitted: ", payload); // 👉 actual emitted payload + console.log("🏠 Room: ", room); + + socket.to(room).emit(event, payload); + + // ✅ Optional: Emit to sender too (if needed) + socket.emit(event, payload); +}; diff --git a/src/socket-server/utils/socketfunctionHelpers.ts b/src/socket-server/utils/socketfunctionHelpers.ts index fd61c91..b503f91 100644 --- a/src/socket-server/utils/socketfunctionHelpers.ts +++ b/src/socket-server/utils/socketfunctionHelpers.ts @@ -1,41 +1,41 @@ -import { Socket, Server } from "socket.io"; - -export const validateFields = ( - data: any, - requiredFields: string[] -): string[] => { - return requiredFields.filter( - (field) => data[field] === undefined || data[field] === null - ); -}; - -export const ErrorResponse = ( - missingFields: string[], - socket: Socket, - organization: string -) => ({ - success: false, - message: `Missing required field(s): ${missingFields.join(", ")}`, - status: "MissingFields", - socketId: socket.id, - organization: organization ?? "unknown", -}); - -export const FinalResponse = ( - status: string, - socket: Socket, - organization: string, - messages: Record, - data?: any -) => { - const msg = messages[status] || { message: "Internal server error" }; - const includeData = (status === "Success" || status === "updated") && data; - return { - success: status === "Success" || status === "updated", - message: msg.message, - status, - socketId: socket.id, - organization, -...(includeData ? { data } : {}), - }; -}; +import { Socket, Server } from "socket.io"; + +export const validateFields = ( + data: any, + requiredFields: string[] +): string[] => { + return requiredFields.filter( + (field) => data[field] === undefined || data[field] === null + ); +}; + +export const ErrorResponse = ( + missingFields: string[], + socket: Socket, + organization: string +) => ({ + success: false, + message: `Missing required field(s): ${missingFields.join(", ")}`, + status: "MissingFields", + socketId: socket.id, + organization: organization ?? "unknown", +}); + +export const FinalResponse = ( + status: string, + socket: Socket, + organization: string, + messages: Record, + data?: any +) => { + const msg = messages[status] || { message: "Internal server error" }; + const includeData = (status === "Success" || status === "updated") && data; + return { + success: status === "Success" || status === "updated", + message: msg.message, + status, + socketId: socket.id, + organization, +...(includeData ? { data } : {}), + }; +};