Skip to content

Commit a16589e

Browse files
committed
Refactor project integration identifiers from externalProjectId to clientId across the backend, including environment configuration, database schema, and API endpoints. Update test cases to reflect these changes for both custom and Neon integrations.
1 parent 6c02787 commit a16589e

11 files changed

Lines changed: 24 additions & 24 deletions

File tree

apps/backend/.env.development

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,4 @@ STACK_ARTIFICIAL_DEVELOPMENT_DELAY_MS=50
4141

4242
STACK_ENABLE_HARDCODED_PASSKEY_CHALLENGE_FOR_TESTING=yes
4343

44-
STACK_INTEGRATION_CLIENTS_CONFIG=[{"client_id": "neon-local", "client_secret": "neon-local-secret", "id_token_signed_response_alg": "ES256", "redirect_uris": ["http://localhost:30000/api/v2/identity/authorize", "http://localhost:30000/api/v2/auth/authorize"]}, {"client_id": "custom-local", "client_secret": "custom-local-secret", "id_token_signed_response_alg": "ES256", "redirect_uris": ["http://localhost:30000/api/v2/identity/authorize", "http://localhost:30000/api/v2/auth/authorize"]}]
44+
STACK_INTEGRATION_CLIENTS_CONFIG=[{"client_id": "neon-dev", "client_secret": "neon-dev-secret", "id_token_signed_response_alg": "ES256", "redirect_uris": ["http://localhost:30000/api/v2/identity/authorize", "http://localhost:30000/api/v2/auth/authorize"]}, {"client_id": "custom-dev", "client_secret": "custom-dev-secret", "id_token_signed_response_alg": "ES256", "redirect_uris": ["http://localhost:30000/api/v2/identity/authorize", "http://localhost:30000/api/v2/auth/authorize"]}]

apps/backend/prisma/migrations/20250520185503_rename_neon/migration.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ ALTER TYPE "VerificationCodeType" RENAME VALUE 'NEON_INTEGRATION_PROJECT_TRANSFE
55
ALTER TABLE "NeonProvisionedProject" RENAME TO "ProvisionedProject";
66
ALTER TABLE "ProvisionedProject" RENAME CONSTRAINT "NeonProvisionedProject_pkey" TO "ProvisionedProject_pkey";
77
ALTER TABLE "ProvisionedProject" RENAME CONSTRAINT "NeonProvisionedProject_projectId_fkey" TO "ProvisionedProject_projectId_fkey";
8-
ALTER TABLE "ProvisionedProject" RENAME COLUMN "neonClientId" TO "externalProjectId";
8+
ALTER TABLE "ProvisionedProject" RENAME COLUMN "neonClientId" TO "clientId";

apps/backend/prisma/schema.prisma

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -641,7 +641,7 @@ model ProvisionedProject {
641641
createdAt DateTime @default(now())
642642
updatedAt DateTime @updatedAt
643643
644-
externalProjectId String
644+
clientId String
645645
}
646646

647647
//#region Events

apps/backend/src/app/api/latest/integrations/custom/projects/provision/route.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ export const POST = createSmartRouteHandler({
5454
await prismaClient.provisionedProject.create({
5555
data: {
5656
projectId: createdProject.id,
57-
externalProjectId: clientId,
57+
clientId: clientId,
5858
},
5959
});
6060

apps/backend/src/app/api/latest/integrations/custom/projects/transfer/confirm/verification-code-handler.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export const integrationProjectTransferCodeHandler = createVerificationCodeHandl
1616
},
1717
type: VerificationCodeType.INTEGRATION_PROJECT_TRANSFER,
1818
data: yupObject({
19-
external_project_id: yupString().defined(),
19+
client_id: yupString().defined(),
2020
project_id: yupString().defined(),
2121
}).defined(),
2222
method: yupObject({}),
@@ -34,7 +34,7 @@ export const integrationProjectTransferCodeHandler = createVerificationCodeHandl
3434
const provisionedProjects = await prismaClient.provisionedProject.findMany({
3535
where: {
3636
projectId: data.project_id,
37-
externalProjectId: data.external_project_id,
37+
clientId: data.client_id,
3838
},
3939
});
4040
if (provisionedProjects.length === 0) throw new StatusError(400, "The project to transfer was not provisioned or has already been transferred.");
@@ -48,7 +48,7 @@ export const integrationProjectTransferCodeHandler = createVerificationCodeHandl
4848
const provisionedProject = await tx.provisionedProject.deleteMany({
4949
where: {
5050
projectId: data.project_id,
51-
externalProjectId: data.external_project_id,
51+
clientId: data.client_id,
5252
},
5353
});
5454

apps/backend/src/app/api/latest/integrations/custom/projects/transfer/route.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ async function validateAndGetTransferInfo(authorizationHeader: string, projectId
1515
const provisionedProject = await prismaClient.provisionedProject.findUnique({
1616
where: {
1717
projectId,
18-
externalProjectId: clientId,
18+
clientId: clientId,
1919
},
2020
});
2121
if (!provisionedProject) {
@@ -89,7 +89,7 @@ export const POST = createSmartRouteHandler({
8989
method: {},
9090
data: {
9191
project_id: provisionedProject.projectId,
92-
external_project_id: provisionedProject.externalProjectId,
92+
client_id: provisionedProject.clientId,
9393
},
9494
callbackUrl: new URL("/integrations/custom/projects/transfer/confirm", getEnvVariable("NEXT_PUBLIC_STACK_DASHBOARD_URL")),
9595
expiresInMs: 1000 * 60 * 60,

apps/backend/src/app/api/latest/integrations/neon/projects/provision/route.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ export const POST = createSmartRouteHandler({
5454
await prismaClient.provisionedProject.create({
5555
data: {
5656
projectId: createdProject.id,
57-
externalProjectId: clientId,
57+
clientId: clientId,
5858
},
5959
});
6060

apps/backend/src/app/api/latest/integrations/neon/projects/transfer/confirm/verification-code-handler.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ export const neonIntegrationProjectTransferCodeHandler = createVerificationCodeH
3434
const provisionedProjects = await prismaClient.provisionedProject.findMany({
3535
where: {
3636
projectId: data.project_id,
37-
externalProjectId: data.neon_client_id,
37+
clientId: data.neon_client_id,
3838
},
3939
});
4040
if (provisionedProjects.length === 0) throw new StatusError(400, "The project to transfer was not provisioned by Neon or has already been transferred.");
@@ -48,7 +48,7 @@ export const neonIntegrationProjectTransferCodeHandler = createVerificationCodeH
4848
const provisionedProject = await tx.provisionedProject.deleteMany({
4949
where: {
5050
projectId: data.project_id,
51-
externalProjectId: data.neon_client_id,
51+
clientId: data.neon_client_id,
5252
},
5353
});
5454

apps/backend/src/app/api/latest/integrations/neon/projects/transfer/route.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ async function validateAndGetTransferInfo(authorizationHeader: string, projectId
1515
const provisionedProject = await prismaClient.provisionedProject.findUnique({
1616
where: {
1717
projectId,
18-
externalProjectId: clientId,
18+
clientId: clientId,
1919
},
2020
});
2121
if (!provisionedProject) {
@@ -89,7 +89,7 @@ export const POST = createSmartRouteHandler({
8989
method: {},
9090
data: {
9191
project_id: provisionedProject.projectId,
92-
neon_client_id: provisionedProject.externalProjectId,
92+
neon_client_id: provisionedProject.clientId,
9393
},
9494
callbackUrl: new URL("/integrations/neon/projects/transfer/confirm", getEnvVariable("NEXT_PUBLIC_STACK_DASHBOARD_URL")),
9595
expiresInMs: 1000 * 60 * 60,

apps/e2e/tests/backend/endpoints/api/v1/integrations/custom/oauth.test.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ async function authorizePart1(redirectUri: string = "http://localhost:30000/api/
1010
method: "GET",
1111
query: {
1212
response_type: "code",
13-
client_id: "custom-local",
13+
client_id: "custom-dev",
1414
redirect_uri: redirectUri,
1515
state: encodeBase64Url(new TextEncoder().encode(JSON.stringify({ details: { external_project_name: 'custom-project' } }))),
1616
code_challenge: "xf6HY7PIgoaCf_eMniSt-45brYE2J_05C9BnfIbueik",
@@ -75,7 +75,7 @@ async function authorize(projectId: string) {
7575
NiceResponse {
7676
"status": 307,
7777
"headers": Headers {
78-
"location": "http://localhost:8102/api/v1/integrations/custom/oauth/idp/auth?response_type=code&client_id=custom-local&redirect_uri=%3Cstripped+query+param%3E&state=%3Cstripped+query+param%3E&code_challenge=%3Cstripped+query+param%3E&code_challenge_method=S256&scope=openid",
78+
"location": "http://localhost:8102/api/v1/integrations/custom/oauth/idp/auth?response_type=code&client_id=custom-dev&redirect_uri=%3Cstripped+query+param%3E&state=%3Cstripped+query+param%3E&code_challenge=%3Cstripped+query+param%3E&code_challenge_method=S256&scope=openid",
7979
<some fields may have been hidden>,
8080
},
8181
},
@@ -169,7 +169,7 @@ it(`should not redirect to the incorrect callback URL`, async ({}) => {
169169
NiceResponse {
170170
"status": 307,
171171
"headers": Headers {
172-
"location": "http://localhost:8102/api/v1/integrations/custom/oauth/idp/auth?response_type=code&client_id=custom-local&redirect_uri=%3Cstripped+query+param%3E&state=%3Cstripped+query+param%3E&code_challenge=%3Cstripped+query+param%3E&code_challenge_method=S256&scope=openid",
172+
"location": "http://localhost:8102/api/v1/integrations/custom/oauth/idp/auth?response_type=code&client_id=custom-dev&redirect_uri=%3Cstripped+query+param%3E&state=%3Cstripped+query+param%3E&code_challenge=%3Cstripped+query+param%3E&code_challenge_method=S256&scope=openid",
173173
<some fields may have been hidden>,
174174
},
175175
},
@@ -203,7 +203,7 @@ it(`should exchange the authorization code for an admin API key that works`, asy
203203
redirect_uri: "http://localhost:30000/api/v2/auth/authorize",
204204
},
205205
headers: {
206-
"Authorization": encodeBasicAuthorizationHeader("custom-local", "custom-local-secret")
206+
"Authorization": encodeBasicAuthorizationHeader("custom-dev", "custom-dev-secret")
207207
},
208208
});
209209
expect(tokenResponse).toMatchInlineSnapshot(`
@@ -257,7 +257,7 @@ it(`should not exchange the authorization code when the client secret is incorre
257257
redirect_uri: "http://localhost:30000/api/v2/auth/authorize",
258258
},
259259
headers: {
260-
"Authorization": encodeBasicAuthorizationHeader("custom-local", "wrong-secret")
260+
"Authorization": encodeBasicAuthorizationHeader("custom-dev", "wrong-secret")
261261
},
262262
});
263263
expect(tokenResponse).toMatchInlineSnapshot(`

0 commit comments

Comments
 (0)