@akinon/next 2.0.16-beta.0 → 2.0.16-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.
@@ -17,8 +17,12 @@ import {
17
17
  withMasterpassRestCallback,
18
18
  withBfcacheHeaders
19
19
  } from '.';
20
- import { urlLocaleMatcherRegex } from '../utils';
21
- import { getPzSegmentsConfig, encodePzValue, isLegacyMode } from '../utils/pz-segments';
20
+ import { getCsrfCookieFlags, urlLocaleMatcherRegex } from '../utils';
21
+ import {
22
+ getPzSegmentsConfig,
23
+ encodePzValue,
24
+ isLegacyMode
25
+ } from '../utils/pz-segments';
22
26
  import withCurrency from './currency';
23
27
  import withLocale from './locale';
24
28
  import logger from '../utils/log';
@@ -262,98 +266,98 @@ const withPzDefault =
262
266
  req: PzNextRequest,
263
267
  event: NextFetchEvent
264
268
  ) => {
265
- let middlewareResult: NextResponse | void =
266
- NextResponse.next();
267
-
268
- try {
269
- const { locale, prettyUrl, currency } =
270
- req.middlewareParams.rewrites;
271
- const { defaultLocaleValue } =
272
- Settings.localization;
273
- const url = req.nextUrl.clone();
274
- const pathnameWithoutLocale =
275
- url.pathname.replace(
276
- urlLocaleMatcherRegex,
277
- ''
278
- );
269
+ let middlewareResult: NextResponse | void =
270
+ NextResponse.next();
271
+
272
+ try {
273
+ const { locale, prettyUrl, currency } =
274
+ req.middlewareParams.rewrites;
275
+ const { defaultLocaleValue } =
276
+ Settings.localization;
277
+ const url = req.nextUrl.clone();
278
+ const pathnameWithoutLocale =
279
+ url.pathname.replace(
280
+ urlLocaleMatcherRegex,
281
+ ''
282
+ );
279
283
 
280
- middlewareResult = (await middleware(
281
- req,
282
- event
283
- )) as NextResponse | void;
284
-
285
- let customRewriteUrlDiff = '';
286
-
287
- if (
288
- middlewareResult instanceof
289
- NextResponse &&
290
- middlewareResult.headers.get(
291
- 'pz-override-response'
292
- ) &&
293
- middlewareResult.headers.get(
294
- 'x-middleware-rewrite'
295
- )
296
- ) {
297
- const rewriteUrl = new URL(
284
+ middlewareResult = (await middleware(
285
+ req,
286
+ event
287
+ )) as NextResponse | void;
288
+
289
+ let customRewriteUrlDiff = '';
290
+
291
+ if (
292
+ middlewareResult instanceof
293
+ NextResponse &&
294
+ middlewareResult.headers.get(
295
+ 'pz-override-response'
296
+ ) &&
298
297
  middlewareResult.headers.get(
299
298
  'x-middleware-rewrite'
300
299
  )
301
- );
302
- const originalUrl = new URL(req.url);
303
- customRewriteUrlDiff =
304
- rewriteUrl.pathname.replace(
305
- originalUrl.pathname,
306
- ''
300
+ ) {
301
+ const rewriteUrl = new URL(
302
+ middlewareResult.headers.get(
303
+ 'x-middleware-rewrite'
304
+ )
307
305
  );
308
- }
306
+ const originalUrl = new URL(req.url);
307
+ customRewriteUrlDiff =
308
+ rewriteUrl.pathname.replace(
309
+ originalUrl.pathname,
310
+ ''
311
+ );
312
+ }
309
313
 
310
- let ordersPrefix: string;
314
+ let ordersPrefix: string;
311
315
 
312
- if (isLegacyMode(Settings)) {
313
- url.basePath = `/${commerceUrl}`;
314
- url.pathname =
315
- `/${locale.length ? `${locale}/` : ''}${currency}/${customRewriteUrlDiff}${
316
- prettyUrl ?? pathnameWithoutLocale
317
- }`.replace(/\/+/g, '/');
318
- ordersPrefix = `/${currency}/orders`;
319
- } else {
320
- const pzConfig =
321
- getPzSegmentsConfig(Settings);
322
- const fullUrlPath =
323
- `${customRewriteUrlDiff}${
316
+ if (isLegacyMode(Settings)) {
317
+ url.basePath = `/${commerceUrl}`;
318
+ url.pathname = `/${
319
+ locale.length ? `${locale}/` : ''
320
+ }${currency}/${customRewriteUrlDiff}${
324
321
  prettyUrl ?? pathnameWithoutLocale
325
322
  }`.replace(/\/+/g, '/');
326
- const fullUrl = `${req.nextUrl.origin}${fullUrlPath}`;
327
- const resolvedLocale =
328
- locale?.length > 0
329
- ? locale
330
- : Settings.localization
331
- .defaultLocaleValue;
332
- const resolveContext = {
333
- req,
334
- event,
335
- url,
336
- locale: resolvedLocale,
337
- currency,
338
- pathname: pathnameWithoutLocale
339
- };
340
- const customSegments = pzConfig.segments
341
- .filter(
342
- (seg) =>
343
- seg.name !== 'locale' &&
344
- seg.name !== 'currency' &&
345
- seg.name !== 'url'
346
- );
347
- const segmentValues: Record<
348
- string,
349
- string
350
- > = {
351
- locale: resolvedLocale,
352
- currency,
353
- url: encodeURIComponent(fullUrl),
354
- ...Object.fromEntries(
355
- customSegments
356
- .map((seg) => [
323
+ ordersPrefix = `/${currency}/orders`;
324
+ } else {
325
+ const pzConfig =
326
+ getPzSegmentsConfig(Settings);
327
+ const fullUrlPath =
328
+ `${customRewriteUrlDiff}${
329
+ prettyUrl ?? pathnameWithoutLocale
330
+ }`.replace(/\/+/g, '/');
331
+ const fullUrl = `${req.nextUrl.origin}${fullUrlPath}`;
332
+ const resolvedLocale =
333
+ locale?.length > 0
334
+ ? locale
335
+ : Settings.localization
336
+ .defaultLocaleValue;
337
+ const resolveContext = {
338
+ req,
339
+ event,
340
+ url,
341
+ locale: resolvedLocale,
342
+ currency,
343
+ pathname: pathnameWithoutLocale
344
+ };
345
+ const customSegments =
346
+ pzConfig.segments.filter(
347
+ (seg) =>
348
+ seg.name !== 'locale' &&
349
+ seg.name !== 'currency' &&
350
+ seg.name !== 'url'
351
+ );
352
+ const segmentValues: Record<
353
+ string,
354
+ string
355
+ > = {
356
+ locale: resolvedLocale,
357
+ currency,
358
+ url: encodeURIComponent(fullUrl),
359
+ ...Object.fromEntries(
360
+ customSegments.map((seg) => [
357
361
  seg.name,
358
362
  req.middlewareParams.rewrites[
359
363
  seg.name
@@ -362,105 +366,121 @@ const withPzDefault =
362
366
  ? seg.resolve(resolveContext)
363
367
  : '')
364
368
  ])
365
- )
366
- };
367
-
368
- const pzValue = encodePzValue(
369
- segmentValues,
370
- pzConfig
371
- );
369
+ )
370
+ };
372
371
 
373
- url.pathname =
374
- `/${pzValue}/${fullUrlPath}`.replace(
375
- /\/+/g,
376
- '/'
372
+ const pzValue = encodePzValue(
373
+ segmentValues,
374
+ pzConfig
377
375
  );
378
- ordersPrefix = `/${pzValue}/orders`;
379
- }
380
376
 
381
- if (
382
- Settings.usePrettyUrlRoute &&
383
- url.searchParams.toString().length > 0 &&
384
- !Object.entries(ROUTES).find(
385
- ([, value]) =>
386
- new RegExp(`^${value}/?$`).test(
387
- pathnameWithoutLocale
388
- )
389
- )
390
- ) {
391
- url.pathname =
392
- url.pathname +
393
- (/\/$/.test(url.pathname) ? '' : '/') +
394
- `searchparams|${encodeURIComponent(
395
- url.searchParams.toString()
396
- )}`;
397
- }
398
-
399
- Settings.rewrites.forEach((rewrite) => {
400
- url.pathname = url.pathname.replace(
401
- rewrite.source,
402
- rewrite.destination
403
- );
404
- });
377
+ url.pathname =
378
+ `/${pzValue}/${fullUrlPath}`.replace(
379
+ /\/+/g,
380
+ '/'
381
+ );
382
+ ordersPrefix = `/${pzValue}/orders`;
383
+ }
405
384
 
406
- // if middleware.ts has a return value for current url
407
- if (
408
- middlewareResult instanceof NextResponse
409
- ) {
410
- // pz-override-response header is used to prevent 404 page for custom responses.
411
385
  if (
412
- middlewareResult.headers.get(
413
- 'pz-override-response'
414
- ) !== 'true'
386
+ Settings.usePrettyUrlRoute &&
387
+ url.searchParams.toString().length >
388
+ 0 &&
389
+ !Object.entries(ROUTES).find(
390
+ ([, value]) =>
391
+ new RegExp(`^${value}/?$`).test(
392
+ pathnameWithoutLocale
393
+ )
394
+ )
415
395
  ) {
416
- middlewareResult.headers.set(
417
- 'x-middleware-rewrite',
418
- url.href
396
+ url.pathname =
397
+ url.pathname +
398
+ (/\/$/.test(url.pathname)
399
+ ? ''
400
+ : '/') +
401
+ `searchparams|${encodeURIComponent(
402
+ url.searchParams.toString()
403
+ )}`;
404
+ }
405
+
406
+ Settings.rewrites.forEach((rewrite) => {
407
+ url.pathname = url.pathname.replace(
408
+ rewrite.source,
409
+ rewrite.destination
419
410
  );
420
- } else if (
421
- middlewareResult.headers.get(
422
- 'x-middleware-rewrite'
423
- ) &&
424
- middlewareResult.headers.get(
425
- 'pz-override-response'
426
- ) === 'true'
411
+ });
412
+
413
+ // if middleware.ts has a return value for current url
414
+ if (
415
+ middlewareResult instanceof NextResponse
427
416
  ) {
417
+ // pz-override-response header is used to prevent 404 page for custom responses.
418
+ if (
419
+ middlewareResult.headers.get(
420
+ 'pz-override-response'
421
+ ) !== 'true'
422
+ ) {
423
+ middlewareResult.headers.set(
424
+ 'x-middleware-rewrite',
425
+ url.href
426
+ );
427
+ } else if (
428
+ middlewareResult.headers.get(
429
+ 'x-middleware-rewrite'
430
+ ) &&
431
+ middlewareResult.headers.get(
432
+ 'pz-override-response'
433
+ ) === 'true'
434
+ ) {
435
+ middlewareResult =
436
+ NextResponse.rewrite(url);
437
+ }
438
+ } else {
439
+ // if middleware.ts doesn't have a return value.
440
+ // e.g. NextResponse.next() doesn't exist in middleware.ts
441
+
428
442
  middlewareResult =
429
443
  NextResponse.rewrite(url);
430
444
  }
431
- } else {
432
- // if middleware.ts doesn't have a return value.
433
- // e.g. NextResponse.next() doesn't exist in middleware.ts
434
445
 
435
- middlewareResult =
436
- NextResponse.rewrite(url);
437
- }
446
+ const { localeUrlStrategy } =
447
+ Settings.localization;
448
+
449
+ const fallbackHost =
450
+ req.headers.get('x-forwarded-host') ||
451
+ req.headers.get('host');
452
+ const hostname =
453
+ process.env.NEXT_PUBLIC_URL ||
454
+ `https://${fallbackHost}`;
455
+ const rootHostname =
456
+ localeUrlStrategy ===
457
+ LocaleUrlStrategy.Subdomain
458
+ ? getRootHostname(hostname)
459
+ : null;
460
+
461
+ if (
462
+ !url.pathname.startsWith(ordersPrefix)
463
+ ) {
464
+ middlewareResult.cookies.set(
465
+ 'pz-locale',
466
+ locale?.length > 0
467
+ ? locale
468
+ : defaultLocaleValue,
469
+ {
470
+ domain: rootHostname,
471
+ sameSite: 'none',
472
+ secure: true,
473
+ expires: new Date(
474
+ Date.now() +
475
+ 1000 * 60 * 60 * 24 * 7
476
+ ) // 7 days
477
+ }
478
+ );
479
+ }
438
480
 
439
- const { localeUrlStrategy } =
440
- Settings.localization;
441
-
442
- const fallbackHost =
443
- req.headers.get('x-forwarded-host') ||
444
- req.headers.get('host');
445
- const hostname =
446
- process.env.NEXT_PUBLIC_URL ||
447
- `https://${fallbackHost}`;
448
- const rootHostname =
449
- localeUrlStrategy ===
450
- LocaleUrlStrategy.Subdomain
451
- ? getRootHostname(hostname)
452
- : null;
453
-
454
- if (
455
- !url.pathname.startsWith(
456
- ordersPrefix
457
- )
458
- ) {
459
481
  middlewareResult.cookies.set(
460
- 'pz-locale',
461
- locale?.length > 0
462
- ? locale
463
- : defaultLocaleValue,
482
+ 'pz-currency',
483
+ currency,
464
484
  {
465
485
  domain: rootHostname,
466
486
  sameSite: 'none',
@@ -470,102 +490,89 @@ const withPzDefault =
470
490
  ) // 7 days
471
491
  }
472
492
  );
473
- }
474
493
 
475
- middlewareResult.cookies.set(
476
- 'pz-currency',
477
- currency,
478
- {
479
- domain: rootHostname,
480
- sameSite: 'none',
481
- secure: true,
482
- expires: new Date(
483
- Date.now() + 1000 * 60 * 60 * 24 * 7
484
- ) // 7 days
494
+ if (
495
+ req.cookies.get('pz-locale') &&
496
+ req.cookies.get('pz-locale').value !==
497
+ locale
498
+ ) {
499
+ logger.debug('Locale changed', {
500
+ locale,
501
+ oldLocale:
502
+ req.cookies.get('pz-locale')?.value,
503
+ ip
504
+ });
485
505
  }
486
- );
487
-
488
- if (
489
- req.cookies.get('pz-locale') &&
490
- req.cookies.get('pz-locale').value !==
491
- locale
492
- ) {
493
- logger.debug('Locale changed', {
494
- locale,
495
- oldLocale:
496
- req.cookies.get('pz-locale')?.value,
497
- ip
498
- });
499
- }
500
-
501
- middlewareResult.headers.set(
502
- 'pz-url',
503
- req.nextUrl.toString()
504
- );
505
506
 
506
- if (req.cookies.get('pz-set-currency')) {
507
- middlewareResult.cookies.delete(
508
- 'pz-set-currency'
507
+ middlewareResult.headers.set(
508
+ 'pz-url',
509
+ req.nextUrl.toString()
509
510
  );
510
- }
511
511
 
512
- if (
513
- req.cookies.get(
514
- 'pz-post-checkout-flow'
515
- )
516
- ) {
517
- if (
518
- pathnameWithoutLocale.startsWith(
519
- '/orders/completed/'
520
- ) ||
521
- pathnameWithoutLocale.startsWith(
522
- '/basket'
523
- )
524
- ) {
512
+ if (req.cookies.get('pz-set-currency')) {
525
513
  middlewareResult.cookies.delete(
526
- 'pz-post-checkout-flow'
514
+ 'pz-set-currency'
527
515
  );
528
516
  }
529
- }
530
-
531
- if (process.env.ACC_APP_VERSION) {
532
- middlewareResult.headers.set(
533
- 'acc-app-version',
534
- process.env.ACC_APP_VERSION
535
- );
536
- }
537
517
 
538
- // Set CSRF token if not set
539
- try {
540
- const url = `${Settings.commerceUrl}${user.csrfToken}`;
518
+ if (
519
+ req.cookies.get('pz-post-checkout-flow')
520
+ ) {
521
+ if (
522
+ pathnameWithoutLocale.startsWith(
523
+ '/orders/completed/'
524
+ ) ||
525
+ pathnameWithoutLocale.startsWith(
526
+ '/basket'
527
+ )
528
+ ) {
529
+ middlewareResult.cookies.delete(
530
+ 'pz-post-checkout-flow'
531
+ );
532
+ }
533
+ }
541
534
 
542
- if (!req.cookies.get('csrftoken')) {
543
- const { csrf_token } = await (
544
- await fetch(url)
545
- ).json();
546
- middlewareResult.cookies.set(
547
- 'csrftoken',
548
- csrf_token,
549
- {
550
- domain: rootHostname
551
- }
535
+ if (process.env.ACC_APP_VERSION) {
536
+ middlewareResult.headers.set(
537
+ 'acc-app-version',
538
+ process.env.ACC_APP_VERSION
552
539
  );
553
540
  }
541
+
542
+ // Set CSRF token if not set
543
+ try {
544
+ const url = `${Settings.commerceUrl}${user.csrfToken}`;
545
+
546
+ if (!req.cookies.get('csrftoken')) {
547
+ const { csrf_token } = await (
548
+ await fetch(url)
549
+ ).json();
550
+ middlewareResult.cookies.set(
551
+ 'csrftoken',
552
+ csrf_token,
553
+ {
554
+ path: '/',
555
+ domain: rootHostname,
556
+ ...getCsrfCookieFlags()
557
+ }
558
+ );
559
+ }
560
+ } catch (error) {
561
+ logger.error('CSRF Error', {
562
+ error,
563
+ ip
564
+ });
565
+ }
554
566
  } catch (error) {
555
- logger.error('CSRF Error', {
567
+ logger.error('withPzDefault Error', {
556
568
  error,
557
569
  ip
558
570
  });
559
571
  }
560
- } catch (error) {
561
- logger.error('withPzDefault Error', {
562
- error,
563
- ip
564
- });
565
- }
566
572
 
567
- return middlewareResult;
568
- })
573
+ return middlewareResult;
574
+ }
575
+ )
569
576
  )
570
577
  )
571
578
  )