Преглед изворни кода

feat: add /group/list endpoint

KernelDeimos пре 10 месеци
родитељ
комит
d55f38ca68

+ 24 - 0
packages/backend/src/definitions/SimpleEntity.js

@@ -0,0 +1,24 @@
+const { Context } = require("../util/context");
+
+module.exports = function SimpleEntity ({ name, methods, fetchers }) {
+    const create = function (values) {
+        const entity = { values };
+        Object.assign(entity, methods);
+        for ( const fetcher_name in fetchers ) {
+            entity['fetch_' + fetcher_name] = async function () {
+                if ( this.values.hasOwnProperty(fetcher_name) ) {
+                    return this.values[fetcher_name];
+                }
+                const value = await fetchers[fetcher_name].call(this);
+                this.values[fetcher_name] = value;
+                return value;
+            }
+        }
+        entity.context = values.context ?? Context.get();
+        entity.services = entity.context.get('services');
+        return entity;
+    };
+
+    create.name = name;
+    return create;
+};

+ 23 - 0
packages/backend/src/entities/Group.js

@@ -0,0 +1,23 @@
+const SimpleEntity = require("../definitions/SimpleEntity");
+
+module.exports = SimpleEntity({
+    name: 'group',
+    fetchers: {
+        async members () {
+            const svc_group = this.services.get('group');
+            const members = await svc_group.list_members({ uid: this.values.uid });
+            return members;
+        }
+    },
+    methods: {
+        async get_client_value () {
+            await this.fetch_members();
+            const group = {
+                uid: this.values.uid,
+                metadata: this.values.metadata,
+                members: this.values.members,
+            };
+            return group;
+        }
+    }
+});

+ 24 - 0
packages/backend/src/services/PermissionAPIService.js

@@ -165,6 +165,30 @@ class PermissionAPIService extends BaseService {
                 res.json({});
                 res.json({});
             }
             }
         }).attach(router);
         }).attach(router);
+
+        Endpoint({
+            route: '/list',
+            methods: ['GET'],
+            mw: [configurable_auth()],
+            handler: async (req, res) => {
+                const svc_group = this.services.get('group');
+                
+                // TODO: validate string and uuid for request
+
+                const owned_groups = await svc_group.list_groups_with_owner(
+                    { owner_user_id: req.user.id });
+
+                const in_groups = await svc_group.list_groups_with_member(
+                    { user_id: req.user.id });
+
+                res.json({
+                    owned_groups: await Promise.all(owned_groups.map(
+                        g => g.get_client_value())),
+                    in_groups: await Promise.all(in_groups.map(
+                        g => g.get_client_value())),
+                });
+            }
+        }).attach(router);
     }
     }
 }
 }
 
 

+ 49 - 0
packages/backend/src/services/auth/GroupService.js

@@ -1,3 +1,4 @@
+const Group = require("../../entities/Group");
 const BaseService = require("../BaseService");
 const BaseService = require("../BaseService");
 const { DB_WRITE } = require("../database/consts");
 const { DB_WRITE } = require("../database/consts");
 
 
@@ -44,6 +45,54 @@ class GroupService extends BaseService {
         
         
         return uid;
         return uid;
     }
     }
+
+    async list_groups_with_owner ({ owner_user_id }) {
+        const groups = await this.db.read(
+            'SELECT * FROM `group` WHERE owner_user_id=?',
+            [owner_user_id],
+        );
+        for ( const group of groups ) {
+            group.extra = this.db.case({
+                mysql: () => group.extra,
+                otherwise: () => JSON.parse(group.extra),
+            })();
+            group.metadata = this.db.case({
+                mysql: () => group.metadata,
+                otherwise: () => JSON.parse(group.metadata),
+            })();
+        }
+        return groups.map(g => Group(g));
+    }
+
+    async list_groups_with_member ({ user_id }) {
+        const groups = await this.db.read(
+            'SELECT * FROM `group` WHERE id IN (' +
+                'SELECT group_id FROM `jct_user_group` WHERE user_id=?)',
+            [user_id],
+        );
+        for ( const group of groups ) {
+            group.extra = this.db.case({
+                mysql: () => group.extra,
+                otherwise: () => JSON.parse(group.extra),
+            })();
+            group.metadata = this.db.case({
+                mysql: () => group.metadata,
+                otherwise: () => JSON.parse(group.metadata),
+            })();
+        }
+        return groups.map(g => Group(g));
+    }
+
+    async list_members ({ uid }) {
+        const users = await this.db.read(
+            'SELECT u.username FROM user u ' +
+            'JOIN (SELECT user_id FROM `jct_user_group` WHERE group_id = ' +
+                '(SELECT id FROM `group` WHERE uid=?)) ug ' +
+            'ON u.id = ug.user_id',
+            [uid],
+        );
+        return users.map(u => u.username);
+    }
     
     
     async add_users ({ uid, users }) {
     async add_users ({ uid, users }) {
         const question_marks =
         const question_marks =