diff --git a/framework/framework/package.json b/framework/framework/package.json index c7272e6ac..62c1c032e 100644 --- a/framework/framework/package.json +++ b/framework/framework/package.json @@ -15,7 +15,7 @@ "koa-compress": "^5.1.1", "koa-router": "^13.0.1", "lodash": "^4.17.21", - "moment-timezone": "^0.5.47", + "moment-timezone": "^0.5.48", "path-to-regexp": "^8.2.0", "sanitize-filename": "^1.6.3", "saslprep": "^1.0.3", diff --git a/install/install.ts b/install/install.ts index b2d04f2ab..e77fcaf78 100644 --- a/install/install.ts +++ b/install/install.ts @@ -253,7 +253,7 @@ parallelism: ${Math.max(1, Math.floor(cpus().length / 4))} singleTaskParallelism: 2 rate: 1.00 rerun: 2 -secret: Hydro-Judge-Secret +secret: ${String.random(32)} env: | PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin HOME=/w @@ -711,7 +711,7 @@ async function main() { while (res.code && op[1].ignore !== true) { if (op[1].retry && retry < 30) { log.warn('Retry in 3 secs... (%s)', op[0]); - // eslint-disable-next-line no-await-in-loop + await sleep(3000); res = exec(op[0], { stdio: 'inherit' }); retry++; @@ -723,9 +723,9 @@ async function main() { while (res === 'retry') { if (retry < 30) { log.warn('Retry in 3 secs...'); - // eslint-disable-next-line no-await-in-loop + await sleep(3000); - // eslint-disable-next-line no-await-in-loop + res = await op[0](op[1]); retry++; } else log.fatal('Error installing'); diff --git a/package.json b/package.json index 9a88200de..2cea346e6 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "license": "AGPL-3.0-only", "devDependencies": { "@types/autocannon": "^7.12.6", - "@types/chai": "^5.2.0", + "@types/chai": "^5.2.1", "@types/cross-spawn": "^6.0.6", "@types/node": "22.13.8", "@types/semver": "^7.5.8", diff --git a/packages/hydrojudge/setting.yaml b/packages/hydrojudge/setting.yaml deleted file mode 100644 index f4e4c5a63..000000000 --- a/packages/hydrojudge/setting.yaml +++ /dev/null @@ -1,87 +0,0 @@ -sandbox_host: - type: text - name: sandbox_host - desc: Sandbox Host - default: http://localhost:5050 -tmp_dir: - type: text - name: tmp_dir - desc: Temp directory - default: $TEMP/hydro/judge -stdio_size: - type: text - name: stdio_size - desc: Stdout/Stderr size - default: 32m -processLimit: - type: number - name: processLimit - desc: Process Limit - default: 32 -testcases_max: - type: number - name: testcases_max - desc: Max testcases per problem - default: 100 -total_time_limit: - type: number - name: total_time_limit - desc: Total time limit per problem - default: 60 -memoryMax: - type: text - name: memoryMax - default: 512m -cache_dir: - type: text - name: cache_dir - desc: Testdata cache directory - default: $HOME/.cache/hydro/judge -parallelism: - type: number - name: parallelism - desc: Runner parallelism - default: 2 -singleTaskParallelism: - type: number - name: singleTaskParallelism - default: 2 -rate: - type: float - name: rate - desc: (?) - default: 1 -rerun: - type: number - name: rerun - desc: Re-Run testcase if time-limit-exceeded (max per submission) - default: 0 -disable: - type: boolean - name: disable - desc: Disable builtin judge - default: false -strict_memory: - type: boolean - name: strict_memory - desc: Strict Memory Mode - default: false -env: - type: textarea - name: env - desc: Sandbox Env - default: | - PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin - HOME=/w - # modify to your python version installed - PYTHONPATH=/lib/python3.10/site-packages -secret: - type: text - name: secret - desc: Judge Token Secret - default: Hydro-Judge-Secret -detail: - type: boolean - name: detail - desc: Show diff detail - default: true diff --git a/packages/hydrojudge/src/config.ts b/packages/hydrojudge/src/config.ts index 38908fae1..b3d4d0c54 100644 --- a/packages/hydrojudge/src/config.ts +++ b/packages/hydrojudge/src/config.ts @@ -30,7 +30,7 @@ export const JudgeSettings = Schema.object({ rate: Schema.number().default(1), env: Schema.string().default(defaultEnv), host: Schema.any(), - secret: Schema.string().description('Judge Token Secret').default('Hydro-Judge-Secret'), + secret: Schema.string().description('Judge Token Secret').default(String.random(32)), disable: Schema.boolean().description('Disable builtin judge').default(false), detail: Schema.boolean().description('Show diff detail').default(true), performance: Schema.boolean().description('Performance mode').default(false), diff --git a/packages/hydrooj/package.json b/packages/hydrooj/package.json index 0fa8b2f3c..22c997f63 100644 --- a/packages/hydrooj/package.json +++ b/packages/hydrooj/package.json @@ -40,7 +40,7 @@ "lodash": "^4.17.21", "lru-cache": "^10.4.3", "mime-types": "^2.1.35", - "moment-timezone": "^0.5.47", + "moment-timezone": "^0.5.48", "mongodb": "^6.15.0", "mongodb-uri": "^0.9.7", "nanoid": "^5.1.5", diff --git a/packages/hydrooj/src/context.ts b/packages/hydrooj/src/context.ts index 5368fd0ef..0bc23c27b 100644 --- a/packages/hydrooj/src/context.ts +++ b/packages/hydrooj/src/context.ts @@ -9,7 +9,6 @@ import type { EventMap } from './service/bus'; import type CheckService from './service/check'; import type { } from './service/migration'; -// TODO: this is an broken declaration export { EventMap as Events }; function addScript(name: string, description: string, validate: Schema, run: (args: K, report: any) => boolean | Promise) { diff --git a/packages/hydrooj/src/entry/cli.ts b/packages/hydrooj/src/entry/cli.ts index b68313825..1d3915e37 100644 --- a/packages/hydrooj/src/entry/cli.ts +++ b/packages/hydrooj/src/entry/cli.ts @@ -8,7 +8,7 @@ import { load as loadOptions } from '../options'; import { MongoService } from '../service/db'; import { ConfigService } from '../settings'; import { - addon, builtinModel, model, service, setting, + addon, builtinModel, model, service, } from './common'; const argv = cac().parse(); @@ -125,7 +125,6 @@ export async function load(ctx: Context) { ctx.plugin(require('../service/worker')); await builtinModel(ctx); await model(pending, fail, ctx); - await setting(pending, fail, require('../model/setting')); ctx.plugin(require('../service/server')); ctx = await new Promise((resolve) => { ctx.inject(['server', 'setting', 'worker'], (c) => { diff --git a/packages/hydrooj/src/entry/common.ts b/packages/hydrooj/src/entry/common.ts index 8acdf995f..a949ae73f 100644 --- a/packages/hydrooj/src/entry/common.ts +++ b/packages/hydrooj/src/entry/common.ts @@ -79,44 +79,3 @@ export async function locale(pending: Record, fail: string[]) { } } } - -export async function setting(pending: Record, fail: string[], modelSetting: typeof import('../model/setting')) { - const map = { - system: modelSetting.SystemSetting, - account: modelSetting.AccountSetting, - preference: modelSetting.PreferenceSetting, - domain: modelSetting.DomainSetting, - }; - for (const i of Object.values(pending)) { - let p = path.resolve(i, 'setting.yaml'); - const t = i.split(path.sep); - // TODO: change this name setting to package name - const name = t[t.length - 1]; - if (!fs.existsSync(p)) p = path.resolve(i, 'settings.yaml'); - if (fs.existsSync(p) && !fail.includes(i)) { - try { - const cfg: any = yaml.load(await fs.readFile(p, 'utf-8')); - for (const key in cfg) { - let val = cfg[key].default || cfg[key].value; - if (typeof val === 'string') { - val = val - .replace(/\$TEMP/g, os.tmpdir()) - .replace(/\$HOME/g, os.homedir()); - } - const category = cfg[key].category || 'system'; - map[category]( - modelSetting.Setting( - cfg[key].family || name, category === 'system' ? `${name}.${key}` : key, val, cfg[key].type || 'text', - cfg[key].name || key, cfg[key].desc || '', - ), - ); - } - logger.info('Config load: %s', i); - } catch (e) { - app.injectUI('Notification', 'Config load fail: {0}', { args: [i], type: 'warn' }, PRIV.PRIV_VIEW_SYSTEM_NOTIFICATION); - logger.error('Config Load Fail: %s', i); - logger.error(e); - } - } - } -} diff --git a/packages/hydrooj/src/entry/worker.ts b/packages/hydrooj/src/entry/worker.ts index 0010c5c86..99ad2419e 100644 --- a/packages/hydrooj/src/entry/worker.ts +++ b/packages/hydrooj/src/entry/worker.ts @@ -9,7 +9,7 @@ import { load } from '../options'; import { MongoService } from '../service/db'; import { ConfigService } from '../settings'; import { - addon, builtinModel, locale, model, service, setting, + addon, builtinModel, locale, model, service, } from './common'; const argv = cac().parse(); @@ -53,11 +53,10 @@ export async function apply(ctx: Context) { require('../lib/index'); ctx.plugin(require('../service/monitor')); - ctx.plugin(require('../service/check')); + ctx.plugin(require('../service/check').default); await service(pending, fail, ctx); await builtinModel(ctx); await model(pending, fail, ctx); - await setting(pending, fail, require('../model/setting')); ctx = await new Promise((resolve) => { ctx.inject(['worker', 'setting'], (c) => { resolve(c); diff --git a/packages/hydrooj/src/service/check.ts b/packages/hydrooj/src/service/check.ts index 26bbdc198..0886cf3f6 100644 --- a/packages/hydrooj/src/service/check.ts +++ b/packages/hydrooj/src/service/check.ts @@ -1,7 +1,7 @@ // TODO check more import os from 'os'; -import { Dictionary } from 'lodash'; +import { DisposableList } from '@cordisjs/core'; import { Context, Service } from '../context'; import * as system from '../model/system'; import db from './db'; @@ -11,7 +11,7 @@ type ReportFunction = (message: string, ...args: any[]) => Promise; type CheckItem = (context: any, log: ReportFunction, warn: ReportFunction, error: ReportFunction) => Promise; export default class CheckService extends Service { - checkers: Dictionary = {}; + checkers = new DisposableList(); c = {}; constructor(ctx: Context) { @@ -51,24 +51,19 @@ export default class CheckService extends Service { } addChecker(type: string, checkFunc: CheckItem) { - this.ctx.effect(() => { - this.checkers[`check${type}`] = checkFunc; - return () => { - delete this.checkers[`check${type}`]; - }; - }); + this.checkers.push(checkFunc); } async run(ctx, log, warn, error, cb: (id: string) => void) { const id = String.random(6); cb(id); - for (const name in this.checkers) { + for (const check of this.checkers) { if (this.c[id]) { delete this.c[id]; return; } // eslint-disable-next-line no-await-in-loop - await this.checkers[name](ctx, log, warn, error); + await check(ctx, log, warn, error); } } diff --git a/packages/login-with-github/index.ts b/packages/login-with-github/index.ts index 106789f5a..5d04c300e 100644 --- a/packages/login-with-github/index.ts +++ b/packages/login-with-github/index.ts @@ -15,9 +15,9 @@ export default class LoginWithGithubService extends Service { ctx.provideModule('oauth', 'github', { text: 'Login with Github', callback: async function callback({ state, code }) { - const url = await SystemModel.get('server.url'); const s = await TokenModel.get(state, TokenModel.TYPE_OAUTH); if (!s) throw new ValidationError('token'); + const url = SystemModel.get('server.url'); const res = await superagent.post(`${config.endpoint || 'https://github.com'}/login/oauth/access_token`) .send({ client_id: config.id, @@ -59,8 +59,7 @@ export default class LoginWithGithubService extends Service { }, get: async function get(this: Handler) { const [state] = await TokenModel.add(TokenModel.TYPE_OAUTH, 600, { redirect: this.request.referer }); - // eslint-disable-next-line max-len - this.response.redirect = `https://github.com/login/oauth/authorize?client_id=${config.appid}&state=${state}&scope=read:user,user:email`; + this.response.redirect = `https://github.com/login/oauth/authorize?client_id=${config.id}&state=${state}&scope=read:user,user:email`; }, }); ctx.i18n.load('zh', { diff --git a/packages/login-with-google/index.ts b/packages/login-with-google/index.ts index 279c7404b..db7b6b7a7 100644 --- a/packages/login-with-google/index.ts +++ b/packages/login-with-google/index.ts @@ -64,14 +64,11 @@ export default class GoogleOAuthService extends Service { }; }, get: async function get(this: Handler) { - const [appid, url, [state]] = await Promise.all([ - config.id, - config.proxy, - TokenModel.add(TokenModel.TYPE_OAUTH, 600, { redirect: this.request.referer }), - ]); + const [state] = await TokenModel.add(TokenModel.TYPE_OAUTH, 600, { redirect: this.request.referer }); + const url = SystemModel.get('server.url'); const scope = encodeURIComponent('https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile'); // eslint-disable-next-line max-len - this.response.redirect = `https://accounts.google.com/o/oauth2/v2/auth?client_id=${appid}&response_type=code&redirect_uri=${url}oauth/google/callback&scope=${scope}&state=${state}`; + this.response.redirect = `https://accounts.google.com/o/oauth2/v2/auth?client_id=${config.id}&response_type=code&redirect_uri=${url}oauth/google/callback&scope=${scope}&state=${state}`; }, }); ctx.i18n.load('zh', { diff --git a/packages/ui-default/package.json b/packages/ui-default/package.json index c136d776b..fb301596f 100644 --- a/packages/ui-default/package.json +++ b/packages/ui-default/package.json @@ -22,7 +22,7 @@ "@fontsource/source-code-pro": "^5.2.5", "@fontsource/ubuntu-mono": "^5.2.5", "@hydrooj/utils": "workspace:^", - "@sentry/browser": "^9.8.0", + "@sentry/browser": "^9.9.0", "@sentry/webpack-plugin": "^3.2.2", "@simplewebauthn/browser": "13.1.0", "@svgr/webpack": "^8.1.0", diff --git a/packages/utils/package.json b/packages/utils/package.json index 06d5aa8a2..d34f4c887 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -12,7 +12,7 @@ "cac": "^6.7.14", "fs-extra": "^11.3.0", "js-yaml": "^4.1.0", - "moment-timezone": "^0.5.47", + "moment-timezone": "^0.5.48", "mongodb": "^6.15.0", "reggol": "^2.1.0", "search-query-parser": "^1.6.0",