diff --git a/packages/plugins/@nocobase/plugin-acl/src/server/__tests__/list-action.test.ts b/packages/plugins/@nocobase/plugin-acl/src/server/__tests__/list-action.test.ts index 8c34b7cd66..17a9759c5c 100644 --- a/packages/plugins/@nocobase/plugin-acl/src/server/__tests__/list-action.test.ts +++ b/packages/plugins/@nocobase/plugin-acl/src/server/__tests__/list-action.test.ts @@ -230,6 +230,78 @@ describe('list action with acl', () => { expect(data.meta.allowedActions.destroy).toEqual([]); }); + it('should list items meta permissions by m2m association field', async () => { + const userRole = app.acl.define({ + role: 'user', + }); + + const Tag = app.db.collection({ + name: 'tags', + fields: [{ type: 'string', name: 'name' }], + }); + + app.db.extendCollection({ + name: 'posts', + fields: [ + { + type: 'belongsToMany', + name: 'tags', + through: 'posts_tags', + }, + ], + }); + await app.db.sync(); + + await Tag.repository.create({ + values: [{ name: 'a' }, { name: 'b' }, { name: 'c' }], + }); + await Post.repository.create({ + values: [ + { title: 'p1', tags: [1, 2] }, + { title: 'p2', tags: [1, 3] }, + { title: 'p3', tags: [2, 3] }, + ], + }); + + userRole.grantAction('posts:view', {}); + + userRole.grantAction('posts:update', { + filter: { + $and: [ + { + tags: { + name: { + $includes: 'c', + }, + }, + }, + ], + }, + }); + + app.resourcer.use( + (ctx, next) => { + ctx.state.currentRole = 'user'; + ctx.state.currentUser = { + id: 1, + tag: 'c', + }; + + return next(); + }, + { + before: 'acl', + after: 'auth', + }, + ); + + const response = await (app as any).agent().set('X-With-ACL-Meta', true).resource('posts').list(); + const data = response.body; + expect(data.meta.allowedActions.view).toEqual([1, 2, 3]); + expect(data.meta.allowedActions.update).toEqual([2, 3]); + expect(data.meta.allowedActions.destroy).toEqual([]); + }); + it('should list items with meta permission', async () => { const userRole = app.acl.define({ role: 'user', diff --git a/packages/plugins/@nocobase/plugin-acl/src/server/middlewares/with-acl-meta.ts b/packages/plugins/@nocobase/plugin-acl/src/server/middlewares/with-acl-meta.ts index 11e2411689..ed3ac6d2b7 100644 --- a/packages/plugins/@nocobase/plugin-acl/src/server/middlewares/with-acl-meta.ts +++ b/packages/plugins/@nocobase/plugin-acl/src/server/middlewares/with-acl-meta.ts @@ -265,6 +265,7 @@ function createWithACLMetaMiddleware() { }), ], include: conditions.map((condition) => condition.include).flat(), + raw: true, }); const allowedActions = inspectActions @@ -273,7 +274,9 @@ function createWithACLMetaMiddleware() { return [action, ids]; } - return [action, results.filter((item) => Boolean(item.get(action))).map((item) => item.get(primaryKeyField))]; + let actionIds = results.filter((item) => Boolean(item[action])).map((item) => item[primaryKeyField]); + actionIds = Array.from(new Set(actionIds)); + return [action, actionIds]; }) .reduce((acc, [action, ids]) => { acc[action] = ids;