Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FIX] Users without the view-other-user-info permission can't use the users.list endpoint #26050

Merged
merged 9 commits into from
Jul 18, 2022
26 changes: 9 additions & 17 deletions apps/meteor/app/api/server/lib/users.ts
Original file line number Diff line number Diff line change
@@ -2,6 +2,7 @@ import { escapeRegExp } from '@rocket.chat/string-helpers';
import { IUser } from '@rocket.chat/core-typings';
import { Filter } from 'mongodb';
import { Users } from '@rocket.chat/models';
import type { Mongo } from 'meteor/mongo';

import { hasPermissionAsync } from '../../../authorization/server/functions/hasPermission';

@@ -80,6 +81,7 @@ export function getNonEmptyFields(fields: { [k: string]: 1 | 0 }): { [k: string]
active: 1,
avatarETag: 1,
lastLogin: 1,
type: 1,
} as const;

if (!fields || Object.keys(fields).length === 0) {
@@ -89,29 +91,19 @@ export function getNonEmptyFields(fields: { [k: string]: 1 | 0 }): { [k: string]
return { ...defaultFields, ...fields };
}

const _defaultQuery = {
$or: [
{ 'emails.address': { $regex: '', $options: 'i' } },
{ username: { $regex: '', $options: 'i' } },
{ name: { $regex: '', $options: 'i' } },
],
};

/**
* get the default query if **query** is empty (`{}`) or `undefined`/`null`
* @param {Object|null|undefined} query the query from parsed jsonQuery
*/

type Query = { [k: string]: unknown };
export function getNonEmptyQuery(query: Query): typeof _defaultQuery | (typeof _defaultQuery & Query) {
const defaultQuery = {
$or: [
{ 'emails.address': { $regex: '', $options: 'i' } },
{ username: { $regex: '', $options: 'i' } },
{ name: { $regex: '', $options: 'i' } },
],
export function getNonEmptyQuery<T extends IUser>(query: Mongo.Query<T> | undefined | null, canSeeAllUserInfo?: boolean): Mongo.Query<T> {
const defaultQuery: Mongo.Query<IUser> = {
$or: [{ username: { $regex: '', $options: 'i' } }, { name: { $regex: '', $options: 'i' } }],
};

if (canSeeAllUserInfo) {
defaultQuery.$or?.push({ 'emails.address': { $regex: '', $options: 'i' } });
}

if (!query || Object.keys(query).length === 0) {
return defaultQuery;
}
3 changes: 2 additions & 1 deletion apps/meteor/app/api/server/v1/users.ts
Original file line number Diff line number Diff line change
@@ -398,7 +398,7 @@ API.v1.addRoute(
const { offset, count } = this.getPaginationItems();
const { sort, fields, query } = this.parseJsonQuery();

const nonEmptyQuery = getNonEmptyQuery(query);
const nonEmptyQuery = getNonEmptyQuery(query, hasPermission(this.userId, 'view-full-other-user-info'));
const nonEmptyFields = getNonEmptyFields(fields);

const inclusiveFields = getInclusiveFields(nonEmptyFields);
@@ -413,6 +413,7 @@ API.v1.addRoute(
inclusiveFieldsKeys.includes('emails') && 'emails.address.*',
inclusiveFieldsKeys.includes('username') && 'username.*',
inclusiveFieldsKeys.includes('name') && 'name.*',
inclusiveFieldsKeys.includes('type') && 'type.*',
].filter(Boolean) as string[],
this.queryOperations,
)