@ordergroove/offers 2.49.0 → 2.49.1-alpha-PR-1517-4.76

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ordergroove/offers",
3
- "version": "2.49.0",
3
+ "version": "2.49.1-alpha-PR-1517-4.76+5e3f5ef73",
4
4
  "description": "offer state component",
5
5
  "author": "Eugenio Lattanzio <eugenio63@gmail.com>",
6
6
  "homepage": "https://github.com/ordergroove/plush-toys#readme",
@@ -50,5 +50,5 @@
50
50
  "@ordergroove/offers-templates": "^0.10.4",
51
51
  "@types/lodash.memoize": "^4.1.9"
52
52
  },
53
- "gitHead": "7b58b4c90e38ed68f42a40be308ecea2b6589d9e"
53
+ "gitHead": "5e3f5ef73dcd7f5843a3db07236c1cf37cfa2140"
54
54
  }
@@ -2,6 +2,6 @@ import { STATIC_HOST } from './core/constants';
2
2
 
3
3
  const mainJs = document.createElement('script');
4
4
  mainJs.setAttribute('id', `mock-main-js`);
5
- mainJs.setAttribute('src', `http://${STATIC_HOST}`);
5
+ mainJs.setAttribute('src', `http://${STATIC_HOST}/test-merchant/main.js`);
6
6
  mainJs.dataset.shopifySellingPlans = true;
7
7
  document.head.appendChild(mainJs);
@@ -0,0 +1,110 @@
1
+ import fetchMock from 'fetch-mock';
2
+ import { authorizeShopifyCustomer } from '../shopifyBootstrap';
3
+ import { AUTHORIZE, UNAUTHORIZED, STATIC_HOST } from '../../core/constants';
4
+
5
+ // init-shopify-tests.js inserts this script before any test runs
6
+ const mainJsScript = document.querySelector(`script[src^="http://${STATIC_HOST}"]`);
7
+
8
+ const MERCHANT_ID = 'test-merchant';
9
+ const AUTH_ENDPOINT = '/apps/subscriptions/auth/';
10
+
11
+ describe('authorizeShopifyCustomer', () => {
12
+ let store;
13
+
14
+ beforeEach(() => {
15
+ store = { dispatch: jasmine.createSpy('dispatch') };
16
+ });
17
+
18
+ afterEach(() => {
19
+ delete mainJsScript.dataset.customer;
20
+ // expire the og_auth cookie; just setting to empty string will be ignored
21
+ document.cookie = 'og_auth=; expires=Thu, 01 Jan 1970 00:00:01 GMT; path=/';
22
+ fetchMock.clearHistory();
23
+ fetchMock.removeRoutes().unmockGlobal();
24
+ });
25
+
26
+ it('fetches OG signature, sets og_auth cookie, and dispatches AUTHORIZE when encoded customer is on main.js script', async () => {
27
+ // The Shopify integration encodes customer data as btoa("id|timestamp|signature|email")
28
+ // on the data-customer attribute of the main.js script tag.
29
+ const shopifyCustomerId = 'shopify-cust-42';
30
+ const shopifyTimestamp = '1700000000';
31
+ const shopifySignature = 'shopify-raw-sig';
32
+
33
+ mainJsScript.dataset.customer = btoa(
34
+ `${shopifyCustomerId}|${shopifyTimestamp}|${shopifySignature}|test@example.com`
35
+ );
36
+
37
+ // OG's auth endpoint returns a signed customer ID embedded between marker strings.
38
+ const ogCustomerId = 'og-cust-99';
39
+ const ogTimestamp = 1700000099;
40
+ const ogSignature = 'og-server-sig';
41
+
42
+ fetchMock.route(
43
+ `${AUTH_ENDPOINT}?customer=${shopifyCustomerId}&customer_signature=${shopifySignature}&customer_timestamp=${shopifyTimestamp}`,
44
+ `<main>
45
+ og_auth_begin
46
+ {
47
+ "customerId": "${ogCustomerId}",
48
+ "timestamp": ${ogTimestamp},
49
+ "signature": "${ogSignature}"
50
+ }
51
+ og_auth_end
52
+ </main>`,
53
+ { method: 'GET' }
54
+ );
55
+ fetchMock.mockGlobal();
56
+
57
+ await authorizeShopifyCustomer({ store });
58
+
59
+ const binarySignature = btoa(ogSignature);
60
+
61
+ expect(document.cookie).toContain(`og_auth=${ogCustomerId}|${ogTimestamp}|${binarySignature}`);
62
+
63
+ expect(store.dispatch).toHaveBeenCalledWith({
64
+ type: AUTHORIZE,
65
+ payload: {
66
+ public_id: MERCHANT_ID,
67
+ sig_field: ogCustomerId,
68
+ ts: ogTimestamp,
69
+ sig: binarySignature
70
+ }
71
+ });
72
+ });
73
+
74
+ it('reuses existing og_auth cookie and dispatches AUTHORIZE without fetching', async () => {
75
+ mainJsScript.dataset.customer = btoa('shopify-cust-42|1700000000|shopify-raw-sig|test@example.com');
76
+
77
+ const cachedCustomerId = 'cached-cust';
78
+ const cachedTimestamp = 1699999999;
79
+ const cachedSig = btoa('cached-server-sig');
80
+ document.cookie = `og_auth=${cachedCustomerId}|${cachedTimestamp}|${cachedSig}; path=/`;
81
+
82
+ fetchMock.mockGlobal(); // no routes — any fetch call would throw
83
+
84
+ await authorizeShopifyCustomer({ store });
85
+
86
+ expect(fetchMock.callHistory.called()).toBe(false);
87
+ expect(store.dispatch).toHaveBeenCalledWith({
88
+ type: AUTHORIZE,
89
+ payload: {
90
+ public_id: MERCHANT_ID,
91
+ sig_field: cachedCustomerId,
92
+ ts: cachedTimestamp,
93
+ sig: cachedSig
94
+ }
95
+ });
96
+ });
97
+
98
+ it('clears og_auth cookie and does not dispatch when no customer is present', async () => {
99
+ document.cookie = 'og_auth=existing-value; path=/';
100
+ expect(document.cookie).toContain('og_auth=existing-value');
101
+
102
+ await authorizeShopifyCustomer({ store });
103
+
104
+ expect(document.cookie).not.toContain('og_auth=');
105
+ expect(store.dispatch).toHaveBeenCalledWith({
106
+ type: UNAUTHORIZED,
107
+ payload: jasmine.any(String)
108
+ });
109
+ });
110
+ });
@@ -1,4 +1,4 @@
1
- import { authorize } from '../core/actions';
1
+ import { authorize, unauthorized } from '../core/actions';
2
2
  import { clearCookie, getCookieValue, getMainJs, resolveEnvAndMerchant } from '../core/utils';
3
3
 
4
4
  const SHOPIFY_OG_AUTH_ENDPOINT = '/apps/subscriptions/auth/';
@@ -93,6 +93,8 @@ export async function authorizeShopifyCustomer({ store }) {
93
93
  }
94
94
  } else {
95
95
  clearCookie('og_auth');
96
+ // after clearing the cookie, we need to make sure the store clears its own auth state
97
+ store.dispatch(unauthorized('No customer found'));
96
98
  }
97
99
  }
98
100
  /**
@@ -138,7 +140,7 @@ export async function getOrCreateAuthCookie(customer: OgShopifyConfigCustomer) {
138
140
  const ogToday = new Date();
139
141
  const binarySignature = btoa(signature);
140
142
  ogToday.setTime(ogToday.getTime() + 2 * 60 * 60 * 1000);
141
- const value = `${customerId}|${timestamp}|${binarySignature};expires=${ogToday.toUTCString()}`;
142
- document.cookie = `og_auth=${value};secure;path=/`;
143
+ const value = `${customerId}|${timestamp}|${binarySignature}`;
144
+ document.cookie = `og_auth=${value};expires=${ogToday.toUTCString()};secure;path=/`;
143
145
  return value;
144
146
  }