Skip to content

Commit cf47798

Browse files
authored
fix(members): allow users to fetch own email. Fixes HELP-2449 (#912)
Co-authored-by: WikiRik <[email protected]>
1 parent beb83dd commit cf47798

File tree

2 files changed

+32
-16
lines changed

2 files changed

+32
-16
lines changed

middlewares/members.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -92,20 +92,20 @@ exports.getUser = async (req, res) => {
9292
};
9393

9494
exports.getUsersEmail = async (req, res) => {
95-
if (!req.permissions.hasPermission('global:mail:member')) {
96-
return errors.makeForbiddenError(res, 'Permission global:mail:member is required, but not present.');
97-
}
95+
const correctQuery = req.query.query && typeof req.query.query === 'string' && req.query.query.trim().length > 0 && req.query.query.match(/^\d+(?:,\d+)*$/g);
9896

99-
if (req.query.query && !req.query.query.match(/^\d+(?:,\d+)*$/g)) {
97+
if (!correctQuery) {
10098
return errors.makeBadRequestError(res, 'Query should be a string of 1 id or multiple ids seperated by commas.');
10199
}
102100

103-
let where = {};
101+
const userIds = req.query.query.split(',');
104102

105-
if (typeof req.query.query === 'string' && req.query.query.trim().length > 0) {
106-
where = { id: { [Sequelize.Op.or]: req.query.query.split(',') } };
103+
if (!req.permissions.hasPermission('global:mail:member') && Number(userIds[0]) !== req.user.id) {
104+
return errors.makeForbiddenError(res, 'Permission global:mail:member is required, but not present.');
107105
}
108106

107+
const where = { id: { [Sequelize.Op.or]: userIds } };
108+
109109
const result = await User.findAndCountAll({
110110
where,
111111
attributes: ['id', 'email', 'gsuite_id', 'primary_email', 'notification_email']

test/api/users-email.test.js

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ describe('Users list', () => {
1515
await generator.clearAll();
1616
});
1717

18-
test('should fail if no permission', async () => {
18+
test('should fail without query', async () => {
1919
const user = await generator.createUser();
2020
const token = await generator.createAccessToken(user);
2121

@@ -25,20 +25,35 @@ describe('Users list', () => {
2525
headers: { 'X-Auth-Token': token.value }
2626
});
2727

28-
expect(res.statusCode).toEqual(403);
28+
expect(res.statusCode).toEqual(400);
2929
expect(res.body.success).toEqual(false);
3030
expect(res.body).toHaveProperty('message');
3131
expect(res.body).not.toHaveProperty('data');
3232
});
3333

34-
test('should succeed when everything is okay', async () => {
35-
const user = await generator.createUser({ superadmin: true });
34+
test('should fail if no permission', async () => {
35+
const user = await generator.createUser();
36+
const secondUser = await generator.createUser();
3637
const token = await generator.createAccessToken(user);
3738

38-
await generator.createPermission({ scope: 'global', action: 'mail', object: 'member' });
39+
const res = await request({
40+
uri: '/members_email?query=' + secondUser.id,
41+
method: 'GET',
42+
headers: { 'X-Auth-Token': token.value }
43+
});
44+
45+
expect(res.statusCode).toEqual(403);
46+
expect(res.body.success).toEqual(false);
47+
expect(res.body).toHaveProperty('message');
48+
expect(res.body).not.toHaveProperty('data');
49+
});
50+
51+
test('should find own by id without permission', async () => {
52+
const user = await generator.createUser();
53+
const token = await generator.createAccessToken(user);
3954

4055
const res = await request({
41-
uri: '/members_email',
56+
uri: '/members_email?query=' + user.id,
4257
method: 'GET',
4358
headers: { 'X-Auth-Token': token.value }
4459
});
@@ -54,12 +69,13 @@ describe('Users list', () => {
5469

5570
test('should find one by id', async () => {
5671
const user = await generator.createUser({ superadmin: true });
72+
const secondUser = await generator.createUser();
5773
const token = await generator.createAccessToken(user);
5874

5975
await generator.createPermission({ scope: 'global', action: 'mail', object: 'member' });
6076

6177
const res = await request({
62-
uri: '/members_email?query=' + user.id,
78+
uri: '/members_email?query=' + secondUser.id,
6379
method: 'GET',
6480
headers: { 'X-Auth-Token': token.value }
6581
});
@@ -70,7 +86,7 @@ describe('Users list', () => {
7086
expect(res.body).not.toHaveProperty('errors');
7187

7288
expect(res.body.data.length).toEqual(1);
73-
expect(res.body.data[0].id).toEqual(user.id);
89+
expect(res.body.data[0].id).toEqual(secondUser.id);
7490
});
7591

7692
test('should find multiple by id array', async () => {
@@ -121,7 +137,7 @@ describe('Users list', () => {
121137
await generator.createPermission({ scope: 'global', action: 'mail', object: 'member' });
122138

123139
const res = await request({
124-
uri: '/members_email',
140+
uri: '/members_email?query=' + user.id,
125141
method: 'GET',
126142
headers: { 'X-Auth-Token': token.value }
127143
});

0 commit comments

Comments
 (0)