From 2d124818d0ceaac73c46193eb1f7ffd86cf4cc46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Sibiril?= <81782+aureliensibiril@users.noreply.github.com> Date: Sat, 11 Jul 2026 19:47:56 +0200 Subject: [PATCH] Guard Crisp code copy against missing clipboard MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The verification-code copy handler called navigator.clipboard.writeText directly and relied on the promise rejection for the failure toast. In an insecure context or an unsupported embedded browser navigator.clipboard is undefined, so the call throws synchronously before .then and neither toast fires, leaving the user without the manual-copy guidance. Guard the access and wrap the call in try/catch, mirroring ScopeDiagram, so the failure toast is always shown. Signed-off-by: Aurélien Sibiril <81782+aureliensibiril@users.noreply.github.com> --- .../_components/APIKeyConnectorDialog.tsx | 43 +++++++++++++------ 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/apps/console/src/pages/organizations/access-reviews/dialogs/_components/APIKeyConnectorDialog.tsx b/apps/console/src/pages/organizations/access-reviews/dialogs/_components/APIKeyConnectorDialog.tsx index 3a230c305..2ed7fda97 100644 --- a/apps/console/src/pages/organizations/access-reviews/dialogs/_components/APIKeyConnectorDialog.tsx +++ b/apps/console/src/pages/organizations/access-reviews/dialogs/_components/APIKeyConnectorDialog.tsx @@ -349,22 +349,37 @@ export function APIKeyConnectorDialog({ type="button" variant="secondary" onClick={() => { + const onCopyFailure = () => + toast({ + title: __("Copy failed"), + description: __("Copy the verification code manually."), + variant: "error", + }); + + // navigator.clipboard is undefined in an insecure + // context or unsupported embedded browser, where + // writeText throws synchronously before .then; guard + // so the manual-copy toast still shows. + if (!navigator.clipboard?.writeText) { + onCopyFailure(); + return; + } + // Copying feeds the Crisp connect flow, so only // claim success once the write actually resolves. - navigator.clipboard.writeText(crispCodeState.code).then( - () => - toast({ - title: __("Copied to clipboard"), - description: __("Verification code"), - variant: "success", - }), - () => - toast({ - title: __("Copy failed"), - description: __("Copy the verification code manually."), - variant: "error", - }), - ); + try { + navigator.clipboard.writeText(crispCodeState.code).then( + () => + toast({ + title: __("Copied to clipboard"), + description: __("Verification code"), + variant: "success", + }), + onCopyFailure, + ); + } catch { + onCopyFailure(); + } }} > {__("Copy")}