feat: add workspace member assertion to card router

This commit is contained in:
Henry
2025-05-26 21:30:09 +01:00
parent a6c6524749
commit 76b65acc0f
2 changed files with 161 additions and 40 deletions

View File

@@ -9,6 +9,7 @@ import * as listRepo from "@kan/db/repository/list.repo";
import * as workspaceRepo from "@kan/db/repository/workspace.repo";
import { createTRPCRouter, protectedProcedure, publicProcedure } from "../trpc";
import { assertUserInWorkspace } from "../utils/auth";
export const cardRouter = createTRPCRouter({
create: protectedProcedure
@@ -42,31 +43,31 @@ export const cardRouter = createTRPCRouter({
code: "UNAUTHORIZED",
});
const list = await listRepo.getWithCardsByPublicId(
const list = await listRepo.getWorkspaceAndListIdByListPublicId(
ctx.db,
input.listPublicId,
);
if (!list?.id)
if (!list)
throw new TRPCError({
message: `List with public ID ${input.listPublicId} not found`,
code: "NOT_FOUND",
});
const lastCard = list.cards.length && list.cards[0];
await assertUserInWorkspace(ctx.db, userId, list.workspaceId);
let index = 0;
if (list.cards.length && input.position === "end" && lastCard) {
index = lastCard.index + 1;
}
if (!userId)
throw new TRPCError({
message: `User not authenticated`,
code: "UNAUTHORIZED",
});
const newCard = await cardRepo.create(ctx.db, {
title: input.title,
description: input.description,
createdBy: userId,
listId: list.id,
index,
position: input.position,
});
const newCardId = newCard.id;
@@ -183,7 +184,10 @@ export const cardRouter = createTRPCRouter({
code: "UNAUTHORIZED",
});
const card = await cardRepo.getByPublicId(ctx.db, input.cardPublicId);
const card = await cardRepo.getWorkspaceAndCardIdByCardPublicId(
ctx.db,
input.cardPublicId,
);
if (!card)
throw new TRPCError({
@@ -191,6 +195,8 @@ export const cardRouter = createTRPCRouter({
code: "NOT_FOUND",
});
await assertUserInWorkspace(ctx.db, userId, card.workspaceId);
const newComment = await cardCommentRepo.create(ctx.db, {
comment: input.comment,
createdBy: userId,
@@ -241,10 +247,9 @@ export const cardRouter = createTRPCRouter({
code: "UNAUTHORIZED",
});
const card = await cardRepo.getByPublicId(ctx.db, input.cardPublicId);
const existingComment = await cardCommentRepo.getByPublicId(
const card = await cardRepo.getWorkspaceAndCardIdByCardPublicId(
ctx.db,
input.commentPublicId,
input.cardPublicId,
);
if (!card)
@@ -253,6 +258,13 @@ export const cardRouter = createTRPCRouter({
code: "NOT_FOUND",
});
await assertUserInWorkspace(ctx.db, userId, card.workspaceId);
const existingComment = await cardCommentRepo.getByPublicId(
ctx.db,
input.commentPublicId,
);
if (!existingComment)
throw new TRPCError({
message: `Comment with public ID ${input.commentPublicId} not found`,
@@ -313,10 +325,9 @@ export const cardRouter = createTRPCRouter({
code: "UNAUTHORIZED",
});
const card = await cardRepo.getByPublicId(ctx.db, input.cardPublicId);
const existingComment = await cardCommentRepo.getByPublicId(
const card = await cardRepo.getWorkspaceAndCardIdByCardPublicId(
ctx.db,
input.commentPublicId,
input.cardPublicId,
);
if (!card)
@@ -325,6 +336,13 @@ export const cardRouter = createTRPCRouter({
code: "NOT_FOUND",
});
await assertUserInWorkspace(ctx.db, userId, card.workspaceId);
const existingComment = await cardCommentRepo.getByPublicId(
ctx.db,
input.commentPublicId,
);
if (!existingComment)
throw new TRPCError({
message: `Comment with public ID ${input.commentPublicId} not found`,
@@ -379,8 +397,10 @@ export const cardRouter = createTRPCRouter({
code: "UNAUTHORIZED",
});
const card = await cardRepo.getByPublicId(ctx.db, input.cardPublicId);
const label = await labelRepo.getByPublicId(ctx.db, input.labelPublicId);
const card = await cardRepo.getWorkspaceAndCardIdByCardPublicId(
ctx.db,
input.cardPublicId,
);
if (!card)
throw new TRPCError({
@@ -388,6 +408,10 @@ export const cardRouter = createTRPCRouter({
code: "NOT_FOUND",
});
await assertUserInWorkspace(ctx.db, userId, card.workspaceId);
const label = await labelRepo.getByPublicId(ctx.db, input.labelPublicId);
if (!label)
throw new TRPCError({
message: `Label with public ID ${input.labelPublicId} not found`,
@@ -465,10 +489,9 @@ export const cardRouter = createTRPCRouter({
code: "UNAUTHORIZED",
});
const card = await cardRepo.getByPublicId(ctx.db, input.cardPublicId);
const member = await workspaceRepo.getMemberByPublicId(
const card = await cardRepo.getWorkspaceAndCardIdByCardPublicId(
ctx.db,
input.workspaceMemberPublicId,
input.cardPublicId,
);
if (!card)
@@ -477,6 +500,13 @@ export const cardRouter = createTRPCRouter({
code: "NOT_FOUND",
});
await assertUserInWorkspace(ctx.db, userId, card.workspaceId);
const member = await workspaceRepo.getMemberByPublicId(
ctx.db,
input.workspaceMemberPublicId,
);
if (!member)
throw new TRPCError({
message: `Member with public ID ${input.workspaceMemberPublicId} not found`,
@@ -548,6 +578,27 @@ export const cardRouter = createTRPCRouter({
>(),
)
.query(async ({ ctx, input }) => {
const userId = ctx.user?.id;
if (!userId)
throw new TRPCError({
message: `User not authenticated`,
code: "UNAUTHORIZED",
});
const card = await cardRepo.getWorkspaceAndCardIdByCardPublicId(
ctx.db,
input.cardPublicId,
);
if (!card)
throw new TRPCError({
message: `Card with public ID ${input.cardPublicId} not found`,
code: "NOT_FOUND",
});
await assertUserInWorkspace(ctx.db, userId, card.workspaceId);
const result = await cardRepo.getWithListAndMembersByPublicId(
ctx.db,
input.cardPublicId,
@@ -591,6 +642,19 @@ export const cardRouter = createTRPCRouter({
code: "UNAUTHORIZED",
});
const card = await cardRepo.getWorkspaceAndCardIdByCardPublicId(
ctx.db,
input.cardPublicId,
);
if (!card)
throw new TRPCError({
message: `Card with public ID ${input.cardPublicId} not found`,
code: "NOT_FOUND",
});
await assertUserInWorkspace(ctx.db, userId, card.workspaceId);
const existingCard = await cardRepo.getByPublicId(
ctx.db,
input.cardPublicId,
@@ -708,31 +772,27 @@ export const cardRouter = createTRPCRouter({
code: "UNAUTHORIZED",
});
const card = await cardRepo.getCardWithListByPublicId(
const card = await cardRepo.getWorkspaceAndCardIdByCardPublicId(
ctx.db,
input.cardPublicId,
);
if (!card?.list.id)
if (!card)
throw new TRPCError({
message: `Card with public ID ${input.cardPublicId} not found`,
code: "NOT_FOUND",
});
await assertUserInWorkspace(ctx.db, userId, card.workspaceId);
const deletedAt = new Date();
const deletedCard = await cardRepo.softDelete(ctx.db, {
await cardRepo.softDelete(ctx.db, {
cardId: card.id,
deletedAt,
deletedBy: userId,
});
if (!deletedCard)
throw new TRPCError({
message: `Failed to delete card`,
code: "INTERNAL_SERVER_ERROR",
});
await cardActivityRepo.create(ctx.db, {
type: "card.archived",
cardId: card.id,