From adbdf733d8cf52dc12bd48f50391fd4e2c4b5b83 Mon Sep 17 00:00:00 2001
From: Nikita Atroshenko <nikita@airheadventures.com>
Date: Tue, 22 Jun 2021 20:37:07 +0300
Subject: [PATCH] wip: add groups handle

---
 combined.log                        | 81 +++++++++++++++++++++++++++++
 src/controllers/GroupsController.ts | 25 +++++++++
 src/controllers/UsersController.ts  |  8 +--
 src/entity/Group.ts                 |  2 +-
 src/entity/Message.ts               |  2 +-
 src/helpers/roleCheck.ts            |  2 +-
 src/helpers/verifyToken.ts          |  2 +-
 src/interfaces/group.ts             |  8 +++
 src/interfaces/index.ts             |  1 +
 src/interfaces/socketEmits.ts       | 11 +++-
 src/routes/group.ts                 | 11 ++++
 src/routes/index.ts                 |  2 +
 src/services/auth.ts                |  4 +-
 src/services/groups.ts              | 58 +++++++++++++++++++++
 src/socket.ts                       | 15 ++----
 15 files changed, 211 insertions(+), 21 deletions(-)
 create mode 100644 src/controllers/GroupsController.ts
 create mode 100644 src/interfaces/group.ts
 create mode 100644 src/routes/group.ts
 create mode 100644 src/services/groups.ts

diff --git a/combined.log b/combined.log
index 9beefea..414d6b2 100644
--- a/combined.log
+++ b/combined.log
@@ -62,3 +62,84 @@
 {"message":"start delete user with session jti: e0a97fd382bab3d2107fb9665216e0f40a299960","level":"info"}
 {"message":"start delete user with session jti: c963c233eeecdfc25dd9268001525c8123ebd904","level":"info"}
 {"message":"start delete user with session jti: d113ac9eb199d64e6f6866ce07f5bf37cae14ffe","level":"info"}
+{"message":"start delete user with session jti: b80a8384e3d94cf87fdd5d2156c93b5cf6e9ac4c","level":"info"}
+{"message":"start delete user with session jti: ce5d1d4b4a99eb5b4b73b681555a5561ac9035c7","level":"info"}
+{"message":"start delete user with session jti: 14a59dc1deff90b533a7d7edfcd0f441d9675c85","level":"info"}
+{"message":"start delete user with session jti: e92e615b0e2e2eec8045b2ed9a3498a9ba2ce8aa","level":"info"}
+{"message":"start delete user with session jti: 9d99a79a6740ffd229a2cbcfd9863a812dd46dbf","level":"info"}
+{"message":"start delete user with session jti: 2e28546a4ae9076e37eeae2c1a73518867764ad9","level":"info"}
+{"message":"start delete user with session jti: 79e6c378779cbdd52bc0acde54835880fc26c605","level":"info"}
+{"message":"start delete user with session jti: edc37e98f4e5336258ae6d5ce72cd2c732e9238a","level":"info"}
+{"message":"start delete user with session jti: 2eb40012517c30c63502b960c42a3bb1085464bf","level":"info"}
+{"message":"start delete user with session jti: 9646a7f5ce2063f12045837ae670f1f601892708","level":"info"}
+{"message":"start delete user with session jti: 3800866480867cda0d9d182bfb20df007fa3f303","level":"info"}
+{"message":"start delete user with session jti: 509b679ff1147e28565c8ba9e85a05a5ee4bd28e","level":"info"}
+{"message":"start delete user with session jti: 25abe210f3871d5c6ddd6bfb2b32869d80c88bed","level":"info"}
+{"message":"start delete user with session jti: eb7245be5216791acda1f32a934be2440e13005c","level":"info"}
+{"message":"start delete user with session jti: 9e409d1c9faba523c671c3b6809318b4f85ec398","level":"info"}
+{"message":"start delete user with session jti: 28ea4ec22153b7756af4e035ad33f97eabc09339","level":"info"}
+{"message":"start delete user with session jti: 614ec05bbce3968d975a08ea9fd09e00871514ca","level":"info"}
+{"message":"start delete user with session jti: 19a5d845686d42658d2c12db8ea96d08cff3209a","level":"info"}
+{"message":"start delete user with session jti: f2187ca060c975b1f21a63df1f841f297fd07b41","level":"info"}
+{"message":"start delete user with session jti: 208cfab93f9f0b4298e381b4ab6b56eb4328bb5c","level":"info"}
+{"message":"start delete user with session jti: 206247485917cead06ae97d1435a70f44c588682","level":"info"}
+{"message":"start delete user with session jti: 5346f63c5f6cc5422b0bebc2d479ff567e455d27","level":"info"}
+{"message":"start delete user with session jti: 704bd70b4342ece4f9b0231945001d8a0be04c4f","level":"info"}
+{"message":"start delete user with session jti: 79fbed1586f2ffa80b42c31107f59ed3597b9819","level":"info"}
+{"message":"start delete user with session jti: df4b5ccc157eb21123397a0b589591bc41a357d2","level":"info"}
+{"message":"start delete user with session jti: f6fcc256768b85fb1e62a36f0af8ffedede4d340","level":"info"}
+{"message":"start delete user with session jti: f23c7649a3207e28cc86aa55c6eda5ad1f4f7398","level":"info"}
+{"message":"start delete user with session jti: fef2aea61e5b16de4b9d137d9da985fe7cac4bd8","level":"info"}
+{"message":"start delete user with session jti: 0529c965e0dd33a7d8d4bd622473e82337b31c6a","level":"info"}
+{"message":"start delete user with session jti: 5dc9a34e4d9a91dea40695de5df605a62d38fee9","level":"info"}
+{"message":"start delete user with session jti: 061b3e8f058f686febf6a7c577fb0bfa398d0aa7","level":"info"}
+{"message":"start delete user with session jti: 917809bc1ebd344447e4eb228eb4c137303dcb84","level":"info"}
+{"message":"start delete user with session jti: 697dd1b4d44e344a5622ab314e4d0c54041cc6c4","level":"info"}
+{"message":"start delete user with session jti: eab8a1d7e012ba2c08c13ca5d7e8c586a51da24c","level":"info"}
+{"message":"start delete user with session jti: 43712fdff93c0a325647afeefddd766abd9e94e3","level":"info"}
+{"message":"start delete user with session jti: 3da5179266ae9c17487cb679a379ac7a4102107e","level":"info"}
+{"message":"start delete user with session jti: 6a592a6691fa8234e844eac6780d85f91b801ef2","level":"info"}
+{"message":"start delete user with session jti: 0ec3258acf812c433b7150d58c14d9fdd3b74e7d","level":"info"}
+{"message":"start delete user with session jti: 3f45e1c111d8baf01af818667abb6b10f7e3554a","level":"info"}
+{"message":"start delete user with session jti: 0b3f2ffba4e65efed4f1ff1f5924e7656c116cbb","level":"info"}
+{"message":"start delete user with session jti: dabf040d34f145662dde676135075556962ab467","level":"info"}
+{"message":"start delete user with session jti: ae325362e7581eb09a0d58cfccadb101a986a2e8","level":"info"}
+{"message":"start delete user with session jti: 3b426bbeac9c02ba572f695236e51af242fc03a4","level":"info"}
+{"message":"start delete user with session jti: 069abbcf38627803fca282854c5060d2352f40a0","level":"info"}
+{"message":"start delete user with session jti: 81186bdc9420efcb01e16b2d716524dec4f74b97","level":"info"}
+{"message":"start delete user with session jti: d9b40f8ac624e0c61df454ca3e3b292bdce96d95","level":"info"}
+{"message":"start delete user with session jti: ad05b259e8fc2f9a1c24e1edc57fac08d5408640","level":"info"}
+{"message":"start delete user with session jti: 32e0547dddfe9c34a435e20f0172d683965cd7d5","level":"info"}
+{"message":"start delete user with session jti: a0a3cf7f8c11cd0c1822fb45585e0267e00a75c5","level":"info"}
+{"message":"start delete user with session jti: 710f79510846a3ee9532d24cc058a76cfe7b4af6","level":"info"}
+{"message":"start delete user with session jti: 9a5107c14c3d33b8ff2a02995fc7543686cc23e0","level":"info"}
+{"message":"start delete user with session jti: 209efba9c47eaa4953ff53054e1285421206bb12","level":"info"}
+{"message":"start delete user with session jti: 0c35a037d8f443f2d21ac3535e00fa4df055c722","level":"info"}
+{"message":"start delete user with session jti: 6efae305148aa6be36f1b1940294e58df85d7825","level":"info"}
+{"message":"start delete user with session jti: b27325dc10d29d63fe94bd5a70477dd2dad3248a","level":"info"}
+{"message":"start delete user with session jti: 8c97b84901269c22672cbc258b317c687167759d","level":"info"}
+{"message":"start delete user with session jti: b77427cbc956829850e4b4aceca104884018c407","level":"info"}
+{"message":"start delete user with session jti: c475f867577678bd6f5ddb29052f41d1352ddf7d","level":"info"}
+{"message":"start delete user with session jti: aceaa3e8b6b10d9aa633c52845fa6efe2ea881f1","level":"info"}
+{"message":"start delete user with session jti: 63446c89e468c728bc29402e700119e530a5f060","level":"info"}
+{"message":"start delete user with session jti: 88fcf84d5a4d9d9b10e61c0c9a9d38ac96fa3a4b","level":"info"}
+{"message":"start delete user with session jti: 07c2c19f8e86fcddadfb91947c7df011a84ea5ef","level":"info"}
+{"message":"start delete user with session jti: c7084ff568a7392b69bface86da0351c5ad38c27","level":"info"}
+{"message":"start delete user with session jti: 3ac054ae6a662fdb3a0d210a9163bdfa19caba5f","level":"info"}
+{"message":"start delete user with session jti: 9fcd6b1b8ba114bb2d1382337b52b1a07cea5df8","level":"info"}
+{"message":"start delete user with session jti: 8b0ec26016f5f3de82fbe530f1a40eebb37fab54","level":"info"}
+{"message":"start delete user with session jti: 0ecbcb2090632baacd23e258f7c9e1333a2ba244","level":"info"}
+{"message":"start delete user with session jti: 4d0f1f686d5f01e440ec1f8f96f90a03275a5af6","level":"info"}
+{"message":"start delete user with session jti: 68cf66c4dea0a8010a3c64852fcefe9f70543fe8","level":"info"}
+{"message":"start delete user with session jti: 30798e574f17744793fce33137a325b724a73969","level":"info"}
+{"message":"start delete user with session jti: ad6fc08457834944a3b890bcdcf920c35bffcb14","level":"info"}
+{"message":"start delete user with session jti: f21a69dbf261321f4bb441dbdb830d8190b51989","level":"info"}
+{"message":"start delete user with session jti: c548dd2fde7e85891282aa9d174d84e66e136cf5","level":"info"}
+{"message":"start delete user with session jti: 99ea530bb873328e9e6f51849cc3aee8547b117d","level":"info"}
+{"message":"start delete user with session jti: ee08ae8b36ce8f760a42683ad96dfe59d3ded29c","level":"info"}
+{"message":"start delete user with session jti: 312fd6b18390aa7ccafb87163f548abc6c4c8e10","level":"info"}
+{"message":"start delete user with session jti: 237c3836476782c7fdcbcde76c39ab1a8f18b864","level":"info"}
+{"message":"start delete user with session jti: 5226d530045ed100366675cee9f7c513448de638","level":"info"}
+{"message":"start delete user with session jti: aef8ce22fbe3d02968edc237374ed4fcc425d3bc","level":"info"}
+{"message":"start delete user with session jti: 62ece7027659519169b22bd55979260f42ee49a0","level":"info"}
+{"message":"start delete user with session jti: 678ffbb1c0cf7cc376680d0b2626151a244c607a","level":"info"}
diff --git a/src/controllers/GroupsController.ts b/src/controllers/GroupsController.ts
new file mode 100644
index 0000000..094f7a0
--- /dev/null
+++ b/src/controllers/GroupsController.ts
@@ -0,0 +1,25 @@
+import { Request, Response } from "express";
+import { IGetUserAuthInfoRequest } from "../interfaces";
+
+import GroupService from "../services/groups";
+
+class GroupsController {
+    /*
+
+    Get All
+
+  */
+    static getAll = async (req: IGetUserAuthInfoRequest, res: Response) => {
+      const { error, result } = await GroupService.getAll(req.uuid);
+      if (error) {
+        return res.status(error.code).json({
+          error: error.msg,
+        });
+      }
+      return res
+        .status(200)
+        .json(result);
+    };
+}
+
+export default GroupsController;
diff --git a/src/controllers/UsersController.ts b/src/controllers/UsersController.ts
index 5ebdc95..c036f24 100644
--- a/src/controllers/UsersController.ts
+++ b/src/controllers/UsersController.ts
@@ -1,6 +1,6 @@
 import { Request, Response } from "express";
 
-import UserServoce from "../services/users";
+import UserService from "../services/users";
 import { IGetUserAuthInfoRequest, ROLES } from "../interfaces";
 
 class UsersController {
@@ -10,7 +10,7 @@ class UsersController {
 
   */
     static getAll = async (req: Request, res: Response) => {
-      const { error, result } = await UserServoce.getAll();
+      const { error, result } = await UserService.getAll();
       if (error) {
         return res.status(error.code).json({
           error: error.msg,
@@ -26,7 +26,7 @@ class UsersController {
 
   */
   static createUser = async (req: Request, res: Response) => {
-    const { error, result } = await UserServoce.createUser(
+    const { error, result } = await UserService.createUser(
       req.body,
       ROLES.USER
     );
@@ -44,7 +44,7 @@ class UsersController {
 
   */
   static updateUser = async (req: IGetUserAuthInfoRequest, res: Response) => {
-    const { error, result } = await UserServoce.updateUser(
+    const { error, result } = await UserService.updateUser(
       req.body,
       req.uuid,
       req.app.get("socketService")
diff --git a/src/entity/Group.ts b/src/entity/Group.ts
index ed3f2e7..38a0ac0 100644
--- a/src/entity/Group.ts
+++ b/src/entity/Group.ts
@@ -21,7 +21,7 @@ export class Group {
   description: string;
 
   @Column({ default: true })
-  private: string;
+  private: boolean;
 
   @Column()
   lastActive: Date;
diff --git a/src/entity/Message.ts b/src/entity/Message.ts
index 6b0d6aa..2ead652 100644
--- a/src/entity/Message.ts
+++ b/src/entity/Message.ts
@@ -28,7 +28,7 @@ export class Message {
   @UpdateDateColumn()
   updatedAt: Date;
 
-  @ManyToMany(() => ChatUser, (user) => user.messages, { nullable: true })
+  @ManyToOne(() => ChatUser, (user) => user.messages, { nullable: true })
   users?: ChatUser[];
 
   @ManyToOne(() => Group, (group) => group.messages, { nullable: true })
diff --git a/src/helpers/roleCheck.ts b/src/helpers/roleCheck.ts
index 0924eb4..76ba496 100644
--- a/src/helpers/roleCheck.ts
+++ b/src/helpers/roleCheck.ts
@@ -27,7 +27,7 @@ export const hasRoles = (roles) => {
       });
 
       if (!isAllowed) {
-        res.status(401).json({ message: "Unauthorized" });
+        res.status(401).json({ error: "Unauthorized" });
       } else {
         next();
       }
diff --git a/src/helpers/verifyToken.ts b/src/helpers/verifyToken.ts
index 68c1619..241078d 100644
--- a/src/helpers/verifyToken.ts
+++ b/src/helpers/verifyToken.ts
@@ -24,6 +24,6 @@ export const verifyToken = async (
     req.uuid = user.uuid;
     next();
   } catch (err) {
-    return res.sendStatus(403);
+    return res.status(403).json({error: "Unauthorized"});
   }
 };
diff --git a/src/interfaces/group.ts b/src/interfaces/group.ts
new file mode 100644
index 0000000..c51f810
--- /dev/null
+++ b/src/interfaces/group.ts
@@ -0,0 +1,8 @@
+
+import {Group } from "../entity";
+
+export interface IGetGroups {
+    publicGroupsWithUser: Group[]
+    privateGroups: Group[]
+    publicGroups: Group[]
+}
\ No newline at end of file
diff --git a/src/interfaces/index.ts b/src/interfaces/index.ts
index df01013..71a0296 100644
--- a/src/interfaces/index.ts
+++ b/src/interfaces/index.ts
@@ -4,6 +4,7 @@ export * from "./auth"
 export * from "./user"
 export * from "./socketEmits"
 export * from "./roles"
+export * from "./group"
 interface Error {
   code: number;
   msg: string;
diff --git a/src/interfaces/socketEmits.ts b/src/interfaces/socketEmits.ts
index ff3f6e5..037b301 100644
--- a/src/interfaces/socketEmits.ts
+++ b/src/interfaces/socketEmits.ts
@@ -1,5 +1,14 @@
 export enum EMITS {
+    // Auth
     LOGIN = "login",
+    LOGIN_OF_OTHER_USER = "loginUsers",
     UPDATE_ACCOUNT = "UpdateAccount",
-    UNAUTHORIZED = "unauthorized"
+    UNAUTHORIZED = "unauthorized",
+
+    // ERROR
+    ERROR = "systemError",
+    // Group / Chats
+    GROUP_CREATED = "groupCreated",
+    NEW_PUBLIC_CHAT = "newPublicChatCreated",
+    NEW_CHAT = "newChatCreated"
 }
\ No newline at end of file
diff --git a/src/routes/group.ts b/src/routes/group.ts
new file mode 100644
index 0000000..cde3ab3
--- /dev/null
+++ b/src/routes/group.ts
@@ -0,0 +1,11 @@
+import { Router } from "express";
+import GroupsController from "../controllers/GroupsController";
+import { emptySchema } from "./validations";
+import { verifyToken } from "../helpers/verifyToken";
+
+const groups = Router();
+
+groups.get("/get_all", verifyToken, emptySchema, GroupsController.getAll);
+
+
+export default groups;
diff --git a/src/routes/index.ts b/src/routes/index.ts
index 48c7dd9..4933a71 100644
--- a/src/routes/index.ts
+++ b/src/routes/index.ts
@@ -3,9 +3,11 @@ import { Router } from "express";
 import admins from "./admins";
 import auth from "./auth"
 import users from "./users"
+import groups from "./group"
 const router = Router();
 
 router.use("/api/admins", admins);
+router.use("/api/groups", groups)
 router.use("/api/auth", auth);
 router.use("/api/users", users)
 
diff --git a/src/services/auth.ts b/src/services/auth.ts
index c49e98f..173eaa5 100644
--- a/src/services/auth.ts
+++ b/src/services/auth.ts
@@ -83,13 +83,13 @@ export default class UserService {
       jti: session.jti,
     };
     const token = await jwtr.sign(JWTData, process.env.JWT_KEY!, {
-      expiresIn: "1m",
+      expiresIn: "15m",
     });
     sessionQueue.add(
       { jti: session.jti },
       // the same time as refresh token in millis
       {
-        delay: 1000 * 60 , // 1h
+        delay: 1000 * 60 * 15 , // 1h
       }
     );
 
diff --git a/src/services/groups.ts b/src/services/groups.ts
new file mode 100644
index 0000000..88fd67a
--- /dev/null
+++ b/src/services/groups.ts
@@ -0,0 +1,58 @@
+import {
+  createQueryBuilder,
+  getRepository,
+  Repository,
+  SelectQueryBuilder,
+} from "typeorm";
+import { Group } from "../entity";
+import { IResponse, IGetGroups } from "../interfaces";
+
+export default class UserService {
+  public static getAll = async (
+    uuid: string
+  ): Promise<IResponse<IGetGroups>> => {
+    const groupRepository: Repository<Group> = getRepository(Group);
+
+    // TODO Find a better solution
+    const privateGroups: SelectQueryBuilder<Group> = groupRepository
+      .createQueryBuilder("group")
+      .innerJoinAndSelect("group.users", "users", "users.uuid = :uuid", {
+        uuid,
+      })
+      .innerJoinAndSelect("group.users", "user")
+      .where("group.private = :private", { private: true });
+
+    const publicUserGroups: SelectQueryBuilder<Group> = groupRepository
+      .createQueryBuilder("group")
+      .innerJoinAndSelect("group.users", "users", "users.uuid = :uuid", {
+        uuid,
+      })
+      .innerJoinAndSelect("group.users", "user")
+      .where("group.private = :private", { private: false });
+
+    const publicGroups: SelectQueryBuilder<Group> = groupRepository
+      .createQueryBuilder("group")
+      .innerJoinAndSelect("group.users", "users", "users.uuid != :uuid", {
+        uuid,
+      })
+      .innerJoinAndSelect("group.users", "user")
+      .where("group.private = :private", { private: false });
+
+    // console.log(privateGroups.getQuery())
+
+    const groupsPr = await privateGroups.getMany();
+    const groupsPubUser = await publicUserGroups.getMany();
+    const groupsPub = await publicGroups.getMany();
+
+    if (groupsPr === undefined) {
+      return { error: { code: 404, msg: "No Records" } };
+    }
+    return {
+      result: {
+        privateGroups: groupsPr,
+        publicGroupsWithUser: groupsPubUser,
+        publicGroups: groupsPub,
+      },
+    };
+  };
+}
diff --git a/src/socket.ts b/src/socket.ts
index ef9a53d..f21a7f4 100644
--- a/src/socket.ts
+++ b/src/socket.ts
@@ -34,14 +34,11 @@ export class SocketService {
       } else {
         socket.decoded = EMITS.UNAUTHORIZED;
         next();
-        // next(new Error("Authentication error"));
-        // return socket.disconnect(true);
       }
     });
     this.io.on("connection", async (socket) => {
       // jwt payload of the connected client
       // tslint:disable-next-line
-      //   console.log(socket.decoded);
       if (socket.decoded === EMITS.UNAUTHORIZED) {
         socket.emit(EMITS.UNAUTHORIZED, `LOGOUT`);
       } else {
@@ -61,14 +58,12 @@ export class SocketService {
           // tslint:disable-next-line
           console.log("user not found");
         }
-        // tslint:disable-next-line
-        //   console.log(user);
         socket.emit(EMITS.LOGIN, `Hi ${user.username}`);
-        socket.broadcast.emit(EMITS.LOGIN, user.username);
+        // socket.broadcast.emit(EMITS.LOGIN_OF_OTHER_USER, user.username); // TODO CHECK WHY IT CAUSES RERENDERS
         socket.join(user.username);
 
         // Group Created
-        socket.on("groupCreated", async (data) => {
+        socket.on(EMITS.GROUP_CREATED, async (data) => {
           if (user.username) {
             console.log(data);
             // data.user = user;
@@ -83,16 +78,16 @@ export class SocketService {
               await groupRepository.save(group);
             } catch (e) {
               // console.log(e.message);
-              return socket.emit("savingGroupError", "Couldn't Save Group");
+              return socket.emit(EMITS.ERROR, "Couldn't Save Group");
             }
 
             if (!data.private) {
-              socket.broadcast.emit("newPublicChatCreated", group);
+              socket.broadcast.emit(EMITS.NEW_PUBLIC_CHAT, group);
             } else {
               data.users.forEach(async (userInData) => {
                 socket
                   .to(userInData)
-                  .emit("newChatWasCreated", "you was added to new group");
+                  .emit(EMITS.NEW_CHAT, "you was added to new group");
                 const userInGroup: ChatUser = await userRepository.findOne({
                   where: { username: userInData },
                 });