2
0
mirror of https://github.com/thedevs-network/the-guard-bot synced 2025-08-23 02:17:47 +00:00

191 lines
3.8 KiB
JavaScript
Raw Normal View History

'use strict';
2020-06-29 15:07:12 +02:00
/**
* @typedef { { id: number } | { username: string } } UserQuery
* @exports UserQuery
*/
2017-09-25 09:56:39 +03:30
// Utils
2020-06-05 22:30:07 +02:00
const { strip } = require('../utils/cmd');
2017-09-25 09:56:39 +03:30
const Datastore = require('nedb-promise');
2020-06-29 15:07:12 +02:00
const ms = require('millisecond');
const R = require('ramda');
const User = new Datastore({
autoload: true,
filename: 'data/User.db',
timestampData: true,
});
User.ensureIndex({
fieldName: 'id',
unique: true,
});
2017-09-27 00:11:20 +03:30
User.ensureIndex({
fieldName: 'status',
});
// Migration
User.update(
{ username: '' },
{ $unset: { username: true } },
{ multi: true },
).then(() =>
User.ensureIndex({ fieldName: 'username', sparse: true, unique: true }));
const normalizeTgUser = R.pipe(
R.pick([ 'first_name', 'id', 'last_name', 'username' ]),
R.evolve({ username: R.toLower }),
R.merge({ first_name: '', last_name: '' }),
);
const getUpdatedDocument = R.prop(1);
2017-09-27 00:11:20 +03:30
const getUser = user =>
2017-09-25 12:40:04 +03:30
User.findOne(user);
const updateUser = async (rawTgUser) => {
const tgUser = normalizeTgUser(rawTgUser);
const { id, username } = tgUser;
const [ rawDbUser ] = await Promise.all([
getUser({ id }),
User.update({ $not: { id }, username }, { $unset: { username: true } }),
]);
if (rawDbUser === null) {
return User.update(
{ id },
{ status: 'member', warns: [], ...tgUser },
{ returnUpdatedDocs: true, upsert: true },
).then(getUpdatedDocument);
}
const dbUser = rawDbUser;
if (!R.whereEq(tgUser, dbUser)) {
return User.update(
{ id },
{ $set: tgUser },
{ returnUpdatedDocs: true },
).then(getUpdatedDocument);
}
return dbUser;
};
const admin = ({ id }) =>
2017-09-27 00:11:20 +03:30
User.update(
{ id },
{ $set: { status: 'admin', warns: [] } },
);
2017-09-27 00:11:20 +03:30
const getAdmins = () =>
User.find({ status: 'admin' });
const unadmin = ({ id }) =>
User.update({ id }, { $set: { status: 'member' } });
2019-01-24 19:53:10 +01:00
const isAdmin = (user) => {
if (!user) return false;
if (user.status) return user.status === 'admin';
return User.findOne({ id: user.id, status: 'admin' });
};
2017-09-27 00:11:20 +03:30
2019-05-02 21:42:13 +02:00
const ban = ({ id }, ban_details) =>
User.update(
{ id, $not: { status: 'admin' } },
2019-05-02 21:42:13 +02:00
{ $set: { ban_details, status: 'banned' } },
{ upsert: true },
);
2017-09-27 00:11:20 +03:30
2019-05-02 21:42:13 +02:00
const batchBan = (users, ban_details) =>
User.update(
2019-01-31 20:19:39 +01:00
{ $or: users.map(strip), $not: { status: 'admin' } },
2019-05-02 21:42:13 +02:00
{ $set: { ban_details, status: 'banned' } },
{ multi: true, returnUpdatedDocs: true },
2019-01-31 20:19:39 +01:00
).then(getUpdatedDocument);
const ensureExists = ({ id }) =>
id && User.insert({ id, status: 'member', warns: [] }).catch(R.F);
2017-09-27 00:11:20 +03:30
const unban = ({ id }) =>
User.update(
{ id },
{
2019-06-20 11:58:19 +02:00
$set: { status: 'member' },
$unset: { ban_details: true, ban_reason: true },
},
);
2017-09-27 00:11:20 +03:30
2020-06-29 15:07:12 +02:00
/**
* @param {UserQuery} user
*/
const permit = (user, { by_id, date }) =>
User.update(
user,
{ $set: { permit: { by_id, date } } },
{ returnUpdatedDocs: true },
).then(getUpdatedDocument);
/**
* @param {UserQuery} user
*/
permit.revoke = (user) =>
User.update(
{ permit: { $exists: true }, ...strip(user) },
{ $unset: { permit: true } },
{ returnUpdatedDocs: true },
).then(getUpdatedDocument);
permit.isValid = (p) => Date.now() - ms('24h') < p?.date;
2019-05-31 17:02:00 +02:00
const warn = ({ id }, reason, { amend }) =>
User.update(
{ id, $not: { status: 'admin' } },
2020-06-29 15:07:12 +02:00
{
$pop: { warns: +!!amend },
$push: { warns: reason },
$unset: { permit: true },
},
{ returnUpdatedDocs: true },
).then(getUpdatedDocument);
const unwarn = ({ id }, warnQuery) =>
User.update(
{ id },
{
$pull: { warns: warnQuery },
$set: { status: 'member' },
$unset: { ban_details: true, ban_reason: true },
},
);
2019-06-20 11:58:19 +02:00
const nowarns = query => unwarn(query, {});
2021-04-23 19:40:59 +04:30
const verifyCaptcha = ({ id }, captcha = true) =>
User.update({ id }, { $set: { captcha } });
module.exports = {
2017-09-27 00:11:20 +03:30
admin,
ban,
2019-01-31 20:19:39 +01:00
batchBan,
ensureExists,
2017-09-27 00:11:20 +03:30
getAdmins,
2017-09-25 12:40:04 +03:30
getUser,
2017-09-27 00:11:20 +03:30
isAdmin,
nowarns,
2020-06-29 15:07:12 +02:00
permit,
2017-09-27 00:11:20 +03:30
unadmin,
unban,
unwarn,
updateUser,
2021-04-23 19:40:59 +04:30
verifyCaptcha,
warn,
};