From 94d99de0016053e840b7d4afbc36e76a9273e7c2 Mon Sep 17 00:00:00 2001 From: Alim TUNC Date: Wed, 2 Nov 2022 17:14:23 +0100 Subject: [PATCH] Add possibility to ban user from level in report modal --- core/client/ui/levels.js | 7 ++++ core/lib/misc.js | 20 +++++++++--- core/modules/report/client/report.hbs.html | 22 +++++++------ core/modules/report/client/report.js | 37 ++++++++++++++++------ core/modules/report/client/report.scss | 20 ++++++++++-- core/server/levels.js | 2 +- core/server/users.js | 16 ++++++---- 7 files changed, 93 insertions(+), 31 deletions(-) diff --git a/core/client/ui/levels.js b/core/client/ui/levels.js index 787525da..10331994 100644 --- a/core/client/ui/levels.js +++ b/core/client/ui/levels.js @@ -11,8 +11,15 @@ const levelQueryFilters = ignoredLevelId => ({ }); const askLoadLevel = (levelId, incrementVisit = false) => { + const bannedUserIds = Levels.findOne({ _id: levelId }).bannedUserIds || []; + if (Meteor.user().profile.levelId === levelId) return; + if (bannedUserIds.includes(Meteor.userId())) { + lp.notif.error('You have been banned from this level'); + return; + } + if (incrementVisit) Meteor.call('increaseLevelVisits', levelId); if (window.self !== window.top) { diff --git a/core/lib/misc.js b/core/lib/misc.js index 07cba923..6fa8a054 100644 --- a/core/lib/misc.js +++ b/core/lib/misc.js @@ -305,6 +305,17 @@ const getChannelType = channelId => { } }; +const kickUser = userId => { + // if (!this.userId) throw new Meteor.Error('missing-user', 'A valid user is required'); + check(userId, Match.Id); + if (!Meteor.settings.defaultKickLevelId) throw new Meteor.Error('missing-levelId', 'Missing configuration for defaultKickLevelId'); + const level = Levels.findOne({ _id: Meteor.settings.defaultKickLevelId }); + if (!level) throw new Meteor.Error('missing-levelId', 'Level in defaultKickLevelId does not exists'); + log('kickUser', { kicker: Meteor.userId(), kicked: userId }); + + Meteor.users.update({ _id: userId }, { $set: { 'profile.levelId': Meteor.settings.defaultKickLevelId } }); +}; + export { canAccessZone, canEditActiveLevel, @@ -316,16 +327,17 @@ export { completeUserProfile, currentLevel, fileOnBeforeUpload, - generateRandomCharacterSkin, generateGuestSkin, + generateRandomCharacterSkin, + getChannelType, getSpawnLevel, guestAllowed, - getChannelType, isLevelOwner, + kickUser, levelSpawnPosition, permissionTypes, + randomFloatInRange, + randomInRange, subscribedUsersToEntity, teleportUserInLevel, - randomInRange, - randomFloatInRange, }; diff --git a/core/modules/report/client/report.hbs.html b/core/modules/report/client/report.hbs.html index e697b41b..4c3a7f9b 100644 --- a/core/modules/report/client/report.hbs.html +++ b/core/modules/report/client/report.hbs.html @@ -5,19 +5,23 @@

{{ title }}


- {{#each reportAllReasons }} - + {{/each }}
- - + +
+ {{#if isAdmin}} + + {{/if}} + +
-{{/modal }} + {{/modal }} diff --git a/core/modules/report/client/report.js b/core/modules/report/client/report.js index 5707b981..beb075fb 100644 --- a/core/modules/report/client/report.js +++ b/core/modules/report/client/report.js @@ -15,7 +15,7 @@ window.addEventListener('load', () => { window.addEventListener(eventTypes.onMenuOptionSelected, onMenuOptionSelected); }); -function buildMessage(text, level, reason, reported, messageId) { +function buildMessage(text, level, reason, reported, messageId, isBanned) { let messageText = ''; if (messageId) { const message = Messages.findOne(messageId); @@ -29,6 +29,8 @@ Level: ${level} Justification: ${text} +Banned: ${isBanned} + Reason: ${reason} ${messageText} Reported: ${reported._id} - ${reported.profile.name}`; @@ -45,12 +47,14 @@ const sendReport = (channel, text) => { return messageId; }; -const onSubmit = (reason, reported, messageId) => { - if (reported._id === Meteor.userId()) { +const onSubmit = (reason, reported, messageId, isBanned = false) => { + const userId = Meteor.userId(); + + if (reported._id === userId) { lp.notif.error('You can\'t report yourself'); return; } - const isAdmin = Meteor.users.findOne(Meteor.userId()).roles?.admin; + const isAdmin = Meteor.users.findOne(userId).roles?.admin; const text = document.querySelector('.report .js-command-input').value; const currentLevel = Meteor.user().profile.levelId; @@ -64,9 +68,9 @@ const onSubmit = (reason, reported, messageId) => { } let admins = Meteor.users.find({ roles: { admin: true } }).fetch(); if (isAdmin) { - admins = admins.filter(admin => admin._id !== Meteor.userId()); + admins = admins.filter(admin => admin._id !== userId); } - if (!admins.length) { + if (!isBanned && !admins.length) { // Quiting even if the user is an admin because we don't want to create a conversation with himself lp.notif.error('No admins found'); return; @@ -76,11 +80,19 @@ const onSubmit = (reason, reported, messageId) => { admins = adminsLevel; } const level = Levels.findOne(currentLevel).name; - const message = buildMessage(text, level, reason, reported, messageId); - const channel = [...admins.map(admin => admin._id), Meteor.userId()].sort().join(';'); + const message = buildMessage(text, level, reason, reported, messageId, isBanned); + const channel = [...admins.map(admin => admin._id), userId].sort().join(';'); sendReport(channel, message); + if (isBanned) { + Meteor.call('banUser', reported._id, currentLevel, err => { + if (err) { lp.notif.error(err); return; } + + lp.notif.success('Successfully Banned!'); + }); + } + closeModal('report'); }; @@ -97,16 +109,23 @@ Template.report.helpers({ const reportAllReasons = ['Non-specified', 'Spam', 'Abusive chat', 'Cheating', 'Offensive name', 'Other']; return reportAllReasons; }, + isAdmin() { return Meteor.user().roles?.admin;}, }); Template.report.events({ 'change .js-report-reason-select'(event) { Template.instance().reason.set(event.target.value); }, - 'click .js-button-submit'(event) { + 'click .js-report-submit'(event) { event.preventDefault(); event.stopPropagation(); const template = Template.instance(); lp.notif.confirm('Report user', `Do you really want to report this ${template.data.messageId ? 'message' : 'user'}?`, () => onSubmit(template.reason.get(), Meteor.users.findOne(template.data.userId), template.data.messageId)); }, + 'click .js-ban-submit'(event) { + event.preventDefault(); + event.stopPropagation(); + const template = Template.instance(); + lp.notif.confirm('Ban user', 'Do you really want to ban this user', () => onSubmit(template.reason.get(), Meteor.users.findOne(template.data.userId), template.data.messageId, true)); + }, }); diff --git a/core/modules/report/client/report.scss b/core/modules/report/client/report.scss index 23a21c66..5d34d3c0 100644 --- a/core/modules/report/client/report.scss +++ b/core/modules/report/client/report.scss @@ -1,3 +1,5 @@ +@import "../../../client/_variables"; + .report { width: 90%; height: 80%; @@ -10,8 +12,22 @@ width: 100%; height: 80%; } - button { - margin-bottom: 0px; + + .buttons { + display: flex; + gap: 10px; + + .js-ban-submit { + background-color: $new-red; + + &:hover { + background-color: lighten($new-red, 5%); + } + } + + button { + margin-bottom: 0px; + } } } } diff --git a/core/server/levels.js b/core/server/levels.js index d4e2c16b..d014c50b 100644 --- a/core/server/levels.js +++ b/core/server/levels.js @@ -169,7 +169,7 @@ deleteLevel = levelId => { Meteor.publish('levels', function () { if (!this.userId) return undefined; - return Levels.find({ }, { fields: { name: 1, hide: 1, visit: 1, createdBy: 1, template: 1 } }); + return Levels.find({ }, { fields: { name: 1, hide: 1, visit: 1, createdBy: 1, template: 1, bannedUserIds: 1 } }); }); Meteor.publish('levelTemplates', function () { diff --git a/core/server/users.js b/core/server/users.js index 43cc009b..fe15c2d8 100644 --- a/core/server/users.js +++ b/core/server/users.js @@ -1,4 +1,4 @@ -import { completeUserProfile, getSpawnLevel, levelSpawnPosition, teleportUserInLevel } from '../lib/misc'; +import { completeUserProfile, getSpawnLevel, kickUser, levelSpawnPosition, teleportUserInLevel } from '../lib/misc'; const mainFields = { options: 1, profile: 1, roles: 1, status: { idle: 1, online: 1 }, beta: 1, guildId: 1 }; @@ -107,14 +107,18 @@ Meteor.methods({ Notifications.update({ userId: this.userId }, { $set: { read: true } }, { multi: true }); }, kickUser(userId) { + kickUser(userId) + }, + banUser(userId, levelId) { if (!this.userId) throw new Meteor.Error('missing-user', 'A valid user is required'); check(userId, Match.Id); - if (!Meteor.settings.defaultKickLevelId) throw new Meteor.Error('missing-levelId', 'Missing configuration for defaultKickLevelId'); - const level = Levels.findOne({ _id: Meteor.settings.defaultKickLevelId }); - if (!level) throw new Meteor.Error('missing-levelId', 'Level in defaultKickLevelId does not exists'); - log('kickUser', { kicker: Meteor.userId(), kicked: userId }); + const level = Levels.findOne({ _id: levelId }); + if (!level) throw new Meteor.Error('missing-levelId', 'Level is required'); + log('banUser', { banner: Meteor.userId(), banned: userId }); + - Meteor.users.update({ _id: userId }, { $set: { 'profile.levelId': Meteor.settings.defaultKickLevelId } }); + kickUser(userId); + Levels.update({ _id: levelId, bannedUserIds: { $ne: userId } }, { $push: { bannedUserIds: userId } }); }, muteFromZone(zoneId) { if (!this.userId) return;