diff --git a/packages/hydrooj/package.json b/packages/hydrooj/package.json index 05e5c9263..a559fda56 100644 --- a/packages/hydrooj/package.json +++ b/packages/hydrooj/package.json @@ -1,6 +1,6 @@ { "name": "hydrooj", - "version": "2.23.20", + "version": "2.23.21", "bin": "bin/hydrooj.js", "main": "dist/loader.js", "typings": "dist/loader.d.ts", diff --git a/packages/hydrooj/src/model/message.ts b/packages/hydrooj/src/model/message.ts index 8e33e5f07..0461a557f 100644 --- a/packages/hydrooj/src/model/message.ts +++ b/packages/hydrooj/src/model/message.ts @@ -22,11 +22,7 @@ class MessageModel { const mdoc = { from, to, content, _id: res.insertedId, flag, }; - if (from !== to) { - // ENHANCE domainId? - const udoc = await user.getById('system', to); - bus.boardcast('user/message', to, mdoc, udoc); - } + if (from !== to) bus.boardcast('user/message', to, mdoc); await user.inc(to, 'unreadMsg', 1); return mdoc; } diff --git a/packages/hydrooj/src/model/opcount.ts b/packages/hydrooj/src/model/opcount.ts index 3203b53e0..d8e39798f 100644 --- a/packages/hydrooj/src/model/opcount.ts +++ b/packages/hydrooj/src/model/opcount.ts @@ -5,26 +5,25 @@ import db from '../service/db'; const coll = db.collection('opcount'); export async function inc(op: string, ident: string, periodSecs: number, maxOperations: number) { - const curTime = new Date().getTime(); - const beginAt = new Date(curTime - (curTime % (periodSecs * 1000))); - const expireAt = new Date(beginAt.getTime() + periodSecs * 1000); + const now = new Date().getTime(); + const expireAt = new Date(now - (now % (periodSecs * 1000)) + periodSecs * 1000); try { await coll.findOneAndUpdate({ op, ident, - beginAt, expireAt, opcount: { $lt: maxOperations }, }, { $inc: { opcount: 1 } }, { upsert: true }); } catch (e) { - throw new OpcountExceededError(op, periodSecs, maxOperations); + if (e.message.includes('duplicate')) throw new OpcountExceededError(op, periodSecs, maxOperations); + throw e; } } function ensureIndexes() { return Promise.all([ coll.createIndex('expireAt', { expireAfterSeconds: 0 }), - coll.createIndex({ op: 1, ident: 1 }, { unique: true }), + coll.createIndex({ op: 1, ident: 1, expireAt: 1 }, { unique: true }), ]); } diff --git a/packages/hydrooj/src/service/bus.ts b/packages/hydrooj/src/service/bus.ts index 436de9298..28bdb32a7 100644 --- a/packages/hydrooj/src/service/bus.ts +++ b/packages/hydrooj/src/service/bus.ts @@ -45,7 +45,7 @@ export interface EventMap extends Record { 'monitor/update': (type: 'server' | 'judge', $set: any) => VoidReturn - 'user/message': (uid: number, mdoc: Mdoc, udoc: User) => void + 'user/message': (uid: number, mdoc: Mdoc) => void 'user/get': (udoc: User) => void 'domain/create': (ddoc: DomainDoc) => VoidReturn diff --git a/packages/hydrooj/src/service/server.ts b/packages/hydrooj/src/service/server.ts index 5c3c33ba5..d68f4163f 100644 --- a/packages/hydrooj/src/service/server.ts +++ b/packages/hydrooj/src/service/server.ts @@ -446,7 +446,7 @@ export class Handler extends HandlerCommon { const [xff, xhost] = system.getMany(['server.xff', 'server.xhost']); if (xff) this.request.ip = this.request.headers[xff.toLowerCase()] || this.request.ip; if (xhost) this.request.host = this.request.headers[xhost.toLowerCase()] || this.request.host; - this.noCheckPermView = true; + this.noCheckPermView = false; } // eslint-disable-next-line class-methods-use-this @@ -468,7 +468,7 @@ export class Handler extends HandlerCommon { this.response.body = data; this.response.template = null; this.response.type = 'application/octet-stream'; - this.response.disposition = `attachment; filename="${name}"`; + if (name) this.response.disposition = `attachment; filename="${name}"`; } async getSession() { @@ -477,19 +477,15 @@ export class Handler extends HandlerCommon { if (!this.session) this.session = { uid: 0 }; } - async getBdoc() { - const bdoc = await blacklist.get(`ip::${this.request.ip}`); - if (bdoc) throw new BlacklistedError(this.request.ip); - } - async init({ domainId }) { - if (!argv.benchmark) await this.limitRate('global', 10, 1); - const [absoluteDomain, inferDomain] = await Promise.all([ + if (!argv.benchmark) await this.limitRate('global', 10, 88); + const [absoluteDomain, inferDomain, bdoc] = await Promise.all([ domain.get(domainId), domain.getByHost(this.request.host), + blacklist.get(`ip::${this.request.ip}`), this.getSession(), - this.getBdoc(), ]); + if (bdoc) throw new BlacklistedError(this.request.ip); if (inferDomain && !this.request.path.startsWith('/d/')) { this.domainId = inferDomain._id; this.args.domainId = inferDomain._id; @@ -553,7 +549,7 @@ export class Handler extends HandlerCommon { this.request.json || this.response.redirect || this.request.query.noTemplate || !this.response.template) { try { - this.response.body = JSON.stringify(this.response.body, serializer, 2); + this.response.body = JSON.stringify(this.response.body, serializer); } catch (e) { this.response.body = new SystemError('Serialize failure', e.message); } @@ -738,7 +734,7 @@ export class ConnectionHandler extends HandlerCommon { } send(data: any) { - this.conn.write(JSON.stringify(data)); + this.conn.write(JSON.stringify(data, serializer)); } close(code: number, reason: string) {