add getUserIdsInRole and getUserIdsInRoleAsync methods with tests

This commit is contained in:
Christian Wahle
2025-11-30 15:46:32 +01:00
parent bcdd3d6da9
commit 7b4d9fea41
4 changed files with 85 additions and 0 deletions

View File

@@ -359,6 +359,31 @@ export declare namespace Roles {
queryOptions?: QueryOptions
): Promise<Mongo.Cursor<Meteor.User>>;
/**
* Retrieve all userIds who are in target role.
*
* Options:
*
* @method getUserIdsInRole
* @param {Array|String} roles Name of role or an array of roles. If array, users
* returned will have at least one of the roles
* specified but need not have _all_ roles.
* Roles do not have to exist.
* @param {Object|String} options Options:
* - `scope`: name of the scope to restrict roles to; user's global
* roles will also be checked
* - `anyScope`: if set, role can be in any scope (`scope` option is ignored)
* - `onlyScoped`: if set, only roles in the specified scope are returned
*/
function getUserIdsInRole(
roles: string | string[],
options?: string | { scope?: string; anyScope?: boolean; onlyScoped?: boolean }
): string[]
function getUserIdsInRoleAsync(
roles: string | string[],
options?: string | { scope?: string; anyScope?: boolean; onlyScoped?: boolean }
): Promise<string[]>;
/**
* Remove users from assigned roles.
*

View File

@@ -809,6 +809,27 @@ Object.assign(Roles, {
return Meteor.users.find({ _id: { $in: ids } }, ((options && options.queryOptions) || queryOptions) || {})
},
/**
* Retrieve all user IDs who are in target role.
*
* @method getUserIdsInRole
* @param {Array|String} roles Name of role or an array of roles. If array, users
* returned will have at least one of the roles
* specified but need not have _all_ roles.
* Roles do not have to exist.
* @param {Object|String} [options] Options:
* - `scope`: name of the scope to restrict roles to; user's global
* roles will also be checked
* - `anyScope`: if set, role can be in any scope (`scope` option is ignored)
* * @return {Array} Array of user IDs in roles.
* @static
*/
getUserIdsInRole: function (roles, options) {
const ids = Roles.getUserAssignmentsForRole(roles, options).fetch().map(a => a.user._id)
return ids
},
/**
* Retrieve all assignments of a user which are for the target role.
*

View File

@@ -1062,6 +1062,29 @@ Object.assign(Roles, {
)
},
/**
* Retrieve all userIds who are in target role.
*
* Options:
*
* @method getUserIdsInRoleAsync
* @param {Array|String} roles Name of role or an array of roles. If array, users
* returned will have at least one of the roles
* specified but need not have _all_ roles.
* Roles do not have to exist.
* @param {Object|String} [options] Options:
* - `scope`: name of the scope to restrict roles to; user's global
* roles will also be checked
* - `anyScope`: if set, role can be in any scope (`scope` option is ignored)
* @return {Promise<Array>} Array of user IDs in roles.
* @static
*/
getUserIdsInRoleAsync: async function (roles, options) {
const cursor = Roles.getUserAssignmentsForRole(roles, options)
return (await cursor.fetchAsync()).map((a) => a.user._id)
},
/**
* @summary Retrieve all assignments of a user which are for the target role.
* @memberof Roles

View File

@@ -1518,6 +1518,22 @@ Tinytest.addAsync("roles -can get all users in role", async function (test) {
sameMembers(test, actual, expected);
});
Tinytest.addAsync("roles - can get all userIds in role", async function (test) {
await clearData();
await Roles.createRoleAsync('admin');
await Roles.createRoleAsync('user');
await Roles.createRoleAsync('editor');
const ids = ['foo', 'bar', 'baz'];
await Roles.addUsersToRolesAsync([ids[0], ids[1]], ['admin', 'user']);
await Roles.addUsersToRolesAsync([ids[1], ids[2]], ['editor']);
const expected = [ids[0], ids[1]];
const userIds = await Roles.getUserIdsInRoleAsync('admin');
sameMembers(test, userIds, expected);
});
Tinytest.addAsync(
"roles -can get all users in role by scope",
async function (test) {