Skip to content

Commit 75cd558

Browse files
committed
Rewrite example
1 parent 052f754 commit 75cd558

2 files changed

Lines changed: 25 additions & 37 deletions

File tree

README.md

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -336,29 +336,6 @@ You can find the [Mailtrap Java API reference](https://mailtrap.github.io/mailtr
336336
- [Webhooks](examples/java/io/mailtrap/examples/webhooks/WebhooksExample.java)
337337
- [Verifying webhook signatures](examples/java/io/mailtrap/examples/webhooks/WebhookSignatureExample.java)
338338

339-
#### Verifying webhook signatures
340-
341-
Mailtrap signs every outbound webhook with HMAC-SHA256 and sends the lowercase hex digest in the `Mailtrap-Signature` header. Verify the signature against the raw request body using the `signing_secret` returned when you created the webhook:
342-
343-
```java
344-
import io.mailtrap.webhooks.WebhookSignatures;
345-
346-
// `payload` must be the unparsed request body — do NOT re-serialize the
347-
// parsed JSON, as that may reorder keys and invalidate the signature.
348-
boolean valid = WebhookSignatures.verify(
349-
payload,
350-
request.getHeader("Mailtrap-Signature"),
351-
System.getenv("MAILTRAP_WEBHOOK_SIGNING_SECRET")
352-
);
353-
354-
if (!valid) {
355-
// reject the request — 401 Unauthorized
356-
return;
357-
}
358-
```
359-
360-
The helper performs a constant-time comparison and returns `false` (rather than throwing) for empty, missing, or malformed signatures.
361-
362339
### Organizations API
363340

364341
- [Sub-Accounts](examples/java/io/mailtrap/examples/organizations/SubAccountsExample.java)
Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,37 @@
11
package io.mailtrap.examples.webhooks;
22

3+
import com.sun.net.httpserver.HttpServer;
34
import io.mailtrap.webhooks.WebhookSignatures;
45

5-
import javax.crypto.Mac;
6-
import javax.crypto.spec.SecretKeySpec;
6+
import java.io.IOException;
7+
import java.io.InputStream;
8+
import java.net.InetSocketAddress;
79
import java.nio.charset.StandardCharsets;
8-
import java.util.HexFormat;
910

1011
public class WebhookSignatureExample {
1112

12-
public static void main(final String[] args) throws Exception {
13-
// --- Direct verification (e.g. for unit tests or custom routers) ----
14-
final String payload = "{\"event\":\"delivery\",\"message_id\":\"abc-123\"}";
15-
final String signingSecret = "8d9a3c0e7f5b2d4a6c1e9f8b3a7d5c2e";
13+
public static void main(final String[] args) throws IOException {
14+
final String signingSecret = System.getenv("MAILTRAP_WEBHOOK_SIGNING_SECRET");
1615

17-
final Mac mac = Mac.getInstance("HmacSHA256");
18-
mac.init(new SecretKeySpec(signingSecret.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
19-
final String signature = HexFormat.of().formatHex(
20-
mac.doFinal(payload.getBytes(StandardCharsets.UTF_8)));
16+
final HttpServer server = HttpServer.create(new InetSocketAddress(9292), 0);
17+
server.createContext("/webhooks/mailtrap", exchange -> {
18+
// Use the raw request body — parsing and re-serializing the JSON may
19+
// reorder keys or alter whitespace and invalidate the signature.
20+
final String payload;
21+
try (InputStream body = exchange.getRequestBody()) {
22+
payload = new String(body.readAllBytes(), StandardCharsets.UTF_8);
23+
}
24+
final String signature = exchange.getRequestHeaders().getFirst("Mailtrap-Signature");
2125

22-
if (!WebhookSignatures.verify(payload, signature, signingSecret)) {
23-
throw new IllegalStateException("Signature verification failed!");
24-
}
26+
if (!WebhookSignatures.verify(payload, signature, signingSecret)) {
27+
exchange.sendResponseHeaders(401, -1);
28+
exchange.close();
29+
return;
30+
}
31+
32+
exchange.sendResponseHeaders(200, -1);
33+
exchange.close();
34+
});
35+
server.start();
2536
}
2637
}

0 commit comments

Comments
 (0)