create-brainerce-store 1.28.4 → 1.28.9

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/dist/index.js CHANGED
@@ -31,7 +31,7 @@ var require_package = __commonJS({
31
31
  "package.json"(exports2, module2) {
32
32
  module2.exports = {
33
33
  name: "create-brainerce-store",
34
- version: "1.28.4",
34
+ version: "1.28.9",
35
35
  description: "Scaffold a production-ready e-commerce storefront connected to Brainerce",
36
36
  bin: {
37
37
  "create-brainerce-store": "dist/index.js"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-brainerce-store",
3
- "version": "1.28.4",
3
+ "version": "1.28.9",
4
4
  "description": "Scaffold a production-ready e-commerce storefront connected to Brainerce",
5
5
  "bin": {
6
6
  "create-brainerce-store": "dist/index.js"
@@ -2,10 +2,17 @@ import type { NextConfig } from 'next';
2
2
 
3
3
  const nextConfig: NextConfig = {
4
4
  images: {
5
- remotePatterns: [
6
- { protocol: 'https', hostname: 'cdn.brainerce.com' },
7
- { protocol: 'https', hostname: '*.brainerce.com' },
8
- ],
5
+ // The storefront is a consumer of the Brainerce API — it has to render
6
+ // whatever image URLs the API returns. In practice those URLs can be on
7
+ // cdn.brainerce.com OR on an upstream merchant host (WooCommerce, Shopify,
8
+ // self-hosted) depending on whether the product's image-import job has
9
+ // completed on the backend. Rather than hard-fail on unknown hosts, skip
10
+ // the server-side optimizer entirely and let the browser fetch each image
11
+ // directly from origin. No server-side fetching → no SSRF or DoS surface
12
+ // on this Next server. Trade-off: no webp/resize/lazy optimization, so
13
+ // LCP is marginally worse. Acceptable; the storefront is not the right
14
+ // layer to enforce a hostname policy.
15
+ unoptimized: true,
9
16
  },
10
17
  async headers() {
11
18
  return [
@@ -17,7 +24,11 @@ const nextConfig: NextConfig = {
17
24
  value: 'max-age=63072000; includeSubDomains; preload',
18
25
  },
19
26
  { key: 'X-Content-Type-Options', value: 'nosniff' },
20
- { key: 'X-Frame-Options', value: 'DENY' },
27
+ // SAMEORIGIN (not DENY) so iframe-based payment providers (e.g. Cardcom)
28
+ // can redirect the iframe back to /payment-complete on the storefront
29
+ // itself after a successful charge — the postMessage relay needs the
30
+ // parent frame to be able to render our own same-origin page.
31
+ { key: 'X-Frame-Options', value: 'SAMEORIGIN' },
21
32
  { key: 'Referrer-Policy', value: 'strict-origin-when-cross-origin' },
22
33
  {
23
34
  key: 'Permissions-Policy',
@@ -557,14 +557,14 @@ export function PaymentStep({ checkoutId, className }: PaymentStepProps) {
557
557
 
558
558
  if (sdk.renderType === 'iframe') {
559
559
  if (!isAllowedPaymentUrl(paymentIntent.clientSecret)) return null;
560
- const formattedAmount = formatPrice(Number(paymentIntent.amount) || 0, {
560
+ const formattedAmount = formatPrice((Number(paymentIntent.amount) || 0) / 100, {
561
561
  currency: paymentIntent.currency,
562
562
  }) as string;
563
563
  return (
564
564
  <>
565
565
  {/* Modal overlay */}
566
566
  <div className="fixed inset-0 z-50 flex items-start justify-center overflow-y-auto bg-black/50 py-6 backdrop-blur-sm">
567
- <div className="bg-background relative mx-4 flex w-full max-w-lg flex-col overflow-hidden rounded-2xl shadow-2xl">
567
+ <div className="bg-background relative mx-4 flex w-full max-w-2xl flex-col overflow-hidden rounded-2xl shadow-2xl">
568
568
  {/* Header */}
569
569
  <div className="border-border flex items-center justify-between gap-4 border-b px-5 py-4">
570
570
  <div className="flex min-w-0 flex-col">
@@ -605,7 +605,7 @@ export function PaymentStep({ checkoutId, className }: PaymentStepProps) {
605
605
  <iframe
606
606
  src={paymentIntent.clientSecret}
607
607
  className="w-full border-0"
608
- style={{ height: '70vh' }}
608
+ style={{ height: '80vh' }}
609
609
  title={t('payment')}
610
610
  allow="payment"
611
611
  />
@@ -35,7 +35,10 @@ function buildCsp(nonce: string): string {
35
35
  "frame-src 'self' https://meshulam.co.il https://*.meshulam.co.il https://grow.link https://*.grow.link https://grow.security https://*.grow.security https://creditguard.co.il https://*.creditguard.co.il https://js.stripe.com https://hooks.stripe.com https://pay.google.com https://secure.cardcom.solutions https://checkout.stripe.com https://www.paypal.com https://www.sandbox.paypal.com",
36
36
  "connect-src 'self' https://*.meshulam.co.il https://grow.link https://*.grow.link https://*.grow.security https://pay.google.com https://*.stripe.com https://*.creditguard.co.il",
37
37
  "worker-src 'self' blob:",
38
- "frame-ancestors 'none'",
38
+ // 'self' (not 'none') so iframe-based payment providers (e.g. Cardcom)
39
+ // can redirect the iframe back to /payment-complete on the storefront
40
+ // itself after a successful charge.
41
+ "frame-ancestors 'self'",
39
42
  "base-uri 'self'",
40
43
  "form-action 'self'",
41
44
  "object-src 'none'",
@@ -149,7 +152,10 @@ function buildCsp(nonce: string): string {
149
152
  "frame-src 'self' https://meshulam.co.il https://*.meshulam.co.il https://grow.link https://*.grow.link https://grow.security https://*.grow.security https://creditguard.co.il https://*.creditguard.co.il https://js.stripe.com https://hooks.stripe.com https://pay.google.com https://secure.cardcom.solutions https://checkout.stripe.com https://www.paypal.com https://www.sandbox.paypal.com",
150
153
  "connect-src 'self' https://*.meshulam.co.il https://grow.link https://*.grow.link https://*.grow.security https://pay.google.com https://*.stripe.com https://*.creditguard.co.il",
151
154
  "worker-src 'self' blob:",
152
- "frame-ancestors 'none'",
155
+ // 'self' (not 'none') so iframe-based payment providers (e.g. Cardcom)
156
+ // can redirect the iframe back to /payment-complete on the storefront
157
+ // itself after a successful charge.
158
+ "frame-ancestors 'self'",
153
159
  "base-uri 'self'",
154
160
  "form-action 'self'",
155
161
  "object-src 'none'",