11import { isBase64Url } from "@stackframe/stack-shared/dist/utils/bytes" ;
22import { it } from "../../../../helpers" ;
3- import { Auth , InternalProjectKeys , Project , backendContext , niceBackendFetch } from "../../../backend-helpers" ;
3+ import { Auth , InternalApiKey , InternalProjectKeys , Project , backendContext , niceBackendFetch } from "../../../backend-helpers" ;
44
55
66// TODO some of the tests here test /api/v1/projects/current, the others test /api/v1/internal/projects/current. We should split them into different test files
@@ -1231,6 +1231,109 @@ it("deletes a project with users, teams, and permissions", async ({ expect }) =>
12311231 "headers": Headers { <some fields may have been hidden> },
12321232 }
12331233 ` ) ;
1234+
1235+ // make sure that the project no longer exists
1236+ const getProjectResponse = await niceBackendFetch ( `/api/v1/projects/current` , {
1237+ accessType : "admin" ,
1238+ method : "GET" ,
1239+ } ) ;
1240+ expect ( getProjectResponse ) . toMatchInlineSnapshot ( `
1241+ NiceResponse {
1242+ "status": 400,
1243+ "body": {
1244+ "code": "CURRENT_PROJECT_NOT_FOUND",
1245+ "details": { "project_id": "<stripped UUID>" },
1246+ "error": "The current project with ID <stripped UUID> was not found. Please check the value of the x-stack-project-id header.",
1247+ },
1248+ "headers": Headers {
1249+ "x-stack-known-error": "CURRENT_PROJECT_NOT_FOUND",
1250+ <some fields may have been hidden>,
1251+ },
1252+ }
1253+ ` ) ;
1254+ } ) ;
1255+
1256+ it ( "does not allow accessing a current project that doesn't exist" , async ( { expect } ) => {
1257+ backendContext . set ( {
1258+ projectKeys : {
1259+ projectId : "does-not-exist" ,
1260+ } ,
1261+ } ) ;
1262+ const response = await niceBackendFetch ( `/api/v1/projects/current` , {
1263+ accessType : "admin" ,
1264+ method : "GET" ,
1265+ } ) ;
1266+ expect ( response ) . toMatchInlineSnapshot ( `
1267+ NiceResponse {
1268+ "status": 400,
1269+ "body": {
1270+ "code": "CURRENT_PROJECT_NOT_FOUND",
1271+ "details": { "project_id": "does-not-exist" },
1272+ "error": "The current project with ID does-not-exist was not found. Please check the value of the x-stack-project-id header.",
1273+ },
1274+ "headers": Headers {
1275+ "x-stack-known-error": "CURRENT_PROJECT_NOT_FOUND",
1276+ <some fields may have been hidden>,
1277+ },
1278+ }
1279+ ` ) ;
1280+ } ) ;
1281+
1282+ it ( "does not allow accessing a project with the wrong API keys" , async ( { expect } ) => {
1283+ await Project . createAndSwitch ( ) ;
1284+ await InternalApiKey . createAndSetProjectKeys ( ) ;
1285+ backendContext . set ( {
1286+ projectKeys : {
1287+ projectId : ( backendContext . value . projectKeys as any ) . projectId ,
1288+ publishableClientKey : "fake publishable client key" ,
1289+ secretServerKey : "fake secret server key" ,
1290+ superSecretAdminKey : "fake admin key" ,
1291+ }
1292+ } ) ;
1293+ const response = await niceBackendFetch ( `/api/v1/projects/current` , {
1294+ accessType : "admin" ,
1295+ method : "GET" ,
1296+ } ) ;
1297+ expect ( response ) . toMatchInlineSnapshot ( `
1298+ NiceResponse {
1299+ "status": 401,
1300+ "body": {
1301+ "code": "INVALID_SUPER_SECRET_ADMIN_KEY",
1302+ "details": { "project_id": "<stripped UUID>" },
1303+ "error": "The super secret admin key is not valid for the project \\"<stripped UUID>\\". Does the project and/or the key exist?",
1304+ },
1305+ "headers": Headers {
1306+ "x-stack-known-error": "INVALID_SUPER_SECRET_ADMIN_KEY",
1307+ <some fields may have been hidden>,
1308+ },
1309+ }
1310+ ` ) ;
1311+ } ) ;
1312+
1313+ it ( "does not allow accessing a project without a project ID header" , async ( { expect } ) => {
1314+ backendContext . set ( { projectKeys : "no-project" } ) ;
1315+ const response = await niceBackendFetch ( `/api/v1/projects/current` , {
1316+ accessType : "admin" ,
1317+ method : "GET" ,
1318+ } ) ;
1319+ expect ( response ) . toMatchInlineSnapshot ( `
1320+ NiceResponse {
1321+ "status": 400,
1322+ "body": {
1323+ "code": "ACCESS_TYPE_WITHOUT_PROJECT_ID",
1324+ "details": { "request_type": "admin" },
1325+ "error": deindent\`
1326+ The x-stack-access-type header was 'admin', but the x-stack-project-id header was not provided.
1327+
1328+ For more information, see the docs on REST API authentication: https://docs.stack-auth.com/rest-api/overview#authentication
1329+ \`,
1330+ },
1331+ "headers": Headers {
1332+ "x-stack-known-error": "ACCESS_TYPE_WITHOUT_PROJECT_ID",
1333+ <some fields may have been hidden>,
1334+ },
1335+ }
1336+ ` ) ;
12341337} ) ;
12351338
12361339it ( "makes sure user have the correct managed project ID after project creation" , async ( { expect } ) => {
@@ -1247,17 +1350,23 @@ it("makes sure user have the correct managed project ID after project creation",
12471350 expect ( projectIds [ 0 ] ) . toBe ( projectId ) ;
12481351} ) ;
12491352
1250- it ( "makes sure user don't have managed project ID after project deletion " , async ( { expect } ) => {
1353+ it ( "removes a deleted project from a user's managed project IDs " , async ( { expect } ) => {
12511354 backendContext . set ( { projectKeys : InternalProjectKeys } ) ;
1252- const { creatorUserId, adminAccessToken } = await Project . createAndGetAdminToken ( ) ;
1355+ const { creatorUserId, adminAccessToken, projectId } = await Project . createAndGetAdminToken ( ) ;
1356+
1357+ backendContext . set ( { projectKeys : InternalProjectKeys } ) ;
1358+ const userResponse1 = await niceBackendFetch ( `/api/v1/users/${ creatorUserId } ` , {
1359+ accessType : "server" ,
1360+ method : "GET" ,
1361+ } ) ;
1362+ const projectIds1 = userResponse1 . body . server_metadata . managedProjectIds ;
1363+ expect ( projectIds1 . length ) . toBe ( 1 ) ;
12531364
12541365 // Delete the project
1366+ backendContext . set ( { projectKeys : { projectId, adminAccessToken } } ) ;
12551367 const deleteResponse = await niceBackendFetch ( `/api/v1/internal/projects/current` , {
12561368 accessType : "admin" ,
12571369 method : "DELETE" ,
1258- headers : {
1259- 'x-stack-admin-access-token' : adminAccessToken ,
1260- }
12611370 } ) ;
12621371
12631372 expect ( deleteResponse ) . toMatchInlineSnapshot ( `
@@ -1270,12 +1379,12 @@ it("makes sure user don't have managed project ID after project deletion", async
12701379
12711380 backendContext . set ( { projectKeys : InternalProjectKeys } ) ;
12721381
1273- const userResponse = await niceBackendFetch ( `/api/v1/users/${ creatorUserId } ` , {
1382+ const userResponse2 = await niceBackendFetch ( `/api/v1/users/${ creatorUserId } ` , {
12741383 accessType : "server" ,
12751384 method : "GET" ,
12761385 } ) ;
1277- const projectIds = userResponse . body . server_metadata . managedProjectIds ;
1278- expect ( projectIds . length ) . toBe ( 0 ) ;
1386+ const projectIds2 = userResponse2 . body . server_metadata . managedProjectIds ;
1387+ expect ( projectIds2 . length ) . toBe ( 0 ) ;
12791388} ) ;
12801389
12811390it ( "makes sure other users are not affected by project deletion" , async ( { expect } ) => {
0 commit comments