core: support ban user from domain

This commit is contained in:
undefined committed 2025-03-23 05:04:38 +08:00
1 parent ff1605797b
commit 7ed859be2d
8 files changed
+15 -6

No files matched your search

+3 -1
View File
@@ -787,6 +787,7 @@ The discussion is locked, you can not reply anymore.: 此讨论已经锁定,
The homework's deadline is due but in extension. You can still submit for this problem but your score will be penalized.: 作业已超过截止时间,但仍在延期时间内。您递交题目将无法获得全部分数。 The homework's deadline is due but in extension. You can still submit for this problem but your score will be penalized.: 作业已超过截止时间,但仍在延期时间内。您递交题目将无法获得全部分数。
The invitation code to enter to successfully join the domain. You can only use letters and numbers in the code and it should not be longer than 64 characters.: 加入此域的邀请码。您只能使用字母和数字,并且不能长于 64 个字符。 The invitation code to enter to successfully join the domain. You can only use letters and numbers in the code and it should not be longer than 64 characters.: 加入此域的邀请码。您只能使用字母和数字,并且不能长于 64 个字符。
The invitation code you provided is invalid.: 您提供的邀请码无效。 The invitation code you provided is invalid.: 您提供的邀请码无效。
The link is either invalid or expired.: 加域链接无效或已过期。
The link will be expired at {0}: 链接将于 {0} 过期 The link will be expired at {0}: 链接将于 {0} 过期
The role to assign when user joining the domain.: 用户加入此域时分配的角色。 The role to assign when user joining the domain.: 用户加入此域时分配的角色。
The uploaded file is too long.: 上传的文件太长。 The uploaded file is too long.: 上传的文件太长。
@@ -925,7 +926,8 @@ Write Your Comment: 发表您的评论
Write Your Solution: 发表您的题解 Write Your Solution: 发表您的题解
WYSIWYG: 所见即所得 WYSIWYG: 所见即所得
Year: 年 Year: 年
You are not allowed to join the domain. The link is either invalid or expired.: 您无法加入该域,链接无效或已过期。 You are banned by the domain moderator.: 您被该域的管理员封禁。
You are not allowed to join domain {0}. {1}: 您无法加入 {0}。{1}
You can create your own training plans and share them with others.: 您可以创建您自己的训练计划并且与他人分享。 You can create your own training plans and share them with others.: 您可以创建您自己的训练计划并且与他人分享。
You cannot submit for this problem because the contest is ended. You can click "Open in Problem Set" to view this problem in normal mode.: 该比赛已结束,您无法在比赛模式下递交该题目。您可以点击“在题库中打开”以普通模式查看和递交本题。 You cannot submit for this problem because the contest is ended. You can click "Open in Problem Set" to view this problem in normal mode.: 该比赛已结束,您无法在比赛模式下递交该题目。您可以点击“在题库中打开”以普通模式查看和递交本题。
You cannot submit for this problem because the homework's deadline is due.: 作业已超过截止时间,您无法递交本题目。 You cannot submit for this problem because the homework's deadline is due.: 作业已超过截止时间,您无法递交本题目。
+3
View File
@@ -463,6 +463,7 @@ Technical Information: 技術資訊
Temporary session: 臨時會話 Temporary session: 臨時會話
Text: 文字 Text: 文字
The homework's deadline is due but in extension. You can still submit for this problem but your score will be penalized.: 功課已經截止,但處於延期時間内。您此時遞交的題目無法獲得全部分數。 The homework's deadline is due but in extension. You can still submit for this problem but your score will be penalized.: 功課已經截止,但處於延期時間内。您此時遞交的題目無法獲得全部分數。
The link is either invalid or expired.: 加域鏈接無效或已過期。
There are no contests...: 沒有比賽… There are no contests...: 沒有比賽…
There is no homework so far ╰(*°▽°*)╯: 目前沒有功課 ╰(*°▽°*)╯ There is no homework so far ╰(*°▽°*)╯: 目前沒有功課 ╰(*°▽°*)╯
This contest is not live.: 比賽沒有開始。 This contest is not live.: 比賽沒有開始。
@@ -545,6 +546,8 @@ Will be used as the domain icon.: 將被用作圖示。
Without slashes or backslashes: 不含斜槓和反斜槓 Without slashes or backslashes: 不含斜槓和反斜槓
Write Your Comment: 發表您的評論 Write Your Comment: 發表您的評論
Write Your Solution: 發表您的題解 Write Your Solution: 發表您的題解
You are banned by the domain moderator.: 您被該域的管理員封禁。
You are not allowed to join domain {0}. {1}: 您無法加入 {0}。{1}
You can create your own training plans and share them with others.: 您可以創建您自己的訓練計劃並且與他人分享。 You can create your own training plans and share them with others.: 您可以創建您自己的訓練計劃並且與他人分享。
You cannot submit for this problem because the homework's deadline is due.: 功課已到達截止時間,您無法遞交了。 You cannot submit for this problem because the homework's deadline is due.: 功課已到達截止時間,您無法遞交了。
You don't have the required permission ({0}) in this domain.: 您在該域中無相應許可權 ({0})。 You don't have the required permission ({0}) in this domain.: 您在該域中無相應許可權 ({0})。
+1 -1
View File
@@ -42,7 +42,7 @@ export const HomeworkNotLiveError = Err('HomeworkNotLiveError', ForbiddenError,
export const HomeworkNotAttendedError = Err('HomeworkNotAttendedError', ForbiddenError, "You haven't claimed this homework yet."); export const HomeworkNotAttendedError = Err('HomeworkNotAttendedError', ForbiddenError, "You haven't claimed this homework yet.");
export const RoleAlreadyExistError = Err('RoleAlreadyExistError', ForbiddenError, 'This role already exists.'); export const RoleAlreadyExistError = Err('RoleAlreadyExistError', ForbiddenError, 'This role already exists.');
export const DomainAlreadyExistsError = Err('DomainAlreadyExistsError', ForbiddenError, 'The domain {0} already exists.'); export const DomainAlreadyExistsError = Err('DomainAlreadyExistsError', ForbiddenError, 'The domain {0} already exists.');
export const DomainJoinForbiddenError = Err('DomainJoinForbiddenError', ForbiddenError, 'You are not allowed to join the domain. The link is either invalid or expired.'); export const DomainJoinForbiddenError = Err('DomainJoinForbiddenError', ForbiddenError, 'You are not allowed to join domain {0}. {1}');
export const DomainJoinAlreadyMemberError = Err('DomainJoinAlreadyMemberError', ForbiddenError, 'Failed to join the domain. You are already a member.'); export const DomainJoinAlreadyMemberError = Err('DomainJoinAlreadyMemberError', ForbiddenError, 'Failed to join the domain. You are already a member.');
export const InvalidJoinInvitationCodeError = Err('InvalidJoinInvitationCodeError', ForbiddenError, 'The invitation code you provided is invalid.'); export const InvalidJoinInvitationCodeError = Err('InvalidJoinInvitationCodeError', ForbiddenError, 'The invitation code you provided is invalid.');
export const CurrentPasswordError = Err('CurrentPasswordError', ForbiddenError, "Current password doesn't match."); export const CurrentPasswordError = Err('CurrentPasswordError', ForbiddenError, "Current password doesn't match.");
+2 -1
View File
@@ -345,7 +345,8 @@ class DomainJoinHandler extends Handler {
const roles = r.map((role) => role._id); const roles = r.map((role) => role._id);
this.joinSettings = domain.getJoinSettings(ddoc, roles); this.joinSettings = domain.getJoinSettings(ddoc, roles);
if (assignedRole !== 'default') delete this.joinSettings; if (assignedRole !== 'default') delete this.joinSettings;
else if (!this.joinSettings) throw new DomainJoinForbiddenError(target); else if (!this.joinSettings) throw new DomainJoinForbiddenError(target, 'The link is either invalid or expired.');
if (assignedRole === 'guest') throw new DomainJoinForbiddenError(target, 'You are banned by the domain moderator.');
} }
@param('code', Types.Content, true) @param('code', Types.Content, true)
+2 -1
View File
@@ -7,7 +7,7 @@ import { Binary, ObjectId } from 'mongodb';
import { UAParser } from 'ua-parser-js'; import { UAParser } from 'ua-parser-js';
import { Context } from '../context'; import { Context } from '../context';
import { import {
AuthOperationError, BlacklistedError, DomainAlreadyExistsError, InvalidTokenError, AuthOperationError, BadRequestError, BlacklistedError, DomainAlreadyExistsError, InvalidTokenError,
NotFoundError, PermissionError, UserAlreadyExistError, NotFoundError, PermissionError, UserAlreadyExistError,
UserNotFoundError, ValidationError, VerifyPasswordError, UserNotFoundError, ValidationError, VerifyPasswordError,
} from '../error'; } from '../error';
@@ -507,6 +507,7 @@ class HomeDomainHandler extends Handler {
@param('id', Types.String) @param('id', Types.String)
async postLeave({ }, id: string) { async postLeave({ }, id: string) {
if (id === 'system') throw new BadRequestError();
const ddoc = await domain.get(id); const ddoc = await domain.get(id);
if (!ddoc) throw new NotFoundError(id); if (!ddoc) throw new NotFoundError(id);
await domain.setJoin(id, this.user._id, false); await domain.setJoin(id, this.user._id, false);
+1 -1
View File
@@ -201,7 +201,7 @@ export async function push(
{ $push: { [key]: v } }, { $push: { [key]: v } },
{ returnDocument: 'after' }, { returnDocument: 'after' },
); );
return [doc.value, _id]; return [doc, _id];
} }
export async function pull<K extends keyof DocType, T extends ArrayKeys<DocType[K]>>( export async function pull<K extends keyof DocType, T extends ArrayKeys<DocType[K]>>(
+1 -1
View File
@@ -707,7 +707,7 @@ export const coreScripts: MigrationScript[] = [
async function _91_92() { async function _91_92() {
await domain.collUser.updateMany({}, { $set: { join: true } }); await domain.collUser.updateMany({}, { $set: { join: true } });
await domain.coll.updateMany( await domain.coll.updateMany(
{ $or: [{ _join: { $exists: false } }, { _join: { $eq: null } }] }, { $or: [{ _join: { $exists: false } }, { _join: { $eq: null } }, { '_join.method': domain.JOIN_METHOD_NONE }] },
{ $set: { _join: { method: domain.JOIN_METHOD_ALL, role: 'default', expire: null }, _migratedJoin: true } }, { $set: { _join: { method: domain.JOIN_METHOD_ALL, role: 'default', expire: null }, _migratedJoin: true } },
); );
const domainUser = await domain.coll.find({ domainId: 'system', join: true }, onPrimary) const domainUser = await domain.coll.find({ domainId: 'system', join: true }, onPrimary)
@@ -44,11 +44,13 @@
{% if canManage[ddoc['_id']] %} {% if canManage[ddoc['_id']] %}
· <a class="typo-a" href="{{ url('domain_dashboard', domainId=ddoc['_id']) }}">{{ _('Manage') }}</a> · <a class="typo-a" href="{{ url('domain_dashboard', domainId=ddoc['_id']) }}">{{ _('Manage') }}</a>
{% endif %} {% endif %}
{% if ddoc['_id'] != 'system' and ddoc['owner'] != handler.user._id %}
· <form class="form--inline" method="post"> · <form class="form--inline" method="post">
<input type="hidden" name="operation" value="leave"> <input type="hidden" name="operation" value="leave">
<input type="hidden" name="id" value="{{ ddoc['_id'] }}"> <input type="hidden" name="id" value="{{ ddoc['_id'] }}">
<button class="typo-a" type="submit">{{ _('Leave') }}</button> <button class="typo-a" type="submit">{{ _('Leave') }}</button>
</form> </form>
{% endif %}
</td> </td>
</tr> </tr>
{%- endfor -%} {%- endfor -%}