2020-05-08 21:30:49 +02:00
|
|
|
|
// @ts-check
|
2017-11-02 00:04:22 +03:30
|
|
|
|
'use strict';
|
|
|
|
|
|
|
|
|
|
// Utils
|
2020-06-29 13:49:41 +02:00
|
|
|
|
const { inspect } = require('util');
|
2020-05-08 21:30:49 +02:00
|
|
|
|
const { displayUser, scheduleDeletion } = require('../../utils/tg');
|
2020-06-15 14:45:55 +02:00
|
|
|
|
const { html, lrm, TgHtml } = require('../../utils/html');
|
2020-05-08 21:30:49 +02:00
|
|
|
|
const { isMaster, isWarnNotExpired } = require('../../utils/config');
|
|
|
|
|
const { parse, strip } = require('../../utils/cmd');
|
2017-11-02 00:04:22 +03:30
|
|
|
|
|
|
|
|
|
// DB
|
2020-06-29 15:07:12 +02:00
|
|
|
|
const { getUser, permit } = require('../../stores/user');
|
2017-11-02 00:04:22 +03:30
|
|
|
|
|
2020-05-25 23:25:42 +02:00
|
|
|
|
/** @param {Date} date */
|
2023-03-08 14:08:57 +01:00
|
|
|
|
const formatDate = (date) =>
|
2021-05-12 16:30:11 +02:00
|
|
|
|
date && date.toISOString().slice(0, -5).replace('T', ' ') + ' UTC';
|
2019-05-02 21:42:13 +02:00
|
|
|
|
|
2020-05-13 15:11:43 +02:00
|
|
|
|
/**
|
|
|
|
|
* @param {string} defaultVal
|
|
|
|
|
*/
|
2019-05-02 21:42:13 +02:00
|
|
|
|
const formatEntry = async (entry, defaultVal) => {
|
2020-05-13 15:11:43 +02:00
|
|
|
|
if (!entry || !entry.by_id) return html`${defaultVal}`;
|
2023-03-08 14:08:57 +01:00
|
|
|
|
const { first_name } = (await getUser({ id: entry.by_id })) || {};
|
|
|
|
|
if (!first_name)
|
|
|
|
|
return html`${lrm}${entry.reason} (${formatDate(entry.date)})`;
|
2020-06-29 13:49:41 +02:00
|
|
|
|
return html`${lrm}${entry.reason} (${first_name}, ${formatDate(entry.date)})`;
|
2019-05-02 21:42:13 +02:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const formatWarn = async (warn, i) =>
|
2020-05-08 21:30:49 +02:00
|
|
|
|
isWarnNotExpired(new Date())(warn)
|
|
|
|
|
? html`${i + 1}. ${await formatEntry(warn, warn)}`
|
|
|
|
|
: html`<del>${i + 1}. ${await formatEntry(warn, warn)}</del>`;
|
2019-05-02 21:42:13 +02:00
|
|
|
|
|
2020-05-13 15:11:43 +02:00
|
|
|
|
/**
|
2020-05-25 23:25:42 +02:00
|
|
|
|
* @param {string | TgHtml | undefined } content
|
2020-05-13 15:11:43 +02:00
|
|
|
|
*/
|
2023-03-08 14:08:57 +01:00
|
|
|
|
const isNotEmpty = (content) => content?.length;
|
2020-05-13 15:11:43 +02:00
|
|
|
|
|
|
|
|
|
const optional = (header, sep, content) =>
|
2023-03-08 14:08:57 +01:00
|
|
|
|
isNotEmpty(content) ? html`${header}${sep}${content}` : html``;
|
2019-05-02 21:42:13 +02:00
|
|
|
|
|
2023-03-08 14:08:57 +01:00
|
|
|
|
const title = (user) => {
|
2020-05-08 21:30:49 +02:00
|
|
|
|
if (isMaster(user)) {
|
|
|
|
|
return html`🕴️ <b>Bot master</b>`;
|
|
|
|
|
} else if (user.status === 'admin') {
|
|
|
|
|
return html`⭐️ <b>Admin</b>`;
|
|
|
|
|
}
|
|
|
|
|
return html`👤 <b>User</b>`;
|
|
|
|
|
};
|
|
|
|
|
|
2020-03-10 22:10:48 +01:00
|
|
|
|
/** @param { import('../../typings/context').ExtendedContext } ctx */
|
2021-05-07 22:46:11 +02:00
|
|
|
|
const getWarnsHandler = async (ctx) => {
|
|
|
|
|
if (!ctx.from) {
|
2023-03-08 14:08:57 +01:00
|
|
|
|
return ctx
|
|
|
|
|
.replyWithHTML(
|
|
|
|
|
'ℹ️ <b>This command is not available in channels.</b>'
|
|
|
|
|
)
|
|
|
|
|
.then(scheduleDeletion());
|
2019-01-28 21:46:29 +01:00
|
|
|
|
}
|
2017-11-02 00:04:22 +03:30
|
|
|
|
|
2023-03-08 14:08:57 +01:00
|
|
|
|
if (typeof ctx.message === 'undefined') return;
|
|
|
|
|
if (!('text' in ctx.message)) return;
|
|
|
|
|
|
2021-05-07 22:46:11 +02:00
|
|
|
|
const { flags, targets } = parse(ctx.message);
|
2017-11-02 15:30:54 +03:30
|
|
|
|
|
2019-01-28 21:46:29 +01:00
|
|
|
|
if (targets.length > 1) {
|
2023-03-08 14:08:57 +01:00
|
|
|
|
return ctx
|
|
|
|
|
.replyWithHTML('ℹ️ <b>Specify one user.</b>')
|
|
|
|
|
.then(scheduleDeletion());
|
2019-01-28 21:46:29 +01:00
|
|
|
|
}
|
|
|
|
|
|
2023-03-08 14:08:57 +01:00
|
|
|
|
const theUser =
|
|
|
|
|
targets.length && ctx.from.status === 'admin'
|
|
|
|
|
? await getUser(strip(targets[0]))
|
|
|
|
|
: ctx.from;
|
2019-01-28 21:46:29 +01:00
|
|
|
|
|
|
|
|
|
if (!theUser) {
|
2023-03-08 14:08:57 +01:00
|
|
|
|
return ctx
|
|
|
|
|
.replyWithHTML('❓ <b>User unknown.</b>')
|
|
|
|
|
.then(scheduleDeletion());
|
2019-01-28 21:46:29 +01:00
|
|
|
|
}
|
2017-11-02 00:04:22 +03:30
|
|
|
|
|
2021-05-07 22:46:11 +02:00
|
|
|
|
if (flags.has('raw') && ctx.from.status === 'admin') {
|
2023-03-08 14:08:57 +01:00
|
|
|
|
return ctx
|
|
|
|
|
.replyWithHTML(TgHtml.pre(inspect(theUser)))
|
|
|
|
|
.then(scheduleDeletion());
|
2020-06-29 13:49:41 +02:00
|
|
|
|
}
|
|
|
|
|
|
2020-05-12 18:03:07 +02:00
|
|
|
|
const header = html`${title(theUser)} ${displayUser(theUser)}`;
|
2019-05-02 21:42:13 +02:00
|
|
|
|
const banReason = optional(
|
2020-05-13 15:11:43 +02:00
|
|
|
|
html`🚫 <b>Ban reason:</b>`,
|
|
|
|
|
' ',
|
2023-03-08 14:08:57 +01:00
|
|
|
|
await formatEntry(theUser.ban_details, theUser.ban_reason || '')
|
2019-05-02 21:42:13 +02:00
|
|
|
|
);
|
2020-05-08 21:30:49 +02:00
|
|
|
|
const { warns = [] } = theUser;
|
2019-05-02 21:42:13 +02:00
|
|
|
|
const userWarns = optional(
|
2020-05-13 15:11:43 +02:00
|
|
|
|
html`<b>⚠️ Warns:</b>`,
|
|
|
|
|
'\n',
|
2023-03-08 14:08:57 +01:00
|
|
|
|
TgHtml.join('\n', await Promise.all(warns.map(formatWarn)))
|
2019-05-02 21:42:13 +02:00
|
|
|
|
);
|
2017-11-02 00:04:22 +03:30
|
|
|
|
|
2020-05-25 23:25:42 +02:00
|
|
|
|
const firstSeen = optional(
|
|
|
|
|
html`👀 <b>First seen:</b>`,
|
|
|
|
|
' ',
|
2023-03-08 14:08:57 +01:00
|
|
|
|
formatDate(theUser.createdAt)
|
2020-05-25 23:25:42 +02:00
|
|
|
|
);
|
|
|
|
|
|
2022-03-29 13:38:04 +02:00
|
|
|
|
const permits = permit.isValid(theUser.permit)
|
2023-03-08 14:08:57 +01:00
|
|
|
|
? // eslint-disable-next-line max-len
|
|
|
|
|
`🎟 ${
|
|
|
|
|
(await getUser({ id: theUser.permit.by_id })).first_name
|
|
|
|
|
}, ${formatDate(theUser.permit.date)}`
|
2020-06-29 15:07:12 +02:00
|
|
|
|
: '';
|
|
|
|
|
|
2023-03-08 14:08:57 +01:00
|
|
|
|
const oneliners = TgHtml.join(
|
|
|
|
|
'\n',
|
|
|
|
|
[header, firstSeen, permits].filter(isNotEmpty)
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
return ctx
|
|
|
|
|
.replyWithHTML(
|
|
|
|
|
TgHtml.join(
|
|
|
|
|
'\n\n',
|
|
|
|
|
[oneliners, userWarns, banReason].filter(isNotEmpty)
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
.then(scheduleDeletion());
|
2017-11-02 00:04:22 +03:30
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
module.exports = getWarnsHandler;
|