mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-17 17:36:08 +08:00
添加全局rate_limit,更换ui节点接口
This commit is contained in:
1 parent
02c1866963
commit
03dc8903e2
22 files changed
+231
-216
No files matched your search
@@ -10,6 +10,7 @@ import {
|
||||
Route, Handler, param, Types,
|
||||
} from 'hydrooj/dist/service/server';
|
||||
import { streamToBuffer } from 'hydrooj/dist/utils';
|
||||
import { ProblemAdd } from 'hydrooj/dist/lib/ui';
|
||||
import * as file from 'hydrooj/dist/model/file';
|
||||
import { PERM } from 'hydrooj/dist/model/builtin';
|
||||
|
||||
@@ -123,6 +124,7 @@ class FpsProblemImportHandler extends Handler {
|
||||
|
||||
export async function apply() {
|
||||
Route('problem_import_fps', '/problem/import/fps', FpsProblemImportHandler, PERM.PERM_CREATE_PROBLEM);
|
||||
ProblemAdd('problem_import_fps', {}, 'copy', 'From FPS File');
|
||||
}
|
||||
|
||||
global.Hydro.handler.fpsImport = apply;
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@hydrooj/fps-importer",
|
||||
"version": "1.0.8",
|
||||
"version": "1.1.0",
|
||||
"description": "Import FPS problems",
|
||||
"main": "package.json",
|
||||
"repository": "https://github.com/hydro-dev/Hydro.git",
|
||||
@@ -16,7 +16,7 @@
|
||||
"bson": "^4.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"hydrooj": "^2.12.22"
|
||||
"hydrooj": "^2.13.0"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import 'hydrooj';
|
||||
import 'hydrooj/src/lib/i18n';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { Reader } from 'maxmind';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@hydrooj/geoip",
|
||||
"version": "1.1.13",
|
||||
"version": "1.1.14",
|
||||
"main": "package.json",
|
||||
"repository": "git@github.com:hydro-dev/Hydro.git",
|
||||
"author": "undefined <masnn0@outlook.com>",
|
||||
@@ -9,6 +9,6 @@
|
||||
"maxmind": "^4.1.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"hydrooj": "^2.12.0"
|
||||
"hydrooj": "^2.12.0||^2.13.0"
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
jest.mock('hydrooj/src/loader');
|
||||
import 'hydrooj';
|
||||
import 'hydrooj/src/lib/i18n';
|
||||
import * as lib from '@hydrooj/geoip/lib';
|
||||
|
||||
describe('geoip', () => {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@hydrooj/hydrojudge",
|
||||
"version": "2.0.9",
|
||||
"version": "2.0.10",
|
||||
"main": "package.json",
|
||||
"author": "masnn",
|
||||
"os": [
|
||||
@@ -10,13 +10,15 @@
|
||||
"axios": "^0.19.0",
|
||||
"bson": "^4.1.0",
|
||||
"fs-extra": "^9.0.1",
|
||||
"hydrooj": "^2.12.0",
|
||||
"js-yaml": "^3.14.0",
|
||||
"lodash": "^4.17.20",
|
||||
"p-queue": "^6.6.1",
|
||||
"shell-quote": "^1.7.2",
|
||||
"systeminformation": "^4.27.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"hydrooj": "^2.12.0||^2.13.0"
|
||||
},
|
||||
"license": "AGPL-3.0-only",
|
||||
"devDependencies": {
|
||||
"@types/bson": "^4.0.2",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "hydrooj",
|
||||
"version": "2.12.27",
|
||||
"version": "2.13.0",
|
||||
"bin": "bin/hydrooj.js",
|
||||
"main": "dist/loader.js",
|
||||
"typings": "dist/loader.d.ts",
|
||||
|
||||
@@ -8,7 +8,7 @@ import { argv } from 'yargs';
|
||||
export const builtinLib = [
|
||||
'jwt', 'download', 'i18n', 'mail', 'useragent',
|
||||
'md5', 'misc', 'paginate', 'hash.hydro', 'rank',
|
||||
'validator', 'nav', 'sysinfo', 'testdata.convert.ini', 'testdataConfig',
|
||||
'validator', 'ui', 'sysinfo', 'testdata.convert.ini', 'testdataConfig',
|
||||
'logger',
|
||||
];
|
||||
|
||||
@@ -21,7 +21,7 @@ export const builtinModel = [
|
||||
|
||||
export const builtinHandler = [
|
||||
'home', 'problem', 'record', 'judge', 'user',
|
||||
'contest', 'training', 'discussion', 'manage', 'import',
|
||||
'contest', 'training', 'discussion', 'manage', 'import.syzoj',
|
||||
'misc', 'homework', 'domain',
|
||||
];
|
||||
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import os from 'os';
|
||||
import assert from 'assert';
|
||||
import superagent from 'superagent';
|
||||
import { ValidationError, RemoteOnlineJudgeError } from '../error';
|
||||
import * as problem from '../model/problem';
|
||||
import { PERM } from '../model/builtin';
|
||||
import {
|
||||
Route, Handler, Types, param,
|
||||
} from '../service/server';
|
||||
import { isPid } from '../lib/validator';
|
||||
import download from '../lib/download';
|
||||
|
||||
const RE_SYZOJ = /https?:\/\/([a-zA-Z0-9.]+)\/problem\/([0-9]+)\/?/i;
|
||||
|
||||
class ProblemImportSYZOJHandler extends Handler {
|
||||
async get() {
|
||||
this.response.template = 'problem_import_syzoj.html';
|
||||
this.response.body = {
|
||||
path: [
|
||||
['Hydro', 'homepage'],
|
||||
['problem_main', 'problem_main'],
|
||||
['problem_import_syzoj', null],
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
@param('url', Types.String)
|
||||
@param('pid', Types.String, true, isPid)
|
||||
@param('hidden', Types.Boolean)
|
||||
async post(domainId: string, url: string, targetPid: string, hidden = false) {
|
||||
assert(url.match(RE_SYZOJ), new ValidationError('url'));
|
||||
if (!url.endsWith('/')) url += '/';
|
||||
const [, host, pid] = RE_SYZOJ.exec(url);
|
||||
const res = await superagent.get(`${url}export`);
|
||||
assert(res.status === 200, new RemoteOnlineJudgeError('Cannot connect to target server'));
|
||||
assert(res.body.success, new RemoteOnlineJudgeError((res.body.error || {}).message));
|
||||
const p = res.body.obj;
|
||||
const content = [];
|
||||
if (p.description) {
|
||||
content.push(
|
||||
`## ${this.translate('Description')}`,
|
||||
p.description,
|
||||
);
|
||||
}
|
||||
if (p.input_format) {
|
||||
content.push(
|
||||
`## ${this.translate('Input Format')}`,
|
||||
p.input_format,
|
||||
);
|
||||
}
|
||||
if (p.output_format) {
|
||||
content.push(
|
||||
`## ${this.translate('Output Format')}`,
|
||||
p.output_format,
|
||||
);
|
||||
}
|
||||
if (p.example) content.push(p.example);
|
||||
if (p.hint) {
|
||||
content.push(
|
||||
`## ${this.translate('Hint')}`,
|
||||
p.hint,
|
||||
);
|
||||
}
|
||||
if (p.limit_and_hint) {
|
||||
content.push(
|
||||
`## ${this.translate('Limit And Hint')}`,
|
||||
p.limit_and_hint,
|
||||
);
|
||||
}
|
||||
if (p.have_additional_file) {
|
||||
content.push(
|
||||
`## ${this.translate('Additional File')}`,
|
||||
`${url}download/additional_file`,
|
||||
);
|
||||
}
|
||||
const docId = await problem.add(
|
||||
domainId, targetPid || `${host}_${pid}`, p.title, content.join(' \n'), this.user._id,
|
||||
p.tags || [], [], null, hidden,
|
||||
);
|
||||
const r = download(`${url}testdata/download`);
|
||||
const file = path.resolve(os.tmpdir(), 'hydro', `import_${domainId}_${docId}.zip`);
|
||||
const w = fs.createWriteStream(file);
|
||||
await new Promise((resolve, reject) => {
|
||||
w.on('finish', resolve);
|
||||
w.on('error', reject);
|
||||
r.pipe(w);
|
||||
});
|
||||
await problem.setTestdata(domainId, docId, file);
|
||||
await problem.edit(domainId, docId, {
|
||||
config: {
|
||||
time: `${p.time_limit}ms`,
|
||||
memory: `${p.memory_limit}m`,
|
||||
filename: p.file_io_input_name.split('.')[0],
|
||||
type: p.type === 'traditional' ? 'default' : p.type,
|
||||
},
|
||||
});
|
||||
this.response.body = { pid: pid || docId };
|
||||
this.response.redirect = this.url('problem_settings', { pid: pid || docId });
|
||||
}
|
||||
}
|
||||
|
||||
export async function apply() {
|
||||
Route('problem_import_syzoj', '/problem/import/syzoj', ProblemImportSYZOJHandler, PERM.PERM_CREATE_PROBLEM);
|
||||
}
|
||||
|
||||
global.Hydro.handler['import.syzoj'] = apply;
|
||||
@@ -1,57 +0,0 @@
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import os from 'os';
|
||||
import { ValidationError } from '../error';
|
||||
import * as problem from '../model/problem';
|
||||
import { PERM } from '../model/builtin';
|
||||
import {
|
||||
Route, Handler, Types, param,
|
||||
} from '../service/server';
|
||||
import { isPid } from '../lib/validator';
|
||||
|
||||
class ProblemImportHandler extends Handler {
|
||||
async get() {
|
||||
this.response.template = 'problem_import.html';
|
||||
this.response.body = {
|
||||
path: [
|
||||
['Hydro', 'homepage'],
|
||||
['problem_main', 'problem_main'],
|
||||
['problem_import', null],
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
@param('url', Types.String)
|
||||
@param('pid', Types.String, true, isPid)
|
||||
@param('hidden', Types.Boolean)
|
||||
@param('remoteType', Types.String)
|
||||
async post(domainId: string, url: string, pid: string, hidden = false, remoteType: string) {
|
||||
if (typeof global.Hydro.lib[`import.${remoteType}`] !== 'function') {
|
||||
throw new ValidationError('remoteType');
|
||||
}
|
||||
const [pdoc, testdata] = await global.Hydro.lib[`import.${remoteType}`](url, this);
|
||||
if (hidden) pdoc.hidden = true;
|
||||
const docId = await problem.add(
|
||||
domainId, pid || pdoc.pid, pdoc.title, pdoc.content, this.user._id,
|
||||
pdoc.tag || [], pdoc.category || [], null, pdoc.hidden,
|
||||
);
|
||||
if (testdata) {
|
||||
const file = path.resolve(os.tmpdir(), 'hydro', `import_${domainId}_${pid || pdoc.pid || docId}.zip`);
|
||||
const w = fs.createWriteStream(file);
|
||||
await new Promise((resolve, reject) => {
|
||||
w.on('finish', resolve);
|
||||
w.on('error', reject);
|
||||
testdata.pipe(w);
|
||||
});
|
||||
await problem.setTestdata(domainId, docId, file);
|
||||
}
|
||||
this.response.body = { pid: pid || docId };
|
||||
this.response.redirect = this.url('problem_settings', { pid: pid || docId });
|
||||
}
|
||||
}
|
||||
|
||||
export async function apply() {
|
||||
Route('problem_import', '/problem/import', ProblemImportHandler, PERM.PERM_CREATE_PROBLEM);
|
||||
}
|
||||
|
||||
global.Hydro.handler.import = apply;
|
||||
@@ -101,10 +101,9 @@ export interface SubtaskConfig {
|
||||
export interface LocalProblemConfig {
|
||||
type?: LocalProblemType,
|
||||
score?: number,
|
||||
/** ms */
|
||||
time?: string,
|
||||
/** Megabytes */
|
||||
memory?: string,
|
||||
filename?: string,
|
||||
checker_type?: string,
|
||||
checker?: string,
|
||||
interactor?: string,
|
||||
@@ -415,13 +414,11 @@ export interface Lib {
|
||||
download: typeof import('./lib/download'),
|
||||
'hash.hydro': typeof import('./lib/hash.hydro'),
|
||||
i18n: typeof import('./lib/i18n'),
|
||||
'import.syzoj': typeof import('./lib/import.syzoj').syzoj,
|
||||
jwt: typeof import('./lib/jwt'),
|
||||
logger: typeof import('./lib/logger'),
|
||||
mail: typeof import('./lib/mail'),
|
||||
md5: typeof import('./lib/md5'),
|
||||
misc: typeof import('./lib/misc'),
|
||||
nav: typeof import('./lib/nav'),
|
||||
paginate: typeof import('./lib/paginate'),
|
||||
rank: typeof import('./lib/rank'),
|
||||
rating: typeof import('./lib/rating'),
|
||||
@@ -434,6 +431,17 @@ export interface Lib {
|
||||
[key: string]: any
|
||||
}
|
||||
|
||||
export interface UI {
|
||||
manifest: Dictionary<string>,
|
||||
template: Dictionary<string>,
|
||||
nodes: {
|
||||
nav: any[],
|
||||
problem_add: any[],
|
||||
},
|
||||
Nav: typeof import('./lib/ui').Nav,
|
||||
ProblemAdd: typeof import('./lib/ui').ProblemAdd,
|
||||
}
|
||||
|
||||
declare global {
|
||||
namespace NodeJS {
|
||||
interface Global {
|
||||
@@ -444,11 +452,7 @@ declare global {
|
||||
service: Service,
|
||||
lib: Lib,
|
||||
stat: any,
|
||||
ui: {
|
||||
manifest: Dict<string>,
|
||||
template: Dict<string>,
|
||||
nav: any,
|
||||
},
|
||||
ui: UI,
|
||||
error: typeof import('./error'),
|
||||
locales: Dict<Dict<string>>,
|
||||
postInit: Array<() => Promise<any>>,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import superagent from 'superagent';
|
||||
import superagent, { SuperAgentRequest } from 'superagent';
|
||||
import fs from 'fs';
|
||||
|
||||
async function _download(url: string, path: string, retry: number) {
|
||||
@@ -11,6 +11,7 @@ async function _download(url: string, path: string, retry: number) {
|
||||
return path;
|
||||
}
|
||||
|
||||
function download(url: string): SuperAgentRequest
|
||||
function download(url: string, path?: string, retry = 3) {
|
||||
if (path) return _download(url, path, retry);
|
||||
return superagent.get(url).retry(retry);
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
import assert from 'assert';
|
||||
import superagent from 'superagent';
|
||||
import download from './download';
|
||||
import { ValidationError, RemoteOnlineJudgeError } from '../error';
|
||||
|
||||
const RE_SYZOJ = /https?:\/\/([a-zA-Z0-9.]+)\/problem\/([0-9]+)\/?/i;
|
||||
|
||||
export async function syzoj(url: string, handler: any) {
|
||||
assert(url.match(RE_SYZOJ), new ValidationError('url'));
|
||||
if (!url.endsWith('/')) url += '/';
|
||||
const [, host, pid] = RE_SYZOJ.exec(url);
|
||||
const res = await superagent.get(`${url}export`);
|
||||
assert(res.status === 200, new RemoteOnlineJudgeError('Cannot connect to target server'));
|
||||
assert(res.body.success, new RemoteOnlineJudgeError((res.body.error || {}).message));
|
||||
const p = res.body.obj;
|
||||
const content = [];
|
||||
if (p.description) {
|
||||
content.push(
|
||||
handler.translate('problem.import.problem_description'),
|
||||
p.description,
|
||||
);
|
||||
}
|
||||
if (p.input_format) {
|
||||
content.push(
|
||||
handler.translate('problem.import.input_format'),
|
||||
p.input_format,
|
||||
);
|
||||
}
|
||||
if (p.output_format) {
|
||||
content.push(
|
||||
handler.translate('problem.import.output_format'),
|
||||
p.output_format,
|
||||
);
|
||||
}
|
||||
if (p.hint) {
|
||||
content.push(
|
||||
handler.translate('problem.import.hint'),
|
||||
p.hint,
|
||||
);
|
||||
}
|
||||
if (p.limit_and_hint) {
|
||||
content.push(
|
||||
handler.translate('problem.import.limit_and_hint'),
|
||||
p.limit_and_hint,
|
||||
);
|
||||
}
|
||||
if (p.have_additional_file) {
|
||||
content.push(
|
||||
handler.translate('problem.import.additional_file'),
|
||||
`${url}download/additional_file`,
|
||||
);
|
||||
}
|
||||
const pdoc = {
|
||||
title: p.title,
|
||||
content: content.join(' \n'),
|
||||
owner: handler.user._id,
|
||||
from: url,
|
||||
pid: `${host}_${pid}`,
|
||||
tags: p.tags,
|
||||
config: {
|
||||
time: p.time_limit,
|
||||
memory: p.memory_limit * 1024,
|
||||
filename: p.file_io_input_name,
|
||||
type: p.type,
|
||||
},
|
||||
};
|
||||
const r = download(`${url}testdata/download`);
|
||||
return [pdoc, r];
|
||||
}
|
||||
|
||||
global.Hydro.lib['import.syzoj'] = syzoj;
|
||||
@@ -1,57 +0,0 @@
|
||||
import { isNull } from 'lodash';
|
||||
import { PERM, PRIV } from '../model/builtin';
|
||||
|
||||
global.Hydro.ui.nav = [];
|
||||
|
||||
const trueChecker = () => true;
|
||||
const Checker = (perm: bigint, priv: number, checker: Function = trueChecker) => (handler) => (
|
||||
checker(handler)
|
||||
&& (perm ? handler.user.hasPerm(perm) : true)
|
||||
&& (priv ? handler.user.hasPriv(priv) : true)
|
||||
);
|
||||
|
||||
const Item = (
|
||||
name: string, args: any, prefix: string,
|
||||
...permPrivChecker: Array<number | bigint | Function>
|
||||
) => {
|
||||
let _priv: number;
|
||||
let _perm: bigint;
|
||||
let checker: Function = trueChecker;
|
||||
for (const item of permPrivChecker) {
|
||||
if (item instanceof Object && !isNull(item)) {
|
||||
if (item instanceof Array) {
|
||||
if (typeof item[0] === 'number') {
|
||||
// @ts-ignore
|
||||
_priv = item;
|
||||
} else if (typeof item[0] === 'bigint') {
|
||||
// @ts-ignore
|
||||
_perm = item;
|
||||
}
|
||||
} else if (typeof item.call !== 'undefined') {
|
||||
checker = item;
|
||||
}
|
||||
} else if (typeof item === 'number') {
|
||||
_priv = item;
|
||||
} else if (typeof item === 'bigint') {
|
||||
_perm = item;
|
||||
}
|
||||
}
|
||||
checker = Checker(_perm, _priv, checker);
|
||||
global.Hydro.ui.nav.push({
|
||||
name, args: args || {}, prefix, checker,
|
||||
});
|
||||
};
|
||||
|
||||
Item('homepage', null, 'homepage');
|
||||
Item('problem_main', null, 'problem', PERM.PERM_VIEW_PROBLEM);
|
||||
Item('training_main', null, 'training', PERM.PERM_VIEW_TRAINING);
|
||||
Item('homework_main', null, 'homework', PERM.PERM_VIEW_HOMEWORK);
|
||||
Item('discussion_main', null, 'discussion', PERM.PERM_VIEW_DISCUSSION);
|
||||
Item('contest_main', null, 'contest', PERM.PERM_VIEW_CONTEST);
|
||||
Item('record_main', null, 'record');
|
||||
Item('ranking', null, 'ranking', PERM.PERM_VIEW_RANKING);
|
||||
Item('domain_dashboard', null, 'domain', PERM.PERM_EDIT_DOMAIN);
|
||||
Item('manage_dashboard', null, 'manage', PRIV.PRIV_EDIT_SYSTEM);
|
||||
|
||||
global.Hydro.lib.nav = Item;
|
||||
export = Item;
|
||||
@@ -0,0 +1,67 @@
|
||||
import { Dictionary, isNull } from 'lodash';
|
||||
import { PERM, PRIV } from '../model/builtin';
|
||||
|
||||
const trueChecker = () => true;
|
||||
const Checker = (perm: bigint, priv: number, checker: Function = trueChecker) => (handler) => (
|
||||
checker(handler)
|
||||
&& (perm ? handler.user.hasPerm(perm) : true)
|
||||
&& (priv ? handler.user.hasPriv(priv) : true)
|
||||
);
|
||||
const buildChecker = (...permPrivChecker: Array<number | bigint | Function>) => {
|
||||
let _priv: number;
|
||||
let _perm: bigint;
|
||||
let checker: Function = trueChecker;
|
||||
for (const item of permPrivChecker) {
|
||||
if (item instanceof Object && !isNull(item)) {
|
||||
if (item instanceof Array) {
|
||||
if (typeof item[0] === 'number') {
|
||||
// @ts-ignore
|
||||
_priv = item;
|
||||
} else if (typeof item[0] === 'bigint') {
|
||||
// @ts-ignore
|
||||
_perm = item;
|
||||
}
|
||||
} else if (typeof item.call !== 'undefined') {
|
||||
checker = item;
|
||||
}
|
||||
} else if (typeof item === 'number') {
|
||||
_priv = item;
|
||||
} else if (typeof item === 'bigint') {
|
||||
_perm = item;
|
||||
}
|
||||
}
|
||||
return Checker(_perm, _priv, checker);
|
||||
};
|
||||
|
||||
export const Nav = (
|
||||
name: string, args: Dictionary<any> = {}, prefix: string,
|
||||
...permPrivChecker: Array<number | bigint | Function>
|
||||
) => {
|
||||
global.Hydro.ui.nodes.nav.push({
|
||||
name, args: args || {}, prefix, checker: buildChecker(...permPrivChecker),
|
||||
});
|
||||
};
|
||||
|
||||
export const ProblemAdd = (
|
||||
name: string, args: Dictionary<any> = {}, icon = 'add', text = 'Create Problem',
|
||||
) => {
|
||||
global.Hydro.ui.nodes.problem_add.push({
|
||||
name, args, icon, text,
|
||||
});
|
||||
};
|
||||
|
||||
Nav('homepage', {}, 'homepage');
|
||||
Nav('problem_main', {}, 'problem', PERM.PERM_VIEW_PROBLEM);
|
||||
Nav('training_main', {}, 'training', PERM.PERM_VIEW_TRAINING);
|
||||
Nav('homework_main', {}, 'homework', PERM.PERM_VIEW_HOMEWORK);
|
||||
Nav('discussion_main', {}, 'discussion', PERM.PERM_VIEW_DISCUSSION);
|
||||
Nav('contest_main', {}, 'contest', PERM.PERM_VIEW_CONTEST);
|
||||
Nav('record_main', {}, 'record');
|
||||
Nav('ranking', {}, 'ranking', PERM.PERM_VIEW_RANKING);
|
||||
Nav('domain_dashboard', {}, 'domain', PERM.PERM_EDIT_DOMAIN);
|
||||
Nav('manage_dashboard', {}, 'manage', PRIV.PRIV_EDIT_SYSTEM);
|
||||
ProblemAdd('problem_create');
|
||||
ProblemAdd('problem_import_syzoj', {}, 'copy', 'Import From SYZOJ');
|
||||
|
||||
global.Hydro.ui.Nav = Nav;
|
||||
global.Hydro.ui.ProblemAdd = ProblemAdd;
|
||||
@@ -24,9 +24,13 @@ if (!global.Hydro) {
|
||||
script: {},
|
||||
// @ts-ignore
|
||||
lib: {},
|
||||
// @ts-ignore
|
||||
ui: {
|
||||
manifest: {},
|
||||
nav: [],
|
||||
nodes: {
|
||||
nav: [],
|
||||
problem_add: [],
|
||||
},
|
||||
template: {},
|
||||
},
|
||||
// @ts-ignore
|
||||
|
||||
@@ -807,6 +807,17 @@ export async function start() {
|
||||
skip: (req, res) => res.hasHeader('nolog'),
|
||||
}));
|
||||
}
|
||||
app.use(async (ctx, next) => {
|
||||
const xff = await system.get('server.xff');
|
||||
const ip = xff ? ctx.request.headers[xff] : ctx.request.ip;
|
||||
try {
|
||||
await opcount.inc('global', ip, 10, 100);
|
||||
} catch (e) {
|
||||
ctx.status = 429;
|
||||
return null;
|
||||
}
|
||||
return await next();
|
||||
});
|
||||
app.use(router.routes()).use(router.allowedMethods());
|
||||
server.listen(argv.port || port);
|
||||
console.log('Server listening at: %s', argv.port || port);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@hydrooj/login-with-github",
|
||||
"version": "0.0.6",
|
||||
"version": "0.0.7",
|
||||
"main": "package.json",
|
||||
"repository": "git@github.com:hydro-dev/Hydro.git",
|
||||
"author": "undefined <masnn0@outlook.com>",
|
||||
@@ -14,7 +14,7 @@
|
||||
"@types/superagent-proxy": "^2.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"hydrooj": "^2.12.1"
|
||||
"hydrooj": "^2.12.1||^2.13.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"superagent": "^6.1.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@hydrooj/login-with-google",
|
||||
"version": "0.0.6",
|
||||
"version": "0.0.7",
|
||||
"main": "package.json",
|
||||
"repository": "git@github.com:hydro-dev/Hydro.git",
|
||||
"author": "undefined <masnn0@outlook.com>",
|
||||
@@ -14,7 +14,7 @@
|
||||
"@types/superagent-proxy": "^2.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"hydrooj": "^2.12.1"
|
||||
"hydrooj": "^2.12.1||^2.13.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"superagent": "^6.1.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@hydrooj/login-with-osu",
|
||||
"version": "0.0.6",
|
||||
"version": "0.0.7",
|
||||
"main": "package.json",
|
||||
"repository": "git@github.com:hydro-dev/Hydro.git",
|
||||
"author": "undefined <masnn0@outlook.com>",
|
||||
@@ -14,7 +14,7 @@
|
||||
"@types/superagent-proxy": "^2.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"hydrooj": "^2.12.1"
|
||||
"hydrooj": "^2.12.1||^2.13.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"superagent": "^6.1.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@hydrooj/login-with-qq",
|
||||
"version": "0.0.2",
|
||||
"version": "0.0.3",
|
||||
"main": "package.json",
|
||||
"repository": "git@github.com:hydro-dev/Hydro.git",
|
||||
"author": "undefined <masnn0@outlook.com>",
|
||||
@@ -10,7 +10,7 @@
|
||||
"build": "tsc"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"hydrooj": "^2.12.1"
|
||||
"hydrooj": "^2.12.1||^2.13.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ws": "^7.3.1"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@hydrooj/migrate-vijos",
|
||||
"version": "1.3.6",
|
||||
"version": "1.3.7",
|
||||
"main": "package.json",
|
||||
"repository": "git@github.com:hydro-dev/Hydro.git",
|
||||
"author": "undefined <masnn0@outlook.com>",
|
||||
@@ -14,7 +14,7 @@
|
||||
"@types/mongodb": "^3.5.27"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"hydrooj": "^2.12.3"
|
||||
"hydrooj": "^2.13.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"js-yaml": "^3.14.0",
|
||||
|
||||
Reference in new issue
Block a user