diff --git a/config/settings/base.py b/config/settings/base.py index bd31cfe98b..55058d921d 100644 --- a/config/settings/base.py +++ b/config/settings/base.py @@ -97,6 +97,7 @@ def safe_key() -> str: MIDDLEWARE = [ "metadeploy.logging_middleware.LoggingMiddleware", "sfdo_template_helpers.admin.middleware.AdminRestrictMiddleware", + "allauth.account.middleware.AccountMiddleware", "django.middleware.security.SecurityMiddleware", "whitenoise.middleware.WhiteNoiseMiddleware", "django.contrib.sessions.middleware.SessionMiddleware", @@ -460,7 +461,7 @@ def safe_key() -> str: ], 'DEFAULT_THROTTLE_RATES': { 'anon': '4/second', - 'user': '4/second' + 'user': '4/second', } } diff --git a/locales/en-gb/translation.json b/locales/en-gb/translation.json index 52fd403f36..37bd69efe5 100644 --- a/locales/en-gb/translation.json +++ b/locales/en-gb/translation.json @@ -136,14 +136,14 @@ "a_or_b": "<0> or <2>", "anErrorOccurred": "An error occurred. Try the <1>home page?", "completed": "Completed", - "credentialsHoldTime": "The credentials to your Salesforce org will only be held for <2>{{token_minutes}} minute or until your requested installation is complete.", - "credentialsHoldTime_plural": "The credentials to your Salesforce org will only be held for <2>{{token_minutes}} minutes or until your requested installation is complete.", - "credentialsHoldTime_0": "The credentials to your Salesforce org will only be held for <2>{{token_minutes}} minutes or until your requested installation is complete.", - "credentialsHoldTime_1": "The credentials to your Salesforce org will only be held for <2>{{token_minutes}} minute or until your requested installation is complete.", - "credentialsHoldTime_2": "The credentials to your Salesforce org will only be held for <2>{{token_minutes}} minutes or until your requested installation is complete.", - "credentialsHoldTime_3": "The credentials to your Salesforce org will only be held for <2>{{token_minutes}} minutes or until your requested installation is complete.", - "credentialsHoldTime_4": "The credentials to your Salesforce org will only be held for <2>{{token_minutes}} minutes or until your requested installation is complete.", - "credentialsHoldTime_5": "The credentials to your Salesforce org will only be held for <2>{{token_minutes}} minutes or until your requested installation is complete.", + "credentialsHoldTime": "If no action is performed for <2>{{token_minutes}} minute, you will be automatically logged out and will need to log in again.", + "credentialsHoldTime_plural": "If no action is performed for <2>{{token_minutes}} minutes, you will be automatically logged out and will need to log in again.", + "credentialsHoldTime_0": "If no action is performed for <2>{{token_minutes}} minutes, you will be automatically logged out and will need to log in again.", + "credentialsHoldTime_1": "If no action is performed for <2>{{token_minutes}} minute, you will be automatically logged out and will need to log in again.", + "credentialsHoldTime_2": "If no action is performed for <2>{{token_minutes}} minutes, you will be automatically logged out and will need to log in again.", + "credentialsHoldTime_3": "If no action is performed for <2>{{token_minutes}} minutes, you will be automatically logged out and will need to log in again.", + "credentialsHoldTime_4": "If no action is performed for <2>{{token_minutes}} minutes, you will be automatically logged out and will need to log in again.", + "credentialsHoldTime_5": "If no action is performed for <2>{{token_minutes}} minutes, you will be automatically logged out and will need to log in again.", "durationDays": "{{count}} day", "durationDays_plural": "{{count}} days", "durationDays_0": "{{count}} days", diff --git a/locales/en/translation.json b/locales/en/translation.json index 3b8c99767f..833e7a1db8 100644 --- a/locales/en/translation.json +++ b/locales/en/translation.json @@ -73,12 +73,12 @@ "Oh no! This installation encountered an error.": "Oh no! This installation encountered an error.", "One Time Apex": "One Time Apex", "Only I and Salesforce staff can view this installation job.": "Only I and Salesforce staff can view this installation job.", - "Oops! It looks like you don’t have permissions to run an installation on this org.": "Oops! It looks like you don’t have permissions to run an installation on this org.", + "Oops! It looks like you have been logged out or don’t have permissions to run an installation on this org.": "Oops! It looks like you have been logged out or don’t have permissions to run an installation on this org.", "Optional": "Optional", "Org:": "Org:", "Other": "Other", "Package": "Package", - "Please contact an Admin within your org or use the button below to log in with a different org.": "Please contact an Admin within your org or use the button below to log in with a different org.", + "Please log back in, contact an Admin, or use the button below to log in with a different org.": "Please log back in, contact an Admin, or use the button below to log in with a different org.", "Potential Issues": "Potential Issues", "Pre-Install Validation In Progress…": "Pre-Install Validation In Progress…", "Pre-install validation completed successfully.": "Pre-install validation completed successfully.", @@ -140,14 +140,14 @@ "a_or_b": "<0> or <2>", "anErrorOccurred": "An error occurred. Try the <1>home page?", "completed": "Completed", - "credentialsHoldTime": "The credentials to your Salesforce org will only be held for <2>{{token_minutes}} minute or until your requested installation is complete.", - "credentialsHoldTime_plural": "The credentials to your Salesforce org will only be held for <2>{{token_minutes}} minutes or until your requested installation is complete.", - "credentialsHoldTime_0": "The credentials to your Salesforce org will only be held for <2>{{token_minutes}} minutes or until your requested installation is complete.", - "credentialsHoldTime_1": "The credentials to your Salesforce org will only be held for <2>{{token_minutes}} minute or until your requested installation is complete.", - "credentialsHoldTime_2": "The credentials to your Salesforce org will only be held for <2>{{token_minutes}} minutes or until your requested installation is complete.", - "credentialsHoldTime_3": "The credentials to your Salesforce org will only be held for <2>{{token_minutes}} minutes or until your requested installation is complete.", - "credentialsHoldTime_4": "The credentials to your Salesforce org will only be held for <2>{{token_minutes}} minutes or until your requested installation is complete.", - "credentialsHoldTime_5": "The credentials to your Salesforce org will only be held for <2>{{token_minutes}} minutes or until your requested installation is complete.", + "credentialsHoldTime": "If no action is performed for <2>{{token_minutes}} minute, you will be automatically logged out and will need to log in again.", + "credentialsHoldTime_plural": "If no action is performed for <2>{{token_minutes}} minutes, you will be automatically logged out and will need to log in again.", + "credentialsHoldTime_0": "If no action is performed for <2>{{token_minutes}} minutes, you will be automatically logged out and will need to log in again.", + "credentialsHoldTime_1": "If no action is performed for <2>{{token_minutes}} minute, you will be automatically logged out and will need to log in again.", + "credentialsHoldTime_2": "If no action is performed for <2>{{token_minutes}} minutes, you will be automatically logged out and will need to log in again.", + "credentialsHoldTime_3": "If no action is performed for <2>{{token_minutes}} minutes, you will be automatically logged out and will need to log in again.", + "credentialsHoldTime_4": "If no action is performed for <2>{{token_minutes}} minutes, you will be automatically logged out and will need to log in again.", + "credentialsHoldTime_5": "If no action is performed for <2>{{token_minutes}} minutes, you will be automatically logged out and will need to log in again.", "durationDays": "{{count}} day", "durationDays_plural": "{{count}} days", "durationDays_0": "{{count}} days", diff --git a/locales_dev/en/translation.json b/locales_dev/en/translation.json index 99a876efe1..3ab47976cc 100644 --- a/locales_dev/en/translation.json +++ b/locales_dev/en/translation.json @@ -67,10 +67,10 @@ "Not Connected to Salesforce": "Not Connected to Salesforce", "Oh no! This installation encountered an error.": "Oh no! This installation encountered an error.", "Only I and Salesforce staff can view this installation job.": "Only I and Salesforce staff can view this installation job.", - "Oops! It looks like you don’t have permissions to run an installation on this org.": "Oops! It looks like you don’t have permissions to run an installation on this org.", + "Oops! It looks like you have been logged out or don’t have permissions to run an installation on this org.": "Oops! It looks like you have been logged out or don’t have permissions to run an installation on this org.", "Optional": "Optional", "Org:": "Org:", - "Please contact an Admin within your org or use the button below to log in with a different org.": "Please contact an Admin within your org or use the button below to log in with a different org.", + "Please log back in, contact an Admin, or use the button below to log in with a different org.": "Please log back in, contact an Admin, or use the button below to log in with a different org.", "Potential Issues": "Potential Issues", "Pre-Install Validation In Progress…": "Pre-Install Validation In Progress…", "Pre-install validation completed successfully.": "Pre-install validation completed successfully.", @@ -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", @@ -128,8 +129,8 @@ "a_or_b": "<0> or <2>", "anErrorOccurred": "An error occurred. Try the <1>home page?", "completed": "Completed", - "credentialsHoldTime": "The credentials to your Salesforce org will only be held for <2>{{token_minutes}} minutes or until your requested installation is complete.", - "credentialsHoldTime_plural": "The credentials to your Salesforce org will only be held for <2>{{token_minutes}} minutes or until your requested installation is complete.", + "credentialsHoldTime": "If no action is performed for <2>{{token_minutes}} minutes, you will be automatically logged out and will need to log in again.", + "credentialsHoldTime_plural": "If no action is performed for <2>{{token_minutes}} minutes, you will be automatically logged out and will need to log in again.", "durationDays": "durationDays", "durationDays_plural": "durationDays", "durationHours": "durationHours", diff --git a/metadeploy/adminapi/api.py b/metadeploy/adminapi/api.py index 35981319ca..2e42eadaf4 100644 --- a/metadeploy/adminapi/api.py +++ b/metadeploy/adminapi/api.py @@ -138,6 +138,7 @@ class Meta: class PlanTemplateViewSet(AdminAPIViewSet): model_name = "PlanTemplate" serializer_base = PlanTemplateSerializer + throttle_classes = [] class PlanFilter(filters.FilterSet): @@ -150,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): @@ -175,6 +181,7 @@ class AllowedListOrgSerializer(AdminAPISerializer): class AllowedListOrgViewSet(AdminAPIViewSet): model_name = "AllowedListOrg" serializer_base = AllowedListOrgSerializer + throttle_classes = [] class TranslationViewSet(viewsets.ViewSet): @@ -194,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 diff --git a/metadeploy/adminapi/tests/test_api.py b/metadeploy/adminapi/tests/test_api.py index 6244fa023e..bc28d1f7d5 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 diff --git a/package.json b/package.json index 4b372052c3..acf432466c 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", diff --git a/requirements/dev.txt b/requirements/dev.txt index 0e552ca6a1..dd6e3af4c1 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -4,40 +4,34 @@ # # pip-compile --output-file=requirements/dev.txt requirements/dev.in # -alabaster==0.7.12 +alabaster==0.7.16 # via sphinx -asgiref==3.5.2 +asgiref==3.7.2 # via # -c requirements/prod.txt # django -asttokens==2.0.5 +asttokens==2.4.1 # via stack-data -attrs==21.4.0 - # via - # -c requirements/prod.txt - # pytest -babel==2.10.3 +babel==2.14.0 # via sphinx -backcall==0.2.0 - # via ipython -black==22.6.0 +black==23.12.1 # via -r requirements/dev.in -build==0.8.0 +build==1.0.3 # via pip-tools -certifi==2022.12.7 +certifi==2023.7.22 # via # -c requirements/prod.txt # requests -charset-normalizer==3.0.1 +charset-normalizer==3.2.0 # via # -c requirements/prod.txt # requests -click==8.1.3 +click==8.1.6 # via # -c requirements/prod.txt # black # pip-tools -coverage[toml]==6.4.1 +coverage[toml]==6.5.0 # via # coveralls # pytest-cov @@ -45,11 +39,11 @@ coveralls==3.3.1 # via -r requirements/dev.in decorator==5.1.1 # via ipython -django==3.2.14 +django==4.2.9 # via # -c requirements/prod.txt # django-extensions -django-extensions==3.1.5 +django-extensions==3.2.3 # via -r requirements/dev.in docopt==0.6.2 # via coveralls @@ -58,17 +52,21 @@ docutils==0.16 # -c requirements/prod.txt # myst-parser # sphinx -executing==0.8.3 +exceptiongroup==1.2.0 + # via + # ipython + # pytest +executing==2.0.1 # via stack-data -factory-boy==3.2.1 +factory-boy==3.3.0 # via # -r requirements/dev.in # pytest-factoryboy -faker==17.0.0 +faker==19.3.0 # via # -c requirements/prod.txt # factory-boy -flake8==4.0.1 +flake8==7.0.0 # via -r requirements/dev.in idna==3.4 # via @@ -77,94 +75,88 @@ idna==3.4 # yarl imagesize==1.4.1 # via sphinx -importlib-metadata==6.0.0 +importlib-metadata==6.8.0 # via # -c requirements/prod.txt + # build # sphinx inflection==0.5.1 # via pytest-factoryboy -iniconfig==1.1.1 +iniconfig==2.0.0 # via pytest -ipython==8.4.0 +ipython==8.18.1 # via -r requirements/dev.in -isort==5.10.1 +isort==5.13.2 # via -r requirements/dev.in -jedi==0.18.1 +jedi==0.19.1 # via ipython jinja2==3.1.2 # via # -c requirements/prod.txt # myst-parser # sphinx -markdown-it-py==2.1.0 +markdown-it-py==2.2.0 # via # -c requirements/prod.txt # mdit-py-plugins # myst-parser -markupsafe==2.1.2 +markupsafe==2.1.3 # via # -c requirements/prod.txt # jinja2 -matplotlib-inline==0.1.3 +matplotlib-inline==0.1.6 # via ipython -mccabe==0.6.1 +mccabe==0.7.0 # via flake8 -mdit-py-plugins==0.3.0 +mdit-py-plugins==0.3.5 # via myst-parser mdurl==0.1.2 # via # -c requirements/prod.txt # markdown-it-py -multidict==6.0.2 +multidict==6.0.4 # via yarl -mypy-extensions==0.4.3 +mypy-extensions==1.0.0 # via black -myst-parser==0.18.0 +myst-parser==1.0.0 # via -r requirements/dev.in -packaging==21.3 +packaging==23.2 # via # -c requirements/prod.txt + # black # build # pytest # sphinx parso==0.8.3 # via jedi -pathspec==0.9.0 +pathspec==0.12.1 # via black -pep517==0.12.0 - # via build -pexpect==4.8.0 - # via ipython -pickleshare==0.7.5 +pexpect==4.9.0 # via ipython -pip-tools==6.8.0 +pip-tools==7.3.0 # via -r requirements/dev.in -platformdirs==2.5.2 +platformdirs==4.1.0 # via black -pluggy==1.0.0 +pluggy==1.3.0 # via pytest -prompt-toolkit==3.0.30 +prompt-toolkit==3.0.43 # via ipython ptyprocess==0.7.0 # via pexpect pure-eval==0.2.2 # via stack-data -py==1.11.0 - # via pytest -pycodestyle==2.8.0 +pycodestyle==2.11.1 # via flake8 -pyflakes==2.4.0 +pyflakes==3.2.0 # via flake8 -pygments==2.14.0 +pygments==2.17.2 # via # -c requirements/prod.txt # ipython # sphinx -pyparsing==3.0.9 - # via - # -c requirements/prod.txt - # packaging -pytest==7.1.2 +pyproject-hooks==1.0.0 + # via build +pytest==7.4.4 # via # -r requirements/dev.in # pytest-asyncio @@ -172,31 +164,26 @@ pytest==7.1.2 # pytest-django # pytest-factoryboy # pytest-mock -pytest-asyncio==0.18.3 +pytest-asyncio==0.23.3 # via -r requirements/dev.in -pytest-cov==3.0.0 +pytest-cov==4.1.0 # via -r requirements/dev.in -pytest-django==4.5.2 +pytest-django==4.7.0 # via -r requirements/dev.in -pytest-factoryboy==2.5.0 +pytest-factoryboy==2.6.0 # via -r requirements/dev.in -pytest-mock==3.8.2 +pytest-mock==3.12.0 # via -r requirements/dev.in python-dateutil==2.8.2 # via # -c requirements/prod.txt # faker -pytz==2022.7.1 - # via - # -c requirements/prod.txt - # babel - # django -pyyaml==6.0 +pyyaml==6.0.1 # via # -c requirements/prod.txt # myst-parser # vcrpy -requests==2.28.2 +requests==2.29.0 # via # -c requirements/prod.txt # coveralls @@ -204,68 +191,71 @@ requests==2.28.2 six==1.16.0 # via # -c requirements/prod.txt + # asttokens + # python-dateutil # sphinxcontrib-httpdomain - # vcrpy snowballstemmer==2.2.0 # via sphinx -sphinx==5.0.2 +sphinx==5.3.0 # via # -r requirements/dev.in # myst-parser # sphinxcontrib-httpdomain -sphinxcontrib-applehelp==1.0.2 +sphinxcontrib-applehelp==1.0.8 # via sphinx -sphinxcontrib-devhelp==1.0.2 +sphinxcontrib-devhelp==1.0.6 # via sphinx -sphinxcontrib-htmlhelp==2.0.0 +sphinxcontrib-htmlhelp==2.0.5 # via sphinx -sphinxcontrib-httpdomain==1.8.0 +sphinxcontrib-httpdomain==1.8.1 # via -r requirements/dev.in sphinxcontrib-jsmath==1.0.1 # via sphinx -sphinxcontrib-qthelp==1.0.3 +sphinxcontrib-qthelp==1.0.7 # via sphinx -sphinxcontrib-serializinghtml==1.1.5 +sphinxcontrib-serializinghtml==1.1.10 # via sphinx -sqlparse==0.4.2 +sqlparse==0.4.4 # via # -c requirements/prod.txt # django -stack-data==0.3.0 +stack-data==0.6.3 # via ipython tomli==2.0.1 # via # black # build # coverage + # pip-tools + # pyproject-hooks # pytest -traitlets==5.3.0 +traitlets==5.14.1 # via # ipython # matplotlib-inline -typing-extensions==4.5.0 +typing-extensions==4.7.1 # via # -c requirements/prod.txt + # asgiref # black - # myst-parser + # ipython # pytest-factoryboy -urllib3==1.26.14 +urllib3==1.26.16 # via # -c requirements/prod.txt # requests -vcrpy==4.2.0 + # vcrpy +vcrpy==5.1.0 # via -r requirements/dev.in -wcwidth==0.2.5 +wcwidth==0.2.13 # via prompt-toolkit -wheel==0.37.1 +wheel==0.42.0 # via pip-tools -wrapt==1.14.1 - # via - # -c requirements/prod.txt - # vcrpy -yarl==1.7.2 +wrapt==1.16.0 + # via vcrpy +yarl==1.9.4 # via vcrpy -zipp==3.13.0 +zipp==3.17.0 # via # -c requirements/prod.txt # importlib-metadata diff --git a/requirements/prod.in b/requirements/prod.in index ba2d3f943c..1e0845f3a0 100644 --- a/requirements/prod.in +++ b/requirements/prod.in @@ -2,16 +2,16 @@ # upgrade-deps.yml workflow. Avoid pinning specific versions here unless required # for stability. -https://github.com/SFDO-Tooling/sfdo-template-helpers/archive/v0.20.0.tar.gz +https://github.com/SFDO-Tooling/sfdo-template-helpers/archive/v0.23.0.tar.gz coloredlogs cumulusci -Django +Django<5 Pillow ansi2html bleach boto3 -channels -channels-redis +channels[daphne]<4 +channels-redis<4 django-allauth django-colorfield django-binary-database-files @@ -36,3 +36,4 @@ sentry-sdk service_identity werkzeug whitenoise +rq-scheduler diff --git a/requirements/prod.txt b/requirements/prod.txt index 03518ef9dc..d8849ab11a 100644 --- a/requirements/prod.txt +++ b/requirements/prod.txt @@ -6,80 +6,82 @@ # aioredis==1.3.1 # via channels-redis -ansi2html==1.8.0 +ansi2html==1.9.1 # via -r requirements/prod.in appdirs==1.4.4 # via # cumulusci # fs -asgiref==3.5.2 +asgiref==3.7.2 # via # channels # channels-redis # daphne # django -async-timeout==4.0.2 +async-timeout==4.0.3 # via # aioredis # redis -attrs==21.4.0 +attrs==23.2.0 # via # automat # service-identity # twisted -authlib==1.2.0 +authlib==1.2.1 # via # cumulusci # simple-salesforce -autobahn==22.6.1 +autobahn==23.6.2 # via daphne -automat==20.2.0 +automat==22.10.0 # via twisted -bleach==5.0.1 +bleach==6.1.0 # via # -r requirements/prod.in # sfdo-template-helpers -boto3==1.24.24 +boto3==1.34.22 # via -r requirements/prod.in -botocore==1.27.24 +botocore==1.34.22 # via # boto3 # s3transfer -certifi==2022.12.7 +certifi==2023.7.22 # via # cumulusci # requests # sentry-sdk # snowfakery -cffi==1.15.1 +cffi==1.16.0 # via # cryptography # cumulusci -channels==3.0.5 +channels[daphne]==3.0.5 # via # -r requirements/prod.in + # channels # channels-redis -channels-redis==3.4.0 +channels-redis==3.4.1 # via -r requirements/prod.in -charset-normalizer==3.0.1 +charset-normalizer==3.2.0 # via # cumulusci # requests # snowfakery -click==8.1.3 +click==8.1.6 # via # cumulusci + # django-rq-scheduler # rq # snowfakery coloredlogs==15.0.1 # via -r requirements/prod.in -constantly==15.1.0 +constantly==23.10.4 # via twisted -croniter==1.3.5 - # via - # django-rq-scheduler - # rq-scheduler -cryptography==39.0.1 +croniter==1.4.1 + # via django-rq-scheduler +crontab==1.0.1 + # via rq-scheduler +cryptography==41.0.7 # via # authlib # autobahn @@ -89,7 +91,7 @@ cryptography==39.0.1 # secretstorage # service-identity # sfdo-template-helpers -cumulusci==3.76.0 +cumulusci==3.84.3 # via -r requirements/prod.in daphne==3.0.2 # via channels @@ -97,9 +99,7 @@ defusedxml==0.7.1 # via # cumulusci # python3-openid -deprecated==1.2.13 - # via redis -django==3.2.14 +django==4.2.9 # via # -r requirements/prod.in # channels @@ -117,60 +117,67 @@ django==3.2.14 # django-storages # djangorestframework # sfdo-template-helpers -django-allauth==0.51.0 +django-allauth==0.60.1 # via -r requirements/prod.in django-binary-database-files==1.0.17 # via -r requirements/prod.in -django-colorfield==0.7.1 +django-colorfield==0.11.0 # via -r requirements/prod.in -django-environ==0.9.0 +django-environ==0.11.2 # via -r requirements/prod.in -django-filter==22.1 +django-filter==23.5 # via # -r requirements/prod.in # sfdo-template-helpers -django-hashid-field==3.3.5 +django-hashid-field==3.4.0 # via -r requirements/prod.in -django-js-reverse==0.9.1 +django-js-reverse==0.10.2 # via -r requirements/prod.in -django-log-request-id==2.0.0 +django-log-request-id==2.1.0 + # via -r requirements/prod.in +django-model-utils==4.3.1 # via -r requirements/prod.in -django-model-utils==4.2.0 - # via - # -r requirements/prod.in - # django-rq-scheduler django-parler==2.3 # via -r requirements/prod.in -django-redis==5.2.0 +django-redis==5.4.0 # via -r requirements/prod.in -django-rq==2.5.1 - # via - # -r requirements/prod.in - # django-rq-scheduler -django-rq-scheduler==2022.6.2 +django-rq==2.10.1 # via -r requirements/prod.in -django-storages==1.12.3 +django-rq-scheduler==2023.9.0 # via -r requirements/prod.in -djangorestframework==3.13.1 +django-storages==1.14.2 + # via -r requirements/prod.in +djangorestframework==3.14.0 # via # -r requirements/prod.in # sfdo-template-helpers docutils==0.16 # via cumulusci -faker==17.0.0 +faker==19.3.0 + # via + # cumulusci + # faker-edu + # faker-nonprofit + # snowfakery +faker-edu==1.0.0 # via # cumulusci # snowfakery +faker-nonprofit==1.0.0 + # via + # cumulusci + # snowfakery +freezegun==1.4.0 + # via rq-scheduler fs==2.4.16 # via cumulusci -github3-py==3.2.0 +github3-py==4.0.1 # via # -r requirements/prod.in # cumulusci -greenlet==2.0.2 +greenlet==3.0.1 # via # cumulusci - # snowfakery # sqlalchemy gvgen==1.0 # via @@ -178,7 +185,7 @@ gvgen==1.0 # snowfakery hashids==1.3.1 # via django-hashid-field -hiredis==2.0.0 +hiredis==2.3.2 # via aioredis honcho==1.1.0 # via -r requirements/prod.in @@ -195,12 +202,12 @@ idna==3.4 # requests # snowfakery # twisted -importlib-metadata==6.0.0 +importlib-metadata==6.8.0 # via # cumulusci # keyring # markdown -incremental==21.3.0 +incremental==22.10.0 # via twisted jeepney==0.8.0 # via @@ -221,68 +228,68 @@ logfmt==0.4 # via # -r requirements/prod.in # sfdo-template-helpers -lxml==4.9.2 +lxml==4.9.3 # via cumulusci -markdown==3.3.7 +markdown==3.5.2 # via sfdo-template-helpers -markdown-it-py==2.1.0 +markdown-it-py==2.2.0 # via # cumulusci # rich -markupsafe==2.1.2 +markupsafe==2.1.3 # via # cumulusci # jinja2 # snowfakery + # werkzeug mdurl==0.1.2 # via # cumulusci # markdown-it-py -msgpack==1.0.4 +msgpack==1.0.7 # via channels-redis -natsort==8.2.0 +natsort==8.4.0 # via # cumulusci # robotframework-pabot -oauthlib==3.2.0 +oauthlib==3.2.2 # via requests-oauthlib -packaging==21.3 - # via redis -pillow==9.2.0 +packaging==23.2 + # via django-js-reverse +pillow==10.2.0 # via # -r requirements/prod.in # django-colorfield -psutil==5.9.4 +psutil==5.9.6 # via cumulusci -psycopg2-binary==2.9.3 +psycopg2-binary==2.9.9 # via -r requirements/prod.in -pyasn1==0.4.8 +pyasn1==0.5.1 # via # pyasn1-modules # service-identity -pyasn1-modules==0.2.8 +pyasn1-modules==0.3.0 # via service-identity pycparser==2.21 # via # cffi # cumulusci -pydantic==1.10.5 +pydantic==1.10.12 # via # cumulusci # snowfakery -pygments==2.14.0 +pygments==2.17.2 # via # cumulusci # rich -pyjwt[crypto]==2.6.0 +pyjwt[crypto]==2.8.0 # via # cumulusci # django-allauth # github3-py -pyopenssl==23.1.1 + # pyjwt +pyopenssl==23.3.0 # via twisted -pyparsing==3.0.9 - # via packaging python-baseconv==1.2.2 # via # cumulusci @@ -293,27 +300,26 @@ python-dateutil==2.8.2 # croniter # cumulusci # faker + # freezegun # github3-py # rq-scheduler # snowfakery python3-openid==3.2.0 # via django-allauth -pytz==2022.7.1 +pytz==2023.3.post1 # via # cumulusci - # django - # django-rq-scheduler # djangorestframework -pyyaml==6.0 +pyyaml==6.0.1 # via # cumulusci # snowfakery -redis==4.3.4 +redis==5.0.1 # via # django-redis # django-rq # rq -requests==2.28.2 +requests==2.29.0 # via # cumulusci # django-allauth @@ -324,29 +330,26 @@ requests==2.28.2 # salesforce-bulk # simple-salesforce # snowfakery -requests-futures==1.0.0 +requests-futures==1.0.1 # via cumulusci requests-oauthlib==1.3.1 # via django-allauth -rich==13.3.1 +rich==13.7.0 # via cumulusci -robotframework==6.0.2 +robotframework==6.1.1 # via # cumulusci - # robotframework-lint # robotframework-pabot # robotframework-requests # robotframework-seleniumlibrary # robotframework-stacktrace -robotframework-lint==1.1 - # via cumulusci -robotframework-pabot==2.13.0 +robotframework-pabot==2.16.0 # via cumulusci -robotframework-pythonlibcore==4.1.0 +robotframework-pythonlibcore==4.3.0 # via # cumulusci # robotframework-seleniumlibrary -robotframework-requests==0.9.4 +robotframework-requests==0.9.6 # via cumulusci robotframework-seleniumlibrary==5.1.3 # via cumulusci @@ -354,16 +357,17 @@ robotframework-stacktrace==0.4.1 # via # cumulusci # robotframework-pabot -rq==1.10.1 +rq==1.15.1 # via # -r requirements/prod.in # django-rq + # django-rq-scheduler # rq-scheduler -rq-scheduler==0.11.0 - # via django-rq-scheduler +rq-scheduler==0.13.1 + # via -r requirements/prod.in rst2ansi==0.1.5 # via cumulusci -s3transfer==0.6.0 +s3transfer==0.10.0 # via boto3 salesforce-bulk==2.2.0 # via cumulusci @@ -377,13 +381,13 @@ selenium==3.141.0 # via # cumulusci # robotframework-seleniumlibrary -sentry-sdk==1.6.0 +sentry-sdk==1.39.2 # via -r requirements/prod.in -service-identity==21.1.0 +service-identity==24.1.0 # via # -r requirements/prod.in # twisted -sfdo-template-helpers @ https://github.com/SFDO-Tooling/sfdo-template-helpers/archive/v0.20.0.tar.gz +sfdo-template-helpers @ https://github.com/SFDO-Tooling/sfdo-template-helpers/archive/v0.23.0.tar.gz # via -r requirements/prod.in simple-salesforce==1.11.4 # via @@ -397,22 +401,24 @@ six==1.16.0 # fs # python-dateutil # salesforce-bulk - # service-identity # snowfakery -snowfakery==3.5.0 +snowfakery==3.6.1 # via cumulusci -sqlalchemy==1.4.46 +sqlalchemy==1.4.49 # via # cumulusci # snowfakery -sqlparse==0.4.2 +sqlparse==0.4.4 # via django -twisted[tls]==22.4.0 - # via daphne -txaio==22.2.1 +twisted[tls]==23.10.0 + # via + # daphne + # twisted +txaio==23.1.1 # via autobahn -typing-extensions==4.5.0 +typing-extensions==4.7.1 # via + # asgiref # cumulusci # pydantic # snowfakery @@ -425,7 +431,7 @@ uritemplate==4.1.1 # via # cumulusci # github3-py -urllib3==1.26.14 +urllib3==1.26.16 # via # botocore # cumulusci @@ -435,19 +441,17 @@ urllib3==1.26.14 # snowfakery webencodings==0.5.1 # via bleach -werkzeug==2.1.2 +werkzeug==3.0.1 # via -r requirements/prod.in -whitenoise==6.2.0 +whitenoise==6.6.0 # via -r requirements/prod.in -wrapt==1.14.1 - # via deprecated xmltodict==0.13.0 # via cumulusci -zipp==3.13.0 +zipp==3.17.0 # via # cumulusci # importlib-metadata -zope-interface==5.4.0 +zope-interface==6.1 # via twisted # The following packages are considered to be unsafe in a requirements file: diff --git a/src/js/components/apiErrors.tsx b/src/js/components/apiErrors.tsx index 9b18c8585e..f17d05a274 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 ( ( -
{children}
+
+ {children} +
); export default BodyContainer; diff --git a/src/js/components/jobs/progressBar.tsx b/src/js/components/jobs/progressBar.tsx index fb7842c623..e8ea6ed788 100644 --- a/src/js/components/jobs/progressBar.tsx +++ b/src/js/components/jobs/progressBar.tsx @@ -116,7 +116,7 @@ class ProgressBar extends Component { const progressRounded = Math.min(Math.round(progress), 100); const id = `${job.id}-progress`; return ( -
+
diff --git a/src/js/components/plans/detail.tsx b/src/js/components/plans/detail.tsx index 429e67c92f..a2d980a052 100644 --- a/src/js/components/plans/detail.tsx +++ b/src/js/components/plans/detail.tsx @@ -298,13 +298,13 @@ class PlanDetail extends Component { {t( - 'Oops! It looks like you don’t have permissions to run an installation on this org.', + 'Oops! It looks like you have been logged out or don’t have permissions to run an installation on this org.', )}

{t( - 'Please contact an Admin within your org or use the button below to log in with a different org.', + 'Please log back in, contact an Admin, or use the button below to log in with a different org.', )}

diff --git a/src/js/components/plans/intro.tsx b/src/js/components/plans/intro.tsx index 14a0bdd2b7..f39aec5585 100644 --- a/src/js/components/plans/intro.tsx +++ b/src/js/components/plans/intro.tsx @@ -27,6 +27,7 @@ const Intro = ({ return (
diff --git a/src/js/components/plans/stepsTable/index.tsx b/src/js/components/plans/stepsTable/index.tsx index a4febb93d1..13ca4c4077 100644 --- a/src/js/components/plans/stepsTable/index.tsx +++ b/src/js/components/plans/stepsTable/index.tsx @@ -205,7 +205,7 @@ class StepsTable extends Component { const hasReadyPreflight = !plan.requires_preflight || preflight?.is_ready; const logsExpanded = expandedPanels.size > 0; return ( -
+

- The credentials to your Salesforce org will only be held for{' '} - {{ token_minutes }} minutes or until your requested installation is - complete. + If no action is performed for {{ token_minutes }} minutes, you will + be automatically logged out and will need to log in again.

@@ -115,6 +114,7 @@ const UserInfo = ({ return contents ? (
diff --git a/src/js/components/products/detail.tsx b/src/js/components/products/detail.tsx index 2e3ef48bcc..3d83f4fa4c 100644 --- a/src/js/components/products/detail.tsx +++ b/src/js/components/products/detail.tsx @@ -135,6 +135,7 @@ const BodySection = ({ children }: { children?: ReactNode }) => (
diff --git a/src/js/components/products/list.tsx b/src/js/components/products/list.tsx index 72e5525f2d..e7d1bfac75 100644 --- a/src/js/components/products/list.tsx +++ b/src/js/components/products/list.tsx @@ -25,6 +25,7 @@ const getProductsList = (products: Product[], category?: Category) => (
{ <>
-
+
{window.GLOBALS.SITE?.welcome_text ? ( // These messages are pre-cleaned by the API
{ {t('Version {{version}}', { version: label })}
{item.short_description ? ( -
{item.short_description}
+
+ {item.short_description} +
) : ( item.description && (
diff --git a/src/js/components/products/planCards.tsx b/src/js/components/products/planCards.tsx index 4137c2a766..319374a4d7 100644 --- a/src/js/components/products/planCards.tsx +++ b/src/js/components/products/planCards.tsx @@ -21,6 +21,7 @@ const PlanCard = ({ 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 9ddd68085a..8907ede4d6 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/components/plans/detail.test.js b/test/js/components/plans/detail.test.js index f49d41d1d2..91304a9530 100644 --- a/test/js/components/plans/detail.test.js +++ b/test/js/components/plans/detail.test.js @@ -215,7 +215,7 @@ describe('', () => { }); expect( - getByText('you don’t have permissions', { exact: false }), + getByText('don’t have permissions', { exact: false }), ).toBeVisible(); }); }); diff --git a/test/js/utils/api.test.js b/test/js/utils/api.test.js index 0d7235f346..4a4b7a8a15 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: {} });