@curless/shopify-storefront 0.1.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__/card-contract.test.d.ts +2 -0
- package/dist/__tests__/card-contract.test.d.ts.map +1 -0
- package/dist/__tests__/card-contract.test.js +22 -0
- package/dist/__tests__/card-contract.test.js.map +1 -0
- package/dist/__tests__/catalog-registry.test.d.ts +2 -0
- package/dist/__tests__/catalog-registry.test.d.ts.map +1 -0
- package/dist/__tests__/catalog-registry.test.js +109 -0
- package/dist/__tests__/catalog-registry.test.js.map +1 -0
- package/dist/__tests__/challenge.test.d.ts +2 -0
- package/dist/__tests__/challenge.test.d.ts.map +1 -0
- package/dist/__tests__/challenge.test.js +46 -0
- package/dist/__tests__/challenge.test.js.map +1 -0
- package/dist/__tests__/config.test.d.ts +2 -0
- package/dist/__tests__/config.test.d.ts.map +1 -0
- package/dist/__tests__/config.test.js +123 -0
- package/dist/__tests__/config.test.js.map +1 -0
- package/dist/__tests__/connection-state.test.d.ts +2 -0
- package/dist/__tests__/connection-state.test.d.ts.map +1 -0
- package/dist/__tests__/connection-state.test.js +40 -0
- package/dist/__tests__/connection-state.test.js.map +1 -0
- package/dist/__tests__/multi-token-store.test.d.ts +2 -0
- package/dist/__tests__/multi-token-store.test.d.ts.map +1 -0
- package/dist/__tests__/multi-token-store.test.js +89 -0
- package/dist/__tests__/multi-token-store.test.js.map +1 -0
- package/dist/__tests__/oauth.test.d.ts +2 -0
- package/dist/__tests__/oauth.test.d.ts.map +1 -0
- package/dist/__tests__/oauth.test.js +112 -0
- package/dist/__tests__/oauth.test.js.map +1 -0
- package/dist/__tests__/output-schema.test.d.ts +2 -0
- package/dist/__tests__/output-schema.test.d.ts.map +1 -0
- package/dist/__tests__/output-schema.test.js +112 -0
- package/dist/__tests__/output-schema.test.js.map +1 -0
- package/dist/__tests__/ping.test.d.ts +2 -0
- package/dist/__tests__/ping.test.d.ts.map +1 -0
- package/dist/__tests__/ping.test.js +22 -0
- package/dist/__tests__/ping.test.js.map +1 -0
- package/dist/__tests__/rate-limit.test.d.ts +2 -0
- package/dist/__tests__/rate-limit.test.d.ts.map +1 -0
- package/dist/__tests__/rate-limit.test.js +46 -0
- package/dist/__tests__/rate-limit.test.js.map +1 -0
- package/dist/__tests__/stock.test.d.ts +2 -0
- package/dist/__tests__/stock.test.d.ts.map +1 -0
- package/dist/__tests__/stock.test.js +109 -0
- package/dist/__tests__/stock.test.js.map +1 -0
- package/dist/__tests__/tenant.test.d.ts +2 -0
- package/dist/__tests__/tenant.test.d.ts.map +1 -0
- package/dist/__tests__/tenant.test.js +105 -0
- package/dist/__tests__/tenant.test.js.map +1 -0
- package/dist/__tests__/tools.test.d.ts +2 -0
- package/dist/__tests__/tools.test.d.ts.map +1 -0
- package/dist/__tests__/tools.test.js +543 -0
- package/dist/__tests__/tools.test.js.map +1 -0
- package/dist/__tests__/upstream-cap.test.d.ts +2 -0
- package/dist/__tests__/upstream-cap.test.d.ts.map +1 -0
- package/dist/__tests__/upstream-cap.test.js +78 -0
- package/dist/__tests__/upstream-cap.test.js.map +1 -0
- package/dist/__tests__/webhooks.test.d.ts +2 -0
- package/dist/__tests__/webhooks.test.d.ts.map +1 -0
- package/dist/__tests__/webhooks.test.js +88 -0
- package/dist/__tests__/webhooks.test.js.map +1 -0
- package/dist/card.generated.d.ts +2 -0
- package/dist/card.generated.d.ts.map +1 -0
- package/dist/card.generated.js +6 -0
- package/dist/card.generated.js.map +1 -0
- package/dist/catalog-registry.d.ts +44 -0
- package/dist/catalog-registry.d.ts.map +1 -0
- package/dist/catalog-registry.js +105 -0
- package/dist/catalog-registry.js.map +1 -0
- package/dist/catalog.d.ts +51 -0
- package/dist/catalog.d.ts.map +1 -0
- package/dist/catalog.js +189 -0
- package/dist/catalog.js.map +1 -0
- package/dist/challenge.d.ts +11 -0
- package/dist/challenge.d.ts.map +1 -0
- package/dist/challenge.js +36 -0
- package/dist/challenge.js.map +1 -0
- package/dist/config.d.ts +141 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +65 -0
- package/dist/config.js.map +1 -0
- package/dist/connection.d.ts +10 -0
- package/dist/connection.d.ts.map +1 -0
- package/dist/connection.js +21 -0
- package/dist/connection.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +974 -0
- package/dist/index.js.map +1 -0
- package/dist/legal.d.ts +52 -0
- package/dist/legal.d.ts.map +1 -0
- package/dist/legal.js +139 -0
- package/dist/legal.js.map +1 -0
- package/dist/load-config.d.ts +11 -0
- package/dist/load-config.d.ts.map +1 -0
- package/dist/load-config.js +23 -0
- package/dist/load-config.js.map +1 -0
- package/dist/multi-token-store.d.ts +18 -0
- package/dist/multi-token-store.d.ts.map +1 -0
- package/dist/multi-token-store.js +95 -0
- package/dist/multi-token-store.js.map +1 -0
- package/dist/oauth.d.ts +20 -0
- package/dist/oauth.d.ts.map +1 -0
- package/dist/oauth.js +123 -0
- package/dist/oauth.js.map +1 -0
- package/dist/rate-limit.d.ts +15 -0
- package/dist/rate-limit.d.ts.map +1 -0
- package/dist/rate-limit.js +56 -0
- package/dist/rate-limit.js.map +1 -0
- package/dist/stock.d.ts +39 -0
- package/dist/stock.d.ts.map +1 -0
- package/dist/stock.js +77 -0
- package/dist/stock.js.map +1 -0
- package/dist/tenant.d.ts +69 -0
- package/dist/tenant.d.ts.map +1 -0
- package/dist/tenant.js +68 -0
- package/dist/tenant.js.map +1 -0
- package/dist/token-store.d.ts +16 -0
- package/dist/token-store.d.ts.map +1 -0
- package/dist/token-store.js +47 -0
- package/dist/token-store.js.map +1 -0
- package/dist/tools.d.ts +201 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +779 -0
- package/dist/tools.js.map +1 -0
- package/dist/webhooks.d.ts +30 -0
- package/dist/webhooks.d.ts.map +1 -0
- package/dist/webhooks.js +69 -0
- package/dist/webhooks.js.map +1 -0
- package/package.json +53 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
// The ceiling on how much of the MERCHANT's Shopify quota this service can
|
|
2
|
+
// spend, whoever is asking.
|
|
3
|
+
//
|
|
4
|
+
// A per-IP limit is the wrong unit for it. One uncached variantsFor costs up to
|
|
5
|
+
// three Admin API calls, the cache holds 50 of 382 products, and cycling handles
|
|
6
|
+
// defeats it by design — so 60 calls a minute per address is 180 Admin calls a
|
|
7
|
+
// minute from one caller, and nothing stops the second. Exhausting that quota
|
|
8
|
+
// does not degrade us; it degrades the merchant's own storefront.
|
|
9
|
+
import { describe, expect, test, vi } from 'vitest';
|
|
10
|
+
import { Catalog } from '../catalog.js';
|
|
11
|
+
const CONFIG = { shopDomain: 'rqxbft-fw.myshopify.com', adminToken: 'shpat_test' };
|
|
12
|
+
const variantsStub = (onCall) => vi.fn(async () => {
|
|
13
|
+
onCall();
|
|
14
|
+
return new Response(JSON.stringify({
|
|
15
|
+
data: {
|
|
16
|
+
shop: { currencyCode: 'USD' },
|
|
17
|
+
productByHandle: {
|
|
18
|
+
variants: {
|
|
19
|
+
pageInfo: { hasNextPage: false, endCursor: null },
|
|
20
|
+
nodes: [
|
|
21
|
+
{
|
|
22
|
+
id: 'gid://shopify/ProductVariant/1',
|
|
23
|
+
sku: null,
|
|
24
|
+
title: '-2.00',
|
|
25
|
+
price: '27.99',
|
|
26
|
+
compareAtPrice: null,
|
|
27
|
+
availableForSale: true,
|
|
28
|
+
selectedOptions: [{ name: 'Diopter', value: '-2.00' }],
|
|
29
|
+
image: null,
|
|
30
|
+
},
|
|
31
|
+
],
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
}), { status: 200, headers: { 'content-type': 'application/json' } });
|
|
36
|
+
});
|
|
37
|
+
const withStub = async (fn) => {
|
|
38
|
+
const real = globalThis.fetch;
|
|
39
|
+
let n = 0;
|
|
40
|
+
globalThis.fetch = variantsStub(() => {
|
|
41
|
+
n += 1;
|
|
42
|
+
});
|
|
43
|
+
try {
|
|
44
|
+
return await fn(new Catalog(async () => CONFIG, () => { }), () => n);
|
|
45
|
+
}
|
|
46
|
+
finally {
|
|
47
|
+
globalThis.fetch = real;
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
describe('upstream ceiling', () => {
|
|
51
|
+
test('a caller cycling handles cannot spend the quota without bound', () => withStub(async (catalog, calls) => {
|
|
52
|
+
// 400 distinct products, more than the 382 this store has and far more
|
|
53
|
+
// than the 50 the cache holds — the exact shape of the attack.
|
|
54
|
+
for (let i = 0; i < 400; i++)
|
|
55
|
+
await catalog.variantsFor(`lens-${i}`);
|
|
56
|
+
expect(calls()).toBeLessThanOrEqual(90);
|
|
57
|
+
expect(calls(), 'still served plenty before capping').toBeGreaterThan(50);
|
|
58
|
+
}));
|
|
59
|
+
// Refusing to fetch must not turn into refusing to answer. A product already
|
|
60
|
+
// read stays readable while the ceiling holds.
|
|
61
|
+
test('a cached product is still served after the ceiling is reached', () => withStub(async (catalog, _calls) => {
|
|
62
|
+
const first = await catalog.variantsFor('matcha-green');
|
|
63
|
+
expect(first).toHaveLength(1);
|
|
64
|
+
for (let i = 0; i < 200; i++)
|
|
65
|
+
await catalog.variantsFor(`other-${i}`);
|
|
66
|
+
// Past the ceiling, and past the TTL so the cache would normally refetch.
|
|
67
|
+
const later = await catalog.variantsFor('matcha-green', Date.now() + 10 * 60_000);
|
|
68
|
+
expect(later, 'stale beats empty').toHaveLength(1);
|
|
69
|
+
}));
|
|
70
|
+
test('ordinary shopping is untouched by it', () => withStub(async (catalog, calls) => {
|
|
71
|
+
// A shopper opening ten lenses, looking at three of them twice.
|
|
72
|
+
for (const h of ['a', 'b', 'c', 'a', 'd', 'e', 'b', 'f', 'g', 'c', 'h', 'i', 'j']) {
|
|
73
|
+
await catalog.variantsFor(h);
|
|
74
|
+
}
|
|
75
|
+
expect(calls(), 'repeat looks are free').toBe(10);
|
|
76
|
+
}));
|
|
77
|
+
});
|
|
78
|
+
//# sourceMappingURL=upstream-cap.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upstream-cap.test.js","sourceRoot":"","sources":["../../src/__tests__/upstream-cap.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhooks.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/webhooks.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { createHmac } from 'node:crypto';
|
|
2
|
+
import { describe, expect, test } from 'vitest';
|
|
3
|
+
import { handleWebhook, verifyWebhookHmac } from '../webhooks.js';
|
|
4
|
+
const SECRET = 'shpss_test_secret';
|
|
5
|
+
const sign = (body) => createHmac('sha256', SECRET).update(body, 'utf8').digest('base64');
|
|
6
|
+
describe('webhook signatures', () => {
|
|
7
|
+
const body = '{"shop_domain":"a-shop.myshopify.com","orders_requested":[1,2]}';
|
|
8
|
+
test('accepts a genuine delivery', () => {
|
|
9
|
+
expect(verifyWebhookHmac(SECRET, body, sign(body))).toBe(true);
|
|
10
|
+
});
|
|
11
|
+
test('rejects a body that changed by one byte', () => {
|
|
12
|
+
expect(verifyWebhookHmac(SECRET, `${body} `, sign(body))).toBe(false);
|
|
13
|
+
});
|
|
14
|
+
test('rejects a signature made with another secret', () => {
|
|
15
|
+
const other = createHmac('sha256', 'someone-else').update(body).digest('base64');
|
|
16
|
+
expect(verifyWebhookHmac(SECRET, body, other)).toBe(false);
|
|
17
|
+
});
|
|
18
|
+
// Base64, not hex — the OAuth callback uses hex and mixing them up is the
|
|
19
|
+
// kind of mistake that verifies nothing while looking like it works.
|
|
20
|
+
test('rejects the same digest in hex', () => {
|
|
21
|
+
const hex = createHmac('sha256', SECRET).update(body).digest('hex');
|
|
22
|
+
expect(verifyWebhookHmac(SECRET, body, hex)).toBe(false);
|
|
23
|
+
});
|
|
24
|
+
test.each([
|
|
25
|
+
['no header', ''],
|
|
26
|
+
['garbage', '!!!!not base64!!!!'],
|
|
27
|
+
['a short digest', Buffer.from('short').toString('base64')],
|
|
28
|
+
])('rejects %s without throwing', (_label, header) => {
|
|
29
|
+
expect(() => verifyWebhookHmac(SECRET, body, header)).not.toThrow();
|
|
30
|
+
expect(verifyWebhookHmac(SECRET, body, header)).toBe(false);
|
|
31
|
+
});
|
|
32
|
+
test('no secret configured verifies nothing', () => {
|
|
33
|
+
// Fail closed. An unset secret must not turn into "everything is genuine".
|
|
34
|
+
expect(verifyWebhookHmac('', body, sign(body))).toBe(false);
|
|
35
|
+
});
|
|
36
|
+
test('verifies the RAW body, not a re-serialised copy', () => {
|
|
37
|
+
// Shopify signs bytes. Re-encoding the parsed JSON reorders keys and drops
|
|
38
|
+
// spacing, so a handler that verified `JSON.stringify(parsed)` would reject
|
|
39
|
+
// every genuine delivery.
|
|
40
|
+
const raw = '{"b":1,\n "a":2}';
|
|
41
|
+
const reserialised = JSON.stringify(JSON.parse(raw));
|
|
42
|
+
expect(verifyWebhookHmac(SECRET, raw, sign(raw))).toBe(true);
|
|
43
|
+
expect(verifyWebhookHmac(SECRET, reserialised, sign(raw))).toBe(false);
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
describe('what each topic does', () => {
|
|
47
|
+
const collect = () => {
|
|
48
|
+
const forgotten = [];
|
|
49
|
+
return { forgotten, handlers: { forgetShop: (s) => void forgotten.push(s) } };
|
|
50
|
+
};
|
|
51
|
+
test('shop/redact forgets the shop', async () => {
|
|
52
|
+
const { forgotten, handlers } = collect();
|
|
53
|
+
const r = await handleWebhook('shop/redact', 'a-shop.myshopify.com', handlers);
|
|
54
|
+
expect(r.status).toBe(200);
|
|
55
|
+
expect(forgotten).toEqual(['a-shop.myshopify.com']);
|
|
56
|
+
});
|
|
57
|
+
test('app/uninstalled forgets the shop too', async () => {
|
|
58
|
+
const { forgotten, handlers } = collect();
|
|
59
|
+
await handleWebhook('app/uninstalled', 'a-shop.myshopify.com', handlers);
|
|
60
|
+
expect(forgotten).toEqual(['a-shop.myshopify.com']);
|
|
61
|
+
});
|
|
62
|
+
test('a retried delivery is not an error', async () => {
|
|
63
|
+
// Shopify retries. A second forget must be as ordinary as the first.
|
|
64
|
+
const { forgotten, handlers } = collect();
|
|
65
|
+
await handleWebhook('shop/redact', 'a-shop.myshopify.com', handlers);
|
|
66
|
+
const again = await handleWebhook('shop/redact', 'a-shop.myshopify.com', handlers);
|
|
67
|
+
expect(again.status).toBe(200);
|
|
68
|
+
expect(forgotten).toHaveLength(2);
|
|
69
|
+
});
|
|
70
|
+
test('customer topics answer honestly and forget nothing', async () => {
|
|
71
|
+
const { forgotten, handlers } = collect();
|
|
72
|
+
for (const topic of ['customers/data_request', 'customers/redact']) {
|
|
73
|
+
const r = await handleWebhook(topic, 'a-shop.myshopify.com', handlers);
|
|
74
|
+
expect(r.status).toBe(200);
|
|
75
|
+
}
|
|
76
|
+
// These are about a SHOPPER, not the shop. Forgetting the shop here would
|
|
77
|
+
// disconnect a merchant because one of their customers asked a question.
|
|
78
|
+
expect(forgotten).toEqual([]);
|
|
79
|
+
});
|
|
80
|
+
test('an unknown topic is acknowledged, not failed', async () => {
|
|
81
|
+
// A 4xx earns retries and eventually a disabled webhook, for a message we
|
|
82
|
+
// had nothing to do with.
|
|
83
|
+
const { handlers } = collect();
|
|
84
|
+
const r = await handleWebhook('orders/create', 'a-shop.myshopify.com', handlers);
|
|
85
|
+
expect(r.status).toBe(200);
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
//# sourceMappingURL=webhooks.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhooks.test.js","sourceRoot":"","sources":["../../src/__tests__/webhooks.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"card.generated.d.ts","sourceRoot":"","sources":["../src/card.generated.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,eAAe,EAAE,MAGZ,CAAC"}
|