@onesub/server 0.13.0 → 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/__tests__/error-codes.test.js +8 -3
- package/dist/__tests__/error-codes.test.js.map +1 -1
- package/dist/__tests__/redis-store.test.js +58 -9
- package/dist/__tests__/redis-store.test.js.map +1 -1
- package/dist/__tests__/webhook-apple.test.js +247 -0
- package/dist/__tests__/webhook-apple.test.js.map +1 -0
- package/dist/__tests__/webhook-google.test.js +255 -0
- package/dist/__tests__/webhook-google.test.js.map +1 -0
- package/dist/cache.js +0 -4
- package/dist/cache.js.map +1 -1
- package/dist/index.cjs +36 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +36 -7
- 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/apple.js +121 -1
- package/dist/providers/apple.js.map +1 -1
- package/dist/providers/google.d.ts +8 -0
- package/dist/providers/google.d.ts.map +1 -1
- package/dist/providers/google.js +42 -0
- package/dist/providers/google.js.map +1 -1
- package/dist/providers/mock.d.ts +2 -0
- package/dist/providers/mock.d.ts.map +1 -1
- package/dist/routes/admin.js +40 -0
- package/dist/routes/admin.js.map +1 -1
- package/dist/routes/apple-offer.js +72 -0
- package/dist/routes/apple-offer.js.map +1 -0
- package/dist/routes/purchase.d.ts.map +1 -1
- package/dist/routes/purchase.js +21 -4
- package/dist/routes/purchase.js.map +1 -1
- package/dist/routes/webhook-apple.js +145 -0
- package/dist/routes/webhook-apple.js.map +1 -0
- package/dist/routes/webhook-google.js +204 -0
- package/dist/routes/webhook-google.js.map +1 -0
- package/dist/routes/webhook.js +9 -451
- package/dist/routes/webhook.js.map +1 -1
- package/dist/stores/redis.js +65 -23
- package/dist/stores/redis.js.map +1 -1
- package/dist/webhook-events.js +9 -8
- package/dist/webhook-events.js.map +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unit tests for webhook-google.ts handler behaviors.
|
|
3
|
+
*
|
|
4
|
+
* Covers gaps not reached by google-paused, google-price-change, or webhook-refund:
|
|
5
|
+
* - Input validation (missing message.data)
|
|
6
|
+
* - Webhook event deduplication via WebhookEventStore
|
|
7
|
+
* - pushAudience JWT authentication (missing / invalid token → 401)
|
|
8
|
+
* - Package name mismatch for subscription notifications
|
|
9
|
+
* - Notification type mappings: CANCELED, REVOKED, EXPIRED, IN_GRACE_PERIOD, unknown fallback
|
|
10
|
+
* - verifyGooglePushToken unit (no network required for invalid tokens)
|
|
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 { InMemoryWebhookEventStore } from '../webhook-events.js';
|
|
18
|
+
import { verifyGooglePushToken } from '../routes/webhook-google.js';
|
|
19
|
+
// ── helpers ──────────────────────────────────────────────────────────────────
|
|
20
|
+
function googlePushBody(notificationType, purchaseToken, opts) {
|
|
21
|
+
const json = JSON.stringify({
|
|
22
|
+
version: '1.0',
|
|
23
|
+
packageName: opts?.packageName ?? 'com.example.app',
|
|
24
|
+
eventTimeMillis: String(Date.now()),
|
|
25
|
+
subscriptionNotification: {
|
|
26
|
+
version: '1.0',
|
|
27
|
+
notificationType,
|
|
28
|
+
purchaseToken,
|
|
29
|
+
subscriptionId: 'pro_monthly',
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
return {
|
|
33
|
+
message: {
|
|
34
|
+
data: Buffer.from(json).toString('base64'),
|
|
35
|
+
messageId: opts?.messageId ?? `msg-${Date.now()}`,
|
|
36
|
+
},
|
|
37
|
+
subscription: 'projects/x/subscriptions/y',
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
const baseConfig = {
|
|
41
|
+
google: { packageName: 'com.example.app' },
|
|
42
|
+
database: { url: '' },
|
|
43
|
+
};
|
|
44
|
+
const sampleSub = (overrides) => ({
|
|
45
|
+
userId: 'user_g',
|
|
46
|
+
productId: 'pro_monthly',
|
|
47
|
+
platform: 'google',
|
|
48
|
+
status: 'active',
|
|
49
|
+
expiresAt: '2099-01-01T00:00:00.000Z',
|
|
50
|
+
originalTransactionId: 'tok_g',
|
|
51
|
+
purchasedAt: '2026-01-01T00:00:00.000Z',
|
|
52
|
+
willRenew: true,
|
|
53
|
+
...overrides,
|
|
54
|
+
});
|
|
55
|
+
function buildServer(config, store, webhookEventStore) {
|
|
56
|
+
const app = express();
|
|
57
|
+
app.use(express.json());
|
|
58
|
+
app.use(createWebhookRouter(config, store, new InMemoryPurchaseStore(), webhookEventStore));
|
|
59
|
+
return {
|
|
60
|
+
async request(body, headers) {
|
|
61
|
+
const srv = app.listen(0);
|
|
62
|
+
const port = srv.address().port;
|
|
63
|
+
try {
|
|
64
|
+
const resp = await fetch(`http://127.0.0.1:${port}/onesub/webhook/google`, {
|
|
65
|
+
method: 'POST',
|
|
66
|
+
headers: { 'Content-Type': 'application/json', ...headers },
|
|
67
|
+
body: JSON.stringify(body),
|
|
68
|
+
});
|
|
69
|
+
const text = await resp.text();
|
|
70
|
+
let parsed = text;
|
|
71
|
+
try {
|
|
72
|
+
parsed = JSON.parse(text);
|
|
73
|
+
}
|
|
74
|
+
catch { /* keep as text */ }
|
|
75
|
+
return { status: resp.status, body: parsed };
|
|
76
|
+
}
|
|
77
|
+
finally {
|
|
78
|
+
await new Promise((r) => srv.close(() => r()));
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
// ── Input validation ─────────────────────────────────────────────────────────
|
|
84
|
+
describe('Google webhook — input validation', () => {
|
|
85
|
+
it('returns 400 when message.data is missing', async () => {
|
|
86
|
+
const store = new InMemorySubscriptionStore();
|
|
87
|
+
const server = buildServer(baseConfig, store);
|
|
88
|
+
const resp = await server.request({ message: { messageId: '1' }, subscription: 's' });
|
|
89
|
+
expect(resp.status).toBe(400);
|
|
90
|
+
expect(resp.body.errorCode).toBe('MISSING_MESSAGE_DATA');
|
|
91
|
+
});
|
|
92
|
+
it('returns 200 when message.data decodes to an unrecognized notification format', async () => {
|
|
93
|
+
const store = new InMemorySubscriptionStore();
|
|
94
|
+
const server = buildServer(baseConfig, store);
|
|
95
|
+
// Valid base64 but payload has no known notification field
|
|
96
|
+
const json = JSON.stringify({ version: '1.0', packageName: 'com.example.app' });
|
|
97
|
+
const resp = await server.request({
|
|
98
|
+
message: { data: Buffer.from(json).toString('base64'), messageId: '1' },
|
|
99
|
+
subscription: 's',
|
|
100
|
+
});
|
|
101
|
+
// decodeGoogleNotification returns null → ack with 200
|
|
102
|
+
expect(resp.status).toBe(200);
|
|
103
|
+
expect(resp.body.received).toBe(true);
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
// ── pushAudience authentication ───────────────────────────────────────────────
|
|
107
|
+
describe('Google webhook — pushAudience authentication', () => {
|
|
108
|
+
const configWithAudience = {
|
|
109
|
+
google: { packageName: 'com.example.app', pushAudience: 'https://myapp.example.com' },
|
|
110
|
+
database: { url: '' },
|
|
111
|
+
};
|
|
112
|
+
it('returns 401 when Authorization header is absent', async () => {
|
|
113
|
+
const store = new InMemorySubscriptionStore();
|
|
114
|
+
const server = buildServer(configWithAudience, store);
|
|
115
|
+
const resp = await server.request(googlePushBody(2, 'tok_auth'));
|
|
116
|
+
expect(resp.status).toBe(401);
|
|
117
|
+
expect(resp.body.errorCode).toBe('UNAUTHORIZED');
|
|
118
|
+
});
|
|
119
|
+
it('returns 401 when Bearer token is malformed (not a valid JWT)', async () => {
|
|
120
|
+
const store = new InMemorySubscriptionStore();
|
|
121
|
+
const server = buildServer(configWithAudience, store);
|
|
122
|
+
const resp = await server.request(googlePushBody(2, 'tok_auth'), { Authorization: 'Bearer not-a-real-jwt' });
|
|
123
|
+
expect(resp.status).toBe(401);
|
|
124
|
+
expect(resp.body.errorCode).toBe('UNAUTHORIZED');
|
|
125
|
+
});
|
|
126
|
+
it('passes through (processes notification) when no pushAudience is configured', async () => {
|
|
127
|
+
const store = new InMemorySubscriptionStore();
|
|
128
|
+
await store.save(sampleSub({ originalTransactionId: 'tok_noauth' }));
|
|
129
|
+
const server = buildServer(baseConfig, store); // no pushAudience
|
|
130
|
+
const resp = await server.request(googlePushBody(2, 'tok_noauth'));
|
|
131
|
+
expect(resp.status).toBe(200);
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
// ── verifyGooglePushToken unit ────────────────────────────────────────────────
|
|
135
|
+
describe('verifyGooglePushToken', () => {
|
|
136
|
+
it('returns false when Authorization header is absent', async () => {
|
|
137
|
+
const req = { headers: {} };
|
|
138
|
+
expect(await verifyGooglePushToken(req, 'https://example.com')).toBe(false);
|
|
139
|
+
});
|
|
140
|
+
it('returns false when header is not Bearer scheme', async () => {
|
|
141
|
+
const req = { headers: { authorization: 'Basic dXNlcjpwYXNz' } };
|
|
142
|
+
expect(await verifyGooglePushToken(req, 'https://example.com')).toBe(false);
|
|
143
|
+
});
|
|
144
|
+
it('returns false for a malformed JWT that cannot be verified', async () => {
|
|
145
|
+
// jose throws on invalid JWT format; verifyGooglePushToken catches and returns false
|
|
146
|
+
const req = { headers: { authorization: 'Bearer not.valid.jwt' } };
|
|
147
|
+
expect(await verifyGooglePushToken(req, 'https://example.com')).toBe(false);
|
|
148
|
+
});
|
|
149
|
+
});
|
|
150
|
+
// ── Package name validation ───────────────────────────────────────────────────
|
|
151
|
+
describe('Google webhook — package name mismatch', () => {
|
|
152
|
+
it('returns 400 when notification packageName does not match config', async () => {
|
|
153
|
+
const store = new InMemorySubscriptionStore();
|
|
154
|
+
const server = buildServer(baseConfig, store);
|
|
155
|
+
const resp = await server.request(googlePushBody(2, 'tok_pkg', { packageName: 'com.attacker.app' }));
|
|
156
|
+
expect(resp.status).toBe(400);
|
|
157
|
+
expect(resp.body.errorCode).toBe('PACKAGE_NAME_MISMATCH');
|
|
158
|
+
});
|
|
159
|
+
it('accepts notification when no packageName is configured (open mode)', async () => {
|
|
160
|
+
const openConfig = {
|
|
161
|
+
google: {}, // no packageName restriction
|
|
162
|
+
database: { url: '' },
|
|
163
|
+
};
|
|
164
|
+
const store = new InMemorySubscriptionStore();
|
|
165
|
+
await store.save(sampleSub({ originalTransactionId: 'tok_open' }));
|
|
166
|
+
const server = buildServer(openConfig, store);
|
|
167
|
+
const resp = await server.request(googlePushBody(2, 'tok_open', { packageName: 'any.package.name' }));
|
|
168
|
+
expect(resp.status).toBe(200);
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
// ── Deduplication ────────────────────────────────────────────────────────────
|
|
172
|
+
describe('Google webhook — deduplication', () => {
|
|
173
|
+
let store;
|
|
174
|
+
let webhookEventStore;
|
|
175
|
+
let server;
|
|
176
|
+
beforeEach(() => {
|
|
177
|
+
store = new InMemorySubscriptionStore();
|
|
178
|
+
webhookEventStore = new InMemoryWebhookEventStore();
|
|
179
|
+
server = buildServer(baseConfig, store, webhookEventStore);
|
|
180
|
+
});
|
|
181
|
+
it('processes the first delivery and returns received=true', async () => {
|
|
182
|
+
await store.save(sampleSub({ originalTransactionId: 'tok_dedup1' }));
|
|
183
|
+
const resp = await server.request(googlePushBody(2, 'tok_dedup1', { messageId: 'msg-dedup-1' }));
|
|
184
|
+
expect(resp.status).toBe(200);
|
|
185
|
+
expect(resp.body.received).toBe(true);
|
|
186
|
+
expect(resp.body.deduped).toBeUndefined();
|
|
187
|
+
});
|
|
188
|
+
it('returns deduped=true and skips store update on replay', async () => {
|
|
189
|
+
await store.save(sampleSub({ originalTransactionId: 'tok_dedup2', status: 'active' }));
|
|
190
|
+
const body = googlePushBody(3, 'tok_dedup2', { messageId: 'msg-dedup-2' }); // CANCELED
|
|
191
|
+
// First delivery → status becomes canceled
|
|
192
|
+
await server.request(body);
|
|
193
|
+
expect((await store.getByTransactionId('tok_dedup2'))?.status).toBe(SUBSCRIPTION_STATUS.CANCELED);
|
|
194
|
+
// Restore to simulate rollback
|
|
195
|
+
await store.save(sampleSub({ originalTransactionId: 'tok_dedup2', status: 'active' }));
|
|
196
|
+
// Replay → must be skipped, status stays active
|
|
197
|
+
const replay = await server.request(body);
|
|
198
|
+
expect(replay.status).toBe(200);
|
|
199
|
+
expect(replay.body.deduped).toBe(true);
|
|
200
|
+
expect((await store.getByTransactionId('tok_dedup2'))?.status).toBe(SUBSCRIPTION_STATUS.ACTIVE);
|
|
201
|
+
});
|
|
202
|
+
});
|
|
203
|
+
// ── Notification type → status mapping ──────────────────────────────────────
|
|
204
|
+
describe('Google webhook — notification type mapping', () => {
|
|
205
|
+
let store;
|
|
206
|
+
let server;
|
|
207
|
+
beforeEach(() => {
|
|
208
|
+
store = new InMemorySubscriptionStore();
|
|
209
|
+
server = buildServer(baseConfig, store);
|
|
210
|
+
});
|
|
211
|
+
it('SUBSCRIPTION_CANCELED (3) → canceled', async () => {
|
|
212
|
+
await store.save(sampleSub({ originalTransactionId: 'tok_cancel' }));
|
|
213
|
+
await server.request(googlePushBody(3, 'tok_cancel'));
|
|
214
|
+
expect((await store.getByTransactionId('tok_cancel'))?.status).toBe(SUBSCRIPTION_STATUS.CANCELED);
|
|
215
|
+
});
|
|
216
|
+
it('SUBSCRIPTION_REVOKED (12) → canceled', async () => {
|
|
217
|
+
await store.save(sampleSub({ originalTransactionId: 'tok_revoke' }));
|
|
218
|
+
await server.request(googlePushBody(12, 'tok_revoke'));
|
|
219
|
+
expect((await store.getByTransactionId('tok_revoke'))?.status).toBe(SUBSCRIPTION_STATUS.CANCELED);
|
|
220
|
+
});
|
|
221
|
+
it('SUBSCRIPTION_EXPIRED (13) → expired', async () => {
|
|
222
|
+
await store.save(sampleSub({ originalTransactionId: 'tok_exp' }));
|
|
223
|
+
await server.request(googlePushBody(13, 'tok_exp'));
|
|
224
|
+
expect((await store.getByTransactionId('tok_exp'))?.status).toBe(SUBSCRIPTION_STATUS.EXPIRED);
|
|
225
|
+
});
|
|
226
|
+
it('SUBSCRIPTION_IN_GRACE_PERIOD (6) → grace_period', async () => {
|
|
227
|
+
await store.save(sampleSub({ originalTransactionId: 'tok_grace' }));
|
|
228
|
+
await server.request(googlePushBody(6, 'tok_grace'));
|
|
229
|
+
expect((await store.getByTransactionId('tok_grace'))?.status).toBe(SUBSCRIPTION_STATUS.GRACE_PERIOD);
|
|
230
|
+
});
|
|
231
|
+
it('SUBSCRIPTION_ON_HOLD (5) → on_hold', async () => {
|
|
232
|
+
await store.save(sampleSub({ originalTransactionId: 'tok_hold' }));
|
|
233
|
+
await server.request(googlePushBody(5, 'tok_hold'));
|
|
234
|
+
expect((await store.getByTransactionId('tok_hold'))?.status).toBe(SUBSCRIPTION_STATUS.ON_HOLD);
|
|
235
|
+
});
|
|
236
|
+
it('SUBSCRIPTION_PURCHASED (4) → active', async () => {
|
|
237
|
+
await store.save(sampleSub({ originalTransactionId: 'tok_buy', status: 'expired' }));
|
|
238
|
+
await server.request(googlePushBody(4, 'tok_buy'));
|
|
239
|
+
expect((await store.getByTransactionId('tok_buy'))?.status).toBe(SUBSCRIPTION_STATUS.ACTIVE);
|
|
240
|
+
});
|
|
241
|
+
it('unknown notification type (SUBSCRIPTION_DEFERRED=9) falls back to active', async () => {
|
|
242
|
+
// Type 9 is not handled by any isGoogle*Notification helper → else branch → ACTIVE
|
|
243
|
+
await store.save(sampleSub({ originalTransactionId: 'tok_deferred', status: 'on_hold' }));
|
|
244
|
+
await server.request(googlePushBody(9, 'tok_deferred'));
|
|
245
|
+
expect((await store.getByTransactionId('tok_deferred'))?.status).toBe(SUBSCRIPTION_STATUS.ACTIVE);
|
|
246
|
+
});
|
|
247
|
+
it('returns 200 even when purchaseToken is unknown (no store record, no serviceAccountKey)', async () => {
|
|
248
|
+
// Without serviceAccountKey, server cannot re-fetch from Play API.
|
|
249
|
+
// Should log a warning and ack 200 so Google doesn't retry forever.
|
|
250
|
+
const resp = await server.request(googlePushBody(2, 'tok_unknown_no_key'));
|
|
251
|
+
expect(resp.status).toBe(200);
|
|
252
|
+
expect(resp.body.received).toBe(true);
|
|
253
|
+
});
|
|
254
|
+
});
|
|
255
|
+
//# sourceMappingURL=webhook-google.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhook-google.test.js","sourceRoot":"","sources":["../../src/__tests__/webhook-google.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAC1D,OAAO,OAAO,MAAM,SAAS,CAAC;AAE9B,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,yBAAyB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAC/E,OAAO,EAAE,yBAAyB,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AAEpE,gFAAgF;AAEhF,SAAS,cAAc,CAAC,gBAAwB,EAAE,aAAqB,EAAE,IAGxE;IACC,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC;QAC1B,OAAO,EAAE,KAAK;QACd,WAAW,EAAE,IAAI,EAAE,WAAW,IAAI,iBAAiB;QACnD,eAAe,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;QACnC,wBAAwB,EAAE;YACxB,OAAO,EAAE,KAAK;YACd,gBAAgB;YAChB,aAAa;YACb,cAAc,EAAE,aAAa;SAC9B;KACF,CAAC,CAAC;IACH,OAAO;QACL,OAAO,EAAE;YACP,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC;YAC1C,SAAS,EAAE,IAAI,EAAE,SAAS,IAAI,OAAO,IAAI,CAAC,GAAG,EAAE,EAAE;SAClD;QACD,YAAY,EAAE,4BAA4B;KAC3C,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,GAAuB;IACrC,MAAM,EAAE,EAAE,WAAW,EAAE,iBAAiB,EAAE;IAC1C,QAAQ,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE;CACtB,CAAC;AAEF,MAAM,SAAS,GAAG,CAAC,SAAqC,EAAoB,EAAE,CAAC,CAAC;IAC9E,MAAM,EAAE,QAAQ;IAChB,SAAS,EAAE,aAAa;IACxB,QAAQ,EAAE,QAAQ;IAClB,MAAM,EAAE,QAAQ;IAChB,SAAS,EAAE,0BAA0B;IACrC,qBAAqB,EAAE,OAAO;IAC9B,WAAW,EAAE,0BAA0B;IACvC,SAAS,EAAE,IAAI;IACf,GAAG,SAAS;CACb,CAAC,CAAC;AAMH,SAAS,WAAW,CAClB,MAA0B,EAC1B,KAAgC,EAChC,iBAA6C;IAE7C,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;IACtB,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IACxB,GAAG,CAAC,GAAG,CAAC,mBAAmB,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,qBAAqB,EAAE,EAAE,iBAAiB,CAAC,CAAC,CAAC;IAC5F,OAAO;QACL,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO;YACzB,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YAC1B,MAAM,IAAI,GAAI,GAAG,CAAC,OAAO,EAAuB,CAAC,IAAI,CAAC;YACtD,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,oBAAoB,IAAI,wBAAwB,EAAE;oBACzE,MAAM,EAAE,MAAM;oBACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,GAAG,OAAO,EAAE;oBAC3D,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;iBAC3B,CAAC,CAAC;gBACH,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;gBAC/B,IAAI,MAAM,GAAY,IAAI,CAAC;gBAC3B,IAAI,CAAC;oBAAC,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAAC,CAAC;gBAAC,MAAM,CAAC,CAAC,kBAAkB,CAAC,CAAC;gBAC/D,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;YAC/C,CAAC;oBAAS,CAAC;gBACT,MAAM,IAAI,OAAO,CAAO,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YACvD,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC;AAED,gFAAgF;AAEhF,QAAQ,CAAC,mCAAmC,EAAE,GAAG,EAAE;IACjD,EAAE,CAAC,0CAA0C,EAAE,KAAK,IAAI,EAAE;QACxD,MAAM,KAAK,GAAG,IAAI,yBAAyB,EAAE,CAAC;QAC9C,MAAM,MAAM,GAAG,WAAW,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;QAE9C,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,EAAE,YAAY,EAAE,GAAG,EAAE,CAAC,CAAC;QACtF,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC9B,MAAM,CAAE,IAAI,CAAC,IAA+B,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;IACvF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8EAA8E,EAAE,KAAK,IAAI,EAAE;QAC5F,MAAM,KAAK,GAAG,IAAI,yBAAyB,EAAE,CAAC;QAC9C,MAAM,MAAM,GAAG,WAAW,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;QAE9C,2DAA2D;QAC3D,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,CAAC,CAAC;QAChF,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC;YAChC,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE;YACvE,YAAY,EAAE,GAAG;SAClB,CAAC,CAAC;QACH,uDAAuD;QACvD,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC9B,MAAM,CAAE,IAAI,CAAC,IAA8B,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACnE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,iFAAiF;AAEjF,QAAQ,CAAC,8CAA8C,EAAE,GAAG,EAAE;IAC5D,MAAM,kBAAkB,GAAuB;QAC7C,MAAM,EAAE,EAAE,WAAW,EAAE,iBAAiB,EAAE,YAAY,EAAE,2BAA2B,EAAE;QACrF,QAAQ,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE;KACtB,CAAC;IAEF,EAAE,CAAC,iDAAiD,EAAE,KAAK,IAAI,EAAE;QAC/D,MAAM,KAAK,GAAG,IAAI,yBAAyB,EAAE,CAAC;QAC9C,MAAM,MAAM,GAAG,WAAW,CAAC,kBAAkB,EAAE,KAAK,CAAC,CAAC;QAEtD,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC;QACjE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC9B,MAAM,CAAE,IAAI,CAAC,IAA+B,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IAC/E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8DAA8D,EAAE,KAAK,IAAI,EAAE;QAC5E,MAAM,KAAK,GAAG,IAAI,yBAAyB,EAAE,CAAC;QAC9C,MAAM,MAAM,GAAG,WAAW,CAAC,kBAAkB,EAAE,KAAK,CAAC,CAAC;QAEtD,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,OAAO,CAC/B,cAAc,CAAC,CAAC,EAAE,UAAU,CAAC,EAC7B,EAAE,aAAa,EAAE,uBAAuB,EAAE,CAC3C,CAAC;QACF,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC9B,MAAM,CAAE,IAAI,CAAC,IAA+B,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IAC/E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4EAA4E,EAAE,KAAK,IAAI,EAAE;QAC1F,MAAM,KAAK,GAAG,IAAI,yBAAyB,EAAE,CAAC;QAC9C,MAAM,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,qBAAqB,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC;QACrE,MAAM,MAAM,GAAG,WAAW,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC,kBAAkB;QAEjE,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC;QACnE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAChC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,iFAAiF;AAEjF,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;IACrC,EAAE,CAAC,mDAAmD,EAAE,KAAK,IAAI,EAAE;QACjE,MAAM,GAAG,GAAG,EAAE,OAAO,EAAE,EAAE,EAAqB,CAAC;QAC/C,MAAM,CAAC,MAAM,qBAAqB,CAAC,GAAG,EAAE,qBAAqB,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC9E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gDAAgD,EAAE,KAAK,IAAI,EAAE;QAC9D,MAAM,GAAG,GAAG,EAAE,OAAO,EAAE,EAAE,aAAa,EAAE,oBAAoB,EAAE,EAAqB,CAAC;QACpF,MAAM,CAAC,MAAM,qBAAqB,CAAC,GAAG,EAAE,qBAAqB,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC9E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2DAA2D,EAAE,KAAK,IAAI,EAAE;QACzE,qFAAqF;QACrF,MAAM,GAAG,GAAG,EAAE,OAAO,EAAE,EAAE,aAAa,EAAE,sBAAsB,EAAE,EAAqB,CAAC;QACtF,MAAM,CAAC,MAAM,qBAAqB,CAAC,GAAG,EAAE,qBAAqB,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC9E,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,iFAAiF;AAEjF,QAAQ,CAAC,wCAAwC,EAAE,GAAG,EAAE;IACtD,EAAE,CAAC,iEAAiE,EAAE,KAAK,IAAI,EAAE;QAC/E,MAAM,KAAK,GAAG,IAAI,yBAAyB,EAAE,CAAC;QAC9C,MAAM,MAAM,GAAG,WAAW,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;QAE9C,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,EAAE,SAAS,EAAE,EAAE,WAAW,EAAE,kBAAkB,EAAE,CAAC,CAAC,CAAC;QACrG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC9B,MAAM,CAAE,IAAI,CAAC,IAA+B,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;IACxF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oEAAoE,EAAE,KAAK,IAAI,EAAE;QAClF,MAAM,UAAU,GAAuB;YACrC,MAAM,EAAE,EAAE,EAAG,6BAA6B;YAC1C,QAAQ,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE;SACtB,CAAC;QACF,MAAM,KAAK,GAAG,IAAI,yBAAyB,EAAE,CAAC;QAC9C,MAAM,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,qBAAqB,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC;QACnE,MAAM,MAAM,GAAG,WAAW,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;QAE9C,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,EAAE,UAAU,EAAE,EAAE,WAAW,EAAE,kBAAkB,EAAE,CAAC,CAAC,CAAC;QACtG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAChC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,gFAAgF;AAEhF,QAAQ,CAAC,gCAAgC,EAAE,GAAG,EAAE;IAC9C,IAAI,KAAgC,CAAC;IACrC,IAAI,iBAA4C,CAAC;IACjD,IAAI,MAAkB,CAAC;IAEvB,UAAU,CAAC,GAAG,EAAE;QACd,KAAK,GAAG,IAAI,yBAAyB,EAAE,CAAC;QACxC,iBAAiB,GAAG,IAAI,yBAAyB,EAAE,CAAC;QACpD,MAAM,GAAG,WAAW,CAAC,UAAU,EAAE,KAAK,EAAE,iBAAiB,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wDAAwD,EAAE,KAAK,IAAI,EAAE;QACtE,MAAM,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,qBAAqB,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC;QAErE,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,EAAE,YAAY,EAAE,EAAE,SAAS,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC;QAEjG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC9B,MAAM,CAAE,IAAI,CAAC,IAA8B,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjE,MAAM,CAAE,IAAI,CAAC,IAA8B,CAAC,OAAO,CAAC,CAAC,aAAa,EAAE,CAAC;IACvE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,KAAK,IAAI,EAAE;QACrE,MAAM,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC;QAEvF,MAAM,IAAI,GAAG,cAAc,CAAC,CAAC,EAAE,YAAY,EAAE,EAAE,SAAS,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,WAAW;QAEvF,2CAA2C;QAC3C,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC3B,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC;QAElG,+BAA+B;QAC/B,MAAM,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC;QAEvF,gDAAgD;QAChD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC1C,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAChC,MAAM,CAAE,MAAM,CAAC,IAA6B,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjE,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAClG,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,+EAA+E;AAE/E,QAAQ,CAAC,4CAA4C,EAAE,GAAG,EAAE;IAC1D,IAAI,KAAgC,CAAC;IACrC,IAAI,MAAkB,CAAC;IAEvB,UAAU,CAAC,GAAG,EAAE;QACd,KAAK,GAAG,IAAI,yBAAyB,EAAE,CAAC;QACxC,MAAM,GAAG,WAAW,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE,KAAK,IAAI,EAAE;QACpD,MAAM,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,qBAAqB,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC;QAErE,MAAM,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC;QAEtD,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC;IACpG,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE,KAAK,IAAI,EAAE;QACpD,MAAM,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,qBAAqB,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC;QAErE,MAAM,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,EAAE,YAAY,CAAC,CAAC,CAAC;QAEvD,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC;IACpG,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qCAAqC,EAAE,KAAK,IAAI,EAAE;QACnD,MAAM,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,qBAAqB,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC;QAElE,MAAM,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC;QAEpD,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC;IAChG,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iDAAiD,EAAE,KAAK,IAAI,EAAE;QAC/D,MAAM,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,qBAAqB,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC;QAEpE,MAAM,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC;QAErD,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,kBAAkB,CAAC,WAAW,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,YAAY,CAAC,CAAC;IACvG,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oCAAoC,EAAE,KAAK,IAAI,EAAE;QAClD,MAAM,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,qBAAqB,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC;QAEnE,MAAM,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC;QAEpD,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,kBAAkB,CAAC,UAAU,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC;IACjG,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qCAAqC,EAAE,KAAK,IAAI,EAAE;QACnD,MAAM,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,qBAAqB,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC;QAErF,MAAM,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC;QAEnD,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAC/F,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0EAA0E,EAAE,KAAK,IAAI,EAAE;QACxF,mFAAmF;QACnF,MAAM,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC;QAE1F,MAAM,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC;QAExD,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,kBAAkB,CAAC,cAAc,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC;IACpG,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wFAAwF,EAAE,KAAK,IAAI,EAAE;QACtG,mEAAmE;QACnE,oEAAoE;QACpE,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,EAAE,oBAAoB,CAAC,CAAC,CAAC;QAC3E,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC9B,MAAM,CAAE,IAAI,CAAC,IAA8B,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACnE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
package/dist/cache.js
CHANGED
|
@@ -36,8 +36,4 @@ export function getDefaultCache() {
|
|
|
36
36
|
export function setDefaultCache(adapter) {
|
|
37
37
|
defaultAdapter = adapter;
|
|
38
38
|
}
|
|
39
|
-
/** Test helper — reset the default adapter to a fresh in-memory one. */
|
|
40
|
-
export function __resetDefaultCacheForTests() {
|
|
41
|
-
defaultAdapter = new InMemoryCacheAdapter();
|
|
42
|
-
}
|
|
43
39
|
//# sourceMappingURL=cache.js.map
|
package/dist/cache.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"AAyBA;;GAEG;AACH,MAAM,OAAO,oBAAoB;IACd,OAAO,GAAG,IAAI,GAAG,EAAiB,CAAC;IAEpD,KAAK,CAAC,GAAG,CAAI,GAAW;QACtB,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC;QACxB,IAAI,KAAK,CAAC,SAAS,KAAK,CAAC,IAAI,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;YAC1D,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACzB,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,KAAK,CAAC,KAAU,CAAC;IAC1B,CAAC;IAED,KAAK,CAAC,GAAG,CAAI,GAAW,EAAE,KAAQ,EAAE,UAAmB;QACrD,MAAM,SAAS,GAAG,UAAU,IAAI,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QACpF,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;IAC9C,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,GAAW;QACnB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;IAED,oFAAoF;IACpF,KAAK;QACH,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;CACF;AAED;;;GAGG;AACH,IAAI,cAAc,GAAiB,IAAI,oBAAoB,EAAE,CAAC;AAE9D,MAAM,UAAU,eAAe;IAC7B,OAAO,cAAc,CAAC;AACxB,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,OAAqB;IACnD,cAAc,GAAG,OAAO,CAAC;AAC3B,CAAC
|
|
1
|
+
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"AAyBA;;GAEG;AACH,MAAM,OAAO,oBAAoB;IACd,OAAO,GAAG,IAAI,GAAG,EAAiB,CAAC;IAEpD,KAAK,CAAC,GAAG,CAAI,GAAW;QACtB,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC;QACxB,IAAI,KAAK,CAAC,SAAS,KAAK,CAAC,IAAI,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;YAC1D,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACzB,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,KAAK,CAAC,KAAU,CAAC;IAC1B,CAAC;IAED,KAAK,CAAC,GAAG,CAAI,GAAW,EAAE,KAAQ,EAAE,UAAmB;QACrD,MAAM,SAAS,GAAG,UAAU,IAAI,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QACpF,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;IAC9C,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,GAAW;QACnB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;IAED,oFAAoF;IACpF,KAAK;QACH,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;CACF;AAED;;;GAGG;AACH,IAAI,cAAc,GAAiB,IAAI,oBAAoB,EAAE,CAAC;AAE9D,MAAM,UAAU,eAAe;IAC7B,OAAO,cAAc,CAAC;AACxB,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,OAAqB;IACnD,cAAc,GAAG,OAAO,CAAC;AAC3B,CAAC"}
|
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) {
|
|
@@ -1536,14 +1542,22 @@ function createPurchaseRouter(config, purchaseStore) {
|
|
|
1536
1542
|
const { platform, receipt, userId, productId, type } = body;
|
|
1537
1543
|
try {
|
|
1538
1544
|
if (type === shared.PURCHASE_TYPE.NON_CONSUMABLE) {
|
|
1539
|
-
const
|
|
1540
|
-
|
|
1541
|
-
|
|
1545
|
+
const owned = (await purchaseStore.getPurchasesByUserId(userId)).find(
|
|
1546
|
+
(p) => p.productId === productId
|
|
1547
|
+
);
|
|
1548
|
+
if (owned) {
|
|
1549
|
+
const response2 = {
|
|
1550
|
+
valid: true,
|
|
1551
|
+
purchase: { ...owned, userId },
|
|
1552
|
+
action: "restored"
|
|
1553
|
+
};
|
|
1554
|
+
res.status(200).json(response2);
|
|
1542
1555
|
return;
|
|
1543
1556
|
}
|
|
1544
1557
|
}
|
|
1545
1558
|
let transactionId = null;
|
|
1546
1559
|
let purchasedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
1560
|
+
let boundAccountId = null;
|
|
1547
1561
|
if (platform === "apple") {
|
|
1548
1562
|
if (!config.apple) {
|
|
1549
1563
|
sendError(res, 500, shared.ONESUB_ERROR_CODE.APPLE_CONFIG_MISSING, "Apple configuration not provided", NO_PURCHASE);
|
|
@@ -1553,6 +1567,7 @@ function createPurchaseRouter(config, purchaseStore) {
|
|
|
1553
1567
|
if (result) {
|
|
1554
1568
|
transactionId = result.transactionId;
|
|
1555
1569
|
purchasedAt = result.purchasedAt;
|
|
1570
|
+
boundAccountId = result.appAccountToken ?? null;
|
|
1556
1571
|
}
|
|
1557
1572
|
} else {
|
|
1558
1573
|
if (!config.google) {
|
|
@@ -1568,12 +1583,26 @@ function createPurchaseRouter(config, purchaseStore) {
|
|
|
1568
1583
|
if (result) {
|
|
1569
1584
|
transactionId = result.transactionId;
|
|
1570
1585
|
purchasedAt = result.purchasedAt;
|
|
1586
|
+
boundAccountId = result.obfuscatedExternalAccountId ?? null;
|
|
1571
1587
|
}
|
|
1572
1588
|
}
|
|
1573
1589
|
if (!transactionId) {
|
|
1574
1590
|
sendError(res, 422, shared.ONESUB_ERROR_CODE.RECEIPT_VALIDATION_FAILED, "Receipt validation failed", NO_PURCHASE);
|
|
1575
1591
|
return;
|
|
1576
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
|
+
}
|
|
1577
1606
|
const existing = await purchaseStore.getPurchaseByTransactionId(transactionId);
|
|
1578
1607
|
let action = "new";
|
|
1579
1608
|
if (existing) {
|