diff --git a/.gitignore b/.gitignore index 14481f1f..d5ef27b3 100644 --- a/.gitignore +++ b/.gitignore @@ -23,6 +23,7 @@ tsconfig.json packages/**/*.js !/build/build.js !**/bin/*.js +!*.page.js # Data files *.mmdb diff --git a/packages/hydrooj/package.json b/packages/hydrooj/package.json index 4ee70733..f0334ac5 100644 --- a/packages/hydrooj/package.json +++ b/packages/hydrooj/package.json @@ -1,6 +1,6 @@ { "name": "hydrooj", - "version": "2.20.29", + "version": "2.20.30", "bin": "bin/hydrooj.js", "main": "dist/loader.js", "typings": "dist/loader.d.ts", diff --git a/packages/hydrooj/src/handler/judge.ts b/packages/hydrooj/src/handler/judge.ts index 610068c2..6b7660c0 100644 --- a/packages/hydrooj/src/handler/judge.ts +++ b/packages/hydrooj/src/handler/judge.ts @@ -33,6 +33,7 @@ async function _postJudge(rdoc: Rdoc) { : await problem.get(rdoc.domainId, rdoc.pid); const difficulty = difficultyAlgorithm(pdoc.nSubmit, pdoc.nAccept); await problem.edit(pdoc.domainId, pdoc.docId, { difficulty }); + await bus.serial('record/judge', rdoc, updated); } export async function next(body: JudgeResultBody) { diff --git a/packages/hydrooj/src/handler/manage.ts b/packages/hydrooj/src/handler/manage.ts index 1a759655..42d454eb 100644 --- a/packages/hydrooj/src/handler/manage.ts +++ b/packages/hydrooj/src/handler/manage.ts @@ -8,6 +8,7 @@ import * as system from '../model/system'; import user from '../model/user'; import { STATUS, PRIV } from '../model/builtin'; import record from '../model/record'; +import domain from '../model/domain'; import { Route, Connection, Handler, ConnectionHandler, param, Types, } from '../service/server'; @@ -193,14 +194,23 @@ class SystemUserImportHandler extends SystemHandler { const messages = []; for (const i in users) { const u = users[i]; - const [email, username, password] = u.split(',').map((t) => t.trim()); + const [email, username, password, displayName] = u.split(',').map((t) => t.trim()); if (email && username && password) { if (!isEmail(email)) messages.push(`Line ${i + 1}: Invalid email.`); else if (!isUname(username)) messages.push(`Line ${i + 1}: Invalid username`); else if (!isPassword(password)) messages.push(`Line ${i + 1}: Invalid password`); else { - udocs.push({ email, username, password }); - if (!confirm) tasks.push(user.create(email, username, password)); + udocs.push({ + email, username, password, displayName, + }); + if (!confirm) { + tasks.push( + user.create(email, username, password).then((uid) => { + if (displayName) return domain.setUserInDomain(domainId, uid, { displayName }); + return Promise.resolve(); + }), + ); + } } } else messages.push(`Line ${i + 1}: Input invalid.`); } diff --git a/packages/hydrooj/src/handler/problem.ts b/packages/hydrooj/src/handler/problem.ts index 54f70485..80807966 100644 --- a/packages/hydrooj/src/handler/problem.ts +++ b/packages/hydrooj/src/handler/problem.ts @@ -447,6 +447,7 @@ export class ProblemSolutionHandler extends ProblemDetailHandler { this.response.body = { path, psdocs, page, pcount, pscount, udict, pssdict, pdoc: this.pdoc, }; + await bus.serial('handler/solution/get', this); } @param('content', Types.String, isContent) diff --git a/packages/hydrooj/src/service/bus.ts b/packages/hydrooj/src/service/bus.ts index 7a459144..bcf8bb95 100644 --- a/packages/hydrooj/src/service/bus.ts +++ b/packages/hydrooj/src/service/bus.ts @@ -10,6 +10,7 @@ import type { } from '../interface'; import type { DomainDoc } from '../loader'; import type { DocType } from '../model/document'; +import type { ProblemSolutionHandler } from '../handler/problem'; const _hooks: Record any>> = {}; const logger = new Logger('bus', true); @@ -59,6 +60,8 @@ export interface EventMap { $set: any, $unset: OnlyFieldsOfType ) => VoidReturn + 'handler/solution/get': (thisArg: ProblemSolutionHandler) => VoidReturn + 'discussion/before-add': ( domainId: string, parentType: number, parentId: ObjectID | number | string, owner: number, title: string, content: string, @@ -76,6 +79,7 @@ export interface EventMap { 'training/get': (tdoc: TrainingDoc, handler: any) => VoidReturn 'record/change': (rdoc: Rdoc, $set?: any, $push?: any) => void + 'record/judge': (rdoc: Rdoc, updated: boolean) => VoidReturn } function getHooks(name: K) { diff --git a/packages/hydrooj/src/service/server.ts b/packages/hydrooj/src/service/server.ts index b668968c..590e732a 100644 --- a/packages/hydrooj/src/service/server.ts +++ b/packages/hydrooj/src/service/server.ts @@ -4,7 +4,9 @@ import { resolve } from 'path'; import os from 'os'; import http from 'http'; import moment from 'moment-timezone'; -import { isSafeInteger, Dictionary, filter } from 'lodash'; +import { + isSafeInteger, Dictionary, filter, cloneDeep, +} from 'lodash'; import { ObjectID } from 'mongodb'; import Koa, { Context } from 'koa'; import Body from 'koa-body'; @@ -245,6 +247,11 @@ export async function prepare() { })); } +export const UiContextBase = { + cdn_prefix: '/', + url_prefix: '/', +}; + export class HandlerCommon { domainId: string; domain: DomainDoc; @@ -326,7 +333,7 @@ export class HandlerCommon { } export class Handler extends HandlerCommon { - UIContext: any; + UiContext: any; args: any; ctx: Koa.Context; @@ -394,10 +401,8 @@ export class Handler extends HandlerCommon { }, disposition: null, }; - this.UIContext = { - cdn_prefix: '/', - url_prefix: '/', - }; + this.UiContext = cloneDeep(UiContextBase); + this.UiContext.cdn_prefix = system.get('server.cdn'); this.session = {}; const xff = system.get('server.xff'); if (xff) this.request.ip = this.request.headers[xff.toLowerCase()] || this.request.ip; @@ -465,7 +470,7 @@ export class Handler extends HandlerCommon { } if (this.user._id === 0 && this.session.viewLang) this.user.viewLang = this.session.viewLang; this.csrfToken = this.getCsrfToken(this.session._id || String.random(32)); - this.UIContext.csrfToken = this.csrfToken; + this.UiContext.csrfToken = this.csrfToken; this.loginMethods = filter(Object.keys(global.Hydro.lib), (str) => str.startsWith('oauth_')) .map((key) => ({ id: key.split('_')[1], @@ -801,6 +806,7 @@ global.Hydro.service.server = { app, server, router, + UiContextBase, get, post, route,