From 3e91c2f03bbeb5f04918dff50776522bbda8e0c4 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Mon, 30 Mar 2026 23:05:29 +0000 Subject: [PATCH 1/2] Add already-added notice for secret approval links Co-authored-by: Kent C. Dodds --- e2e/account-secrets.spec.ts | 43 ++++++- .../worker/client/routes/account-secrets.tsx | 111 +++++++++++++++++- 2 files changed, 151 insertions(+), 3 deletions(-) diff --git a/e2e/account-secrets.spec.ts b/e2e/account-secrets.spec.ts index 74171a18c8..ae1bd96d77 100644 --- a/e2e/account-secrets.spec.ts +++ b/e2e/account-secrets.spec.ts @@ -6,6 +6,8 @@ async function saveSecret( name: string description: string value: string + allowedHosts?: Array + allowedCapabilities?: Array }, ) { const response = await page.request.post('/account/secrets.json', { @@ -16,8 +18,8 @@ async function saveSecret( appId: null, description: input.description, value: input.value, - allowedHosts: [], - allowedCapabilities: [], + allowedHosts: input.allowedHosts ?? [], + allowedCapabilities: input.allowedCapabilities ?? [], }, headers: { 'Content-Type': 'application/json' }, }) @@ -81,3 +83,40 @@ test('switching secrets updates detail view without a full reload', async ({ ), ).resolves.toBe('still-here') }) + +test('landing on an approval link shows already added when the host is present', async ({ + page, + login, +}) => { + await login() + + const nonce = Date.now().toString(36) + const secret = { + name: `cloudflare-token-${nonce}`, + description: `Cloudflare token ${nonce}`, + value: `token-${nonce}`, + allowedHosts: ['api.cloudflare.com'], + } + + await saveSecret(page, secret) + + await page.goto( + `/account/secrets/user/${secret.name}?allowed-host=api.cloudflare.com&request=stale-token`, + ) + + await expect( + page.getByRole('heading', { level: 2, name: secret.name }), + ).toBeVisible() + await expect( + page.getByRole('heading', { level: 2, name: 'Already added' }), + ).toBeVisible() + await expect( + page.getByRole('status').getByText('This request is already complete for this secret.'), + ).toBeVisible() + await expect( + page.getByRole('status').getByText('Host', { exact: false }), + ).toContainText('api.cloudflare.com') + await expect( + page.getByRole('heading', { level: 2, name: 'Approve host access' }), + ).toHaveCount(0) +}) diff --git a/packages/worker/client/routes/account-secrets.tsx b/packages/worker/client/routes/account-secrets.tsx index 691c3d9624..b3b97a614e 100644 --- a/packages/worker/client/routes/account-secrets.tsx +++ b/packages/worker/client/routes/account-secrets.tsx @@ -228,6 +228,62 @@ function readCapabilityPrefill(href: string) { return value?.trim() ? value.trim() : null } +function readRequestedHost(href: string) { + const url = new URL(href, 'http://localhost') + const value = url.searchParams.get('allowed-host') + return value?.trim() ? value.trim() : null +} + +function normalizeSingleAllowedHost(host: string | null) { + if (!host) return null + return clientNormalizeAllowedHosts([host])[0] ?? null +} + +function normalizeSingleAllowedCapability(capability: string | null) { + if (!capability) return null + return clientNormalizeAllowedCapabilities([capability])[0] ?? null +} + +function getAlreadyAddedNotice(input: { + href: string + selectedSecret: SecretDetail | null + approval: ApprovalView | null +}) { + const requestedHost = normalizeSingleAllowedHost(readRequestedHost(input.href)) + const requestedCapability = normalizeSingleAllowedCapability( + readCapabilityPrefill(input.href), + ) + const allowedHosts = input.selectedSecret + ? clientNormalizeAllowedHosts(coerceStringRows(input.selectedSecret.allowedHosts)) + : input.approval + ? clientNormalizeAllowedHosts(input.approval.currentAllowedHosts) + : [] + const allowedCapabilities = input.selectedSecret + ? clientNormalizeAllowedCapabilities( + coerceStringRows(input.selectedSecret.allowedCapabilities), + ) + : [] + const items: Array = [] + const hostAlreadyAdded = + requestedHost != null && allowedHosts.includes(requestedHost) + if (hostAlreadyAdded) { + items.push(`Host ${requestedHost} is already in allowed hosts.`) + } + if ( + requestedCapability != null && + allowedCapabilities.includes(requestedCapability) + ) { + items.push( + `Capability ${requestedCapability} is already in allowed capabilities.`, + ) + } + if (items.length === 0) return null + return { + items, + hostAlreadyAdded, + } +} + function applyCapabilityPrefill(state: EditorState, capability: string | null) { if (!capability) return state if (state.allowedCapabilities.some((entry) => entry.trim() === capability)) { @@ -767,6 +823,15 @@ export function AccountSecretsRoute(handle: Handle) { const isMutating = saveState !== 'idle' || submittingApprovalAction != null const canCreateAppSecrets = apps.length > 0 const showEditor = selection.isCreating || selectedSecret != null + const alreadyAddedNotice = getAlreadyAddedNotice({ + href: currentHref, + selectedSecret, + approval, + }) + const showApprovalCard = + approval && + !isRefreshingForLocationChange && + !alreadyAddedNotice?.hostAlreadyAdded return (
- {approval && !isRefreshingForLocationChange ? ( + {showApprovalCard ? (
) : null} + {alreadyAddedNotice ? ( +
+
+

+ Already added +

+

+ This request is already complete for this secret. +

+
+
    + {alreadyAddedNotice.items.map((item) => ( +
  • + {item} +
  • + ))} +
+
+ ) : null} {status === 'loading' ? (

Loading secrets…

From e4db22c6364fd201581b19dc67d5e25042605262 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 31 Mar 2026 00:52:12 +0000 Subject: [PATCH 2/2] Fix account secrets approval card type narrowing Co-authored-by: Kent C. Dodds --- .../worker/client/routes/account-secrets.tsx | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/packages/worker/client/routes/account-secrets.tsx b/packages/worker/client/routes/account-secrets.tsx index b3b97a614e..5c5fdcc22b 100644 --- a/packages/worker/client/routes/account-secrets.tsx +++ b/packages/worker/client/routes/account-secrets.tsx @@ -828,10 +828,12 @@ export function AccountSecretsRoute(handle: Handle) { selectedSecret, approval, }) - const showApprovalCard = + const approvalCard = approval && !isRefreshingForLocationChange && !alreadyAddedNotice?.hostAlreadyAdded + ? approval + : null return (
- {showApprovalCard ? ( + {approvalCard ? (

- Allow {approval.requestedHost} to receive secret{' '} - {approval.name} from the{' '} - {getScopeLabel(approval.scope)} scope. + Allow {approvalCard.requestedHost} to receive + secret {approvalCard.name} from the{' '} + {getScopeLabel(approvalCard.scope)} scope.

- {approval.requestedCapability ? ( + {approvalCard.requestedCapability ? (

Requested capability:{' '} - {approval.requestedCapability} + {approvalCard.requestedCapability}

) : null}

Current allowed hosts:{' '} - {approval.currentAllowedHosts.length > 0 - ? approval.currentAllowedHosts.join(', ') + {approvalCard.currentAllowedHosts.length > 0 + ? approvalCard.currentAllowedHosts.join(', ') : 'none'}