mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-20 01:38:19 +08:00
system check & setting_secret
This commit is contained in:
1 parent
c52ddd7512
commit
57f711ed4f
18 files changed
+295
-134
No files matched your search
@@ -0,0 +1,69 @@
|
||||
// TODO check more
|
||||
|
||||
const os = require('os');
|
||||
const superagent = require('superagent');
|
||||
const system = require('./model/system');
|
||||
const db = require('./service/db');
|
||||
|
||||
const c = {};
|
||||
|
||||
async function checkDb(log, warn, error) {
|
||||
try {
|
||||
const coll = db.collection('check');
|
||||
const d = await coll.findOne({ _id: 'check' });
|
||||
if (!d) await coll.insertOne({ _id: 'check', value: 'check' });
|
||||
await coll.createIndex('check');
|
||||
await coll.deleteOne({ _id: 'check' });
|
||||
} catch (e) {
|
||||
error(`Mongo Error: Database read-write failed.\n${e.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
async function checkPerm(log, warn) {
|
||||
const { username } = os.userInfo();
|
||||
if (username === 'root') warn('Hydro should not be run as root.');
|
||||
// TODO check cwd read-write
|
||||
}
|
||||
|
||||
async function checkMail(log, warn) {
|
||||
const from = await system.get('smtp.from');
|
||||
if (!from) warn('SMTP account was not provided, email verification disabled.');
|
||||
}
|
||||
|
||||
async function checkProxy(log, warn) {
|
||||
const [github, google, proxy] = await system.getMany([
|
||||
'oauth.githubappid', 'oauth.googleappid', 'proxy',
|
||||
]);
|
||||
if (proxy) {
|
||||
superagent.get('https://www.google.com/').timeout(10000).proxy(proxy)
|
||||
.catch(() => warn('The proxy configured seem to be invalid.'));
|
||||
} else if (github || google) {
|
||||
warn('OAuth enabled. But for well-known reasons, a proxy is required.');
|
||||
}
|
||||
}
|
||||
|
||||
const checks = [
|
||||
checkDb,
|
||||
checkPerm,
|
||||
checkMail,
|
||||
checkProxy,
|
||||
];
|
||||
|
||||
async function start(log, warn, error, cb) {
|
||||
const id = String.random(6);
|
||||
cb(id);
|
||||
for (const check of checks) {
|
||||
if (c[id]) {
|
||||
delete c[id];
|
||||
return;
|
||||
}
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
await check(log, warn, error);
|
||||
}
|
||||
}
|
||||
|
||||
async function cancel(id) {
|
||||
c[id] = true;
|
||||
}
|
||||
|
||||
module.exports = { start, cancel };
|
||||
@@ -132,8 +132,12 @@ class HomeSecurityHandler extends Handler {
|
||||
);
|
||||
}
|
||||
}
|
||||
const path = [
|
||||
['Hydro', 'homepage'],
|
||||
['home_security', null],
|
||||
];
|
||||
this.response.template = 'home_security.html';
|
||||
this.response.body = { sessions, geoipProvider: (geoip || {}).provider };
|
||||
this.response.body = { sessions, geoipProvider: (geoip || {}).provider, path };
|
||||
if (useragent) this.response.body.icon = useragent.icon;
|
||||
}
|
||||
|
||||
@@ -202,7 +206,7 @@ class HomeSettingsHandler extends Handler {
|
||||
async post(args) {
|
||||
const $set = {};
|
||||
for (const key in args) {
|
||||
if (setting.SETTINGS_BY_KEY[key]) {
|
||||
if (setting.SETTINGS_BY_KEY[key] && !setting.SETTINGS_BY_KEY[key].disabled) {
|
||||
$set[key] = args[key];
|
||||
}
|
||||
}
|
||||
|
||||
+27
-5
@@ -3,9 +3,12 @@ const system = require('../model/system');
|
||||
const { STATUS, PRIV } = require('../model/builtin');
|
||||
const record = require('../model/record');
|
||||
const judge = require('./judge');
|
||||
const { Route, Handler } = require('../service/server');
|
||||
const {
|
||||
Route, Connection, Handler, ConnectionHandler,
|
||||
} = require('../service/server');
|
||||
const hpm = require('../lib/hpm');
|
||||
const loader = require('../loader');
|
||||
const check = require('../check');
|
||||
|
||||
class SystemHandler extends Handler {
|
||||
async prepare() {
|
||||
@@ -24,6 +27,24 @@ class SystemMainHandler extends SystemHandler {
|
||||
}
|
||||
}
|
||||
|
||||
class SystemCheckConnHandler extends ConnectionHandler {
|
||||
async prepare() {
|
||||
this.checkPriv(PRIV.PRIV_EDIT_SYSTEM);
|
||||
await this.check();
|
||||
}
|
||||
|
||||
async check() {
|
||||
const log = (payload) => this.send({ type: 'log', payload });
|
||||
const warn = (payload) => this.send({ type: 'warn', payload });
|
||||
const error = (payload) => this.send({ type: 'error', payload });
|
||||
await check.start(log, warn, error, (id) => { this.id = id; });
|
||||
}
|
||||
|
||||
async cleanup() {
|
||||
check.cancel(this.token);
|
||||
}
|
||||
}
|
||||
|
||||
class SystemDashboardHandler extends SystemHandler {
|
||||
async get() {
|
||||
this.response.template = 'manage_dashboard.html';
|
||||
@@ -111,8 +132,8 @@ class SystemScriptHandler extends SystemHandler {
|
||||
|
||||
class SystemSettingHandler extends SystemHandler {
|
||||
async get() {
|
||||
this.response.template = 'manage_settings.html';
|
||||
this.response.body.path.push(['manage_settings', null]);
|
||||
this.response.template = 'manage_setting.html';
|
||||
this.response.body.path.push(['manage_setting', null]);
|
||||
this.response.body.current = {};
|
||||
this.response.body.settings = setting.SYSTEM_SETTINGS;
|
||||
for (const s of this.response.body.settings) {
|
||||
@@ -129,7 +150,7 @@ class SystemSettingHandler extends SystemHandler {
|
||||
const subtasks = [];
|
||||
for (const sub in args[key]) {
|
||||
const s = setting.SYSTEM_SETTINGS_BY_KEY[`${key}.${sub}`];
|
||||
if (s) {
|
||||
if (s && !((s.flag & setting.FLAG_SECRET) && args[key][sub] === '')) {
|
||||
if (s.ui === 'number') args[key][sub] = Number(args[key][sub]);
|
||||
subtasks.push(system.set(`${key}.${sub}`, args[key][sub]));
|
||||
}
|
||||
@@ -137,7 +158,7 @@ class SystemSettingHandler extends SystemHandler {
|
||||
tasks.push(Promise.all(subtasks));
|
||||
} else {
|
||||
const s = setting.SYSTEM_SETTINGS_BY_KEY[key];
|
||||
if (s) {
|
||||
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]));
|
||||
}
|
||||
@@ -154,6 +175,7 @@ async function apply() {
|
||||
Route('manage_script', '/manage/script', SystemScriptHandler);
|
||||
Route('manage_module', '/manage/module', SystemModuleHandler);
|
||||
Route('manage_setting', '/manage/setting', SystemSettingHandler);
|
||||
Connection('manage_check', '/manage/check-conn', SystemCheckConnHandler);
|
||||
}
|
||||
|
||||
global.Hydro.handler.manage = module.exports = apply;
|
||||
@@ -1,10 +1,16 @@
|
||||
/* eslint-disable no-empty-function */
|
||||
/* eslint-disable class-methods-use-this */
|
||||
const { Route, Handler } = require('../service/server');
|
||||
const { NotFoundError } = require('../error');
|
||||
|
||||
class NotFoundHandler extends Handler {
|
||||
async prepare() { // eslint-disable-line class-methods-use-this
|
||||
async prepare() {
|
||||
throw new NotFoundError();
|
||||
}
|
||||
|
||||
async get() { }
|
||||
|
||||
async post() { }
|
||||
}
|
||||
|
||||
async function apply() {
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
// From https://github.com/pvorb/node-md5/blob/master/md5.js
|
||||
// BSD 3-Clause "New" or "Revised" License
|
||||
|
||||
/* eslint-disable no-bitwise */ /* eslint-disable max-len */
|
||||
/* eslint-disable max-len */
|
||||
function safeAdd(x, y) {
|
||||
const lsw = (x & 0xffff) + (y & 0xffff);
|
||||
const msw = (x >> 16) + (y >> 16) + (lsw >> 16);
|
||||
|
||||
@@ -23,6 +23,7 @@ class Nunjucks extends nunjucks.Environment {
|
||||
});
|
||||
this.addFilter('ansi', (self) => misc.ansiToHtml(self));
|
||||
this.addFilter('base64_encode', (s) => Buffer.from(s).toString('base64'));
|
||||
this.addFilter('bitand', (self, val) => self & val);
|
||||
}
|
||||
}
|
||||
const env = new Nunjucks();
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable no-bitwise */
|
||||
const PERM = {
|
||||
PERM_NONE: '',
|
||||
|
||||
|
||||
+17
-6
@@ -9,6 +9,10 @@ for (const country of countries) {
|
||||
}
|
||||
const timezones = Array.from(tzs).sort().map((tz) => [tz, tz]);
|
||||
|
||||
const FLAG_HIDDEN = 1;
|
||||
const FLAG_DISABLED = 2;
|
||||
const FLAG_SECRET = 4;
|
||||
|
||||
const PREFERENCE_SETTINGS = [];
|
||||
const ACCOUNT_SETTINGS = [];
|
||||
const DOMAIN_SETTINGS = [];
|
||||
@@ -23,9 +27,9 @@ const SYSTEM_SETTINGS_BY_KEY = {};
|
||||
const Setting = (
|
||||
family, key, range = null,
|
||||
value = null, type = 'text', name = '',
|
||||
desc = '', hidden = false, disabled = false,
|
||||
desc = '', flag = 0,
|
||||
) => ({
|
||||
family, key, range, value, type, name, desc, hidden, disabled,
|
||||
family, key, range, value, type, name, desc, flag,
|
||||
});
|
||||
|
||||
const PreferenceSetting = (...settings) => {
|
||||
@@ -93,11 +97,15 @@ DomainSetting(
|
||||
Setting('setting_domain', 'name', null, 'New domain', 'text', 'name'),
|
||||
Setting('setting_domain', 'gravatar', null, '', 'text', 'gravatar', 'Will be used as the domain icon.'),
|
||||
Setting('setting_domain', 'bulletin', null, '', 'markdown', 'Bulletin'),
|
||||
Setting('storage', 'nAccept', null, 0, 'number', 'nAccept', null, FLAG_HIDDEN & FLAG_DISABLED),
|
||||
Setting('storage', 'nSubmit', null, 0, 'number', 'nSubmit', null, FLAG_HIDDEN & FLAG_DISABLED),
|
||||
Setting('storage', 'nLike', null, 0, 'number', 'nLike', null, FLAG_HIDDEN & FLAG_DISABLED),
|
||||
Setting('storage', 'rating', null, 1500, 'number', 'rating', null, FLAG_HIDDEN & FLAG_DISABLED),
|
||||
);
|
||||
|
||||
SystemSetting(
|
||||
Setting('setting_smtp', 'smtp.user', null, null, 'text', 'SMTP Username'),
|
||||
Setting('setting_smtp', 'smtp.pass', null, null, 'password', 'SMTP Password'),
|
||||
Setting('setting_smtp', 'smtp.pass', null, null, 'password', 'SMTP Password', null, FLAG_SECRET),
|
||||
Setting('setting_smtp', 'smtp.host', null, null, 'text', 'SMTP Server Host'),
|
||||
Setting('setting_smtp', 'smtp.port', null, 465, 'number', 'SMTP Server Port'),
|
||||
Setting('setting_smtp', 'smtp.from', null, null, 'text', 'Mail From'),
|
||||
@@ -109,9 +117,9 @@ SystemSetting(
|
||||
Setting('setting_server', 'server.port', null, 8888, 'number', 'Server Port'),
|
||||
Setting('setting_server', 'server.log', null, false, 'boolean', 'Disable Access Log'),
|
||||
Setting('setting_oauth', 'oauth.githubappid', null, null, 'text', 'Github Oauth AppID'),
|
||||
Setting('setting_oauth', 'oauth.githubsecret', null, null, 'text', 'Github Oauth Secret'),
|
||||
Setting('setting_oauth', 'oauth.googleappid', null, null, 'text', 'Google Oauth ClientID'),
|
||||
Setting('setting_oauth', 'oauth.googlesecret', null, null, 'text', 'Google Oauth Secret'),
|
||||
Setting('setting_oauth', 'oauth.githubsecret', null, null, 'text', 'Github Oauth Secret', null, FLAG_SECRET),
|
||||
Setting('setting_oauth', 'oauth.googleappid', null, null, 'text', 'Google Oauth ClientID', null),
|
||||
Setting('setting_oauth', 'oauth.googlesecret', null, null, 'text', 'Google Oauth Secret', null, FLAG_SECRET),
|
||||
Setting('setting_proxy', 'proxy', null, null, 'text', 'Proxy Server URL'),
|
||||
Setting('setting_constant', 'PROBLEM_PER_PAGE', null, 100, 'number', 'Problems per Page'),
|
||||
Setting('setting_constant', 'CONTEST_PER_PAGE', null, 20, 'number', 'Contests per Page'),
|
||||
@@ -129,6 +137,9 @@ global.Hydro.model.setting = module.exports = {
|
||||
DomainSetting,
|
||||
DomainUserSetting,
|
||||
SystemSetting,
|
||||
FLAG_HIDDEN,
|
||||
FLAG_DISABLED,
|
||||
FLAG_SECRET,
|
||||
PREFERENCE_SETTINGS,
|
||||
ACCOUNT_SETTINGS,
|
||||
SETTINGS,
|
||||
|
||||
+22
-19
@@ -9,6 +9,14 @@ const db = require('../service/db');
|
||||
|
||||
const coll = db.collection('user');
|
||||
|
||||
function setPassword(uid, password) {
|
||||
const salt = String.random();
|
||||
return coll.findOneAndUpdate(
|
||||
{ _id: uid },
|
||||
{ $set: { salt, hash: pwhash(password, salt), hashType: 'hydro' } },
|
||||
);
|
||||
}
|
||||
|
||||
class USER {
|
||||
constructor(udoc, dudoc) {
|
||||
this.udoc = () => udoc;
|
||||
@@ -18,7 +26,12 @@ class USER {
|
||||
this.uname = udoc.uname;
|
||||
this.salt = () => udoc.salt;
|
||||
this.hash = () => udoc.hash;
|
||||
this.hashType = udoc.hashType || 'hydro';
|
||||
this.priv = udoc.priv;
|
||||
this.regat = udoc.regat;
|
||||
this.loginat = udoc.loginat;
|
||||
this.perm = dudoc.perm;
|
||||
this.role = dudoc.role || 'default';
|
||||
|
||||
for (const key in setting.SETTINGS_BY_KEY) {
|
||||
if (udoc[key]) this[key] = udoc[key];
|
||||
@@ -27,14 +40,12 @@ class USER {
|
||||
}
|
||||
}
|
||||
|
||||
this.regat = udoc.regat;
|
||||
this.loginat = udoc.loginat;
|
||||
this.ban = udoc.ban || false;
|
||||
this.nAccept = dudoc.nAccept || 0;
|
||||
this.nSubmit = dudoc.nSubmit || 0;
|
||||
this.rating = dudoc.rating || 1500;
|
||||
this.perm = dudoc.perm;
|
||||
this.role = dudoc.role || 'default';
|
||||
for (const key in setting.DOMAIN_USER_SETTINGS_BY_KEY) {
|
||||
if (dudoc[key]) this[key] = dudoc[key];
|
||||
else if (setting.DOMAIN_USER_SETTINGS_BY_KEY[key].value) {
|
||||
this[key] = setting.DOMAIN_USER_SETTINGS_BY_KEY[key].value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hasPerm(p) {
|
||||
@@ -42,15 +53,16 @@ class USER {
|
||||
}
|
||||
|
||||
hasPriv(p) {
|
||||
// eslint-disable-next-line no-bitwise
|
||||
return this.priv & p;
|
||||
}
|
||||
|
||||
checkPassword(password) {
|
||||
const h = global.Hydro.lib[`hash.${this.hashType || 'hydro'}`];
|
||||
const h = global.Hydro.lib[`hash.${this.hashType}`];
|
||||
if (!h) throw new Error('Unknown hash method');
|
||||
if (!(h(password, this.salt(), this) === this.hash())) {
|
||||
throw new LoginError(this.uname);
|
||||
} else if (this.hashType !== 'hydro') {
|
||||
setPassword(this._id, password);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -59,7 +71,6 @@ async function getInDomain(domainId, udoc) {
|
||||
let dudoc = await document.getStatus(domainId, document.TYPE_DOMAIN_USER, 0, udoc._id);
|
||||
dudoc = dudoc || {};
|
||||
if (udoc._id === 1) dudoc.role = 'guest';
|
||||
// eslint-disable-next-line no-bitwise
|
||||
if (udoc.priv & PRIV.PRIV_MANAGE_ALL_DOMAIN) dudoc.role = 'admin';
|
||||
const p = await document.get(domainId, document.TYPE_DOMAIN_USER, dudoc.role || 'default');
|
||||
dudoc.perm = p ? p.content : BUILTIN_ROLES[dudoc.role || 'default'].perm;
|
||||
@@ -116,14 +127,6 @@ async function getByEmail(domainId, mail, ignoreMissing = false) {
|
||||
return new USER(udoc, dudoc);
|
||||
}
|
||||
|
||||
function setPassword(uid, password) {
|
||||
const salt = String.random();
|
||||
return coll.findOneAndUpdate(
|
||||
{ _id: uid },
|
||||
{ $set: { salt, hash: pwhash(password, salt), hashType: 'hydro' } },
|
||||
);
|
||||
}
|
||||
|
||||
function setById(uid, $set, $unset) {
|
||||
const op = {};
|
||||
if ($set && Object.keys($set).length) op.$set = $set;
|
||||
|
||||
+74
-86
@@ -121,41 +121,7 @@ async function prepare() {
|
||||
}));
|
||||
}
|
||||
|
||||
class Handler {
|
||||
/**
|
||||
* @param {import('koa').Context} ctx
|
||||
*/
|
||||
constructor(ctx) {
|
||||
this.ctx = ctx;
|
||||
this.request = {
|
||||
host: ctx.request.host,
|
||||
hostname: ctx.request.hostname,
|
||||
ip: ctx.request.ip,
|
||||
headers: ctx.request.headers,
|
||||
cookies: ctx.cookies,
|
||||
body: ctx.request.body,
|
||||
files: ctx.request.files,
|
||||
query: ctx.query,
|
||||
path: ctx.path,
|
||||
params: ctx.params,
|
||||
referer: ctx.request.headers.referer || '/',
|
||||
};
|
||||
this.response = {
|
||||
body: '',
|
||||
type: '',
|
||||
status: null,
|
||||
template: null,
|
||||
redirect: null,
|
||||
attachment: (name) => ctx.attachment(name),
|
||||
};
|
||||
this.UIContext = {
|
||||
cdn_prefix: '/',
|
||||
url_prefix: '/',
|
||||
};
|
||||
this._handler = {};
|
||||
this.session = {};
|
||||
}
|
||||
|
||||
const HandlerMixin = (Class) => class extends Class {
|
||||
async renderHTML(name, context) {
|
||||
if (enableLog) console.time(name);
|
||||
this.hasPerm = (perm) => this.user.hasPerm(perm);
|
||||
@@ -171,9 +137,12 @@ class Handler {
|
||||
return res;
|
||||
}
|
||||
|
||||
async render(name, context) {
|
||||
this.response.body = await this.renderHTML(name, context);
|
||||
this.response.type = 'text/html';
|
||||
async limitRate(op, periodSecs, maxOperations) {
|
||||
await opcount.inc(op, this.request.ip, periodSecs, maxOperations);
|
||||
}
|
||||
|
||||
translate(str) {
|
||||
return str ? str.toString().translate(this.user.viewLang || this.session.viewLang) : '';
|
||||
}
|
||||
|
||||
renderTitle(str) {
|
||||
@@ -214,26 +183,6 @@ class Handler {
|
||||
}
|
||||
}
|
||||
|
||||
async limitRate(op, periodSecs, maxOperations) {
|
||||
await opcount.inc(op, this.request.ip, periodSecs, maxOperations);
|
||||
}
|
||||
|
||||
back(body) {
|
||||
this.response.body = body || this.response.body || {};
|
||||
this.response.redirect = this.request.headers.referer || '/';
|
||||
}
|
||||
|
||||
translate(str) {
|
||||
return str ? str.toString().translate(this.user.viewLang || this.session.viewLang) : '';
|
||||
}
|
||||
|
||||
binary(data, name) {
|
||||
this.response.body = data;
|
||||
this.response.template = null;
|
||||
this.response.type = 'application/octet-stream';
|
||||
this.response.disposition = `attachment; filename="${name}"`;
|
||||
}
|
||||
|
||||
url(name, kwargs = {}) {
|
||||
let res = '#';
|
||||
const args = { ...kwargs };
|
||||
@@ -252,8 +201,61 @@ class Handler {
|
||||
}
|
||||
return res;
|
||||
}
|
||||
};
|
||||
|
||||
async ___prepare({ domainId }) {
|
||||
const Handler = HandlerMixin(class {
|
||||
/**
|
||||
* @param {import('koa').Context} ctx
|
||||
*/
|
||||
constructor(ctx) {
|
||||
this.ctx = ctx;
|
||||
this.request = {
|
||||
host: ctx.request.host,
|
||||
hostname: ctx.request.hostname,
|
||||
ip: ctx.request.ip,
|
||||
headers: ctx.request.headers,
|
||||
cookies: ctx.cookies,
|
||||
body: ctx.request.body,
|
||||
files: ctx.request.files,
|
||||
query: ctx.query,
|
||||
path: ctx.path,
|
||||
params: ctx.params,
|
||||
referer: ctx.request.headers.referer || '/',
|
||||
};
|
||||
this.response = {
|
||||
body: '',
|
||||
type: '',
|
||||
status: null,
|
||||
template: null,
|
||||
redirect: null,
|
||||
attachment: (name) => ctx.attachment(name),
|
||||
};
|
||||
this.UIContext = {
|
||||
cdn_prefix: '/',
|
||||
url_prefix: '/',
|
||||
};
|
||||
this._handler = {};
|
||||
this.session = {};
|
||||
}
|
||||
|
||||
async render(name, context) {
|
||||
this.response.body = await this.renderHTML(name, context);
|
||||
this.response.type = 'text/html';
|
||||
}
|
||||
|
||||
back(body) {
|
||||
this.response.body = body || this.response.body || {};
|
||||
this.response.redirect = this.request.headers.referer || '/';
|
||||
}
|
||||
|
||||
binary(data, name) {
|
||||
this.response.body = data;
|
||||
this.response.template = null;
|
||||
this.response.type = 'application/octet-stream';
|
||||
this.response.disposition = `attachment; filename="${name}"`;
|
||||
}
|
||||
|
||||
async init({ domainId }) {
|
||||
this.response.body = {};
|
||||
this.now = new Date();
|
||||
this._handler.sid = this.request.cookies.get('sid');
|
||||
@@ -377,7 +379,7 @@ class Handler {
|
||||
};
|
||||
await this.___cleanup().catch(() => { });
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
async function handle(ctx, HandlerClass, checker) {
|
||||
global.Hydro.stat.reqCount++;
|
||||
@@ -394,7 +396,7 @@ async function handle(ctx, HandlerClass, checker) {
|
||||
.replace(/_([a-z])/gm, (s) => s[1].toUpperCase());
|
||||
}
|
||||
|
||||
if (h.___prepare) await h.___prepare(args);
|
||||
if (h.init) await h.init(args);
|
||||
if (checker) checker.call(h);
|
||||
if (method === 'post') {
|
||||
await h.checkCsrfToken(args.csrfToken);
|
||||
@@ -437,7 +439,7 @@ async function handle(ctx, HandlerClass, checker) {
|
||||
if (h.__cleanup) await h.__cleanup(args);
|
||||
if (h.___cleanup) await h.___cleanup(args);
|
||||
} catch (e) {
|
||||
if (h.onerror) await h.onerror(e);
|
||||
await h.onerror(e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -471,7 +473,7 @@ function Route(name, route, RouteHandler, ...permPrivChecker) {
|
||||
router.all(`${name}_with_domainId`, `/d/:domainId${route}`, (ctx) => handle(ctx, RouteHandler, checker));
|
||||
}
|
||||
|
||||
class ConnectionHandler {
|
||||
const ConnectionHandler = HandlerMixin(class {
|
||||
/**
|
||||
* @param {import('sockjs').Connection} conn
|
||||
*/
|
||||
@@ -486,25 +488,6 @@ class ConnectionHandler {
|
||||
for (const i in p) this.request.params[p[i][0]] = decodeURIComponent(p[i][1]);
|
||||
}
|
||||
|
||||
url(name, kwargs = {}) {
|
||||
let res = '#';
|
||||
const args = { ...kwargs };
|
||||
try {
|
||||
if (this.args.domainId !== 'system') {
|
||||
name += '_with_domainId';
|
||||
args.domainId = args.domainId || this.args.domainId;
|
||||
}
|
||||
const { anchor, query } = args;
|
||||
if (query) res = router.url(name, args, { query });
|
||||
else res = router.url(name, args);
|
||||
if (anchor) return `${res}#${anchor}`;
|
||||
} catch (e) {
|
||||
console.error(e.message);
|
||||
console.error(name, kwargs);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
async renderHTML(name, context) {
|
||||
this._user = { ...this.user, gravatar: misc.gravatar(this.user.gravatar, 128) };
|
||||
const res = await template.render(name, Object.assign(context, {
|
||||
@@ -524,7 +507,12 @@ class ConnectionHandler {
|
||||
this.conn.close(code, reason);
|
||||
}
|
||||
|
||||
async ___prepare({ domainId }) {
|
||||
onerror(err) {
|
||||
console.error(err);
|
||||
this.close(1001, err.toString());
|
||||
}
|
||||
|
||||
async init({ domainId }) {
|
||||
try {
|
||||
this.session = await token.get(this.request.params.token, token.TYPE_CSRF_TOKEN);
|
||||
await token.del(this.request.params.token, token.TYPE_CSRF_TOKEN);
|
||||
@@ -536,7 +524,7 @@ class ConnectionHandler {
|
||||
this.user = await user.getById(domainId, this.session.uid);
|
||||
if (!this.user) throw new UserNotFoundError(this.session.uid);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function Connection(name, prefix, RouteConnHandler, permission) {
|
||||
const sock = sockjs.createServer({ prefix });
|
||||
@@ -545,7 +533,7 @@ function Connection(name, prefix, RouteConnHandler, permission) {
|
||||
try {
|
||||
const args = { domainId: 'system', ...h.request.params };
|
||||
h.args = args;
|
||||
if (h.___prepare) await h.___prepare(args);
|
||||
if (h.init) await h.init(args);
|
||||
if (permission) h.checkPerm(permission);
|
||||
let checking = '';
|
||||
try {
|
||||
@@ -575,7 +563,7 @@ function Connection(name, prefix, RouteConnHandler, permission) {
|
||||
});
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
if (h.onerror) await h.onerror(e);
|
||||
await h.onerror(e);
|
||||
}
|
||||
});
|
||||
sock.installHandlers(server);
|
||||
|
||||
Reference in new issue
Block a user