From 90cdc163ca07b6e0ca28a840c204feb275b2c395 Mon Sep 17 00:00:00 2001 From: masnn Date: Tue, 13 Apr 2021 18:24:07 +0000 Subject: [PATCH] core: ignore _ prefixed keys when serializing --- packages/hydrooj/src/handler/domain.ts | 2 +- packages/hydrooj/src/interface.ts | 23 ++++++++------- packages/hydrooj/src/model/domain.ts | 2 +- packages/hydrooj/src/model/user.ts | 40 ++++++++++++++------------ packages/hydrooj/src/service/server.ts | 8 +++++- packages/hydrooj/src/upgrade.ts | 10 +++++++ 6 files changed, 53 insertions(+), 32 deletions(-) diff --git a/packages/hydrooj/src/handler/domain.ts b/packages/hydrooj/src/handler/domain.ts index a7abc5da3..a2eec10b9 100644 --- a/packages/hydrooj/src/handler/domain.ts +++ b/packages/hydrooj/src/handler/domain.ts @@ -248,7 +248,7 @@ class DomainJoinApplicationsHandler extends ManageHandler { else joinSettings.expire = moment().add(expire, 'hours').toDate(); if (method === domain.JOIN_METHOD_CODE) joinSettings.code = invitationCode; } - await domain.edit(domainId, { join: joinSettings }); + await domain.edit(domainId, { _join: joinSettings }); this.back(); } } diff --git a/packages/hydrooj/src/interface.ts b/packages/hydrooj/src/interface.ts index ae6e19ff2..ca2a78b0a 100644 --- a/packages/hydrooj/src/interface.ts +++ b/packages/hydrooj/src/interface.ts @@ -70,23 +70,24 @@ export interface Udoc extends Dictionary { loginip: string, } -export interface User extends Dictionary { - udoc: () => Udoc, - dudoc: () => any, +export interface User extends Record { _id: number, + _udoc: Udoc, + _dudoc: any, + _salt: string, + _hash: string, + _regip: string, + _loginip: string, + mail: string, uname: string, - salt: () => string, - hash: () => string, hashType: string, priv: number, regat: Date, loginat: Date, - perm: () => bigint, - scope: () => bigint, + perm: bigint, + scope: bigint, role: string, - regip: () => string, - loginip: () => string, hasPerm: (...perm: bigint[]) => boolean, hasPriv: (...priv: number[]) => boolean, checkPassword: (password: string) => void, @@ -296,14 +297,14 @@ export interface TrainingDoc extends Tdoc { dag: TrainingNode[], } -export interface DomainDoc extends Dictionary { +export interface DomainDoc extends Record { _id: string, owner: number, roles: Dictionary, gravatar: string, bulletin: string, pidCounter: number, - join?: any, + _join?: any, host?: string, } diff --git a/packages/hydrooj/src/model/domain.ts b/packages/hydrooj/src/model/domain.ts index f246dd2df..139fdb2d0 100644 --- a/packages/hydrooj/src/model/domain.ts +++ b/packages/hydrooj/src/model/domain.ts @@ -218,7 +218,7 @@ class DomainModel { static getJoinSettings(ddoc: DomainDoc, roles: string[]) { if (!ddoc.join) return null; - const joinSettings = ddoc.join; + const joinSettings = ddoc._join; if (joinSettings.method === DomainModel.JOIN_METHOD_NONE) return null; if (!roles.includes(joinSettings.role)) return null; if (joinSettings.expire && joinSettings.expire < new Date()) return null; diff --git a/packages/hydrooj/src/model/user.ts b/packages/hydrooj/src/model/user.ts index 75373d6a0..214d2ce0d 100644 --- a/packages/hydrooj/src/model/user.ts +++ b/packages/hydrooj/src/model/user.ts @@ -18,40 +18,44 @@ const coll: Collection = db.collection('user'); const logger = new Logger('model/user'); class User implements _User { - udoc: () => any; - dudoc: () => any; _id: number; + + _udoc: Udoc; + _dudoc: any; + _salt: string; + _hash: string; + _regip: string; + _loginip: string; + mail: string; uname: string; - salt: () => string; - hash: () => string; hashType: string; priv: number; regat: Date; loginat: Date; - perm: () => bigint; + perm: bigint; role: string; - regip: () => string; - loginip: () => string; - scope: () => bigint; + scope: bigint; [key: string]: any; constructor(udoc: Udoc, dudoc, scope = PERM.PERM_ALL) { - this.udoc = () => udoc; - this.dudoc = () => dudoc; this._id = udoc._id; + + this._udoc = udoc; + this._dudoc = dudoc; + this._salt = udoc.salt; + this._hash = udoc.hash; + this._regip = udoc.regip; + this._loginip = udoc.loginip; + this.mail = udoc.mail; 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.regip = () => udoc.regip; this.loginat = udoc.loginat; - this.loginip = () => udoc.loginip; - this.perm = () => dudoc.perm; - this.scope = () => (typeof scope === 'string' ? BigInt(scope) : scope); + this.perm = dudoc.perm; + this.scope = typeof scope === 'string' ? BigInt(scope) : scope; this.role = dudoc.role || 'default'; for (const key in setting.SETTINGS_BY_KEY) { @@ -67,7 +71,7 @@ class User implements _User { hasPerm(...perm: bigint[]) { for (const i in perm) { - if ((this.perm() & this.scope() & perm[i]) === perm[i]) return true; + if ((this.perm & this.scope & perm[i]) === perm[i]) return true; } return false; } @@ -82,7 +86,7 @@ class User implements _User { checkPassword(password: string) { const h = global.Hydro.lib[`hash.${this.hashType}`]; if (!h) throw new Error('Unknown hash method'); - if (h(password, this.salt(), this) !== this.hash()) { + if (h(password, this._salt, this) !== this._hash) { throw new LoginError(this.uname); } else if (this.hashType !== 'hydro') { // eslint-disable-next-line @typescript-eslint/no-use-before-define diff --git a/packages/hydrooj/src/service/server.ts b/packages/hydrooj/src/service/server.ts index dd46f37cc..017d5438c 100644 --- a/packages/hydrooj/src/service/server.ts +++ b/packages/hydrooj/src/service/server.ts @@ -281,6 +281,12 @@ export const UiContextBase = { url_prefix: '/', }; +function serializer(k: string, v: any) { + if (k.startsWith('_') && k !== '_id') return undefined; + if (typeof k === 'bigint') return `BigInt::${v.toString()}`; + return v; +} + export class HandlerCommon { domainId: string; domain: DomainDoc; @@ -321,7 +327,7 @@ export class HandlerCommon { perm: this.user.perm.toString(), viewLang: this.translate('__id'), }; - if (!global.Hydro.lib.template) return JSON.stringify(context); + if (!global.Hydro.lib.template) return JSON.stringify(context, serializer); const res = await global.Hydro.lib.template.render(name, { handler: this, UserContext, diff --git a/packages/hydrooj/src/upgrade.ts b/packages/hydrooj/src/upgrade.ts index a49235f5f..916739841 100644 --- a/packages/hydrooj/src/upgrade.ts +++ b/packages/hydrooj/src/upgrade.ts @@ -4,6 +4,7 @@ import { FilterQuery, ObjectID } from 'mongodb'; import AdmZip from 'adm-zip'; import Queue from 'p-queue'; import yaml from 'js-yaml'; +import { pick } from 'lodash'; import { convertIniConfig } from '@hydrooj/utils/lib/cases'; import { Progress } from './ui'; import { Rdoc } from './interface'; @@ -289,6 +290,15 @@ const scripts: UpgradeScript[] = [ }); return true; }, + async function _21_22() { + const coll = db.collection('domain'); + await iterateAllDomain(async (ddoc) => { + if (ddoc.join) { + await coll.updateOne(pick(ddoc, '_id'), { $set: { _join: ddoc.join }, $unset: { join: '' } }); + } + }); + return true; + }, ]; export default scripts;