@akinon/next 1.126.4-v1-rc.2 → 1.126.4

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/CHANGELOG.md CHANGED
@@ -1,18 +1,10 @@
1
1
  # @akinon/next
2
2
 
3
- ## 1.126.4-v1-rc.2
4
-
5
- ## 1.126.4-v1-rc.1
6
-
7
- ### Patch Changes
8
-
9
- - d480941: ZERO-4399: add card rewards to pz-masterpass-rest
10
-
11
- ## 1.126.4-v1-rc.0
3
+ ## 1.126.4
12
4
 
13
5
  ### Patch Changes
14
6
 
15
- - 182a639: ZERO-4483: Verify v1-rc maintenance pipeline (no-op patch to confirm v1-rc dist-tag flow)
7
+ - 17a2288: ZERO-4622: Add additional remote pattern for akinoncloudcdn.com in image configuration
16
8
 
17
9
  ## 1.126.3
18
10
 
package/data/urls.ts CHANGED
@@ -40,10 +40,11 @@ export const account = {
40
40
  shipping_option_slug
41
41
  ? `&shipping_option_slug${shipping_option_operator}${shipping_option_slug}`
42
42
  : ''
43
- }${currency ? `&currency=${currency}` : ''}
44
- ${filterType && filterValue ? `&${filterType}=${filterValue}` : ''}`,
43
+ }${currency ? `&currency=${currency}` : ''}${
44
+ filterType && filterValue ? `&${filterType}=${filterValue}` : ''
45
+ }`,
45
46
  getOldOrders: ({ page, limit }: { page?: number; limit?: number }) =>
46
- `/users/old-orders/?page=${page || 1}&limit=${limit || 12}}`,
47
+ `/users/old-orders/?page=${page || 1}&limit=${limit || 12}`,
47
48
  getQuotations: (page?: number, status?: string, limit?: number) =>
48
49
  `/b2b/my-quotations/?page=${page || 1}` +
49
50
  (status ? `&status=${status}` : '') +
@@ -243,7 +244,9 @@ export const b2b = {
243
244
  };
244
245
 
245
246
  export const widgets = {
246
- getWidget: (slug: string) => `/widgets/${slug}/`
247
+ getWidget: (slug: string) => `/widgets/${slug}/`,
248
+ getWidgetSchema: (widgetSlug: string) => `/widgets/${widgetSlug}/schema/`,
249
+ getCollectionWidget: (slug: string) => `/product_collection_widgets/${slug}/`
247
250
  };
248
251
 
249
252
  export const form = {
@@ -7,111 +7,224 @@ import { getCheckoutPath } from '../utils';
7
7
 
8
8
  const withMasterpassRestCallback =
9
9
  (middleware: NextMiddleware) =>
10
- async (req: PzNextRequest, event: NextFetchEvent) => {
11
- const url = req.nextUrl.clone();
12
- const ip = req.headers.get('x-forwarded-for') ?? '';
13
-
14
- const isMasterpassCompletePage =
15
- url.pathname.includes('/orders/checkout') &&
16
- url.searchParams.get('page') === 'MasterpassRestCompletePage';
10
+ async (req: PzNextRequest, event: NextFetchEvent) => {
11
+ const url = req.nextUrl.clone();
12
+ const ip = req.headers.get('x-forwarded-for') ?? '';
13
+ const sessionId = req.cookies.get('osessionid');
14
+
15
+ if (!url.pathname.includes('/orders/masterpass-rest-callback')) {
16
+ return middleware(req, event);
17
+ }
18
+
19
+ if (req.method !== 'POST') {
20
+ logger.warn('Invalid request method for masterpass REST callback', {
21
+ middleware: 'masterpass-rest-callback',
22
+ method: req.method,
23
+ ip
24
+ });
25
+
26
+ return NextResponse.redirect(
27
+ `${url.origin}${getUrlPathWithLocale(
28
+ '/orders/checkout/',
29
+ req.cookies.get('pz-locale')?.value
30
+ )}`,
31
+ 303
32
+ );
33
+ }
34
+
35
+ const responseCode = url.searchParams.get('responseCode');
36
+ const token = url.searchParams.get('token');
37
+
38
+ if (!responseCode || !token) {
39
+ logger.warn('Missing required parameters for masterpass REST callback', {
40
+ middleware: 'masterpass-rest-callback',
41
+ responseCode,
42
+ token,
43
+ ip
44
+ });
45
+
46
+ return NextResponse.redirect(
47
+ `${url.origin}${getUrlPathWithLocale(
48
+ '/orders/checkout/',
49
+ req.cookies.get('pz-locale')?.value
50
+ )}`,
51
+ 303
52
+ );
53
+ }
54
+
55
+ try {
56
+ const formData = await req.formData();
57
+ const body: Record<string, string> = {};
58
+
59
+ Array.from(formData.entries()).forEach(([key, value]) => {
60
+ body[key] = value.toString();
61
+ });
62
+
63
+ if (!sessionId) {
64
+ logger.warn(
65
+ 'Make sure that the SESSION_COOKIE_SAMESITE environment variable is set to None in Commerce.',
66
+ {
67
+ middleware: 'masterpass-rest-callback',
68
+ ip
69
+ }
70
+ );
17
71
 
18
- if (!isMasterpassCompletePage) {
19
- return middleware(req, event);
72
+ return NextResponse.redirect(
73
+ `${url.origin}${getUrlPathWithLocale(
74
+ '/orders/checkout/',
75
+ req.cookies.get('pz-locale')?.value
76
+ )}`,
77
+ 303
78
+ );
20
79
  }
21
80
 
22
- try {
23
- const isPostCheckout = req.cookies.get('pz-post-checkout-flow')?.value === 'true';
24
- const requestUrl = new URL(getCheckoutPath(isPostCheckout), Settings.commerceUrl);
81
+ const isPostCheckout = req.cookies.get('pz-post-checkout-flow')?.value === 'true';
82
+ const requestUrl = new URL(getCheckoutPath(isPostCheckout), Settings.commerceUrl);
83
+ requestUrl.searchParams.set('page', 'MasterpassRestCompletePage');
84
+ requestUrl.searchParams.set('responseCode', responseCode);
85
+ requestUrl.searchParams.set('token', token);
86
+ requestUrl.searchParams.set(
87
+ 'three_d_secure',
88
+ body.transactionType?.includes('3D') ? 'true' : 'false'
89
+ );
90
+ requestUrl.searchParams.set(
91
+ 'transactionType',
92
+ body.transactionType || ''
93
+ );
94
+
95
+ const requestHeaders = {
96
+ 'Content-Type': 'application/x-www-form-urlencoded',
97
+ 'X-Requested-With': 'XMLHttpRequest',
98
+ Cookie: req.headers.get('cookie') ?? '',
99
+ 'x-currency': req.cookies.get('pz-currency')?.value ?? '',
100
+ 'x-forwarded-for': ip,
101
+ 'User-Agent': req.headers.get('user-agent') ?? ''
102
+ };
103
+
104
+ const request = await fetch(requestUrl.toString(), {
105
+ method: 'POST',
106
+ headers: requestHeaders,
107
+ body: new URLSearchParams(body)
108
+ });
109
+
110
+ logger.info('Masterpass REST callback request', {
111
+ requestUrl: requestUrl.toString(),
112
+ status: request.status,
113
+ requestHeaders,
114
+ ip
115
+ });
116
+
117
+ const response = await request.json();
118
+
119
+ const { context_list: contextList, errors } = response;
120
+
121
+ let redirectUrl = response.redirect_url;
122
+
123
+ if (!redirectUrl && contextList && contextList.length > 0) {
124
+ for (const context of contextList) {
125
+ if (context.page_context && context.page_context.redirect_url) {
126
+ redirectUrl = context.page_context.redirect_url;
127
+ break;
128
+ }
129
+ }
130
+ }
25
131
 
26
- url.searchParams.forEach((value, key) => {
27
- requestUrl.searchParams.set(key, value);
132
+ if (errors && Object.keys(errors).length) {
133
+ logger.error('Error while processing masterpass REST callback', {
134
+ middleware: 'masterpass-rest-callback',
135
+ errors,
136
+ requestHeaders,
137
+ ip
28
138
  });
29
139
 
30
- const formData = await req.formData();
31
- const body: Record<string, string> = {};
32
-
33
- Array.from(formData.entries()).forEach(([key, value]) => {
34
- body[key] = value.toString();
35
- });
140
+ const errorResponse = NextResponse.redirect(
141
+ `${url.origin}${getUrlPathWithLocale(
142
+ '/orders/checkout/',
143
+ req.cookies.get('pz-locale')?.value
144
+ )}`,
145
+ {
146
+ status: 303,
147
+ headers: {
148
+ 'Set-Cookie': `pz-pos-error=${encodeURIComponent(JSON.stringify(errors))}; path=/;`
149
+ }
150
+ }
151
+ );
36
152
 
37
- const requestHeaders = {
38
- 'Content-Type': 'application/x-www-form-urlencoded',
39
- 'X-Requested-With': 'XMLHttpRequest',
40
- Cookie: req.headers.get('cookie') ?? '',
41
- 'x-currency': req.cookies.get('pz-currency')?.value ?? '',
42
- 'x-forwarded-for': ip,
43
- 'User-Agent': req.headers.get('user-agent') ?? ''
44
- };
45
-
46
- const request = await fetch(requestUrl.toString(), {
47
- method: 'POST',
48
- headers: requestHeaders,
49
- body: new URLSearchParams(body)
153
+ // Add error cookie
154
+ errorResponse.cookies.set('pz-pos-error', JSON.stringify(errors), {
155
+ path: '/'
50
156
  });
51
157
 
52
- const response = await request.json();
53
- const { errors } = response;
158
+ return errorResponse;
159
+ }
54
160
 
55
- if (errors && Object.keys(errors).length) {
56
- logger.error('Error while processing MasterpassRestCompletePage', {
161
+ logger.info('Masterpass REST callback response', {
162
+ middleware: 'masterpass-rest-callback',
163
+ contextList,
164
+ redirectUrl,
165
+ ip
166
+ });
167
+
168
+ if (!redirectUrl) {
169
+ logger.warn(
170
+ 'No redirection url found in response. Redirecting to checkout page.',
171
+ {
57
172
  middleware: 'masterpass-rest-callback',
58
- errors,
173
+ requestHeaders,
174
+ response: JSON.stringify(response),
59
175
  ip
60
- });
61
-
62
- const errorResponse = NextResponse.redirect(
63
- `${url.origin}${getUrlPathWithLocale(
64
- '/orders/checkout/',
65
- req.cookies.get('pz-locale')?.value
66
- )}`,
67
- 303
68
- );
69
-
70
- // Add error cookie
71
- errorResponse.cookies.set('pz-pos-error', JSON.stringify(errors), {
72
- path: '/'
73
- });
74
-
75
- return errorResponse;
76
- }
77
-
78
- const redirectUrl =
79
- response.redirect_url ||
80
- response.context_list?.[0]?.page_context?.redirect_url;
81
-
82
- if (redirectUrl) {
83
- const nextResponse = NextResponse.redirect(
84
- `${url.origin}${getUrlPathWithLocale(redirectUrl, req.cookies.get('pz-locale')?.value)}`,
85
- 303
86
- );
87
-
88
- // Forward set-cookie headers from the upstream response
89
- const setCookieHeader = request.headers.get('set-cookie');
90
- if (setCookieHeader) {
91
- setCookieHeader.split(',').forEach((cookie) => {
92
- nextResponse.headers.append('Set-Cookie', cookie.trim());
93
- });
94
176
  }
177
+ );
95
178
 
96
- return nextResponse;
97
- }
179
+ const redirectUrlWithLocale = `${url.origin}${getUrlPathWithLocale(
180
+ '/orders/checkout/',
181
+ req.cookies.get('pz-locale')?.value
182
+ )}`;
98
183
 
99
- return NextResponse.redirect(
100
- `${url.origin}${getUrlPathWithLocale('/orders/checkout/', req.cookies.get('pz-locale')?.value)}`,
101
- 303
102
- );
103
- } catch (error) {
104
- logger.error('Error while processing MasterpassRestCompletePage', {
105
- middleware: 'masterpass-rest-callback',
106
- error,
107
- ip
108
- });
184
+ return NextResponse.redirect(redirectUrlWithLocale, 303);
185
+ }
109
186
 
110
- return NextResponse.redirect(
111
- `${url.origin}${getUrlPathWithLocale('/orders/checkout/', req.cookies.get('pz-locale')?.value)}`,
112
- 303
113
- );
187
+ const redirectUrlWithLocale = `${url.origin}${getUrlPathWithLocale(
188
+ redirectUrl,
189
+ req.cookies.get('pz-locale')?.value
190
+ )}`;
191
+
192
+ logger.info('Redirecting after masterpass REST callback', {
193
+ middleware: 'masterpass-rest-callback',
194
+ redirectUrl: redirectUrlWithLocale,
195
+ ip
196
+ });
197
+
198
+ const nextResponse = NextResponse.redirect(redirectUrlWithLocale, 303);
199
+
200
+ // Forward set-cookie headers from the upstream response
201
+ const setCookieHeader = request.headers.get('set-cookie');
202
+ if (setCookieHeader) {
203
+ setCookieHeader.split(',').forEach((cookie) => {
204
+ nextResponse.headers.append('Set-Cookie', cookie.trim());
205
+ });
114
206
  }
115
- };
207
+
208
+ return nextResponse;
209
+ } catch (error) {
210
+ logger.error('Error while processing masterpass REST callback', {
211
+ middleware: 'masterpass-rest-callback',
212
+ error,
213
+ requestHeaders: {
214
+ Cookie: req.headers.get('cookie') ?? '',
215
+ 'x-currency': req.cookies.get('pz-currency')?.value ?? ''
216
+ },
217
+ ip
218
+ });
219
+
220
+ return NextResponse.redirect(
221
+ `${url.origin}${getUrlPathWithLocale(
222
+ '/orders/checkout/',
223
+ req.cookies.get('pz-locale')?.value
224
+ )}`,
225
+ 303
226
+ );
227
+ }
228
+ };
116
229
 
117
230
  export default withMasterpassRestCallback;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@akinon/next",
3
3
  "description": "Core package for Project Zero Next",
4
- "version": "1.126.4-v1-rc.2",
4
+ "version": "1.126.4",
5
5
  "private": false,
6
6
  "license": "MIT",
7
7
  "bin": {
@@ -35,7 +35,7 @@
35
35
  "set-cookie-parser": "2.6.0"
36
36
  },
37
37
  "devDependencies": {
38
- "@akinon/eslint-plugin-projectzero": "1.126.4-v1-rc.2",
38
+ "@akinon/eslint-plugin-projectzero": "1.126.4",
39
39
  "@babel/core": "7.26.10",
40
40
  "@babel/preset-env": "7.26.9",
41
41
  "@babel/preset-typescript": "7.27.0",
package/with-pz-config.js CHANGED
@@ -21,6 +21,10 @@ const defaultConfig = {
21
21
  protocol: 'https',
22
22
  hostname: '**.akinoncloud.com'
23
23
  },
24
+ {
25
+ protocol: 'https',
26
+ hostname: '**.akinoncloudcdn.com'
27
+ },
24
28
  {
25
29
  protocol: 'https',
26
30
  hostname: '**.akinoncdn.com'