Merge pull request #18942 from RocketChat/release-3.6.2

Release 3.6.2
pull/18905/head^2 3.6.2
Diego Sampaio 5 years ago committed by GitHub
commit 7301fc4f6c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      .docker/Dockerfile.rhel
  2. 79
      .github/history.json
  3. 2
      .snapcraft/resources/prepareRocketChat
  4. 2
      .snapcraft/snap/snapcraft.yaml
  5. 42
      HISTORY.md
  6. 11
      app/api/server/v1/users.js
  7. 12
      app/lib/server/startup/oAuthServicesUpdate.js
  8. 2
      app/utils/rocketchat.info
  9. 4
      app/version-check/server/index.js
  10. 2
      client/channel/hooks/useUserInfoActions.js
  11. 14
      client/components/CustomFieldsForm.js
  12. 4
      imports/message-read-receipt/server/hooks.js
  13. 2
      package-lock.json
  14. 2
      package.json
  15. 7
      tests/data/rooms.helper.js
  16. 579
      tests/end-to-end/api/01-users.js

@ -1,6 +1,6 @@
FROM registry.access.redhat.com/rhscl/nodejs-8-rhel7
ENV RC_VERSION 3.6.1
ENV RC_VERSION 3.6.2
MAINTAINER buildmaster@rocket.chat

@ -49264,6 +49264,85 @@
]
}
]
},
"3.6.2": {
"node_version": "12.16.1",
"npm_version": "6.14.0",
"apps_engine_version": "1.17.0",
"mongo_versions": [
"3.4",
"3.6",
"4.0"
],
"pull_requests": [
{
"pr": "18794",
"title": "[FIX] Show custom fields of invalid type",
"userLogin": "gabriellsh",
"milestone": "3.6.2",
"contributors": [
"gabriellsh"
]
},
{
"pr": "18864",
"title": "[FIX] Deactivate users that are the last owner of a room using REST API",
"userLogin": "FelipeParreira",
"description": "Allow for user deactivation through REST API (even if user is the last owner of a room)",
"milestone": "3.6.2",
"contributors": [
"FelipeParreira",
"sampaiodiego",
"web-flow"
]
},
{
"pr": "18866",
"title": "[FIX] Ignore User action from user card",
"userLogin": "pierre-lehnen-rc",
"milestone": "3.6.2",
"contributors": [
"pierre-lehnen-rc"
]
},
{
"pr": "18916",
"title": "[FIX] Version update check cron job",
"userLogin": "wreiske",
"milestone": "3.6.2",
"contributors": [
"wreiske"
]
},
{
"pr": "18918",
"title": "[FIX] Read receipts showing blank names and not marking messages as read",
"userLogin": "wreiske",
"milestone": "3.6.2",
"contributors": [
"wreiske"
]
},
{
"pr": "17377",
"title": "[FIX] Create Custom OAuth services from environment variables",
"userLogin": "mrtndwrd",
"milestone": "3.6.2",
"contributors": [
"mrtndwrd",
"web-flow"
]
},
{
"pr": "18919",
"title": "[FIX] invite-all-from and invite-all-to commands don't work with multibyte room names",
"userLogin": "FelipeParreira",
"description": "Fix slash commands (invite-all-from and invite-all-to) to accept multi-byte room names.",
"contributors": [
"FelipeParreira"
]
}
]
}
}
}

@ -1,6 +1,6 @@
#!/bin/bash
curl -SLf "https://releases.rocket.chat/3.6.1/download/" -o rocket.chat.tgz
curl -SLf "https://releases.rocket.chat/3.6.2/download/" -o rocket.chat.tgz
tar xf rocket.chat.tgz --strip 1

@ -7,7 +7,7 @@
# 5. `snapcraft snap`
name: rocketchat-server
version: 3.6.1
version: 3.6.2
summary: Rocket.Chat server
description: Have your own Slack like online chat, built with Meteor. https://rocket.chat/
confinement: strict

@ -1,4 +1,46 @@
# 3.6.2
`2020-09-17 · 7 🐛 · 6 👩💻👨💻`
### Engine versions
- Node: `12.16.1`
- NPM: `6.14.0`
- MongoDB: `3.4, 3.6, 4.0`
- Apps-Engine: `1.17.0`
### 🐛 Bug fixes
- Create Custom OAuth services from environment variables ([#17377](https://github.com/RocketChat/Rocket.Chat/pull/17377) by [@mrtndwrd](https://github.com/mrtndwrd))
- Deactivate users that are the last owner of a room using REST API ([#18864](https://github.com/RocketChat/Rocket.Chat/pull/18864))
Allow for user deactivation through REST API (even if user is the last owner of a room)
- Ignore User action from user card ([#18866](https://github.com/RocketChat/Rocket.Chat/pull/18866))
- invite-all-from and invite-all-to commands don't work with multibyte room names ([#18919](https://github.com/RocketChat/Rocket.Chat/pull/18919))
Fix slash commands (invite-all-from and invite-all-to) to accept multi-byte room names.
- Read receipts showing blank names and not marking messages as read ([#18918](https://github.com/RocketChat/Rocket.Chat/pull/18918) by [@wreiske](https://github.com/wreiske))
- Show custom fields of invalid type ([#18794](https://github.com/RocketChat/Rocket.Chat/pull/18794))
- Version update check cron job ([#18916](https://github.com/RocketChat/Rocket.Chat/pull/18916) by [@wreiske](https://github.com/wreiske))
### 👩💻👨💻 Contributors 😍
- [@mrtndwrd](https://github.com/mrtndwrd)
- [@wreiske](https://github.com/wreiske)
### 👩💻👨💻 Core Team 🤓
- [@FelipeParreira](https://github.com/FelipeParreira)
- [@gabriellsh](https://github.com/gabriellsh)
- [@pierre-lehnen-rc](https://github.com/pierre-lehnen-rc)
- [@sampaiodiego](https://github.com/sampaiodiego)
# 3.6.1
`2020-09-11 · 7 🐛 · 3 👩💻👨💻`

@ -98,8 +98,10 @@ API.v1.addRoute('users.deleteOwnAccount', { authRequired: true }, {
throw new Meteor.Error('error-not-allowed', 'Not allowed');
}
const { confirmRelinquish = false } = this.requestParams();
Meteor.runAsUser(this.userId, () => {
Meteor.call('deleteUserOwnAccount', password);
Meteor.call('deleteUserOwnAccount', password, confirmRelinquish);
});
return API.v1.success();
@ -133,7 +135,8 @@ API.v1.addRoute('users.setActiveStatus', { authRequired: true }, {
}
Meteor.runAsUser(this.userId, () => {
Meteor.call('setUserActiveStatus', this.bodyParams.userId, this.bodyParams.activeStatus, this.bodyParams.confirmRelinquish);
const { userId, activeStatus, confirmRelinquish = false } = this.bodyParams;
Meteor.call('setUserActiveStatus', userId, activeStatus, confirmRelinquish);
});
return API.v1.success({ user: Users.findOneById(this.bodyParams.userId, { fields: { active: 1 } }) });
},
@ -463,8 +466,10 @@ API.v1.addRoute('users.update', { authRequired: true, twoFactorRequired: true },
}
if (typeof this.bodyParams.data.active !== 'undefined') {
const { userId, data: { active }, confirmRelinquish = false } = this.bodyParams;
Meteor.runAsUser(this.userId, () => {
Meteor.call('setUserActiveStatus', this.bodyParams.userId, this.bodyParams.data.active);
Meteor.call('setUserActiveStatus', userId, active, confirmRelinquish);
});
}
const { fields } = this.parseJsonQuery();

@ -132,3 +132,15 @@ settings.get(/^Accounts_OAuth_Custom-[a-z0-9_]+/, function(key, value) {
return OAuthServicesRemove(key);// eslint-disable-line new-cap
}
});
function customOAuthServicesInit() {
// Add settings for custom OAuth providers to the settings so they get
// automatically added when they are defined in ENV variables
Object.keys(process.env).forEach((key) => {
if (/Accounts_OAuth_Custom-[a-zA-Z0-9_-]+$/.test(key)) {
settings.add(key, process.env[key]);
}
});
}
customOAuthServicesInit();

@ -1,3 +1,3 @@
{
"version": "3.6.1"
"version": "3.6.2"
}

@ -13,7 +13,7 @@ if (SyncedCron.nextScheduledAtDate(jobName)) {
SyncedCron.remove(jobName);
}
const addVersionCheckJob = () => {
const addVersionCheckJob = Meteor.bindEnvironment(() => {
SyncedCron.add({
name: jobName,
schedule: (parser) => parser.text('at 2:00 am'),
@ -21,7 +21,7 @@ const addVersionCheckJob = () => {
checkVersionUpdate();
},
});
};
});
Meteor.startup(() => {

@ -234,7 +234,7 @@ export const useUserInfoActions = (user = {}, rid) => {
const ignoreUser = useMethod('ignoreUser');
const ignoreUserAction = useMutableCallback(async () => {
try {
await ignoreUser({ rid, ignoredUser: uid, ignore: !isIgnored });
await ignoreUser({ rid, userId: uid, ignore: !isIgnored });
dispatchToastMessage({ type: 'success', message: t('User_has_been_unignored') });
} catch (error) {
dispatchToastMessage({ type: 'error', message: error });

@ -46,15 +46,21 @@ const CustomFieldsAssembler = ({ formValues, formHandlers, customFields, ...prop
state: formValues[key],
...value,
};
return value.type === 'text'
? <CustomTextInput {...extraProps} {...props}/>
: <CustomSelect {...extraProps} {...props}/>;
if (value.type === 'select') {
return <CustomSelect {...extraProps} {...props}/>;
}
if (value.type === 'text') {
return <CustomTextInput {...extraProps} {...props}/>;
}
return null;
});
export default function CustomFieldsForm({ customFieldsData, setCustomFieldsData, onLoadFields = () => {}, ...props }) {
const customFieldsJson = useSetting('Accounts_CustomFields');
// TODO: add deps. Left this way so that a possible change in the setting can't crash the page (useForm generates states automatically)
const [customFields] = useState(() => {
try {
return JSON.parse(customFieldsJson || '{}');

@ -19,6 +19,6 @@ callbacks.add('afterSaveMessage', (message, room) => {
return message;
}, callbacks.priority.MEDIUM, 'message-read-receipt-afterSaveMessage');
callbacks.add('afterReadMessages', (rid, { userId, lastSeen }) => {
ReadReceipt.markMessagesAsRead(rid, userId, lastSeen);
callbacks.add('afterReadMessages', (rid, { uid, lastSeen }) => {
ReadReceipt.markMessagesAsRead(rid, uid, lastSeen);
}, callbacks.priority.MEDIUM, 'message-read-receipt-afterReadMessages');

2
package-lock.json generated

@ -1,6 +1,6 @@
{
"name": "Rocket.Chat",
"version": "3.6.1",
"version": "3.6.2",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

@ -1,7 +1,7 @@
{
"name": "Rocket.Chat",
"description": "The Ultimate Open Source WebChat Platform",
"version": "3.6.1",
"version": "3.6.2",
"author": {
"name": "Rocket.Chat",
"url": "https://rocket.chat/"

@ -1,6 +1,6 @@
import { api, credentials, request } from './api-data';
export const createRoom = ({ name, type, username }) => {
export const createRoom = ({ name, type, username, members = [] }) => {
if (!type) {
throw new Error('"type" is required in "createRoom" test helper');
}
@ -18,7 +18,10 @@ export const createRoom = ({ name, type, username }) => {
return request.post(api(endpoints[type]))
.set(credentials)
.send(params);
.send({
...params,
members,
});
};
export const closeRoom = ({ type, roomId }) => {

@ -18,6 +18,7 @@ import { imgURL } from '../../data/interactions.js';
import { customFieldText, clearCustomFields, setCustomFields } from '../../data/custom-fields.js';
import { updatePermission, updateSetting } from '../../data/permissions.helper';
import { createUser, login, deleteUser, getUserStatus } from '../../data/users.helper.js';
import { createRoom } from '../../data/rooms.helper';
describe('[Users]', function() {
this.retries(0);
@ -1324,6 +1325,165 @@ describe('[Users]', function() {
});
});
});
it('should return an error when trying to delete user own account if user is the last room owner', async () => {
const user = await createUser();
const createdUserCredentials = await login(user.username, password);
const room = (await createRoom({
type: 'c',
name: `channel.test.${ Date.now() }-${ Math.random() }`,
username: user.username,
members: [user.username],
})).body.channel;
await request.post(api('channels.addOwner'))
.set(credentials)
.send({
userId: user._id,
roomId: room._id,
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
});
await request.post(api('channels.removeOwner'))
.set(credentials)
.send({
userId: credentials['X-User-Id'],
roomId: room._id,
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
});
await request
.post(api('users.deleteOwnAccount'))
.set(createdUserCredentials)
.send({
password: crypto.createHash('sha256').update(password, 'utf8').digest('hex'),
})
.expect('Content-Type', 'application/json')
.expect(400)
.expect((res) => {
expect(res.body).to.have.property('success', false);
expect(res.body).to.have.property('error', '[user-last-owner]');
expect(res.body).to.have.property('errorType', 'user-last-owner');
});
});
it('should delete user own account if the user is the last room owner and `confirmRelinquish` is set to `true`', async () => {
const user = await createUser();
const createdUserCredentials = await login(user.username, password);
const room = (await createRoom({
type: 'c',
name: `channel.test.${ Date.now() }-${ Math.random() }`,
username: user.username,
members: [user.username],
})).body.channel;
await request.post(api('channels.addOwner'))
.set(credentials)
.send({
userId: user._id,
roomId: room._id,
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
});
await request.post(api('channels.removeOwner'))
.set(credentials)
.send({
userId: credentials['X-User-Id'],
roomId: room._id,
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
});
await request
.post(api('users.deleteOwnAccount'))
.set(createdUserCredentials)
.send({
password: crypto.createHash('sha256').update(password, 'utf8').digest('hex'),
confirmRelinquish: true,
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
});
});
it('should assign a new owner to the room if the last room owner is deleted', async () => {
const user = await createUser();
const createdUserCredentials = await login(user.username, password);
const room = (await createRoom({
type: 'c',
name: `channel.test.${ Date.now() }-${ Math.random() }`,
username: user.username,
members: [user.username],
})).body.channel;
await request.post(api('channels.addOwner'))
.set(credentials)
.send({
userId: user._id,
roomId: room._id,
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
});
await request.post(api('channels.removeOwner'))
.set(credentials)
.send({
userId: credentials['X-User-Id'],
roomId: room._id,
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
});
await request
.post(api('users.deleteOwnAccount'))
.set(createdUserCredentials)
.send({
password: crypto.createHash('sha256').update(password, 'utf8').digest('hex'),
confirmRelinquish: true,
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
});
await request.get(api('channels.roles'))
.set(credentials)
.query({
roomId: room._id,
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
expect(res.body.roles).to.have.lengthOf(1);
expect(res.body.roles[0].roles).to.eql(['owner']);
expect(res.body.roles[0].u).to.have.property('_id', credentials['X-User-Id']);
});
});
});
describe('[/users.delete]', () => {
@ -1340,7 +1500,7 @@ describe('[Users]', function() {
});
const testUsername = `testuserdelete${ +new Date() }`;
let targetUser;
it('register a new user...', (done) => {
beforeEach((done) => {
request.post(api('users.register'))
.set(credentials)
.send({
@ -1353,40 +1513,196 @@ describe('[Users]', function() {
.expect(200)
.expect((res) => {
targetUser = res.body.user;
}).end(done);
});
afterEach((done) => {
updatePermission('delete-user', ['admin']).then(() => {
request.post(api('users.delete'))
.set(credentials)
.send({
userId: targetUser._id,
confirmRelinquish: true,
}).end(done);
});
});
it('should return an error when trying delete user account without "delete-user" permission', async () => {
await updatePermission('delete-user', ['user']);
await request.post(api('users.delete'))
.set(credentials)
.send({
userId: targetUser._id,
})
.end(done);
.expect('Content-Type', 'application/json')
.expect(403)
.expect((res) => {
expect(res.body).to.have.property('success', false);
expect(res.body).to.have.property('error', 'unauthorized');
});
});
it('should return an error when trying delete user account without "delete-user" permission', (done) => {
updatePermission('delete-user', ['user'])
.then(() => {
request.post(api('users.delete'))
.set(credentials)
.send({
userId: targetUser._id,
})
.expect('Content-Type', 'application/json')
.expect(403)
.expect((res) => {
expect(res.body).to.have.property('success', false);
expect(res.body).to.have.property('error', 'unauthorized');
})
.end(done);
it('should return an error when trying to delete user account if the user is the last room owner', async () => {
await updatePermission('delete-user', ['admin']);
const room = (await createRoom({
type: 'c',
name: `channel.test.${ Date.now() }-${ Math.random() }`,
members: [targetUser.username],
})).body.channel;
await request.post(api('channels.addOwner'))
.set(credentials)
.send({
userId: targetUser._id,
roomId: room._id,
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
});
await request.post(api('channels.removeOwner'))
.set(credentials)
.send({
userId: credentials['X-User-Id'],
roomId: room._id,
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
});
await request.post(api('users.delete'))
.set(credentials)
.send({
userId: targetUser._id,
})
.expect('Content-Type', 'application/json')
.expect(400)
.expect((res) => {
expect(res.body).to.have.property('success', false);
expect(res.body).to.have.property('error', '[user-last-owner]');
expect(res.body).to.have.property('errorType', 'user-last-owner');
});
});
it('should delete user account when logged user has "delete-user" permission', (done) => {
updatePermission('delete-user', ['admin'])
.then(() => {
request.post(api('users.delete'))
.set(credentials)
.send({
userId: targetUser._id,
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
})
.end(done);
it('should delete user account if the user is the last room owner and `confirmRelinquish` is set to `true`', async () => {
await updatePermission('delete-user', ['admin']);
const room = (await createRoom({
type: 'c',
name: `channel.test.${ Date.now() }-${ Math.random() }`,
members: [targetUser.username],
})).body.channel;
await request.post(api('channels.addOwner'))
.set(credentials)
.send({
userId: targetUser._id,
roomId: room._id,
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
});
await request.post(api('channels.removeOwner'))
.set(credentials)
.send({
userId: credentials['X-User-Id'],
roomId: room._id,
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
});
await request.post(api('users.delete'))
.set(credentials)
.send({
userId: targetUser._id,
confirmRelinquish: true,
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
});
});
it('should delete user account when logged user has "delete-user" permission', async () => {
await updatePermission('delete-user', ['admin']);
await request.post(api('users.delete'))
.set(credentials)
.send({
userId: targetUser._id,
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
});
});
it('should assign a new owner to the room if the last room owner is deleted', async () => {
await updatePermission('delete-user', ['admin']);
const room = (await createRoom({
type: 'c',
name: `channel.test.${ Date.now() }-${ Math.random() }`,
members: [targetUser.username],
})).body.channel;
await request.post(api('channels.addOwner'))
.set(credentials)
.send({
userId: targetUser._id,
roomId: room._id,
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
});
await request.post(api('channels.removeOwner'))
.set(credentials)
.send({
userId: credentials['X-User-Id'],
roomId: room._id,
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
});
await request.post(api('users.delete'))
.set(credentials)
.send({
userId: targetUser._id,
confirmRelinquish: true,
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
});
await request.get(api('channels.roles'))
.set(credentials)
.query({
roomId: room._id,
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
expect(res.body.roles).to.have.lengthOf(1);
expect(res.body.roles[0].roles).to.eql(['owner']);
expect(res.body.roles[0].u).to.have.property('_id', credentials['X-User-Id']);
});
});
});
@ -1650,6 +1966,207 @@ describe('[Users]', function() {
})
.end(done);
});
it('should return an error when trying to set other user status to inactive and the user is the last owner of a room', async () => {
const room = (await createRoom({
type: 'c',
name: `channel.test.${ Date.now() }-${ Math.random() }`,
username: targetUser.username,
members: [targetUser.username],
})).body.channel;
await request.post(api('channels.invite'))
.set(credentials)
.send({
userId: targetUser._id,
roomId: room._id,
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
});
await request.post(api('channels.addOwner'))
.set(credentials)
.send({
userId: targetUser._id,
roomId: room._id,
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
});
await request.post(api('channels.removeOwner'))
.set(credentials)
.send({
userId: credentials['X-User-Id'],
roomId: room._id,
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
});
await request.post(api('users.setActiveStatus'))
.set(userCredentials)
.send({
activeStatus: false,
userId: targetUser._id,
})
.expect('Content-Type', 'application/json')
.expect(400)
.expect((res) => {
expect(res.body).to.have.property('success', false);
expect(res.body).to.have.property('error', '[user-last-owner]');
expect(res.body).to.have.property('errorType', 'user-last-owner');
});
});
it('should set other user status to inactive if the user is the last owner of a room and `confirmRelinquish` is set to `true`', async () => {
const room = (await createRoom({
type: 'c',
name: `channel.test.${ Date.now() }-${ Math.random() }`,
username: targetUser.username,
members: [targetUser.username],
})).body.channel;
await request.post(api('channels.invite'))
.set(credentials)
.send({
userId: targetUser._id,
roomId: room._id,
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
});
await request.post(api('channels.addOwner'))
.set(credentials)
.send({
userId: targetUser._id,
roomId: room._id,
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
});
await request.post(api('channels.removeOwner'))
.set(credentials)
.send({
userId: credentials['X-User-Id'],
roomId: room._id,
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
});
await request.post(api('users.setActiveStatus'))
.set(userCredentials)
.send({
activeStatus: false,
userId: targetUser._id,
confirmRelinquish: true,
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
});
});
it('should set other user as room owner if the last owner of a room is deactivated and `confirmRelinquish` is set to `true`', async () => {
const room = (await createRoom({
type: 'c',
name: `channel.test.${ Date.now() }-${ Math.random() }`,
members: [targetUser.username],
})).body.channel;
await request.post(api('users.setActiveStatus'))
.set(userCredentials)
.send({
activeStatus: true,
userId: targetUser._id,
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
});
await request.post(api('channels.invite'))
.set(credentials)
.send({
userId: targetUser._id,
roomId: room._id,
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
});
await request.post(api('channels.addOwner'))
.set(credentials)
.send({
userId: targetUser._id,
roomId: room._id,
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
});
await request.post(api('channels.removeOwner'))
.set(credentials)
.send({
userId: credentials['X-User-Id'],
roomId: room._id,
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
});
await request.post(api('users.setActiveStatus'))
.set(userCredentials)
.send({
activeStatus: false,
userId: targetUser._id,
confirmRelinquish: true,
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
});
await request.get(api('channels.roles'))
.set(credentials)
.query({
roomId: room._id,
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
expect(res.body.roles).to.have.lengthOf(2);
expect(res.body.roles[1].roles).to.eql(['owner']);
expect(res.body.roles[1].u).to.have.property('_id', credentials['X-User-Id']);
});
});
it('should return an error when trying to set other user active status and has not the necessary permission(edit-other-user-active-status)', (done) => {
updatePermission('edit-other-user-active-status', []).then(() => {
request.post(api('users.setActiveStatus'))

Loading…
Cancel
Save