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 Which projects would you like to connect? - } value={searchParams.get("neon_project_display_name") || "Neon project connected!"} /> + } value={searchParams.get("neon_project_name") || "Neon project connected!"} />
@@ -75,7 +75,7 @@ export default function NeonConfirmCard(props: { onContinue: (options: { project if (p === "create-new") { const createSearchParams = new URLSearchParams(); createSearchParams.set("redirect_to_neon_confirm_with", searchParams.toString()); - const neonDisplayName = searchParams.get("neon_project_display_name"); + const neonDisplayName = searchParams.get("neon_project_name"); if (neonDisplayName) { createSearchParams.set("display_name", neonDisplayName); } @@ -120,7 +120,7 @@ export default function NeonConfirmCard(props: { onContinue: (options: { project