You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Hydro/hydro/script/blacklist.ts

88 lines
2.8 KiB
TypeScript

/* eslint-disable no-use-before-define */
import { ObjectID } from 'mongodb';
import * as document from '../model/document';
import * as discussion from '../model/discussion';
import * as user from '../model/user';
import * as blacklist from '../model/blacklist';
import * as db from '../service/db';
export const description = 'Add blacklist by ip, uid';
async function _address(
ip: string,
bset: Set<string>, uset: Set<number>, dset: Set<ObjectID>,
dryrun: boolean, report: Function,
) {
if (bset.has(ip)) return;
bset.add(ip);
report({ message: `ip ${ip}` });
const users = await db.collection('user').find({ loginip: ip }).toArray();
const tasks = [];
for (const udoc of users) {
tasks.push(_user(udoc._id, bset, uset, dset, dryrun, report));
}
await Promise.all(tasks);
if (!dryrun) await blacklist.add(ip);
}
async function _discussion(
domainId: string, did: ObjectID,
bset: Set<string>, uset: Set<number>, dset: Set<ObjectID>,
dryrun: boolean, report: Function,
) {
if (dset.has(did)) return;
dset.add(did);
const ddoc = await discussion.get(domainId, did);
if (!ddoc) return;
report({ message: `discussion ${ddoc.title}` });
await _user(ddoc.owner, bset, uset, dset, dryrun, report);
if (ddoc.ip) await _address(ddoc.ip, bset, uset, dset, dryrun, report);
if (!dryrun) await discussion.del(domainId, ddoc.docId);
}
async function _user(
uid: number,
bset: Set<string>, uset: Set<number>, dset: Set<ObjectID>,
dryrun: boolean, report: Function,
) {
if (uset.has(uid)) return;
uset.add(uid);
const udoc = await user.getById('system', uid);
if (!udoc) return;
report({ message: `user ${udoc._id} ${udoc.uname}` });
await _address(udoc.loginip(), bset, uset, dset, dryrun, report);
const ddocs = await db.collection('document').find({ docType: document.TYPE_DISCUSSION })
.sort({ domainId: 1, docId: 1 }).toArray();
const tasks = [];
for (const ddoc of ddocs) {
tasks.push(_discussion(ddoc.domainId, ddoc.docId, bset, uset, dset, dryrun, report));
}
await Promise.all(tasks);
if (!dryrun) await user.ban(uid);
}
export async function run({
// eslint-disable-next-line no-shadow
address = null, discuss = null, user = null, dryrun = true,
}, report) {
if (address) await _address(address, new Set(), new Set(), new Set(), dryrun, report);
if (discuss) {
await _discussion(
discuss.domainId, new ObjectID(discuss.did),
new Set(), new Set(), new Set(), dryrun, report,
);
}
if (user) await _user(user, new Set(), new Set(), new Set(), dryrun, report);
}
export const validate = {
$or: {
address: 'string',
discuss: ObjectID,
user: 'number',
},
dryrun: 'boolean',
};
global.Hydro.script.blacklist = { run, description, validate };