@better-auth/stripe 1.5.0-beta.2 → 1.5.0-beta.4
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/.turbo/turbo-build.log +9 -9
- package/CHANGELOG.md +15 -13
- package/LICENSE.md +15 -12
- package/dist/client.d.mts +105 -1
- package/dist/client.mjs +1 -1
- package/dist/error-codes-Bkj5yJMT.mjs +29 -0
- package/dist/{index-SbT5j9k6.d.mts → index-BnHmwMru.d.mts} +269 -154
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +449 -194
- package/package.json +7 -7
- package/src/error-codes.ts +16 -0
- package/src/hooks.ts +98 -71
- package/src/index.ts +142 -45
- package/src/middleware.ts +89 -42
- package/src/routes.ts +502 -224
- package/src/schema.ts +18 -0
- package/src/types.ts +75 -19
- package/src/utils.ts +11 -0
- package/test/stripe-organization.test.ts +1993 -0
- package/{src → test}/stripe.test.ts +821 -18
- package/dist/error-codes-qqooUh6R.mjs +0 -16
package/src/middleware.ts
CHANGED
|
@@ -1,57 +1,104 @@
|
|
|
1
1
|
import { createAuthMiddleware } from "@better-auth/core/api";
|
|
2
|
-
import { APIError } from "better-auth/
|
|
3
|
-
import
|
|
2
|
+
import { APIError } from "@better-auth/core/error";
|
|
3
|
+
import { sessionMiddleware } from "better-auth/api";
|
|
4
|
+
import { STRIPE_ERROR_CODES } from "./error-codes";
|
|
5
|
+
import type {
|
|
6
|
+
AuthorizeReferenceAction,
|
|
7
|
+
CustomerType,
|
|
8
|
+
StripeCtxSession,
|
|
9
|
+
SubscriptionOptions,
|
|
10
|
+
} from "./types";
|
|
11
|
+
|
|
12
|
+
export const stripeSessionMiddleware = createAuthMiddleware(
|
|
13
|
+
{
|
|
14
|
+
use: [sessionMiddleware],
|
|
15
|
+
},
|
|
16
|
+
async (ctx) => {
|
|
17
|
+
const session = ctx.context.session as StripeCtxSession;
|
|
18
|
+
return {
|
|
19
|
+
session,
|
|
20
|
+
};
|
|
21
|
+
},
|
|
22
|
+
);
|
|
4
23
|
|
|
5
24
|
export const referenceMiddleware = (
|
|
6
25
|
subscriptionOptions: SubscriptionOptions,
|
|
7
|
-
action:
|
|
8
|
-
| "upgrade-subscription"
|
|
9
|
-
| "list-subscription"
|
|
10
|
-
| "cancel-subscription"
|
|
11
|
-
| "restore-subscription"
|
|
12
|
-
| "billing-portal",
|
|
26
|
+
action: AuthorizeReferenceAction,
|
|
13
27
|
) =>
|
|
14
28
|
createAuthMiddleware(async (ctx) => {
|
|
15
|
-
const
|
|
16
|
-
if (!
|
|
17
|
-
throw
|
|
29
|
+
const ctxSession = ctx.context.session as StripeCtxSession;
|
|
30
|
+
if (!ctxSession) {
|
|
31
|
+
throw APIError.from("UNAUTHORIZED", STRIPE_ERROR_CODES.UNAUTHORIZED);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const customerType: CustomerType =
|
|
35
|
+
ctx.body?.customerType || ctx.query?.customerType;
|
|
36
|
+
const explicitReferenceId = ctx.body?.referenceId || ctx.query?.referenceId;
|
|
37
|
+
|
|
38
|
+
if (customerType === "organization") {
|
|
39
|
+
// Organization subscriptions always require authorizeReference
|
|
40
|
+
if (!subscriptionOptions.authorizeReference) {
|
|
41
|
+
ctx.context.logger.error(
|
|
42
|
+
`Organization subscriptions require authorizeReference to be defined in your stripe plugin config.`,
|
|
43
|
+
);
|
|
44
|
+
throw APIError.from(
|
|
45
|
+
"BAD_REQUEST",
|
|
46
|
+
STRIPE_ERROR_CODES.ORGANIZATION_SUBSCRIPTION_NOT_ENABLED,
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const referenceId =
|
|
51
|
+
explicitReferenceId || ctxSession.session.activeOrganizationId;
|
|
52
|
+
if (!referenceId) {
|
|
53
|
+
throw APIError.from(
|
|
54
|
+
"BAD_REQUEST",
|
|
55
|
+
STRIPE_ERROR_CODES.ORGANIZATION_REFERENCE_ID_REQUIRED,
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
const isAuthorized = await subscriptionOptions.authorizeReference(
|
|
59
|
+
{
|
|
60
|
+
user: ctxSession.user,
|
|
61
|
+
session: ctxSession.session,
|
|
62
|
+
referenceId,
|
|
63
|
+
action,
|
|
64
|
+
},
|
|
65
|
+
ctx,
|
|
66
|
+
);
|
|
67
|
+
if (!isAuthorized) {
|
|
68
|
+
throw APIError.from("UNAUTHORIZED", STRIPE_ERROR_CODES.UNAUTHORIZED);
|
|
69
|
+
}
|
|
70
|
+
return;
|
|
18
71
|
}
|
|
19
|
-
const referenceId =
|
|
20
|
-
ctx.body?.referenceId || ctx.query?.referenceId || session.user.id;
|
|
21
72
|
|
|
22
|
-
if
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
73
|
+
// User subscriptions - pass if no explicit referenceId
|
|
74
|
+
if (!explicitReferenceId) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Pass if referenceId is user id
|
|
79
|
+
if (explicitReferenceId === ctxSession.user.id) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (!subscriptionOptions.authorizeReference) {
|
|
26
84
|
ctx.context.logger.error(
|
|
27
85
|
`Passing referenceId into a subscription action isn't allowed if subscription.authorizeReference isn't defined in your stripe plugin config.`,
|
|
28
86
|
);
|
|
29
|
-
throw
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
87
|
+
throw APIError.from(
|
|
88
|
+
"BAD_REQUEST",
|
|
89
|
+
STRIPE_ERROR_CODES.REFERENCE_ID_NOT_ALLOWED,
|
|
90
|
+
);
|
|
33
91
|
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
ctx
|
|
42
|
-
|
|
43
|
-
{
|
|
44
|
-
user: session.user,
|
|
45
|
-
session: session.session,
|
|
46
|
-
referenceId,
|
|
47
|
-
action,
|
|
48
|
-
},
|
|
49
|
-
ctx,
|
|
50
|
-
)) || sameReference
|
|
51
|
-
: true;
|
|
92
|
+
const isAuthorized = await subscriptionOptions.authorizeReference(
|
|
93
|
+
{
|
|
94
|
+
user: ctxSession.user,
|
|
95
|
+
session: ctxSession.session,
|
|
96
|
+
referenceId: explicitReferenceId,
|
|
97
|
+
action,
|
|
98
|
+
},
|
|
99
|
+
ctx,
|
|
100
|
+
);
|
|
52
101
|
if (!isAuthorized) {
|
|
53
|
-
throw
|
|
54
|
-
message: "Unauthorized",
|
|
55
|
-
});
|
|
102
|
+
throw APIError.from("UNAUTHORIZED", STRIPE_ERROR_CODES.UNAUTHORIZED);
|
|
56
103
|
}
|
|
57
104
|
});
|