From 894b046f56f976ab7a0cf8afa72824ddf293ee38 Mon Sep 17 00:00:00 2001 From: "open-swe-dev-andrinoid[bot]" Date: Thu, 22 Jan 2026 00:30:18 +0000 Subject: [PATCH] Apply patch [skip ci] --- islands/AddPaymentMethodModal.tsx | 231 ++++++++++++++++++++++++++++++ 1 file changed, 231 insertions(+) create mode 100644 islands/AddPaymentMethodModal.tsx diff --git a/islands/AddPaymentMethodModal.tsx b/islands/AddPaymentMethodModal.tsx new file mode 100644 index 0000000..586c687 --- /dev/null +++ b/islands/AddPaymentMethodModal.tsx @@ -0,0 +1,231 @@ +import { useCallback, useRef, useState } from "preact/hooks"; +import { + encryptDataWithStoredPassword, + getEncryptionPassword, +} from "../helpers.ts"; + +interface AddPaymentMethodModalProps { + userId?: string; +} + +export default function AddPaymentMethodModal( + { userId }: AddPaymentMethodModalProps, +) { + const formRef = useRef(null); + const encryptedRoutingNumberRef = useRef(null); + const encryptedAccountNumberRef = useRef(null); + const bankNameRef = useRef(null); + const accountTypeRef = useRef(null); + const routingNumberRef = useRef(null); + const accountNumberRef = useRef(null); + const isDefaultRef = useRef(null); + const [loading, setLoading] = useState(false); + + // Only encrypt on submit, not on every keystroke - prevents V8 overload + const handleEncryptData = useCallback(async () => { + // Get current values from the form inputs + const routingNumber = routingNumberRef.current?.value || ""; + const accountNumber = accountNumberRef.current?.value || ""; + + // Check if encryption is available and encrypt sensitive fields + if (userId && (routingNumber || accountNumber)) { + const encryptionPassword = getEncryptionPassword(userId); + + if (encryptionPassword) { + try { + // Encrypt routing number + if (routingNumber && encryptedRoutingNumberRef.current) { + const encryptedRoutingNumber = await encryptDataWithStoredPassword( + userId, + routingNumber, + ); + if (encryptedRoutingNumber) { + encryptedRoutingNumberRef.current.value = encryptedRoutingNumber; + } + } + + // Encrypt account number + if (accountNumber && encryptedAccountNumberRef.current) { + const encryptedAccountNumber = await encryptDataWithStoredPassword( + userId, + accountNumber, + ); + if (encryptedAccountNumber) { + encryptedAccountNumberRef.current.value = encryptedAccountNumber; + } + } + } catch (error) { + console.error("Failed to encrypt payment method data:", error); + } + } + } + }, [userId]); + + const handleAddClick = async () => { + // Validate form + const bankName = bankNameRef.current?.value?.trim() || ""; + const accountType = accountTypeRef.current?.value || ""; + const routingNumber = routingNumberRef.current?.value?.trim() || ""; + const accountNumber = accountNumberRef.current?.value?.trim() || ""; + + if (!bankName || !accountType || !routingNumber || !accountNumber) { + alert("Please fill in all required fields."); + return; + } + + if (routingNumber.length !== 9) { + alert("Routing number must be 9 digits."); + return; + } + + if (accountNumber.length < 4) { + alert("Account number must be at least 4 digits."); + return; + } + + setLoading(true); + // Encrypt data before submission + await handleEncryptData(); + + // Clear plaintext fields if encryption was successful + if (userId && (routingNumber || accountNumber)) { + const encryptionPassword = getEncryptionPassword(userId); + + if (encryptionPassword) { + if (routingNumberRef.current) routingNumberRef.current.value = ""; + if (accountNumberRef.current) accountNumberRef.current.value = ""; + } + } + + // Submit the form + setTimeout(() => { + if (formRef.current) { + formRef.current.submit(); + } + }, 100); + }; + + return ( +
+

Add Payment Method

+
+ + + + +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+
+ +
+ + Cancel + + +
+
+ ); +}