diff --git a/hydro/entry/common.js b/hydro/entry/common.js index 5a37b4de0..cc6a80855 100644 --- a/hydro/entry/common.js +++ b/hydro/entry/common.js @@ -1,3 +1,4 @@ +/* eslint-disable no-await-in-loop */ /* eslint-disable no-eval */ const os = require('os'); const fs = require('fs'); @@ -6,7 +7,7 @@ const builtinLib = [ 'axios', 'download', 'i18n', 'mail', 'markdown', 'md5', 'misc', 'paginate', 'hash.hydro', 'rank', 'template', 'validator', 'nav', 'sysinfo', 'testdata.convert.ini', - 'readConfig', + 'readConfig', 'logger', ]; const builtinModel = [ @@ -59,6 +60,25 @@ async function locale(pending, fail) { } } +async function config(pending, fail, system) { + for (const i of pending) { + const p = `${os.tmpdir()}/hydro/tmp/${i}/config.js`; + if (fs.existsSync(p) && !fail.includes(i)) { + try { + global.Hydro.config[i] = eval('require')(p); + for (const key in global.Hydro.config[i]) { + if (global.Hydro.config[i][key].default) { + const current = await system.get(`${i}.${key}`); + if (!current) await system.set(`${i}.${key}`, global.Hydro.config[i][key].default); + } + } + } catch (e) { + console.error(`Config Load Fail: ${i}`); + } + } + } +} + async function template(pending, fail) { for (const i of pending) { const p = `${os.tmpdir()}/hydro/tmp/${i}/template.json`; @@ -157,4 +177,5 @@ module.exports = { script, service, template, + config, }; diff --git a/hydro/entry/master.js b/hydro/entry/master.js index b8063490d..3d7fcc288 100644 --- a/hydro/entry/master.js +++ b/hydro/entry/master.js @@ -4,8 +4,8 @@ const os = require('os'); const fs = require('fs'); const path = require('path'); const { - lib, service, model, handler, script, - builtinLib, builtinScript, builtinHandler, builtinModel, + lib, service, model, config, + builtinLib, builtinHandler, builtinModel, } = require('./common'); function ensureDir(dir) { @@ -67,10 +67,7 @@ async function load(call) { const ins = require('../script/install'); await ins.run({ username: 'Root', password: 'rootroot' }); } - await handler(pending, fail); - for (const i in global.Hydro.handler) { - await global.Hydro.handler[i](); - } + await config(pending, fail); for (const i in global.Hydro.service) { if (global.Hydro.service[i].postInit) { try { @@ -80,8 +77,6 @@ async function load(call) { } } } - for (const i of builtinScript) require(`../script/${i}`); - await script(pending, fail, active); pending = []; return { fail, active }; } diff --git a/hydro/handler/contest.js b/hydro/handler/contest.js index bd8cc1dd2..c4271a510 100644 --- a/hydro/handler/contest.js +++ b/hydro/handler/contest.js @@ -149,10 +149,8 @@ class ContestEditHandler extends ContestDetailHandler { async post({ domainId, beginAtDate, beginAtTime, duration, title, content, rule, pids, rated = false, }) { - let beginAt; - try { - beginAt = moment.tz(`${beginAtDate} ${beginAtTime}`, this.user.timeZone); - } catch (e) { + let beginAt = moment.tz(`${beginAtDate} ${beginAtTime}`, this.user.timeZone); + if (!beginAt.isValid()) { throw new ValidationError('beginAtDate', 'beginAtTime'); } const endAt = beginAt.clone().add(duration, 'hours').toDate(); @@ -288,10 +286,8 @@ class ContestCreateHandler extends ContestHandler { async post({ domainId, title, content, rule, beginAtDate, beginAtTime, duration, pids, rated = false, }) { - let beginAt; - try { - beginAt = moment.tz(`${beginAtDate} ${beginAtTime}`, this.user.timeZone); - } catch (e) { + const beginAt = moment.tz(`${beginAtDate} ${beginAtTime}`, this.user.timeZone); + if (!beginAt.isValid()) { throw new ValidationError('beginAtDate', 'beginAtTime'); } const endAt = beginAt.clone().add(duration, 'hours'); diff --git a/hydro/lib/hash.hydro.js b/hydro/lib/hash.hydro.js index 6a797906b..80931fe2a 100644 --- a/hydro/lib/hash.hydro.js +++ b/hydro/lib/hash.hydro.js @@ -1,20 +1,12 @@ const crypto = require('crypto'); -global.Hydro.lib['hash.hydro'] = module.exports = { - /** - * @param {string} password - * @param {string} salt - * @param {string} hash - */ - check(password, salt, hash) { - return hash === this.hash(password, salt); - }, - /** - * @param {string} password - * @param {string} salt - */ - hash(password, salt) { - const res = crypto.pbkdf2Sync(password, salt, 100000, 64, 'sha256'); - return res.toString('Hex'); - }, -}; +/** + * @param {string} password + * @param {string} salt + */ +function hash(password, salt) { + const res = crypto.pbkdf2Sync(password, salt, 100000, 64, 'sha256'); + return res.toString('Hex'); +} + +global.Hydro.lib['hash.hydro'] = module.exports = hash; diff --git a/hydro/lib/logger.js b/hydro/lib/logger.js new file mode 100644 index 000000000..e50548e1b --- /dev/null +++ b/hydro/lib/logger.js @@ -0,0 +1,23 @@ +const yaml = require('js-yaml'); + +function warp(func, type) { + return (...args) => { + const time = new Date(); + func(...args); + if (global.Hydro.model.message) { + global.Hydro.model.message.send(1, 1, yaml.safeDump({ time, type, args })); + } + }; +} + +class Logger { + constructor() { + this.log = warp(console.log, 'log'); + this.error = warp(console.error, 'error'); + this.info = warp(console.info, 'info'); + this.warn = warp(console.warn, 'warn'); + this.debug = warp(console.debug, 'debug'); + } +} + +global.Hydro.lib.logger = module.exports = new Logger(); diff --git a/hydro/loader.js b/hydro/loader.js index 70d845133..46dddde45 100644 --- a/hydro/loader.js +++ b/hydro/loader.js @@ -46,6 +46,7 @@ async function load() { mongodb: require('mongodb'), }; global.Hydro = { + config: {}, handler: {}, service: {}, model: {}, diff --git a/hydro/model/file.js b/hydro/model/file.js index 180fea72f..a099ee4a7 100644 --- a/hydro/model/file.js +++ b/hydro/model/file.js @@ -57,8 +57,8 @@ async function get(_id, secret) { const file = await coll.findOne({ _id }); if (typeof secret !== 'undefined') { const timestamp = _timestamp(); - if (!hash.check(file.secret, timestamp.toString(), secret)) { - if (!hash.check(file.secret, timestamp.toString() - 1, secret)) { + if (!(hash(file.secret, timestamp.toString()) === secret)) { + if (!(hash(file.secret, timestamp.toString() - 1) === secret)) { throw new ForbiddenError(); } } @@ -72,7 +72,7 @@ function getMeta(_id) { async function url(_id, name) { const file = await coll.findOne({ _id }); - const secret = hash.hash(file.secret, _timestamp().toString()); + const secret = hash(file.secret, _timestamp().toString()); if (name) return `/fs/${_id}/${Buffer.from(name).toString('base64')}/${secret}`; return `/fs/${_id}/${secret}`; } diff --git a/module/migrate-vijos/lib.js b/module/migrate-vijos/lib.js index cc56062e3..f5b67f810 100644 --- a/module/migrate-vijos/lib.js +++ b/module/migrate-vijos/lib.js @@ -1,22 +1,10 @@ const { md5, sha1 } = global.Hydro.lib; -global.Hydro.lib['hash.vj2'] = module.exports = { - /** - * @param {string} password - * @param {string} salt - * @param {string} hash - */ - check(password, salt, hash, udoc) { - return hash === this.hash(password, salt, udoc); - }, - /** - * @param {string} password - * @param {string} salt - */ - hash(password, salt, udoc) { - const { uname, unameLower } = udoc; - const pmd5 = md5(password); - const mixedSha1 = sha1(md5(unameLower + pmd5) + salt + sha1(pmd5 + salt)); - return `${Buffer.from(uname).toString('base64')}|${mixedSha1}`; - }, -}; +function hash(password, salt, udoc) { + const { uname, unameLower } = udoc; + const pmd5 = md5(password); + const mixedSha1 = sha1(md5(unameLower + pmd5) + salt + sha1(pmd5 + salt)); + return `${Buffer.from(uname).toString('base64')}|${mixedSha1}`; +} + +global.Hydro.lib['hash.vj2'] = module.exports = hash;