diff --git a/packages/hydrooj/src/service/layers/base.ts b/packages/hydrooj/src/service/layers/base.ts index 4ff10f48..fd0f3012 100644 --- a/packages/hydrooj/src/service/layers/base.ts +++ b/packages/hydrooj/src/service/layers/base.ts @@ -1,6 +1,7 @@ import { PassThrough } from 'stream'; import type { Next } from 'koa'; import { cloneDeep, pick } from 'lodash'; +import { PERM } from '../../model/builtin'; import * as system from '../../model/system'; import token from '../../model/token'; import type { HydroRequest, HydroResponse, KoaContext } from '../server'; @@ -65,12 +66,19 @@ export default async (ctx: KoaContext, next: Next) => { ctx.HydroContext = { request, response, UiContext, domain: domainInfo, user: null, args, }; + const header = ctx.request.headers.authorization; + const sid = header + ? header.split(' ')[1] // Accept bearer token + : ctx.cookies.get('sid') || ctx.query.sid; // FIXME maybe a better way for shared conn? + const session = sid ? await token.get(sid instanceof Array ? sid[0] : sid, token.TYPE_SESSION) : null; + ctx.session = Object.create(session || { uid: 0, scope: PERM.PERM_ALL.toString() }); await next(); const ua = request.headers['user-agent'] || ''; if (!ctx.session.uid && system.get('server.ignoreUA').replace(/\r/g, '').split('\n').filter((i) => i && ua.includes(i)).length) return; const expireSeconds = ctx.session.save ? system.get('session.saved_expire_seconds') : system.get('session.unsaved_expire_seconds'); + if (!ctx.session._id && !Object.getOwnPropertyNames(ctx.session).length) return; Object.assign(ctx.session, { updateIp: request.ip, updateUa: ua }); if (ctx.session._id) { await token.update(ctx.session._id, token.TYPE_SESSION, expireSeconds, ctx.session); diff --git a/packages/hydrooj/src/service/layers/domain.ts b/packages/hydrooj/src/service/layers/domain.ts index e4b59e65..0c5cfc24 100644 --- a/packages/hydrooj/src/service/layers/domain.ts +++ b/packages/hydrooj/src/service/layers/domain.ts @@ -1,7 +1,6 @@ import BlackListModel from '../../model/blacklist'; import DomainModel from '../../model/domain'; import * as system from '../../model/system'; -import token from '../../model/token'; import { KoaContext } from '../server'; export default async (ctx: KoaContext, next) => { @@ -12,29 +11,18 @@ export default async (ctx: KoaContext, next) => { let ip = ctx.request.headers[xff?.toLowerCase() || ''] as string || ctx.request.ip; ip = ip.split(',')[0].trim(); const host = ctx.request.headers[xhost?.toLowerCase() || ''] as string || ctx.request.host; - const header = ctx.request.headers.authorization; - const sid = header - ? header.split(' ')[1] // Accept bearer token - : ctx.cookies.get('sid') || ctx.query.sid; // FIXME maybe a better way for shared conn? - let domainId = forceDomain?.[1] || 'system'; - const [absoluteDomain, inferDomain, bdoc, session] = await Promise.all([ + const domainId = forceDomain?.[1] || 'system'; + const [absoluteDomain, inferDomain, bdoc] = await Promise.all([ DomainModel.get(domainId), - forceDomain ? Promise.resolve() : DomainModel.getByHost(host), + forceDomain ? Promise.resolve(null) : DomainModel.getByHost(host), BlackListModel.get(`ip::${ip}`), - token.get(sid instanceof Array ? sid[0] : sid, token.TYPE_SESSION), ]); if (bdoc) { ctx.body = 'blacklisted'; // Just return 404 if blacklisted return; } - if (inferDomain) domainId = inferDomain._id; - ctx.domainId = domainId; + ctx.domainId = inferDomain?._id || domainId; ctx.domainInfo = inferDomain || absoluteDomain; - if (domainId !== ctx.domainInfo._id) { - // Case sensitive - ctx.redirect(ctx.originalPath.replace(/^\/d\/[^/]+\//, `/d/${ctx.domainInfo._id}/`)); - } else { - ctx.session = session || { uid: 0 }; - await next(); - } + if (domainId !== ctx.domainInfo._id) ctx.redirect(ctx.originalPath.replace(/^\/d\/[^/]+\//, `/d/${ctx.domainInfo._id}/`)); + else await next(); };