@vex-chat/spire 2.4.0 → 2.6.0
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/dist/BillingVerification.d.ts +40 -0
- package/dist/BillingVerification.js +535 -0
- package/dist/BillingVerification.js.map +1 -0
- package/dist/Database.d.ts +39 -1
- package/dist/Database.js +285 -2
- package/dist/Database.js.map +1 -1
- package/dist/db/schema.d.ts +50 -0
- package/dist/migrations/2026-06-24_account-entitlements.d.ts +8 -0
- package/dist/migrations/2026-06-24_account-entitlements.js +20 -0
- package/dist/migrations/2026-06-24_account-entitlements.js.map +1 -0
- package/dist/migrations/2026-07-02_store-subscriptions.d.ts +8 -0
- package/dist/migrations/2026-07-02_store-subscriptions.js +83 -0
- package/dist/migrations/2026-07-02_store-subscriptions.js.map +1 -0
- package/dist/server/billing.d.ts +14 -0
- package/dist/server/billing.js +234 -0
- package/dist/server/billing.js.map +1 -0
- package/dist/server/entitlements.d.ts +8 -0
- package/dist/server/entitlements.js +71 -0
- package/dist/server/entitlements.js.map +1 -0
- package/dist/server/index.js +6 -0
- package/dist/server/index.js.map +1 -1
- package/package.json +4 -4
- package/src/BillingVerification.ts +800 -0
- package/src/Database.ts +422 -2
- package/src/__tests__/Database.spec.ts +6 -3
- package/src/__tests__/billing.spec.ts +282 -0
- package/src/__tests__/entitlements.spec.ts +241 -0
- package/src/db/schema.ts +66 -1
- package/src/migrations/2026-06-24_account-entitlements.ts +23 -0
- package/src/migrations/2026-07-02_store-subscriptions.ts +92 -0
- package/src/server/billing.ts +361 -0
- package/src/server/entitlements.ts +104 -0
- package/src/server/index.ts +6 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2020-2026 Vex Heavy Industries LLC
|
|
3
|
+
* Licensed under AGPL-3.0. See LICENSE for details.
|
|
4
|
+
* Commercial licenses available at vex.wtf
|
|
5
|
+
*/
|
|
6
|
+
import type { AppleTransactionVerificationRequest, BillingEnvironment, BillingPlatform, BillingProduct, BillingSubscriptionStatus, GooglePurchaseVerificationRequest } from "@vex-chat/types";
|
|
7
|
+
export interface AppleServerNotificationPayload {
|
|
8
|
+
data?: {
|
|
9
|
+
signedTransactionInfo?: string;
|
|
10
|
+
};
|
|
11
|
+
notificationType?: string;
|
|
12
|
+
}
|
|
13
|
+
export interface GooglePlayPubSubNotificationPayload {
|
|
14
|
+
packageName?: string;
|
|
15
|
+
subscriptionNotification?: {
|
|
16
|
+
purchaseToken: string;
|
|
17
|
+
subscriptionId?: string;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export interface VerifiedStorePurchase {
|
|
21
|
+
environment: BillingEnvironment;
|
|
22
|
+
expiresAt: null | string;
|
|
23
|
+
externalOriginalID: null | string;
|
|
24
|
+
externalTransactionID: null | string;
|
|
25
|
+
platform: BillingPlatform;
|
|
26
|
+
purchaseToken?: string | undefined;
|
|
27
|
+
rawPayload: unknown;
|
|
28
|
+
status: BillingSubscriptionStatus;
|
|
29
|
+
storeProductID: string;
|
|
30
|
+
}
|
|
31
|
+
export declare class BillingVerificationError extends Error {
|
|
32
|
+
readonly status: number;
|
|
33
|
+
constructor(message: string, status?: number);
|
|
34
|
+
}
|
|
35
|
+
export declare function decodeAppleServerNotificationPayload(signedPayload: string): AppleServerNotificationPayload;
|
|
36
|
+
export declare function decodeGooglePlayPubSubNotificationPayload(body: unknown): GooglePlayPubSubNotificationPayload;
|
|
37
|
+
export declare function getBillingProductCatalog(env?: NodeJS.ProcessEnv): BillingProduct[];
|
|
38
|
+
export declare function resolveBillingProduct(purchase: Pick<VerifiedStorePurchase, "environment" | "platform" | "storeProductID">, products?: BillingProduct[]): BillingProduct;
|
|
39
|
+
export declare function verifyAppleTransaction(request: AppleTransactionVerificationRequest, env?: NodeJS.ProcessEnv): Promise<VerifiedStorePurchase>;
|
|
40
|
+
export declare function verifyGooglePurchase(request: GooglePurchaseVerificationRequest, env?: NodeJS.ProcessEnv): Promise<VerifiedStorePurchase>;
|
|
@@ -0,0 +1,535 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2020-2026 Vex Heavy Industries LLC
|
|
3
|
+
* Licensed under AGPL-3.0. See LICENSE for details.
|
|
4
|
+
* Commercial licenses available at vex.wtf
|
|
5
|
+
*/
|
|
6
|
+
import { createSign } from "node:crypto";
|
|
7
|
+
import { BillingEnvironmentSchema, BillingProductSchema, } from "@vex-chat/types";
|
|
8
|
+
export class BillingVerificationError extends Error {
|
|
9
|
+
status;
|
|
10
|
+
constructor(message, status = 400) {
|
|
11
|
+
super(message);
|
|
12
|
+
this.name = "BillingVerificationError";
|
|
13
|
+
this.status = status;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export function decodeAppleServerNotificationPayload(signedPayload) {
|
|
17
|
+
return appleServerNotificationPayloadFromUnknown(decodePossiblySignedPayload(signedPayload));
|
|
18
|
+
}
|
|
19
|
+
export function decodeGooglePlayPubSubNotificationPayload(body) {
|
|
20
|
+
const direct = googleNotificationPayloadFromUnknown(body);
|
|
21
|
+
if (direct) {
|
|
22
|
+
return direct;
|
|
23
|
+
}
|
|
24
|
+
const messageData = stringField(recordField(body, "message"), "data");
|
|
25
|
+
if (!messageData) {
|
|
26
|
+
throw new BillingVerificationError("Google Play notification is missing message.data.");
|
|
27
|
+
}
|
|
28
|
+
const decoded = JSON.parse(Buffer.from(base64UrlToBase64(messageData), "base64").toString("utf8"));
|
|
29
|
+
const notification = googleNotificationPayloadFromUnknown(decoded);
|
|
30
|
+
if (!notification) {
|
|
31
|
+
throw new BillingVerificationError("Google Play notification is missing subscription purchase token.");
|
|
32
|
+
}
|
|
33
|
+
return notification;
|
|
34
|
+
}
|
|
35
|
+
export function getBillingProductCatalog(env = process.env) {
|
|
36
|
+
const rawCatalog = env["VEX_BILLING_PRODUCTS_JSON"]?.trim();
|
|
37
|
+
if (rawCatalog) {
|
|
38
|
+
const parsed = JSON.parse(rawCatalog);
|
|
39
|
+
const products = BillingProductSchema.array().parse(parsed);
|
|
40
|
+
return products;
|
|
41
|
+
}
|
|
42
|
+
const environment = defaultBillingEnvironment(env);
|
|
43
|
+
const products = [];
|
|
44
|
+
const applePlus = env["VEX_APPLE_PLUS_PRODUCT_ID"]?.trim();
|
|
45
|
+
const applePro = env["VEX_APPLE_PRO_PRODUCT_ID"]?.trim();
|
|
46
|
+
const googlePlus = env["VEX_GOOGLE_PLUS_PRODUCT_ID"]?.trim();
|
|
47
|
+
const googlePro = env["VEX_GOOGLE_PRO_PRODUCT_ID"]?.trim();
|
|
48
|
+
if (applePlus) {
|
|
49
|
+
products.push({
|
|
50
|
+
environment,
|
|
51
|
+
platform: "apple_app_store",
|
|
52
|
+
productID: "apple_plus_monthly",
|
|
53
|
+
storeProductID: applePlus,
|
|
54
|
+
tier: "plus",
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
if (applePro) {
|
|
58
|
+
products.push({
|
|
59
|
+
environment,
|
|
60
|
+
platform: "apple_app_store",
|
|
61
|
+
productID: "apple_pro_monthly",
|
|
62
|
+
storeProductID: applePro,
|
|
63
|
+
tier: "pro",
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
if (googlePlus) {
|
|
67
|
+
products.push({
|
|
68
|
+
environment,
|
|
69
|
+
platform: "google_play",
|
|
70
|
+
productID: "google_plus_monthly",
|
|
71
|
+
storeProductID: googlePlus,
|
|
72
|
+
tier: "plus",
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
if (googlePro) {
|
|
76
|
+
products.push({
|
|
77
|
+
environment,
|
|
78
|
+
platform: "google_play",
|
|
79
|
+
productID: "google_pro_monthly",
|
|
80
|
+
storeProductID: googlePro,
|
|
81
|
+
tier: "pro",
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
return products;
|
|
85
|
+
}
|
|
86
|
+
export function resolveBillingProduct(purchase, products = getBillingProductCatalog()) {
|
|
87
|
+
const product = products.find((entry) => entry.platform === purchase.platform &&
|
|
88
|
+
entry.environment === purchase.environment &&
|
|
89
|
+
entry.storeProductID === purchase.storeProductID);
|
|
90
|
+
if (!product) {
|
|
91
|
+
throw new BillingVerificationError(`No billing product configured for ${purchase.platform}/${purchase.environment}/${purchase.storeProductID}.`, 422);
|
|
92
|
+
}
|
|
93
|
+
return product;
|
|
94
|
+
}
|
|
95
|
+
export async function verifyAppleTransaction(request, env = process.env) {
|
|
96
|
+
const requestedEnvironment = request.environment ?? defaultBillingEnvironment(env);
|
|
97
|
+
let signedTransactionInfo = request.signedTransactionInfo;
|
|
98
|
+
const transactionID = request.transactionID ??
|
|
99
|
+
(signedTransactionInfo
|
|
100
|
+
? decodeAppleTransactionPayload(signedTransactionInfo).transactionId
|
|
101
|
+
: undefined);
|
|
102
|
+
if (appleCredentialsConfigured(env) && transactionID) {
|
|
103
|
+
signedTransactionInfo = await fetchAppleSignedTransactionInfo(transactionID, requestedEnvironment, env);
|
|
104
|
+
}
|
|
105
|
+
else if (!allowLocalStorePayloads(env)) {
|
|
106
|
+
throw new BillingVerificationError("Apple transaction verification is not configured.", 503);
|
|
107
|
+
}
|
|
108
|
+
if (!signedTransactionInfo) {
|
|
109
|
+
throw new BillingVerificationError("Apple transaction verification did not return transaction info.");
|
|
110
|
+
}
|
|
111
|
+
const payload = decodeAppleTransactionPayload(signedTransactionInfo);
|
|
112
|
+
const environment = normalizeAppleEnvironment(payload.environment, requestedEnvironment);
|
|
113
|
+
const storeProductID = payload.productId;
|
|
114
|
+
if (!storeProductID) {
|
|
115
|
+
throw new BillingVerificationError("Apple transaction payload is missing productId.");
|
|
116
|
+
}
|
|
117
|
+
const expiresAt = normalizeExpiry(payload.expiresDate);
|
|
118
|
+
const status = subscriptionStatusFromExpiry({
|
|
119
|
+
expiresAt,
|
|
120
|
+
revoked: payload.revocationDate !== undefined,
|
|
121
|
+
});
|
|
122
|
+
return {
|
|
123
|
+
environment,
|
|
124
|
+
expiresAt,
|
|
125
|
+
externalOriginalID: payload.originalTransactionId ?? null,
|
|
126
|
+
externalTransactionID: payload.transactionId ?? transactionID ?? null,
|
|
127
|
+
platform: "apple_app_store",
|
|
128
|
+
rawPayload: payload,
|
|
129
|
+
status,
|
|
130
|
+
storeProductID,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
export async function verifyGooglePurchase(request, env = process.env) {
|
|
134
|
+
let response;
|
|
135
|
+
if (googleCredentialsConfigured(env)) {
|
|
136
|
+
response = await fetchGoogleSubscriptionV2(request, env);
|
|
137
|
+
}
|
|
138
|
+
else if (allowLocalStorePayloads(env)) {
|
|
139
|
+
response = decodeLocalGooglePurchaseToken(request.purchaseToken);
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
throw new BillingVerificationError("Google Play purchase verification is not configured.", 503);
|
|
143
|
+
}
|
|
144
|
+
const lineItem = response.lineItems?.[0];
|
|
145
|
+
const storeProductID = lineItem?.productId ?? request.productID;
|
|
146
|
+
if (!storeProductID) {
|
|
147
|
+
throw new BillingVerificationError("Google Play subscription response is missing productId.");
|
|
148
|
+
}
|
|
149
|
+
const expiresAt = normalizeExpiry(lineItem?.expiryTime ?? null);
|
|
150
|
+
const environment = request.environment ??
|
|
151
|
+
(response.testPurchase ? "sandbox" : defaultBillingEnvironment(env));
|
|
152
|
+
return {
|
|
153
|
+
environment,
|
|
154
|
+
expiresAt,
|
|
155
|
+
externalOriginalID: response.latestOrderId ?? null,
|
|
156
|
+
externalTransactionID: response.latestOrderId ?? null,
|
|
157
|
+
platform: "google_play",
|
|
158
|
+
purchaseToken: request.purchaseToken,
|
|
159
|
+
rawPayload: response,
|
|
160
|
+
status: mapGoogleSubscriptionState(response.subscriptionState, expiresAt),
|
|
161
|
+
storeProductID,
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
function allowLocalStorePayloads(env) {
|
|
165
|
+
return (env["NODE_ENV"] !== "production" &&
|
|
166
|
+
env["VEX_BILLING_ALLOW_LOCAL_STORE_PAYLOADS"] === "1");
|
|
167
|
+
}
|
|
168
|
+
function appleCredentialsConfigured(env) {
|
|
169
|
+
return Boolean(env["APPLE_APP_STORE_ISSUER_ID"]?.trim() &&
|
|
170
|
+
env["APPLE_APP_STORE_KEY_ID"]?.trim() &&
|
|
171
|
+
env["APPLE_APP_STORE_PRIVATE_KEY"]?.trim() &&
|
|
172
|
+
env["APPLE_APP_BUNDLE_ID"]?.trim());
|
|
173
|
+
}
|
|
174
|
+
function appleServerNotificationPayloadFromUnknown(value) {
|
|
175
|
+
const data = recordField(value, "data");
|
|
176
|
+
const signedTransactionInfo = stringField(data, "signedTransactionInfo");
|
|
177
|
+
return {
|
|
178
|
+
...(signedTransactionInfo ? { data: { signedTransactionInfo } } : {}),
|
|
179
|
+
...stringObjectField(value, "notificationType"),
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
function appleTransactionPayloadFromUnknown(value) {
|
|
183
|
+
return {
|
|
184
|
+
...stringObjectField(value, "environment"),
|
|
185
|
+
...numberOrStringObjectField(value, "expiresDate"),
|
|
186
|
+
...stringObjectField(value, "originalTransactionId"),
|
|
187
|
+
...stringObjectField(value, "productId"),
|
|
188
|
+
...numberOrStringObjectField(value, "revocationDate"),
|
|
189
|
+
...stringObjectField(value, "transactionId"),
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
function base64Url(input) {
|
|
193
|
+
return Buffer.from(input)
|
|
194
|
+
.toString("base64")
|
|
195
|
+
.replace(/=/g, "")
|
|
196
|
+
.replace(/\+/g, "-")
|
|
197
|
+
.replace(/\//g, "_");
|
|
198
|
+
}
|
|
199
|
+
function base64UrlToBase64(input) {
|
|
200
|
+
const normalized = input.replace(/-/g, "+").replace(/_/g, "/");
|
|
201
|
+
const padding = normalized.length % 4;
|
|
202
|
+
return padding === 0 ? normalized : normalized + "=".repeat(4 - padding);
|
|
203
|
+
}
|
|
204
|
+
function createAppleServerApiJwt(env) {
|
|
205
|
+
const issuerID = requiredEnv(env, "APPLE_APP_STORE_ISSUER_ID");
|
|
206
|
+
const keyID = requiredEnv(env, "APPLE_APP_STORE_KEY_ID");
|
|
207
|
+
const bundleID = requiredEnv(env, "APPLE_APP_BUNDLE_ID");
|
|
208
|
+
const privateKey = normalizePrivateKey(requiredEnv(env, "APPLE_APP_STORE_PRIVATE_KEY"));
|
|
209
|
+
const iat = Math.floor(Date.now() / 1000);
|
|
210
|
+
const header = {
|
|
211
|
+
alg: "ES256",
|
|
212
|
+
kid: keyID,
|
|
213
|
+
typ: "JWT",
|
|
214
|
+
};
|
|
215
|
+
const payload = {
|
|
216
|
+
aud: "appstoreconnect-v1",
|
|
217
|
+
bid: bundleID,
|
|
218
|
+
exp: iat + 900,
|
|
219
|
+
iat,
|
|
220
|
+
iss: issuerID,
|
|
221
|
+
};
|
|
222
|
+
const signingInput = `${base64Url(JSON.stringify(header))}.${base64Url(JSON.stringify(payload))}`;
|
|
223
|
+
const signature = createSign("SHA256")
|
|
224
|
+
.update(signingInput)
|
|
225
|
+
.end()
|
|
226
|
+
.sign(privateKey);
|
|
227
|
+
return `${signingInput}.${base64Url(derEcdsaToJose(signature, 32))}`;
|
|
228
|
+
}
|
|
229
|
+
function decodeAppleTransactionPayload(signedTransactionInfo) {
|
|
230
|
+
return appleTransactionPayloadFromUnknown(decodePossiblySignedPayload(signedTransactionInfo));
|
|
231
|
+
}
|
|
232
|
+
function decodeLocalGooglePurchaseToken(purchaseToken) {
|
|
233
|
+
return googleSubscriptionV2ResponseFromUnknown(decodePossiblySignedPayload(purchaseToken));
|
|
234
|
+
}
|
|
235
|
+
function decodePossiblySignedPayload(value) {
|
|
236
|
+
const payload = value.includes(".") ? value.split(".")[1] : value;
|
|
237
|
+
if (!payload) {
|
|
238
|
+
throw new BillingVerificationError("Invalid encoded billing payload.");
|
|
239
|
+
}
|
|
240
|
+
try {
|
|
241
|
+
return JSON.parse(Buffer.from(base64UrlToBase64(payload), "base64").toString("utf8"));
|
|
242
|
+
}
|
|
243
|
+
catch {
|
|
244
|
+
try {
|
|
245
|
+
return JSON.parse(value);
|
|
246
|
+
}
|
|
247
|
+
catch {
|
|
248
|
+
throw new BillingVerificationError("Billing payload could not be decoded.");
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
function defaultBillingEnvironment(env) {
|
|
253
|
+
const parsed = BillingEnvironmentSchema.safeParse(env["VEX_BILLING_ENVIRONMENT"]);
|
|
254
|
+
return parsed.success ? parsed.data : "production";
|
|
255
|
+
}
|
|
256
|
+
function derEcdsaToJose(signature, partLength) {
|
|
257
|
+
let offset = 0;
|
|
258
|
+
if (signature[offset++] !== 0x30) {
|
|
259
|
+
throw new BillingVerificationError("Invalid ECDSA DER signature.", 500);
|
|
260
|
+
}
|
|
261
|
+
const sequenceLength = readDerLength(signature, offset);
|
|
262
|
+
offset = sequenceLength.offset;
|
|
263
|
+
if (signature[offset++] !== 0x02) {
|
|
264
|
+
throw new BillingVerificationError("Invalid ECDSA DER signature.", 500);
|
|
265
|
+
}
|
|
266
|
+
const rLength = readDerLength(signature, offset);
|
|
267
|
+
offset = rLength.offset;
|
|
268
|
+
const r = signature.subarray(offset, offset + rLength.length);
|
|
269
|
+
offset += rLength.length;
|
|
270
|
+
if (signature[offset++] !== 0x02) {
|
|
271
|
+
throw new BillingVerificationError("Invalid ECDSA DER signature.", 500);
|
|
272
|
+
}
|
|
273
|
+
const sLength = readDerLength(signature, offset);
|
|
274
|
+
offset = sLength.offset;
|
|
275
|
+
const s = signature.subarray(offset, offset + sLength.length);
|
|
276
|
+
return Buffer.concat([
|
|
277
|
+
leftPadUnsignedInteger(r, partLength),
|
|
278
|
+
leftPadUnsignedInteger(s, partLength),
|
|
279
|
+
]);
|
|
280
|
+
}
|
|
281
|
+
async function fetchAppleSignedTransactionInfo(transactionID, environment, env) {
|
|
282
|
+
const token = createAppleServerApiJwt(env);
|
|
283
|
+
const host = environment === "sandbox"
|
|
284
|
+
? "https://api.storekit-sandbox.itunes.apple.com"
|
|
285
|
+
: "https://api.storekit.itunes.apple.com";
|
|
286
|
+
const res = await fetch(`${host}/inApps/v1/transactions/${encodeURIComponent(transactionID)}`, {
|
|
287
|
+
headers: {
|
|
288
|
+
Authorization: `Bearer ${token}`,
|
|
289
|
+
},
|
|
290
|
+
});
|
|
291
|
+
if (!res.ok) {
|
|
292
|
+
throw new BillingVerificationError(`Apple transaction verification failed with HTTP ${String(res.status)}.`, 502);
|
|
293
|
+
}
|
|
294
|
+
const body = await res.json();
|
|
295
|
+
const signedTransactionInfo = stringField(body, "signedTransactionInfo");
|
|
296
|
+
if (!signedTransactionInfo) {
|
|
297
|
+
throw new BillingVerificationError("Apple transaction response is missing signedTransactionInfo.", 502);
|
|
298
|
+
}
|
|
299
|
+
return signedTransactionInfo;
|
|
300
|
+
}
|
|
301
|
+
function fetchFormBody(params) {
|
|
302
|
+
return new URLSearchParams(params).toString();
|
|
303
|
+
}
|
|
304
|
+
async function fetchGoogleAccessToken(account) {
|
|
305
|
+
const iat = Math.floor(Date.now() / 1000);
|
|
306
|
+
const signingInput = `${base64Url(JSON.stringify({ alg: "RS256", typ: "JWT" }))}.${base64Url(JSON.stringify({
|
|
307
|
+
aud: "https://oauth2.googleapis.com/token",
|
|
308
|
+
exp: iat + 3600,
|
|
309
|
+
iat,
|
|
310
|
+
iss: account.client_email,
|
|
311
|
+
scope: "https://www.googleapis.com/auth/androidpublisher",
|
|
312
|
+
}))}`;
|
|
313
|
+
const signature = createSign("RSA-SHA256")
|
|
314
|
+
.update(signingInput)
|
|
315
|
+
.end()
|
|
316
|
+
.sign(normalizePrivateKey(account.private_key));
|
|
317
|
+
const assertion = `${signingInput}.${base64Url(signature)}`;
|
|
318
|
+
const res = await fetch("https://oauth2.googleapis.com/token", {
|
|
319
|
+
body: fetchFormBody({
|
|
320
|
+
assertion,
|
|
321
|
+
grant_type: "urn:ietf:params:oauth:grant-type:jwt-bearer",
|
|
322
|
+
}),
|
|
323
|
+
headers: {
|
|
324
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
325
|
+
},
|
|
326
|
+
method: "POST",
|
|
327
|
+
});
|
|
328
|
+
if (!res.ok) {
|
|
329
|
+
throw new BillingVerificationError(`Google OAuth failed with HTTP ${String(res.status)}.`, 502);
|
|
330
|
+
}
|
|
331
|
+
const body = await res.json();
|
|
332
|
+
const accessToken = stringField(body, "access_token");
|
|
333
|
+
if (!accessToken) {
|
|
334
|
+
throw new BillingVerificationError("Google OAuth response is missing access_token.", 502);
|
|
335
|
+
}
|
|
336
|
+
return accessToken;
|
|
337
|
+
}
|
|
338
|
+
async function fetchGoogleSubscriptionV2(request, env) {
|
|
339
|
+
const packageName = request.packageName ?? requiredEnv(env, "GOOGLE_PLAY_PACKAGE_NAME");
|
|
340
|
+
const account = googleServiceAccount(env);
|
|
341
|
+
const accessToken = await fetchGoogleAccessToken(account);
|
|
342
|
+
const url = "https://androidpublisher.googleapis.com/androidpublisher/v3/applications/" +
|
|
343
|
+
encodeURIComponent(packageName) +
|
|
344
|
+
"/purchases/subscriptionsv2/tokens/" +
|
|
345
|
+
encodeURIComponent(request.purchaseToken);
|
|
346
|
+
const res = await fetch(url, {
|
|
347
|
+
headers: {
|
|
348
|
+
Authorization: `Bearer ${accessToken}`,
|
|
349
|
+
},
|
|
350
|
+
});
|
|
351
|
+
if (!res.ok) {
|
|
352
|
+
throw new BillingVerificationError(`Google Play verification failed with HTTP ${String(res.status)}.`, 502);
|
|
353
|
+
}
|
|
354
|
+
return googleSubscriptionV2ResponseFromUnknown(await res.json());
|
|
355
|
+
}
|
|
356
|
+
function googleCredentialsConfigured(env) {
|
|
357
|
+
if (env["GOOGLE_PLAY_SERVICE_ACCOUNT_JSON"]?.trim()) {
|
|
358
|
+
return Boolean(env["GOOGLE_PLAY_PACKAGE_NAME"]?.trim());
|
|
359
|
+
}
|
|
360
|
+
return Boolean(env["GOOGLE_PLAY_CLIENT_EMAIL"]?.trim() &&
|
|
361
|
+
env["GOOGLE_PLAY_PRIVATE_KEY"]?.trim() &&
|
|
362
|
+
env["GOOGLE_PLAY_PACKAGE_NAME"]?.trim());
|
|
363
|
+
}
|
|
364
|
+
function googleNotificationPayloadFromUnknown(value) {
|
|
365
|
+
const subscriptionNotification = recordField(value, "subscriptionNotification");
|
|
366
|
+
const purchaseToken = stringField(subscriptionNotification, "purchaseToken");
|
|
367
|
+
if (!purchaseToken) {
|
|
368
|
+
return null;
|
|
369
|
+
}
|
|
370
|
+
return {
|
|
371
|
+
...stringObjectField(value, "packageName"),
|
|
372
|
+
subscriptionNotification: {
|
|
373
|
+
purchaseToken,
|
|
374
|
+
...stringObjectField(subscriptionNotification, "subscriptionId"),
|
|
375
|
+
},
|
|
376
|
+
};
|
|
377
|
+
}
|
|
378
|
+
function googleServiceAccount(env) {
|
|
379
|
+
const raw = env["GOOGLE_PLAY_SERVICE_ACCOUNT_JSON"]?.trim();
|
|
380
|
+
if (raw) {
|
|
381
|
+
const parsed = JSON.parse(raw);
|
|
382
|
+
const clientEmail = stringField(parsed, "client_email");
|
|
383
|
+
const privateKey = stringField(parsed, "private_key");
|
|
384
|
+
if (clientEmail && privateKey) {
|
|
385
|
+
return {
|
|
386
|
+
client_email: clientEmail,
|
|
387
|
+
private_key: privateKey,
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
return {
|
|
392
|
+
client_email: requiredEnv(env, "GOOGLE_PLAY_CLIENT_EMAIL"),
|
|
393
|
+
private_key: requiredEnv(env, "GOOGLE_PLAY_PRIVATE_KEY"),
|
|
394
|
+
};
|
|
395
|
+
}
|
|
396
|
+
function googleSubscriptionV2ResponseFromUnknown(value) {
|
|
397
|
+
const lineItemsValue = isRecord(value) ? value["lineItems"] : undefined;
|
|
398
|
+
const lineItems = Array.isArray(lineItemsValue)
|
|
399
|
+
? lineItemsValue.flatMap((item) => {
|
|
400
|
+
if (!isRecord(item)) {
|
|
401
|
+
return [];
|
|
402
|
+
}
|
|
403
|
+
return [
|
|
404
|
+
{
|
|
405
|
+
...stringObjectField(item, "expiryTime"),
|
|
406
|
+
...stringObjectField(item, "productId"),
|
|
407
|
+
},
|
|
408
|
+
];
|
|
409
|
+
})
|
|
410
|
+
: undefined;
|
|
411
|
+
return {
|
|
412
|
+
...stringObjectField(value, "acknowledgementState"),
|
|
413
|
+
...stringObjectField(value, "latestOrderId"),
|
|
414
|
+
...(lineItems && lineItems.length > 0 ? { lineItems } : {}),
|
|
415
|
+
...stringObjectField(value, "subscriptionState"),
|
|
416
|
+
...(recordField(value, "testPurchase") ? { testPurchase: {} } : {}),
|
|
417
|
+
};
|
|
418
|
+
}
|
|
419
|
+
function isRecord(value) {
|
|
420
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
421
|
+
}
|
|
422
|
+
function leftPadUnsignedInteger(value, length) {
|
|
423
|
+
const trimmed = value[0] === 0 ? value.subarray(1) : value;
|
|
424
|
+
if (trimmed.length > length) {
|
|
425
|
+
return trimmed.subarray(trimmed.length - length);
|
|
426
|
+
}
|
|
427
|
+
if (trimmed.length === length) {
|
|
428
|
+
return trimmed;
|
|
429
|
+
}
|
|
430
|
+
return Buffer.concat([Buffer.alloc(length - trimmed.length), trimmed]);
|
|
431
|
+
}
|
|
432
|
+
function mapGoogleSubscriptionState(state, expiresAt) {
|
|
433
|
+
switch (state) {
|
|
434
|
+
case "SUBSCRIPTION_STATE_ACTIVE":
|
|
435
|
+
return "active";
|
|
436
|
+
case "SUBSCRIPTION_STATE_CANCELED":
|
|
437
|
+
return subscriptionStatusFromExpiry({ expiresAt, revoked: false });
|
|
438
|
+
case "SUBSCRIPTION_STATE_EXPIRED":
|
|
439
|
+
return "expired";
|
|
440
|
+
case "SUBSCRIPTION_STATE_IN_GRACE_PERIOD":
|
|
441
|
+
return "grace_period";
|
|
442
|
+
case "SUBSCRIPTION_STATE_ON_HOLD":
|
|
443
|
+
return "billing_retry";
|
|
444
|
+
case "SUBSCRIPTION_STATE_PAUSED":
|
|
445
|
+
case "SUBSCRIPTION_STATE_PENDING":
|
|
446
|
+
case "SUBSCRIPTION_STATE_UNSPECIFIED":
|
|
447
|
+
default:
|
|
448
|
+
return "pending";
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
function normalizeAppleEnvironment(value, fallback) {
|
|
452
|
+
if (value === "Sandbox") {
|
|
453
|
+
return "sandbox";
|
|
454
|
+
}
|
|
455
|
+
if (value === "Production") {
|
|
456
|
+
return "production";
|
|
457
|
+
}
|
|
458
|
+
const parsed = BillingEnvironmentSchema.safeParse(value);
|
|
459
|
+
return parsed.success ? parsed.data : fallback;
|
|
460
|
+
}
|
|
461
|
+
function normalizeExpiry(value) {
|
|
462
|
+
if (value === null || value === undefined || value === "") {
|
|
463
|
+
return null;
|
|
464
|
+
}
|
|
465
|
+
if (typeof value === "number") {
|
|
466
|
+
return new Date(value).toISOString();
|
|
467
|
+
}
|
|
468
|
+
if (/^\d+$/.test(value)) {
|
|
469
|
+
return new Date(Number(value)).toISOString();
|
|
470
|
+
}
|
|
471
|
+
const parsed = Date.parse(value);
|
|
472
|
+
return Number.isFinite(parsed) ? new Date(parsed).toISOString() : null;
|
|
473
|
+
}
|
|
474
|
+
function normalizePrivateKey(value) {
|
|
475
|
+
return value.replace(/\\n/g, "\n");
|
|
476
|
+
}
|
|
477
|
+
function numberOrStringObjectField(value, field) {
|
|
478
|
+
const recordValue = isRecord(value) ? value[field] : undefined;
|
|
479
|
+
return typeof recordValue === "string" || typeof recordValue === "number"
|
|
480
|
+
? { [field]: recordValue }
|
|
481
|
+
: {};
|
|
482
|
+
}
|
|
483
|
+
function readDerLength(input, offset) {
|
|
484
|
+
const first = input[offset++];
|
|
485
|
+
if (first === undefined) {
|
|
486
|
+
throw new BillingVerificationError("Invalid DER length.", 500);
|
|
487
|
+
}
|
|
488
|
+
if (first < 0x80) {
|
|
489
|
+
return { length: first, offset };
|
|
490
|
+
}
|
|
491
|
+
const byteCount = first & 0x7f;
|
|
492
|
+
let length = 0;
|
|
493
|
+
for (let i = 0; i < byteCount; i++) {
|
|
494
|
+
const byte = input[offset++];
|
|
495
|
+
if (byte === undefined) {
|
|
496
|
+
throw new BillingVerificationError("Invalid DER length.", 500);
|
|
497
|
+
}
|
|
498
|
+
length = (length << 8) | byte;
|
|
499
|
+
}
|
|
500
|
+
return { length, offset };
|
|
501
|
+
}
|
|
502
|
+
function recordField(value, field) {
|
|
503
|
+
const recordValue = isRecord(value) ? value[field] : undefined;
|
|
504
|
+
return isRecord(recordValue) ? recordValue : undefined;
|
|
505
|
+
}
|
|
506
|
+
function requiredEnv(env, key) {
|
|
507
|
+
const value = env[key]?.trim();
|
|
508
|
+
if (!value) {
|
|
509
|
+
throw new BillingVerificationError(`Missing required billing environment variable ${key}.`, 503);
|
|
510
|
+
}
|
|
511
|
+
return value;
|
|
512
|
+
}
|
|
513
|
+
function stringField(value, field) {
|
|
514
|
+
const recordValue = isRecord(value) ? value[field] : undefined;
|
|
515
|
+
return typeof recordValue === "string" && recordValue.length > 0
|
|
516
|
+
? recordValue
|
|
517
|
+
: undefined;
|
|
518
|
+
}
|
|
519
|
+
function stringObjectField(value, field) {
|
|
520
|
+
const recordValue = stringField(value, field);
|
|
521
|
+
return recordValue ? { [field]: recordValue } : {};
|
|
522
|
+
}
|
|
523
|
+
function subscriptionStatusFromExpiry(args) {
|
|
524
|
+
if (args.revoked) {
|
|
525
|
+
return "revoked";
|
|
526
|
+
}
|
|
527
|
+
if (!args.expiresAt) {
|
|
528
|
+
return "active";
|
|
529
|
+
}
|
|
530
|
+
const expiresAtMs = Date.parse(args.expiresAt);
|
|
531
|
+
return Number.isFinite(expiresAtMs) && expiresAtMs > Date.now()
|
|
532
|
+
? "active"
|
|
533
|
+
: "expired";
|
|
534
|
+
}
|
|
535
|
+
//# sourceMappingURL=BillingVerification.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BillingVerification.js","sourceRoot":"","sources":["../src/BillingVerification.ts"],"names":[],"mappings":"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"}
|