diff --git a/hydro/entry/master.ts b/hydro/entry/master.ts index d24b9cfaf..9e2df1c6c 100644 --- a/hydro/entry/master.ts +++ b/hydro/entry/master.ts @@ -24,7 +24,6 @@ export async function load(call: Entry) { await fs.writeFile(lockfile, JSON.stringify(context)); global.onDestory.push(() => { fs.removeSync(lockfile); - fs.emptyDirSync(tmpdir); }); require('../lib/i18n'); require('../utils'); diff --git a/hydro/entry/worker.ts b/hydro/entry/worker.ts index be89faf8e..67303e777 100644 --- a/hydro/entry/worker.ts +++ b/hydro/entry/worker.ts @@ -37,11 +37,6 @@ export async function load() { for (const i of builtinModel) require(`../model/${i}`); for (const i of builtinHandler) require(`../handler/${i}`); await model(pending, fail); - for (const m in global.Hydro.model) { - if (global.Hydro.model[m].ensureIndexes) { - await global.Hydro.model[m].ensureIndexes(); - } - } const modelSetting = require('../model/setting'); await setting(pending, fail, modelSetting); await handler(pending, fail); @@ -50,20 +45,9 @@ export async function load() { } const notfound = require('../handler/notfound'); await notfound.apply(); - for (const i in global.Hydro.service) { - if (global.Hydro.service[i].postInit) { - try { - await global.Hydro.service[i].postInit(); - } catch (e) { - console.error(e); - } - } - } for (const i of builtinScript) require(`../script/${i}`); await script(pending, fail, active); - for (const postInit of global.Hydro.postInit) { - await postInit(); - } + for (const postInit of global.Hydro.postInit) await postInit(); pending = []; await server.start(); setInterval(() => { diff --git a/hydro/handler/user.ts b/hydro/handler/user.ts index ba6523c72..86ddc87c6 100644 --- a/hydro/handler/user.ts +++ b/hydro/handler/user.ts @@ -83,7 +83,8 @@ class UserRegisterHandler extends Handler { } class UserRegisterWithCodeHandler extends Handler { - async get({ code }) { + @param('code', Types.String) + async get(domainId: string, code: string) { this.response.template = 'user_register_with_code.html'; const { mail } = await token.get(code, token.TYPE_REGISTRATION); if (!mail) throw new InvalidTokenError(token.TYPE_REGISTRATION, code); @@ -95,14 +96,13 @@ class UserRegisterWithCodeHandler extends Handler { @param('uname', Types.String, isUname) @param('code', Types.String) async post( - domainId: string, password: string, verifyPassword: string, + domainId: string, password: string, verify: string, uname: string, code: string, ) { const { mail } = await token.get(code, token.TYPE_REGISTRATION); if (!mail) throw new InvalidTokenError(token.TYPE_REGISTRATION, code); - if (password !== verifyPassword) throw new VerifyPasswordError(); - const uid = await system.inc('user'); - await user.create(mail, uname, password, uid, this.request.ip); + if (password !== verify) throw new VerifyPasswordError(); + const uid = await user.create(mail, uname, password, undefined, this.request.ip); await token.del(code, token.TYPE_REGISTRATION); this.session.uid = uid; this.response.redirect = this.url('homepage'); diff --git a/hydro/model/blacklist.ts b/hydro/model/blacklist.ts index 6ef24b7bc..1ab5d015c 100644 --- a/hydro/model/blacklist.ts +++ b/hydro/model/blacklist.ts @@ -21,10 +21,9 @@ export function del(ip: string) { return coll.deleteOne({ _id: ip }); } -export function ensureIndexes() { +function ensureIndexes() { return coll.createIndex('expireAt', { expireAfterSeconds: 0 }); } -global.Hydro.model.blacklist = { - add, get, del, ensureIndexes, -}; +global.Hydro.postInit.push(ensureIndexes); +global.Hydro.model.blacklist = { add, get, del }; diff --git a/hydro/model/document.ts b/hydro/model/document.ts index 298baaf5d..571ff90f5 100644 --- a/hydro/model/document.ts +++ b/hydro/model/document.ts @@ -328,7 +328,7 @@ export async function revSetStatus( return await collStatus.updateOne(filter, update); } -export async function ensureIndexes() { +async function ensureIndexes() { await coll.createIndex({ domainId: 1, docType: 1, docId: 1 }, { unique: true }); await coll.createIndex({ domainId: 1, docType: 1, owner: 1, docId: -1, @@ -390,6 +390,7 @@ export async function ensureIndexes() { }, { sparse: true }); } +global.Hydro.postInit.push(ensureIndexes); global.Hydro.model.document = { add, addToSet, @@ -399,7 +400,6 @@ global.Hydro.model.document = { deleteMultiStatus, deleteOne, deleteSub, - ensureIndexes, get, getMulti, getMultiStatus, diff --git a/hydro/model/file.ts b/hydro/model/file.ts index 694fd1dee..cb6210fb0 100644 --- a/hydro/model/file.ts +++ b/hydro/model/file.ts @@ -135,13 +135,14 @@ export function url(arg0: any, name: any) { return __url(arg0, name); } -export function ensureIndexes() { +function ensureIndexes() { return Promise.all([ collChunk.createIndex({ files_id: 1, n: 1 }, { unique: true }), collFile.createIndex({ md5: 1 }), ]); } +global.Hydro.postInit.push(ensureIndexes); global.Hydro.model.file = { - add, get, del, inc, dec, getMeta, getWithSecret, getMulti, getMetaDict, url, ensureIndexes, + add, get, del, inc, dec, getMeta, getWithSecret, getMulti, getMetaDict, url, }; diff --git a/hydro/model/message.ts b/hydro/model/message.ts index 5920bb9be..b64d469eb 100644 --- a/hydro/model/message.ts +++ b/hydro/model/message.ts @@ -62,13 +62,14 @@ export function getMulti(uid: number) { return coll.find({ $or: [{ from: uid }, { to: uid }] }); } -export function ensureIndexes() { +function ensureIndexes() { return Promise.all([ coll.createIndex({ to: 1, _id: -1 }), coll.createIndex({ from: 1, _id: -1 }), ]); } +global.Hydro.postInit.push(ensureIndexes); global.Hydro.model.message = { FLAG_UNREAD, FLAG_ALERT, @@ -81,5 +82,4 @@ global.Hydro.model.message = { getMany, getMulti, send, - ensureIndexes, }; diff --git a/hydro/model/opcount.ts b/hydro/model/opcount.ts index 6f496934f..f9bd53ca7 100644 --- a/hydro/model/opcount.ts +++ b/hydro/model/opcount.ts @@ -19,8 +19,9 @@ export async function inc(op: string, ident: string, periodSecs: number, maxOper } } -export function ensureIndexes() { +function ensureIndexes() { return coll.createIndex('expireAt', { expireAfterSeconds: 0 }); } -global.Hydro.model.opcount = { inc, ensureIndexes }; +global.Hydro.postInit.push(ensureIndexes); +global.Hydro.model.opcount = { inc }; diff --git a/hydro/model/record.ts b/hydro/model/record.ts index 6fa770c04..2c6357552 100644 --- a/hydro/model/record.ts +++ b/hydro/model/record.ts @@ -80,31 +80,17 @@ export async function add( rejudged: false, }; if ((contestOrConfig as ContestInfo).type) { - // is contest data.contest = contestOrConfig as ContestInfo; } else { data.config = contestOrConfig as PretestConfig; } - const [pdoc, res] = await Promise.all([ - problem.get(domainId, pid, null), - coll.insertOne(data), - ]); + const res = await coll.insertOne(data); if (addTask) { - const t: any = { + await task.add({ type: 'judge', rid: res.insertedId, domainId, - pid: data.pid, - lang: data.lang, - code: data.code, - }; - if (t.type === 'judge') { - t.data = pdoc.data; - t.config = pdoc.config; - } else { - t.config = yaml.safeDump(contestOrConfig); - } - await task.add(t); + }); } return res.insertedId; } diff --git a/hydro/model/token.ts b/hydro/model/token.ts index f029a7d19..44f26c1f0 100644 --- a/hydro/model/token.ts +++ b/hydro/model/token.ts @@ -10,7 +10,7 @@ export const TYPE_CHANGEMAIL = 3; export const TYPE_OAUTH = 4; export const TYPE_LOSTPASS = 5; -export function ensureIndexes() { +function ensureIndexes() { return Promise.all([ coll.createIndex([{ uid: 1 }, { tokenType: 1 }, { updateAt: -1 }], { sparse: true }), coll.createIndex('expireAt', { expireAfterSeconds: 0 }), @@ -31,9 +31,8 @@ export async function add(tokenType: number, expireSeconds: number, data: any) { return [str, res.ops[0]]; } -export async function get(tokenId: string, tokenType: number, doThrow = true) { +export async function get(tokenId: string, tokenType: number) { const res = await coll.findOne({ _id: tokenId, tokenType }); - if (!res && doThrow) throw new ValidationError('token'); return res; } @@ -86,6 +85,7 @@ export function delByUid(uid: number) { return coll.deleteMany({ uid }); } +global.Hydro.postInit.push(ensureIndexes); global.Hydro.model.token = { TYPE_SESSION, TYPE_CHANGEMAIL, @@ -94,7 +94,6 @@ global.Hydro.model.token = { TYPE_REGISTRATION, TYPE_LOSTPASS, - ensureIndexes, add, createOrUpdate, get, diff --git a/hydro/model/user.ts b/hydro/model/user.ts index bd3c93555..0174f8150 100644 --- a/hydro/model/user.ts +++ b/hydro/model/user.ts @@ -85,12 +85,18 @@ export class User implements _User { } } - hasPerm(p: bigint) { - return (this.perm() & p) === p; + hasPerm(...perm: bigint[]) { + for (const i in perm) { + if ((this.perm() & perm[i]) === perm[i]) return true; + } + return false; } - hasPriv(p: number) { - return !!(this.priv & p); + hasPriv(...priv: number[]) { + for (const i in priv) { + if ((this.priv & priv[i]) === priv[i]) return true; + } + return false; } checkPassword(password: string) { @@ -215,13 +221,14 @@ export function ban(uid: number) { ]); } -export function ensureIndexes() { +function ensureIndexes() { return Promise.all([ coll.createIndex('unameLower', { unique: true }), coll.createIndex('mailLower', { sparse: true }), ]); } +global.Hydro.postInit.push(ensureIndexes); global.Hydro.model.user = { User, create, @@ -237,5 +244,4 @@ global.Hydro.model.user = { setPriv, getList, ban, - ensureIndexes, }; diff --git a/hydro/service/server.ts b/hydro/service/server.ts index 8b4205d6f..0f5d8dac7 100644 --- a/hydro/service/server.ts +++ b/hydro/service/server.ts @@ -210,7 +210,7 @@ export class Handler { query: any, path: string, params: any, - referer: any, + referer: string, json: boolean, }; @@ -218,9 +218,9 @@ export class Handler { body: any, type: string, status: number, - template: string | undefined, - redirect: string | undefined, - disposition: string | undefined, + template?: string, + redirect?: string, + disposition?: string, attachment: (name: string) => void, }; @@ -286,7 +286,7 @@ export class Handler { return res; } - async limitRate(op, periodSecs, maxOperations) { + async limitRate(op: string, periodSecs: number, maxOperations: number) { await opcount.inc(op, this.request.ip, periodSecs, maxOperations); } @@ -299,40 +299,14 @@ export class Handler { return `${this.translate(str)} - Hydro`; } - checkPerm(...args: Array) { - for (const i in args) { - if (args[i] instanceof Array) { - let p = false; - for (const j in args) { - if (this.user.hasPerm(args[i][j])) { - p = true; - break; - } - } - if (!p) throw new PermissionError([args[i]]); - // @ts-ignore - } else if (!this.user.hasPerm(args[i])) { - throw new PermissionError([[args[i]]]); - } - } + checkPerm(...args: bigint[]) { + // @ts-ignore + if (!this.user.hasPerm(...args)) throw new PermissionError(...args); } - checkPriv(...args: Array) { - for (const i in args) { - if (args[i] instanceof Array) { - let p = false; - for (const j in args) { - if (this.user.hasPriv(args[i][j])) { - p = true; - break; - } - } - if (!p) throw new PrivilegeError([args[i]]); - // @ts-ignore - } else if (!this.user.hasPriv(args[i])) { - throw new PrivilegeError([[args[i]]]); - } - } + checkPriv(...args: number[]) { + // @ts-ignore + if (!this.user.hasPriv(...args)) throw new PrivilegeError(...args); } url(name: string, kwargs = {}) { @@ -373,7 +347,7 @@ export class Handler { async getSession() { const sid = this.request.cookies.get('sid'); - this.session = await token.get(sid, token.TYPE_SESSION, false); + this.session = await token.get(sid, token.TYPE_SESSION); if (!this.session) this.session = { uid: 0 }; } @@ -416,7 +390,10 @@ export class Handler { } catch (error) { this.response.status = error instanceof UserFacingError ? error.code : 500; if (this.request.json) this.response.body = { error }; - else await this.render(error instanceof UserFacingError ? 'error.html' : 'bsod.html', { error }); + else { + await this.render(error instanceof UserFacingError ? 'error.html' : 'bsod.html', { error }) + .catch(() => { }); + } } await this.putResponse(); await this.saveCookie(); @@ -720,11 +697,8 @@ export class ConnectionHandler { } async init({ domainId }) { - try { - this.session = await token.get(this.request.params.token, token.TYPE_TOKEN, true); - } catch (e) { - this.session = { uid: 0, domainId: 'system' }; - } + this.session = await token.get(this.request.params.token, token.TYPE_TOKEN); + this.session = this.session || { uid: 0, domainId: 'system' }; this.args.domainId = this.session.domainId; const bdoc = await blacklist.get(this.request.ip); if (bdoc) throw new BlacklistedError(this.request.ip); diff --git a/package.json b/package.json index dfa8290e8..0c5337af1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "hydrooj", - "version": "2.10.6", + "version": "2.10.7", "main": "dist/loader.js", "bin": "bin/hydrooj.js", "repository": "https://github.com/hydro-dev/Hydro.git",