Explorar el Código

fix(core): Prevent use of unrecognized currency codes in RequestContext

Relates to #GHSA-wm63-7627-ch33
Michael Bromley hace 2 años
padre
commit
fee503ff6f

+ 16 - 0
packages/core/e2e/channel.e2e-spec.ts

@@ -28,6 +28,7 @@ import {
     CREATE_ROLE,
     GET_CHANNELS,
     GET_CUSTOMER_LIST,
+    GET_PRODUCT_LIST,
     GET_PRODUCT_WITH_VARIANTS,
     ME,
     UPDATE_CHANNEL,
@@ -436,6 +437,21 @@ describe('Channels', () => {
                 });
             }, 'availableCurrencyCodes must include the defaultCurrencyCode (AUD)'),
         );
+
+        it(
+            'specifying an unsupported currencyCode throws',
+            assertThrowsWithMessage(async () => {
+                await adminClient.query<Codegen.GetProductListQuery, Codegen.GetProductListQueryVariables>(
+                    GET_PRODUCT_LIST,
+                    {
+                        options: {
+                            take: 1,
+                        },
+                    },
+                    { currencyCode: 'JPY' },
+                );
+            }, 'The currency "JPY" is not available in the current Channel'),
+        );
     });
 });
 

+ 12 - 12
packages/core/e2e/product-prices.e2e-spec.ts

@@ -164,17 +164,17 @@ describe('Product prices', () => {
             expect(product?.variants[0]?.currencyCode).toEqual(CurrencyCode.GBP);
         });
 
-        it('uses default if unrecognised currency code passed in query string', async () => {
-            const { product } = await adminClient.query(
-                GetProductWithVariantsDocument,
-                {
-                    id: multiPriceProduct.id,
-                },
-                { currencyCode: 'JPY' },
-            );
-
-            expect(product?.variants[0]?.price).toEqual(1200);
-            expect(product?.variants[0]?.currencyCode).toEqual(CurrencyCode.USD);
-        });
+        it(
+            'throws if unrecognised currency code passed in query string',
+            assertThrowsWithMessage(async () => {
+                await adminClient.query(
+                    GetProductWithVariantsDocument,
+                    {
+                        id: multiPriceProduct.id,
+                    },
+                    { currencyCode: 'JPY' },
+                );
+            }, 'The currency "JPY" is not available in the current Channel'),
+        );
     });
 });

+ 8 - 1
packages/core/src/service/helpers/request-context/request-context.service.ts

@@ -7,6 +7,7 @@ import ms from 'ms';
 
 import { ApiType, getApiType } from '../../../api/common/get-api-type';
 import { RequestContext } from '../../../api/common/request-context';
+import { UserInputError } from '../../../common/index';
 import { idsAreEqual } from '../../../common/utils';
 import { ConfigService } from '../../../config/config.service';
 import { CachedSession, CachedSessionUser } from '../../../config/session-cache/session-cache-strategy';
@@ -138,7 +139,13 @@ export class RequestContextService {
     }
 
     private getCurrencyCode(req: Request, channel: Channel): CurrencyCode | undefined {
-        return (req.query && (req.query.currencyCode as CurrencyCode)) ?? channel.defaultCurrencyCode;
+        const queryCurrencyCode = req.query && (req.query.currencyCode as CurrencyCode);
+        if (queryCurrencyCode && !channel.availableCurrencyCodes.includes(queryCurrencyCode)) {
+            throw new UserInputError('error.currency-not-available-in-channel', {
+                currencyCode: queryCurrencyCode,
+            });
+        }
+        return queryCurrencyCode ?? channel.defaultCurrencyCode;
     }
 
     /**