feat: assert permission for remaining routes
This commit is contained in:
@@ -8,7 +8,7 @@ import * as workspaceRepo from "@kan/db/repository/workspace.repo";
|
||||
import { generateUID } from "@kan/shared/utils";
|
||||
|
||||
import { createTRPCRouter, protectedProcedure } from "../trpc";
|
||||
import { assertUserInWorkspace } from "../utils/auth";
|
||||
import { assertPermission } from "../utils/permissions";
|
||||
import { deleteObject, generateUploadUrl } from "../utils/s3";
|
||||
|
||||
export const attachmentRouter = createTRPCRouter({
|
||||
@@ -55,8 +55,7 @@ export const attachmentRouter = createTRPCRouter({
|
||||
message: `Card with public ID ${input.cardPublicId} not found`,
|
||||
code: "NOT_FOUND",
|
||||
});
|
||||
|
||||
await assertUserInWorkspace(ctx.db, userId, card.workspaceId);
|
||||
await assertPermission(ctx.db, userId, card.workspaceId, "card:edit");
|
||||
|
||||
// Get workspace publicId
|
||||
const workspace = await workspaceRepo.getById(ctx.db, card.workspaceId);
|
||||
@@ -131,8 +130,7 @@ export const attachmentRouter = createTRPCRouter({
|
||||
message: `Card with public ID ${input.cardPublicId} not found`,
|
||||
code: "NOT_FOUND",
|
||||
});
|
||||
|
||||
await assertUserInWorkspace(ctx.db, userId, card.workspaceId);
|
||||
await assertPermission(ctx.db, userId, card.workspaceId, "card:edit");
|
||||
|
||||
const attachment = await cardAttachmentRepo.create(ctx.db, {
|
||||
cardId: card.id,
|
||||
@@ -186,8 +184,7 @@ export const attachmentRouter = createTRPCRouter({
|
||||
});
|
||||
|
||||
const workspaceId = attachment.card.list.board.workspaceId;
|
||||
|
||||
await assertUserInWorkspace(ctx.db, userId, workspaceId);
|
||||
await assertPermission(ctx.db, userId, workspaceId, "card:edit");
|
||||
|
||||
const bucket = process.env.NEXT_PUBLIC_ATTACHMENTS_BUCKET_NAME;
|
||||
if (bucket) {
|
||||
|
||||
@@ -6,7 +6,7 @@ import * as cardActivityRepo from "@kan/db/repository/cardActivity.repo";
|
||||
import * as checklistRepo from "@kan/db/repository/checklist.repo";
|
||||
|
||||
import { createTRPCRouter, protectedProcedure } from "../trpc";
|
||||
import { assertUserInWorkspace } from "../utils/auth";
|
||||
import { assertPermission } from "../utils/permissions";
|
||||
|
||||
const checklistSchema = z.object({
|
||||
publicId: z.string().length(12),
|
||||
@@ -57,8 +57,7 @@ export const checklistRouter = createTRPCRouter({
|
||||
message: `Card with public ID ${input.cardPublicId} not found`,
|
||||
code: "NOT_FOUND",
|
||||
});
|
||||
|
||||
await assertUserInWorkspace(ctx.db, userId, card.workspaceId);
|
||||
await assertPermission(ctx.db, userId, card.workspaceId, "card:edit");
|
||||
|
||||
const newChecklist = await checklistRepo.create(ctx.db, {
|
||||
name: input.name,
|
||||
@@ -106,11 +105,11 @@ export const checklistRouter = createTRPCRouter({
|
||||
message: `Checklist with public ID ${input.checklistPublicId} not found`,
|
||||
code: "NOT_FOUND",
|
||||
});
|
||||
|
||||
await assertUserInWorkspace(
|
||||
await assertPermission(
|
||||
ctx.db,
|
||||
userId,
|
||||
checklist.card.list.board.workspace.id,
|
||||
"card:edit",
|
||||
);
|
||||
|
||||
const previousName = checklist.name;
|
||||
@@ -166,11 +165,11 @@ export const checklistRouter = createTRPCRouter({
|
||||
message: `Checklist with public ID ${input.checklistPublicId} not found`,
|
||||
code: "NOT_FOUND",
|
||||
});
|
||||
|
||||
await assertUserInWorkspace(
|
||||
await assertPermission(
|
||||
ctx.db,
|
||||
userId,
|
||||
checklist.card.list.board.workspace.id,
|
||||
"card:edit",
|
||||
);
|
||||
|
||||
await checklistRepo.softDeleteAllItemsByChecklistId(ctx.db, {
|
||||
@@ -237,11 +236,11 @@ export const checklistRouter = createTRPCRouter({
|
||||
message: `Checklist with public ID ${input.checklistPublicId} not found`,
|
||||
code: "NOT_FOUND",
|
||||
});
|
||||
|
||||
await assertUserInWorkspace(
|
||||
await assertPermission(
|
||||
ctx.db,
|
||||
userId,
|
||||
checklist.card.list.board.workspace.id,
|
||||
"card:edit",
|
||||
);
|
||||
|
||||
const newChecklistItem = await checklistRepo.createItem(ctx.db, {
|
||||
@@ -304,11 +303,11 @@ export const checklistRouter = createTRPCRouter({
|
||||
message: `Checklist item with public ID ${input.checklistItemPublicId} not found`,
|
||||
code: "NOT_FOUND",
|
||||
});
|
||||
|
||||
await assertUserInWorkspace(
|
||||
await assertPermission(
|
||||
ctx.db,
|
||||
userId,
|
||||
item.checklist.card.list.board.workspace.id,
|
||||
"card:edit",
|
||||
);
|
||||
|
||||
const previousTitle = item.title;
|
||||
@@ -394,11 +393,11 @@ export const checklistRouter = createTRPCRouter({
|
||||
message: `Checklist item with public ID ${input.checklistItemPublicId} not found`,
|
||||
code: "NOT_FOUND",
|
||||
});
|
||||
|
||||
await assertUserInWorkspace(
|
||||
await assertPermission(
|
||||
ctx.db,
|
||||
userId,
|
||||
item.checklist.card.list.board.workspace.id,
|
||||
"card:edit",
|
||||
);
|
||||
|
||||
const deleted = await checklistRepo.softDeleteItemById(ctx.db, {
|
||||
|
||||
@@ -14,7 +14,7 @@ import { colours } from "@kan/shared/constants";
|
||||
import { generateUID } from "@kan/shared/utils";
|
||||
|
||||
import { createTRPCRouter, protectedProcedure } from "../trpc";
|
||||
import { assertUserInWorkspace } from "../utils/auth";
|
||||
import { assertPermission } from "../utils/permissions";
|
||||
import { apiKeys, urls } from "./integration";
|
||||
|
||||
export interface TrelloBoard {
|
||||
@@ -180,8 +180,7 @@ export const importRouter = createTRPCRouter({
|
||||
message: `Workspace with public ID ${input.workspacePublicId} not found`,
|
||||
code: "NOT_FOUND",
|
||||
});
|
||||
|
||||
await assertUserInWorkspace(ctx.db, userId, workspace.id);
|
||||
await assertPermission(ctx.db, userId, workspace.id, "board:create");
|
||||
|
||||
const newImport = await importRepo.create(ctx.db, {
|
||||
source: "trello",
|
||||
|
||||
@@ -6,7 +6,7 @@ import * as cardRepo from "@kan/db/repository/card.repo";
|
||||
import * as labelRepo from "@kan/db/repository/label.repo";
|
||||
|
||||
import { createTRPCRouter, protectedProcedure } from "../trpc";
|
||||
import { assertUserInWorkspace } from "../utils/auth";
|
||||
import { assertPermission } from "../utils/permissions";
|
||||
|
||||
const labelSchema = z.object({
|
||||
publicId: z.string(),
|
||||
@@ -47,8 +47,7 @@ export const labelRouter = createTRPCRouter({
|
||||
message: `Label with public ID ${input.labelPublicId} not found`,
|
||||
code: "NOT_FOUND",
|
||||
});
|
||||
|
||||
await assertUserInWorkspace(ctx.db, userId, label.workspaceId);
|
||||
await assertPermission(ctx.db, userId, label.workspaceId, "board:view");
|
||||
|
||||
const result = await labelRepo.getByPublicId(ctx.db, input.labelPublicId);
|
||||
|
||||
@@ -102,8 +101,7 @@ export const labelRouter = createTRPCRouter({
|
||||
message: `Board with public ID ${input.boardPublicId} not found`,
|
||||
code: "NOT_FOUND",
|
||||
});
|
||||
|
||||
await assertUserInWorkspace(ctx.db, userId, board.workspaceId);
|
||||
await assertPermission(ctx.db, userId, board.workspaceId, "board:edit");
|
||||
|
||||
const result = await labelRepo.create(ctx.db, {
|
||||
name: input.name,
|
||||
@@ -162,8 +160,7 @@ export const labelRouter = createTRPCRouter({
|
||||
message: `Label with public ID ${input.labelPublicId} not found`,
|
||||
code: "NOT_FOUND",
|
||||
});
|
||||
|
||||
await assertUserInWorkspace(ctx.db, userId, label.workspaceId);
|
||||
await assertPermission(ctx.db, userId, label.workspaceId, "board:edit");
|
||||
|
||||
const result = await labelRepo.update(ctx.db, input);
|
||||
|
||||
@@ -211,8 +208,7 @@ export const labelRouter = createTRPCRouter({
|
||||
message: `Label with public ID ${input.labelPublicId} not found`,
|
||||
code: "NOT_FOUND",
|
||||
});
|
||||
|
||||
await assertUserInWorkspace(ctx.db, userId, label.workspaceId);
|
||||
await assertPermission(ctx.db, userId, label.workspaceId, "board:edit");
|
||||
|
||||
await cardRepo.hardDeleteAllCardLabelRelationships(ctx.db, label.id);
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@ import {
|
||||
import { updateSubscriptionSeats } from "@kan/stripe";
|
||||
|
||||
import { createTRPCRouter, protectedProcedure, publicProcedure } from "../trpc";
|
||||
import { assertUserInWorkspace } from "../utils/auth";
|
||||
import {
|
||||
assertCanManageMember,
|
||||
assertCanManageRole,
|
||||
@@ -62,7 +61,7 @@ export const memberRouter = createTRPCRouter({
|
||||
code: "NOT_FOUND",
|
||||
});
|
||||
|
||||
await assertUserInWorkspace(ctx.db, userId, workspace.id, "admin");
|
||||
await assertPermission(ctx.db, userId, workspace.id, "member:invite");
|
||||
|
||||
const isInvitedEmailAlreadyMember = workspace.members.some(
|
||||
(member) => member.email === input.email,
|
||||
@@ -196,7 +195,7 @@ export const memberRouter = createTRPCRouter({
|
||||
code: "NOT_FOUND",
|
||||
});
|
||||
|
||||
await assertUserInWorkspace(ctx.db, userId, workspace.id, "admin");
|
||||
await assertPermission(ctx.db, userId, workspace.id, "member:remove");
|
||||
|
||||
const member = await memberRepo.getByPublicId(
|
||||
ctx.db,
|
||||
@@ -298,8 +297,8 @@ export const memberRouter = createTRPCRouter({
|
||||
code: "NOT_FOUND",
|
||||
});
|
||||
|
||||
// Check if user is in workspace
|
||||
await assertUserInWorkspace(ctx.db, userId, workspace.id);
|
||||
// Check if user can view members
|
||||
await assertPermission(ctx.db, userId, workspace.id, "member:view");
|
||||
|
||||
// Get active invite link for this workspace
|
||||
const activeInviteLink = await inviteLinkRepo.getActiveForWorkspace(
|
||||
@@ -366,8 +365,8 @@ export const memberRouter = createTRPCRouter({
|
||||
code: "NOT_FOUND",
|
||||
});
|
||||
|
||||
// Check if user is in workspace
|
||||
await assertUserInWorkspace(ctx.db, userId, workspace.id, "admin");
|
||||
// Check if user can edit members (admin-equivalent)
|
||||
await assertPermission(ctx.db, userId, workspace.id, "member:edit");
|
||||
|
||||
// Check subscription for cloud environment
|
||||
if (process.env.NEXT_PUBLIC_KAN_ENV === "cloud") {
|
||||
@@ -467,8 +466,8 @@ export const memberRouter = createTRPCRouter({
|
||||
code: "NOT_FOUND",
|
||||
});
|
||||
|
||||
// Check if user is in workspace
|
||||
await assertUserInWorkspace(ctx.db, userId, workspace.id, "admin");
|
||||
// Check if user can edit members (admin-equivalent)
|
||||
await assertPermission(ctx.db, userId, workspace.id, "member:edit");
|
||||
|
||||
// Deactivate all active invite links
|
||||
await inviteLinkRepo.deactivateAllActiveForWorkspace(ctx.db, {
|
||||
|
||||
@@ -7,7 +7,7 @@ import * as workspaceSlugRepo from "@kan/db/repository/workspaceSlug.repo";
|
||||
import { generateUID } from "@kan/shared/utils";
|
||||
|
||||
import { createTRPCRouter, protectedProcedure, publicProcedure } from "../trpc";
|
||||
import { assertUserInWorkspace } from "../utils/auth";
|
||||
import { assertPermission } from "../utils/permissions";
|
||||
|
||||
export const workspaceRouter = createTRPCRouter({
|
||||
all: protectedProcedure
|
||||
@@ -74,8 +74,7 @@ export const workspaceRouter = createTRPCRouter({
|
||||
message: `Workspace not found`,
|
||||
code: "NOT_FOUND",
|
||||
});
|
||||
|
||||
await assertUserInWorkspace(ctx.db, userId, result.id);
|
||||
await assertPermission(ctx.db, userId, result.id, "workspace:view");
|
||||
|
||||
// Check if user is an admin
|
||||
const userMember = result.members.find(
|
||||
@@ -164,8 +163,7 @@ export const workspaceRouter = createTRPCRouter({
|
||||
message: `Workspace not found`,
|
||||
code: "NOT_FOUND",
|
||||
});
|
||||
|
||||
await assertUserInWorkspace(ctx.db, userId, result.id);
|
||||
await assertPermission(ctx.db, userId, result.id, "workspace:view");
|
||||
|
||||
return result;
|
||||
}),
|
||||
@@ -296,8 +294,7 @@ export const workspaceRouter = createTRPCRouter({
|
||||
message: `Workspace not found`,
|
||||
code: "NOT_FOUND",
|
||||
});
|
||||
|
||||
await assertUserInWorkspace(ctx.db, userId, workspace.id, "admin");
|
||||
await assertPermission(ctx.db, userId, workspace.id, "workspace:edit");
|
||||
|
||||
if (input.slug) {
|
||||
const reservedOrPremiumWorkspaceSlug =
|
||||
@@ -379,8 +376,7 @@ export const workspaceRouter = createTRPCRouter({
|
||||
message: `Workspace not found`,
|
||||
code: "NOT_FOUND",
|
||||
});
|
||||
|
||||
await assertUserInWorkspace(ctx.db, userId, workspace.id, "admin");
|
||||
await assertPermission(ctx.db, userId, workspace.id, "workspace:delete");
|
||||
|
||||
const result = await workspaceRepo.hardDelete(
|
||||
ctx.db,
|
||||
@@ -518,8 +514,7 @@ export const workspaceRouter = createTRPCRouter({
|
||||
message: `Workspace not found`,
|
||||
code: "NOT_FOUND",
|
||||
});
|
||||
|
||||
await assertUserInWorkspace(ctx.db, userId, workspace.id);
|
||||
await assertPermission(ctx.db, userId, workspace.id, "workspace:view");
|
||||
|
||||
const result = await workspaceRepo.searchBoardsAndCards(
|
||||
ctx.db,
|
||||
|
||||
Reference in New Issue
Block a user