mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-20 01:38:19 +08:00
core: user: private and public projection (#507)
This commit is contained in:
1 parent
4fe734a6f3
commit
bd13c57d82
6 files changed
+44
-26
No files matched your search
@@ -0,0 +1,16 @@
|
||||
interface SerializeOptions {
|
||||
showDisplayName: boolean;
|
||||
currentSerializer?: (k: string, v: any) => any;
|
||||
}
|
||||
|
||||
export default function serializer(options: SerializeOptions, ignoreSerializeFunction = false) {
|
||||
options.currentSerializer = (k: string, v: any) => {
|
||||
if (typeof k.startsWith !== 'function') console.log(k, v);
|
||||
if (k.startsWith('_') && k !== '_id') return undefined;
|
||||
if (typeof v === 'bigint') return `BigInt::${v.toString()}`;
|
||||
if (!ignoreSerializeFunction && v && typeof v === 'object'
|
||||
&& 'serialize' in v && typeof v.serialize === 'function') return v.serialize(options);
|
||||
return v;
|
||||
};
|
||||
return options.currentSerializer;
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
ownerInfo, Udict, Udoc, VUdoc,
|
||||
} from '../interface';
|
||||
import pwhash from '../lib/hash.hydro';
|
||||
import serializer from '../lib/serializer';
|
||||
import * as bus from '../service/bus';
|
||||
import db from '../service/db';
|
||||
import { Value } from '../typeutils';
|
||||
@@ -47,6 +48,7 @@ bus.on('user/delcache', (content) => deleteUserCache(typeof content === 'string'
|
||||
|
||||
export class User {
|
||||
_id: number;
|
||||
_isPrivate = false;
|
||||
|
||||
_udoc: Udoc;
|
||||
_dudoc: any;
|
||||
@@ -149,6 +151,21 @@ export class User {
|
||||
UserModel.setPassword(this._id, password);
|
||||
}
|
||||
}
|
||||
|
||||
async private() {
|
||||
const user = await new User(this._udoc, this._dudoc, this.scope).init();
|
||||
user._isPrivate = true;
|
||||
return user;
|
||||
}
|
||||
|
||||
serialize(options) {
|
||||
if (!this._isPrivate) {
|
||||
const fields = ['_id', 'uname', 'mail', 'perm', 'role', 'priv', 'regat', 'loginat', 'tfa', 'authn'];
|
||||
if (options.showDisplayName) fields.push('displayName');
|
||||
return pick(this, fields);
|
||||
}
|
||||
return JSON.stringify(this, serializer({ showDisplayName: options.showDisplayName }, true));
|
||||
}
|
||||
}
|
||||
|
||||
function handleMailLower(mail: string) {
|
||||
|
||||
@@ -1,17 +1,10 @@
|
||||
import { ObjectID } from 'mongodb';
|
||||
import avatar from '../../lib/avatar';
|
||||
import serializer from '../../lib/serializer';
|
||||
import { PERM } from '../../model/builtin';
|
||||
import * as system from '../../model/system';
|
||||
import { User } from '../../model/user';
|
||||
import type { KoaContext } from '../server';
|
||||
|
||||
const serializer = (showDisplayName = false) => (k: string, v: any) => {
|
||||
if (k.startsWith('_') && k !== '_id') return undefined;
|
||||
if (typeof v === 'bigint') return `BigInt::${v.toString()}`;
|
||||
if (v instanceof User && !showDisplayName) delete v.displayName;
|
||||
return v;
|
||||
};
|
||||
|
||||
export default (router, logger) => async (ctx: KoaContext, next) => {
|
||||
const { request, response } = ctx.HydroContext;
|
||||
ctx.renderHTML = (templateName, args) => {
|
||||
@@ -22,7 +15,9 @@ export default (router, logger) => async (ctx: KoaContext, next) => {
|
||||
viewLang: ctx.translate('__id'),
|
||||
};
|
||||
const engine = global.Hydro.lib.template?.render
|
||||
|| (() => JSON.stringify(args, serializer(user?.hasPerm(PERM.PREM_VIEW_DISPLAYNAME))));
|
||||
|| (() => JSON.stringify(args, serializer({
|
||||
showDisplayName: user?.hasPerm(PERM.PREM_VIEW_DISPLAYNAME),
|
||||
})));
|
||||
return engine(templateName, {
|
||||
handler: ctx.handler,
|
||||
UserContext,
|
||||
|
||||
@@ -1,16 +1,9 @@
|
||||
import { errorMessage } from '@hydrooj/utils/lib/utils';
|
||||
import { SystemError, UserFacingError } from '../../error';
|
||||
import serializer from '../../lib/serializer';
|
||||
import { PERM } from '../../model/builtin';
|
||||
import { User } from '../../model/user';
|
||||
import type { KoaContext } from '../server';
|
||||
|
||||
const serializer = (showDisplayName = false) => (k: string, v: any) => {
|
||||
if (k.startsWith('_') && k !== '_id') return undefined;
|
||||
if (typeof v === 'bigint') return `BigInt::${v.toString()}`;
|
||||
if (v instanceof User && !showDisplayName) delete v.displayName;
|
||||
return v;
|
||||
};
|
||||
|
||||
export default (logger) => async (ctx: KoaContext, next) => {
|
||||
const { request, response } = ctx.HydroContext;
|
||||
try {
|
||||
@@ -34,7 +27,7 @@ export default (logger) => async (ctx: KoaContext, next) => {
|
||||
response.body.UiContext = UiContext;
|
||||
response.body.UserContext = user;
|
||||
}
|
||||
response.body = JSON.stringify(response.body, serializer(user?.hasPerm(PERM.PREM_VIEW_DISPLAYNAME)));
|
||||
response.body = JSON.stringify(response.body, serializer({ showDisplayName: user?.hasPerm(PERM.PREM_VIEW_DISPLAYNAME) }));
|
||||
} catch (e) {
|
||||
response.body = new SystemError('Serialize failure', e.message);
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ export default async (ctx: KoaContext, next) => {
|
||||
}
|
||||
if (user._id === 0) delete user.viewLang;
|
||||
user.avatarUrl = avatar(user.avatar, 128);
|
||||
ctx.HydroContext.user = user;
|
||||
ctx.HydroContext.user = await user.private();
|
||||
if (!domain) {
|
||||
ctx.pendingError = new NotFoundError(args.domainId);
|
||||
args.domainId = 'system';
|
||||
|
||||
@@ -17,6 +17,7 @@ import {
|
||||
PrivilegeError, UserFacingError,
|
||||
} from '../error';
|
||||
import { DomainDoc } from '../interface';
|
||||
import serializer from '../lib/serializer';
|
||||
import { Types } from '../lib/validator';
|
||||
import { Logger } from '../logger';
|
||||
import { PERM, PRIV } from '../model/builtin';
|
||||
@@ -109,12 +110,6 @@ wsServer.on('error', (error) => {
|
||||
});
|
||||
|
||||
const ignoredLimit = `,${argv.options.ignoredLimit},`;
|
||||
const serializer = (showDisplayName = false) => (k: string, v: any) => {
|
||||
if (k.startsWith('_') && k !== '_id') return undefined;
|
||||
if (typeof v === 'bigint') return `BigInt::${v.toString()}`;
|
||||
if (v instanceof User && !showDisplayName) delete v.displayName;
|
||||
return v;
|
||||
};
|
||||
|
||||
export class HandlerCommon {
|
||||
render: (name: string, args?: any) => Promise<void>;
|
||||
@@ -341,7 +336,9 @@ export class ConnectionHandler extends HandlerCommon {
|
||||
conn: WebSocket;
|
||||
|
||||
send(data: any) {
|
||||
this.conn.send(JSON.stringify(data, serializer(this.user?.hasPerm(PERM.PREM_VIEW_DISPLAYNAME))));
|
||||
this.conn.send(JSON.stringify(data, serializer({
|
||||
showDisplayName: this.user?.hasPerm(PERM.PREM_VIEW_DISPLAYNAME),
|
||||
})));
|
||||
}
|
||||
|
||||
close(code: number, reason: string) {
|
||||
|
||||
Reference in new issue
Block a user