@onesub/server 0.13.1 → 0.14.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/index.cjs +26 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +26 -4
- package/dist/index.js.map +1 -1
- package/dist/providers/apple.d.ts +8 -0
- package/dist/providers/apple.d.ts.map +1 -1
- package/dist/providers/google.d.ts +8 -0
- package/dist/providers/google.d.ts.map +1 -1
- package/dist/providers/mock.d.ts +2 -0
- package/dist/providers/mock.d.ts.map +1 -1
- package/dist/routes/purchase.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -255,10 +255,12 @@ function mockValidateAppleProduct(receipt, expectedProductId) {
|
|
|
255
255
|
const outcome = classifyMockReceipt(receipt);
|
|
256
256
|
if (!outcomePasses(outcome, "apple")) return null;
|
|
257
257
|
const productId = expectedProductId ?? "mock_product";
|
|
258
|
+
const tokenMatch = receipt.match(/#token=([^#]+)/);
|
|
258
259
|
return {
|
|
259
260
|
transactionId: deterministicTransactionId(`mock_apple_${productId}`, receipt),
|
|
260
261
|
productId,
|
|
261
|
-
purchasedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
262
|
+
purchasedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
263
|
+
...tokenMatch ? { appAccountToken: tokenMatch[1] } : {}
|
|
262
264
|
};
|
|
263
265
|
}
|
|
264
266
|
function mockValidateGoogleSubscription(receipt, productId) {
|
|
@@ -280,9 +282,11 @@ function mockValidateGoogleSubscription(receipt, productId) {
|
|
|
280
282
|
function mockValidateGoogleProduct(receipt, productId) {
|
|
281
283
|
const outcome = classifyMockReceipt(receipt);
|
|
282
284
|
if (!outcomePasses(outcome, "google")) return null;
|
|
285
|
+
const tokenMatch = receipt.match(/#token=([^#]+)/);
|
|
283
286
|
return {
|
|
284
287
|
transactionId: deterministicTransactionId(`mock_google_${productId}`, receipt),
|
|
285
|
-
purchasedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
288
|
+
purchasedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
289
|
+
...tokenMatch ? { obfuscatedExternalAccountId: tokenMatch[1] } : {}
|
|
286
290
|
};
|
|
287
291
|
}
|
|
288
292
|
|
|
@@ -446,7 +450,8 @@ async function validateAppleConsumableReceipt(signedTransaction, config, expecte
|
|
|
446
450
|
return {
|
|
447
451
|
transactionId,
|
|
448
452
|
productId: tx.productId,
|
|
449
|
-
purchasedAt: tx.purchaseDate ? new Date(tx.purchaseDate).toISOString() : (/* @__PURE__ */ new Date()).toISOString()
|
|
453
|
+
purchasedAt: tx.purchaseDate ? new Date(tx.purchaseDate).toISOString() : (/* @__PURE__ */ new Date()).toISOString(),
|
|
454
|
+
appAccountToken: tx.appAccountToken ?? void 0
|
|
450
455
|
};
|
|
451
456
|
}
|
|
452
457
|
async function decodeAppleNotification(payload, skipJwsVerification = false) {
|
|
@@ -1005,7 +1010,8 @@ async function validateGoogleProductReceipt(purchaseToken, productId, config, ty
|
|
|
1005
1010
|
}
|
|
1006
1011
|
return {
|
|
1007
1012
|
transactionId: purchase.orderId,
|
|
1008
|
-
purchasedAt: purchase.purchaseTimeMillis ? new Date(parseInt(purchase.purchaseTimeMillis, 10)).toISOString() : (/* @__PURE__ */ new Date()).toISOString()
|
|
1013
|
+
purchasedAt: purchase.purchaseTimeMillis ? new Date(parseInt(purchase.purchaseTimeMillis, 10)).toISOString() : (/* @__PURE__ */ new Date()).toISOString(),
|
|
1014
|
+
obfuscatedExternalAccountId: purchase.obfuscatedExternalAccountId
|
|
1009
1015
|
};
|
|
1010
1016
|
}
|
|
1011
1017
|
function decodeGoogleNotification(payload) {
|
|
@@ -1551,6 +1557,7 @@ function createPurchaseRouter(config, purchaseStore) {
|
|
|
1551
1557
|
}
|
|
1552
1558
|
let transactionId = null;
|
|
1553
1559
|
let purchasedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
1560
|
+
let boundAccountId = null;
|
|
1554
1561
|
if (platform === "apple") {
|
|
1555
1562
|
if (!config.apple) {
|
|
1556
1563
|
sendError(res, 500, shared.ONESUB_ERROR_CODE.APPLE_CONFIG_MISSING, "Apple configuration not provided", NO_PURCHASE);
|
|
@@ -1560,6 +1567,7 @@ function createPurchaseRouter(config, purchaseStore) {
|
|
|
1560
1567
|
if (result) {
|
|
1561
1568
|
transactionId = result.transactionId;
|
|
1562
1569
|
purchasedAt = result.purchasedAt;
|
|
1570
|
+
boundAccountId = result.appAccountToken ?? null;
|
|
1563
1571
|
}
|
|
1564
1572
|
} else {
|
|
1565
1573
|
if (!config.google) {
|
|
@@ -1575,12 +1583,26 @@ function createPurchaseRouter(config, purchaseStore) {
|
|
|
1575
1583
|
if (result) {
|
|
1576
1584
|
transactionId = result.transactionId;
|
|
1577
1585
|
purchasedAt = result.purchasedAt;
|
|
1586
|
+
boundAccountId = result.obfuscatedExternalAccountId ?? null;
|
|
1578
1587
|
}
|
|
1579
1588
|
}
|
|
1580
1589
|
if (!transactionId) {
|
|
1581
1590
|
sendError(res, 422, shared.ONESUB_ERROR_CODE.RECEIPT_VALIDATION_FAILED, "Receipt validation failed", NO_PURCHASE);
|
|
1582
1591
|
return;
|
|
1583
1592
|
}
|
|
1593
|
+
if (boundAccountId && boundAccountId.toLowerCase() !== userId.toLowerCase()) {
|
|
1594
|
+
log.warn(
|
|
1595
|
+
`[onesub/purchase] account binding mismatch for transaction ${transactionId}: token does not match userId ${userId}`
|
|
1596
|
+
);
|
|
1597
|
+
sendError(
|
|
1598
|
+
res,
|
|
1599
|
+
409,
|
|
1600
|
+
shared.ONESUB_ERROR_CODE.TRANSACTION_BELONGS_TO_OTHER_USER,
|
|
1601
|
+
"TRANSACTION_BELONGS_TO_OTHER_USER",
|
|
1602
|
+
NO_PURCHASE
|
|
1603
|
+
);
|
|
1604
|
+
return;
|
|
1605
|
+
}
|
|
1584
1606
|
const existing = await purchaseStore.getPurchaseByTransactionId(transactionId);
|
|
1585
1607
|
let action = "new";
|
|
1586
1608
|
if (existing) {
|