@akinon/next 1.126.4-v1-rc.3 → 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 +2 -17
- package/middlewares/masterpass-rest-callback.ts +202 -89
- package/package.json +2 -2
- package/with-pz-config.js +4 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,25 +1,10 @@
|
|
|
1
1
|
# @akinon/next
|
|
2
2
|
|
|
3
|
-
## 1.126.4
|
|
3
|
+
## 1.126.4
|
|
4
4
|
|
|
5
5
|
### Patch Changes
|
|
6
6
|
|
|
7
|
-
-
|
|
8
|
-
- 182a639: ZERO-4483: Verify v1-rc maintenance pipeline (no-op patch to confirm v1-rc dist-tag flow)
|
|
9
|
-
|
|
10
|
-
## 1.126.4-v1-rc.2
|
|
11
|
-
|
|
12
|
-
## 1.126.4-v1-rc.1
|
|
13
|
-
|
|
14
|
-
### Patch Changes
|
|
15
|
-
|
|
16
|
-
- d480941: ZERO-4399: add card rewards to pz-masterpass-rest
|
|
17
|
-
|
|
18
|
-
## 1.126.4-v1-rc.0
|
|
19
|
-
|
|
20
|
-
### Patch Changes
|
|
21
|
-
|
|
22
|
-
- 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
|
|
23
8
|
|
|
24
9
|
## 1.126.3
|
|
25
10
|
|
|
@@ -7,111 +7,224 @@ import { getCheckoutPath } from '../utils';
|
|
|
7
7
|
|
|
8
8
|
const withMasterpassRestCallback =
|
|
9
9
|
(middleware: NextMiddleware) =>
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
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
|
-
|
|
19
|
-
|
|
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
|
-
|
|
23
|
-
|
|
24
|
-
|
|
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
|
-
|
|
27
|
-
|
|
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
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
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
|
-
|
|
38
|
-
|
|
39
|
-
|
|
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
|
-
|
|
53
|
-
|
|
158
|
+
return errorResponse;
|
|
159
|
+
}
|
|
54
160
|
|
|
55
|
-
|
|
56
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
111
|
-
|
|
112
|
-
|
|
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
|
|
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
|
|
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",
|