Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SPIKE] Namespace /mobify #1795

Closed
wants to merge 12 commits into from
5 changes: 3 additions & 2 deletions packages/commerce-sdk-react/src/auth/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ interface AuthConfig extends ApiClientConfigParams {
proxy: string
fetchOptions?: ShopperLoginTypes.FetchOptions
fetchedToken?: string
envNamespace?: string
OCAPISessionsURL?: string
enablePWAKitPrivateClient?: boolean
clientSecret?: string
Expand Down Expand Up @@ -175,7 +176,7 @@ class Auth {

constructor(config: AuthConfig) {
// Special endpoint for injecting SLAS private client secret
const baseUrl = config.proxy.split(`/mobify/proxy/api`)[0]
const baseUrl = config.proxy.split(`/mobify`)[0]
const privateClientEndpoint = `${baseUrl}/mobify/slas/private`

this.client = new ShopperLogin({
Expand All @@ -202,7 +203,7 @@ class Auth {
})

const options = {
keySuffix: config.siteId,
keySuffix: config.envNamespace ? `${config.envNamespace}_${config.siteId}` : config.siteId,
// Setting this to true on the server allows us to reuse guest auth tokens across lambda runs
sharedContext: !onClient()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
*/

import {ApiClients} from '../../hooks/types'
import {DEVELOPMENT_ORIGIN, getParentOrigin, isOriginTrusted} from '../../utils'
import {DEVELOPMENT_ORIGIN, getParentOrigin, isOriginTrusted, getNamespace} from '../../utils'

/** Detects whether the storefront is running in an iframe as part of Storefront Preview.
* @private
Expand All @@ -21,8 +21,9 @@ export const detectStorefrontPreview = () => {
*/
export const getClientScript = () => {
const parentOrigin = getParentOrigin() ?? 'https://runtime.commercecloud.com'

return parentOrigin === DEVELOPMENT_ORIGIN
? `${parentOrigin}/mobify/bundle/development/static/storefront-preview.js`
? `${parentOrigin}${getNamespace()}/mobify/bundle/development/static/storefront-preview.js`
: `${parentOrigin}/cc/b2c/preview/preview.client.js`
}

Expand Down
5 changes: 5 additions & 0 deletions packages/commerce-sdk-react/src/provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export interface CommerceApiProviderProps extends ApiClientConfigParams {
fetchOptions?: ShopperBasketsTypes.FetchOptions
headers?: Record<string, string>
fetchedToken?: string
envNamespace?: string
OCAPISessionsURL?: string
enablePWAKitPrivateClient?: boolean
clientSecret?: string
Expand Down Expand Up @@ -107,6 +108,7 @@ const CommerceApiProvider = (props: CommerceApiProviderProps): ReactElement => {
locale,
currency,
fetchedToken,
envNamespace,
OCAPISessionsURL,
enablePWAKitPrivateClient,
clientSecret,
Expand Down Expand Up @@ -162,6 +164,7 @@ const CommerceApiProvider = (props: CommerceApiProviderProps): ReactElement => {
redirectURI,
fetchOptions,
fetchedToken,
envNamespace,
OCAPISessionsURL,
enablePWAKitPrivateClient,
clientSecret,
Expand All @@ -176,6 +179,7 @@ const CommerceApiProvider = (props: CommerceApiProviderProps): ReactElement => {
redirectURI,
fetchOptions,
fetchedToken,
envNamespace,
OCAPISessionsURL,
enablePWAKitPrivateClient,
clientSecret,
Expand All @@ -194,6 +198,7 @@ const CommerceApiProvider = (props: CommerceApiProviderProps): ReactElement => {
proxy,
redirectURI,
fetchOptions,
envNamespace,
siteId,
shortCode,
locale,
Expand Down
27 changes: 27 additions & 0 deletions packages/commerce-sdk-react/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@
import Cookies, {CookieAttributes} from 'js-cookie'
import {IFRAME_HOST_ALLOW_LIST} from './constant'

declare global {
interface Window {
__CONFIG__: any;
}
}


/** Utility to determine if you are on the browser (client) or not. */
export const onClient = (): boolean => typeof window !== 'undefined'

Expand All @@ -34,6 +41,26 @@ export const getParentOrigin = () => {
}
}

export const getNamespace = () => {
/* tslint:disable-next-line */

if (!onClient()) {
return ''
}
const config = window.__CONFIG__
const isSSRNamespace = config.enableSSRNamespace

if (!isSSRNamespace) {
return ''
}

const defaultSiteId = config.app.defaultSite
const siteAliases = config.app.siteAliases
const alias = siteAliases[defaultSiteId]

return alias ? `/${alias}` : `/${defaultSiteId}`
}

/**
* Determines whether the given origin is trusted to host the storefront in an iframe.
* @private
Expand Down
4 changes: 3 additions & 1 deletion packages/pwa-kit-dev/src/configs/jest/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
*/
import path from 'path'

const LOCAL_ENV_NAMESPACE = process.env.LOCAL_ENV_NAMESPACE ? `/${process.env.LOCAL_ENV_NAMESPACE}` : ''

module.exports = {
testURL: 'http://localhost/',
verbose: true,
Expand All @@ -26,7 +28,7 @@ module.exports = {
DEBUG: true,
NODE_ENV: 'test',
Progressive: {
buildOrigin: '/mobify/bundle/development/'
buildOrigin: `${LOCAL_ENV_NAMESPACE}/mobify/bundle/development/`
}
},
transform: {
Expand Down
4 changes: 3 additions & 1 deletion packages/pwa-kit-dev/src/configs/webpack/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ const DEBUG = mode !== production && process.env.DEBUG === 'true'
const CI = process.env.CI
const disableHMR = process.env.HMR === 'false'

const LOCAL_ENV_NAMESPACE = process.env.LOCAL_ENV_NAMESPACE ? `/${process.env.LOCAL_ENV_NAMESPACE}` : ''

if ([production, development].indexOf(mode) < 0) {
throw new Error(`Invalid mode "${mode}"`)
}
Expand Down Expand Up @@ -407,7 +409,7 @@ const enableReactRefresh = (config) => {
output: {
...config.output,
// Setting this so that *.hot-update.json requests are resolving
publicPath: '/mobify/bundle/development/'
publicPath: `${LOCAL_ENV_NAMESPACE}/mobify/bundle/development/`
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions packages/pwa-kit-dev/src/ssr/server/build-dev-server.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import webpackHotMiddleware from 'webpack-hot-middleware'
import open from 'open'
import requireFromString from 'require-from-string'
import {RemoteServerFactory} from '@salesforce/pwa-kit-runtime/ssr/server/build-remote-server'
import {proxyConfigs} from '@salesforce/pwa-kit-runtime/utils/ssr-shared'
import {proxyConfigs, getBundlePathBase} from '@salesforce/pwa-kit-runtime/utils/ssr-shared'
import {
SERVER,
CLIENT,
Expand Down Expand Up @@ -166,7 +166,7 @@ export const DevServerMixin = {
app.__hotServerMiddleware = webpackHotServerMiddleware(app.__compiler)
}

app.use('/mobify/bundle/development', app.__devMiddleware)
app.use(`${getBundlePathBase()}/development`, app.__devMiddleware)

app.__hmrMiddleware = (_, res) => res.status(501).send('Hot Module Reloading is disabled.')
const clientCompiler = app.__compiler.compilers.find((compiler) => compiler.name === CLIENT)
Expand Down Expand Up @@ -209,7 +209,7 @@ export const DevServerMixin = {
// Proxy bundle asset requests to the local
// build directory.
app.use(
'/mobify/bundle/development',
`${getBundlePathBase}/development`,
express.static(path.resolve(process.cwd(), 'src'), {
dotFiles: 'deny',
setHeaders: setLocalAssetHeaders,
Expand Down
4 changes: 2 additions & 2 deletions packages/pwa-kit-react-sdk/src/ssr/universal/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
/**
* @module progressive-web-sdk/ssr/universal/utils
*/
import {proxyConfigs} from '@salesforce/pwa-kit-runtime/utils/ssr-shared'
import {proxyConfigs, getBundlePathBase} from '@salesforce/pwa-kit-runtime/utils/ssr-shared'

const onClient = typeof window !== 'undefined'

Expand All @@ -22,7 +22,7 @@ export const getAssetUrl = (path) => {
/* istanbul ignore next */
const publicPath = onClient
? `${window.Progressive.buildOrigin}`
: `/mobify/bundle/${process.env.BUNDLE_ID || 'development'}/`
: `${getBundlePathBase()}/${process.env.BUNDLE_ID || 'development'}/`
return path ? `${publicPath}${path}` : publicPath
}

Expand Down
23 changes: 11 additions & 12 deletions packages/pwa-kit-runtime/src/ssr/server/build-remote-server.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ import {
X_MOBIFY_QUERYSTRING,
SET_COOKIE,
CACHE_CONTROL,
NO_CACHE,
SLAS_CUSTOM_PROXY_PATH
NO_CACHE
} from './constants'
import {
catchAndLog,
Expand All @@ -39,7 +38,7 @@ import fs from 'fs'
import {RESOLVED_PROMISE} from './express'
import http from 'http'
import https from 'https'
import {proxyConfigs, updatePackageMobify} from '../../utils/ssr-shared'
import {proxyConfigs, updatePackageMobify, startsWithMobify, getProxyPathBase, getHealtCheckPathBase, getSLASPrivateProxyPath} from '../../utils/ssr-shared'
import {applyProxyRequestHeaders} from '../../utils/ssr-server/configure-proxy'
import awsServerlessExpress from 'aws-serverless-express'
import expressLogging from 'morgan'
Expand Down Expand Up @@ -432,7 +431,7 @@ export const RemoteServerFactory = {
const processIncomingRequest = (req, res) => {
const options = req.app.options
// If the request is for a proxy or bundle path, do nothing
if (req.originalUrl.startsWith('/mobify/')) {
if (startsWithMobify(req.originalUrl)) {
return
}

Expand Down Expand Up @@ -569,7 +568,7 @@ export const RemoteServerFactory = {
// different types of the 'req' object, and will
// always contain the original full path.
/* istanbul ignore else */
if (!req.originalUrl.startsWith('/mobify/')) {
if (!startsWithMobify(req.originalUrl)) {
req.app.sendMetric(
'RequestTime',
Date.now() - locals.requestStart,
Expand Down Expand Up @@ -615,7 +614,7 @@ export const RemoteServerFactory = {
*/
// eslint-disable-next-line @typescript-eslint/no-unused-vars
_setupProxying(app, options) {
app.all('/mobify/proxy/*', (_, res) => {
app.all(`${getProxyPathBase()}/*`, (_, res) => {
return res.status(501).json({
message:
'Environment proxies are not set: https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/proxying-requests.html'
Expand All @@ -627,7 +626,7 @@ export const RemoteServerFactory = {
* @private
*/
_handleMissingSlasPrivateEnvVar(app) {
app.use(SLAS_CUSTOM_PROXY_PATH, (_, res) => {
app.use(getSLASPrivateProxyPath(), (_, res) => {
return res.status(501).json({
message:
'Environment variable PWA_KIT_SLAS_CLIENT_SECRET not set: Please set this environment variable to proceed.'
Expand All @@ -642,7 +641,7 @@ export const RemoteServerFactory = {
if (!options.useSLASPrivateClient) {
return
}
localDevLog(`Proxying ${SLAS_CUSTOM_PROXY_PATH} to ${options.slasTarget}`)
localDevLog(`Proxying ${getSLASPrivateProxyPath()} to ${options.slasTarget}`)

const clientId = options.mobify?.app?.commerceAPI?.parameters?.clientId
const clientSecret = process.env.PWA_KIT_SLAS_CLIENT_SECRET
Expand All @@ -654,16 +653,16 @@ export const RemoteServerFactory = {
const encodedSlasCredentials = Buffer.from(`${clientId}:${clientSecret}`).toString('base64')

app.use(
SLAS_CUSTOM_PROXY_PATH,
getSLASPrivateProxyPath(),
createProxyMiddleware({
target: options.slasTarget,
changeOrigin: true,
pathRewrite: {[SLAS_CUSTOM_PROXY_PATH]: ''},
pathRewrite: {[getSLASPrivateProxyPath()]: ''},
onProxyReq: (proxyRequest, incomingRequest) => {
applyProxyRequestHeaders({
proxyRequest,
incomingRequest,
proxyPath: SLAS_CUSTOM_PROXY_PATH,
proxyPath: getSLASPrivateProxyPath(),
targetHost: options.slasHostName,
targetProtocol: 'https'
})
Expand Down Expand Up @@ -702,7 +701,7 @@ export const RemoteServerFactory = {
* @private
*/
_setupHealthcheck(app) {
app.get('/mobify/ping', (_, res) =>
app.get(`${getHealtCheckPathBase()}`, (_, res) =>
res.set('cache-control', NO_CACHE).sendStatus(200).end()
)
},
Expand Down
8 changes: 4 additions & 4 deletions packages/pwa-kit-runtime/src/utils/ssr-server.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import {
} from './ssr-server'

import {
getProxyPathBase,
getPackageMobify,
getSSRParameters,
proxyConfigs,
Expand All @@ -43,8 +44,7 @@ import {
CONTENT_ENCODING,
CONTENT_TYPE,
X_ORIGINAL_CONTENT_TYPE,
APPLICATION_OCTET_STREAM,
PROXY_PATH_PREFIX
APPLICATION_OCTET_STREAM
} from '../ssr/server/constants'

const baseMobify = {
Expand Down Expand Up @@ -117,11 +117,11 @@ describe('utils/ssr-server tests', () => {

updatePackageMobify(baseMobify)

expect(getFullRequestURL(`${PROXY_PATH_PREFIX}/base/somepath`)).toBe(
expect(getFullRequestURL(`${getProxyPathBase()}/base/somepath`)).toBe(
'https://www.merlinspotions.com/somepath'
)

expect(getFullRequestURL(`${PROXY_PATH_PREFIX}/base2/somepath`)).toBe(
expect(getFullRequestURL(`${getProxyPathBase()}/base2/somepath`)).toBe(
'https://api.merlinspotions.com/somepath'
)
})
Expand Down
11 changes: 5 additions & 6 deletions packages/pwa-kit-runtime/src/utils/ssr-server/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@
// ../ssr-server.js because it would create circular dependencies.

import crypto from 'crypto'
import {PROXY_PATH_PREFIX} from '../../ssr/server/constants'
import {proxyConfigs} from '../ssr-shared'
import {getProxyPathBase, getBundlePathBase, proxyConfigs} from '../ssr-shared'

// TODO: Clean this up or provide a way to toggle
export const verboseProxyLogging = false
Expand All @@ -21,7 +20,7 @@ export const isRemote = () =>
Object.prototype.hasOwnProperty.call(process.env, 'AWS_LAMBDA_FUNCTION_NAME')

export const getBundleBaseUrl = () => {
return `/mobify/bundle/${isRemote() ? process.env.BUNDLE_ID : 'development'}/`
return `${getBundlePathBase()}/${isRemote() ? process.env.BUNDLE_ID : 'development'}/`
}

let QUIET = false
Expand Down Expand Up @@ -82,16 +81,16 @@ export const getHashForString = (text) => {
export const getFullRequestURL = (url) => {
// If it starts with a protocol (e.g. http(s)://, file://), then it's already a full URL
if (/^[a-zA-Z]+:\/\//.test(url)) return url
const proxy = proxyConfigs.find(({path}) => url.startsWith(`${PROXY_PATH_PREFIX}/${path}/`))
const proxy = proxyConfigs.find(({path}) => url.startsWith(`${getProxyPathBase()}/${path}/`))
if (proxy) {
return url.replace(
`${PROXY_PATH_PREFIX}/${proxy.path}`,
`${getProxyPathBase()}/${proxy.path}`,
`${proxy.protocol}://${proxy.host}`
)
}

throw new Error(
`Unable to fetch ${url}, relative paths must begin with ${PROXY_PATH_PREFIX} followed by a configured proxy path.`
`Unable to fetch ${url}, relative paths must begin with ${getProxyPathBase()} followed by a configured proxy path.`
)
}

Expand Down
Loading
Loading