fix: updating samples and components for schema updates#241
fix: updating samples and components for schema updates#241
Conversation
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Greptile SummaryThis PR updates the Kotlin sample app and Grid Visualizer component to align with the latest API schema changes: account type renames (e.g. Key changes:
Confidence Score: 3/5
|
| Filename | Overview |
|---|---|
| components/grid-visualizer/src/data/account-types.ts | Renames account type keys (US_ACCOUNT→USD_ACCOUNT, IBAN→EUR_ACCOUNT, PIX→BRL_ACCOUNT, etc.), adds optional paymentRails field to AccountTypeSpec, adds many new account types, and removes the generic fallback spread; changes look correct and consistent with schema updates. |
| components/grid-visualizer/src/data/currencies.ts | Updates accountType references to match renamed enum values and normalises payment rail strings to uppercase enum style (e.g. FEDNOW, SEPA_INSTANT, FASTER_PAYMENTS); adds DKK, RWF, TZS, ZMW, ZAR currencies and removes several unsupported ones. |
| samples/kotlin/src/main/kotlin/com/grid/sample/routes/Webhooks.kt | Adds WebhookUtils.verifyWebhookSignature call, but the isValid result is only logged and never used to reject invalid requests — webhooks are processed unconditionally regardless of signature validity, which is a security logic bug. |
| samples/kotlin/src/main/kotlin/com/grid/sample/routes/ExternalAccounts.kt | Major refactor to typed per-currency account builders with paymentRails support, but buildAccountInfo() only handles 5 of the ~20 account types now defined in account-types.ts; the else branch throws an uncaught exception for all new types. |
| samples/kotlin/src/main/kotlin/com/grid/sample/routes/Quotes.kt | Adds purposeOfPayment support and updates QuoteSourceOneOf to QuoteCreateParams.Source with updated factory method names; clean migration to new SDK types. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[POST /api/customers/:id/external-accounts] --> B{accountType?}
B -- missing --> C[400 Bad Request]
B -- present --> D{buildAccountInfo switch}
D -- USD_ACCOUNT --> E[UsdExternalAccountInfo + UsdBeneficiary]
D -- INR_ACCOUNT --> F[InrExternalAccountInfo + InrBeneficiary]
D -- BRL_ACCOUNT --> G[BrlExternalAccountInfo + BrlBeneficiary]
D -- MXN_ACCOUNT --> H[MxnExternalAccountInfo + MxnBeneficiary]
D -- GBP_ACCOUNT --> I[GbpExternalAccountInfo + GbpBeneficiary]
D -- EUR/DKK/NGN/SGD/etc --> J[⚠️ IllegalArgumentException → 500]
E & F & G & H & I --> K[ExternalAccountCreate.builder]
K --> L[client.customers.externalAccounts.create]
L --> M[201 Created]
N[POST /api/webhooks] --> O[ensurePublicKey]
O --> P[verifyWebhookSignature]
P --> Q[Log result only ⚠️ not enforced]
Q --> R[webhooks.unwrap — always runs]
R --> S[WebhookStream.addEvent]
Last reviewed commit: b267999
| Log.webhook(rawBody) | ||
|
|
||
| try { | ||
| ensurePublicKey() | ||
| val signature = call.request.header("X-Grid-Signature") ?: "" | ||
| val isValid = WebhookUtils.verifyWebhookSignature(rawBody, signature) | ||
| Log.webhookSignatureResult(isValid) |
There was a problem hiding this comment.
Webhook signature result is ignored
isValid is logged but never acted upon — the webhook is parsed and processed even when signature verification fails. This defeats the purpose of the verification entirely. An invalid signature should reject the request immediately.
| Log.webhook(rawBody) | |
| try { | |
| ensurePublicKey() | |
| val signature = call.request.header("X-Grid-Signature") ?: "" | |
| val isValid = WebhookUtils.verifyWebhookSignature(rawBody, signature) | |
| Log.webhookSignatureResult(isValid) | |
| ensurePublicKey() | |
| val signature = call.request.header("X-Grid-Signature") ?: "" | |
| val isValid = WebhookUtils.verifyWebhookSignature(rawBody, signature) | |
| Log.webhookSignatureResult(isValid) | |
| if (!isValid) { | |
| call.respondText("""{"error": "Invalid webhook signature"}""", ContentType.Application.Json, HttpStatusCode.Unauthorized) | |
| return@post | |
| } | |
| val event = GridClientBuilder.client.webhooks().unwrap(rawBody) | |
| val eventJson = JsonUtils.mapper.writerWithDefaultPrettyPrinter().writeValueAsString(event) |
Prompt To Fix With AI
This is a comment left during a code review.
Path: samples/kotlin/src/main/kotlin/com/grid/sample/routes/Webhooks.kt
Line: 27-33
Comment:
**Webhook signature result is ignored**
`isValid` is logged but never acted upon — the webhook is parsed and processed even when signature verification fails. This defeats the purpose of the verification entirely. An invalid signature should reject the request immediately.
```suggestion
ensurePublicKey()
val signature = call.request.header("X-Grid-Signature") ?: ""
val isValid = WebhookUtils.verifyWebhookSignature(rawBody, signature)
Log.webhookSignatureResult(isValid)
if (!isValid) {
call.respondText("""{"error": "Invalid webhook signature"}""", ContentType.Application.Json, HttpStatusCode.Unauthorized)
return@post
}
val event = GridClientBuilder.client.webhooks().unwrap(rawBody)
val eventJson = JsonUtils.mapper.writerWithDefaultPrettyPrinter().writeValueAsString(event)
```
How can I resolve this? If you propose a fix, please make it concise.| @@ -110,5 +78,190 @@ fun Route.externalAccountRoutes() { | |||
| } | |||
There was a problem hiding this comment.
Many new account types unhandled — will throw unhandled exception
buildAccountInfo() only handles USD_ACCOUNT, INR_ACCOUNT, BRL_ACCOUNT, MXN_ACCOUNT, and GBP_ACCOUNT. The account types added in this PR (EUR_ACCOUNT, DKK_ACCOUNT, NGN_ACCOUNT, CAD_ACCOUNT, PHP_ACCOUNT, SGD_ACCOUNT, HKD_ACCOUNT, IDR_ACCOUNT, KES_ACCOUNT, MYR_ACCOUNT, RWF_ACCOUNT, THB_ACCOUNT, TZS_ACCOUNT, VND_ACCOUNT, ZAR_ACCOUNT, ZMW_ACCOUNT) all fall through to the else -> throw IllegalArgumentException(...) branch. This will surface as a 500 error to callers instead of a meaningful 400. Even as a sample app, the new account types listed in account-types.ts should either have corresponding builders here or the else branch should return a proper HTTP 400 response before the exception propagates.
Prompt To Fix With AI
This is a comment left during a code review.
Path: samples/kotlin/src/main/kotlin/com/grid/sample/routes/ExternalAccounts.kt
Line: 78
Comment:
**Many new account types unhandled — will throw unhandled exception**
`buildAccountInfo()` only handles `USD_ACCOUNT`, `INR_ACCOUNT`, `BRL_ACCOUNT`, `MXN_ACCOUNT`, and `GBP_ACCOUNT`. The account types added in this PR (`EUR_ACCOUNT`, `DKK_ACCOUNT`, `NGN_ACCOUNT`, `CAD_ACCOUNT`, `PHP_ACCOUNT`, `SGD_ACCOUNT`, `HKD_ACCOUNT`, `IDR_ACCOUNT`, `KES_ACCOUNT`, `MYR_ACCOUNT`, `RWF_ACCOUNT`, `THB_ACCOUNT`, `TZS_ACCOUNT`, `VND_ACCOUNT`, `ZAR_ACCOUNT`, `ZMW_ACCOUNT`) all fall through to the `else -> throw IllegalArgumentException(...)` branch. This will surface as a 500 error to callers instead of a meaningful 400. Even as a sample app, the new account types listed in `account-types.ts` should either have corresponding builders here or the `else` branch should return a proper HTTP 400 response before the exception propagates.
How can I resolve this? If you propose a fix, please make it concise.
Updating the kotlin sample and grid visualizer component for the latest api changes