diff --git a/apps/backend/src/route-handlers/smart-request.tsx b/apps/backend/src/route-handlers/smart-request.tsx index f59b29541..7a834ddde 100644 --- a/apps/backend/src/route-handlers/smart-request.tsx +++ b/apps/backend/src/route-handlers/smart-request.tsx @@ -231,7 +231,7 @@ async function parseAuth(req: NextRequest): Promise { const project = await getProject(projectId); if (!project) { - throw new StackAssertionError("Project not found; this should never happen because having a project ID should guarantee a project"); + throw new StackAssertionError("Project not found; this should only happen if the project was deleted and the access token is still valid", { projectId }); } let user = null; diff --git a/apps/e2e/tests/backend/endpoints/api/v1/projects.test.ts b/apps/e2e/tests/backend/endpoints/api/v1/projects.test.ts index 44f3182d2..4abc434f0 100644 --- a/apps/e2e/tests/backend/endpoints/api/v1/projects.test.ts +++ b/apps/e2e/tests/backend/endpoints/api/v1/projects.test.ts @@ -2,7 +2,7 @@ import { it } from "../../../../helpers"; import { Auth, InternalProjectKeys, Project, backendContext, niceBackendFetch } from "../../../backend-helpers"; -it("should not have have access to the project", async ({ expect }) => { +it("should not have have access to the project without project keys", async ({ expect }) => { backendContext.set({ projectKeys: 'no-project' }); @@ -801,3 +801,130 @@ it("updates the project oauth configuration", async ({ expect }) => { } `); }); + +it("deletes a project with admin access", async ({ expect }) => { + await Auth.Otp.signIn(); + const { adminAccessToken } = await Project.createAndGetAdminToken(); + + // Delete the project + const deleteResponse = await niceBackendFetch(`/api/v1/projects/current`, { + accessType: "admin", + method: "DELETE", + headers: { + 'x-stack-admin-access-token': adminAccessToken, + } + }); + + expect(deleteResponse).toMatchInlineSnapshot(` + NiceResponse { + "status": 200, + "body": { "success": true }, + "headers": Headers {