diff --git a/packages/hydrooj/src/handler/home.ts b/packages/hydrooj/src/handler/home.ts index aa5ccd59b..2fe9268cc 100644 --- a/packages/hydrooj/src/handler/home.ts +++ b/packages/hydrooj/src/handler/home.ts @@ -3,7 +3,7 @@ import yaml from 'js-yaml'; import { VerifyPasswordError, UserAlreadyExistError, InvalidTokenError, NotFoundError, UserNotFoundError, PermissionError, - DomainAlreadyExistsError, ValidationError, + DomainAlreadyExistsError, ValidationError, BlacklistedError, } from '../error'; import { Mdoc, Setting } from '../interface'; import * as bus from '../service/bus'; @@ -25,6 +25,7 @@ import * as discussion from '../model/discussion'; import token from '../model/token'; import * as training from '../model/training'; import { PERM, PRIV } from '../model/builtin'; +import BlackListModel from '../model/blacklist'; const { geoip, useragent } = global.Hydro.lib; @@ -153,10 +154,12 @@ class HomeSecurityHandler extends Handler { @param('password', Types.String) @param('mail', Types.Name, isEmail) async postChangeMail(domainId: string, current: string, email: string) { - await this.limitRate('send_mail', 3600, 30); + const mailDomain = email.split('@')[1]; + if (await BlackListModel.get(`mail::${mailDomain}`)) throw new BlacklistedError(mailDomain); this.user.checkPassword(current); const udoc = await user.getByEmail(domainId, email); if (udoc) throw new UserAlreadyExistError(email); + await this.limitRate('send_mail', 3600, 30); const [code] = await token.add( token.TYPE_CHANGEMAIL, system.get('session.unsaved_expire_seconds'), diff --git a/packages/hydrooj/src/handler/user.ts b/packages/hydrooj/src/handler/user.ts index 5fa1f5d9a..37fb8c9f7 100644 --- a/packages/hydrooj/src/handler/user.ts +++ b/packages/hydrooj/src/handler/user.ts @@ -16,6 +16,7 @@ import problem, { Pdoc } from '../model/problem'; import task from '../model/task'; import * as system from '../model/system'; import { PERM, PRIV } from '../model/builtin'; +import BlackListModel from '../model/blacklist'; import { isEmail, isPassword, isUname } from '../lib/validator'; import { sendMail } from '../lib/mail'; import paginate from '../lib/paginate'; @@ -67,6 +68,8 @@ export class UserRegisterHandler extends Handler { async post(domainId: string, mail: string, phoneNumber: string) { if (mail) { if (await user.getByEmail('system', mail)) throw new UserAlreadyExistError(mail); + const mailDomain = mail.split('@')[1]; + if (await BlackListModel.get(`mail::${mailDomain}`)) throw new BlacklistedError(mailDomain); await this.limitRate('send_mail', 3600, 30); const t = await token.add( token.TYPE_REGISTRATION, diff --git a/packages/hydrooj/src/model/blacklist.ts b/packages/hydrooj/src/model/blacklist.ts index d6bb0cd93..fe368869d 100644 --- a/packages/hydrooj/src/model/blacklist.ts +++ b/packages/hydrooj/src/model/blacklist.ts @@ -6,10 +6,10 @@ const coll = db.collection('blacklist'); class BlackListModel { @ArgMethod - static async add(ip: string) { + static async add(id: string) { const expireAt = new Date(new Date().getTime() + 365 * 24 * 60 * 60 * 1000); const res = await coll.findOneAndUpdate( - { _id: ip }, + { _id: id }, { $set: { expireAt } }, { upsert: true, returnOriginal: false }, ); @@ -17,8 +17,8 @@ class BlackListModel { } @ArgMethod - static async get(ip: string) { - return await coll.findOne({ _id: ip }); + static async get(id: string) { + return await coll.findOne({ _id: id }); } @ArgMethod diff --git a/packages/hydrooj/src/service/server.ts b/packages/hydrooj/src/service/server.ts index 950dbc13a..48cd8ebda 100644 --- a/packages/hydrooj/src/service/server.ts +++ b/packages/hydrooj/src/service/server.ts @@ -477,7 +477,7 @@ export class Handler extends HandlerCommon { } async getBdoc() { - const bdoc = await blacklist.get(this.request.ip); + const bdoc = await blacklist.get(`ip::${this.request.ip}`); if (bdoc) throw new BlacklistedError(this.request.ip); }