diff --git a/apps/backend/src/app/api/v1/integrations/neon/internal/confirm/route.tsx b/apps/backend/src/app/api/v1/integrations/neon/internal/confirm/route.tsx
index d9edcb0dd..fe539e00d 100644
--- a/apps/backend/src/app/api/v1/integrations/neon/internal/confirm/route.tsx
+++ b/apps/backend/src/app/api/v1/integrations/neon/internal/confirm/route.tsx
@@ -18,6 +18,7 @@ export const POST = createSmartRouteHandler({
body: yupObject({
interaction_uid: yupString().defined(),
project_id: yupString().defined(),
+ neon_project_name: yupString().optional(),
}).defined(),
}),
response: yupObject({
@@ -32,7 +33,7 @@ export const POST = createSmartRouteHandler({
const set = await prismaClient.apiKeySet.create({
data: {
projectId: req.body.project_id,
- description: "Auto-generated for Neon",
+ description: `Auto-generated for Neon${req.body.neon_project_name ? ` (${req.body.neon_project_name})` : ""}`,
expiresAt: new Date(Date.now() + 1000 * 60 * 60 * 24 * 365 * 100),
superSecretAdminKey: `sak_${generateSecureRandomString()}`,
},
diff --git a/apps/backend/src/app/api/v1/integrations/neon/oauth/idp/[[...route]]/idp.ts b/apps/backend/src/app/api/v1/integrations/neon/oauth/idp/[[...route]]/idp.ts
index 9732657f0..508e509b2 100644
--- a/apps/backend/src/app/api/v1/integrations/neon/oauth/idp/[[...route]]/idp.ts
+++ b/apps/backend/src/app/api/v1/integrations/neon/oauth/idp/[[...route]]/idp.ts
@@ -373,13 +373,13 @@ export async function createOidcProvider(options: { id: string, baseUrl: string
if (typeof state !== 'string') {
throwErr(`state is not a string`);
}
- let neonProjectDisplayName: string | undefined;
+ let neonProjectName: string | undefined;
try {
const base64Decoded = new TextDecoder().decode(decodeBase64OrBase64Url(state));
const json = JSON.parse(base64Decoded);
- neonProjectDisplayName = json?.details?.neon_project_name;
- if (typeof neonProjectDisplayName !== 'string') {
- throwErr(`neon_project_name is not a string`, { type: typeof neonProjectDisplayName, neonProjectDisplayName });
+ neonProjectName = json?.details?.neon_project_name;
+ if (typeof neonProjectName !== 'string') {
+ throwErr(`neon_project_name is not a string`, { type: typeof neonProjectName, neonProjectName });
}
} catch (e) {
// this probably shouldn't happen, because it means Neon messed up the configuration
@@ -391,8 +391,8 @@ export async function createOidcProvider(options: { id: string, baseUrl: string
const uid = ctx.path.split('/')[2];
const interactionUrl = new URL(`/integrations/neon/confirm`, getEnvVariable("NEXT_PUBLIC_STACK_DASHBOARD_URL"));
interactionUrl.searchParams.set("interaction_uid", uid);
- if (neonProjectDisplayName) {
- interactionUrl.searchParams.set("neon_project_display_name", neonProjectDisplayName);
+ if (neonProjectName) {
+ interactionUrl.searchParams.set("neon_project_name", neonProjectName);
}
return ctx.redirect(interactionUrl.toString());
}
diff --git a/apps/backend/src/app/api/v1/integrations/neon/projects/provision/route.tsx b/apps/backend/src/app/api/v1/integrations/neon/projects/provision/route.tsx
index 1f2e78a4f..d7ef37da9 100644
--- a/apps/backend/src/app/api/v1/integrations/neon/projects/provision/route.tsx
+++ b/apps/backend/src/app/api/v1/integrations/neon/projects/provision/route.tsx
@@ -42,7 +42,7 @@ export const POST = createSmartRouteHandler({
const set = await createApiKeySet({
projectId: createdProject.id,
- description: "Auto-generated for Neon",
+ description: `Auto-generated for Neon (${req.body.display_name})`,
expires_at_millis: new Date(Date.now() + 1000 * 60 * 60 * 24 * 365 * 100).getTime(),
has_publishable_client_key: false,
has_secret_server_key: false,
diff --git a/apps/dashboard/src/app/(main)/integrations/neon/confirm/neon-confirm-card.tsx b/apps/dashboard/src/app/(main)/integrations/neon/confirm/neon-confirm-card.tsx
index 1412321d1..7ab731763 100644
--- a/apps/dashboard/src/app/(main)/integrations/neon/confirm/neon-confirm-card.tsx
+++ b/apps/dashboard/src/app/(main)/integrations/neon/confirm/neon-confirm-card.tsx
@@ -8,7 +8,7 @@ import { useSearchParams } from "next/navigation";
import { useState } from "react";
import NeonLogo from "../../../../../../public/neon.png";
-export default function NeonConfirmCard(props: { onContinue: (options: { projectId: string }) => Promise<{ error: string } | undefined> }) {
+export default function NeonConfirmCard(props: { onContinue: (options: { projectId: string, neonProjectName?: string }) => Promise<{ error: string } | undefined> }) {
const user = useUser({ or: "redirect", projectIdMustMatch: "internal" });
const projects = user.useOwnedProjects();
const searchParams = useSearchParams();
@@ -64,7 +64,7 @@ export default function NeonConfirmCard(props: { onContinue: (options: { project