|
|
|
/* eslint-disable no-await-in-loop */
|
|
|
|
import * as user from '../model/user';
|
|
|
|
import * as document from '../model/document';
|
|
|
|
import * as setting from '../model/setting';
|
|
|
|
import * as db from '../service/db';
|
|
|
|
import paginate from '../lib/paginate';
|
|
|
|
import { STATUS, PRIV } from '../model/builtin';
|
|
|
|
|
|
|
|
export const description = 'Delete a user';
|
|
|
|
|
|
|
|
const collDocument = db.collection('document');
|
|
|
|
const collDomainUser = db.collection('domain.user');
|
|
|
|
const collRecord = db.collection('record');
|
|
|
|
|
|
|
|
const $unset = {
|
|
|
|
regip: '', regat: '', loginat: '', loginip: '',
|
|
|
|
};
|
|
|
|
for (const s of setting.PREFERENCE_SETTINGS) {
|
|
|
|
$unset[s.key] = '';
|
|
|
|
}
|
|
|
|
|
|
|
|
async function deleteRecord(uid: number) {
|
|
|
|
const [, pcount] = await paginate(
|
|
|
|
collRecord.find(),
|
|
|
|
1,
|
|
|
|
100,
|
|
|
|
);
|
|
|
|
for (let i = 1; i <= pcount; i++) {
|
|
|
|
const [rdocs] = await paginate(
|
|
|
|
collRecord.find(),
|
|
|
|
1,
|
|
|
|
100,
|
|
|
|
);
|
|
|
|
const tasks = [];
|
|
|
|
for (const rdoc of rdocs) {
|
|
|
|
if (rdoc.pid) {
|
|
|
|
tasks.push(document.inc(rdoc.domainId, document.TYPE_PROBLEM, rdoc.pid, 'nSubmit', -1));
|
|
|
|
}
|
|
|
|
if (rdoc.status === STATUS.STATUS_ACCEPTED) {
|
|
|
|
tasks.push(document.inc(rdoc.domainId, document.TYPE_PROBLEM, rdoc.pid, 'nAccept', -1));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
await Promise.all(tasks);
|
|
|
|
}
|
|
|
|
await collRecord.deleteMany({ uid });
|
|
|
|
}
|
|
|
|
|
|
|
|
async function deleteDiscussion(uid: number) {
|
|
|
|
const [, pcount] = await paginate(
|
|
|
|
collDocument.find({ docType: document.TYPE_DISCUSSION, owner: uid }),
|
|
|
|
1,
|
|
|
|
100,
|
|
|
|
);
|
|
|
|
for (let i = 1; i <= pcount; i++) {
|
|
|
|
const [ddocs] = await paginate(
|
|
|
|
collDocument.find({ docType: document.TYPE_DISCUSSION, owner: uid }),
|
|
|
|
1,
|
|
|
|
100,
|
|
|
|
);
|
|
|
|
const tasks = [];
|
|
|
|
for (const ddoc of ddocs) {
|
|
|
|
tasks.push(document.deleteMulti(ddoc.domainId, document.TYPE_DISCUSSION_REPLY, {
|
|
|
|
parentId: ddoc.docId,
|
|
|
|
parentType: document.TYPE_DISCUSSION,
|
|
|
|
}));
|
|
|
|
}
|
|
|
|
await Promise.all(tasks);
|
|
|
|
}
|
|
|
|
await collDocument.deleteMany({ docType: document.TYPE_DISCUSSION, owner: uid });
|
|
|
|
// TODO delete replies
|
|
|
|
}
|
|
|
|
|
|
|
|
export async function run({
|
|
|
|
uid,
|
|
|
|
}) {
|
|
|
|
await deleteRecord(uid);
|
|
|
|
await deleteDiscussion(uid);
|
|
|
|
await collDomainUser.deleteMany({ uid });
|
|
|
|
const uname = String.random(32);
|
|
|
|
await user.setById(uid, {
|
|
|
|
uname,
|
|
|
|
unameLower: uname.toLowerCase(),
|
|
|
|
priv: PRIV.PRIV_NONE,
|
|
|
|
}, $unset);
|
|
|
|
await user.setPassword(uid, String.random(32));
|
|
|
|
// TODO delete contest, homework, etc
|
|
|
|
return uid;
|
|
|
|
}
|
|
|
|
|
|
|
|
export const validate = {
|
|
|
|
uid: 'number',
|
|
|
|
};
|
|
|
|
|
|
|
|
global.Hydro.script.deleteUser = { run, description, validate };
|