@onesub/server 0.11.4 → 0.12.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 +119 -2
- package/dist/__tests__/cache.test.d.ts +2 -0
- package/dist/__tests__/cache.test.d.ts.map +1 -0
- package/dist/__tests__/openapi.test.d.ts +2 -0
- package/dist/__tests__/openapi.test.d.ts.map +1 -0
- package/dist/__tests__/redis-store.test.d.ts +2 -0
- package/dist/__tests__/redis-store.test.d.ts.map +1 -0
- package/dist/__tests__/webhook-apple.test.d.ts +12 -0
- package/dist/__tests__/webhook-apple.test.d.ts.map +1 -0
- package/dist/__tests__/webhook-events.test.d.ts +2 -0
- package/dist/__tests__/webhook-events.test.d.ts.map +1 -0
- package/dist/__tests__/webhook-google.test.d.ts +13 -0
- package/dist/__tests__/webhook-google.test.d.ts.map +1 -0
- package/dist/__tests__/webhook-queue.test.d.ts +2 -0
- package/dist/__tests__/webhook-queue.test.d.ts.map +1 -0
- package/dist/cache.d.ts +32 -0
- package/dist/cache.d.ts.map +1 -0
- package/dist/index.cjs +3084 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +34 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3045 -118
- package/dist/index.js.map +1 -1
- package/dist/openapi.d.ts +41 -0
- package/dist/openapi.d.ts.map +1 -0
- package/dist/providers/apple.d.ts +1 -1
- package/dist/providers/apple.d.ts.map +1 -1
- package/dist/providers/google.d.ts.map +1 -1
- package/dist/routes/admin.d.ts +2 -1
- package/dist/routes/admin.d.ts.map +1 -1
- package/dist/routes/webhook-apple.d.ts +6 -0
- package/dist/routes/webhook-apple.d.ts.map +1 -0
- package/dist/routes/webhook-google.d.ts +7 -0
- package/dist/routes/webhook-google.d.ts.map +1 -0
- package/dist/routes/webhook.d.ts +6 -18
- package/dist/routes/webhook.d.ts.map +1 -1
- package/dist/stores/redis.d.ts +60 -0
- package/dist/stores/redis.d.ts.map +1 -0
- package/dist/stores/schema.d.ts.map +1 -1
- package/dist/tracing.d.ts +32 -0
- package/dist/tracing.d.ts.map +1 -0
- package/dist/webhook-events.d.ts +58 -0
- package/dist/webhook-events.d.ts.map +1 -0
- package/dist/webhook-queue.d.ts +92 -0
- package/dist/webhook-queue.d.ts.map +1 -0
- package/package.json +33 -4
- package/sql/schema.sql +10 -0
- package/dist/__tests__/admin-customer-detail.test.js +0 -146
- package/dist/__tests__/admin-customer-detail.test.js.map +0 -1
- package/dist/__tests__/admin-list-subscriptions.test.js +0 -192
- package/dist/__tests__/admin-list-subscriptions.test.js.map +0 -1
- package/dist/__tests__/admin-subscription-detail.test.js +0 -112
- package/dist/__tests__/admin-subscription-detail.test.js.map +0 -1
- package/dist/__tests__/apple-root-ca.test.js +0 -41
- package/dist/__tests__/apple-root-ca.test.js.map +0 -1
- package/dist/__tests__/apple-status-api.test.js +0 -345
- package/dist/__tests__/apple-status-api.test.js.map +0 -1
- package/dist/__tests__/entitlements.test.js +0 -268
- package/dist/__tests__/entitlements.test.js.map +0 -1
- package/dist/__tests__/error-codes.test.js +0 -168
- package/dist/__tests__/error-codes.test.js.map +0 -1
- package/dist/__tests__/fetch-hardening.test.js +0 -192
- package/dist/__tests__/fetch-hardening.test.js.map +0 -1
- package/dist/__tests__/google-paused.test.js +0 -126
- package/dist/__tests__/google-paused.test.js.map +0 -1
- package/dist/__tests__/google-price-change.test.js +0 -186
- package/dist/__tests__/google-price-change.test.js.map +0 -1
- package/dist/__tests__/google-subscriptions-v2.test.js +0 -206
- package/dist/__tests__/google-subscriptions-v2.test.js.map +0 -1
- package/dist/__tests__/lifecycle-scenarios.test.js +0 -579
- package/dist/__tests__/lifecycle-scenarios.test.js.map +0 -1
- package/dist/__tests__/lifecycle-states.test.js +0 -423
- package/dist/__tests__/lifecycle-states.test.js.map +0 -1
- package/dist/__tests__/linked-purchase-token.test.js +0 -227
- package/dist/__tests__/linked-purchase-token.test.js.map +0 -1
- package/dist/__tests__/metrics.test.js +0 -340
- package/dist/__tests__/metrics.test.js.map +0 -1
- package/dist/__tests__/mock-provider.test.js +0 -188
- package/dist/__tests__/mock-provider.test.js.map +0 -1
- package/dist/__tests__/paused-auto-resume.test.js +0 -162
- package/dist/__tests__/paused-auto-resume.test.js.map +0 -1
- package/dist/__tests__/providers.test.js +0 -321
- package/dist/__tests__/providers.test.js.map +0 -1
- package/dist/__tests__/refund-policy.test.js +0 -317
- package/dist/__tests__/refund-policy.test.js.map +0 -1
- package/dist/__tests__/schema.test.js +0 -46
- package/dist/__tests__/schema.test.js.map +0 -1
- package/dist/__tests__/store.test.js +0 -172
- package/dist/__tests__/store.test.js.map +0 -1
- package/dist/__tests__/test-utils.js +0 -30
- package/dist/__tests__/test-utils.js.map +0 -1
- package/dist/__tests__/webhook-refund.test.js +0 -313
- package/dist/__tests__/webhook-refund.test.js.map +0 -1
- package/dist/errors.js +0 -19
- package/dist/errors.js.map +0 -1
- package/dist/http.js +0 -36
- package/dist/http.js.map +0 -1
- package/dist/logger.js +0 -20
- package/dist/logger.js.map +0 -1
- package/dist/providers/apple-root-ca.js +0 -38
- package/dist/providers/apple-root-ca.js.map +0 -1
- package/dist/providers/apple.js +0 -499
- package/dist/providers/apple.js.map +0 -1
- package/dist/providers/google.js +0 -493
- package/dist/providers/google.js.map +0 -1
- package/dist/providers/mock.js +0 -93
- package/dist/providers/mock.js.map +0 -1
- package/dist/routes/admin.js +0 -251
- package/dist/routes/admin.js.map +0 -1
- package/dist/routes/entitlements.js +0 -130
- package/dist/routes/entitlements.js.map +0 -1
- package/dist/routes/metrics.js +0 -281
- package/dist/routes/metrics.js.map +0 -1
- package/dist/routes/purchase.js +0 -187
- package/dist/routes/purchase.js.map +0 -1
- package/dist/routes/status.js +0 -55
- package/dist/routes/status.js.map +0 -1
- package/dist/routes/validate.js +0 -70
- package/dist/routes/validate.js.map +0 -1
- package/dist/routes/webhook.js +0 -441
- package/dist/routes/webhook.js.map +0 -1
- package/dist/store.js +0 -145
- package/dist/store.js.map +0 -1
- package/dist/stores/postgres.js +0 -329
- package/dist/stores/postgres.js.map +0 -1
- package/dist/stores/schema.js +0 -57
- package/dist/stores/schema.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"refund-policy.test.js","sourceRoot":"","sources":["../../src/__tests__/refund-policy.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { readFileSync } from 'node:fs';
|
|
2
|
-
import { fileURLToPath } from 'node:url';
|
|
3
|
-
import { dirname, join } from 'node:path';
|
|
4
|
-
import { describe, it, expect } from 'vitest';
|
|
5
|
-
import { SUBSCRIPTIONS_SCHEMA_SQL, PURCHASES_SCHEMA_SQL } from '../stores/schema.js';
|
|
6
|
-
/**
|
|
7
|
-
* Parity check between the canonical SQL file (sql/schema.sql) and the
|
|
8
|
-
* embedded string constants used by initSchema() at runtime. If this fails,
|
|
9
|
-
* one of the two was edited without the other.
|
|
10
|
-
*/
|
|
11
|
-
describe('schema SQL parity', () => {
|
|
12
|
-
const here = dirname(fileURLToPath(import.meta.url));
|
|
13
|
-
// __tests__ lives under src/, so sql/schema.sql is three levels up.
|
|
14
|
-
const schemaPath = join(here, '..', '..', 'sql', 'schema.sql');
|
|
15
|
-
const sqlFile = readFileSync(schemaPath, 'utf8');
|
|
16
|
-
// Normalize both sides to compare by semantics rather than whitespace:
|
|
17
|
-
// strip SQL line comments, collapse whitespace, lowercase.
|
|
18
|
-
// The leading \r normalisation matters on Windows checkouts (core.autocrlf):
|
|
19
|
-
// without it, `--.*$` fails to match because `$` doesn't see `\r` as a line
|
|
20
|
-
// terminator, leaving comments in place and breaking the parity check.
|
|
21
|
-
const normalize = (sql) => sql
|
|
22
|
-
.replace(/\r/g, '')
|
|
23
|
-
.split('\n')
|
|
24
|
-
.map((l) => l.replace(/--.*$/, ''))
|
|
25
|
-
.join('\n')
|
|
26
|
-
.replace(/\s+/g, ' ')
|
|
27
|
-
.trim()
|
|
28
|
-
.toLowerCase();
|
|
29
|
-
it('contains both table DDLs in the canonical .sql file', () => {
|
|
30
|
-
const n = normalize(sqlFile);
|
|
31
|
-
expect(n).toContain('create table if not exists onesub_subscriptions');
|
|
32
|
-
expect(n).toContain('create table if not exists onesub_purchases');
|
|
33
|
-
});
|
|
34
|
-
it('subscriptions DDL constant appears verbatim in schema.sql', () => {
|
|
35
|
-
expect(normalize(sqlFile)).toContain(normalize(SUBSCRIPTIONS_SCHEMA_SQL));
|
|
36
|
-
});
|
|
37
|
-
it('purchases DDL constant appears verbatim in schema.sql', () => {
|
|
38
|
-
expect(normalize(sqlFile)).toContain(normalize(PURCHASES_SCHEMA_SQL));
|
|
39
|
-
});
|
|
40
|
-
it('non-consumable partial unique index is present (0.2.0 semantics)', () => {
|
|
41
|
-
const n = normalize(sqlFile);
|
|
42
|
-
expect(n).toContain('create unique index if not exists idx_onesub_purchases_non_consumable');
|
|
43
|
-
expect(n).toContain("where type = 'non_consumable'");
|
|
44
|
-
});
|
|
45
|
-
});
|
|
46
|
-
//# sourceMappingURL=schema.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"schema.test.js","sourceRoot":"","sources":["../../src/__tests__/schema.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,wBAAwB,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAErF;;;;GAIG;AACH,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;IACjC,MAAM,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACrD,oEAAoE;IACpE,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC;IAC/D,MAAM,OAAO,GAAG,YAAY,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IAEjD,uEAAuE;IACvE,2DAA2D;IAC3D,6EAA6E;IAC7E,4EAA4E;IAC5E,uEAAuE;IACvE,MAAM,SAAS,GAAG,CAAC,GAAW,EAAE,EAAE,CAChC,GAAG;SACA,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;SAClB,KAAK,CAAC,IAAI,CAAC;SACX,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;SAClC,IAAI,CAAC,IAAI,CAAC;SACV,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;SACpB,IAAI,EAAE;SACN,WAAW,EAAE,CAAC;IAEnB,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;QAC7D,MAAM,CAAC,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC;QAC7B,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,iDAAiD,CAAC,CAAC;QACvE,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,6CAA6C,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2DAA2D,EAAE,GAAG,EAAE;QACnE,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,wBAAwB,CAAC,CAAC,CAAC;IAC5E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;QAC/D,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC,CAAC;IACxE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kEAAkE,EAAE,GAAG,EAAE;QAC1E,MAAM,CAAC,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC;QAC7B,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,uEAAuE,CAAC,CAAC;QAC7F,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,+BAA+B,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -1,172 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, beforeEach } from 'vitest';
|
|
2
|
-
import { InMemorySubscriptionStore, InMemoryPurchaseStore } from '../store.js';
|
|
3
|
-
const makeSub = (overrides) => ({
|
|
4
|
-
userId: 'user_123',
|
|
5
|
-
productId: 'com.example.pro_monthly',
|
|
6
|
-
platform: 'apple',
|
|
7
|
-
status: 'active',
|
|
8
|
-
expiresAt: '2025-12-31T00:00:00.000Z',
|
|
9
|
-
originalTransactionId: 'txn_abc123',
|
|
10
|
-
purchasedAt: '2025-01-01T00:00:00.000Z',
|
|
11
|
-
willRenew: true,
|
|
12
|
-
...overrides,
|
|
13
|
-
});
|
|
14
|
-
describe('InMemorySubscriptionStore', () => {
|
|
15
|
-
let store;
|
|
16
|
-
beforeEach(() => {
|
|
17
|
-
store = new InMemorySubscriptionStore();
|
|
18
|
-
});
|
|
19
|
-
it('save() and getByUserId() returns the correct subscription', async () => {
|
|
20
|
-
const sub = makeSub();
|
|
21
|
-
await store.save(sub);
|
|
22
|
-
const result = await store.getByUserId('user_123');
|
|
23
|
-
expect(result).toEqual(sub);
|
|
24
|
-
});
|
|
25
|
-
it('save() and getByTransactionId() returns the correct subscription', async () => {
|
|
26
|
-
const sub = makeSub();
|
|
27
|
-
await store.save(sub);
|
|
28
|
-
const result = await store.getByTransactionId('txn_abc123');
|
|
29
|
-
expect(result).toEqual(sub);
|
|
30
|
-
});
|
|
31
|
-
it('getByUserId() returns null for an unknown user', async () => {
|
|
32
|
-
const result = await store.getByUserId('nonexistent_user');
|
|
33
|
-
expect(result).toBeNull();
|
|
34
|
-
});
|
|
35
|
-
it('getByTransactionId() returns null for an unknown transaction', async () => {
|
|
36
|
-
const result = await store.getByTransactionId('nonexistent_txn');
|
|
37
|
-
expect(result).toBeNull();
|
|
38
|
-
});
|
|
39
|
-
it('save() overwrites an existing subscription for the same userId', async () => {
|
|
40
|
-
const original = makeSub({ status: 'active', expiresAt: '2025-06-01T00:00:00.000Z' });
|
|
41
|
-
await store.save(original);
|
|
42
|
-
const updated = makeSub({
|
|
43
|
-
status: 'expired',
|
|
44
|
-
expiresAt: '2025-01-15T00:00:00.000Z',
|
|
45
|
-
originalTransactionId: 'txn_abc123',
|
|
46
|
-
});
|
|
47
|
-
await store.save(updated);
|
|
48
|
-
const result = await store.getByUserId('user_123');
|
|
49
|
-
expect(result?.status).toBe('expired');
|
|
50
|
-
expect(result?.expiresAt).toBe('2025-01-15T00:00:00.000Z');
|
|
51
|
-
});
|
|
52
|
-
it('save() overwrites an existing subscription indexed by the same transactionId', async () => {
|
|
53
|
-
const original = makeSub({ willRenew: true });
|
|
54
|
-
await store.save(original);
|
|
55
|
-
const updated = makeSub({ willRenew: false, originalTransactionId: 'txn_abc123' });
|
|
56
|
-
await store.save(updated);
|
|
57
|
-
const result = await store.getByTransactionId('txn_abc123');
|
|
58
|
-
expect(result?.willRenew).toBe(false);
|
|
59
|
-
});
|
|
60
|
-
it('stores multiple subscriptions independently', async () => {
|
|
61
|
-
const sub1 = makeSub({ userId: 'user_1', originalTransactionId: 'txn_1' });
|
|
62
|
-
const sub2 = makeSub({ userId: 'user_2', originalTransactionId: 'txn_2', platform: 'google' });
|
|
63
|
-
await store.save(sub1);
|
|
64
|
-
await store.save(sub2);
|
|
65
|
-
expect(await store.getByUserId('user_1')).toEqual(sub1);
|
|
66
|
-
expect(await store.getByUserId('user_2')).toEqual(sub2);
|
|
67
|
-
expect(await store.getByTransactionId('txn_1')).toEqual(sub1);
|
|
68
|
-
expect(await store.getByTransactionId('txn_2')).toEqual(sub2);
|
|
69
|
-
});
|
|
70
|
-
});
|
|
71
|
-
// ── InMemoryPurchaseStore ────────────────────────────────────────────────────
|
|
72
|
-
const makePurchase = (overrides) => ({
|
|
73
|
-
userId: 'user_1',
|
|
74
|
-
productId: 'credits_10',
|
|
75
|
-
platform: 'apple',
|
|
76
|
-
type: 'consumable',
|
|
77
|
-
transactionId: 'txn_p1',
|
|
78
|
-
purchasedAt: '2026-01-01T00:00:00.000Z',
|
|
79
|
-
quantity: 1,
|
|
80
|
-
...overrides,
|
|
81
|
-
});
|
|
82
|
-
describe('InMemoryPurchaseStore', () => {
|
|
83
|
-
let purchaseStore;
|
|
84
|
-
beforeEach(() => {
|
|
85
|
-
purchaseStore = new InMemoryPurchaseStore();
|
|
86
|
-
});
|
|
87
|
-
it('savePurchase + getPurchasesByUserId returns purchases', async () => {
|
|
88
|
-
const p = makePurchase();
|
|
89
|
-
await purchaseStore.savePurchase(p);
|
|
90
|
-
const results = await purchaseStore.getPurchasesByUserId('user_1');
|
|
91
|
-
expect(results).toHaveLength(1);
|
|
92
|
-
expect(results[0]).toEqual(p);
|
|
93
|
-
});
|
|
94
|
-
it('getPurchaseByTransactionId returns the correct purchase', async () => {
|
|
95
|
-
const p = makePurchase();
|
|
96
|
-
await purchaseStore.savePurchase(p);
|
|
97
|
-
expect(await purchaseStore.getPurchaseByTransactionId('txn_p1')).toEqual(p);
|
|
98
|
-
expect(await purchaseStore.getPurchaseByTransactionId('unknown')).toBeNull();
|
|
99
|
-
});
|
|
100
|
-
it('hasPurchased returns true for existing purchase', async () => {
|
|
101
|
-
await purchaseStore.savePurchase(makePurchase({ type: 'non_consumable', productId: 'premium_unlock' }));
|
|
102
|
-
expect(await purchaseStore.hasPurchased('user_1', 'premium_unlock')).toBe(true);
|
|
103
|
-
expect(await purchaseStore.hasPurchased('user_1', 'other_product')).toBe(false);
|
|
104
|
-
expect(await purchaseStore.hasPurchased('user_2', 'premium_unlock')).toBe(false);
|
|
105
|
-
});
|
|
106
|
-
it('stores multiple consumable purchases for same user+product', async () => {
|
|
107
|
-
await purchaseStore.savePurchase(makePurchase({ transactionId: 'txn_1' }));
|
|
108
|
-
await purchaseStore.savePurchase(makePurchase({ transactionId: 'txn_2' }));
|
|
109
|
-
await purchaseStore.savePurchase(makePurchase({ transactionId: 'txn_3' }));
|
|
110
|
-
const results = await purchaseStore.getPurchasesByUserId('user_1');
|
|
111
|
-
expect(results).toHaveLength(3);
|
|
112
|
-
});
|
|
113
|
-
it('getPurchasesByUserId returns empty for unknown user', async () => {
|
|
114
|
-
expect(await purchaseStore.getPurchasesByUserId('unknown')).toEqual([]);
|
|
115
|
-
});
|
|
116
|
-
it('stores purchases for different users independently', async () => {
|
|
117
|
-
await purchaseStore.savePurchase(makePurchase({ userId: 'a', transactionId: 't1' }));
|
|
118
|
-
await purchaseStore.savePurchase(makePurchase({ userId: 'b', transactionId: 't2' }));
|
|
119
|
-
expect(await purchaseStore.getPurchasesByUserId('a')).toHaveLength(1);
|
|
120
|
-
expect(await purchaseStore.getPurchasesByUserId('b')).toHaveLength(1);
|
|
121
|
-
});
|
|
122
|
-
it('savePurchase is idempotent for same transactionId + same userId', async () => {
|
|
123
|
-
await purchaseStore.savePurchase(makePurchase({ userId: 'a', transactionId: 't1' }));
|
|
124
|
-
await purchaseStore.savePurchase(makePurchase({ userId: 'a', transactionId: 't1' }));
|
|
125
|
-
expect(await purchaseStore.getPurchasesByUserId('a')).toHaveLength(1);
|
|
126
|
-
});
|
|
127
|
-
it('savePurchase rejects same transactionId from a different userId', async () => {
|
|
128
|
-
await purchaseStore.savePurchase(makePurchase({ userId: 'a', transactionId: 't1' }));
|
|
129
|
-
await expect(purchaseStore.savePurchase(makePurchase({ userId: 'b', transactionId: 't1' }))).rejects.toMatchObject({ code: 'TRANSACTION_BELONGS_TO_OTHER_USER' });
|
|
130
|
-
// Original owner unchanged
|
|
131
|
-
expect(await purchaseStore.getPurchasesByUserId('a')).toHaveLength(1);
|
|
132
|
-
expect(await purchaseStore.getPurchasesByUserId('b')).toHaveLength(0);
|
|
133
|
-
});
|
|
134
|
-
it('reassignPurchase transfers ownership to a new userId', async () => {
|
|
135
|
-
await purchaseStore.savePurchase(makePurchase({ userId: 'a', transactionId: 't1' }));
|
|
136
|
-
expect(await purchaseStore.reassignPurchase('t1', 'b')).toBe(true);
|
|
137
|
-
expect(await purchaseStore.getPurchasesByUserId('a')).toHaveLength(0);
|
|
138
|
-
expect(await purchaseStore.getPurchasesByUserId('b')).toHaveLength(1);
|
|
139
|
-
// now saving as 'b' is idempotent, 'a' is rejected
|
|
140
|
-
await purchaseStore.savePurchase(makePurchase({ userId: 'b', transactionId: 't1' }));
|
|
141
|
-
await expect(purchaseStore.savePurchase(makePurchase({ userId: 'a', transactionId: 't1' }))).rejects.toMatchObject({ code: 'TRANSACTION_BELONGS_TO_OTHER_USER' });
|
|
142
|
-
});
|
|
143
|
-
it('reassignPurchase returns false for unknown transaction', async () => {
|
|
144
|
-
expect(await purchaseStore.reassignPurchase('nope', 'a')).toBe(false);
|
|
145
|
-
});
|
|
146
|
-
it('deletePurchases removes matching rows', async () => {
|
|
147
|
-
await purchaseStore.savePurchase(makePurchase({ userId: 'a', transactionId: 't1', productId: 'pass' }));
|
|
148
|
-
await purchaseStore.savePurchase(makePurchase({ userId: 'a', transactionId: 't2', productId: 'pass' }));
|
|
149
|
-
await purchaseStore.savePurchase(makePurchase({ userId: 'a', transactionId: 't3', productId: 'other' }));
|
|
150
|
-
const deleted = await purchaseStore.deletePurchases('a', 'pass');
|
|
151
|
-
expect(deleted).toBe(2);
|
|
152
|
-
expect(await purchaseStore.getPurchasesByUserId('a')).toHaveLength(1);
|
|
153
|
-
});
|
|
154
|
-
it('deletePurchaseByTransactionId removes only the matching row', async () => {
|
|
155
|
-
await purchaseStore.savePurchase(makePurchase({ userId: 'a', transactionId: 't1', productId: 'coins' }));
|
|
156
|
-
await purchaseStore.savePurchase(makePurchase({ userId: 'a', transactionId: 't2', productId: 'coins' }));
|
|
157
|
-
expect(await purchaseStore.deletePurchaseByTransactionId('t1')).toBe(true);
|
|
158
|
-
const remaining = await purchaseStore.getPurchasesByUserId('a');
|
|
159
|
-
expect(remaining).toHaveLength(1);
|
|
160
|
-
expect(remaining[0].transactionId).toBe('t2');
|
|
161
|
-
expect(await purchaseStore.getPurchaseByTransactionId('t1')).toBeNull();
|
|
162
|
-
});
|
|
163
|
-
it('deletePurchaseByTransactionId returns false for unknown transaction', async () => {
|
|
164
|
-
expect(await purchaseStore.deletePurchaseByTransactionId('nope')).toBe(false);
|
|
165
|
-
});
|
|
166
|
-
it('deletePurchaseByTransactionId removes the user index when last row is gone', async () => {
|
|
167
|
-
await purchaseStore.savePurchase(makePurchase({ userId: 'a', transactionId: 'only' }));
|
|
168
|
-
expect(await purchaseStore.deletePurchaseByTransactionId('only')).toBe(true);
|
|
169
|
-
expect(await purchaseStore.getPurchasesByUserId('a')).toEqual([]);
|
|
170
|
-
});
|
|
171
|
-
});
|
|
172
|
-
//# sourceMappingURL=store.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"store.test.js","sourceRoot":"","sources":["../../src/__tests__/store.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shared test helpers — kept here so unit tests don't reinvent the wheel
|
|
3
|
-
* (and don't trip CodeQL with substring URL matching, which is unsafe in
|
|
4
|
-
* production code and inconsistent across files).
|
|
5
|
-
*/
|
|
6
|
-
/**
|
|
7
|
-
* Extract the hostname from a fetch input (string | URL | Request).
|
|
8
|
-
* Returns null when the input isn't a parseable absolute URL.
|
|
9
|
-
*
|
|
10
|
-
* Use this instead of `urlStr.includes('host.com')` — substring matching
|
|
11
|
-
* matches `https://attacker.example/?q=host.com` too, which CodeQL flags.
|
|
12
|
-
*/
|
|
13
|
-
export function urlHost(input) {
|
|
14
|
-
try {
|
|
15
|
-
return new URL(String(input)).hostname;
|
|
16
|
-
}
|
|
17
|
-
catch {
|
|
18
|
-
return null;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* True for fetch URLs targeting the in-process test HTTP server. Used by
|
|
23
|
-
* fetch mocks that need to pass-through the test runner's own requests
|
|
24
|
-
* while intercepting outbound API calls.
|
|
25
|
-
*/
|
|
26
|
-
export function isLocalhostUrl(input) {
|
|
27
|
-
const host = urlHost(input);
|
|
28
|
-
return host === '127.0.0.1' || host === 'localhost';
|
|
29
|
-
}
|
|
30
|
-
//# sourceMappingURL=test-utils.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"test-utils.js","sourceRoot":"","sources":["../../src/__tests__/test-utils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;GAMG;AACH,MAAM,UAAU,OAAO,CAAC,KAAc;IACpC,IAAI,CAAC;QACH,OAAO,IAAI,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC;IACzC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,KAAc;IAC3C,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;IAC5B,OAAO,IAAI,KAAK,WAAW,IAAI,IAAI,KAAK,WAAW,CAAC;AACtD,CAAC"}
|
|
@@ -1,313 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Refund / voided-purchase webhook tests.
|
|
3
|
-
*
|
|
4
|
-
* Covers:
|
|
5
|
-
* - Apple webhook REFUND for IAP (Consumable / Non-Consumable) →
|
|
6
|
-
* PurchaseStore row removed, SubscriptionStore untouched.
|
|
7
|
-
* - Apple webhook REFUND for subscriptions still updates SubscriptionStore.
|
|
8
|
-
* - Google voidedPurchaseNotification productType=2 → IAP row removed.
|
|
9
|
-
* - Google voidedPurchaseNotification productType=1 → subscription canceled.
|
|
10
|
-
* - decodeGoogleVoidedNotification recognises voided payload, ignores other kinds.
|
|
11
|
-
*/
|
|
12
|
-
import { describe, it, expect, beforeEach } from 'vitest';
|
|
13
|
-
import express from 'express';
|
|
14
|
-
import { SUBSCRIPTION_STATUS } from '@onesub/shared';
|
|
15
|
-
import { createWebhookRouter } from '../routes/webhook.js';
|
|
16
|
-
import { InMemorySubscriptionStore, InMemoryPurchaseStore } from '../store.js';
|
|
17
|
-
import { decodeGoogleVoidedNotification } from '../providers/google.js';
|
|
18
|
-
// ── helpers ─────────────────────────────────────────────────────────────────
|
|
19
|
-
function makeJws(payload) {
|
|
20
|
-
const header = Buffer.from(JSON.stringify({ alg: 'ES256' })).toString('base64url');
|
|
21
|
-
const body = Buffer.from(JSON.stringify(payload)).toString('base64url');
|
|
22
|
-
return `${header}.${body}.fakesig`;
|
|
23
|
-
}
|
|
24
|
-
function appleConfig() {
|
|
25
|
-
return {
|
|
26
|
-
apple: { bundleId: 'com.example.app', skipJwsVerification: true },
|
|
27
|
-
database: { url: '' },
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
function googleConfig() {
|
|
31
|
-
return {
|
|
32
|
-
google: { packageName: 'com.example.app' },
|
|
33
|
-
database: { url: '' },
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
function buildServer(config, store, purchaseStore) {
|
|
37
|
-
const app = express();
|
|
38
|
-
app.use(express.json());
|
|
39
|
-
app.use(createWebhookRouter(config, store, purchaseStore));
|
|
40
|
-
return {
|
|
41
|
-
async request(path, body) {
|
|
42
|
-
// Use Node http directly for a lightweight test server.
|
|
43
|
-
const server = app.listen(0);
|
|
44
|
-
const address = server.address();
|
|
45
|
-
const port = typeof address === 'object' && address ? address.port : 0;
|
|
46
|
-
try {
|
|
47
|
-
const resp = await fetch(`http://127.0.0.1:${port}${path}`, {
|
|
48
|
-
method: 'POST',
|
|
49
|
-
headers: { 'Content-Type': 'application/json' },
|
|
50
|
-
body: JSON.stringify(body),
|
|
51
|
-
});
|
|
52
|
-
const text = await resp.text();
|
|
53
|
-
let parsed = text;
|
|
54
|
-
try {
|
|
55
|
-
parsed = JSON.parse(text);
|
|
56
|
-
}
|
|
57
|
-
catch { /* keep as text */ }
|
|
58
|
-
return { status: resp.status, body: parsed };
|
|
59
|
-
}
|
|
60
|
-
finally {
|
|
61
|
-
await new Promise((resolve) => server.close(() => resolve()));
|
|
62
|
-
}
|
|
63
|
-
},
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
const samplePurchase = (overrides) => ({
|
|
67
|
-
userId: 'user_1',
|
|
68
|
-
productId: 'credits_100',
|
|
69
|
-
platform: 'apple',
|
|
70
|
-
type: 'consumable',
|
|
71
|
-
transactionId: 'txn_apple_consumable_001',
|
|
72
|
-
purchasedAt: '2026-01-01T00:00:00.000Z',
|
|
73
|
-
quantity: 1,
|
|
74
|
-
...overrides,
|
|
75
|
-
});
|
|
76
|
-
const sampleSub = (overrides) => ({
|
|
77
|
-
userId: 'user_sub',
|
|
78
|
-
productId: 'pro_monthly',
|
|
79
|
-
platform: 'google',
|
|
80
|
-
status: 'active',
|
|
81
|
-
expiresAt: '2027-01-01T00:00:00.000Z',
|
|
82
|
-
originalTransactionId: 'token_google_sub_xyz',
|
|
83
|
-
purchasedAt: '2026-01-01T00:00:00.000Z',
|
|
84
|
-
willRenew: true,
|
|
85
|
-
...overrides,
|
|
86
|
-
});
|
|
87
|
-
// ── Apple webhook: IAP REFUND ───────────────────────────────────────────────
|
|
88
|
-
describe('Apple webhook — IAP REFUND', () => {
|
|
89
|
-
let store;
|
|
90
|
-
let purchaseStore;
|
|
91
|
-
let server;
|
|
92
|
-
beforeEach(() => {
|
|
93
|
-
store = new InMemorySubscriptionStore();
|
|
94
|
-
purchaseStore = new InMemoryPurchaseStore();
|
|
95
|
-
server = buildServer(appleConfig(), store, purchaseStore);
|
|
96
|
-
});
|
|
97
|
-
it('removes the consumable purchase row on REFUND', async () => {
|
|
98
|
-
await purchaseStore.savePurchase(samplePurchase({ transactionId: 'txn_consumable_a' }));
|
|
99
|
-
const signedTransactionInfo = makeJws({
|
|
100
|
-
bundleId: 'com.example.app',
|
|
101
|
-
type: 'Consumable',
|
|
102
|
-
productId: 'credits_100',
|
|
103
|
-
transactionId: 'txn_consumable_a',
|
|
104
|
-
originalTransactionId: 'orig_consumable_a',
|
|
105
|
-
purchaseDate: Date.now(),
|
|
106
|
-
});
|
|
107
|
-
const signedRenewalInfo = makeJws({});
|
|
108
|
-
const signedPayload = makeJws({
|
|
109
|
-
notificationType: 'REFUND',
|
|
110
|
-
data: { signedTransactionInfo, signedRenewalInfo },
|
|
111
|
-
});
|
|
112
|
-
const resp = await server.request('/onesub/webhook/apple', { signedPayload });
|
|
113
|
-
expect(resp.status).toBe(200);
|
|
114
|
-
expect(await purchaseStore.getPurchaseByTransactionId('txn_consumable_a')).toBeNull();
|
|
115
|
-
});
|
|
116
|
-
it('removes the non-consumable purchase row on REVOKE', async () => {
|
|
117
|
-
await purchaseStore.savePurchase(samplePurchase({
|
|
118
|
-
transactionId: 'txn_nc_a',
|
|
119
|
-
type: 'non_consumable',
|
|
120
|
-
productId: 'premium_unlock',
|
|
121
|
-
}));
|
|
122
|
-
const signedTransactionInfo = makeJws({
|
|
123
|
-
bundleId: 'com.example.app',
|
|
124
|
-
type: 'Non-Consumable',
|
|
125
|
-
productId: 'premium_unlock',
|
|
126
|
-
transactionId: 'txn_nc_a',
|
|
127
|
-
originalTransactionId: 'txn_nc_a',
|
|
128
|
-
purchaseDate: Date.now(),
|
|
129
|
-
});
|
|
130
|
-
const signedPayload = makeJws({
|
|
131
|
-
notificationType: 'REVOKE',
|
|
132
|
-
data: { signedTransactionInfo, signedRenewalInfo: makeJws({}) },
|
|
133
|
-
});
|
|
134
|
-
const resp = await server.request('/onesub/webhook/apple', { signedPayload });
|
|
135
|
-
expect(resp.status).toBe(200);
|
|
136
|
-
expect(await purchaseStore.getPurchaseByTransactionId('txn_nc_a')).toBeNull();
|
|
137
|
-
});
|
|
138
|
-
it('does not touch the SubscriptionStore on IAP REFUND', async () => {
|
|
139
|
-
await store.save(sampleSub({ originalTransactionId: 'orig_sub_untouched' }));
|
|
140
|
-
await purchaseStore.savePurchase(samplePurchase({ transactionId: 'iap_only' }));
|
|
141
|
-
const signedTransactionInfo = makeJws({
|
|
142
|
-
bundleId: 'com.example.app',
|
|
143
|
-
type: 'Consumable',
|
|
144
|
-
productId: 'credits_100',
|
|
145
|
-
transactionId: 'iap_only',
|
|
146
|
-
originalTransactionId: 'iap_only',
|
|
147
|
-
purchaseDate: Date.now(),
|
|
148
|
-
});
|
|
149
|
-
const signedPayload = makeJws({
|
|
150
|
-
notificationType: 'REFUND',
|
|
151
|
-
data: { signedTransactionInfo, signedRenewalInfo: makeJws({}) },
|
|
152
|
-
});
|
|
153
|
-
await server.request('/onesub/webhook/apple', { signedPayload });
|
|
154
|
-
expect(await store.getByTransactionId('orig_sub_untouched')).not.toBeNull();
|
|
155
|
-
});
|
|
156
|
-
it('still routes subscription REFUND through the SubscriptionStore', async () => {
|
|
157
|
-
await store.save(sampleSub({
|
|
158
|
-
platform: 'apple',
|
|
159
|
-
originalTransactionId: 'orig_sub_apple',
|
|
160
|
-
status: 'active',
|
|
161
|
-
}));
|
|
162
|
-
const signedTransactionInfo = makeJws({
|
|
163
|
-
bundleId: 'com.example.app',
|
|
164
|
-
type: 'Auto-Renewable Subscription',
|
|
165
|
-
productId: 'pro_monthly',
|
|
166
|
-
transactionId: 'tx_sub_apple_1',
|
|
167
|
-
originalTransactionId: 'orig_sub_apple',
|
|
168
|
-
purchaseDate: Date.now(),
|
|
169
|
-
expiresDate: Date.now() + 86400000,
|
|
170
|
-
});
|
|
171
|
-
const signedPayload = makeJws({
|
|
172
|
-
notificationType: 'REFUND',
|
|
173
|
-
data: { signedTransactionInfo, signedRenewalInfo: makeJws({}) },
|
|
174
|
-
});
|
|
175
|
-
const resp = await server.request('/onesub/webhook/apple', { signedPayload });
|
|
176
|
-
expect(resp.status).toBe(200);
|
|
177
|
-
const updated = await store.getByTransactionId('orig_sub_apple');
|
|
178
|
-
expect(updated?.status).toBe(SUBSCRIPTION_STATUS.CANCELED);
|
|
179
|
-
});
|
|
180
|
-
});
|
|
181
|
-
// ── Google webhook: voidedPurchaseNotification ──────────────────────────────
|
|
182
|
-
function makeVoidedPushBody(notification) {
|
|
183
|
-
const json = JSON.stringify({
|
|
184
|
-
version: '1.0',
|
|
185
|
-
eventTimeMillis: String(Date.now()),
|
|
186
|
-
...notification,
|
|
187
|
-
});
|
|
188
|
-
return {
|
|
189
|
-
message: {
|
|
190
|
-
data: Buffer.from(json, 'utf-8').toString('base64'),
|
|
191
|
-
messageId: '1',
|
|
192
|
-
},
|
|
193
|
-
subscription: 'projects/x/subscriptions/y',
|
|
194
|
-
};
|
|
195
|
-
}
|
|
196
|
-
describe('Google webhook — voidedPurchaseNotification', () => {
|
|
197
|
-
let store;
|
|
198
|
-
let purchaseStore;
|
|
199
|
-
let server;
|
|
200
|
-
beforeEach(() => {
|
|
201
|
-
store = new InMemorySubscriptionStore();
|
|
202
|
-
purchaseStore = new InMemoryPurchaseStore();
|
|
203
|
-
server = buildServer(googleConfig(), store, purchaseStore);
|
|
204
|
-
});
|
|
205
|
-
it('removes IAP row when productType=2 (one-time product refund)', async () => {
|
|
206
|
-
await purchaseStore.savePurchase(samplePurchase({
|
|
207
|
-
platform: 'google',
|
|
208
|
-
transactionId: 'GPA.refunded_order',
|
|
209
|
-
}));
|
|
210
|
-
const resp = await server.request('/onesub/webhook/google', makeVoidedPushBody({
|
|
211
|
-
packageName: 'com.example.app',
|
|
212
|
-
voidedPurchaseNotification: {
|
|
213
|
-
purchaseToken: 'tok_x',
|
|
214
|
-
orderId: 'GPA.refunded_order',
|
|
215
|
-
productType: 2,
|
|
216
|
-
refundType: 1,
|
|
217
|
-
},
|
|
218
|
-
}));
|
|
219
|
-
expect(resp.status).toBe(200);
|
|
220
|
-
expect(await purchaseStore.getPurchaseByTransactionId('GPA.refunded_order')).toBeNull();
|
|
221
|
-
});
|
|
222
|
-
it('cancels subscription when productType=1', async () => {
|
|
223
|
-
await store.save(sampleSub({ originalTransactionId: 'tok_sub' }));
|
|
224
|
-
const resp = await server.request('/onesub/webhook/google', makeVoidedPushBody({
|
|
225
|
-
packageName: 'com.example.app',
|
|
226
|
-
voidedPurchaseNotification: {
|
|
227
|
-
purchaseToken: 'tok_sub',
|
|
228
|
-
orderId: 'GPA.sub_order',
|
|
229
|
-
productType: 1,
|
|
230
|
-
refundType: 1,
|
|
231
|
-
},
|
|
232
|
-
}));
|
|
233
|
-
expect(resp.status).toBe(200);
|
|
234
|
-
const updated = await store.getByTransactionId('tok_sub');
|
|
235
|
-
expect(updated?.status).toBe(SUBSCRIPTION_STATUS.CANCELED);
|
|
236
|
-
});
|
|
237
|
-
it('rejects voided notification when packageName mismatches', async () => {
|
|
238
|
-
const resp = await server.request('/onesub/webhook/google', makeVoidedPushBody({
|
|
239
|
-
packageName: 'com.attacker.app',
|
|
240
|
-
voidedPurchaseNotification: {
|
|
241
|
-
purchaseToken: 'tok',
|
|
242
|
-
orderId: 'GPA.x',
|
|
243
|
-
productType: 2,
|
|
244
|
-
refundType: 1,
|
|
245
|
-
},
|
|
246
|
-
}));
|
|
247
|
-
expect(resp.status).toBe(400);
|
|
248
|
-
});
|
|
249
|
-
it('acknowledges with 200 even when the orderId is unknown', async () => {
|
|
250
|
-
// Idempotent ack semantics — Google retries until 2xx; we don't want loops
|
|
251
|
-
// when the row was already removed.
|
|
252
|
-
const resp = await server.request('/onesub/webhook/google', makeVoidedPushBody({
|
|
253
|
-
packageName: 'com.example.app',
|
|
254
|
-
voidedPurchaseNotification: {
|
|
255
|
-
purchaseToken: 'tok',
|
|
256
|
-
orderId: 'GPA.unknown',
|
|
257
|
-
productType: 2,
|
|
258
|
-
refundType: 1,
|
|
259
|
-
},
|
|
260
|
-
}));
|
|
261
|
-
expect(resp.status).toBe(200);
|
|
262
|
-
});
|
|
263
|
-
});
|
|
264
|
-
// ── decodeGoogleVoidedNotification unit ─────────────────────────────────────
|
|
265
|
-
describe('decodeGoogleVoidedNotification', () => {
|
|
266
|
-
it('returns null for subscription notifications', () => {
|
|
267
|
-
const json = JSON.stringify({
|
|
268
|
-
packageName: 'com.example.app',
|
|
269
|
-
eventTimeMillis: '0',
|
|
270
|
-
subscriptionNotification: {
|
|
271
|
-
version: '1.0',
|
|
272
|
-
notificationType: 4,
|
|
273
|
-
purchaseToken: 't',
|
|
274
|
-
subscriptionId: 'p',
|
|
275
|
-
},
|
|
276
|
-
});
|
|
277
|
-
const result = decodeGoogleVoidedNotification({
|
|
278
|
-
message: { data: Buffer.from(json).toString('base64'), messageId: '1' },
|
|
279
|
-
subscription: 's',
|
|
280
|
-
});
|
|
281
|
-
expect(result).toBeNull();
|
|
282
|
-
});
|
|
283
|
-
it('extracts voided payload fields', () => {
|
|
284
|
-
const json = JSON.stringify({
|
|
285
|
-
packageName: 'com.example.app',
|
|
286
|
-
eventTimeMillis: '0',
|
|
287
|
-
voidedPurchaseNotification: {
|
|
288
|
-
purchaseToken: 'tok123',
|
|
289
|
-
orderId: 'GPA.xyz',
|
|
290
|
-
productType: 2,
|
|
291
|
-
refundType: 1,
|
|
292
|
-
},
|
|
293
|
-
});
|
|
294
|
-
const result = decodeGoogleVoidedNotification({
|
|
295
|
-
message: { data: Buffer.from(json).toString('base64'), messageId: '1' },
|
|
296
|
-
subscription: 's',
|
|
297
|
-
});
|
|
298
|
-
expect(result).toEqual({
|
|
299
|
-
purchaseToken: 'tok123',
|
|
300
|
-
orderId: 'GPA.xyz',
|
|
301
|
-
productType: 2,
|
|
302
|
-
refundType: 1,
|
|
303
|
-
packageName: 'com.example.app',
|
|
304
|
-
});
|
|
305
|
-
});
|
|
306
|
-
it('returns null for malformed base64', () => {
|
|
307
|
-
expect(decodeGoogleVoidedNotification({
|
|
308
|
-
message: { data: '!!!not-base64!!!', messageId: '1' },
|
|
309
|
-
subscription: 's',
|
|
310
|
-
})).toBeNull();
|
|
311
|
-
});
|
|
312
|
-
});
|
|
313
|
-
//# sourceMappingURL=webhook-refund.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"webhook-refund.test.js","sourceRoot":"","sources":["../../src/__tests__/webhook-refund.test.ts"],"names":[],"mappings":"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"}
|