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
This commit is contained in:
2026-06-05 21:11:47 +01:00
parent 883fd3076a
commit d2dea38b01
+23 -3
View File
@@ -253,7 +253,8 @@
const errText = await res.text(); const errText = await res.text();
toast.error(errText || 'Failed to redeem gift card'); toast.error(errText || 'Failed to redeem gift card');
} }
} catch { } catch (err) {
console.error('redeemGiftCard error:', err);
toast.error('Network error'); toast.error('Network error');
} finally { } finally {
redeemingGiftCard = false; redeemingGiftCard = false;
@@ -283,7 +284,7 @@
return; return;
} }
const idempotencyKey = crypto.randomUUID(); const idempotencyKey = generateIdempotencyKey();
const res = await fetch('/api/user/giftcards/buy', { const res = await fetch('/api/user/giftcards/buy', {
method: 'POST', method: 'POST',
@@ -317,7 +318,8 @@
const errText = await res.text(); const errText = await res.text();
toast.error(errText || 'Failed to purchase gift card'); toast.error(errText || 'Failed to purchase gift card');
} }
} catch { } catch (err) {
console.error('buyGiftCard error:', err);
toast.error('Network error'); toast.error('Network error');
} finally { } finally {
buyingGiftCard = false; buyingGiftCard = false;
@@ -452,6 +454,24 @@
buyNewCardCVC = formatted; 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() { async function addCard() {
if (!isValidLuhn(newCardNumber) || !/^\d{2}\/\d{2}$/.test(newCardExpiry) || newCardCVC.length < 3) { if (!isValidLuhn(newCardNumber) || !/^\d{2}\/\d{2}$/.test(newCardExpiry) || newCardCVC.length < 3) {
toast.error('Please fill in all card details correctly'); toast.error('Please fill in all card details correctly');