@akinon/next 1.126.3 → 1.126.4-v1-rc.1
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 +12 -0
- package/middlewares/masterpass-rest-callback.ts +89 -202
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @akinon/next
|
|
2
2
|
|
|
3
|
+
## 1.126.4-v1-rc.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- d480941: ZERO-4399: add card rewards to pz-masterpass-rest
|
|
8
|
+
|
|
9
|
+
## 1.126.4-v1-rc.0
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- 182a639: ZERO-4483: Verify v1-rc maintenance pipeline (no-op patch to confirm v1-rc dist-tag flow)
|
|
14
|
+
|
|
3
15
|
## 1.126.3
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
|
@@ -7,224 +7,111 @@ import { getCheckoutPath } from '../utils';
|
|
|
7
7
|
|
|
8
8
|
const withMasterpassRestCallback =
|
|
9
9
|
(middleware: NextMiddleware) =>
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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
|
-
);
|
|
10
|
+
async (req: PzNextRequest, event: NextFetchEvent) => {
|
|
11
|
+
const url = req.nextUrl.clone();
|
|
12
|
+
const ip = req.headers.get('x-forwarded-for') ?? '';
|
|
71
13
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
req.cookies.get('pz-locale')?.value
|
|
76
|
-
)}`,
|
|
77
|
-
303
|
|
78
|
-
);
|
|
79
|
-
}
|
|
14
|
+
const isMasterpassCompletePage =
|
|
15
|
+
url.pathname.includes('/orders/checkout') &&
|
|
16
|
+
url.searchParams.get('page') === 'MasterpassRestCompletePage';
|
|
80
17
|
|
|
81
|
-
|
|
82
|
-
|
|
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
|
-
}
|
|
18
|
+
if (!isMasterpassCompletePage) {
|
|
19
|
+
return middleware(req, event);
|
|
130
20
|
}
|
|
131
21
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
22
|
+
try {
|
|
23
|
+
const isPostCheckout = req.cookies.get('pz-post-checkout-flow')?.value === 'true';
|
|
24
|
+
const requestUrl = new URL(getCheckoutPath(isPostCheckout), Settings.commerceUrl);
|
|
25
|
+
|
|
26
|
+
url.searchParams.forEach((value, key) => {
|
|
27
|
+
requestUrl.searchParams.set(key, value);
|
|
138
28
|
});
|
|
139
29
|
|
|
140
|
-
const
|
|
141
|
-
|
|
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
|
-
);
|
|
30
|
+
const formData = await req.formData();
|
|
31
|
+
const body: Record<string, string> = {};
|
|
152
32
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
path: '/'
|
|
33
|
+
Array.from(formData.entries()).forEach(([key, value]) => {
|
|
34
|
+
body[key] = value.toString();
|
|
156
35
|
});
|
|
157
36
|
|
|
158
|
-
|
|
159
|
-
|
|
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)
|
|
50
|
+
});
|
|
160
51
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
});
|
|
167
|
-
|
|
168
|
-
if (!redirectUrl) {
|
|
169
|
-
logger.warn(
|
|
170
|
-
'No redirection url found in response. Redirecting to checkout page.',
|
|
171
|
-
{
|
|
52
|
+
const response = await request.json();
|
|
53
|
+
const { errors } = response;
|
|
54
|
+
|
|
55
|
+
if (errors && Object.keys(errors).length) {
|
|
56
|
+
logger.error('Error while processing MasterpassRestCompletePage', {
|
|
172
57
|
middleware: 'masterpass-rest-callback',
|
|
173
|
-
|
|
174
|
-
response: JSON.stringify(response),
|
|
58
|
+
errors,
|
|
175
59
|
ip
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
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
|
+
}
|
|
191
77
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
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
|
+
}
|
|
197
95
|
|
|
198
|
-
|
|
96
|
+
return nextResponse;
|
|
97
|
+
}
|
|
199
98
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
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
|
|
205
108
|
});
|
|
206
|
-
}
|
|
207
109
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
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
|
-
};
|
|
110
|
+
return NextResponse.redirect(
|
|
111
|
+
`${url.origin}${getUrlPathWithLocale('/orders/checkout/', req.cookies.get('pz-locale')?.value)}`,
|
|
112
|
+
303
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
};
|
|
229
116
|
|
|
230
117
|
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
|
+
"version": "1.126.4-v1-rc.1",
|
|
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.
|
|
38
|
+
"@akinon/eslint-plugin-projectzero": "1.126.4-v1-rc.1",
|
|
39
39
|
"@babel/core": "7.26.10",
|
|
40
40
|
"@babel/preset-env": "7.26.9",
|
|
41
41
|
"@babel/preset-typescript": "7.27.0",
|