fix: enforce active organization boundary

This commit is contained in:
2026-07-10 18:42:12 +08:00
parent f07f280b8f
commit d730e51c3d
24 changed files with 1686 additions and 460 deletions
+12 -5
View File
@@ -11,6 +11,7 @@ import {
createProjectFromOrgAdmin,
moveProjectToFolder,
} from "../projectOnboarding.js";
import { lockActiveOrganization } from "./status.js";
export interface ExplorerFolderNode {
readonly id: string;
@@ -120,6 +121,7 @@ export async function renameFolder(
},
) {
return prisma.$transaction(async (tx) => {
await lockActiveOrganization(tx, input.organizationId);
const folder = await requireActiveFolder(tx, input.folderId, input.organizationId);
if (input.parentId !== undefined && input.parentId !== null) {
if (input.parentId === folder.id) {
@@ -148,6 +150,7 @@ export async function archiveFolder(
input: { readonly organizationId: string; readonly folderId: string },
): Promise<{ readonly archived: true; readonly folderId: string }> {
return prisma.$transaction(async (tx) => {
await lockActiveOrganization(tx, input.organizationId);
const folder = await requireActiveFolder(tx, input.folderId, input.organizationId);
const childFolders = await tx.folder.count({
where: { parentId: folder.id, archivedAt: null },
@@ -195,11 +198,14 @@ export async function renameProject(
},
) {
const name = requireNonEmpty(input.name, "project name");
const project = await requireActiveProject(prisma, input.projectId, input.organizationId);
return prisma.project.update({
where: { id: project.id },
data: { name },
select: { id: true, name: true, folderId: true },
return prisma.$transaction(async (tx) => {
await lockActiveOrganization(tx, input.organizationId);
const project = await requireActiveProject(tx, input.projectId, input.organizationId);
return tx.project.update({
where: { id: project.id },
data: { name },
select: { id: true, name: true, folderId: true },
});
});
}
@@ -223,6 +229,7 @@ export async function archiveProject(
input: { readonly organizationId: string; readonly projectId: string },
): Promise<{ readonly archived: true; readonly projectId: string }> {
return prisma.$transaction(async (tx) => {
await lockActiveOrganization(tx, input.organizationId);
const project = await requireActiveProject(tx, input.projectId, input.organizationId);
const activeBinding = await tx.projectGroupBinding.findFirst({
where: { projectId: project.id, archivedAt: null },