@akinon/next 1.2.0 → 1.4.0
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 +18 -0
- package/api/auth.ts +17 -7
- package/bin/pz-install-theme.js +41 -0
- package/bin/pz-postbuild.js +1 -0
- package/bin/pz-postdev.js +1 -0
- package/bin/pz-postinstall.js +5 -0
- package/bin/pz-poststart.js +1 -0
- package/bin/pz-prebuild.js +5 -0
- package/bin/pz-predev.js +5 -0
- package/bin/pz-prestart.js +1 -0
- package/components/client-root.tsx +1 -40
- package/components/plugin-module.tsx +28 -23
- package/data/client/user.ts +9 -1
- package/data/urls.ts +1 -0
- package/hocs/client/with-segment-defaults.tsx +1 -2
- package/hocs/server/with-segment-defaults.tsx +4 -2
- package/hooks/use-localization.ts +18 -3
- package/lib/cache.ts +1 -1
- package/middlewares/currency.ts +35 -1
- package/middlewares/default.ts +4 -17
- package/middlewares/oauth-login.ts +2 -1
- package/middlewares/redirection-payment.ts +2 -1
- package/middlewares/three-d-redirection.ts +78 -69
- package/package.json +8 -2
- package/types/commerce/account.ts +4 -8
- package/utils/index.ts +3 -0
- package/utils/log.ts +0 -20
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# @akinon/next
|
|
2
2
|
|
|
3
|
+
## 1.4.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Fix basket reset on mobile app checkout page
|
|
8
|
+
- Upgrade typescript to v5 and remove ts-expect-error lines
|
|
9
|
+
- Fix 3D payment with different currencies
|
|
10
|
+
- Support tailwind theming
|
|
11
|
+
|
|
12
|
+
## 1.3.0
|
|
13
|
+
|
|
14
|
+
### Minor Changes
|
|
15
|
+
|
|
16
|
+
- Refactor currency and locale selection
|
|
17
|
+
- Update TS types
|
|
18
|
+
- Fix 3D redirection middleware
|
|
19
|
+
- Refactor logging
|
|
20
|
+
|
|
3
21
|
## 1.2.0
|
|
4
22
|
|
|
5
23
|
### Minor Changes
|
package/api/auth.ts
CHANGED
|
@@ -8,13 +8,16 @@ import { urlLocaleMatcherRegex } from '../utils';
|
|
|
8
8
|
import logger from '@akinon/next/utils/log';
|
|
9
9
|
import { AuthError } from '../types';
|
|
10
10
|
|
|
11
|
-
async function getCurrentUser(sessionId: string) {
|
|
11
|
+
async function getCurrentUser(sessionId: string, currency = '') {
|
|
12
|
+
const headers = {
|
|
13
|
+
'Content-Type': 'application/json',
|
|
14
|
+
Cookie: `osessionid=${sessionId}`,
|
|
15
|
+
'x-currency': currency
|
|
16
|
+
};
|
|
17
|
+
|
|
12
18
|
const currentUser = await (
|
|
13
19
|
await fetch(URLS.user.currentUser, {
|
|
14
|
-
headers
|
|
15
|
-
'Content-Type': 'application/json',
|
|
16
|
-
Cookie: `osessionid=${sessionId}`
|
|
17
|
-
}
|
|
20
|
+
headers
|
|
18
21
|
})
|
|
19
22
|
).json();
|
|
20
23
|
|
|
@@ -51,7 +54,10 @@ const nextAuthOptions = (req: NextApiRequest, res: NextApiResponse) => {
|
|
|
51
54
|
return null;
|
|
52
55
|
}
|
|
53
56
|
|
|
54
|
-
const currentUser = await getCurrentUser(
|
|
57
|
+
const currentUser = await getCurrentUser(
|
|
58
|
+
sessionId,
|
|
59
|
+
req.cookies['pz-currency'] ?? ''
|
|
60
|
+
);
|
|
55
61
|
return currentUser;
|
|
56
62
|
}
|
|
57
63
|
}),
|
|
@@ -78,6 +84,7 @@ const nextAuthOptions = (req: NextApiRequest, res: NextApiResponse) => {
|
|
|
78
84
|
headers.set('Content-Type', 'application/json');
|
|
79
85
|
headers.set('cookie', `${req.headers.cookie}`);
|
|
80
86
|
headers.set('Accept-Language', `${language}`);
|
|
87
|
+
headers.set('x-currency', req.cookies['pz-currency'] ?? '');
|
|
81
88
|
|
|
82
89
|
logger.debug('Trying to login/register', {
|
|
83
90
|
formType: credentials.formType
|
|
@@ -160,7 +167,10 @@ const nextAuthOptions = (req: NextApiRequest, res: NextApiResponse) => {
|
|
|
160
167
|
}
|
|
161
168
|
}
|
|
162
169
|
|
|
163
|
-
const currentUser = await getCurrentUser(
|
|
170
|
+
const currentUser = await getCurrentUser(
|
|
171
|
+
sessionId,
|
|
172
|
+
req.cookies['pz-currency'] ?? ''
|
|
173
|
+
);
|
|
164
174
|
return currentUser;
|
|
165
175
|
}
|
|
166
176
|
})
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
|
|
6
|
+
const BASE_DIR =
|
|
7
|
+
path.resolve(__dirname, '../../../apps/projectzeropwa') || process.cwd();
|
|
8
|
+
const getFullPath = (relativePath) => path.join(BASE_DIR, relativePath);
|
|
9
|
+
|
|
10
|
+
const theme = require(getFullPath('src/theme.js'));
|
|
11
|
+
|
|
12
|
+
try {
|
|
13
|
+
const spawn = require('cross-spawn');
|
|
14
|
+
const tsConfigPath = getFullPath('tsconfig.json');
|
|
15
|
+
|
|
16
|
+
if (!fs.existsSync(tsConfigPath)) {
|
|
17
|
+
throw new Error(`tsconfig.json not found at ${tsConfigPath}`);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const tsConfigContent = fs.readFileSync(tsConfigPath, 'utf8');
|
|
21
|
+
const themePaths = ['"./*"'];
|
|
22
|
+
|
|
23
|
+
if (theme !== 'default') {
|
|
24
|
+
themePaths.splice(0, 0, `"themes/${theme}/*"`);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const newContent = tsConfigContent.replace(
|
|
28
|
+
/"@theme\/\*":\s\[.+\]/,
|
|
29
|
+
`"@theme/*": [${themePaths.join(', ')}]`
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
fs.writeFileSync(tsConfigPath, newContent);
|
|
33
|
+
|
|
34
|
+
if (fs.existsSync(getFullPath('../../turbo.json'))) {
|
|
35
|
+
spawn.sync('turbo', ['clean'], {
|
|
36
|
+
stdio: 'inherit'
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
} catch (error) {
|
|
40
|
+
console.error('Error:', error.message);
|
|
41
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
package/bin/pz-predev.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
@@ -1,15 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import { usePathname } from 'next/navigation';
|
|
4
|
-
import {
|
|
5
|
-
import { api } from '../data/client/api';
|
|
6
|
-
import {
|
|
7
|
-
useClearBasketMutation,
|
|
8
|
-
useGetBasketQuery
|
|
9
|
-
} from '../data/client/basket';
|
|
10
|
-
import { useAppDispatch, useAppSelector } from '../redux/hooks';
|
|
11
|
-
import { getCookie, removeCookie } from '../utils';
|
|
12
|
-
import { useRouter } from '../hooks';
|
|
4
|
+
import { useAppSelector } from '../redux/hooks';
|
|
13
5
|
|
|
14
6
|
export default function ClientRoot({
|
|
15
7
|
children,
|
|
@@ -18,39 +10,8 @@ export default function ClientRoot({
|
|
|
18
10
|
children: React.ReactNode;
|
|
19
11
|
sessionId?: string;
|
|
20
12
|
}) {
|
|
21
|
-
const dispatch = useAppDispatch();
|
|
22
13
|
const pathname = usePathname();
|
|
23
|
-
const router = useRouter();
|
|
24
14
|
const { isMobileApp } = useAppSelector((state) => state.root);
|
|
25
|
-
const { data: basketData, isSuccess } = useGetBasketQuery();
|
|
26
|
-
const [clearBasket] = useClearBasketMutation();
|
|
27
|
-
const resetClientCache = getCookie('pz-reset-client-cache') === 'true';
|
|
28
|
-
const resetBasket = getCookie('pz-reset-basket') === 'true';
|
|
29
|
-
|
|
30
|
-
useEffect(() => {
|
|
31
|
-
if (basketData?.basketitem_set.length && resetBasket) {
|
|
32
|
-
dispatch(
|
|
33
|
-
api.util.invalidateTags([
|
|
34
|
-
'Checkout',
|
|
35
|
-
'Product',
|
|
36
|
-
'Addresses',
|
|
37
|
-
'Favorite',
|
|
38
|
-
'Basket'
|
|
39
|
-
])
|
|
40
|
-
);
|
|
41
|
-
|
|
42
|
-
clearBasket();
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
removeCookie('pz-reset-basket');
|
|
46
|
-
}, [resetBasket, isSuccess, basketData]);
|
|
47
|
-
|
|
48
|
-
useEffect(() => {
|
|
49
|
-
if (resetClientCache) {
|
|
50
|
-
removeCookie('pz-reset-client-cache');
|
|
51
|
-
location.reload();
|
|
52
|
-
}
|
|
53
|
-
}, [resetClientCache]);
|
|
54
15
|
|
|
55
16
|
if (isMobileApp && pathname.includes('/orders/completed')) {
|
|
56
17
|
((window.parent || window) as any)?.ReactNativeWebView?.postMessage?.(
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import dynamic from 'next/dynamic';
|
|
2
2
|
import plugins from 'plugins';
|
|
3
3
|
import logger from '../utils/log';
|
|
4
|
+
import { useMemo } from 'react';
|
|
4
5
|
|
|
5
6
|
enum Plugin {
|
|
6
7
|
BasketGiftPack = 'pz-basket-gift-pack',
|
|
@@ -47,31 +48,35 @@ export default function PluginModule({
|
|
|
47
48
|
return null;
|
|
48
49
|
}
|
|
49
50
|
|
|
50
|
-
const Component =
|
|
51
|
-
() =>
|
|
52
|
-
|
|
51
|
+
const Component = useMemo(
|
|
52
|
+
() =>
|
|
53
|
+
dynamic(
|
|
54
|
+
() => {
|
|
55
|
+
let promise: any;
|
|
53
56
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
57
|
+
try {
|
|
58
|
+
if (plugin === Plugin.BasketGiftPack) {
|
|
59
|
+
promise = import(`${'pz-basket-gift-pack'}`);
|
|
60
|
+
} else if (plugin === Plugin.ClickCollect) {
|
|
61
|
+
promise = import(`${'pz-click-collect'}`);
|
|
62
|
+
} else if (plugin === Plugin.OneClickCheckout) {
|
|
63
|
+
promise = import(`${'pz-one-click-checkout'}`);
|
|
64
|
+
} else if (plugin === Plugin.PayOnDelivery) {
|
|
65
|
+
promise = import(`${'pz-pay-on-delivery'}`);
|
|
66
|
+
} else if (plugin === Plugin.CheckoutGiftPack) {
|
|
67
|
+
promise = import(`${'pz-checkout-gift-pack'}`);
|
|
68
|
+
}
|
|
69
|
+
} catch (error) {
|
|
70
|
+
logger.error(error);
|
|
71
|
+
}
|
|
69
72
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
73
|
+
return promise
|
|
74
|
+
? promise.then((mod) => mod[component]).catch(() => () => null)
|
|
75
|
+
: new Promise<any>((resolve) => resolve(() => null));
|
|
76
|
+
},
|
|
77
|
+
{ ssr: false }
|
|
78
|
+
),
|
|
79
|
+
[plugin]
|
|
75
80
|
);
|
|
76
81
|
|
|
77
82
|
return <Component {...props} />;
|
package/data/client/user.ts
CHANGED
|
@@ -70,13 +70,21 @@ const userApi = api.injectEndpoints({
|
|
|
70
70
|
method: 'POST',
|
|
71
71
|
body
|
|
72
72
|
})
|
|
73
|
-
})
|
|
73
|
+
}),
|
|
74
|
+
changeEmailVerification: build.query<void, string>({
|
|
75
|
+
query: (token) => ({
|
|
76
|
+
url: buildClientRequestUrl(user.changeEmailVerification(token), {
|
|
77
|
+
contentType: 'application/json'
|
|
78
|
+
})
|
|
79
|
+
})
|
|
80
|
+
}),
|
|
74
81
|
}),
|
|
75
82
|
overrideExisting: false
|
|
76
83
|
});
|
|
77
84
|
|
|
78
85
|
export const {
|
|
79
86
|
useGetCaptchaQuery,
|
|
87
|
+
useChangeEmailVerificationQuery,
|
|
80
88
|
useValidateCaptchaMutation,
|
|
81
89
|
useLogoutMutation,
|
|
82
90
|
useForgotPasswordMutation
|
package/data/urls.ts
CHANGED
|
@@ -142,6 +142,7 @@ export const user = {
|
|
|
142
142
|
captcha: '/users/pz-captcha',
|
|
143
143
|
profiles: '/users/profile',
|
|
144
144
|
forgotPassword: '/users/password/reset',
|
|
145
|
+
changeEmailVerification: (token: string) => `/users/email-set-primary/${token}`,
|
|
145
146
|
csrfToken: '/csrf_token'
|
|
146
147
|
};
|
|
147
148
|
|
|
@@ -15,11 +15,10 @@ export const withSegmentDefaults =
|
|
|
15
15
|
options: SegmentDefaultsOptions
|
|
16
16
|
) =>
|
|
17
17
|
(props: T) => {
|
|
18
|
-
|
|
18
|
+
const componentProps = { ...props };
|
|
19
19
|
|
|
20
20
|
return (
|
|
21
21
|
<>
|
|
22
|
-
{/* @ts-expect-error Server Component */}
|
|
23
22
|
<Component {...componentProps} />
|
|
24
23
|
</>
|
|
25
24
|
);
|
|
@@ -35,7 +35,6 @@ export const withSegmentDefaults =
|
|
|
35
35
|
|
|
36
36
|
return await (
|
|
37
37
|
<>
|
|
38
|
-
{/* @ts-expect-error Server Component */}
|
|
39
38
|
<Component {...componentProps} />
|
|
40
39
|
</>
|
|
41
40
|
);
|
|
@@ -74,7 +73,10 @@ const checkRedisVariables = () => {
|
|
|
74
73
|
process.env.CACHE_SECRET
|
|
75
74
|
];
|
|
76
75
|
|
|
77
|
-
if (
|
|
76
|
+
if (
|
|
77
|
+
!requiredVariableValues.every((v) => v) &&
|
|
78
|
+
process.env.NODE_ENV === 'production'
|
|
79
|
+
) {
|
|
78
80
|
logger.warn('Redis cache variables are not set', {
|
|
79
81
|
requiredVariables: ['CACHE_HOST', 'CACHE_PORT', 'CACHE_SECRET'],
|
|
80
82
|
values: requiredVariableValues
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { LocalizationContext } from '../localization/provider';
|
|
4
4
|
import { useContext } from 'react';
|
|
5
|
-
import { urlLocaleMatcherRegex } from '../utils';
|
|
5
|
+
import { setCookie, urlLocaleMatcherRegex } from '../utils';
|
|
6
6
|
import { LocaleUrlStrategy } from '../localization';
|
|
7
7
|
import { useRouter } from 'next/navigation';
|
|
8
8
|
|
|
@@ -36,7 +36,21 @@ export const useLocalization = () => {
|
|
|
36
36
|
''
|
|
37
37
|
);
|
|
38
38
|
|
|
39
|
-
router.push
|
|
39
|
+
// router.push is not used because reloading the page also clears the client side cache.
|
|
40
|
+
location.href = `${localePath}${pathnameWithoutLocale}${location.search}`;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Sets the currency.
|
|
45
|
+
*
|
|
46
|
+
* If the currency is linked to the locale by using `getActiveCurrencyCode` function in the settings,
|
|
47
|
+
* you need to use `setLocale` instead of this.
|
|
48
|
+
* @param currency Currency code defined in the settings.
|
|
49
|
+
*/
|
|
50
|
+
const setCurrency = (currency: string) => {
|
|
51
|
+
// It is a temp cookie to set currency in `currency` middleware.
|
|
52
|
+
setCookie('pz-set-currency', currency);
|
|
53
|
+
location.reload();
|
|
40
54
|
};
|
|
41
55
|
|
|
42
56
|
return {
|
|
@@ -52,12 +66,13 @@ export const useLocalization = () => {
|
|
|
52
66
|
*/
|
|
53
67
|
t: (path: string) => translate(path),
|
|
54
68
|
setLocale,
|
|
69
|
+
setCurrency,
|
|
55
70
|
locale,
|
|
56
71
|
currency,
|
|
57
72
|
locales,
|
|
58
73
|
currencies,
|
|
59
74
|
defaultLocaleValue,
|
|
60
75
|
defaultCurrencyCode,
|
|
61
|
-
localeUrlStrategy
|
|
76
|
+
localeUrlStrategy
|
|
62
77
|
};
|
|
63
78
|
};
|
package/lib/cache.ts
CHANGED
package/middlewares/currency.ts
CHANGED
|
@@ -1,8 +1,21 @@
|
|
|
1
1
|
import { NextFetchEvent, NextMiddleware } from 'next/server';
|
|
2
|
-
import { ROUTES } from 'routes';
|
|
3
2
|
import settings from 'settings';
|
|
4
3
|
import { PzNextRequest } from '.';
|
|
5
4
|
import logger from '../utils/log';
|
|
5
|
+
import { basket } from '../data/urls';
|
|
6
|
+
import { urlLocaleMatcherRegex } from '../utils';
|
|
7
|
+
|
|
8
|
+
const resetBasket = async (req: PzNextRequest) => {
|
|
9
|
+
await fetch(`${settings.commerceUrl}${basket.getBasket}`, {
|
|
10
|
+
method: 'DELETE',
|
|
11
|
+
headers: {
|
|
12
|
+
Cookie: req.headers.get('cookie') || '',
|
|
13
|
+
'Content-Type': 'application/json',
|
|
14
|
+
'X-CSRFToken': req.cookies.get('csrftoken')?.value ?? '',
|
|
15
|
+
Referer: settings.commerceUrl
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
};
|
|
6
19
|
|
|
7
20
|
const withCurrency =
|
|
8
21
|
(middleware: NextMiddleware) =>
|
|
@@ -11,6 +24,7 @@ const withCurrency =
|
|
|
11
24
|
const { currencies, defaultCurrencyCode, defaultLocaleValue } =
|
|
12
25
|
settings.localization;
|
|
13
26
|
const locale = req.middlewareParams.rewrites.locale ?? defaultLocaleValue;
|
|
27
|
+
const url = req.nextUrl.clone();
|
|
14
28
|
|
|
15
29
|
if (!defaultCurrencyCode) {
|
|
16
30
|
logger.error('Default currency code is not defined in settings.');
|
|
@@ -34,6 +48,10 @@ const withCurrency =
|
|
|
34
48
|
defaultCurrencyCode
|
|
35
49
|
});
|
|
36
50
|
|
|
51
|
+
if (req.cookies.get('pz-set-currency')) {
|
|
52
|
+
activeCurrency = req.cookies.get('pz-set-currency')?.value;
|
|
53
|
+
}
|
|
54
|
+
|
|
37
55
|
if (
|
|
38
56
|
!activeCurrency ||
|
|
39
57
|
!currencies.find((c) => c.code === activeCurrency)
|
|
@@ -44,6 +62,22 @@ const withCurrency =
|
|
|
44
62
|
activeCurrency = defaultCurrencyCode;
|
|
45
63
|
}
|
|
46
64
|
|
|
65
|
+
if (
|
|
66
|
+
req.cookies.get('pz-currency') &&
|
|
67
|
+
req.cookies.get('pz-currency')?.value !== activeCurrency &&
|
|
68
|
+
url.pathname.match(urlLocaleMatcherRegex) &&
|
|
69
|
+
!url.search.includes('mobile_app=true') &&
|
|
70
|
+
!url.search.includes('page=CreditCardThreeDSecurePage')
|
|
71
|
+
) {
|
|
72
|
+
logger.info('Currency changed. Resetting basket...', {
|
|
73
|
+
sessionid: req.cookies.get('osessionid')?.value ?? '',
|
|
74
|
+
oldCurrency: req.cookies.get('pz-currency')?.value,
|
|
75
|
+
newCurrency: activeCurrency
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
resetBasket(req);
|
|
79
|
+
}
|
|
80
|
+
|
|
47
81
|
req.middlewareParams.rewrites.currency = activeCurrency;
|
|
48
82
|
} catch (error) {
|
|
49
83
|
logger.error('withCurrency error', error);
|
package/middlewares/default.ts
CHANGED
|
@@ -154,18 +154,6 @@ const withPzDefault =
|
|
|
154
154
|
secure: true
|
|
155
155
|
});
|
|
156
156
|
|
|
157
|
-
if (
|
|
158
|
-
req.cookies.get('pz-currency') &&
|
|
159
|
-
req.cookies.get('pz-currency').value !== currency
|
|
160
|
-
) {
|
|
161
|
-
logger.debug('Currency changed', {
|
|
162
|
-
currency,
|
|
163
|
-
oldCurrency: req.cookies.get('pz-currency')?.value
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
middlewareResult.cookies.set('pz-reset-basket', 'true');
|
|
167
|
-
}
|
|
168
|
-
|
|
169
157
|
if (
|
|
170
158
|
req.cookies.get('pz-locale') &&
|
|
171
159
|
req.cookies.get('pz-locale').value !== locale
|
|
@@ -174,11 +162,6 @@ const withPzDefault =
|
|
|
174
162
|
locale,
|
|
175
163
|
oldLocale: req.cookies.get('pz-locale')?.value
|
|
176
164
|
});
|
|
177
|
-
|
|
178
|
-
middlewareResult.cookies.set(
|
|
179
|
-
'pz-reset-client-cache',
|
|
180
|
-
'true'
|
|
181
|
-
);
|
|
182
165
|
}
|
|
183
166
|
|
|
184
167
|
middlewareResult.headers.set(
|
|
@@ -186,6 +169,10 @@ const withPzDefault =
|
|
|
186
169
|
req.nextUrl.toString()
|
|
187
170
|
);
|
|
188
171
|
|
|
172
|
+
if (req.cookies.get('pz-set-currency')) {
|
|
173
|
+
middlewareResult.cookies.delete('pz-set-currency');
|
|
174
|
+
}
|
|
175
|
+
|
|
189
176
|
if (process.env.ACC_APP_VERSION) {
|
|
190
177
|
middlewareResult.headers.set(
|
|
191
178
|
'acc-app-version',
|
|
@@ -18,7 +18,8 @@ const withOauthLogin =
|
|
|
18
18
|
|
|
19
19
|
const headers = {
|
|
20
20
|
'x-forwarded-host':
|
|
21
|
-
req.headers.get('x-forwarded-host') || req.headers.get('host') || ''
|
|
21
|
+
req.headers.get('x-forwarded-host') || req.headers.get('host') || '',
|
|
22
|
+
'x-currency': req.cookies.get('pz-currency')?.value ?? ''
|
|
22
23
|
};
|
|
23
24
|
|
|
24
25
|
if (loginUrlMatcherRegex.test(url.pathname)) {
|
|
@@ -55,7 +55,8 @@ const withRedirectionPayment =
|
|
|
55
55
|
headers: {
|
|
56
56
|
'X-Requested-With': 'XMLHttpRequest',
|
|
57
57
|
'Content-Type': 'application/x-www-form-urlencoded',
|
|
58
|
-
Cookie: req.headers.get('cookie') ?? ''
|
|
58
|
+
Cookie: req.headers.get('cookie') ?? '',
|
|
59
|
+
'x-currency': req.cookies.get('pz-currency')?.value ?? ''
|
|
59
60
|
},
|
|
60
61
|
body
|
|
61
62
|
});
|
|
@@ -37,86 +37,95 @@ const withThreeDRedirection =
|
|
|
37
37
|
return middleware(req, event);
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
const
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
40
|
+
const requestUrl = `${Settings.commerceUrl}/orders/checkout/${url.search}`;
|
|
41
|
+
const requestHeaders = {
|
|
42
|
+
'X-Requested-With': 'XMLHttpRequest',
|
|
43
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
44
|
+
Cookie: `osessionid=${req.cookies.get('osessionid')?.value ?? ''}`,
|
|
45
|
+
'x-currency': req.cookies.get('pz-currency')?.value ?? ''
|
|
46
|
+
};
|
|
47
47
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
return middleware(req, event);
|
|
51
|
-
}
|
|
48
|
+
try {
|
|
49
|
+
const body = await streamToString(req.body);
|
|
52
50
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
51
|
+
const request = await fetch(requestUrl, {
|
|
52
|
+
method: 'POST',
|
|
53
|
+
headers: requestHeaders,
|
|
54
|
+
body
|
|
55
|
+
});
|
|
57
56
|
|
|
58
|
-
|
|
57
|
+
logger.info('Complete 3D payment request', {
|
|
58
|
+
requestUrl,
|
|
59
|
+
status: request.status,
|
|
60
|
+
requestHeaders
|
|
61
|
+
});
|
|
59
62
|
|
|
60
|
-
|
|
63
|
+
const response = await request.json();
|
|
61
64
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
'X-Requested-With': 'XMLHttpRequest',
|
|
66
|
-
'Content-Type': 'application/x-www-form-urlencoded',
|
|
67
|
-
Cookie: `osessionid=${pzParams.session}`
|
|
68
|
-
},
|
|
69
|
-
body
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
logger.info('Complete 3D payment request', {
|
|
73
|
-
requestUrl,
|
|
74
|
-
status: request.status
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
const response = await request.json();
|
|
78
|
-
|
|
79
|
-
const { context_list: contextList } = response;
|
|
80
|
-
const redirectionContext = contextList?.find(
|
|
81
|
-
(context) => context.page_context?.redirect_url
|
|
82
|
-
);
|
|
83
|
-
const redirectUrl = redirectionContext?.page_context?.redirect_url;
|
|
84
|
-
|
|
85
|
-
logger.info('Order success page context list', {
|
|
86
|
-
middleware: 'three-d-redirection',
|
|
87
|
-
contextList
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
if (!redirectUrl) {
|
|
91
|
-
logger.warn(
|
|
92
|
-
'No redirection url for order success page found in page_context',
|
|
93
|
-
{
|
|
94
|
-
middleware: 'three-d-redirection'
|
|
95
|
-
}
|
|
65
|
+
const { context_list: contextList } = response;
|
|
66
|
+
const redirectionContext = contextList?.find(
|
|
67
|
+
(context) => context.page_context?.redirect_url
|
|
96
68
|
);
|
|
97
|
-
|
|
98
|
-
|
|
69
|
+
const redirectUrl = redirectionContext?.page_context?.redirect_url;
|
|
70
|
+
|
|
71
|
+
logger.info('Order success page context list', {
|
|
72
|
+
middleware: 'three-d-redirection',
|
|
73
|
+
contextList
|
|
74
|
+
});
|
|
99
75
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
76
|
+
if (!redirectUrl) {
|
|
77
|
+
logger.warn(
|
|
78
|
+
'No redirection url for order success page found in page_context. Redirecting to checkout page.',
|
|
79
|
+
{
|
|
80
|
+
middleware: 'three-d-redirection',
|
|
81
|
+
requestHeaders,
|
|
82
|
+
response: JSON.stringify(response)
|
|
83
|
+
}
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
const redirectUrlWithLocale = `${url.origin}${getUrlPathWithLocale(
|
|
87
|
+
'/orders/checkout/',
|
|
88
|
+
req.cookies.get('pz-locale')?.value
|
|
89
|
+
)}`;
|
|
90
|
+
|
|
91
|
+
return NextResponse.redirect(redirectUrlWithLocale, 303);
|
|
92
|
+
}
|
|
104
93
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
94
|
+
const redirectUrlWithLocale = `${url.origin}${getUrlPathWithLocale(
|
|
95
|
+
redirectUrl,
|
|
96
|
+
req.cookies.get('pz-locale')?.value
|
|
97
|
+
)}`;
|
|
109
98
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
99
|
+
logger.info('Redirecting to order success page', {
|
|
100
|
+
middleware: 'three-d-redirection',
|
|
101
|
+
redirectUrlWithLocale
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
// Using POST method while redirecting causes an error,
|
|
105
|
+
// So we use 303 status code to change the method to GET
|
|
106
|
+
const nextResponse = NextResponse.redirect(redirectUrlWithLocale, 303);
|
|
113
107
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
108
|
+
nextResponse.headers.set(
|
|
109
|
+
'Set-Cookie',
|
|
110
|
+
request.headers.get('set-cookie') ?? ''
|
|
111
|
+
);
|
|
118
112
|
|
|
119
|
-
|
|
113
|
+
return nextResponse;
|
|
114
|
+
} catch (error) {
|
|
115
|
+
logger.error('Error while completing 3D payment', {
|
|
116
|
+
middleware: 'three-d-redirection',
|
|
117
|
+
error,
|
|
118
|
+
requestHeaders
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
return NextResponse.redirect(
|
|
122
|
+
`${url.origin}${getUrlPathWithLocale(
|
|
123
|
+
'/orders/checkout/',
|
|
124
|
+
req.cookies.get('pz-locale')?.value
|
|
125
|
+
)}`,
|
|
126
|
+
303
|
|
127
|
+
);
|
|
128
|
+
}
|
|
120
129
|
};
|
|
121
130
|
|
|
122
131
|
export default withThreeDRedirection;
|
package/package.json
CHANGED
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@akinon/next",
|
|
3
3
|
"description": "Core package for Project Zero Next",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.4.0",
|
|
5
5
|
"private": false,
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"bin": {
|
|
8
|
-
"pz-
|
|
8
|
+
"pz-postbuild": "bin/pz-postbuild.js",
|
|
9
|
+
"pz-prebuild": "bin/pz-prebuild.js",
|
|
10
|
+
"pz-postinstall": "bin/pz-postinstall.js",
|
|
11
|
+
"pz-prestart": "bin/pz-prestart.js",
|
|
12
|
+
"pz-poststart": "bin/pz-poststart.js",
|
|
13
|
+
"pz-predev": "bin/pz-predev.js",
|
|
14
|
+
"pz-postdev": "bin/pz-postdev.js"
|
|
9
15
|
},
|
|
10
16
|
"dependencies": {
|
|
11
17
|
"@reduxjs/toolkit": "1.9.2",
|
|
@@ -42,18 +42,14 @@ export type AccountChangePasswordFormType = {
|
|
|
42
42
|
};
|
|
43
43
|
|
|
44
44
|
export type AccountProfileFormType = {
|
|
45
|
+
date_of_birth: string;
|
|
46
|
+
email_allowed: boolean;
|
|
45
47
|
first_name: string;
|
|
48
|
+
gender: string;
|
|
46
49
|
last_name: string;
|
|
47
50
|
phone: string;
|
|
48
|
-
email_allowed: boolean;
|
|
49
51
|
sms_allowed: boolean;
|
|
50
|
-
|
|
51
|
-
email: string;
|
|
52
|
-
birthdate_day: string;
|
|
53
|
-
birthdate_month: string;
|
|
54
|
-
birthdate_year: string;
|
|
55
|
-
country_code: string;
|
|
56
|
-
date_of_birth: string;
|
|
52
|
+
[key: string]: any;
|
|
57
53
|
};
|
|
58
54
|
|
|
59
55
|
export type ContactFormType = {
|
package/utils/index.ts
CHANGED
|
@@ -35,6 +35,9 @@ export function removeCookie(name: string) {
|
|
|
35
35
|
document.cookie = name + '=' + '; expires=' + date + '; path=/';
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
+
/**
|
|
39
|
+
* @deprecated Use setCurrency method in useLocalization hook instead.
|
|
40
|
+
*/
|
|
38
41
|
export function setCurrency(currency: string) {
|
|
39
42
|
if (getCookie('pz-currency') !== currency) {
|
|
40
43
|
setCookie('pz-reset-basket', 'true');
|
package/utils/log.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import * as Sentry from '@sentry/nextjs';
|
|
2
|
-
|
|
3
1
|
enum LogLevel {
|
|
4
2
|
TRACE = 'trace',
|
|
5
3
|
DEBUG = 'debug',
|
|
@@ -94,15 +92,6 @@ const error: LoggerFn = (message, payload) => {
|
|
|
94
92
|
message,
|
|
95
93
|
payload
|
|
96
94
|
});
|
|
97
|
-
|
|
98
|
-
Sentry.withScope(function (scope) {
|
|
99
|
-
scope.setLevel('error');
|
|
100
|
-
|
|
101
|
-
Sentry.captureException({
|
|
102
|
-
message,
|
|
103
|
-
extra: payload
|
|
104
|
-
});
|
|
105
|
-
});
|
|
106
95
|
};
|
|
107
96
|
|
|
108
97
|
const warn: LoggerFn = (message, payload) => {
|
|
@@ -111,15 +100,6 @@ const warn: LoggerFn = (message, payload) => {
|
|
|
111
100
|
message,
|
|
112
101
|
payload
|
|
113
102
|
});
|
|
114
|
-
|
|
115
|
-
Sentry.withScope(function (scope) {
|
|
116
|
-
scope.setLevel('warning');
|
|
117
|
-
|
|
118
|
-
Sentry.captureEvent({
|
|
119
|
-
message,
|
|
120
|
-
extra: payload
|
|
121
|
-
});
|
|
122
|
-
});
|
|
123
103
|
};
|
|
124
104
|
|
|
125
105
|
const debug: LoggerFn = (message, payload) => {
|