diff --git a/ui/apps/dashboard/src/app/(organization-active)/(dashboard)/env/[environmentSlug]/apps/sync-new/ManualSync.tsx b/ui/apps/dashboard/src/app/(organization-active)/(dashboard)/env/[environmentSlug]/apps/sync-new/ManualSync.tsx index f2c85bf61..0cdb681fa 100644 --- a/ui/apps/dashboard/src/app/(organization-active)/(dashboard)/env/[environmentSlug]/apps/sync-new/ManualSync.tsx +++ b/ui/apps/dashboard/src/app/(organization-active)/(dashboard)/env/[environmentSlug]/apps/sync-new/ManualSync.tsx @@ -12,10 +12,10 @@ import { useMutation } from 'urql'; import type { CodedError } from '@/codedError'; import Input from '@/components/Forms/Input'; +import { Secret } from '@/components/Secret'; import { SyncFailure } from '@/components/SyncFailure'; import { graphql } from '@/gql'; import { pathCreator } from '@/utils/urls'; -import DeploySigningKey from '../../deploys/DeploySigningKey'; import { useEnvironment } from '../../environment-context'; const SyncNewAppDocument = graphql(` @@ -136,7 +136,9 @@ export default function ManualSync({ appsURL }: Props) { . Verify that you assigned the signing key below to the INNGEST_SIGNING_KEY{' '} environment variable:

- + + +
-
-
-

- - 1 - - Send your events -

-

- After syncing your app, you can start sending events to this environment. To send - events, your application needs to have an Event Key. -

-

Event Key

-

- An Event Key let's your application send events to Inngest with{' '} - - inngest.send(...) - - . -

-

- We recommend adding your event key as the{' '} - - INNGEST_EVENT_KEY - {' '} - environment variable in your application. Your platform may support setting this in an{' '} - - .env - {' '} - file or you may need to set it manually on your platform. -

- - - -
-
-
+
+ + + + + +

+ + 2 + + Trigger Functions With Events +

+

+ After registering your functions, you can trigger them with events sent to this + environment. Your events will show up on this page when they are received. +

+
- - - -
-

- - 2 - - Trigger Functions With Events -

-

- After registering your functions, you can trigger them with events sent to this - environment. Your events will show up on this page when they are received. -

-
-
-
+
+
); diff --git a/ui/apps/dashboard/src/app/(organization-active)/(dashboard)/env/[environmentSlug]/manage/[ingestKeys]/[keyID]/page.tsx b/ui/apps/dashboard/src/app/(organization-active)/(dashboard)/env/[environmentSlug]/manage/[ingestKeys]/[keyID]/page.tsx index 8951cb0d7..5bedb9b10 100644 --- a/ui/apps/dashboard/src/app/(organization-active)/(dashboard)/env/[environmentSlug]/manage/[ingestKeys]/[keyID]/page.tsx +++ b/ui/apps/dashboard/src/app/(organization-active)/(dashboard)/env/[environmentSlug]/manage/[ingestKeys]/[keyID]/page.tsx @@ -3,7 +3,6 @@ import { useState } from 'react'; import { notFound } from 'next/navigation'; import { PencilIcon, TrashIcon } from '@heroicons/react/20/solid'; -import { CodeKey } from '@inngest/components/CodeKey'; import { DropdownMenu, DropdownMenuContent, @@ -13,6 +12,8 @@ import { import { RiMore2Line } from '@remixicon/react'; import { useEnvironment } from '@/app/(organization-active)/(dashboard)/env/[environmentSlug]/environment-context'; +import { Secret } from '@/components/Secret'; +import type { SecretKind } from '@/components/Secret/Secret'; import { graphql } from '@/gql'; import { useGraphQLQuery } from '@/utils/useGraphQLQuery'; import { Provider } from './Context'; @@ -84,18 +85,14 @@ export default function Keys({ params: { ingestKeys, keyID } }: KeyDetailsProps) // Integration created keys cannot be deleted or renamed const isIntegration = key.source === SOURCE_INTEGRATION; - let value = '', - maskedValue = '', - keyLabel = 'Key'; + let secretKind: SecretKind; + let value; if (ingestKeys === 'webhooks') { + secretKind = 'webhook-path'; value = key.url || ''; - // Leave the base url + the beginning of the key - maskedValue = value.replace(/(.{0,}\/e\/)(\w{0,8}).+/, '$1$2'); - keyLabel = 'Webhook URL'; } else { + secretKind = 'event-key'; value = key.presharedKey; - maskedValue = value.substring(0, 8); - keyLabel = 'Event Key'; } return ( @@ -140,7 +137,7 @@ export default function Keys({ params: { ingestKeys, keyID } }: KeyDetailsProps) )}
- +
diff --git a/ui/apps/dashboard/src/app/(organization-active)/(dashboard)/env/[environmentSlug]/manage/signing-key/SigningKey.tsx b/ui/apps/dashboard/src/app/(organization-active)/(dashboard)/env/[environmentSlug]/manage/signing-key/SigningKey.tsx index e847b3045..47da8434a 100644 --- a/ui/apps/dashboard/src/app/(organization-active)/(dashboard)/env/[environmentSlug]/manage/signing-key/SigningKey.tsx +++ b/ui/apps/dashboard/src/app/(organization-active)/(dashboard)/env/[environmentSlug]/manage/signing-key/SigningKey.tsx @@ -1,9 +1,9 @@ import { Badge } from '@inngest/components/Badge'; import { Card } from '@inngest/components/Card'; +import { Time } from '@inngest/components/Time'; import { RiStarFill } from '@remixicon/react'; import { Secret } from '@/components/Secret'; -import { Time } from '@/components/Time'; import { DeleteSigningKeyButton } from './DeleteSigningKeyButton'; type Props = { diff --git a/ui/apps/dashboard/src/app/(organization-active)/(dashboard)/env/[environmentSlug]/manage/signing-key/page-old.tsx b/ui/apps/dashboard/src/app/(organization-active)/(dashboard)/env/[environmentSlug]/manage/signing-key/page-old.tsx index 9a42cdd92..dcf752946 100644 --- a/ui/apps/dashboard/src/app/(organization-active)/(dashboard)/env/[environmentSlug]/manage/signing-key/page-old.tsx +++ b/ui/apps/dashboard/src/app/(organization-active)/(dashboard)/env/[environmentSlug]/manage/signing-key/page-old.tsx @@ -4,8 +4,8 @@ */ import { Alert } from '@inngest/components/Alert'; -import { CodeKey } from '@inngest/components/CodeKey'; +import { Secret } from '@/components/Secret'; import { graphql } from '@/gql'; import graphqlAPI from '@/queries/graphqlAPI'; import { getEnvironment } from '@/queries/server-only/getEnvironment'; @@ -32,21 +32,12 @@ export default async function Page({ environmentSlug }: Props) { environmentID: environment.id, }); - const maskedSigningKey = res.environment.webhookSigningKey.replace( - /signkey-(prod|test)-.+/, - 'signkey-$1' - ); - return (

Inngest Signing Key

- +

Use this secret signing key with the diff --git a/ui/apps/dashboard/src/components/Secret/CopyButton.tsx b/ui/apps/dashboard/src/components/Secret/CopyButton.tsx index 68013ac83..e12f6a4d6 100644 --- a/ui/apps/dashboard/src/components/Secret/CopyButton.tsx +++ b/ui/apps/dashboard/src/components/Secret/CopyButton.tsx @@ -20,10 +20,10 @@ export function CopyButton({ value }: Props) { return ( - + diff --git a/ui/apps/dashboard/src/components/Secret/Secret.tsx b/ui/apps/dashboard/src/components/Secret/Secret.tsx index d38b51a5a..26b7784f8 100644 --- a/ui/apps/dashboard/src/components/Secret/Secret.tsx +++ b/ui/apps/dashboard/src/components/Secret/Secret.tsx @@ -1,14 +1,16 @@ +'use client'; + import { useState } from 'react'; import { cn } from '@inngest/components/utils/classNames'; import { CopyButton } from './CopyButton'; import { RevealButton } from './RevealButton'; -type SecretKind = 'signing-key'; +export type SecretKind = 'event-key' | 'signing-key' | 'webhook-path'; type Props = { className?: string; - kind?: SecretKind; + kind: SecretKind; secret: string; }; @@ -23,27 +25,44 @@ export function Secret({ className, kind, secret }: Props) { return (

-
- {value} - setIsRevealed((prev) => !prev)} /> +
+ {value}
+ setIsRevealed((prev) => !prev)} + /> +
); } -function maskSecret(value: string, kind: SecretKind | undefined): string { +function maskSecret(value: string, kind: SecretKind): string { + if (value.length < 8) { + // Invalid secret + return value.replaceAll(/./g, 'X'); + } + + if (kind === 'event-key') { + // Mask everything after the 8th character + return value.substring(0, 7) + 'X'.repeat(value.length - 8); + } + if (kind === 'signing-key') { + // Mask everything after the prefix (e.g. "signkey-prod-") return value.replace( /^(signkey-[A-Za-z0-9]+-).+$/, (match, p1) => p1 + 'X'.repeat(match.length - p1.length) ); } - return value.replaceAll(/./g, 'X'); + // Mask everything after the 8th character of the path (e.g. "/e/12345678") + return value.replace(/^(\/e\/.{8}).+$/, (match, p1) => p1 + 'X'.repeat(match.length - p1.length)); } diff --git a/ui/packages/components/src/Card/Card.tsx b/ui/packages/components/src/Card/Card.tsx index 9687316e5..ced363366 100644 --- a/ui/packages/components/src/Card/Card.tsx +++ b/ui/packages/components/src/Card/Card.tsx @@ -38,20 +38,22 @@ export function Card({ accentColor, accentPosition = 'top', children, className )} > {accentColor &&
} -
{children}
+
+ {children} +
); } Card.Content = ({ children, className }: PropsWithChildren<{ className?: string }>) => { - return
{children}
; + return
{children}
; }; Card.Footer = ({ children, className }: PropsWithChildren<{ className?: string }>) => { return (
@@ -64,7 +66,7 @@ Card.Header = ({ children, className }: PropsWithChildren<{ className?: string } return (
diff --git a/ui/packages/components/src/CodeKey/CodeKey.stories.tsx b/ui/packages/components/src/CodeKey/CodeKey.stories.tsx deleted file mode 100644 index 350db5361..000000000 --- a/ui/packages/components/src/CodeKey/CodeKey.stories.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/react'; - -import { CodeKey } from './CodeKey'; - -const meta = { - title: 'Components/CodeKey', - component: CodeKey, - decorators: [ - (Story) => ( -
- -
- ), - ], - parameters: { - layout: 'centered', - }, - tags: ['autodocs'], -} satisfies Meta; - -export default meta; - -type Story = StoryObj; - -export const Default: Story = { - args: { - fullKey: 'FNb31q4iFNb31q4iFNb31q4iFNb31q4iFNb31q4iFNb31q4i', - maskedKey: 'FNb31q4i...', - label: 'Signing Key', - }, -}; diff --git a/ui/packages/components/src/CodeKey/CodeKey.tsx b/ui/packages/components/src/CodeKey/CodeKey.tsx deleted file mode 100644 index 402366d3d..000000000 --- a/ui/packages/components/src/CodeKey/CodeKey.tsx +++ /dev/null @@ -1,50 +0,0 @@ -'use client'; - -import { useState } from 'react'; -import { Button } from '@inngest/components/Button'; -import { CopyButton } from '@inngest/components/CopyButton'; -import { useCopyToClipboard } from '@inngest/components/hooks/useCopyToClipboard'; -import { classNames } from '@inngest/components/utils/classNames'; - -type CodeKeyProps = { - fullKey: string; - maskedKey?: string; - label?: string; - className?: string; -}; - -export function CodeKey({ fullKey, maskedKey, label, className }: CodeKeyProps) { - const [showKey, setShowKey] = useState(false); - const { handleCopyClick, isCopying } = useCopyToClipboard(); - - return ( -
-
-
- {label && ( -

- {label} -

- )} -
- ); -} diff --git a/ui/packages/components/src/CodeKey/index.ts b/ui/packages/components/src/CodeKey/index.ts deleted file mode 100644 index ccbcb91b5..000000000 --- a/ui/packages/components/src/CodeKey/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { CodeKey } from './CodeKey';