Skip to content

Commit 838e047

Browse files
committed
W-21432256: address code review comments on ssr.js
1 parent 36d3c48 commit 838e047

File tree

4 files changed

+99
-132
lines changed

4 files changed

+99
-132
lines changed

packages/pwa-kit-create-app/assets/bootstrap/js/overrides/app/ssr.js.hbs

Lines changed: 31 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
import crypto from 'crypto'
1111
import express from 'express'
1212
import helmet from 'helmet'
13-
import https from 'https'
1413
import {createRemoteJWKSet as joseCreateRemoteJWKSet, jwtVerify, decodeJwt} from 'jose'
1514
import path from 'path'
1615
import {getRuntime} from '@salesforce/pwa-kit-runtime/ssr/server/express'
@@ -359,7 +358,8 @@ const {handler} = runtime.createHandler(options, (app) => {
359358
'*.stripe.com',
360359
'*.paypal.com',
361360
'*.adyen.com',
362-
'*.google.com',
361+
'pay.google.com',
362+
'www.gstatic.com',
363363
'*.demandware.net' // Used to load a valid payment scripts in test environment
364364
],
365365
'connect-src': [
@@ -375,16 +375,21 @@ const {handler} = runtime.createHandler(options, (app) => {
375375
// Payment gateways
376376
'*.demandware.net', // Used to load a valid payment scripts in test environment
377377
'*.adyen.com',
378-
'*.google.com'
378+
'*.paypal.com',
379+
'pay.google.com',
380+
'payments.google.com',
381+
'google.com',
382+
'www.google.com'
379383
],
380384
'frame-src': [
381385
// Allow frames from Salesforce site.com (Needed for MIAW)
382386
'*.site.com',
383387
// Payment gateways
384388
'*.stripe.com',
385389
'*.paypal.com',
386-
'*.google.com',
387-
'*.adyen.com'
390+
'*.adyen.com',
391+
'payments.google.com',
392+
'pay.google.com'
388393
]
389394
}
390395
}
@@ -450,49 +455,30 @@ const {handler} = runtime.createHandler(options, (app) => {
450455
// Helper function to transform relative icon paths to absolute URLs
451456
function transformIconPaths(data, ecomServerHost) {
452457
const baseUrl = `https://${ecomServerHost}/on/demandware.static/Sites-Site/-/-/internal`
453-
const dataStr = JSON.stringify(data)
454-
// Replace all relative icon paths with absolute URLs
455-
const transformedStr = dataStr.replace(/"src":\s*"\/icons\//g, `"src":"${baseUrl}/icons/`)
456-
return JSON.parse(transformedStr)
458+
const methodTypes = data?.paymentMethodTypes
459+
if (methodTypes) {
460+
for (const method of Object.values(methodTypes)) {
461+
for (const image of method.images ?? []) {
462+
if (image.src?.startsWith('/icons/')) {
463+
image.src = `${baseUrl}${image.src}`
464+
}
465+
}
466+
}
467+
}
468+
return data
457469
}
458-
470+
471+
// Helper function to fetch payment metadata from the Commerce Cloud instance
459472
app.get('/api/payment-metadata', async (req, res) => {
460473
try {
461-
// Parse the URL to extract hostname and path
462-
const url = new URL(config.app.sfPayments.metadataUrl)
463-
// Use Node's https module instead of fetch
464-
const data = await new Promise((resolve, reject) => {
465-
const options = {
466-
hostname: url.hostname,
467-
path: url.pathname,
468-
method: 'GET',
469-
rejectUnauthorized: false, // This bypasses SSL verification
470-
headers: {
471-
Accept: 'application/json'
472-
}
473-
}
474-
475-
const req = https.request(options, (response) => {
476-
let data = ''
477-
response.on('data', (chunk) => {
478-
data += chunk
479-
})
480-
response.on('end', () => {
481-
try {
482-
resolve(JSON.parse(data))
483-
} catch (e) {
484-
reject(e)
485-
}
486-
})
487-
})
488-
489-
req.on('error', reject)
490-
req.end()
474+
const response = await fetch(config.app.sfPayments.metadataUrl, {
475+
headers: { Accept: 'application/json' }
491476
})
492-
493-
// Transform relative icon paths to absolute URLs
494-
const transformedData = transformIconPaths(data, url.hostname)
495-
477+
if (!response.ok) {
478+
throw new Error(`Metadata request failed with status: ${response.status}`)
479+
}
480+
const data = await response.json()
481+
const transformedData = transformIconPaths(data, new URL(config.app.sfPayments.metadataUrl).hostname)
496482
res.setHeader('Access-Control-Allow-Origin', '*')
497483
res.setHeader('Content-Type', 'application/json')
498484
res.json(transformedData)
@@ -503,6 +489,7 @@ const {handler} = runtime.createHandler(options, (app) => {
503489
})
504490
}
505491
})
492+
506493
app.get('*', runtime.render)
507494
})
508495
// SSR requires that we export a single handler function called 'get', that

packages/pwa-kit-create-app/assets/templates/@salesforce/retail-react-app/app/ssr.js.hbs

Lines changed: 30 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
import crypto from 'crypto'
1111
import express from 'express'
1212
import helmet from 'helmet'
13-
import https from 'https'
1413
import {createRemoteJWKSet as joseCreateRemoteJWKSet, jwtVerify, decodeJwt} from 'jose'
1514
import path from 'path'
1615
import {getRuntime} from '@salesforce/pwa-kit-runtime/ssr/server/express'
@@ -359,7 +358,8 @@ const {handler} = runtime.createHandler(options, (app) => {
359358
'*.stripe.com',
360359
'*.paypal.com',
361360
'*.adyen.com',
362-
'*.google.com',
361+
'pay.google.com',
362+
'www.gstatic.com',
363363
'*.demandware.net' // Used to load a valid payment scripts in test environment
364364
],
365365
'connect-src': [
@@ -375,16 +375,21 @@ const {handler} = runtime.createHandler(options, (app) => {
375375
// Payment gateways
376376
'*.demandware.net', // Used to load a valid payment scripts in test environment
377377
'*.adyen.com',
378-
'*.google.com'
378+
'*.paypal.com',
379+
'pay.google.com',
380+
'payments.google.com',
381+
'google.com',
382+
'www.google.com'
379383
],
380384
'frame-src': [
381385
// Allow frames from Salesforce site.com (Needed for MIAW)
382386
'*.site.com',
383387
// Payment gateways
384388
'*.stripe.com',
385389
'*.paypal.com',
386-
'*.google.com',
387-
'*.adyen.com'
390+
'*.adyen.com',
391+
'payments.google.com',
392+
'pay.google.com'
388393
]
389394
}
390395
}
@@ -450,49 +455,30 @@ const {handler} = runtime.createHandler(options, (app) => {
450455
// Helper function to transform relative icon paths to absolute URLs
451456
function transformIconPaths(data, ecomServerHost) {
452457
const baseUrl = `https://${ecomServerHost}/on/demandware.static/Sites-Site/-/-/internal`
453-
const dataStr = JSON.stringify(data)
454-
// Replace all relative icon paths with absolute URLs
455-
const transformedStr = dataStr.replace(/"src":\s*"\/icons\//g, `"src":"${baseUrl}/icons/`)
456-
return JSON.parse(transformedStr)
458+
const methodTypes = data?.paymentMethodTypes
459+
if (methodTypes) {
460+
for (const method of Object.values(methodTypes)) {
461+
for (const image of method.images ?? []) {
462+
if (image.src?.startsWith('/icons/')) {
463+
image.src = `${baseUrl}${image.src}`
464+
}
465+
}
466+
}
467+
}
468+
return data
457469
}
458-
470+
471+
// Helper function to fetch payment metadata from the Commerce Cloud instance
459472
app.get('/api/payment-metadata', async (req, res) => {
460473
try {
461-
// Parse the URL to extract hostname and path
462-
const url = new URL(config.app.sfPayments.metadataUrl)
463-
// Use Node's https module instead of fetch
464-
const data = await new Promise((resolve, reject) => {
465-
const options = {
466-
hostname: url.hostname,
467-
path: url.pathname,
468-
method: 'GET',
469-
rejectUnauthorized: false, // This bypasses SSL verification
470-
headers: {
471-
Accept: 'application/json'
472-
}
473-
}
474-
475-
const req = https.request(options, (response) => {
476-
let data = ''
477-
response.on('data', (chunk) => {
478-
data += chunk
479-
})
480-
response.on('end', () => {
481-
try {
482-
resolve(JSON.parse(data))
483-
} catch (e) {
484-
reject(e)
485-
}
486-
})
487-
})
488-
489-
req.on('error', reject)
490-
req.end()
474+
const response = await fetch(config.app.sfPayments.metadataUrl, {
475+
headers: { Accept: 'application/json' }
491476
})
492-
493-
// Transform relative icon paths to absolute URLs
494-
const transformedData = transformIconPaths(data, url.hostname)
495-
477+
if (!response.ok) {
478+
throw new Error(`Metadata request failed with status: ${response.status}`)
479+
}
480+
const data = await response.json()
481+
const transformedData = transformIconPaths(data, new URL(config.app.sfPayments.metadataUrl).hostname)
496482
res.setHeader('Access-Control-Allow-Origin', '*')
497483
res.setHeader('Content-Type', 'application/json')
498484
res.json(transformedData)

packages/template-retail-react-app/app/hooks/use-shopper-configuration.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,13 @@ import {useConfigurations} from '@salesforce/commerce-sdk-react'
1313
* @returns {*} The configuration value, or undefined if not found
1414
*/
1515
export const useShopperConfiguration = (configurationId) => {
16-
const {data: configurations} = useConfigurations()
16+
// Stale time is set to 10 minutes to avoid unnecessary API calls
17+
const {data: configurations} = useConfigurations(
18+
{},
19+
{
20+
staleTime: 10 * 60 * 1000 // 10 minutes
21+
}
22+
)
1723
const config = configurations?.configurations?.find(
1824
(configuration) => configuration.id === configurationId
1925
)

packages/template-retail-react-app/app/ssr.js

Lines changed: 31 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
import crypto from 'crypto'
2020
import express from 'express'
2121
import helmet from 'helmet'
22-
import https from 'https'
2322
import {createRemoteJWKSet as joseCreateRemoteJWKSet, jwtVerify, decodeJwt} from 'jose'
2423
import path from 'path'
2524
import {getRuntime} from '@salesforce/pwa-kit-runtime/ssr/server/express'
@@ -370,7 +369,8 @@ const {handler} = runtime.createHandler(options, (app) => {
370369
'*.stripe.com',
371370
'*.paypal.com',
372371
'*.adyen.com',
373-
'*.google.com',
372+
'pay.google.com',
373+
'www.gstatic.com',
374374
'*.demandware.net', // Used to load a valid payment scripts in test environment
375375
'maps.googleapis.com',
376376
'places.googleapis.com'
@@ -387,7 +387,11 @@ const {handler} = runtime.createHandler(options, (app) => {
387387
// Payment gateways
388388
'*.demandware.net', // Used to load a valid payment scripts in test environment
389389
'*.adyen.com',
390-
'*.google.com'
390+
'*.paypal.com',
391+
'pay.google.com',
392+
'payments.google.com',
393+
'google.com',
394+
'www.google.com'
391395
],
392396
'frame-src': [
393397
// Allow frames from Salesforce site.com (Needed for MIAW)
@@ -396,7 +400,8 @@ const {handler} = runtime.createHandler(options, (app) => {
396400
'*.stripe.com',
397401
'*.paypal.com',
398402
'*.adyen.com',
399-
'*.google.com'
403+
'payments.google.com',
404+
'pay.google.com'
400405
]
401406
}
402407
}
@@ -457,50 +462,33 @@ const {handler} = runtime.createHandler(options, (app) => {
457462
// Helper function to transform relative icon paths to absolute URLs
458463
function transformIconPaths(data, ecomServerHost) {
459464
const baseUrl = `https://${ecomServerHost}/on/demandware.static/Sites-Site/-/-/internal`
460-
const dataStr = JSON.stringify(data)
461-
// Replace all relative icon paths with absolute URLs
462-
const transformedStr = dataStr.replace(/"src":\s*"\/icons\//g, `"src":"${baseUrl}/icons/`)
463-
return JSON.parse(transformedStr)
465+
const methodTypes = data?.paymentMethodTypes
466+
if (methodTypes) {
467+
for (const method of Object.values(methodTypes)) {
468+
for (const image of method.images ?? []) {
469+
if (image.src?.startsWith('/icons/')) {
470+
image.src = `${baseUrl}${image.src}`
471+
}
472+
}
473+
}
474+
}
475+
return data
464476
}
465477

478+
// Helper function to fetch payment metadata from the Commerce Cloud instance
466479
app.get('/api/payment-metadata', async (req, res) => {
467480
try {
468-
// Parse the URL to extract hostname and path
469-
const url = new URL(config.app.sfPayments.metadataUrl)
470-
// Use Node's https module instead of fetch
471-
const data = await new Promise((resolve, reject) => {
472-
const options = {
473-
hostname: url.hostname,
474-
path: url.pathname,
475-
method: 'GET',
476-
rejectUnauthorized: false, // This bypasses SSL verification
477-
headers: {
478-
Accept: 'application/json'
479-
}
480-
}
481-
482-
const req = https.request(options, (response) => {
483-
let data = ''
484-
response.on('data', (chunk) => {
485-
data += chunk
486-
})
487-
response.on('end', () => {
488-
try {
489-
resolve(JSON.parse(data))
490-
} catch (e) {
491-
reject(e)
492-
}
493-
})
494-
})
495-
496-
req.on('error', reject)
497-
req.end()
481+
const response = await fetch(config.app.sfPayments.metadataUrl, {
482+
headers: {Accept: 'application/json'}
498483
})
499-
500-
// Transform relative icon paths to absolute URLs
501-
const transformedData = transformIconPaths(data, url.hostname)
502-
503-
res.setHeader('Access-Control-Allow-Origin', '*')
484+
if (!response.ok) {
485+
throw new Error(`Metadata request failed with status: ${response.status}`)
486+
}
487+
const data = await response.json()
488+
const transformedData = transformIconPaths(
489+
data,
490+
new URL(config.app.sfPayments.metadataUrl).hostname
491+
)
504492
res.setHeader('Content-Type', 'application/json')
505493
res.json(transformedData)
506494
} catch (error) {

0 commit comments

Comments
 (0)