@@ -156,3 +156,190 @@ describe('isBinary function', () => {
156156 expect ( isBinary ( headers ) ) . toBe ( false )
157157 } )
158158} )
159+
160+ describe ( 'SLAS private proxy' , ( ) => {
161+ let request
162+ let mockExpress
163+
164+ beforeEach ( ( ) => {
165+ // Mock express application
166+ mockExpress = require ( 'express' )
167+ request = require ( 'supertest' )
168+ } )
169+
170+ afterEach ( ( ) => {
171+ // Clean up environment variables
172+ delete process . env . PWA_KIT_SLAS_CLIENT_SECRET
173+ } )
174+
175+ test ( 'returns 404 when useSLASPrivateClient is false' , async ( ) => {
176+ const app = mockExpress ( )
177+ const options = {
178+ useSLASPrivateClient : false ,
179+ mobify : {
180+ app : {
181+ commerceAPI : {
182+ parameters : {
183+ shortCode : 'test' ,
184+ clientId : 'test-client-id'
185+ }
186+ }
187+ }
188+ }
189+ }
190+
191+ RemoteServerFactory . _setupSlasPrivateClientProxy ( app , options )
192+
193+ // Attempt to access the SLAS private proxy path
194+ const response = await request ( app ) . get ( '/mobify/slas/private/shopper/auth/v1/oauth2/token' )
195+
196+ expect ( response . status ) . toBe ( 404 )
197+ } )
198+
199+ test ( 'returns 501 when useSLASPrivateClient is true but no secret is set' , async ( ) => {
200+ const app = mockExpress ( )
201+ const options = RemoteServerFactory . _configure ( {
202+ useSLASPrivateClient : true ,
203+ mobify : {
204+ app : {
205+ commerceAPI : {
206+ parameters : {
207+ shortCode : 'test' ,
208+ organizationId : 'f_ecom_test' ,
209+ clientId : 'test-client-id'
210+ }
211+ }
212+ }
213+ }
214+ } )
215+
216+ RemoteServerFactory . _setupSlasPrivateClientProxy ( app , options )
217+
218+ const response = await request ( app ) . get ( '/mobify/slas/private/shopper/auth/v1/oauth2/token' )
219+
220+ expect ( response . status ) . toBe ( 501 )
221+ } )
222+
223+ test ( 'returns 403 for non-SLAS auth paths' , async ( ) => {
224+ const app = mockExpress ( )
225+ const options = RemoteServerFactory . _configure ( {
226+ useSLASPrivateClient : true ,
227+ mobify : {
228+ app : {
229+ commerceAPI : {
230+ parameters : {
231+ shortCode : 'test' ,
232+ organizationId : 'f_ecom_test' ,
233+ clientId : 'test-client-id'
234+ }
235+ }
236+ }
237+ }
238+ } )
239+
240+ process . env . PWA_KIT_SLAS_CLIENT_SECRET = 'test-secret'
241+
242+ RemoteServerFactory . _setupSlasPrivateClientProxy ( app , options )
243+
244+ const response = await request ( app ) . get ( '/mobify/slas/private/shopper/products/v1' )
245+
246+ expect ( response . status ) . toBe ( 403 )
247+ } )
248+
249+ test ( 'returns 403 for trusted-system paths' , async ( ) => {
250+ const app = mockExpress ( )
251+ const options = RemoteServerFactory . _configure ( {
252+ useSLASPrivateClient : true ,
253+ mobify : {
254+ app : {
255+ commerceAPI : {
256+ parameters : {
257+ shortCode : 'test' ,
258+ organizationId : 'f_ecom_test' ,
259+ clientId : 'test-client-id'
260+ }
261+ }
262+ }
263+ }
264+ } )
265+
266+ process . env . PWA_KIT_SLAS_CLIENT_SECRET = 'test-secret'
267+
268+ RemoteServerFactory . _setupSlasPrivateClientProxy ( app , options )
269+
270+ const response = await request ( app ) . post (
271+ '/mobify/slas/private/shopper/auth/v1/oauth2/trusted-system/token'
272+ )
273+
274+ expect ( response . status ) . toBe ( 403 )
275+ } )
276+
277+ test ( 'invokes onSLASPrivateProxyReq callback and onSLASPrivateProxyRes callback' , async ( ) => {
278+ // Create a mock SLAS endpoint for the http-proxy to consume
279+ const mockSlasServer = mockExpress ( )
280+ mockSlasServer . post ( '/shopper/auth/v1/oauth2/token' , ( req , res ) => {
281+ // Reflect the custom header back in the response to verify it was set
282+ res . status ( 200 ) . json ( {
283+ access_token : 'mock-token' ,
284+ reflected_header : req . headers [ 'x-custom-request-header' ]
285+ } )
286+ } )
287+
288+ const mockSlasServerInstance = mockSlasServer . listen ( 0 )
289+ const mockSlasPort = mockSlasServerInstance . address ( ) . port
290+
291+ try {
292+ const onSLASPrivateProxyReqMock = jest . fn ( ( proxyRequest ) => {
293+ proxyRequest . setHeader ( 'X-Custom-Request-Header' , 'CustomRequestValue' )
294+ } )
295+
296+ const onSLASPrivateProxyResMock = jest . fn ( ( responseBuffer , proxyRes , req , res ) => {
297+ // Add a custom response header
298+ res . setHeader ( 'X-Custom-Response-Header' , 'CustomResponseValue' )
299+ return responseBuffer
300+ } )
301+
302+ const app = mockExpress ( )
303+ const options = RemoteServerFactory . _configure ( {
304+ useSLASPrivateClient : true ,
305+ slasTarget : `http://localhost:${ mockSlasPort } ` ,
306+ onSLASPrivateProxyReq : onSLASPrivateProxyReqMock ,
307+ onSLASPrivateProxyRes : onSLASPrivateProxyResMock ,
308+ mobify : {
309+ app : {
310+ commerceAPI : {
311+ parameters : {
312+ shortCode : 'test' ,
313+ organizationId : 'f_ecom_test' ,
314+ clientId : 'test-client-id'
315+ }
316+ }
317+ }
318+ }
319+ } )
320+
321+ process . env . PWA_KIT_SLAS_CLIENT_SECRET = 'test-secret'
322+
323+ RemoteServerFactory . _setupSlasPrivateClientProxy ( app , options )
324+
325+ const response = await request ( app ) . post (
326+ '/mobify/slas/private/shopper/auth/v1/oauth2/token'
327+ )
328+
329+ // Verify the request was successful
330+ expect ( response . status ) . toBe ( 200 )
331+
332+ // Verify the callbacks were invoked
333+ expect ( onSLASPrivateProxyReqMock ) . toHaveBeenCalled ( )
334+ expect ( onSLASPrivateProxyResMock ) . toHaveBeenCalled ( )
335+
336+ // Verify the custom request header was added (reflected back in response)
337+ expect ( response . body . reflected_header ) . toBe ( 'CustomRequestValue' )
338+
339+ // Verify the custom response header was added
340+ expect ( response . headers [ 'x-custom-response-header' ] ) . toBe ( 'CustomResponseValue' )
341+ } finally {
342+ mockSlasServerInstance . close ( )
343+ }
344+ } )
345+ } )
0 commit comments