diff --git a/packages/hydrooj/src/handler/domain.ts b/packages/hydrooj/src/handler/domain.ts index 786854976..398349c48 100644 --- a/packages/hydrooj/src/handler/domain.ts +++ b/packages/hydrooj/src/handler/domain.ts @@ -282,13 +282,16 @@ class DomainJoinHandler extends Handler { async prepare({ domainId }, target: string = domainId) { const [ddoc, dudoc] = await Promise.all([ domain.get(target), - domain.getDomainUser(target, this.user), + domain.collUser.findOne({ domainId, uid: this.user._id }), ]); - if (dudoc.join) throw new DomainJoinAlreadyMemberError(target, this.user._id); + const assignedRole = this.user.hasPriv(PRIV.PRIV_MANAGE_ALL_DOMAIN) + ? 'root' + : dudoc?.role; + if (dudoc?.join) throw new DomainJoinAlreadyMemberError(target, this.user._id); const r = await domain.getRoles(ddoc); const roles = r.map((role) => role._id); this.joinSettings = domain.getJoinSettings(ddoc, roles); - if (dudoc.role !== 'default') delete this.joinSettings; + if (assignedRole !== 'default') delete this.joinSettings; else if (!this.joinSettings) throw new DomainJoinForbiddenError(target); } diff --git a/packages/hydrooj/src/model/domain.ts b/packages/hydrooj/src/model/domain.ts index be74c8d85..10cefde02 100644 --- a/packages/hydrooj/src/model/domain.ts +++ b/packages/hydrooj/src/model/domain.ts @@ -128,8 +128,8 @@ class DomainModel { } static async countUser(domainId: string, role?: string) { - if (role) return await collUser.countDocuments({ domainId, role }); - return await collUser.countDocuments({ domainId }); + if (role) return await collUser.countDocuments({ domainId, role, join: true }); + return await collUser.countDocuments({ domainId, join: true }); } @ArgMethod @@ -166,10 +166,8 @@ class DomainModel { } } if (count) { - await Promise.all(roles.map(async (role) => { - if (['default', 'guest'].includes(role._id)) return role; + await Promise.all(roles.filter((i) => i._id !== 'guest').map(async (role) => { role.count = await DomainModel.countUser(ddoc._id, role._id); - return role; })); } return roles; @@ -207,7 +205,7 @@ class DomainModel { let dudoc = await collUser.findOne({ domainId, uid: udoc._id }); dudoc ||= { domainId, uid: udoc._id }; if (!(udoc.priv & PRIV.PRIV_USER_PROFILE)) dudoc.role = 'guest'; - if (!dudoc.join) dudoc.role = 'guest'; + if (!dudoc.join && !(udoc.priv & PRIV.PRIV_VIEW_ALL_DOMAIN)) dudoc.role = 'guest'; if (udoc.priv & PRIV.PRIV_MANAGE_ALL_DOMAIN) dudoc.role = 'root'; dudoc.role ||= 'default'; const ddoc = await DomainModel.get(domainId);