@distyra/sdk 0.6.0 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +37 -0
- package/dist/generated.d.ts +3556 -526
- package/dist/index.d.ts +94 -2
- package/dist/index.js +154 -4
- package/dist/webhook.d.ts +56 -0
- package/dist/webhook.js +93 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -77,6 +77,43 @@ Note: `resolution.retryable` is a different signal. It is `true` only for a tran
|
|
|
77
77
|
backend error (`timed_out` / `transient_error`), which you retry within seconds. See the
|
|
78
78
|
full resolution-and-retries guide at <https://api.distyra.com/docs>.
|
|
79
79
|
|
|
80
|
+
## Verifying webhooks
|
|
81
|
+
|
|
82
|
+
Distyra signs every webhook delivery with a Stripe-shape header:
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
X-Distyra-Signature: t=<unix>,v1=<hmac_sha256_hex>
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
`verifyWebhook` checks it (HMAC-SHA256 over `"<t>.<rawBody>"`, keyed by the
|
|
89
|
+
endpoint's signing secret, with replay protection). Always verify against the
|
|
90
|
+
**raw request body**, before JSON parsing — re-serializing changes the bytes and
|
|
91
|
+
breaks the signature.
|
|
92
|
+
|
|
93
|
+
```ts
|
|
94
|
+
import { verifyWebhook } from '@distyra/sdk';
|
|
95
|
+
|
|
96
|
+
// Express — capture the raw body, e.g. app.use(express.raw({ type: 'application/json' }))
|
|
97
|
+
app.post('/webhooks/distyra', (req, res) => {
|
|
98
|
+
const raw = req.body.toString('utf8');
|
|
99
|
+
const result = verifyWebhook(
|
|
100
|
+
process.env.DISTYRA_WEBHOOK_SECRET!,
|
|
101
|
+
raw,
|
|
102
|
+
req.header('X-Distyra-Signature'),
|
|
103
|
+
);
|
|
104
|
+
if (!result.ok) return res.status(400).send(result.reason);
|
|
105
|
+
|
|
106
|
+
const event = JSON.parse(raw);
|
|
107
|
+
// ... handle event ...
|
|
108
|
+
res.sendStatus(200);
|
|
109
|
+
});
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
It returns `{ ok: true, timestamp }` or `{ ok: false, reason }` where `reason` is
|
|
113
|
+
`'malformed'`, `'stale'`, or `'no_match'`. The default replay window is 5 minutes
|
|
114
|
+
(`DEFAULT_TOLERANCE_SECONDS`); override it with `{ toleranceSeconds }`. Uses
|
|
115
|
+
`node:crypto`, so it runs server-side (Node 18+).
|
|
116
|
+
|
|
80
117
|
## Lower-level access
|
|
81
118
|
|
|
82
119
|
The generated `paths` and `operations` types are re-exported if you want to build your own `openapi-fetch` client or reference response shapes directly:
|