From d2dea38b01f53025f6cf8914c9d9d63a0fe36221 Mon Sep 17 00:00:00 2001 From: Stephen Adamson Date: Fri, 5 Jun 2026 21:11:47 +0100 Subject: [PATCH] fix: replace crypto.randomUUID with generateIdempotencyKey - Changed purchase flow to use generateIdempotencyKey() which uses secure window.crypto.getRandomValues with a math fallback, avoiding secure-context blocks on HTTP - Log actual error to console in both Buy and Redeem catch blocks --- frontend/src/routes/account/+page.svelte | 26 +++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/frontend/src/routes/account/+page.svelte b/frontend/src/routes/account/+page.svelte index e75cd3d..5d2d8fe 100644 --- a/frontend/src/routes/account/+page.svelte +++ b/frontend/src/routes/account/+page.svelte @@ -253,7 +253,8 @@ const errText = await res.text(); toast.error(errText || 'Failed to redeem gift card'); } - } catch { + } catch (err) { + console.error('redeemGiftCard error:', err); toast.error('Network error'); } finally { redeemingGiftCard = false; @@ -283,7 +284,7 @@ return; } - const idempotencyKey = crypto.randomUUID(); + const idempotencyKey = generateIdempotencyKey(); const res = await fetch('/api/user/giftcards/buy', { method: 'POST', @@ -317,7 +318,8 @@ const errText = await res.text(); toast.error(errText || 'Failed to purchase gift card'); } - } catch { + } catch (err) { + console.error('buyGiftCard error:', err); toast.error('Network error'); } finally { buyingGiftCard = false; @@ -452,6 +454,24 @@ buyNewCardCVC = formatted; } + function generateIdempotencyKey(): string { + const array = new Uint8Array(16); + if (typeof window !== 'undefined' && window.crypto) { + window.crypto.getRandomValues(array); + } else { + for (let i = 0; i < 16; i++) array[i] = Math.floor(Math.random() * 256); + } + array[6] = (array[6] & 0x0f) | 0x40; + array[8] = (array[8] & 0x3f) | 0x80; + return [...array] + .map((b, i) => { + const hex = b.toString(16).padStart(2, '0'); + if (i === 4 || i === 6 || i === 8 || i === 10) return '-' + hex; + return hex; + }) + .join(''); + } + async function addCard() { if (!isValidLuhn(newCardNumber) || !/^\d{2}\/\d{2}$/.test(newCardExpiry) || newCardCVC.length < 3) { toast.error('Please fill in all card details correctly');