mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-20 01:38:19 +08:00
core: allow extra user private & public fields (#1059)
This commit is contained in:
1 parent
8f2c5a17cd
commit
3a25e4e53f
11 files changed
+61
-46
No files matched your search
@@ -1,4 +1,4 @@
|
||||
import { escapeRegExp, pick, uniq } from 'lodash';
|
||||
import { escapeRegExp, omit, pick, uniq } from 'lodash';
|
||||
import { LRUCache } from 'lru-cache';
|
||||
import { Collection, Filter, ObjectId } from 'mongodb';
|
||||
import { serializer } from '@hydrooj/framework';
|
||||
@@ -59,6 +59,8 @@ export class User {
|
||||
_loginip: string;
|
||||
_tfa: string;
|
||||
_authenticators: Authenticator[];
|
||||
_privateFields: string[] = [];
|
||||
_publicFields: string[] = [];
|
||||
|
||||
mail: string;
|
||||
uname: string;
|
||||
@@ -101,14 +103,15 @@ export class User {
|
||||
this.tfa = !!udoc.tfa;
|
||||
this.authn = (udoc.authenticators || []).length > 0;
|
||||
if (dudoc.group) this.group = dudoc.group;
|
||||
|
||||
for (const key in setting.SETTINGS_BY_KEY) {
|
||||
this[key] = udoc[key] ?? (setting.SETTINGS_BY_KEY[key].value || system.get(`preference.${key}`));
|
||||
}
|
||||
|
||||
for (const key in setting.DOMAIN_USER_SETTINGS_BY_KEY) {
|
||||
this[key] = dudoc[key] ?? (setting.DOMAIN_USER_SETTINGS_BY_KEY[key].value || system.get(`preference.${key}`));
|
||||
}
|
||||
const load = (settings: Record<string, ReturnType<typeof setting.Setting>>, source: any) => {
|
||||
for (const key in settings) {
|
||||
this[key] = source[key] ?? (settings[key].value || system.get(`preference.${key}`));
|
||||
if (settings[key].flag & setting.FLAG_PUBLIC) this._publicFields.push(key);
|
||||
if (settings[key].flag & setting.FLAG_PRIVATE) this._privateFields.push(key);
|
||||
}
|
||||
};
|
||||
load(setting.SETTINGS_BY_KEY, udoc);
|
||||
load(setting.DOMAIN_USER_SETTINGS_BY_KEY, dudoc);
|
||||
}
|
||||
|
||||
async init() {
|
||||
@@ -159,13 +162,14 @@ export class User {
|
||||
return user;
|
||||
}
|
||||
|
||||
getFields(type: 'public' | 'private' = 'public') {
|
||||
const fields = ['_id', 'uname', 'mail', 'perm', 'role', 'priv', 'regat', 'loginat', 'tfa', 'authn'].concat(this._publicFields);
|
||||
return type === 'public' ? fields : fields.concat(this._privateFields);
|
||||
}
|
||||
|
||||
serialize(h) {
|
||||
if (!this._isPrivate) {
|
||||
const fields = ['_id', 'uname', 'mail', 'perm', 'role', 'priv', 'regat', 'loginat', 'tfa', 'authn'];
|
||||
if (h?.user?.hasPerm(PERM.PERM_VIEW_DISPLAYNAME)) {
|
||||
fields.push('displayName', 'school', 'studentId');
|
||||
}
|
||||
return pick(this, fields);
|
||||
return pick(this, this.getFields(h?.user?.hasPerm(PERM.PERM_VIEW_USER_PRIVATE_INFO) ? 'private' : 'public'));
|
||||
}
|
||||
return JSON.stringify(this, serializer(true, h));
|
||||
}
|
||||
@@ -398,19 +402,26 @@ class UserModel {
|
||||
return projection ? coll.find(params).project<Udoc>(buildProjection(projection)) : coll.find(params);
|
||||
}
|
||||
|
||||
static async getListForRender(domainId: string, uids: number[], showPrivateInfo: boolean, extraFields?: string[]): Promise<BaseUserDict>;
|
||||
static async getListForRender(domainId: string, uids: number[], extraFields?: string[]): Promise<BaseUserDict>;
|
||||
static async getListForRender(domainId: string, uids: number[], arg: string[] | boolean) {
|
||||
const fields = ['_id', 'uname', 'mail', 'avatar', 'school', 'studentId'].concat(arg instanceof Array ? arg : []);
|
||||
const showDisplayName = arg instanceof Array ? fields.includes('displayName') : arg;
|
||||
static async getListForRender(domainId: string, uids: number[], arg: string[] | boolean, extraFields?: string[]) {
|
||||
const _extraFields = Array.isArray(arg) ? arg : Array.isArray(extraFields) ? extraFields : [];
|
||||
const showPrivateInfo = arg === true || _extraFields.includes('displayName');
|
||||
const fields = Array.from(new Set([
|
||||
...(await UserModel.getById('system', 0)).getFields(showPrivateInfo ? 'private' : 'public'),
|
||||
..._extraFields,
|
||||
]));
|
||||
const [udocs, vudocs, dudocs] = await Promise.all([
|
||||
UserModel.getMulti({ _id: { $in: uids } }, fields).toArray(),
|
||||
collV.find({ _id: { $in: uids } }).toArray(),
|
||||
domain.getDomainUserMulti(domainId, uids).project({ uid: 1, ...(showDisplayName ? { displayName: 1 } : {}) }).toArray(),
|
||||
domain.getDomainUserMulti(domainId, uids).project(buildProjection(fields.concat('uid'))).toArray(),
|
||||
]);
|
||||
const udict = {};
|
||||
for (const udoc of udocs) udict[udoc._id] = udoc;
|
||||
for (const udoc of vudocs) udict[udoc._id] = udoc;
|
||||
if (showDisplayName) for (const dudoc of dudocs) udict[dudoc.uid].displayName = dudoc.displayName;
|
||||
if (showPrivateInfo) {
|
||||
for (const dudoc of dudocs) Object.assign(udict[dudoc.uid], omit(dudoc, ['_id', 'uid']));
|
||||
}
|
||||
for (const uid of uids) udict[uid] ||= { ...UserModel.defaultUser };
|
||||
for (const key in udict) {
|
||||
udict[key].school ||= '';
|
||||
|
||||
Reference in new issue
Block a user