From 0b6282632b2043b5654787fff325997e44e9bcff Mon Sep 17 00:00:00 2001 From: James Estevez Date: Tue, 17 Oct 2023 12:14:19 -0700 Subject: [PATCH 1/7] Make Omnistudio local compiler optional External users may not have access to the Vlocity private NPM repository, blocking them from installing front end dependencies. This change allows yarn install to complete successfully. --- package.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 4b372052c..acf432466 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,6 @@ "heroku-postbuild": "yarn prod" }, "dependencies": { - "@omnistudio/omniscript-lwc-compiler": "^244.4.0", "@react-hook/window-scroll": "^1.3.0", "@salesforce-ux/design-system": "^2.18.1", "@salesforce/design-system-react": "^0.10.48", @@ -154,6 +153,9 @@ "webpack-dev-server": "^4.9.3", "webpack-merge": "^5.8.0" }, + "optionalDependencies": { + "@omnistudio/omniscript-lwc-compiler": "^244.4.0" + }, "resolutions": { "@storybook/**/ansi-regex": "^5.0.1", "@storybook/**/glob-parent": "^5.1.2", From 3347a2ab3ac596f73c3e4f12957a4712aee264ad Mon Sep 17 00:00:00 2001 From: Naman Jain Date: Fri, 3 Nov 2023 11:56:47 +0530 Subject: [PATCH 2/7] Fixes Bad reporting 500 Status Code (#3541) * Fixed 500 error reporting * Fixed 500 error reporting and added tests * Lint Test Fix * Test Fixes --- locales_dev/en/translation.json | 1 + src/js/components/apiErrors.tsx | 9 +++++++++ src/js/utils/api.ts | 3 +++ test/js/components/apiErrors.test.js | 17 +++++++++++++++++ test/js/utils/api.test.js | 8 ++++++++ 5 files changed, 38 insertions(+) diff --git a/locales_dev/en/translation.json b/locales_dev/en/translation.json index 99a876efe..b6542aa5c 100644 --- a/locales_dev/en/translation.json +++ b/locales_dev/en/translation.json @@ -99,6 +99,7 @@ "Share Link to Installation Job": "Share Link to Installation Job", "Show Logs": "Show Logs", "Skipped": "Skipped", + "Something went wrong. Please try again later.": "Something went wrong. Please try again later.", "Start Pre-Install Validation": "Start Pre-Install Validation", "Start Pre-Install Validation on Scratch Org": "Start Pre-Install Validation on Scratch Org", "Steps": "Steps", diff --git a/src/js/components/apiErrors.tsx b/src/js/components/apiErrors.tsx index 9b18c8585..f17d05a27 100644 --- a/src/js/components/apiErrors.tsx +++ b/src/js/components/apiErrors.tsx @@ -18,6 +18,15 @@ const ErrorToast = ({ doRemoveError: typeof removeError; }) => { const { t } = useTranslation(); + + if ( + error.message && + typeof error.message === 'string' && + /<[a-z][\s\S]*>/i.test(error.message) + ) { + error.message = t('Something went wrong. Please try again later.'); + } + return ( 500 && response.status <= 600) { + msg = 'Something went wrong. Please try again later.'; + } dispatch(addError(msg)); const error: ApiError = new Error(msg); error.response = response; diff --git a/test/js/components/apiErrors.test.js b/test/js/components/apiErrors.test.js index 9ddd68085..8907ede4d 100644 --- a/test/js/components/apiErrors.test.js +++ b/test/js/components/apiErrors.test.js @@ -16,6 +16,16 @@ describe('', () => { return { getByText }; }; + const setupforRawHTML = () => { + const errors = [ + { id: 'err1', message: '
This is Error
' }, + ]; + const { getByText } = render( + , + ); + return { getByText }; + }; + test('calls window.location.reload on link click', () => { const { getByText } = setup(); @@ -24,6 +34,13 @@ describe('', () => { expect(window.location.reload).toHaveBeenCalledTimes(1); }); + test('for raw html error', () => { + const { getByText } = setupforRawHTML(); + + expect( + getByText('Something went wrong. Please try again later.'), + ).toBeVisible(); + }); test('calls doRemoveError on close click', () => { const { getByText } = setup(); diff --git a/test/js/utils/api.test.js b/test/js/utils/api.test.js index 0d7235f34..4a4b7a8a1 100644 --- a/test/js/utils/api.test.js +++ b/test/js/utils/api.test.js @@ -35,6 +35,14 @@ describe('apiFetch', () => { }); describe('error', () => { + test('throws Error for status code greater than 500', () => { + fetchMock.getOnce('/test/url/', { status: 503, body: {} }); + + expect.assertions(1); + return expect(apiFetch('/test/url/', dispatch)).rejects.toThrow( + 'Something went wrong. Please try again later.', + ); + }); test('throws Error without response', () => { fetchMock.getOnce('/test/url/', { status: 500, body: {} }); From 4e2439260f877ef2e7344ed49af980d9a7391da8 Mon Sep 17 00:00:00 2001 From: jain-naman-sf Date: Mon, 20 Nov 2023 15:34:39 +0530 Subject: [PATCH 3/7] Added Rate Limiting for One Admin API VIew --- config/settings/base.py | 3 ++- metadeploy/adminapi/api.py | 7 +++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/config/settings/base.py b/config/settings/base.py index bd31cfe98..0f9272c84 100644 --- a/config/settings/base.py +++ b/config/settings/base.py @@ -460,7 +460,8 @@ def safe_key() -> str: ], 'DEFAULT_THROTTLE_RATES': { 'anon': '4/second', - 'user': '4/second' + 'user': '4/second', + 'admin':'100/minute' } } diff --git a/metadeploy/adminapi/api.py b/metadeploy/adminapi/api.py index 35981319c..3f1a631ba 100644 --- a/metadeploy/adminapi/api.py +++ b/metadeploy/adminapi/api.py @@ -3,6 +3,7 @@ from django_filters import rest_framework as filters from rest_framework import serializers, status, viewsets from rest_framework.response import Response +from rest_framework.throttling import UserRateThrottle from sfdo_template_helpers.admin.permissions import IsAPIUser from sfdo_template_helpers.admin.serializers import AdminAPISerializer from sfdo_template_helpers.admin.views import AdminAPIViewSet @@ -12,6 +13,10 @@ from metadeploy.api.models import SUPPORTED_ORG_TYPES, Plan from metadeploy.api.serializers import get_from_data_or_instance +class AdminThrottle(UserRateThrottle): + scope = 'admin' + + class ProductSerializer(AdminAPISerializer): title = serializers.CharField() @@ -138,6 +143,7 @@ class Meta: class PlanTemplateViewSet(AdminAPIViewSet): model_name = "PlanTemplate" serializer_base = PlanTemplateSerializer + throttle_classes = [AdminThrottle] class PlanFilter(filters.FilterSet): @@ -152,6 +158,7 @@ class PlanViewSet(AdminAPIViewSet): filterset_class = PlanFilter + class PlanSlugViewSet(AdminAPIViewSet): model_name = "PlanSlug" From 6ffeb8ad89655d01aee4a407bc62bb9c471061e3 Mon Sep 17 00:00:00 2001 From: jain-naman-sf Date: Tue, 21 Nov 2023 14:37:43 +0530 Subject: [PATCH 4/7] Disabled Rate Limiting on PlanTemplate/v --- metadeploy/adminapi/api.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/metadeploy/adminapi/api.py b/metadeploy/adminapi/api.py index 3f1a631ba..a2f87023f 100644 --- a/metadeploy/adminapi/api.py +++ b/metadeploy/adminapi/api.py @@ -3,7 +3,6 @@ from django_filters import rest_framework as filters from rest_framework import serializers, status, viewsets from rest_framework.response import Response -from rest_framework.throttling import UserRateThrottle from sfdo_template_helpers.admin.permissions import IsAPIUser from sfdo_template_helpers.admin.serializers import AdminAPISerializer from sfdo_template_helpers.admin.views import AdminAPIViewSet @@ -13,10 +12,6 @@ from metadeploy.api.models import SUPPORTED_ORG_TYPES, Plan from metadeploy.api.serializers import get_from_data_or_instance -class AdminThrottle(UserRateThrottle): - scope = 'admin' - - class ProductSerializer(AdminAPISerializer): title = serializers.CharField() @@ -143,7 +138,7 @@ class Meta: class PlanTemplateViewSet(AdminAPIViewSet): model_name = "PlanTemplate" serializer_base = PlanTemplateSerializer - throttle_classes = [AdminThrottle] + throttle_classes = [] class PlanFilter(filters.FilterSet): @@ -158,7 +153,6 @@ class PlanViewSet(AdminAPIViewSet): filterset_class = PlanFilter - class PlanSlugViewSet(AdminAPIViewSet): model_name = "PlanSlug" From 5ffde3a0a1fcb9ed88e6a07646cdfb616b7168a7 Mon Sep 17 00:00:00 2001 From: jain-naman-sf Date: Tue, 21 Nov 2023 14:43:18 +0530 Subject: [PATCH 5/7] Disabled Rate Limiting for Admin Apis --- metadeploy/adminapi/api.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/metadeploy/adminapi/api.py b/metadeploy/adminapi/api.py index a2f87023f..2e42eadaf 100644 --- a/metadeploy/adminapi/api.py +++ b/metadeploy/adminapi/api.py @@ -151,22 +151,27 @@ class PlanViewSet(AdminAPIViewSet): model_name = "Plan" serializer_base = PlanSerializer filterset_class = PlanFilter + throttle_classes = [] class PlanSlugViewSet(AdminAPIViewSet): model_name = "PlanSlug" + throttle_classes = [] class VersionViewSet(AdminAPIViewSet): model_name = "Version" + throttle_classes = [] class ProductCategoryViewSet(AdminAPIViewSet): model_name = "ProductCategory" + throttle_classes = [] class AllowedListViewSet(AdminAPIViewSet): model_name = "AllowedList" + throttle_classes = [] class AllowedListOrgSerializer(AdminAPISerializer): @@ -176,6 +181,7 @@ class AllowedListOrgSerializer(AdminAPISerializer): class AllowedListOrgViewSet(AdminAPIViewSet): model_name = "AllowedListOrg" serializer_base = AllowedListOrgSerializer + throttle_classes = [] class TranslationViewSet(viewsets.ViewSet): @@ -195,6 +201,7 @@ class TranslationViewSet(viewsets.ViewSet): permission_classes = [IsAPIUser] model_name = "Translation" + throttle_classes = [] def partial_update(self, request, pk=None): # Add or update a Translation record for each message From 2fbeaffab1d9ae15b63e2b0699fabb4e7c380c40 Mon Sep 17 00:00:00 2001 From: jain-naman-sf Date: Tue, 21 Nov 2023 14:50:28 +0530 Subject: [PATCH 6/7] Reverted base.py --- config/settings/base.py | 1 - 1 file changed, 1 deletion(-) diff --git a/config/settings/base.py b/config/settings/base.py index 0f9272c84..9755ac871 100644 --- a/config/settings/base.py +++ b/config/settings/base.py @@ -461,7 +461,6 @@ def safe_key() -> str: 'DEFAULT_THROTTLE_RATES': { 'anon': '4/second', 'user': '4/second', - 'admin':'100/minute' } } From 832c1d695c07da4bad1b3bfd21929690485360e1 Mon Sep 17 00:00:00 2001 From: jain-naman-sf Date: Thu, 23 Nov 2023 14:51:17 +0530 Subject: [PATCH 7/7] Added Tests for Rate Limiting --- metadeploy/adminapi/tests/test_api.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/metadeploy/adminapi/tests/test_api.py b/metadeploy/adminapi/tests/test_api.py index 6244fa023..bc28d1f7d 100644 --- a/metadeploy/adminapi/tests/test_api.py +++ b/metadeploy/adminapi/tests/test_api.py @@ -86,6 +86,14 @@ def test_list(self, admin_api_client, plan_factory): "meta": {"page": {"total": 1}}, } + def test_throttle(self, admin_api_client): + url = "http://testserver/admin/rest/allowedlistorgs" + for i in range(0, 4): + response = admin_api_client.get(url) + + response = admin_api_client.get(url) + assert response.status_code == 200 + def test_retrieve(self, admin_api_client, step_factory): step = step_factory() plan = step.plan