@pylonsync/stripe 0.3.287 → 0.3.289
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/package.json +3 -3
- package/src/handlers/webhook.test.ts +20 -0
- package/src/handlers/webhook.ts +6 -0
- package/src/manifest.ts +4 -0
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "0.3.
|
|
6
|
+
"version": "0.3.289",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"main": "src/index.ts",
|
|
9
9
|
"types": "src/index.ts",
|
|
@@ -12,8 +12,8 @@
|
|
|
12
12
|
"check": "tsc -p tsconfig.json --noEmit"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@pylonsync/sdk": "0.3.
|
|
16
|
-
"@pylonsync/functions": "0.3.
|
|
15
|
+
"@pylonsync/sdk": "0.3.289",
|
|
16
|
+
"@pylonsync/functions": "0.3.289"
|
|
17
17
|
},
|
|
18
18
|
"peerDependencies": {
|
|
19
19
|
"bun-types": "*"
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { expect, test } from "bun:test";
|
|
2
|
+
|
|
3
|
+
import type { StripeConfig } from "../types";
|
|
4
|
+
import { stripeWebhookHandler } from "./webhook";
|
|
5
|
+
|
|
6
|
+
// Regression for the high-severity "billing silently never syncs" bug: Stripe
|
|
7
|
+
// POSTs the webhook anonymously, so the handler MUST declare auth:"public".
|
|
8
|
+
// With the default auth:"user", every delivery to /api/fn/stripeWebhook is
|
|
9
|
+
// rejected with 401 AUTH_REQUIRED before the signature check runs, so no
|
|
10
|
+
// subscription/credit row is ever written. The signature verification inside
|
|
11
|
+
// the handler (STRIPE_WEBHOOK_SECRET) is the real auth boundary, not a session.
|
|
12
|
+
test("stripeWebhookHandler is public (Stripe POSTs anonymously)", () => {
|
|
13
|
+
const cfg = {
|
|
14
|
+
referenceType: "org",
|
|
15
|
+
plans: [],
|
|
16
|
+
} as unknown as StripeConfig;
|
|
17
|
+
|
|
18
|
+
const handler = stripeWebhookHandler(cfg);
|
|
19
|
+
expect(handler.auth).toBe("public");
|
|
20
|
+
});
|
package/src/handlers/webhook.ts
CHANGED
|
@@ -31,6 +31,12 @@ import { resolveWebhookSecret } from "./internal";
|
|
|
31
31
|
*/
|
|
32
32
|
export function stripeWebhookHandler(cfg: StripeConfig) {
|
|
33
33
|
return action({
|
|
34
|
+
// Webhook receivers are unauthenticated by nature: Stripe POSTs
|
|
35
|
+
// anonymously, so the default `auth: "user"` 401s every delivery
|
|
36
|
+
// before the handler runs. The real auth boundary is the signature
|
|
37
|
+
// check below (verifyStripeSignature against STRIPE_WEBHOOK_SECRET),
|
|
38
|
+
// not a user session.
|
|
39
|
+
auth: "public",
|
|
34
40
|
args: {},
|
|
35
41
|
async handler(ctx: HandlerCtx) {
|
|
36
42
|
if (!ctx.request) {
|
package/src/manifest.ts
CHANGED
|
@@ -117,6 +117,10 @@ export function buildStripeManifest(
|
|
|
117
117
|
action("restoreSubscription", {
|
|
118
118
|
input: [{ name: "referenceId", type: "string", optional: true }],
|
|
119
119
|
}),
|
|
120
|
+
// Public-by-handler: the handler factory declares `auth: "public"`
|
|
121
|
+
// (Stripe POSTs anonymously; the signature check is the real auth
|
|
122
|
+
// boundary). The manifest action() builder carries input shapes
|
|
123
|
+
// only — auth lives on the handler, which the runtime gates on.
|
|
120
124
|
action("stripeWebhook"),
|
|
121
125
|
],
|
|
122
126
|
};
|