From a93da2badb1e1b17e5cafef086bfdcc5bdbcb3f2 Mon Sep 17 00:00:00 2001 From: undefined Date: Mon, 13 Jul 2020 22:33:52 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96domain.user=E5=AD=98=E5=82=A8?= =?UTF-8?q?=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hydro/handler/domain.ts | 57 ++++--------- hydro/handler/home.ts | 46 ++++++++++- hydro/handler/judge.ts | 4 +- hydro/handler/problem.ts | 3 +- hydro/lib/i18n.ts | 2 +- hydro/model/builtin.ts | 8 +- hydro/model/document.ts | 11 ++- hydro/model/domain.ts | 142 +++++++++++++++++++++++++------- hydro/model/setting.ts | 35 +++++--- hydro/model/user.ts | 96 ++------------------- hydro/script/deleteUser.ts | 4 +- hydro/script/install.ts | 38 +-------- hydro/script/recalcRating.ts | 5 +- package.json | 2 +- templates/manage_dashboard.html | 2 +- templates/record_detail.html | 2 +- templates/record_main.html | 2 +- 17 files changed, 220 insertions(+), 239 deletions(-) diff --git a/hydro/handler/domain.ts b/hydro/handler/domain.ts index 8d5be6b8e..176fd3a20 100644 --- a/hydro/handler/domain.ts +++ b/hydro/handler/domain.ts @@ -1,20 +1,18 @@ -import { RoleAlreadyExistError, ValidationError, PermissionError } from '../error'; +import { RoleAlreadyExistError, ValidationError } from '../error'; import * as user from '../model/user'; import * as domain from '../model/domain'; -import * as system from '../model/system'; import { DOMAIN_SETTINGS, DOMAIN_SETTINGS_BY_KEY } from '../model/setting'; import { PERM, PERMS_BY_FAMILY } from '../model/builtin'; import paginate from '../lib/paginate'; import { Route, Handler, Types, param, } from '../service/server'; -import { isTitle, isUname } from '../lib/validator'; class DomainRankHandler extends Handler { @param('page', Types.UnsignedInt, true) async get(domainId: string, page = 1) { const [dudocs, upcount, ucount] = await paginate( - user.getMultiInDomain(domainId).sort({ rating: -1 }), + domain.getMultiInDomain(domainId).sort({ rating: -1 }), page, 100, ); @@ -34,31 +32,6 @@ class DomainRankHandler extends Handler { } } -class DomainCreateHandler extends Handler { - async prepare() { - if (this.user.priv !== 1) { - if (!await system.get('user.create_domain')) throw new PermissionError('domain_create'); - } - } - - async get() { - const path = [ - ['Hydro', 'homepage'], - ['domain_create', null], - ]; - this.response.body = { path }; - this.response.template = 'domain_create.html'; - } - - @param('id', Types.String, isUname) - @param('name', Types.String, isTitle) - async post(domainId: string, id: string, name: string) { - await domain.add(id, this.user._id, name); - this.response.body = { domainId: id }; - this.response.redirect = this.url('homepage', { domainId: id }); - } -} - class ManageHandler extends Handler { domain: any; @@ -105,13 +78,13 @@ class DomainUserHandler extends ManageHandler { async get({ domainId }) { const rudocs = {}; const [dudocs, roles] = await Promise.all([ - user.getMultiInDomain(domainId, { + domain.getMultiInDomain(domainId, { $and: [ { role: { $ne: 'default' } }, { role: { $ne: null } }, ], }).toArray(), - user.getRoles(domainId), + domain.getRoles(domainId), ]); const uids = dudocs.map((dudoc) => dudoc.uid); const udict = await user.getList(domainId, uids); @@ -133,14 +106,14 @@ class DomainUserHandler extends ManageHandler { } async postSetUser({ domainId, uid, role }) { - await user.setRole(domainId, uid, role); + await domain.setUserRole(domainId, uid, role); this.back(); } } class DomainPermissionHandler extends ManageHandler { async get({ domainId }) { - const roles = await user.getRoles(domainId); + const roles = await domain.getRoles(domainId); const path = [ ['Hydro', 'homepage'], ['domain', null], @@ -159,14 +132,14 @@ class DomainPermissionHandler extends ManageHandler { roles[role] = this.request.body[role].join(''); } } - await user.setRoles(domainId, roles); + await domain.setRoles(domainId, roles); this.back(); } } class DomainRoleHandler extends ManageHandler { async get({ domainId }) { - const roles = await user.getRoles(domainId); + const roles = await domain.getRoles(domainId); const path = [ ['Hydro', 'homepage'], ['domain', null], @@ -177,12 +150,11 @@ class DomainRoleHandler extends ManageHandler { } async postAdd({ domainId, role }) { - const [r, u] = await Promise.all([ - user.getRole(domainId, role), - user.getRole(domainId, 'default'), - ]); - if (r) throw new RoleAlreadyExistError(role); - await user.addRole(domainId, role, u.perm); + const roles = await domain.getRoles(this.domain); + const rdict: any = {}; + for (const r of roles) rdict[r._id] = r.perm; + if (rdict[role]) throw new RoleAlreadyExistError(role); + await domain.addRole(domainId, role, rdict.default.perm); this.back(); } @@ -192,14 +164,13 @@ class DomainRoleHandler extends ManageHandler { throw new ValidationError('role'); } } - await user.deleteRoles(domainId, roles); + await domain.deleteRoles(domainId, roles); this.back(); } } export async function apply() { Route('ranking', '/ranking', DomainRankHandler); - Route('domain_create', '/domain/create', DomainCreateHandler); Route('domain_dashboard', '/domain/dashboard', DomainDashboardHandler); Route('domain_edit', '/domain/edit', DomainEditHandler); Route('domain_user', '/domain/user', DomainUserHandler); diff --git a/hydro/handler/home.ts b/hydro/handler/home.ts index e60d389e9..160eba057 100644 --- a/hydro/handler/home.ts +++ b/hydro/handler/home.ts @@ -24,7 +24,9 @@ import * as discussion from '../model/discussion'; import * as token from '../model/token'; import * as training from '../model/training'; import { PERM, PRIV } from '../model/builtin'; -import { isContent, isPassword, isEmail } from '../lib/validator'; +import { + isContent, isPassword, isEmail, isTitle, +} from '../lib/validator'; const { geoip, useragent } = global.Hydro.lib; @@ -133,7 +135,7 @@ class HomeSecurityHandler extends Handler { ['home_security', null], ]; this.response.template = 'home_security.html'; - this.response.body = { sessions, geoipProvider: (geoip || {}).provider, path }; + this.response.body = { sessions, geoipProvider: geoip?.provider, path }; if (useragent) this.response.body.icon = useragent.icon; } @@ -210,7 +212,8 @@ class HomeSettingsHandler extends Handler { async post(args: any) { const $set = {}; for (const key in args) { - if (setting.SETTINGS_BY_KEY[key] && !setting.SETTINGS_BY_KEY[key].disabled) { + if (setting.SETTINGS_BY_KEY[key] + && !(setting.SETTINGS_BY_KEY[key].flag & setting.FLAG_DISABLED)) { $set[key] = args[key]; } } @@ -236,6 +239,41 @@ class UserChangemailWithCodeHandler extends Handler { } } +class HomeDomainHandler extends Handler { + async get() { + const dudict = await domain.getDictUserByDomainId(this.user._id); + const dids = Object.keys(dudict); + const ddocs = await domain.getMulti({ _id: { $in: dids } }).toArray(); + const canManage = {}; + for (const ddoc of ddocs) { + // eslint-disable-next-line no-await-in-loop + const udoc = await user.getById(ddoc._id, this.user._id); + canManage[ddoc._id] = udoc.hasPerm(PERM.PERM_EDIT_DOMAIN) + || udoc.hasPriv(PRIV.PRIV_MANAGE_ALL_DOMAIN); + } + this.response.template = 'home_domain.html'; + this.response.body = { ddocs, dudict, canManage }; + } +} + +class HomeDomainCreateHandler extends Handler { + async get() { + this.response.body = 'home_domain_create.html'; + } + + @param('id', Types.String) + @param('name', Types.String, isTitle) + @param('bulletin', Types.String, isContent) + @param('gravatar', Types.String, isEmail, true) + async post(_: string, id: string, name: string, bulletin: string, gravatar: string) { + gravatar = gravatar || this.user.gravatar || this.user.mail || 'guest@hydro.local'; + const domainId = await domain.add(id, this.user._id, name, bulletin); + await domain.edit(domainId, { gravatar }); + this.response.redirect = this.url('domain_manage', { domainId }); + this.response.body = { domainId }; + } +} + class HomeMessagesHandler extends Handler { async get() { // TODO(iceboy): projection, pagination. @@ -324,6 +362,8 @@ async function apply() { Route('home_security', '/home/security', HomeSecurityHandler, PRIV.PRIV_USER_PROFILE); Route('user_changemail_with_code', '/home/changeMail/:code', UserChangemailWithCodeHandler, PRIV.PRIV_USER_PROFILE); Route('home_settings', '/home/settings/:category', HomeSettingsHandler, PRIV.PRIV_USER_PROFILE); + Route('home_domain', '/home/domain', HomeDomainHandler, PRIV.PRIV_USER_PROFILE); + Route('home_domain_create', '/home/domain/create', HomeDomainCreateHandler, PRIV.PRIV_CREATE_DOMAIN); Route('home_messages', '/home/messages', HomeMessagesHandler, PRIV.PRIV_USER_PROFILE); Route('home_file', '/home/file', HomeFileHandler, PRIV.PRIV_USER_PROFILE); Connection('home_messages_conn', '/home/messages-conn', HomeMessagesConnectionHandler, PRIV.PRIV_USER_PROFILE); diff --git a/hydro/handler/judge.ts b/hydro/handler/judge.ts index cf012ec1f..e798eaf76 100644 --- a/hydro/handler/judge.ts +++ b/hydro/handler/judge.ts @@ -5,7 +5,7 @@ import * as record from '../model/record'; import * as problem from '../model/problem'; import * as builtin from '../model/builtin'; import * as contest from '../model/contest'; -import * as user from '../model/user'; +import * as domain from '../model/domain'; import * as task from '../model/task'; import * as bus from '../service/bus'; import { @@ -29,7 +29,7 @@ async function _postJudge(rdoc) { if (accept && !rdoc.rejudged) { tasks.push( problem.inc(rdoc.domainId, rdoc.pid, 'nAccept', 1), - user.incDomain(rdoc.domainId, rdoc.uid, 'nAccept', 1), + domain.incUserInDomain(rdoc.domainId, rdoc.uid, 'nAccept', 1), ); } } diff --git a/hydro/handler/problem.ts b/hydro/handler/problem.ts index 15c833ea4..cc3104ecd 100644 --- a/hydro/handler/problem.ts +++ b/hydro/handler/problem.ts @@ -7,6 +7,7 @@ import { import * as file from '../model/file'; import * as problem from '../model/problem'; import * as record from '../model/record'; +import * as domain from '../model/domain'; import * as user from '../model/user'; import * as solution from '../model/solution'; import * as system from '../model/system'; @@ -219,7 +220,7 @@ class ProblemSubmitHandler extends ProblemDetailHandler { const rid = await record.add(domainId, { uid: this.user._id, lang, code, pid: this.pdoc.docId, }, true); - await user.incDomain(domainId, this.user._id, 'nSubmit'); + await domain.incUserInDomain(domainId, this.user._id, 'nSubmit'); this.response.body = { rid }; this.response.redirect = this.url('record_detail', { rid }); } diff --git a/hydro/lib/i18n.ts b/hydro/lib/i18n.ts index f337d97fb..2c1fe0ef9 100644 --- a/hydro/lib/i18n.ts +++ b/hydro/lib/i18n.ts @@ -36,7 +36,7 @@ String.prototype.rawformat = function rawFormat(object) { }; String.prototype.translate = function translate(...languages: string[]) { - if (languages.length == 0) languages = ['zh_CN']; + if (languages.length === 0) languages = ['zh_CN']; for (const language of languages) { if (locales[language]) { if (locales[language][this] !== undefined) return locales[language][this]; diff --git a/hydro/model/builtin.ts b/hydro/model/builtin.ts index cbb2b73c0..74bddbdb8 100644 --- a/hydro/model/builtin.ts +++ b/hydro/model/builtin.ts @@ -85,7 +85,7 @@ export const PERM = { PERM_ADMIN: '', }; -export const Permission = (family, key, desc) => ({ family, key, desc }); +export const Permission = (family: string, key: string, desc: string) => ({ family, key, desc }); export const PERMS = [ Permission('perm_general', PERM.PERM_VIEW, 'View this domain'), @@ -298,9 +298,9 @@ export const BUILTIN_USERS = [ ]; export const BUILTIN_ROLES = { - guest: { perm: PERM.PERM_BASIC }, - default: { perm: PERM.PERM_DEFAULT }, - admin: { perm: PERM.PERM_ADMIN }, + guest: PERM.PERM_BASIC, + default: PERM.PERM_DEFAULT, + admin: PERM.PERM_ADMIN, }; export const DEFAULT_NODES = { diff --git a/hydro/model/document.ts b/hydro/model/document.ts index a2c50ef32..aaa49da21 100644 --- a/hydro/model/document.ts +++ b/hydro/model/document.ts @@ -7,7 +7,6 @@ type DocID = ObjectID | string | number; const coll = db.collection('document'); const collStatus = db.collection('document.status'); -export const TYPE_DOMAIN_USER = 0; export const TYPE_PROBLEM = 10; export const TYPE_PROBLEM_SOLUTION = 11; export const TYPE_PROBLEM_LIST = 12; @@ -52,14 +51,14 @@ export async function set(domainId: string, docType: number, docId: DocID, args: const res = await coll.findOneAndUpdate( { domainId, docType, docId }, { $set: args }, - { returnOriginal: false }, + { returnOriginal: false, upsert: true }, ); return res.value; } export function deleteOne(domainId: string, docType: number, docId: DocID) { return Promise.all([ - coll.deleteMany({ domainId, docType, docId }), + collStatus.deleteMany({ domainId, docType, docId }), coll.deleteOne({ domainId, docType, docId }), ]); } @@ -207,6 +206,10 @@ export function getMultiStatus(domainId: string, docType: number, args: any) { return collStatus.find({ ...args, docType, domainId }); } +export function getMultiStatusWithoutDomain(docType: number, args: any) { + return collStatus.find({ ...args, docType }); +} + export async function setStatus( domainId: string, docType: number, docId: DocID, uid: number, args: any, ) { @@ -388,6 +391,7 @@ global.Hydro.model.document = { get, getMulti, getMultiStatus, + getMultiStatusWithoutDomain, getStatus, getSub, inc, @@ -404,7 +408,6 @@ global.Hydro.model.document = { setMultiStatus, setSub, - TYPE_DOMAIN_USER, TYPE_CONTEST, TYPE_DISCUSSION, TYPE_DISCUSSION_NODE, diff --git a/hydro/model/domain.ts b/hydro/model/domain.ts index 17c9b7b09..1ec7f2b49 100644 --- a/hydro/model/domain.ts +++ b/hydro/model/domain.ts @@ -1,39 +1,18 @@ -import * as builtin from './builtin'; -import * as document from './document'; +import { BUILTIN_ROLES, PRIV } from './builtin'; +import { Udoc } from '../interface'; import * as db from '../service/db'; -import * as validator from '../lib/validator'; const coll = db.collection('domain'); +const collUser = db.collection('domain.user'); -export function add(domainId: string, owner: number, name: string, isEnsure = false) { - const tasks = []; - if (isEnsure) { - tasks.push( - coll.updateOne( - { _id: domainId }, - { $set: { owner }, $setOnInsert: { name, bulletin: '' } }, - { upsert: true }, - ), - ); - } else { - tasks.push( - coll.insertOne({ - _id: domainId, owner, name, bulletin: '', - }), - ); - } - for (const id in builtin.BUILTIN_ROLES) { - tasks.push( - document.add( - domainId, builtin.BUILTIN_ROLES[id].perm, owner, - document.TYPE_DOMAIN_USER, id, - ), - ); - } - return Promise.all(tasks); +export async function add(domainId: string, owner: number, name: string, bulletin: string) { + await coll.insertOne({ + _id: domainId, owner, name, bulletin, roles: BUILTIN_ROLES, + }); + return domainId; } -export async function get(domainId: string) { +export function get(domainId: string) { return coll.findOne({ _id: domainId }); } @@ -47,8 +26,6 @@ export function getMulti(query: any = {}) { } export function edit(domainId: string, $set: any) { - if ($set.title) validator.checkTitle($set.title); - if ($set.content) validator.checkContent($set.content); return coll.updateOne({ _id: domainId }, { $set }); } @@ -68,7 +45,98 @@ export async function getList(domainIds: string[]) { return r; } +export function setUserRole(domainId: string, uid: number, role: string) { + return collUser.updateOne({ uid, domainId }, { role }, { upsert: true }); +} + +export async function getRoles(arg: string | any) { + let ddoc; + if (typeof arg === 'string') ddoc = get(arg); + else ddoc = arg; + const roles = []; + const r = []; + for (const role in ddoc.roles) { + roles.push({ _id: role, perm: ddoc.roles[role] }); + r.push(role); + } + for (const role in BUILTIN_ROLES) { + if (!r.includes(role)) { + roles.push({ _id: role, perm: BUILTIN_ROLES[role] }); + } + } + return roles; +} + +export async function setRoles(domainId: string, roles: any) { + const current = await get(domainId); + for (const role in roles) { + current.roles[role] = roles[role]; + } + return await coll.updateOne({ _id: domainId }, { $set: { roles: current } }); +} + +export async function addRole(domainId: string, name: string, permission: string) { + const current = await get(domainId); + current.roles[name] = permission; + return await coll.updateOne({ _id: domainId }, { $set: { roles: current } }); +} + +export async function deleteRoles(domainId: string, roles: string[]) { + const current = await get(domainId); + for (const role of roles) delete current.roles[role]; + await Promise.all([ + coll.updateOne({ _id: domainId }, { $set: current }), + collUser.updateMany({ domainId, role: { $in: roles } }, { $set: { role: 'default' } }), + ]); +} + +export async function getDomainUser(domainId: string, udoc: Udoc) { + let dudoc = await collUser.findOne({ domainId, uid: udoc._id }); + dudoc = dudoc || {}; + if (udoc._id === 1) dudoc.role = 'guest'; + if (udoc.priv & PRIV.PRIV_MANAGE_ALL_DOMAIN) dudoc.role = 'admin'; + dudoc.role = dudoc.role || 'default'; + const ddoc = await get(domainId); + dudoc.perm = ddoc.roles[dudoc.role] || BUILTIN_ROLES[dudoc.role]; + return dudoc; +} + +export function setMultiUserInDomain(domainId: string, query: any, params: any) { + return collUser.updateMany({ domainId, ...query }, { $set: params }); +} + +export function getMultiInDomain(domainId: string, query: any = {}) { + return collUser.find({ domainId, ...query }); +} + +export function setUserInDomain(domainId: string, uid: number, params: any) { + return collUser.updateOne({ domainId, uid }, { $set: params }); +} + +export async function incUserInDomain(domainId: string, uid: number, field: string, n = 1) { + // @ts-ignore + const dudoc = await getDomainUser(domainId, { _id: uid }); + dudoc[field] = dudoc[field] + n || n; + await setUserInDomain(domainId, uid, { [field]: dudoc[field] }); + return dudoc; +} + +export async function getDictUserByDomainId(uid: number) { + const dudocs = await collUser.find({ uid }).toArray(); + const ddocs = await coll.find({ owner: uid }).toArray(); + const dudict = {}; + for (const dudoc of dudocs) { + // eslint-disable-next-line no-await-in-loop + dudict[dudoc.domainId] = await get(dudoc.domainId); + } + for (const ddoc of ddocs) { + dudict[ddoc._id] = ddoc; + } + return dudict; +} + global.Hydro.model.domain = { + getRoles, add, inc, get, @@ -76,4 +144,14 @@ global.Hydro.model.domain = { edit, getMulti, getList, + setRoles, + addRole, + deleteRoles, + setUserRole, + getDomainUser, + setMultiUserInDomain, + setUserInDomain, + incUserInDomain, + getMultiInDomain, + getDictUserByDomainId, }; diff --git a/hydro/model/setting.ts b/hydro/model/setting.ts index 1bddc0480..1658bea2a 100644 --- a/hydro/model/setting.ts +++ b/hydro/model/setting.ts @@ -1,7 +1,9 @@ /* eslint-disable no-await-in-loop */ import moment from 'moment-timezone'; import * as builtin from './builtin'; -import { Setting as _Setting } from '../interface'; +import { Setting as _Setting, Dict } from '../interface'; + +type SettingDict = Dict<_Setting>; const countries = moment.tz.countries(); const tzs: Set = new Set(); @@ -10,6 +12,11 @@ for (const country of countries) { for (const t of tz) tzs.add(t); } const timezones = Array.from(tzs).sort().map((tz) => [tz, tz]); +const langRange: Dict = {}; + +for (const lang in global.Hydro.locales) { + langRange[lang] = global.Hydro.locales[lang].__langname; +} export const FLAG_HIDDEN = 1; export const FLAG_DISABLED = 2; @@ -21,13 +28,13 @@ export const DOMAIN_SETTINGS: _Setting[] = []; export const DOMAIN_USER_SETTINGS: _Setting[] = []; export const SYSTEM_SETTINGS: _Setting[] = []; export const SETTINGS: _Setting[] = []; -export const SETTINGS_BY_KEY = {}; -export const DOMAIN_USER_SETTINGS_BY_KEY = {}; -export const DOMAIN_SETTINGS_BY_KEY = {}; -export const SYSTEM_SETTINGS_BY_KEY = {}; +export const SETTINGS_BY_KEY: SettingDict = {}; +export const DOMAIN_USER_SETTINGS_BY_KEY: SettingDict = {}; +export const DOMAIN_SETTINGS_BY_KEY: SettingDict = {}; +export const SYSTEM_SETTINGS_BY_KEY: SettingDict = {}; export const Setting = ( - family: string, key: string, range: Array<[string, string]> | { [key: string]: string } = null, + family: string, key: string, range: Array<[string, string]> | Dict = null, value: any = null, type = 'text', name = '', desc = '', flag = 0, ): _Setting => ({ @@ -68,8 +75,7 @@ export const SystemSetting = (...settings: _Setting[]) => { }; PreferenceSetting( - // TODO generate by global.Hydro.locales - Setting('setting_display', 'viewLang', builtin.VIEW_LANGS.map((i) => [i.code, i.name]), + Setting('setting_display', 'viewLang', langRange, 'zh_CN', 'select', 'UI Language'), Setting('setting_display', 'timeZone', timezones as [string, string][], 'Asia/Shanghai', 'select', 'Timezone'), @@ -99,10 +105,10 @@ DomainSetting( Setting('setting_domain', 'name', null, 'New domain', 'text', 'name'), Setting('setting_domain', 'gravatar', null, '', 'text', 'gravatar', 'Will be used as the domain icon.'), Setting('setting_domain', 'bulletin', null, '', 'markdown', 'Bulletin'), - Setting('storage', 'nAccept', null, 0, 'number', 'nAccept', null, FLAG_HIDDEN & FLAG_DISABLED), - Setting('storage', 'nSubmit', null, 0, 'number', 'nSubmit', null, FLAG_HIDDEN & FLAG_DISABLED), - Setting('storage', 'nLike', null, 0, 'number', 'nLike', null, FLAG_HIDDEN & FLAG_DISABLED), - Setting('storage', 'rating', null, 1500, 'number', 'rating', null, FLAG_HIDDEN & FLAG_DISABLED), + Setting('storage', 'nAccept', null, 0, 'number', 'nAccept', null, FLAG_HIDDEN | FLAG_DISABLED), + Setting('storage', 'nSubmit', null, 0, 'number', 'nSubmit', null, FLAG_HIDDEN | FLAG_DISABLED), + Setting('storage', 'nLike', null, 0, 'number', 'nLike', null, FLAG_HIDDEN | FLAG_DISABLED), + Setting('storage', 'rating', null, 1500, 'number', 'rating', null, FLAG_HIDDEN | FLAG_DISABLED), ); SystemSetting( @@ -112,6 +118,7 @@ SystemSetting( Setting('setting_smtp', 'smtp.port', null, 465, 'number', 'SMTP Server Port'), Setting('setting_smtp', 'smtp.from', null, null, 'text', 'Mail From'), Setting('setting_smtp', 'smtp.secure', null, false, 'boolean', 'SSL'), + Setting('setting_db', 'db.ver', null, 1, 'number', 'Database version', null, FLAG_DISABLED | FLAG_HIDDEN), Setting('setting_server', 'server.worker', null, 1, 'number', 'Server Workers Number'), Setting('setting_server', 'server.hostname', null, null, 'text', 'Server Hostname'), Setting('setting_server', 'server.host', null, null, 'text', 'Server Host'), @@ -119,6 +126,10 @@ SystemSetting( Setting('setting_server', 'server.port', null, 8888, 'number', 'Server Port'), Setting('setting_server', 'server.xff', null, null, 'text', 'IP Header'), Setting('setting_server', 'server.log', null, false, 'boolean', 'Disable Access Log'), + Setting('setting_session', 'session.keys', null, [String.random(32)], 'text', 'session.keys', null, FLAG_DISABLED | FLAG_HIDDEN), + Setting('setting_session', 'session.secure', null, false, 'boolean', 'session.secure'), + Setting('setting_session', 'session.saved_expire_seconds', null, 3600 * 24 * 30, 'number', 'Saved session expire seconds'), + Setting('setting_session', 'session.unsaved_expire_seconds', null, 3600 * 3, 'number', 'Unsaved session expire seconds'), Setting('setting_ui', 'ui.header_logo', null, '/components/header/header-logo.png', 'text', 'Header Logo'), Setting('setting_ui', 'ui.header_logo_2x', null, '/components/header/header-logo@2x.png', 'text', 'Header Logo@2x'), Setting('setting_ui', 'ui.header_background', null, '/components/header/header-background.png', 'text', 'Header Background'), diff --git a/hydro/model/user.ts b/hydro/model/user.ts index 1eac70c8e..64a2feaab 100644 --- a/hydro/model/user.ts +++ b/hydro/model/user.ts @@ -1,8 +1,8 @@ -import * as document from './document'; import * as system from './system'; import * as token from './token'; import * as setting from './setting'; -import { BUILTIN_ROLES, BUILTIN_USERS, PRIV } from './builtin'; +import * as domain from './domain'; +import { BUILTIN_USERS, PRIV } from './builtin'; import { UserNotFoundError, UserAlreadyExistError, LoginError } from '../error'; import pwhash from '../lib/hash.hydro'; import * as db from '../service/db'; @@ -100,22 +100,12 @@ export class User implements Udoc { } } -export async function getInDomain(domainId: string, udoc: User) { - let dudoc = await document.getStatus(domainId, document.TYPE_DOMAIN_USER, 0, udoc._id); - dudoc = dudoc || {}; - if (udoc._id === 1) dudoc.role = 'guest'; - if (udoc.priv & PRIV.PRIV_MANAGE_ALL_DOMAIN) dudoc.role = 'admin'; - const p = await document.get(domainId, document.TYPE_DOMAIN_USER, dudoc.role || 'default'); - dudoc.perm = p ? p.content : BUILTIN_ROLES[dudoc.role || 'default'].perm; - return dudoc; -} - export async function getById(domainId: string, _id: number): Promise { const udoc = _id === 0 || _id === 1 ? BUILTIN_USERS[_id] : await coll.findOne({ _id }); if (!udoc) return null; - const dudoc = await getInDomain(domainId, udoc); + const dudoc = await domain.getDomainUser(domainId, udoc); return new User(udoc, dudoc); } @@ -140,7 +130,7 @@ export async function getByUname( if (ignoreMissing) return null; throw new UserNotFoundError(uname); } - const dudoc = await getInDomain(domainId, udoc); + const dudoc = await domain.getDomainUser(domainId, udoc); return new User(udoc, dudoc); } @@ -152,7 +142,7 @@ export async function getByEmail(domainId: string, mail: string): Promise { - if (!value) return system.set(key, def[key]); - return Promise.resolve(); - })); - } - await Promise.all(tasks); - await domain.add('system', 0, 'Hydro', true); + await domain.add('system', 0, 'Hydro', 'Hydro System'); if (username && password) { const udoc = await user.getById('system', -1); if (!udoc) { diff --git a/hydro/script/recalcRating.ts b/hydro/script/recalcRating.ts index 42b38cae3..dc0926ce0 100644 --- a/hydro/script/recalcRating.ts +++ b/hydro/script/recalcRating.ts @@ -1,7 +1,6 @@ /* eslint-disable no-await-in-loop */ import * as domain from '../model/domain'; import * as contest from '../model/contest'; -import * as user from '../model/user'; import rating from '../lib/rating'; import { STATUS } from '../model/builtin'; @@ -27,7 +26,7 @@ export async function run({ domainId, isSub = false }, report) { } return true; } - await user.setMultiInDomain(domainId, {}, { rating: 1500 }); + await domain.setMultiUserInDomain(domainId, {}, { rating: 1500 }); const contests = await contest.getMulti(domainId, { rated: true }).sort('endAt', -1).toArray(); await report({ message: `Found ${contests.length} contests in ${domainId}` }); const udict = {}; @@ -60,7 +59,7 @@ export async function run({ domainId, isSub = false }, report) { } const tasks = []; for (const uid in udict) { - tasks.push(user.setInDomain(domainId, parseInt(uid, 10), { rating: udict[uid] })); + tasks.push(domain.setUserInDomain(domainId, parseInt(uid, 10), { rating: udict[uid] })); } await Promise.all(tasks); return true; diff --git a/package.json b/package.json index 11eba3722..843369af0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "hydrooj", - "version": "2.7.4", + "version": "2.7.5", "main": "hydro/loader.ts", "repository": "https://github.com/hydro-dev/Hydro.git", "author": "masnn", diff --git a/templates/manage_dashboard.html b/templates/manage_dashboard.html index 136145618..de12869ca 100644 --- a/templates/manage_dashboard.html +++ b/templates/manage_dashboard.html @@ -3,7 +3,7 @@ {% block manage_content %}
diff --git a/templates/record_detail.html b/templates/record_detail.html index 76a35416f..8b19a9ba4 100644 --- a/templates/record_detail.html +++ b/templates/record_detail.html @@ -3,7 +3,7 @@ {% block content %}
diff --git a/templates/record_main.html b/templates/record_main.html index 27135eb1d..69e8f971b 100644 --- a/templates/record_main.html +++ b/templates/record_main.html @@ -2,7 +2,7 @@ {% block content %}