@akinon/next 1.92.0-rc.22 → 1.92.0-rc.24

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,5 +1,17 @@
1
1
  # @akinon/next
2
2
 
3
+ ## 1.92.0-rc.24
4
+
5
+ ### Minor Changes
6
+
7
+ - fee608d: ZERO-3422: Refactor body handling in wallet complete redirection middleware
8
+
9
+ ## 1.92.0-rc.23
10
+
11
+ ### Minor Changes
12
+
13
+ - cbdb5c14: ZERO-3448: fix set cookie domain handling for subdomain locale strategy
14
+
3
15
  ## 1.92.0-rc.22
4
16
 
5
17
  ### Minor Changes
@@ -49,7 +49,31 @@ const withWalletCompleteRedirection =
49
49
  };
50
50
 
51
51
  try {
52
- const body = await streamToString(req.body);
52
+ const existingBody = await streamToString(req.body);
53
+ const queryParams = new URLSearchParams(url.search);
54
+ const bodyParams = new URLSearchParams();
55
+
56
+ if (existingBody) {
57
+ try {
58
+ const existingParams = new URLSearchParams(existingBody);
59
+
60
+ for (const [key, value] of existingParams) {
61
+ bodyParams.append(key, value);
62
+ }
63
+ } catch {
64
+ logger.error('Error parsing existing body as URL-encoded data', {
65
+ middleware: 'wallet-complete-redirection',
66
+ existingBody,
67
+ ip
68
+ });
69
+ }
70
+ }
71
+
72
+ for (const [key, value] of queryParams) {
73
+ bodyParams.append(key, value);
74
+ }
75
+
76
+ const body = bodyParams.toString();
53
77
 
54
78
  if (!sessionId) {
55
79
  logger.warn(
@@ -70,7 +94,7 @@ const withWalletCompleteRedirection =
70
94
  }
71
95
 
72
96
  const request = await fetch(requestUrl, {
73
- method: req.method,
97
+ method: 'POST',
74
98
  headers: requestHeaders,
75
99
  body
76
100
  });
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.92.0-rc.22",
4
+ "version": "1.92.0-rc.24",
5
5
  "private": false,
6
6
  "license": "MIT",
7
7
  "bin": {
@@ -34,7 +34,7 @@
34
34
  "set-cookie-parser": "2.6.0"
35
35
  },
36
36
  "devDependencies": {
37
- "@akinon/eslint-plugin-projectzero": "1.92.0-rc.22",
37
+ "@akinon/eslint-plugin-projectzero": "1.92.0-rc.24",
38
38
  "@babel/core": "7.26.10",
39
39
  "@babel/preset-env": "7.26.9",
40
40
  "@babel/preset-typescript": "7.27.0",
package/types/index.ts CHANGED
@@ -224,6 +224,14 @@ export interface CacheOptions {
224
224
  useProxy?: boolean;
225
225
  }
226
226
 
227
+ export interface SetCookieOptions {
228
+ expires?: number; // days
229
+ path?: string;
230
+ domain?: string;
231
+ secure?: boolean;
232
+ sameSite?: 'strict' | 'lax' | 'none';
233
+ }
234
+
227
235
  export interface ClientRequestOptions {
228
236
  useTrailingSlash?: boolean;
229
237
  useFormData?: boolean;
package/utils/index.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import settings from 'settings';
2
2
  import { LocaleUrlStrategy } from '../localization';
3
- import { CDNOptions, ClientRequestOptions } from '../types';
3
+ import { CDNOptions, ClientRequestOptions, SetCookieOptions } from '../types';
4
4
  import getRootHostname from './get-root-hostname';
5
5
 
6
6
  export * from './get-currency';
@@ -21,29 +21,40 @@ export function getCookie(name: string) {
21
21
  }
22
22
  }
23
23
 
24
- export function setCookie(name: string, value: string) {
25
- const WEEK_IN_MS = 7 * 24 * 60 * 60 * 1000;
26
- const hostname = process.env.NEXT_PUBLIC_URL || '';
24
+ export function setCookie(
25
+ name: string,
26
+ value: string,
27
+ options: SetCookieOptions = {}
28
+ ) {
29
+ const cookieParts = [`${name}=${value}`];
30
+
31
+ if (options.expires) {
32
+ const date = new Date();
33
+ date.setTime(date.getTime() + options.expires * 24 * 60 * 60 * 1000);
34
+ cookieParts.push(`expires=${date.toUTCString()}`);
35
+ }
36
+
37
+ cookieParts.push(`path=${options.path ?? '/'}`);
38
+
39
+ if (options.secure) {
40
+ cookieParts.push('secure');
41
+ }
42
+
43
+ if (options.sameSite) {
44
+ cookieParts.push(`sameSite=${options.sameSite}`);
45
+ }
46
+
27
47
  const domain =
28
- localeUrlStrategy === LocaleUrlStrategy.Subdomain
29
- ? getRootHostname(hostname)
30
- : null;
31
- const domainStr = domain ? `Domain=${domain}` : '';
32
- const expiryDate = new Date(Date.now() + WEEK_IN_MS);
33
- const isSecure = hostname.startsWith('https://');
34
-
35
- const cookieParts = [
36
- `${name}=${value}`,
37
- `Eexpires=${expiryDate.toUTCString()}`,
38
- `Path=/`,
39
- `SameSite=lax`,
40
- `Secure=${isSecure}`,
41
- domainStr
42
- ].filter(Boolean);
43
-
44
- const cookieString = cookieParts.join('; ');
45
-
46
- document.cookie = cookieString;
48
+ options.domain ??
49
+ (settings.localization.localeUrlStrategy === LocaleUrlStrategy.Subdomain
50
+ ? getRootHostname(document.location.href)
51
+ : null);
52
+
53
+ if (domain) {
54
+ cookieParts.push(`domain=${domain}`);
55
+ }
56
+
57
+ document.cookie = cookieParts.join('; ');
47
58
  }
48
59
 
49
60
  export function removeCookie(name: string) {
@@ -168,9 +179,6 @@ export function buildCDNUrl(url: string, config?: CDNOptions) {
168
179
  return `${rootWithoutOptions}${options}${fileExtension}`;
169
180
  }
170
181
 
171
- const { locales, localeUrlStrategy, defaultLocaleValue } =
172
- settings.localization;
173
-
174
182
  export const urlLocaleMatcherRegex = new RegExp(
175
183
  `^/(${settings.localization.locales
176
184
  .filter((l) =>