From 92f929152f713646ec8836891718c2ac18fff81f Mon Sep 17 00:00:00 2001 From: Ahmed Bouhuolia Date: Sun, 16 Jul 2023 21:15:13 +0200 Subject: [PATCH 1/7] feat(server): expose the api rate limit to the env vars --- .env.example | 3 +++ packages/server/src/config/index.ts | 11 +++++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.env.example b/.env.example index 4978f6a78..f07f28c5f 100644 --- a/.env.example +++ b/.env.example @@ -47,3 +47,6 @@ AGENDASH_AUTH_PASSWORD=123123 SIGNUP_DISABLED=false SIGNUP_ALLOWED_DOMAINS= SIGNUP_ALLOWED_EMAILS= + +# API rate limit (points,duration,block duration). +API_RATE_LIMIT=120,60,600 \ No newline at end of file diff --git a/packages/server/src/config/index.ts b/packages/server/src/config/index.ts index ff1fedb6a..bc6833130 100644 --- a/packages/server/src/config/index.ts +++ b/packages/server/src/config/index.ts @@ -1,9 +1,12 @@ import dotenv from 'dotenv'; import path from 'path'; +import { toInteger } from 'lodash'; import { castCommaListEnvVarToArray, parseBoolean } from '@/utils'; dotenv.config(); +const API_RATE_LIMIT = process.env.API_RATE_LIMIT?.split(',') || []; + module.exports = { /** * Your favorite port @@ -97,7 +100,7 @@ module.exports = { jwtSecret: process.env.JWT_SECRET, /** - * + * */ resetPasswordSeconds: 600, @@ -130,9 +133,9 @@ module.exports = { blockDuration: 60 * 15, }, requests: { - points: 60, - duration: 60, - blockDuration: 60 * 10, + points: API_RATE_LIMIT[0] ? toInteger(API_RATE_LIMIT[0]) : 120, + duration: API_RATE_LIMIT[1] ? toInteger(API_RATE_LIMIT[1]) : 60, + blockDuration: API_RATE_LIMIT[2] ? toInteger(API_RATE_LIMIT[2]) : 60 * 10, }, }, From 8b0feb902284ff36350663b2b2113ac13b70f5f6 Mon Sep 17 00:00:00 2001 From: Ahmed Bouhuolia Date: Sun, 16 Jul 2023 21:19:06 +0200 Subject: [PATCH 2/7] fix(webapp): handle the too many requests error --- .../src/containers/GlobalErrors/GlobalErrors.tsx | 13 +++++++++++++ packages/webapp/src/hooks/useRequest.tsx | 3 +++ packages/webapp/src/lang/en/index.json | 3 ++- .../src/style/components/BigcapitalLoading.scss | 6 ++++-- packages/webapp/src/style/variables.scss | 4 ++++ 5 files changed, 26 insertions(+), 3 deletions(-) diff --git a/packages/webapp/src/containers/GlobalErrors/GlobalErrors.tsx b/packages/webapp/src/containers/GlobalErrors/GlobalErrors.tsx index 211402c0f..e972733d8 100644 --- a/packages/webapp/src/containers/GlobalErrors/GlobalErrors.tsx +++ b/packages/webapp/src/containers/GlobalErrors/GlobalErrors.tsx @@ -9,6 +9,7 @@ import { compose } from '@/utils'; let toastKeySessionExpired; let toastKeySomethingWrong; +let toastTooManyRequests; function GlobalErrors({ // #withGlobalErrors @@ -41,6 +42,18 @@ function GlobalErrors({ toastKeySomethingWrong, ); } + if (globalErrors.too_many_requests) { + toastTooManyRequests = AppToaster.show( + { + message: intl.get('global_error.too_many_requests'), + intent: Intent.DANGER, + onDismiss: () => { + globalErrorsSet({ too_many_requests: false }); + }, + }, + toastTooManyRequests, + ); + } if (globalErrors.access_denied) { toastKeySomethingWrong = AppToaster.show( { diff --git a/packages/webapp/src/hooks/useRequest.tsx b/packages/webapp/src/hooks/useRequest.tsx index c092f1faf..12635ad0a 100644 --- a/packages/webapp/src/hooks/useRequest.tsx +++ b/packages/webapp/src/hooks/useRequest.tsx @@ -60,6 +60,9 @@ export default function useApiRequest() { if (status === 403) { setGlobalErrors({ access_denied: true }); } + if (status === 429) { + setGlobalErrors({ too_many_requests: true }); + } if (status === 400) { const lockedError = data.errors.find( (error) => error.type === 'TRANSACTIONS_DATE_LOCKED', diff --git a/packages/webapp/src/lang/en/index.json b/packages/webapp/src/lang/en/index.json index 2010d32b1..6fb394354 100644 --- a/packages/webapp/src/lang/en/index.json +++ b/packages/webapp/src/lang/en/index.json @@ -2292,5 +2292,6 @@ "sidebar.projects": "Projects", "sidebar.new_project": "New Project", "sidebar.new_time_entry": "New Time Entry", - "sidebar.project_profitability_summary": "Project Profitability Summary" + "sidebar.project_profitability_summary": "Project Profitability Summary", + "global_error.too_many_requests": "Too many requests" } \ No newline at end of file diff --git a/packages/webapp/src/style/components/BigcapitalLoading.scss b/packages/webapp/src/style/components/BigcapitalLoading.scss index 2375d2a1f..c387b5b13 100644 --- a/packages/webapp/src/style/components/BigcapitalLoading.scss +++ b/packages/webapp/src/style/components/BigcapitalLoading.scss @@ -1,10 +1,12 @@ +@import '@/style/variables.scss'; + .bigcapital-loading { height: 100%; width: 100%; position: fixed; display: flex; background: #fff; - z-index: 999999; + z-index: $zindex-dashboard-splash-screen; .center { width: auto; @@ -18,4 +20,4 @@ opacity: 0.85; display: none; } -} +} \ No newline at end of file diff --git a/packages/webapp/src/style/variables.scss b/packages/webapp/src/style/variables.scss index bea903aa4..21fe0ded6 100644 --- a/packages/webapp/src/style/variables.scss +++ b/packages/webapp/src/style/variables.scss @@ -45,3 +45,7 @@ $form-check-input-checked-color: #fff; $form-check-input-checked-bg-color: $blue1; $form-check-input-checked-bg-image: url("data:image/svg+xml,") !default; $form-check-input-indeterminate-bg-image: url("data:image/svg+xml,") !default; + +// z-indexs +$zindex-dashboard-splash-screen: 39; +$zindex-toast: 40; \ No newline at end of file From ce62a0524c7143a50833436b721bb557b13f1266 Mon Sep 17 00:00:00 2001 From: Suhaib Affan Date: Wed, 19 Jul 2023 20:19:56 -0400 Subject: [PATCH 3/7] Added restart policy to docker compose files. --- docker-compose.prod.yml | 32 +++++++++++++++++++++++++++++++- docker-compose.yml | 15 +++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 04c580729..e4b0f0895 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -21,10 +21,20 @@ services: depends_on: - server - webapp + deploy: + restart_policy: + condition: on-failure + delay: 5s + window: 120s webapp: container_name: bigcapital-webapp image: ghcr.io/bigcapitalhq/webapp:latest + deploy: + restart_policy: + condition: on-failure + delay: 5s + window: 120s server: container_name: bigcapital-server @@ -37,6 +47,11 @@ services: - mysql - mongo - redis + deploy: + restart_policy: + condition: on-failure + delay: 5s + window: 120s environment: # Mail - MAIL_HOST=${MAIL_HOST} @@ -93,6 +108,11 @@ services: mysql: container_name: bigcapital-mysql + deploy: + restart_policy: + condition: on-failure + delay: 5s + window: 120s build: context: ./docker/mariadb environment: @@ -106,7 +126,12 @@ services: - '3306' mongo: - container_name: bigcapital-mongo + container_name: bigcapital-mongo + deploy: + restart_policy: + condition: on-failure + delay: 5s + window: 120s build: ./docker/mongo expose: - '27017' @@ -115,6 +140,11 @@ services: redis: container_name: bigcapital-redis + deploy: + restart_policy: + condition: on-failure + delay: 5s + window: 120s build: context: ./docker/redis expose: diff --git a/docker-compose.yml b/docker-compose.yml index 11143c063..8df1498f6 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -20,6 +20,11 @@ services: - '3306' ports: - '3306:3306' + deploy: + restart_policy: + condition: on-failure + delay: 5s + window: 120s mongo: build: ./docker/mongo @@ -29,6 +34,11 @@ services: - mongo:/var/lib/mongodb ports: - '27017:27017' + deploy: + restart_policy: + condition: on-failure + delay: 5s + window: 120s redis: build: @@ -37,6 +47,11 @@ services: - "6379" volumes: - redis:/data + deploy: + restart_policy: + condition: on-failure + delay: 5s + window: 120s # Volumes volumes: From ef5ef647d4842e029d4ec3fa4f46a048d52e3a69 Mon Sep 17 00:00:00 2001 From: Ahmed Bouhuolia Date: Sun, 23 Jul 2023 19:54:55 +0200 Subject: [PATCH 4/7] chore: change docker restart policy to unless-stopped --- docker-compose.prod.yml | 20 +++++--------------- docker-compose.yml | 12 +++--------- 2 files changed, 8 insertions(+), 24 deletions(-) diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index e4b0f0895..7b5236e1b 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -23,18 +23,14 @@ services: - webapp deploy: restart_policy: - condition: on-failure - delay: 5s - window: 120s + condition: unless-stopped webapp: container_name: bigcapital-webapp image: ghcr.io/bigcapitalhq/webapp:latest deploy: restart_policy: - condition: on-failure - delay: 5s - window: 120s + condition: unless-stopped server: container_name: bigcapital-server @@ -49,9 +45,7 @@ services: - redis deploy: restart_policy: - condition: on-failure - delay: 5s - window: 120s + condition: unless-stopped environment: # Mail - MAIL_HOST=${MAIL_HOST} @@ -129,9 +123,7 @@ services: container_name: bigcapital-mongo deploy: restart_policy: - condition: on-failure - delay: 5s - window: 120s + condition: unless-stopped build: ./docker/mongo expose: - '27017' @@ -142,9 +134,7 @@ services: container_name: bigcapital-redis deploy: restart_policy: - condition: on-failure - delay: 5s - window: 120s + condition: unless-stopped build: context: ./docker/redis expose: diff --git a/docker-compose.yml b/docker-compose.yml index 8df1498f6..9563ae91e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -22,9 +22,7 @@ services: - '3306:3306' deploy: restart_policy: - condition: on-failure - delay: 5s - window: 120s + condition: unless-stopped mongo: build: ./docker/mongo @@ -36,9 +34,7 @@ services: - '27017:27017' deploy: restart_policy: - condition: on-failure - delay: 5s - window: 120s + condition: unless-stopped redis: build: @@ -49,9 +45,7 @@ services: - redis:/data deploy: restart_policy: - condition: on-failure - delay: 5s - window: 120s + condition: unless-stopped # Volumes volumes: From 7a33f7926828e6bce3c95dc2687ae77a36ab5098 Mon Sep 17 00:00:00 2001 From: Ahmed Bouhuolia Date: Sun, 23 Jul 2023 20:05:34 +0200 Subject: [PATCH 5/7] chore: update mysql docker container restart policy --- docker-compose.prod.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 7b5236e1b..b7e2e1040 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -104,9 +104,7 @@ services: container_name: bigcapital-mysql deploy: restart_policy: - condition: on-failure - delay: 5s - window: 120s + condition: unless-stopped build: context: ./docker/mariadb environment: From 0fd256c8013b8154802eaa3843c3bf3a67bafcca Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Sun, 23 Jul 2023 18:16:21 +0000 Subject: [PATCH 6/7] docs: update README.md [skip ci] --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3c5186476..208d39aab 100644 --- a/README.md +++ b/README.md @@ -69,9 +69,10 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d Ahmed Bouhuolia
Ahmed Bouhuolia

💻 - ElforJani13
ElforJani13

💻 Ameir Abdeldayem
Ameir Abdeldayem

🐛 + ElforJani13
ElforJani13

💻 Lars Scheibling
Lars Scheibling

🐛 + Suhaib Affan
Suhaib Affan

💻 From ed6517c0e18313b57fe2a270203631beca65711f Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Sun, 23 Jul 2023 18:16:22 +0000 Subject: [PATCH 7/7] docs: update .all-contributorsrc [skip ci] --- .all-contributorsrc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index e37bacbf9..d69d4da6f 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -42,6 +42,15 @@ "contributions": [ "bug" ] + }, + { + "login": "suhaibaffan", + "name": "Suhaib Affan", + "avatar_url": "https://avatars.githubusercontent.com/u/18115937?v=4", + "profile": "https://github.com/suhaibaffan", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7,