feat(helpers): verify webhook signatures without a Standard Webhooks library - #4
Draft
antonwhop wants to merge 2 commits into
Draft
feat(helpers): verify webhook signatures without a Standard Webhooks library#4antonwhop wants to merge 2 commits into
antonwhop wants to merge 2 commits into
Conversation
…library Restores the verification half of client.webhooks.unwrap, which the Stainless SDK shipped and Fern cannot generate: Fern generates from OpenAPI paths and unwrap was never a path. Standalone under com.whop.api.helpers rather than a method on WhopApiClient, so nothing generated has to be patched. javax.crypto.Mac, java.util.Base64 and java.security.MessageDigest are all in the JDK, so the HMAC is computed over the raw ws_ secret directly — sidestepping the base64-decoded-key mismatch that made the Ruby, Python and TypeScript helpers reject every genuine delivery until each learned to base64-encode the whole secret to cancel it out. No dependency is added, which matters because build.gradle stays Fern's. .fernignore was a single comment line and protected nothing; it now keeps the helper and its tests, and ci.yml fails if either the files or the entries go missing. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XV1533iUUxKJxfn4FXptWz
The e2e suite counts System.getenv references under src/main and asserts the SDK reads no environment variables. A javadoc example is a match, so the example now names the secret as a parameter. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XV1533iUUxKJxfn4FXptWz
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
client.webhooks.unwrapshipped in the Stainless SDK and every Fern SDK lost it — Fern generates from OpenAPI paths andunwrapwas never a path. Ruby, Python and TypeScript have it back as hand-written helpers; Java did not, so a Java consumer had no way to tell a genuine Whop delivery from a forged one.What changed?
com.whop.api.helpers.WebhookVerifier.unwrap(payload, headers, key)verifies thewebhook-id/webhook-timestamp/webhook-signaturetriple and returns the parsed body as aJsonNode. Standalone, so no generated file is patched, and it adds no dependency:javax.crypto.Mac,java.util.Base64andjava.security.MessageDigestare JDK, so it HMACs the rawws_…secret directly instead of fighting the Standard Webhooks libraries' base64-decoded key — the bug that made all three sibling helpers reject real deliveries until each base64-encoded the whole secret to cancel it out.WebhooksManager::SignWebhooksigns and the fixture signer itself pinned to a vector computed in Python. Covers a valid signature, tampered body, wrong secret, each of the three headers missing, stale and future timestamps, a multi-entry header whose validv1entry is not first, mixed header casing, and byte-exactness (a re-serialised body is refused)..fernignorewas a single comment line and protected nothing. It now keepssrc/{main,test}/java/com/whop/api/helpers, andci.ymlfails if either the files or the entries go missing.build.gradlestays Fern-owned, as ci: release pipeline for the Java SDK, publishing to GitHub Packages now and Maven Central later #2 intends.Stacked on #2. Nothing published, nothing tagged.