bug fixes

This commit is contained in:
undefined committed 2025-03-25 00:57:56 +08:00
1 parent 68e641f28f
commit 62fb745322
15 files changed
+23 -163

No files matched your search

+1 -1
View File
@@ -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",
+4 -4
View File
@@ -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');
+1 -1
View File
@@ -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",
-87
View File
@@ -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
+1 -1
View File
@@ -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),
+1 -1
View File
@@ -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",
-1
View File
@@ -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<K>(name: string, description: string, validate: Schema<K>, run: (args: K, report: any) => boolean | Promise<boolean>) {
+1 -2
View File
@@ -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) => {
-41
View File
@@ -79,44 +79,3 @@ export async function locale(pending: Record<string, string>, fail: string[]) {
}
}
}
export async function setting(pending: Record<string, string>, 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);
}
}
}
}
+2 -3
View File
@@ -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);
+5 -10
View File
@@ -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<void>;
type CheckItem = (context: any, log: ReportFunction, warn: ReportFunction, error: ReportFunction) => Promise<void>;
export default class CheckService extends Service {
checkers: Dictionary<CheckItem> = {};
checkers = new DisposableList<CheckItem>();
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);
}
}
+2 -3
View File
@@ -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', {
+3 -6
View File
@@ -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', {
+1 -1
View File
@@ -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",
+1 -1
View File
@@ -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",