mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-20 01:38:19 +08:00
优化csrf_token检查
This commit is contained in:
1 parent
fb5c29226b
commit
c9b6412527
10 files changed
+76
-184
No files matched your search
+1
-1
@@ -10,5 +10,5 @@ dist/
|
|||||||
__*
|
__*
|
||||||
ui/misc/.iconfont
|
ui/misc/.iconfont
|
||||||
ui/static/locale
|
ui/static/locale
|
||||||
.webpackStats.json
|
*.log
|
||||||
!.gitkeep
|
!.gitkeep
|
||||||
+25
-13
@@ -10,6 +10,25 @@ const hpm = require('../lib/hpm');
|
|||||||
const loader = require('../loader');
|
const loader = require('../loader');
|
||||||
const check = require('../check');
|
const check = require('../check');
|
||||||
|
|
||||||
|
function set(key, value) {
|
||||||
|
if (setting.SYSTEM_SETTINGS_BY_KEY[key]) {
|
||||||
|
const s = setting.SYSTEM_SETTINGS_BY_KEY[key];
|
||||||
|
if (s.flag & setting.FLAG_DISABLED) return undefined;
|
||||||
|
if (s.type === 'boolean') {
|
||||||
|
if (value === 'on') return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (s.type === 'number') {
|
||||||
|
if (!Number.isSafeInteger(parseInt(value, 10))) {
|
||||||
|
throw new ValidationError(key);
|
||||||
|
}
|
||||||
|
return parseInt(value, 10);
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
class SystemHandler extends Handler {
|
class SystemHandler extends Handler {
|
||||||
async prepare() {
|
async prepare() {
|
||||||
this.checkPriv(PRIV.PRIV_EDIT_SYSTEM);
|
this.checkPriv(PRIV.PRIV_EDIT_SYSTEM);
|
||||||
@@ -147,21 +166,14 @@ class SystemSettingHandler extends SystemHandler {
|
|||||||
const tasks = [];
|
const tasks = [];
|
||||||
for (const key in args) {
|
for (const key in args) {
|
||||||
if (typeof args[key] === 'object') {
|
if (typeof args[key] === 'object') {
|
||||||
const subtasks = [];
|
for (const subkey in args[key]) {
|
||||||
for (const sub in args[key]) {
|
console.log(`${key}.${subkey}`, set(`${key}.${subkey}`, args[key][subkey]));
|
||||||
const s = setting.SYSTEM_SETTINGS_BY_KEY[`${key}.${sub}`];
|
if (typeof set(`${key}.${subkey}`, args[key][subkey]) !== 'undefined') {
|
||||||
if (s && !((s.flag & setting.FLAG_SECRET) && args[key][sub] === '')) {
|
tasks.push(system.set(`${key}.${subkey}`, set(`${key}.${subkey}`, args[key][subkey])));
|
||||||
if (s.ui === 'number') args[key][sub] = Number(args[key][sub]);
|
|
||||||
subtasks.push(system.set(`${key}.${sub}`, args[key][sub]));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tasks.push(Promise.all(subtasks));
|
} else if (typeof set(key, args[key]) !== 'undefined') {
|
||||||
} else {
|
tasks.push(system.set(key, set(key, args[key])));
|
||||||
const s = setting.SYSTEM_SETTINGS_BY_KEY[key];
|
|
||||||
if (s && !((s.flag & setting.FLAG_SECRET) && args[key] === '')) {
|
|
||||||
if (s.ui === 'number') args[key] = Number(args[key]);
|
|
||||||
tasks.push(system.set(key, args[key]));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
await Promise.all(tasks);
|
await Promise.all(tasks);
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ const {
|
|||||||
PERM_CREATE_PROBLEM, PERM_READ_PROBLEM_DATA, PERM_EDIT_PROBLEM,
|
PERM_CREATE_PROBLEM, PERM_READ_PROBLEM_DATA, PERM_EDIT_PROBLEM,
|
||||||
PERM_VIEW_PROBLEM_SOLUTION, PERM_CREATE_PROBLEM_SOLUTION,
|
PERM_VIEW_PROBLEM_SOLUTION, PERM_CREATE_PROBLEM_SOLUTION,
|
||||||
PERM_EDIT_PROBLEM_SOLUTION, PERM_DELETE_PROBLEM_SOLUTION, PERM_EDIT_PROBLEM_SOLUTION_REPLY,
|
PERM_EDIT_PROBLEM_SOLUTION, PERM_DELETE_PROBLEM_SOLUTION, PERM_EDIT_PROBLEM_SOLUTION_REPLY,
|
||||||
PERM_REPLY_PROBLEM_SOLUTION,
|
PERM_REPLY_PROBLEM_SOLUTION, PERM_EDIT_PROBLEM_SELF,
|
||||||
},
|
},
|
||||||
PRIV: {
|
PRIV: {
|
||||||
PRIV_USER_PROFILE, PRIV_JUDGE,
|
PRIV_USER_PROFILE, PRIV_JUDGE,
|
||||||
@@ -202,11 +202,8 @@ class ProblemSubmitHandler extends ProblemDetailHandler {
|
|||||||
const { lang, code } = this.request.body;
|
const { lang, code } = this.request.body;
|
||||||
const rid = await record.add(domainId, {
|
const rid = await record.add(domainId, {
|
||||||
uid: this.user._id, lang, code, pid: this.pdoc.docId,
|
uid: this.user._id, lang, code, pid: this.pdoc.docId,
|
||||||
});
|
}, true);
|
||||||
await Promise.all([
|
await user.incDomain(domainId, this.user._id, 'nSubmit');
|
||||||
record.judge(domainId, rid),
|
|
||||||
user.incDomain(domainId, this.user._id, 'nSubmit'),
|
|
||||||
]);
|
|
||||||
this.response.body = { rid };
|
this.response.body = { rid };
|
||||||
this.response.redirect = this.url('record_detail', { rid });
|
this.response.redirect = this.url('record_detail', { rid });
|
||||||
}
|
}
|
||||||
@@ -264,6 +261,7 @@ class ProblemStatisticsHandler extends ProblemDetailHandler {
|
|||||||
class ProblemManageHandler extends ProblemDetailHandler {
|
class ProblemManageHandler extends ProblemDetailHandler {
|
||||||
async prepare() {
|
async prepare() {
|
||||||
if (this.pdoc.owner !== this.user._id) this.checkPerm(PERM_EDIT_PROBLEM);
|
if (this.pdoc.owner !== this.user._id) this.checkPerm(PERM_EDIT_PROBLEM);
|
||||||
|
else this.checkPerm(PERM_EDIT_PROBLEM_SELF);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -475,7 +473,7 @@ class ProblemCreateHandler extends Handler {
|
|||||||
pid, hidden,
|
pid, hidden,
|
||||||
});
|
});
|
||||||
this.response.body = { pid };
|
this.response.body = { pid };
|
||||||
this.response.redirect = `/p/${pid}/settings`;
|
this.response.redirect = this.url('problem_settings', { pid });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,98 +0,0 @@
|
|||||||
const domain = require('../model/domain');
|
|
||||||
const system = require('../model/system');
|
|
||||||
const setting = require('../model/setting');
|
|
||||||
const { Route, Handler } = require('../service/server');
|
|
||||||
const { PRIV_EDIT_SYSTEM } = require('../model/builtin').PRIV;
|
|
||||||
const hpm = require('../lib/hpm');
|
|
||||||
const loader = require('../loader');
|
|
||||||
|
|
||||||
class SystemHandler extends Handler {
|
|
||||||
async prepare({ domainId }) {
|
|
||||||
this.checkPriv(PRIV_EDIT_SYSTEM);
|
|
||||||
this.domain = await domain.get(domainId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class SystemDashboardHandler extends SystemHandler {
|
|
||||||
async get() {
|
|
||||||
const path = [
|
|
||||||
['Hydro', 'homepage'],
|
|
||||||
['manage', null],
|
|
||||||
['manage_dashboard', null],
|
|
||||||
];
|
|
||||||
this.response.template = 'manage_dashboard.html';
|
|
||||||
this.response.body = { domain: this.domain, path };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class SystemModuleHandler extends SystemHandler {
|
|
||||||
async get() {
|
|
||||||
const installed = await hpm.getInstalled();
|
|
||||||
const path = [
|
|
||||||
['Hydro', 'homepage'],
|
|
||||||
['manage', null],
|
|
||||||
['manage_module', null],
|
|
||||||
];
|
|
||||||
this.response.body = { installed, active: loader.active, path };
|
|
||||||
this.response.template = 'manage_module.html';
|
|
||||||
}
|
|
||||||
|
|
||||||
async postInstall({ url, id }) {
|
|
||||||
await hpm.install(url, id);
|
|
||||||
this.back();
|
|
||||||
}
|
|
||||||
|
|
||||||
async postDelete({ id }) {
|
|
||||||
await hpm.del(id);
|
|
||||||
this.back();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class SystemSettingHandler extends SystemHandler {
|
|
||||||
async get() {
|
|
||||||
this.response.template = 'manage_settings.html';
|
|
||||||
const current = {};
|
|
||||||
const settings = setting.SYSTEM_SETTINGS;
|
|
||||||
for (const s of settings) {
|
|
||||||
// eslint-disable-next-line no-await-in-loop
|
|
||||||
current[s.key] = await system.get(s.key);
|
|
||||||
}
|
|
||||||
this.response.body = {
|
|
||||||
current, settings,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
async post(args) {
|
|
||||||
const tasks = [];
|
|
||||||
for (const key in args) {
|
|
||||||
if (typeof args[key] === 'object') {
|
|
||||||
const subtasks = [];
|
|
||||||
for (const sub in args[key]) {
|
|
||||||
if (setting.SYSTEM_SETTINGS_BY_KEY[`${key}.${sub}`]) {
|
|
||||||
const s = setting.SYSTEM_SETTINGS_BY_KEY[`${key}.${sub}`];
|
|
||||||
if (s.ui === 'checkbox') {
|
|
||||||
if (args[key][sub] === 'on') {
|
|
||||||
subtasks.push(system.set(`${key}.${sub}`, true));
|
|
||||||
} else {
|
|
||||||
subtasks.push(system.set(`${key}.${sub}`, false));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
subtasks.push(system.set(`${key}.${sub}`, args[key][sub]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tasks.push(Promise.all(subtasks));
|
|
||||||
} else tasks.push(system.set(key, args[key]));
|
|
||||||
}
|
|
||||||
await Promise.all(tasks);
|
|
||||||
this.back();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function apply() {
|
|
||||||
Route('system_dashboard', '/system', SystemDashboardHandler);
|
|
||||||
Route('system_module', '/system/module', SystemModuleHandler);
|
|
||||||
Route('system_setting', '/system/setting', SystemSettingHandler);
|
|
||||||
}
|
|
||||||
|
|
||||||
global.Hydro.handler.manage = module.exports = apply;
|
|
||||||
@@ -73,13 +73,13 @@ function getMulti(domainId, query) {
|
|||||||
|
|
||||||
async function update(domainId, rid, $set, $push, $unset) {
|
async function update(domainId, rid, $set, $push, $unset) {
|
||||||
const _id = new ObjectID(rid);
|
const _id = new ObjectID(rid);
|
||||||
const upd = {};
|
const $update = {};
|
||||||
if ($set && Object.keys($set).length) upd.$set = $set;
|
if ($set && Object.keys($set).length) $update.$set = $set;
|
||||||
if ($push && Object.keys($push).length) upd.$push = $push;
|
if ($push && Object.keys($push).length) $update.$push = $push;
|
||||||
if ($unset && Object.keys($unset).length) upd.$unset = $unset;
|
if ($unset && Object.keys($unset).length) $update.$unset = $unset;
|
||||||
const rdoc = await coll.findOneAndUpdate({ domainId, _id }, upd, { returnOriginal: false });
|
const res = await coll.findOneAndUpdate({ domainId, _id }, $update, { returnOriginal: false });
|
||||||
if (!rdoc) throw new RecordNotFoundError(rid);
|
if (!res.value) throw new RecordNotFoundError(rid);
|
||||||
return rdoc;
|
return res.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
function reset(domainId, rid) {
|
function reset(domainId, rid) {
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ function unsubscribe(events, handler, funcName) {
|
|||||||
handler.__bus = (...args) => {
|
handler.__bus = (...args) => {
|
||||||
handler[funcName].call(handler, ...args);
|
handler[funcName].call(handler, ...args);
|
||||||
};
|
};
|
||||||
|
// FIXME doesn't work
|
||||||
for (const event of events) bus.off(event, handler.__bus);
|
for (const event of events) bus.off(event, handler.__bus);
|
||||||
delete handler.__bus;
|
delete handler.__bus;
|
||||||
}
|
}
|
||||||
|
|||||||
+33
-53
@@ -207,8 +207,9 @@ const Handler = HandlerMixin(class {
|
|||||||
/**
|
/**
|
||||||
* @param {import('koa').Context} ctx
|
* @param {import('koa').Context} ctx
|
||||||
*/
|
*/
|
||||||
constructor(ctx) {
|
constructor(ctx, args) {
|
||||||
this.ctx = ctx;
|
this.ctx = ctx;
|
||||||
|
this.args = args;
|
||||||
this.request = {
|
this.request = {
|
||||||
host: ctx.request.host,
|
host: ctx.request.host,
|
||||||
hostname: ctx.request.hostname,
|
hostname: ctx.request.hostname,
|
||||||
@@ -223,7 +224,7 @@ const Handler = HandlerMixin(class {
|
|||||||
referer: ctx.request.headers.referer || '/',
|
referer: ctx.request.headers.referer || '/',
|
||||||
};
|
};
|
||||||
this.response = {
|
this.response = {
|
||||||
body: '',
|
body: {},
|
||||||
type: '',
|
type: '',
|
||||||
status: null,
|
status: null,
|
||||||
template: null,
|
template: null,
|
||||||
@@ -274,8 +275,6 @@ const Handler = HandlerMixin(class {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async init({ domainId }) {
|
async init({ domainId }) {
|
||||||
this.response.body = {};
|
|
||||||
this.now = new Date();
|
|
||||||
this.preferJson = (this.request.headers.accept || '').includes('application/json');
|
this.preferJson = (this.request.headers.accept || '').includes('application/json');
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
this.getSession(),
|
this.getSession(),
|
||||||
@@ -292,7 +291,7 @@ const Handler = HandlerMixin(class {
|
|||||||
if (!sdoc || sdoc.uid !== this.user._id) throw new CsrfTokenError(csrfToken);
|
if (!sdoc || sdoc.uid !== this.user._id) throw new CsrfTokenError(csrfToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
async ___cleanup() {
|
async finish() {
|
||||||
try {
|
try {
|
||||||
await this.renderBody();
|
await this.renderBody();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -385,26 +384,25 @@ const Handler = HandlerMixin(class {
|
|||||||
this.response.body = {
|
this.response.body = {
|
||||||
error: { message: error.msg(), params: error.params, stack: error.stack },
|
error: { message: error.msg(), params: error.params, stack: error.stack },
|
||||||
};
|
};
|
||||||
await this.___cleanup().catch(() => { });
|
await this.finish().catch(() => { });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
async function handle(ctx, HandlerClass, checker) {
|
async function handle(ctx, HandlerClass, checker) {
|
||||||
global.Hydro.stat.reqCount++;
|
global.Hydro.stat.reqCount++;
|
||||||
const h = new HandlerClass(ctx);
|
|
||||||
try {
|
|
||||||
const method = ctx.method.toLowerCase();
|
|
||||||
const args = {
|
const args = {
|
||||||
domainId: 'system', ...ctx.params, ...ctx.query, ...ctx.request.body,
|
domainId: 'system', ...ctx.params, ...ctx.query, ...ctx.request.body,
|
||||||
};
|
};
|
||||||
h.args = args;
|
const h = new HandlerClass(ctx, args);
|
||||||
|
try {
|
||||||
|
const method = ctx.method.toLowerCase();
|
||||||
let operation;
|
let operation;
|
||||||
if (method === 'post' && ctx.request.body.operation) {
|
if (method === 'post' && ctx.request.body.operation) {
|
||||||
operation = `_${ctx.request.body.operation}`
|
operation = `_${ctx.request.body.operation}`
|
||||||
.replace(/_([a-z])/gm, (s) => s[1].toUpperCase());
|
.replace(/_([a-z])/gm, (s) => s[1].toUpperCase());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (h.init) await h.init(args);
|
await h.init(args);
|
||||||
if (checker) checker.call(h);
|
if (checker) checker.call(h);
|
||||||
if (method === 'post') {
|
if (method === 'post') {
|
||||||
await h.checkCsrfToken(args.csrfToken);
|
await h.checkCsrfToken(args.csrfToken);
|
||||||
@@ -432,51 +430,47 @@ async function handle(ctx, HandlerClass, checker) {
|
|||||||
throw new ValidationError(`Argument ${checking} check failed`);
|
throw new ValidationError(`Argument ${checking} check failed`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (h.__prepare) await h.__prepare(args);
|
|
||||||
if (h._prepare) await h._prepare(args);
|
if (h._prepare) await h._prepare(args);
|
||||||
if (h.prepare) await h.prepare(args);
|
if (h.prepare) await h.prepare(args);
|
||||||
|
|
||||||
if (h[`___${method}`]) await h[`___${method}`](args);
|
|
||||||
if (h[`__${method}`]) await h[`__${method}`](args);
|
|
||||||
if (h[`_${method}`]) await h[`_${method}`](args);
|
|
||||||
if (h[method]) await h[method](args);
|
if (h[method]) await h[method](args);
|
||||||
if (operation) await h[`post${operation}`](args);
|
if (operation) await h[`post${operation}`](args);
|
||||||
|
|
||||||
if (h.cleanup) await h.cleanup(args);
|
if (h.cleanup) await h.cleanup(args);
|
||||||
if (h._cleanup) await h._cleanup(args);
|
if (h.finish) await h.finish(args);
|
||||||
if (h.__cleanup) await h.__cleanup(args);
|
|
||||||
if (h.___cleanup) await h.___cleanup(args);
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
await h.onerror(e);
|
await h.onerror(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const Checker = (perm, priv, checker) => function __() {
|
const Checker = (permPrivChecker) => {
|
||||||
checker();
|
let perm;
|
||||||
if (perm) this.checkPerm(perm);
|
let priv;
|
||||||
if (priv) this.checkPriv(priv);
|
|
||||||
};
|
|
||||||
|
|
||||||
function Route(name, route, RouteHandler, ...permPrivChecker) {
|
|
||||||
let _priv;
|
|
||||||
let _perm;
|
|
||||||
let checker = () => { };
|
let checker = () => { };
|
||||||
for (const item of permPrivChecker) {
|
for (const item of permPrivChecker) {
|
||||||
if (typeof item === 'object') {
|
if (typeof item === 'object') {
|
||||||
if (typeof item.call !== 'undefined') {
|
if (typeof item.call !== 'undefined') {
|
||||||
checker = item;
|
checker = item;
|
||||||
} if (typeof item[0] === 'number') {
|
} if (typeof item[0] === 'number') {
|
||||||
_priv = item;
|
priv = item;
|
||||||
} else if (typeof item[0] === 'string') {
|
} else if (typeof item[0] === 'string') {
|
||||||
_perm = item;
|
perm = item;
|
||||||
}
|
}
|
||||||
} else if (typeof item === 'number') {
|
} else if (typeof item === 'number') {
|
||||||
_priv = item;
|
priv = item;
|
||||||
} else if (typeof item === 'string') {
|
} else if (typeof item === 'string') {
|
||||||
_perm = item;
|
perm = item;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
checker = Checker(_perm, _priv, checker);
|
return function check() {
|
||||||
|
checker();
|
||||||
|
if (perm) this.checkPerm(perm);
|
||||||
|
if (priv) this.checkPriv(priv);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
function Route(name, route, RouteHandler, ...permPrivChecker) {
|
||||||
|
const checker = Checker(permPrivChecker);
|
||||||
router.all(name, route, (ctx) => handle(ctx, RouteHandler, checker));
|
router.all(name, route, (ctx) => handle(ctx, RouteHandler, checker));
|
||||||
router.all(`${name}_with_domainId`, `/d/:domainId${route}`, (ctx) => handle(ctx, RouteHandler, checker));
|
router.all(`${name}_with_domainId`, `/d/:domainId${route}`, (ctx) => handle(ctx, RouteHandler, checker));
|
||||||
}
|
}
|
||||||
@@ -496,17 +490,6 @@ const ConnectionHandler = HandlerMixin(class {
|
|||||||
for (const i in p) this.request.params[p[i][0]] = decodeURIComponent(p[i][1]);
|
for (const i in p) this.request.params[p[i][0]] = decodeURIComponent(p[i][1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
async renderHTML(name, context) {
|
|
||||||
this._user = { ...this.user, gravatar: misc.gravatar(this.user.gravatar, 128) };
|
|
||||||
const res = await template.render(name, Object.assign(context, {
|
|
||||||
handler: this,
|
|
||||||
url: (...args) => this.url(...args),
|
|
||||||
_: (str) => (str ? str.toString().translate(this.user.viewLang || this.session.viewLang) : ''),
|
|
||||||
user: this.user,
|
|
||||||
}));
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
send(data) {
|
send(data) {
|
||||||
this.conn.write(JSON.stringify(data));
|
this.conn.write(JSON.stringify(data));
|
||||||
}
|
}
|
||||||
@@ -522,10 +505,9 @@ const ConnectionHandler = HandlerMixin(class {
|
|||||||
|
|
||||||
async init({ domainId }) {
|
async init({ domainId }) {
|
||||||
try {
|
try {
|
||||||
this.session = await token.get(this.request.params.token, token.TYPE_CSRF_TOKEN);
|
this.session = await token.get(this.request.params.token, token.TYPE_CSRF_TOKEN, true);
|
||||||
await token.del(this.request.params.token, token.TYPE_CSRF_TOKEN);
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.session = { uid: 1 };
|
this.session = { uid: 0 };
|
||||||
}
|
}
|
||||||
const bdoc = await blacklist.get(this.request.ip);
|
const bdoc = await blacklist.get(this.request.ip);
|
||||||
if (bdoc) throw new BlacklistedError(this.request.ip);
|
if (bdoc) throw new BlacklistedError(this.request.ip);
|
||||||
@@ -534,15 +516,16 @@ const ConnectionHandler = HandlerMixin(class {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function Connection(name, prefix, RouteConnHandler, permission) {
|
function Connection(name, prefix, RouteConnHandler, ...permPrivChecker) {
|
||||||
const sock = sockjs.createServer({ prefix });
|
const sock = sockjs.createServer({ prefix });
|
||||||
|
const checker = Checker(permPrivChecker);
|
||||||
sock.on('connection', async (conn) => {
|
sock.on('connection', async (conn) => {
|
||||||
const h = new RouteConnHandler(conn);
|
const h = new RouteConnHandler(conn);
|
||||||
try {
|
try {
|
||||||
const args = { domainId: 'system', ...h.request.params };
|
const args = { domainId: 'system', ...h.request.params };
|
||||||
h.args = args;
|
h.args = args;
|
||||||
if (h.init) await h.init(args);
|
await h.init(args);
|
||||||
if (permission) h.checkPerm(permission);
|
checker.call(h);
|
||||||
let checking = '';
|
let checking = '';
|
||||||
try {
|
try {
|
||||||
for (const key in validate) {
|
for (const key in validate) {
|
||||||
@@ -555,7 +538,6 @@ function Connection(name, prefix, RouteConnHandler, permission) {
|
|||||||
if (e instanceof ValidationError) throw e;
|
if (e instanceof ValidationError) throw e;
|
||||||
throw new ValidationError(`Argument ${checking} check failed`);
|
throw new ValidationError(`Argument ${checking} check failed`);
|
||||||
}
|
}
|
||||||
if (h.__prepare) await h.__prepare(args);
|
|
||||||
if (h._prepare) await h._prepare(args);
|
if (h._prepare) await h._prepare(args);
|
||||||
if (h.prepare) await h.prepare(args);
|
if (h.prepare) await h.prepare(args);
|
||||||
if (h.message) {
|
if (h.message) {
|
||||||
@@ -565,9 +547,7 @@ function Connection(name, prefix, RouteConnHandler, permission) {
|
|||||||
}
|
}
|
||||||
conn.on('close', async () => {
|
conn.on('close', async () => {
|
||||||
if (h.cleanup) await h.cleanup(args);
|
if (h.cleanup) await h.cleanup(args);
|
||||||
if (h._cleanup) await h._cleanup(args);
|
if (h.finish) await h.finish(args);
|
||||||
if (h.__cleanup) await h.__cleanup(args);
|
|
||||||
if (h.___cleanup) await h.___cleanup(args);
|
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
|
|||||||
@@ -64,7 +64,7 @@
|
|||||||
value:pdoc['tag']|join(', ')
|
value:pdoc['tag']|join(', ')
|
||||||
}) }}
|
}) }}
|
||||||
<div class="row"><div class="columns">
|
<div class="row"><div class="columns">
|
||||||
<input type="hidden" name="operation" value="settings">
|
<input type="hidden" name="operation" value="setting">
|
||||||
<input type="hidden" name="csrfToken" value="{{ handler.csrfToken }}">
|
<input type="hidden" name="csrfToken" value="{{ handler.csrfToken }}">
|
||||||
<button type="submit" class="rounded primary button">
|
<button type="submit" class="rounded primary button">
|
||||||
{{ _('Update') }}
|
{{ _('Update') }}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="medium-9 columns">
|
<div class="medium-9 columns">
|
||||||
{% if showStatus %}
|
{% if showStatus %}
|
||||||
{% include 'record_detail_STATUS.html' %}
|
{% include 'record_detail_status.html' %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if rdoc['code'] %}
|
{% if rdoc['code'] %}
|
||||||
<div class="section">
|
<div class="section">
|
||||||
|
|||||||
@@ -87,11 +87,11 @@ global.Hydro.handler.handlerName = module.exports = apply;
|
|||||||
|
|
||||||
在路由中定义所有的函数应均为异步函数,支持的函数如下:
|
在路由中定义所有的函数应均为异步函数,支持的函数如下:
|
||||||
|
|
||||||
_prepare, prepare, get, post, post[Operation], cleanup, _cleanup
|
prepare, get, post, post[Operation], cleanup
|
||||||
|
|
||||||
具体流程如下:
|
具体流程如下:
|
||||||
|
|
||||||
先执行 _prepare(args) (如果存在)
|
先执行 prepare(args) (如果存在)
|
||||||
args 为传入的参数集合(包括 QueryString, Body, Path)中的全部参数,并对以下字段进行了校验:
|
args 为传入的参数集合(包括 QueryString, Body, Path)中的全部参数,并对以下字段进行了校验:
|
||||||
|
|
||||||
| Key | Type |
|
| Key | Type |
|
||||||
@@ -130,7 +130,6 @@ args 为传入的参数集合(包括 QueryString, Body, Path)中的全部参
|
|||||||
```
|
```
|
||||||
|
|
||||||
执行 cleanup()
|
执行 cleanup()
|
||||||
执行 _cleanup()
|
|
||||||
|
|
||||||
如果在 this.response.template 指定模板则渲染,否则直接返回 this.response.body 中的内容。
|
如果在 this.response.template 指定模板则渲染,否则直接返回 this.response.body 中的内容。
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user