From 7aa3cb731255e5d3fc8d8a47a6109d9a43f96b91 Mon Sep 17 00:00:00 2001 From: KernelDeimos Date: Tue, 4 Mar 2025 16:43:23 -0500 Subject: [PATCH] dev: puter.js support for group management --- src/backend/src/entities/Group.js | 8 ++-- .../src/services/PermissionAPIService.js | 23 +++++++++-- src/backend/src/services/auth/GroupService.js | 39 +++++++++++++++++++ 3 files changed, 64 insertions(+), 6 deletions(-) diff --git a/src/backend/src/entities/Group.js b/src/backend/src/entities/Group.js index 9aabf5911..0e24f33a5 100644 --- a/src/backend/src/entities/Group.js +++ b/src/backend/src/entities/Group.js @@ -28,12 +28,14 @@ module.exports = SimpleEntity({ } }, methods: { - async get_client_value () { - await this.fetch_members(); + async get_client_value (options = {}) { + if ( options.members ) { + await this.fetch_members(); + } const group = { uid: this.values.uid, metadata: this.values.metadata, - members: this.values.members, + ...(options.members ? { members: this.values.members } : {}), }; return group; } diff --git a/src/backend/src/services/PermissionAPIService.js b/src/backend/src/services/PermissionAPIService.js index c838c2643..4b94bee2d 100644 --- a/src/backend/src/services/PermissionAPIService.js +++ b/src/backend/src/services/PermissionAPIService.js @@ -105,9 +105,10 @@ class PermissionAPIService extends BaseService { const svc_group = this.services.get('group'); const uid = await svc_group.create({ owner_user_id, - // TODO: allow specifying these in request + // TODO: includeslist for allowed 'extra' fields extra: {}, - metadata: {}, + // Metadata can be specified in request + metadata: metadata ?? {}, }); res.json({ uid }); @@ -228,14 +229,30 @@ class PermissionAPIService extends BaseService { const in_groups = await svc_group.list_groups_with_member( { user_id: req.user.id }); + const public_groups = await svc_group.list_public_groups(); + res.json({ owned_groups: await Promise.all(owned_groups.map( - g => g.get_client_value())), + g => g.get_client_value({ members: true }))), in_groups: await Promise.all(in_groups.map( + g => g.get_client_value({ members: true }))), + public_groups: await Promise.all(public_groups.map( g => g.get_client_value())), }); } }).attach(router); + + Endpoint({ + route: '/public-groups', + methods: ['GET'], + mw: [configurable_auth()], + handler: async (req, res) => { + res.json({ + user: this.global_config.default_user_group, + temp: this.global_config.default_temp_group, + }); + } + }).attach(router); } } diff --git a/src/backend/src/services/auth/GroupService.js b/src/backend/src/services/auth/GroupService.js index 9b7925bed..ef0759334 100644 --- a/src/backend/src/services/auth/GroupService.js +++ b/src/backend/src/services/auth/GroupService.js @@ -33,6 +33,7 @@ const { DB_WRITE } = require("../database/consts"); */ class GroupService extends BaseService { static MODULES = { + kv: globalThis.kv, uuidv4: require('uuid').v4, }; @@ -46,6 +47,7 @@ class GroupService extends BaseService { */ _init () { this.db = this.services.get('database').get(DB_WRITE, 'permissions'); + this.kvkey = this.modules.uuidv4(); const svc_anomaly = this.services.get('anomaly'); svc_anomaly.register('groups-user-hour', { @@ -189,6 +191,42 @@ class GroupService extends BaseService { } + /** + * Lists public groups. May get groups from kv.js cache. + */ + async list_public_groups () { + const public_group_uids = [ + this.global_config.default_user_group, + this.global_config.default_temp_group, + ]; + + let groups = this.modules.kv.get(`${this.kvkey}:public-groups`); + if ( groups ) { + return groups; + } + + groups = await this.db.read( + 'SELECT * FROM `group` WHERE uid IN (' + + public_group_uids.map(() => '?').join(', ') + + ')', + public_group_uids, + ); + 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), + })(); + } + groups = groups.map(g => Group(g)); + this.modules.kv.set(`${this.kvkey}:public-groups`, groups, 60); + return groups; + } + + /** * Lists the members of a group by their username. * @@ -206,6 +244,7 @@ class GroupService extends BaseService { ); return users.map(u => u.username); } + /**