[NEW] add delete-own-message permission (#15512)

pull/15699/head
Guilherme Gazzo 7 years ago committed by GitHub
parent 6c0e8d12ea
commit 04b4b9a8f4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 41
      app/authorization/server/functions/canDeleteMessage.js
  2. 1
      app/authorization/server/startup.js
  3. 40
      app/lib/server/methods/deleteMessage.js
  4. 1
      app/ui-utils/client/lib/messageContext.js
  5. 8
      app/ui/client/lib/chatMessages.js
  6. 11
      app/utils/client/lib/canDeleteMessage.js

@ -0,0 +1,41 @@
import { hasPermissionAsync } from './hasPermission';
import { getValue } from '../../../settings/server/raw';
const elapsedTime = (ts) => {
const dif = Date.now() - ts;
return Math.round((dif / 1000) / 60);
};
export const canDeleteMessageAsync = async (uid, { u, rid, ts }) => {
const forceDelete = await hasPermissionAsync(uid, 'force-delete-message', rid);
if (forceDelete) {
return true;
}
if (!ts) {
return false;
}
const deleteAllowed = await getValue('Message_AllowDeleting');
if (!deleteAllowed) {
return false;
}
const allowedToDeleteAny = await hasPermissionAsync(uid, 'delete-message', rid);
const allowed = allowedToDeleteAny || (uid === u._id && await hasPermissionAsync(uid, 'delete-own-message'));
if (!allowed) {
return false;
}
const blockDeleteInMinutes = await getValue('Message_AllowDeleting_BlockDeleteInMinutes');
if (!blockDeleteInMinutes) {
return true;
}
const timeElapsedForMessage = elapsedTime(ts);
return timeElapsedForMessage <= blockDeleteInMinutes;
};
export const canDeleteMessage = (uid, { u, rid, ts }) => Promise.await(canDeleteMessageAsync(uid, { u, rid, ts }));

@ -32,6 +32,7 @@ Meteor.startup(function() {
{ _id: 'delete-c', roles: ['admin', 'owner'] },
{ _id: 'delete-d', roles: ['admin'] },
{ _id: 'delete-message', roles: ['admin', 'owner', 'moderator'] },
{ _id: 'delete-own-message', roles: ['admin', 'user'] },
{ _id: 'delete-p', roles: ['admin', 'owner'] },
{ _id: 'delete-user', roles: ['admin'] },
{ _id: 'edit-message', roles: ['admin', 'owner', 'moderator'] },

@ -1,9 +1,7 @@
import { Meteor } from 'meteor/meteor';
import { Match, check } from 'meteor/check';
import moment from 'moment';
import { hasPermission } from '../../../authorization';
import { settings } from '../../../settings';
import { canDeleteMessage } from '../../../authorization/server/functions/canDeleteMessage';
import { Messages } from '../../../models';
import { deleteMessage } from '../functions';
@ -12,11 +10,15 @@ Meteor.methods({
check(message, Match.ObjectIncluding({
_id: String,
}));
if (!Meteor.userId()) {
const uid = Meteor.userId();
if (!uid) {
throw new Meteor.Error('error-invalid-user', 'Invalid user', {
method: 'deleteMessage',
});
}
const originalMessage = Messages.findOneById(message._id, {
fields: {
u: 1,
@ -25,38 +27,14 @@ Meteor.methods({
ts: 1,
},
});
if (originalMessage == null) {
throw new Meteor.Error('error-action-not-allowed', 'Not allowed', {
method: 'deleteMessage',
action: 'Delete_message',
});
}
const forceDelete = hasPermission(Meteor.userId(), 'force-delete-message', originalMessage.rid);
const _hasPermission = hasPermission(Meteor.userId(), 'delete-message', originalMessage.rid);
const deleteAllowed = settings.get('Message_AllowDeleting');
const deleteOwn = originalMessage && originalMessage.u && originalMessage.u._id === Meteor.userId();
if (!(_hasPermission || (deleteAllowed && deleteOwn)) && !forceDelete) {
if (!originalMessage || !canDeleteMessage(uid, originalMessage)) {
throw new Meteor.Error('error-action-not-allowed', 'Not allowed', {
method: 'deleteMessage',
action: 'Delete_message',
});
}
const blockDeleteInMinutes = settings.get('Message_AllowDeleting_BlockDeleteInMinutes');
if (blockDeleteInMinutes != null && blockDeleteInMinutes !== 0 && !forceDelete) {
if (originalMessage.ts == null) {
return;
}
const msgTs = moment(originalMessage.ts);
if (msgTs == null) {
return;
}
const currentTsDiff = moment().diff(msgTs, 'minutes');
if (currentTsDiff > blockDeleteInMinutes) {
throw new Meteor.Error('error-message-deleting-blocked', 'Message deleting is blocked', {
method: 'deleteMessage',
});
}
}
return deleteMessage(originalMessage, Meteor.user());
},
});

@ -30,6 +30,7 @@ export function messageContext({ rid } = Template.instance()) {
showreply: true,
showReplyButton: true,
hasPermissionDeleteMessage: hasPermission('delete-message', rid),
hasPermissionDeleteOwnMessage: hasPermission('delete-own-message'),
hideRoles: !settings.get('UI_DisplayRoles') || getUserPreference(uid, 'hideRoles'),
UI_Use_Real_Name: settings.get('UI_Use_Real_Name'),
Chatops_Username: settings.get('Chatops_Username'),

@ -493,12 +493,8 @@ export class ChatMessages {
}
}
try {
await call('deleteMessage', { _id });
} catch (error) {
console.error(error);
handleError(error);
}
await call('deleteMessage', { _id });
}
keydown(event) {

@ -1,13 +1,13 @@
import { Meteor } from 'meteor/meteor';
import moment from 'moment';
import { hasAtLeastOnePermission } from '../../../authorization/client';
import { hasPermission } from '../../../authorization/client';
import { settings } from '../../../settings/client';
export const canDeleteMessage = ({ rid, ts, uid }) => {
const userId = Meteor.userId();
const forceDelete = hasAtLeastOnePermission('force-delete-message', rid);
const forceDelete = hasPermission('force-delete-message', rid);
if (forceDelete) {
return true;
}
@ -17,9 +17,10 @@ export const canDeleteMessage = ({ rid, ts, uid }) => {
return false;
}
const hasPermission = hasAtLeastOnePermission('delete-message', rid);
const deleteOwn = uid === userId;
if (!hasPermission && !deleteOwn) {
const allowed = hasPermission('delete-message', rid);
const deleteOwn = allowed || (uid === userId && hasPermission('delete-own-message'));
if (!allowed && !deleteOwn) {
return false;
}

Loading…
Cancel
Save