From 92c62cb118437f41c921bea828cd006db09dc972 Mon Sep 17 00:00:00 2001 From: undefined Date: Tue, 20 Sep 2022 02:23:56 +0800 Subject: [PATCH] core: fix oauth redirect --- packages/hydrooj/package.json | 2 +- packages/hydrooj/src/entry/cli.ts | 2 +- packages/hydrooj/src/entry/common.ts | 120 +++++++++------------------ packages/hydrooj/src/entry/worker.ts | 7 +- packages/hydrooj/src/handler/user.ts | 2 + packages/hydrooj/src/loader.ts | 46 +++++----- 6 files changed, 67 insertions(+), 112 deletions(-) diff --git a/packages/hydrooj/package.json b/packages/hydrooj/package.json index 578f6f971..96f47f066 100644 --- a/packages/hydrooj/package.json +++ b/packages/hydrooj/package.json @@ -1,6 +1,6 @@ { "name": "hydrooj", - "version": "3.17.9", + "version": "3.17.10", "bin": "bin/hydrooj.js", "main": "src/loader", "module": "src/loader", diff --git a/packages/hydrooj/src/entry/cli.ts b/packages/hydrooj/src/entry/cli.ts index 543cd0bc3..e37d8996e 100644 --- a/packages/hydrooj/src/entry/cli.ts +++ b/packages/hydrooj/src/entry/cli.ts @@ -104,6 +104,6 @@ export async function load() { require('../model/index'); await model(pending, fail); require('../script/index'); - await script(pending, fail, []); + await script(pending, fail); await cli(); } diff --git a/packages/hydrooj/src/entry/common.ts b/packages/hydrooj/src/entry/common.ts index 4cfb71851..d03753c2c 100644 --- a/packages/hydrooj/src/entry/common.ts +++ b/packages/hydrooj/src/entry/common.ts @@ -11,45 +11,57 @@ import * as bus from '../service/bus'; const logger = new Logger('common'); -function getFiles(folder: string, base = ''): string[] { +async function getFiles(folder: string, base = ''): Promise { const files = []; - const f = fs.readdirSync(folder); + const f = await fs.readdir(folder); for (const i of f) { - if (fs.statSync(path.join(folder, i)).isDirectory()) { - files.push(...getFiles(path.join(folder, i), path.join(base, i))); + if ((await fs.stat(path.join(folder, i))).isDirectory()) { + files.push(...await getFiles(path.join(folder, i), path.join(base, i))); } else files.push(path.join(base, i)); } return files.map((item) => item.replace(/\\/gmi, '/')); } -export async function handler(pending: string[], fail: string[]) { +function locateFile(basePath: string, filenames: string[]) { + for (const i of filenames) { + const p = path.resolve(basePath, i); + if (fs.existsSync(p)) return p; + } + return null; +} + +const getLoader = (type: string, filename: string) => async function loader(pending: string[], fail: string[]) { for (const i of pending) { - let p = path.resolve(i, 'handler.ts'); - if (!fs.existsSync(p)) p = path.resolve(i, 'handler.js'); - if (fs.existsSync(p) && !fail.includes(i)) { + const p = locateFile(i, [`${filename}.ts`, `${filename}.js`]); + if (p && !fail.includes(i)) { try { - logger.info('Handler init: %s', i); + logger.info(`${type.replace(/^(.)/, (t) => t.toUpperCase())} init: %s`, i); require(p); } catch (e) { fail.push(i); - logger.error('Handler Load Fail: %s', i); + logger.info(`${type.replace(/^(.)/, (t) => t.toUpperCase())} load fail: %s`, i); logger.error(e); } } } - await bus.serial('app/load/handler'); -} + await bus.serial(`app/load/${type}`); +}; + +export const handler = getLoader('handler', 'handler'); +export const addon = getLoader('addon', 'index'); +export const model = getLoader('model', 'model'); +export const lib = getLoader('lib', 'lib'); +export const script = getLoader('script', 'script'); export async function locale(pending: string[], fail: string[]) { - for (const i of pending) { - let p = path.resolve(i, 'locales'); - if (!fs.existsSync(p)) p = path.resolve(i, 'locale'); - if (fs.existsSync(p) && fs.statSync(p).isDirectory() && !fail.includes(i)) { + await Promise.all(pending.map(async (i) => { + const p = locateFile(i, ['locale', 'locales']); + if (p && (await fs.stat(p)).isDirectory() && !fail.includes(i)) { try { - const files = fs.readdirSync(p); + const files = await fs.readdir(p); const locales = {}; for (const file of files) { - const content = fs.readFileSync(path.resolve(p, file)).toString(); + const content = await fs.readFile(path.resolve(p, file), 'utf-8'); locales[file.split('.')[0]] = yaml.load(content); } i18n(locales); @@ -60,7 +72,7 @@ export async function locale(pending: string[], fail: string[]) { logger.error(e); } } - } + })); await bus.serial('app/load/locale'); } @@ -74,11 +86,12 @@ export async function setting(pending: string[], fail: string[], modelSetting: t for (const i of 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(fs.readFileSync(p, 'utf-8')); + 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') { @@ -106,11 +119,10 @@ export async function setting(pending: string[], fail: string[], modelSetting: t export async function template(pending: string[], fail: string[]) { for (const i of pending) { - let p = path.resolve(i, 'templates'); - if (!fs.existsSync(p)) p = path.resolve(i, 'template'); - if (fs.existsSync(p) && fs.statSync(p).isDirectory() && !fail.includes(i)) { + const p = locateFile(i, ['template', 'templates']); + if (p && (await fs.stat(p)).isDirectory() && !fail.includes(i)) { try { - const files = getFiles(p); + const files = await getFiles(p); for (const file of files) { if (file.endsWith('.tsx')) global.Hydro.ui.template[file] = require(path.resolve(p, file)); global.Hydro.ui.template[file] = await fs.readFile(path.resolve(p, file), 'utf-8'); @@ -126,47 +138,10 @@ export async function template(pending: string[], fail: string[]) { await bus.serial('app/load/template'); } -export async function model(pending: string[], fail: string[]) { - for (const i of pending) { - let p = path.resolve(i, 'model.ts'); - if (!fs.existsSync(p)) p = path.resolve(i, 'model.js'); - if (fs.existsSync(p) && !fail.includes(i)) { - try { - logger.info('Model init: %s', i); - require(p); - } catch (e) { - fail.push(i); - logger.error('Model Load Fail: %s', i); - logger.error(e); - } - } - } - await bus.serial('app/load/model'); -} - -export async function lib(pending: string[], fail: string[]) { - for (const i of pending) { - let p = path.resolve(i, 'lib.ts'); - if (!fs.existsSync(p)) p = path.resolve(i, 'lib.js'); - if (fs.existsSync(p) && !fail.includes(i)) { - try { - logger.info('Lib init: %s', i); - require(p); - } catch (e) { - fail.push(i); - logger.error('Lib Load Fail: %s', i); - logger.error(e); - } - } - } - await bus.serial('app/load/lib'); -} - export async function service(pending: string[], fail: string[]) { for (const i of pending) { - let p = path.resolve(i, 'service.ts'); - if (!fs.existsSync(p)) p = path.resolve(i, 'service.js'); - if (fs.existsSync(p) && !fail.includes(i)) { + const p = locateFile(i, ['service.ts', 'service.js']); + if (p && !fail.includes(i)) { try { logger.info('Service init: %s', i); require(p); @@ -184,22 +159,3 @@ export async function service(pending: string[], fail: string[]) { } await bus.serial('app/load/service'); } - -export async function script(pending: string[], fail: string[], active: string[]) { - for (const i of pending) { - let p = path.resolve(i, 'script.ts'); - if (!fs.existsSync(p)) p = path.resolve(i, 'script.js'); - if (await fs.pathExists(p) && !fail.includes(i)) { - try { - logger.info('Script init: %s', i); - require(p); - } catch (e) { - fail.push(i); - logger.error('Script Load Fail: %s', i); - logger.error(e); - } - } - active.push(i); - } - await bus.serial('app/load/script'); -} diff --git a/packages/hydrooj/src/entry/worker.ts b/packages/hydrooj/src/entry/worker.ts index f4577695b..9ba609163 100644 --- a/packages/hydrooj/src/entry/worker.ts +++ b/packages/hydrooj/src/entry/worker.ts @@ -28,7 +28,6 @@ export async function load() { } const pending = global.addons; const fail = []; - const active = []; if (detail) logger.info('start'); await Promise.all([ locale(pending, fail), @@ -73,7 +72,7 @@ export async function load() { await notfound.apply(); require('../script/index'); if (detail) logger.info('finish: script.builtin'); - await script(pending, fail, active); + await script(pending, fail); if (detail) logger.info('finish: script.extra'); await bus.serial('app/started'); if (detail) logger.info('finish: bus.serial(start)'); @@ -98,6 +97,6 @@ export async function load() { } } logger.success('Server started'); - if (process.send) process.send('ready'); - return { active, fail }; + process.send?.('ready'); + return { fail }; } diff --git a/packages/hydrooj/src/handler/user.ts b/packages/hydrooj/src/handler/user.ts index 9450ec043..f69e475f3 100644 --- a/packages/hydrooj/src/handler/user.ts +++ b/packages/hydrooj/src/handler/user.ts @@ -148,6 +148,7 @@ class UserLogoutHandler extends Handler { async post() { this.session.uid = 0; this.session.scope = PERM.PERM_ALL.toString(); + this.response.redirect = '/'; } } @@ -379,6 +380,7 @@ class OauthCallbackHandler extends Handler { await user.setById(udoc._id, { loginat: new Date(), loginip: this.request.ip }); this.session.uid = udoc._id; this.session.scope = PERM.PERM_ALL.toString(); + this.response.redirect = '/'; return; } } diff --git a/packages/hydrooj/src/loader.ts b/packages/hydrooj/src/loader.ts index 922d6ba1b..d38920db3 100644 --- a/packages/hydrooj/src/loader.ts +++ b/packages/hydrooj/src/loader.ts @@ -24,33 +24,31 @@ process.on('unhandledRejection', logger.error); process.on('uncaughtException', logger.error); export function addon(addonPath: string, prepend = false) { - if (!(fs.existsSync(addonPath) && fs.statSync(addonPath).isFile())) { - try { - // Is a npm package - const packagejson = require.resolve(`${addonPath}/package.json`); - // eslint-disable-next-line import/no-dynamic-require - const payload = require(packagejson); - const name = payload.name.startsWith('@hydrooj/') ? payload.name.split('@hydrooj/')[1] : payload.name; - global.Hydro.version[name] = payload.version; - const modulePath = path.dirname(packagejson); - const publicPath = path.resolve(modulePath, 'public'); - if (fs.existsSync(publicPath)) { - global.publicDirs[prepend ? 'push' : 'unshift'](publicPath); - const targets = fs.readdirSync(publicPath); - for (const target of targets) { - if (global.Hydro.ui.manifest[target] && !prepend) { - global.Hydro.ui.manifest[target] = publicPath; - } else if (!global.Hydro.ui.manifest[target]) { - global.Hydro.ui.manifest[target] = publicPath; - } + try { + // Is a npm package + const packagejson = require.resolve(`${addonPath}/package.json`); + // eslint-disable-next-line import/no-dynamic-require + const payload = require(packagejson); + const name = payload.name.startsWith('@hydrooj/') ? payload.name.split('@hydrooj/')[1] : payload.name; + global.Hydro.version[name] = payload.version; + const modulePath = path.dirname(packagejson); + const publicPath = path.resolve(modulePath, 'public'); + if (fs.existsSync(publicPath)) { + global.publicDirs[prepend ? 'push' : 'unshift'](publicPath); + const targets = fs.readdirSync(publicPath); + for (const target of targets) { + if (global.Hydro.ui.manifest[target] && !prepend) { + global.Hydro.ui.manifest[target] = publicPath; + } else if (!global.Hydro.ui.manifest[target]) { + global.Hydro.ui.manifest[target] = publicPath; } } - global.addons[prepend ? 'unshift' : 'push'](modulePath); - } catch (e) { - logger.error(`Addon not found: ${addonPath}`); - logger.error(e); } - } else logger.error(`Addon not found: ${addonPath}`); + global.addons[prepend ? 'unshift' : 'push'](modulePath); + } catch (e) { + logger.error(`Addon not found: ${addonPath}`); + logger.error(e); + } } export function addScript(name: string, description: string) {