mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-10-26 16:46:12 +01:00
feat: added PUT/DELETE /api/v1/users/:uid/ban routes
This commit is contained in:
69
openapi.yaml
69
openapi.yaml
@@ -242,19 +242,74 @@ paths:
|
|||||||
$ref: '#/components/schemas/Status'
|
$ref: '#/components/schemas/Status'
|
||||||
response:
|
response:
|
||||||
type: object
|
type: object
|
||||||
|
'/{uid}/ban':
|
||||||
|
put:
|
||||||
|
tags:
|
||||||
|
- users
|
||||||
|
summary: bans a user
|
||||||
|
parameters:
|
||||||
|
- in: path
|
||||||
|
name: uid
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
required: true
|
||||||
|
description: uid of the user to ban
|
||||||
|
requestBody:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
until:
|
||||||
|
type: number
|
||||||
|
description: UNIX timestamp of the ban expiry
|
||||||
|
example: 1585775608076
|
||||||
|
reason:
|
||||||
|
type: string
|
||||||
|
example: the reason for the ban
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: successfully banned user
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
status:
|
||||||
|
$ref: '#/components/schemas/Status'
|
||||||
|
response:
|
||||||
|
type: object
|
||||||
|
delete:
|
||||||
|
tags:
|
||||||
|
- users
|
||||||
|
summary: unbans a user
|
||||||
|
parameters:
|
||||||
|
- in: path
|
||||||
|
name: uid
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
required: true
|
||||||
|
description: uid of the user to unban
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: successfully unbanned user
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
status:
|
||||||
|
$ref: '#/components/schemas/Status'
|
||||||
|
response:
|
||||||
|
type: object
|
||||||
components:
|
components:
|
||||||
schemas:
|
schemas:
|
||||||
Status:
|
Status:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
code:
|
code:
|
||||||
allOf:
|
type: string
|
||||||
- title: Success
|
example: ok
|
||||||
type: string
|
|
||||||
example: ok
|
|
||||||
- title: Error
|
|
||||||
type: string
|
|
||||||
example: error
|
|
||||||
message:
|
message:
|
||||||
type: string
|
type: string
|
||||||
example: OK
|
example: OK
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ define('admin/manage/users', ['translator', 'benchpress', 'autocomplete'], funct
|
|||||||
$('.users-table [component="user/select/single"]:checked').parents('.user-row').remove();
|
$('.users-table [component="user/select/single"]:checked').parents('.user-row').remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// use onSuccess/onFail instead
|
||||||
function done(successMessage, className, flag) {
|
function done(successMessage, className, flag) {
|
||||||
return function (err) {
|
return function (err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
@@ -57,6 +58,18 @@ define('admin/manage/users', ['translator', 'benchpress', 'autocomplete'], funct
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onSuccess(successMessage, className, flag) {
|
||||||
|
app.alertSuccess(successMessage);
|
||||||
|
if (className) {
|
||||||
|
update(className, flag);
|
||||||
|
}
|
||||||
|
unselectAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
function onFail(err) {
|
||||||
|
app.alertError(err.message);
|
||||||
|
}
|
||||||
|
|
||||||
$('[component="user/select/all"]').on('click', function () {
|
$('[component="user/select/all"]').on('click', function () {
|
||||||
$('.users-table [component="user/select/single"]').prop('checked', $(this).is(':checked'));
|
$('.users-table [component="user/select/single"]').prop('checked', $(this).is(':checked'));
|
||||||
});
|
});
|
||||||
@@ -119,7 +132,20 @@ define('admin/manage/users', ['translator', 'benchpress', 'autocomplete'], funct
|
|||||||
|
|
||||||
bootbox.confirm((uids.length > 1 ? '[[admin/manage/users:alerts.confirm-ban-multi]]' : '[[admin/manage/users:alerts.confirm-ban]]'), function (confirm) {
|
bootbox.confirm((uids.length > 1 ? '[[admin/manage/users:alerts.confirm-ban-multi]]' : '[[admin/manage/users:alerts.confirm-ban]]'), function (confirm) {
|
||||||
if (confirm) {
|
if (confirm) {
|
||||||
socket.emit('user.banUsers', { uids: uids, reason: '' }, done('[[admin/manage/users:alerts.ban-success]]', '.ban', true));
|
var requests = uids.map(function (uid) {
|
||||||
|
return $.ajax({
|
||||||
|
url: config.relative_path + '/api/v1/users/' + uid + '/ban',
|
||||||
|
method: 'put',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$.when(requests)
|
||||||
|
.done(function () {
|
||||||
|
onSuccess('[[admin/manage/users:alerts.ban-success]]', '.ban', true);
|
||||||
|
})
|
||||||
|
.fail(function (ev) {
|
||||||
|
onFail(ev.responseJSON.status);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -150,7 +176,24 @@ define('admin/manage/users', ['translator', 'benchpress', 'autocomplete'], funct
|
|||||||
return data;
|
return data;
|
||||||
}, {});
|
}, {});
|
||||||
var until = formData.length > 0 ? (Date.now() + (formData.length * 1000 * 60 * 60 * (parseInt(formData.unit, 10) ? 24 : 1))) : 0;
|
var until = formData.length > 0 ? (Date.now() + (formData.length * 1000 * 60 * 60 * (parseInt(formData.unit, 10) ? 24 : 1))) : 0;
|
||||||
socket.emit('user.banUsers', { uids: uids, until: until, reason: formData.reason }, done('[[admin/manage/users:alerts.ban-success]]', '.ban', true));
|
|
||||||
|
var requests = uids.map(function (uid) {
|
||||||
|
return $.ajax({
|
||||||
|
url: config.relative_path + '/api/v1/users/' + uid + '/ban',
|
||||||
|
method: 'put',
|
||||||
|
data: {
|
||||||
|
until: until,
|
||||||
|
reason: formData.reason,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$.when(requests)
|
||||||
|
.done(function () {
|
||||||
|
onSuccess('[[admin/manage/users:alerts.ban-success]]', '.ban', true);
|
||||||
|
}).fail(function (ev) {
|
||||||
|
onFail(ev.responseJSON.status);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -165,7 +208,19 @@ define('admin/manage/users', ['translator', 'benchpress', 'autocomplete'], funct
|
|||||||
return false; // specifically to keep the menu open
|
return false; // specifically to keep the menu open
|
||||||
}
|
}
|
||||||
|
|
||||||
socket.emit('user.unbanUsers', uids, done('[[admin/manage/users:alerts.unban-success]]', '.ban', false));
|
var requests = uids.map(function (uid) {
|
||||||
|
return $.ajax({
|
||||||
|
url: config.relative_path + '/api/v1/users/' + uid + '/ban',
|
||||||
|
method: 'delete',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$.when(requests)
|
||||||
|
.done(function () {
|
||||||
|
onSuccess('[[admin/manage/users:alerts.unban-success]]', '.ban', false);
|
||||||
|
}).fail(function (ev) {
|
||||||
|
onFail(ev.responseJSON.status);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
$('.reset-lockout').on('click', function () {
|
$('.reset-lockout').on('click', function () {
|
||||||
|
|||||||
@@ -154,20 +154,21 @@ define('forum/account/header', [
|
|||||||
|
|
||||||
var until = formData.length > 0 ? (Date.now() + (formData.length * 1000 * 60 * 60 * (parseInt(formData.unit, 10) ? 24 : 1))) : 0;
|
var until = formData.length > 0 ? (Date.now() + (formData.length * 1000 * 60 * 60 * (parseInt(formData.unit, 10) ? 24 : 1))) : 0;
|
||||||
|
|
||||||
socket.emit('user.banUsers', {
|
$.ajax({
|
||||||
uids: [theirid],
|
url: config.relative_path + '/api/v1/users/' + theirid + '/ban',
|
||||||
until: until,
|
method: 'put',
|
||||||
reason: formData.reason || '',
|
data: {
|
||||||
}, function (err) {
|
until: until,
|
||||||
if (err) {
|
reason: formData.reason || '',
|
||||||
return app.alertError(err.message);
|
},
|
||||||
}
|
}).done(function () {
|
||||||
|
|
||||||
if (typeof onSuccess === 'function') {
|
if (typeof onSuccess === 'function') {
|
||||||
return onSuccess();
|
return onSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
ajaxify.refresh();
|
ajaxify.refresh();
|
||||||
|
}).fail(function (ev) {
|
||||||
|
app.alertError(ev.responseJSON.status.message);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -177,11 +178,13 @@ define('forum/account/header', [
|
|||||||
}
|
}
|
||||||
|
|
||||||
function unbanAccount() {
|
function unbanAccount() {
|
||||||
socket.emit('user.unbanUsers', [ajaxify.data.theirid], function (err) {
|
$.ajax({
|
||||||
if (err) {
|
url: config.relative_path + '/api/v1/users/' + ajaxify.data.theirid + '/ban',
|
||||||
return app.alertError(err.message);
|
method: 'delete',
|
||||||
}
|
}).done(function () {
|
||||||
ajaxify.refresh();
|
ajaxify.refresh();
|
||||||
|
}).fail(function (ev) {
|
||||||
|
app.alertError(ev.responseJSON.status.message);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,11 @@ const privileges = require('../../privileges');
|
|||||||
const notifications = require('../../notifications');
|
const notifications = require('../../notifications');
|
||||||
const meta = require('../../meta');
|
const meta = require('../../meta');
|
||||||
const events = require('../../events');
|
const events = require('../../events');
|
||||||
|
const translator = require('../../translator');
|
||||||
|
|
||||||
|
const db = require('../../database');
|
||||||
const helpers = require('../helpers');
|
const helpers = require('../helpers');
|
||||||
|
const sockets = require('../../socket.io');
|
||||||
|
|
||||||
const Users = module.exports;
|
const Users = module.exports;
|
||||||
|
|
||||||
@@ -155,3 +159,62 @@ Users.unfollow = async (req, res) => {
|
|||||||
});
|
});
|
||||||
helpers.formatApiResponse(200, res);
|
helpers.formatApiResponse(200, res);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Users.ban = async (req, res) => {
|
||||||
|
if (!await privileges.users.hasBanPrivilege(req.user.uid)) {
|
||||||
|
return helpers.formatApiResponse(403, res, new Error('[[error:no-privileges]]'));
|
||||||
|
} else if (await user.isAdministrator(req.params.uid)) {
|
||||||
|
return helpers.formatApiResponse(403, res, new Error('[[error:cant-ban-other-admins]]'));
|
||||||
|
}
|
||||||
|
|
||||||
|
const banData = await user.bans.ban(req.params.uid, req.body.until, req.body.reason);
|
||||||
|
await db.setObjectField('uid:' + req.params.uid + ':ban:' + banData.timestamp, 'fromUid', req.user.uid);
|
||||||
|
|
||||||
|
if (!req.body.reason) {
|
||||||
|
req.body.reason = await translator.translate('[[user:info.banned-no-reason]]');
|
||||||
|
}
|
||||||
|
|
||||||
|
sockets.in('uid_' + req.params.uid).emit('event:banned', {
|
||||||
|
until: req.body.until,
|
||||||
|
reason: req.body.reason,
|
||||||
|
});
|
||||||
|
|
||||||
|
await events.log({
|
||||||
|
type: 'user-ban',
|
||||||
|
uid: req.user.uid,
|
||||||
|
targetUid: req.params.uid,
|
||||||
|
ip: req.ip,
|
||||||
|
reason: req.body.reason || undefined,
|
||||||
|
});
|
||||||
|
plugins.fireHook('action:user.banned', {
|
||||||
|
callerUid: req.user.uid,
|
||||||
|
ip: req.ip,
|
||||||
|
uid: req.params.uid,
|
||||||
|
until: req.body.until > 0 ? req.body.until : undefined,
|
||||||
|
reason: req.body.reason || undefined,
|
||||||
|
});
|
||||||
|
await user.auth.revokeAllSessions(req.params.uid);
|
||||||
|
|
||||||
|
helpers.formatApiResponse(200, res);
|
||||||
|
};
|
||||||
|
|
||||||
|
Users.unban = async (req, res) => {
|
||||||
|
if (!await privileges.users.hasBanPrivilege(req.user.uid)) {
|
||||||
|
return helpers.formatApiResponse(403, res, new Error('[[error:no-privileges]]'));
|
||||||
|
}
|
||||||
|
|
||||||
|
await user.bans.unban(req.params.uid);
|
||||||
|
await events.log({
|
||||||
|
type: 'user-unban',
|
||||||
|
uid: req.user.uid,
|
||||||
|
targetUid: req.params.uid,
|
||||||
|
ip: req.ip,
|
||||||
|
});
|
||||||
|
plugins.fireHook('action:user.unbanned', {
|
||||||
|
callerUid: req.user.uid,
|
||||||
|
ip: req.ip,
|
||||||
|
uid: req.params.uid,
|
||||||
|
});
|
||||||
|
|
||||||
|
helpers.formatApiResponse(200, res);
|
||||||
|
};
|
||||||
|
|||||||
@@ -32,59 +32,8 @@ function authenticatedRoutes() {
|
|||||||
setupApiRoute(router, '/:uid/follow', middleware, [...middlewares], 'post', controllers.write.users.follow);
|
setupApiRoute(router, '/:uid/follow', middleware, [...middlewares], 'post', controllers.write.users.follow);
|
||||||
setupApiRoute(router, '/:uid/follow', middleware, [...middlewares], 'delete', controllers.write.users.unfollow);
|
setupApiRoute(router, '/:uid/follow', middleware, [...middlewares], 'delete', controllers.write.users.unfollow);
|
||||||
|
|
||||||
// app.put('/:uid/follow', apiMiddleware.requireUser, function(req, res) {
|
setupApiRoute(router, '/:uid/ban', middleware, [...middlewares, middleware.exposePrivileges], 'put', controllers.write.users.ban);
|
||||||
// Users.follow(req.user.uid, req.params.uid, function(err) {
|
setupApiRoute(router, '/:uid/ban', middleware, [...middlewares, middleware.exposePrivileges], 'delete', controllers.write.users.unban);
|
||||||
// return errorHandler.handle(err, res);
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
|
|
||||||
// app.delete('/:uid/follow', apiMiddleware.requireUser, function(req, res) {
|
|
||||||
// Users.unfollow(req.user.uid, req.params.uid, function(err) {
|
|
||||||
// return errorHandler.handle(err, res);
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
|
|
||||||
// app.route('/:uid/chats')
|
|
||||||
// .post(apiMiddleware.requireUser, function(req, res) {
|
|
||||||
// if (!utils.checkRequired(['message'], req, res)) {
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// var timestamp = parseInt(req.body.timestamp, 10) || Date.now();
|
|
||||||
|
|
||||||
// function addMessage(roomId) {
|
|
||||||
// Messaging.addMessage({
|
|
||||||
// uid: req.user.uid,
|
|
||||||
// roomId: roomId,
|
|
||||||
// content: req.body.message,
|
|
||||||
// timestamp: timestamp,
|
|
||||||
// }, function(err, message) {
|
|
||||||
// if (parseInt(req.body.quiet, 10) !== 1) {
|
|
||||||
// Messaging.notifyUsersInRoom(req.user.uid, roomId, message);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return errorHandler.handle(err, res, message);
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Messaging.canMessageUser(req.user.uid, req.params.uid, function(err) {
|
|
||||||
// if (err) {
|
|
||||||
// return errorHandler.handle(err, res);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (req.body.roomId) {
|
|
||||||
// addMessage(req.body.roomId);
|
|
||||||
// } else {
|
|
||||||
// Messaging.newRoom(req.user.uid, [req.params.uid], function(err, roomId) {
|
|
||||||
// if (err) {
|
|
||||||
// return errorHandler.handle(err, res);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// addMessage(roomId);
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
|
|
||||||
// app.route('/:uid/ban')
|
// app.route('/:uid/ban')
|
||||||
// .put(apiMiddleware.requireUser, apiMiddleware.requireAdmin, function(req, res) {
|
// .put(apiMiddleware.requireUser, apiMiddleware.requireAdmin, function(req, res) {
|
||||||
@@ -131,6 +80,52 @@ function authenticatedRoutes() {
|
|||||||
// errorHandler.handle(err, res);
|
// errorHandler.handle(err, res);
|
||||||
// });
|
// });
|
||||||
// });
|
// });
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Chat routes were not migrated because chats may get refactored... also the logic is derpy
|
||||||
|
* It also does not take into account multiple chats for a given user.
|
||||||
|
*/
|
||||||
|
// app.route('/:uid/chats')
|
||||||
|
// .post(apiMiddleware.requireUser, function(req, res) {
|
||||||
|
// if (!utils.checkRequired(['message'], req, res)) {
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// var timestamp = parseInt(req.body.timestamp, 10) || Date.now();
|
||||||
|
|
||||||
|
// function addMessage(roomId) {
|
||||||
|
// Messaging.addMessage({
|
||||||
|
// uid: req.user.uid,
|
||||||
|
// roomId: roomId,
|
||||||
|
// content: req.body.message,
|
||||||
|
// timestamp: timestamp,
|
||||||
|
// }, function(err, message) {
|
||||||
|
// if (parseInt(req.body.quiet, 10) !== 1) {
|
||||||
|
// Messaging.notifyUsersInRoom(req.user.uid, roomId, message);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return errorHandler.handle(err, res, message);
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Messaging.canMessageUser(req.user.uid, req.params.uid, function(err) {
|
||||||
|
// if (err) {
|
||||||
|
// return errorHandler.handle(err, res);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (req.body.roomId) {
|
||||||
|
// addMessage(req.body.roomId);
|
||||||
|
// } else {
|
||||||
|
// Messaging.newRoom(req.user.uid, [req.params.uid], function(err, roomId) {
|
||||||
|
// if (err) {
|
||||||
|
// return errorHandler.handle(err, res);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// addMessage(roomId);
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// });
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = function () {
|
module.exports = function () {
|
||||||
|
|||||||
@@ -1,21 +1,18 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const winston = require('winston');
|
|
||||||
|
|
||||||
const db = require('../../database');
|
const db = require('../../database');
|
||||||
const user = require('../../user');
|
const user = require('../../user');
|
||||||
const meta = require('../../meta');
|
|
||||||
const websockets = require('../index');
|
const websockets = require('../index');
|
||||||
const events = require('../../events');
|
const events = require('../../events');
|
||||||
const privileges = require('../../privileges');
|
const privileges = require('../../privileges');
|
||||||
const plugins = require('../../plugins');
|
const plugins = require('../../plugins');
|
||||||
const emailer = require('../../emailer');
|
|
||||||
const translator = require('../../translator');
|
const translator = require('../../translator');
|
||||||
const utils = require('../../../public/src/utils');
|
|
||||||
const flags = require('../../flags');
|
const flags = require('../../flags');
|
||||||
|
|
||||||
module.exports = function (SocketUser) {
|
module.exports = function (SocketUser) {
|
||||||
SocketUser.banUsers = async function (socket, data) {
|
SocketUser.banUsers = async function (socket, data) {
|
||||||
|
websockets.warnDeprecated(socket, 'PUT /api/v1/users/:uid/ban');
|
||||||
|
|
||||||
if (!data || !Array.isArray(data.uids)) {
|
if (!data || !Array.isArray(data.uids)) {
|
||||||
throw new Error('[[error:invalid-data]]');
|
throw new Error('[[error:invalid-data]]');
|
||||||
}
|
}
|
||||||
@@ -43,6 +40,8 @@ module.exports = function (SocketUser) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
SocketUser.unbanUsers = async function (socket, uids) {
|
SocketUser.unbanUsers = async function (socket, uids) {
|
||||||
|
websockets.warnDeprecated(socket, 'DELETE /api/v1/users/:uid/ban');
|
||||||
|
|
||||||
await toggleBan(socket.uid, uids, async function (uid) {
|
await toggleBan(socket.uid, uids, async function (uid) {
|
||||||
await user.bans.unban(uid);
|
await user.bans.unban(uid);
|
||||||
await events.log({
|
await events.log({
|
||||||
@@ -76,19 +75,7 @@ module.exports = function (SocketUser) {
|
|||||||
if (isAdmin) {
|
if (isAdmin) {
|
||||||
throw new Error('[[error:cant-ban-other-admins]]');
|
throw new Error('[[error:cant-ban-other-admins]]');
|
||||||
}
|
}
|
||||||
const username = await user.getUserField(uid, 'username');
|
|
||||||
const siteTitle = meta.config.title || 'NodeBB';
|
|
||||||
const data = {
|
|
||||||
subject: '[[email:banned.subject, ' + siteTitle + ']]',
|
|
||||||
username: username,
|
|
||||||
until: until ? utils.toISOString(until) : false,
|
|
||||||
reason: reason,
|
|
||||||
};
|
|
||||||
try {
|
|
||||||
await emailer.send('banned', uid, data);
|
|
||||||
} catch (err) {
|
|
||||||
winston.error('[emailer.send] ' + err.message);
|
|
||||||
}
|
|
||||||
const banData = await user.bans.ban(uid, until, reason);
|
const banData = await user.bans.ban(uid, until, reason);
|
||||||
await db.setObjectField('uid:' + uid + ':ban:' + banData.timestamp, 'fromUid', callerUid);
|
await db.setObjectField('uid:' + uid + ':ban:' + banData.timestamp, 'fromUid', callerUid);
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
const winston = require('winston');
|
||||||
|
|
||||||
|
const meta = require('../meta');
|
||||||
|
const utils = require('../utils');
|
||||||
|
const emailer = require('../emailer');
|
||||||
const db = require('../database');
|
const db = require('../database');
|
||||||
|
|
||||||
module.exports = function (User) {
|
module.exports = function (User) {
|
||||||
@@ -38,6 +43,22 @@ module.exports = function (User) {
|
|||||||
} else {
|
} else {
|
||||||
await db.sortedSetRemove('users:banned:expire', uid);
|
await db.sortedSetRemove('users:banned:expire', uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Email notification of ban
|
||||||
|
const username = await User.getUserField(uid, 'username');
|
||||||
|
const siteTitle = meta.config.title || 'NodeBB';
|
||||||
|
const data = {
|
||||||
|
subject: '[[email:banned.subject, ' + siteTitle + ']]',
|
||||||
|
username: username,
|
||||||
|
until: until ? utils.toISOString(until) : false,
|
||||||
|
reason: reason,
|
||||||
|
};
|
||||||
|
try {
|
||||||
|
await emailer.send('banned', uid, data);
|
||||||
|
} catch (err) {
|
||||||
|
winston.error('[emailer.send] ' + err.message);
|
||||||
|
}
|
||||||
|
|
||||||
return banData;
|
return banData;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user