diff --git a/packages/hydrooj/src/handler/discussion.ts b/packages/hydrooj/src/handler/discussion.ts index 32658249f..ebaba2b9a 100644 --- a/packages/hydrooj/src/handler/discussion.ts +++ b/packages/hydrooj/src/handler/discussion.ts @@ -56,7 +56,9 @@ class DiscussionHandler extends Handler { // TODO(twd2): exclude problem/contest discussions? // TODO(iceboy): continuation based pagination. this.vnode = await discussion.getVnode(domainId, typeMapper[type], name, this.user._id); - if (!discussion.checkVNodeVisibility(typeMapper[type], this.vnode, this.user)) throw new DiscussionNodeNotFoundError(this.vnode.id); + if (!discussion.checkVNodeVisibility(typeMapper[type], this.vnode, this.user)) { + throw new DiscussionNodeNotFoundError(domainId, this.vnode.id); + } if (this.ddoc) { this.ddoc.parentType ||= this.vnode.type; this.ddoc.parentId ||= this.vnode.id; @@ -422,7 +424,7 @@ class DiscussionEditHandler extends DiscussionHandler { } export async function apply(ctx) { - ctx.Route('discussion_main', '/discuss', DiscussionMainHandler); + ctx.Route('discussion_main', '/discuss', DiscussionMainHandler, PERM.PERM_VIEW_DISCUSSION); ctx.Route('discussion_detail', '/discuss/:did', DiscussionDetailHandler); ctx.Route('discussion_edit', '/discuss/:did/edit', DiscussionEditHandler); ctx.Route('discussion_raw', '/discuss/:did/raw', DiscussionRawHandler); diff --git a/packages/hydrooj/src/model/discussion.ts b/packages/hydrooj/src/model/discussion.ts index df201cea5..8e2221f06 100644 --- a/packages/hydrooj/src/model/discussion.ts +++ b/packages/hydrooj/src/model/discussion.ts @@ -276,15 +276,16 @@ export function flushNodes(domainId: string) { export async function getVnode(domainId: string, type: number, id: string, uid?: number) { if (type === document.TYPE_PROBLEM) { const pdoc = await problem.get(domainId, Number.isSafeInteger(+id) ? +id : id, problem.PROJECTION_LIST); - if (!pdoc) throw new DiscussionNodeNotFoundError(`problem/${id}`); + if (!pdoc) throw new DiscussionNodeNotFoundError(domainId, `problem/${id}`); return { ...pdoc, type, id: pdoc.docId }; } if ([document.TYPE_CONTEST, document.TYPE_TRAINING].includes(type as any)) { const model = type === document.TYPE_TRAINING ? training : contest; - if (!ObjectId.isValid(id)) throw new DiscussionNodeNotFoundError(`contest/${id}`); + const typeName = type === document.TYPE_TRAINING ? 'training' : 'contest'; + if (!ObjectId.isValid(id)) throw new DiscussionNodeNotFoundError(domainId, `${typeName}/${id}`); const _id = new ObjectId(id); const tdoc = await model.get(domainId, _id); - if (!tdoc) throw new DiscussionNodeNotFoundError(`contest/${id}`); + if (!tdoc) throw new DiscussionNodeNotFoundError(domainId, `${typeName}/${id}`); if (uid) { const tsdoc = await model.getStatus(domainId, _id, uid); tdoc.attend = tsdoc?.attend || tsdoc?.enroll;