diff --git a/README.md b/README.md index a31cd686f..c67422e05 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,25 @@ Telegram [@webpack_exports_undefined](https://t.me/webpack_exports_undefined)

更新日志(点击展开)

+### HYdro 4.8.0 / UI 4.47.6 +- core: 升级至 mongodb@5 +- ui: 评测详情中显示子任务得分 +- core: 修复测试数据文件名以空格开头导致操作异常的问题 +- dev: 升级 devcontainer 环境 +- ui: 优化 IDE 页面布局 +- ui: 使用 cordis 进行生命周期管理(移除旧 bus) +- blog: 移动功能到独立的 `@hydrooj/blog` 插件 +- core: 支持动态设置 +- judge: 性能模式(关闭单点回调) +- ui: 支持为作业设置维护者 +- core: 放行提交答案题至提交语言白名单 +- import-qduoj: 修复空标签导致无法导入的问题 +- ui: 精简 serviceworker 逻辑 +- ui: 修复训练计划加入失败的问题 +- core: 简化 user 返回字段列表 +- core&ui: contest.rule.ioi.strict +- 其他漏洞修复和体验优化 + ### Hydro 4.7.3 / UI 4.47.3 - core: 修复无输入自测 - core: 修复 endpointForUser 域名不一致导致的 token 无效问题 diff --git a/package.json b/package.json index f1dc59108..8825de877 100644 --- a/package.json +++ b/package.json @@ -36,8 +36,8 @@ "@types/node": "^18.14.1", "@types/semver": "^7.3.13", "@types/supertest": "^2.0.12", - "@typescript-eslint/eslint-plugin": "^5.53.0", - "@typescript-eslint/parser": "^5.53.0", + "@typescript-eslint/eslint-plugin": "^5.54.0", + "@typescript-eslint/parser": "^5.54.0", "autocannon": "^7.10.0", "cac": "^6.7.14", "chokidar": "^3.5.3", diff --git a/packages/hydrojudge/package.json b/packages/hydrojudge/package.json index d6b2be8bc..04241d953 100644 --- a/packages/hydrojudge/package.json +++ b/packages/hydrojudge/package.json @@ -1,14 +1,13 @@ { "name": "@hydrooj/hydrojudge", "bin": "bin/hydrojudge.js", - "version": "3.1.18", + "version": "3.1.19", "main": "package.json", "author": "undefined ", "repository": "https://github.com/hydro-dev/Hydro.git", "dependencies": { "@hydrooj/utils": "workspace:*", "cac": "^6.7.14", - "fs-extra": "^11.1.0", "mongodb": "^5.1.0", "p-queue": "^7.3.4", "schemastery": "^3.7.1", @@ -19,7 +18,6 @@ "preferUnplugged": true, "license": "AGPL-3.0-or-later", "devDependencies": { - "@types/fs-extra": "^11.0.1", "@types/shell-quote": "^1.7.1", "@types/ws": "^8.5.4" } diff --git a/packages/hydrojudge/src/cache.ts b/packages/hydrojudge/src/cache.ts index 44ce8e7e1..04f278fbb 100644 --- a/packages/hydrojudge/src/cache.ts +++ b/packages/hydrojudge/src/cache.ts @@ -2,7 +2,7 @@ import './utils'; import path from 'path'; import cac from 'cac'; -import fs from 'fs-extra'; +import { fs } from '@hydrooj/utils'; import { getConfig } from './config'; import { Logger } from './log'; diff --git a/packages/hydrojudge/src/cases.ts b/packages/hydrojudge/src/cases.ts index 36d707166..a86e0ca58 100644 --- a/packages/hydrojudge/src/cases.ts +++ b/packages/hydrojudge/src/cases.ts @@ -1,9 +1,9 @@ /* eslint-disable no-await-in-loop */ import path from 'path'; -import fs from 'fs-extra'; +import { + changeErrorType, fs, normalizeSubtasks, readSubtasksFromFiles, yaml, +} from '@hydrooj/utils'; import readYamlCases, { convertIniConfig } from '@hydrooj/utils/lib/cases'; -import { normalizeSubtasks, readSubtasksFromFiles } from '@hydrooj/utils/lib/common'; -import { changeErrorType, yaml } from '@hydrooj/utils/lib/utils'; import { ProblemConfigFile } from 'hydrooj'; import { getConfig } from './config'; import { FormatError, SystemError } from './error'; diff --git a/packages/hydrojudge/src/config.ts b/packages/hydrojudge/src/config.ts index a9d1fd2fe..cc285c4bb 100644 --- a/packages/hydrojudge/src/config.ts +++ b/packages/hydrojudge/src/config.ts @@ -1,9 +1,8 @@ import os from 'os'; import path from 'path'; import cac from 'cac'; -import fs from 'fs-extra'; import Schema from 'schemastery'; -import { yaml } from '@hydrooj/utils'; +import { fs, yaml } from '@hydrooj/utils'; const argv = cac().parse(); diff --git a/packages/hydrojudge/src/daemon.ts b/packages/hydrojudge/src/daemon.ts index e4b7f4993..e4e369b52 100644 --- a/packages/hydrojudge/src/daemon.ts +++ b/packages/hydrojudge/src/daemon.ts @@ -15,8 +15,8 @@ ~ */ import './utils'; -import fs from 'fs-extra'; import PQueue from 'p-queue'; +import { fs } from '@hydrooj/utils'; import { getConfig } from './config'; import HydroHost from './hosts/hydro'; import log from './log'; diff --git a/packages/hydrojudge/src/hosts/builtin.ts b/packages/hydrojudge/src/hosts/builtin.ts index fc95765c9..981b74e27 100644 --- a/packages/hydrojudge/src/hosts/builtin.ts +++ b/packages/hydrojudge/src/hosts/builtin.ts @@ -1,7 +1,7 @@ // Hydro Integration /* eslint-disable no-await-in-loop */ import path from 'path'; -import fs from 'fs-extra'; +import { fs } from '@hydrooj/utils'; import { JudgeResultBody, RecordModel, SettingModel, StorageModel, SystemModel, TaskModel, diff --git a/packages/hydrojudge/src/hosts/hydro.ts b/packages/hydrojudge/src/hosts/hydro.ts index 862ed96e5..3f1c8774a 100644 --- a/packages/hydrojudge/src/hosts/hydro.ts +++ b/packages/hydrojudge/src/hosts/hydro.ts @@ -1,10 +1,10 @@ /* eslint-disable no-await-in-loop */ import path from 'path'; -import fs from 'fs-extra'; import { ObjectId } from 'mongodb'; import PQueue from 'p-queue'; import superagent from 'superagent'; import WebSocket from 'ws'; +import { fs } from '@hydrooj/utils'; import { LangConfig } from '@hydrooj/utils/lib/lang'; import * as sysinfo from '@hydrooj/utils/lib/sysinfo'; import type { JudgeResultBody } from 'hydrooj'; diff --git a/packages/hydrojudge/src/judge/hack.ts b/packages/hydrojudge/src/judge/hack.ts index 336bd9361..93867daa8 100644 --- a/packages/hydrojudge/src/judge/hack.ts +++ b/packages/hydrojudge/src/judge/hack.ts @@ -1,6 +1,6 @@ /* eslint-disable no-sequences */ -import { unlinkSync } from 'fs'; import { basename } from 'path'; +import { fs } from '@hydrooj/utils'; import { STATUS } from '@hydrooj/utils/lib/status'; import checkers from '../checkers'; import compile, { compileChecker, compileValidator } from '../compile'; @@ -26,7 +26,7 @@ export async function judge(ctx: Context) { compileValidator(session.getLang, config.validator, judgeExtraFiles).then(markCleanup), ctx.session.fetchFile(ctx.files.hack), ]); - ctx.clean.push(async () => unlinkSync(input)); + ctx.clean.push(() => fs.unlink(input)); ctx.next({ status: STATUS.STATUS_JUDGING, progress: 0 }); const validateResult = await run( validator.execute, diff --git a/packages/hydrojudge/src/judge/objective.ts b/packages/hydrojudge/src/judge/objective.ts index 897657e30..cd3f50a7a 100644 --- a/packages/hydrojudge/src/judge/objective.ts +++ b/packages/hydrojudge/src/judge/objective.ts @@ -1,6 +1,5 @@ import assert from 'assert'; -import { readFile } from 'fs-extra'; -import { yaml } from '@hydrooj/utils'; +import { fs, yaml } from '@hydrooj/utils'; import { STATUS } from '@hydrooj/utils/lib/status'; import { FormatError } from '../error'; import { Context } from './interface'; @@ -10,7 +9,7 @@ export async function judge({ }: Context) { next({ status: STATUS.STATUS_JUDGING, progress: 0 }); const answer = ('src' in code) - ? await readFile(code.src, 'utf-8') + ? await fs.readFile(code.src, 'utf-8') : ('content' in code) ? code.content.toString().replace(/\r/g, '') : ''; diff --git a/packages/hydrojudge/src/judge/submit_answer.ts b/packages/hydrojudge/src/judge/submit_answer.ts index db31a483c..3162252e4 100644 --- a/packages/hydrojudge/src/judge/submit_answer.ts +++ b/packages/hydrojudge/src/judge/submit_answer.ts @@ -1,5 +1,5 @@ import { basename } from 'path'; -import { readFile } from 'fs-extra'; +import { fs } from '@hydrooj/utils'; import { STATUS } from '@hydrooj/utils/lib/status'; import checkers from '../checkers'; import { compileChecker } from '../compile'; @@ -13,7 +13,7 @@ function judgeCase(c: NormalizedCase) { const chars = /[a-zA-Z0-9_.-]/; const name = (ctx.config.filename && /^[a-zA-Z0-9-_#.]+$/.test(ctx.config.filename)) ? ctx.config.filename.replace('#', c.id.toString()) - : await readFile(c.input, 'utf-8').then((res) => res.trim().split('').filter((i) => chars.test(i)).join('')); + : await fs.readFile(c.input, 'utf-8').then((res) => res.trim().split('').filter((i) => chars.test(i)).join('')); let file = ctx.code; let status = STATUS.STATUS_ACCEPTED; let message: any = ''; diff --git a/packages/hydrojudge/src/task.ts b/packages/hydrojudge/src/task.ts index 76599ea14..4efbead94 100644 --- a/packages/hydrojudge/src/task.ts +++ b/packages/hydrojudge/src/task.ts @@ -1,4 +1,4 @@ -import fs from 'fs-extra'; +import { fs } from '@hydrooj/utils'; import { LangConfig } from '@hydrooj/utils/lib/lang'; import { STATUS } from '@hydrooj/utils/lib/status'; import type { diff --git a/packages/hydrojudge/src/utils.ts b/packages/hydrojudge/src/utils.ts index c6c4993c2..f30f99dfb 100644 --- a/packages/hydrojudge/src/utils.ts +++ b/packages/hydrojudge/src/utils.ts @@ -1,7 +1,6 @@ import path from 'path'; -import fs from 'fs-extra'; import { parse } from 'shell-quote'; -import { sleep } from '@hydrooj/utils/lib/utils'; +import { fs, sleep } from '@hydrooj/utils'; import { FormatError } from './error'; const EMPTY_STR = /^[ \r\n\t]*$/i; diff --git a/packages/hydrooj/package.json b/packages/hydrooj/package.json index 2dcc15368..26e063cb1 100644 --- a/packages/hydrooj/package.json +++ b/packages/hydrooj/package.json @@ -1,6 +1,6 @@ { "name": "hydrooj", - "version": "4.7.9", + "version": "4.8.0", "bin": "bin/hydrooj.js", "main": "src/plugin-api", "module": "src/plugin-api", @@ -12,11 +12,11 @@ }, "preferUnplugged": true, "dependencies": { - "@aws-sdk/client-s3": "^3.279.0", - "@aws-sdk/lib-storage": "^3.279.0", - "@aws-sdk/middleware-endpoint": "^3.272.0", - "@aws-sdk/s3-presigned-post": "^3.279.0", - "@aws-sdk/s3-request-presigner": "^3.279.0", + "@aws-sdk/client-s3": "^3.282.0", + "@aws-sdk/lib-storage": "^3.282.0", + "@aws-sdk/middleware-endpoint": "^3.282.0", + "@aws-sdk/s3-presigned-post": "^3.282.0", + "@aws-sdk/s3-request-presigner": "^3.282.0", "@graphql-tools/schema": "^9.0.16", "@hydrooj/utils": "workspace:*", "@simplewebauthn/server": "^7.0.1", diff --git a/packages/hydrooj/src/handler/user.ts b/packages/hydrooj/src/handler/user.ts index f677aa852..f098adf26 100644 --- a/packages/hydrooj/src/handler/user.ts +++ b/packages/hydrooj/src/handler/user.ts @@ -94,8 +94,12 @@ class UserLoginHandler extends Handler { let udoc = await user.getByEmail(domainId, uname); udoc ||= await user.getByUname(domainId, uname); if (!udoc) throw new UserNotFoundError(uname); - if (system.get('system.contestmode') && udoc._loginip && udoc._loginip !== this.request.ip) { - if (!udoc.hasPriv(PRIV.PRIV_EDIT_SYSTEM)) throw new ValidationError('ip'); + if (system.get('system.contestmode') && !udoc.hasPriv(PRIV.PRIV_EDIT_SYSTEM)) { + if (udoc._loginip && udoc._loginip !== this.request.ip) throw new ValidationError('ip'); + if (system.get('system.contestmode') === 'strict') { + const udocs = await user.getMulti({ loginip: this.request.ip, _id: { $ne: udoc._id } }).toArray(); + if (udocs.length) throw new ValidationError('ip'); + } } await Promise.all([ this.limitRate('user_login', 60, 30, false), diff --git a/packages/migrate/package.json b/packages/migrate/package.json index fbb369575..a4df48a8a 100644 --- a/packages/migrate/package.json +++ b/packages/migrate/package.json @@ -1,6 +1,6 @@ { "name": "@hydrooj/migrate", - "version": "0.2.2", + "version": "0.2.3", "main": "index.ts", "repository": "git@github.com:hydro-dev/Hydro.git", "author": "undefined ", diff --git a/packages/ui-default/components/monaco/languages/markdown.ts b/packages/ui-default/components/monaco/languages/markdown.ts index bda6e4291..ec3ec72ea 100644 --- a/packages/ui-default/components/monaco/languages/markdown.ts +++ b/packages/ui-default/components/monaco/languages/markdown.ts @@ -94,7 +94,7 @@ monaco.languages.registerCompletionItemProvider('markdown', { suggestions: users.map((i) => ({ label: { label: `@${i.uname}`, description: `UID=${i._id}` }, kind: monaco.languages.CompletionItemKind.Property, - documentation: { value: `[](#loader) ![avatar](${i.avatarUrl})`, isTrusted: true }, + documentation: { value: `[](#loader) ![avatar](${new URL(i.avatarUrl, window.location.href)})`, isTrusted: true }, insertText: `@[](/user/${i._id}) `, range, sortText: i.priv === 0 ? '0' : '1', diff --git a/packages/ui-default/package.json b/packages/ui-default/package.json index a3427b8a1..6b3976fb6 100644 --- a/packages/ui-default/package.json +++ b/packages/ui-default/package.json @@ -1,6 +1,6 @@ { "name": "@hydrooj/ui-default", - "version": "4.47.5", + "version": "4.47.6", "author": "undefined ", "license": "AGPL-3.0", "main": "index.ts", @@ -14,7 +14,7 @@ "cli": false }, "devDependencies": { - "@blueprintjs/core": "4.15.1", + "@blueprintjs/core": "4.17.4", "@fontsource/dm-mono": "^4.5.10", "@fontsource/fira-code": "^4.5.13", "@fontsource/inconsolata": "^4.5.10", @@ -66,7 +66,7 @@ "jquery.transit": "^0.9.12", "matchmedia-polyfill": "^0.3.2", "moment": "^2.29.4", - "monaco-editor": "0.33.0", + "monaco-editor": "0.36.1", "monaco-editor-nls": "^2.0.0", "monaco-themes": "^0.4.3", "monaco-yaml": "^4.0.4", diff --git a/packages/utils/package.json b/packages/utils/package.json index 3c1190ba5..d4a70f5fe 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "@hydrooj/utils", - "version": "1.4.8", + "version": "1.4.9", "description": "hydrooj utils", "main": "lib/utils.ts", "repository": "https://github.com/hydro-dev/Hydro.git", @@ -16,7 +16,7 @@ "mongodb": "^5.1.0", "reggol": "^1.3.5", "source-map-support": "^0.5.21", - "systeminformation": "^5.17.10" + "systeminformation": "^5.17.12" }, "devDependencies": { "@types/fs-extra": "^11.0.1", diff --git a/packages/vjudge/package.json b/packages/vjudge/package.json index 8ede1c743..dfe6d9cdc 100644 --- a/packages/vjudge/package.json +++ b/packages/vjudge/package.json @@ -1,6 +1,6 @@ { "name": "@hydrooj/vjudge", - "version": "1.8.3", + "version": "1.8.4", "description": "Submit problems to remote oj", "main": "src/model.ts", "repository": "https://github.com/hydro-dev/Hydro.git",