Compare commits

...

13 Commits

Author SHA1 Message Date
Ahmed Bouhuolia
efad38fcdc Merge pull request #195 from bigcapitalhq/api-rate-env-vars
fix: expose the rate limit to the env variables
2023-07-23 20:17:51 +02:00
Ahmed Bouhuolia
d84568e43a Merge pull request #201 from bigcapitalhq/all-contributors/add-suhaibaffan
docs: add suhaibaffan as a contributor for code
2023-07-23 20:16:56 +02:00
allcontributors[bot]
ed6517c0e1 docs: update .all-contributorsrc [skip ci] 2023-07-23 18:16:22 +00:00
allcontributors[bot]
0fd256c801 docs: update README.md [skip ci] 2023-07-23 18:16:21 +00:00
Ahmed Bouhuolia
f0285560aa Merge pull request #198 from suhaibaffan/#149-restart-crashed-docker-containers
Added restart policy to docker compose files.
2023-07-23 20:13:48 +02:00
Ahmed Bouhuolia
7a33f79268 chore: update mysql docker container restart policy 2023-07-23 20:05:34 +02:00
Ahmed Bouhuolia
ef5ef647d4 chore: change docker restart policy to unless-stopped 2023-07-23 19:54:55 +02:00
Suhaib Affan
ce62a0524c Added restart policy to docker compose files. 2023-07-19 20:19:56 -04:00
Ahmed Bouhuolia
278c8a01c5 Merge remote-tracking branch 'refs/remotes/origin/develop' into develop 2023-07-18 20:03:31 +02:00
Ahmed Bouhuolia
f22dc9a18b fix(webapp): assign currency code of customer/vendor to the transaction form. 2023-07-18 20:02:45 +02:00
Ahmed Bouhuolia
b224a2c313 Merge pull request #196 from bigcapitalhq/fix-loading-status-on-financial-reports
fix(webapp): show loading message of cost computing job on financial reports
2023-07-17 01:51:02 +02:00
Ahmed Bouhuolia
8b0feb9022 fix(webapp): handle the too many requests error 2023-07-16 21:19:16 +02:00
Ahmed Bouhuolia
92f929152f feat(server): expose the api rate limit to the env vars 2023-07-16 21:15:13 +02:00
19 changed files with 83 additions and 18 deletions

View File

@@ -42,6 +42,15 @@
"contributions": [ "contributions": [
"bug" "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, "contributorsPerLine": 7,

View File

@@ -47,3 +47,6 @@ AGENDASH_AUTH_PASSWORD=123123
SIGNUP_DISABLED=false SIGNUP_DISABLED=false
SIGNUP_ALLOWED_DOMAINS= SIGNUP_ALLOWED_DOMAINS=
SIGNUP_ALLOWED_EMAILS= SIGNUP_ALLOWED_EMAILS=
# API rate limit (points,duration,block duration).
API_RATE_LIMIT=120,60,600

View File

@@ -69,9 +69,10 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
<tbody> <tbody>
<tr> <tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/abouolia"><img src="https://avatars.githubusercontent.com/u/2197422?v=4?s=100" width="100px;" alt="Ahmed Bouhuolia"/><br /><sub><b>Ahmed Bouhuolia</b></sub></a><br /><a href="https://github.com/bigcapitalhq/bigcapital/commits?author=abouolia" title="Code">💻</a></td> <td align="center" valign="top" width="14.28%"><a href="https://github.com/abouolia"><img src="https://avatars.githubusercontent.com/u/2197422?v=4?s=100" width="100px;" alt="Ahmed Bouhuolia"/><br /><sub><b>Ahmed Bouhuolia</b></sub></a><br /><a href="https://github.com/bigcapitalhq/bigcapital/commits?author=abouolia" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/elforjani13"><img src="https://avatars.githubusercontent.com/u/39470382?v=4?s=100" width="100px;" alt="ElforJani13"/><br /><sub><b>ElforJani13</b></sub></a><br /><a href="https://github.com/bigcapitalhq/bigcapital/commits?author=elforjani13" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://ameir.net"><img src="https://avatars.githubusercontent.com/u/374330?v=4?s=100" width="100px;" alt="Ameir Abdeldayem"/><br /><sub><b>Ameir Abdeldayem</b></sub></a><br /><a href="https://github.com/bigcapitalhq/bigcapital/issues?q=author%3Aameir" title="Bug reports">🐛</a></td> <td align="center" valign="top" width="14.28%"><a href="http://ameir.net"><img src="https://avatars.githubusercontent.com/u/374330?v=4?s=100" width="100px;" alt="Ameir Abdeldayem"/><br /><sub><b>Ameir Abdeldayem</b></sub></a><br /><a href="https://github.com/bigcapitalhq/bigcapital/issues?q=author%3Aameir" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/elforjani13"><img src="https://avatars.githubusercontent.com/u/39470382?v=4?s=100" width="100px;" alt="ElforJani13"/><br /><sub><b>ElforJani13</b></sub></a><br /><a href="https://github.com/bigcapitalhq/bigcapital/commits?author=elforjani13" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://scheibling.se"><img src="https://avatars.githubusercontent.com/u/24367830?v=4?s=100" width="100px;" alt="Lars Scheibling"/><br /><sub><b>Lars Scheibling</b></sub></a><br /><a href="https://github.com/bigcapitalhq/bigcapital/issues?q=author%3Ascheibling" title="Bug reports">🐛</a></td> <td align="center" valign="top" width="14.28%"><a href="https://scheibling.se"><img src="https://avatars.githubusercontent.com/u/24367830?v=4?s=100" width="100px;" alt="Lars Scheibling"/><br /><sub><b>Lars Scheibling</b></sub></a><br /><a href="https://github.com/bigcapitalhq/bigcapital/issues?q=author%3Ascheibling" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/suhaibaffan"><img src="https://avatars.githubusercontent.com/u/18115937?v=4?s=100" width="100px;" alt="Suhaib Affan"/><br /><sub><b>Suhaib Affan</b></sub></a><br /><a href="https://github.com/bigcapitalhq/bigcapital/commits?author=suhaibaffan" title="Code">💻</a></td>
</tr> </tr>
</tbody> </tbody>
</table> </table>

View File

@@ -21,10 +21,16 @@ services:
depends_on: depends_on:
- server - server
- webapp - webapp
deploy:
restart_policy:
condition: unless-stopped
webapp: webapp:
container_name: bigcapital-webapp container_name: bigcapital-webapp
image: ghcr.io/bigcapitalhq/webapp:latest image: ghcr.io/bigcapitalhq/webapp:latest
deploy:
restart_policy:
condition: unless-stopped
server: server:
container_name: bigcapital-server container_name: bigcapital-server
@@ -37,6 +43,9 @@ services:
- mysql - mysql
- mongo - mongo
- redis - redis
deploy:
restart_policy:
condition: unless-stopped
environment: environment:
# Mail # Mail
- MAIL_HOST=${MAIL_HOST} - MAIL_HOST=${MAIL_HOST}
@@ -93,6 +102,9 @@ services:
mysql: mysql:
container_name: bigcapital-mysql container_name: bigcapital-mysql
deploy:
restart_policy:
condition: unless-stopped
build: build:
context: ./docker/mariadb context: ./docker/mariadb
environment: environment:
@@ -107,6 +119,9 @@ services:
mongo: mongo:
container_name: bigcapital-mongo container_name: bigcapital-mongo
deploy:
restart_policy:
condition: unless-stopped
build: ./docker/mongo build: ./docker/mongo
expose: expose:
- '27017' - '27017'
@@ -115,6 +130,9 @@ services:
redis: redis:
container_name: bigcapital-redis container_name: bigcapital-redis
deploy:
restart_policy:
condition: unless-stopped
build: build:
context: ./docker/redis context: ./docker/redis
expose: expose:

View File

@@ -20,6 +20,9 @@ services:
- '3306' - '3306'
ports: ports:
- '3306:3306' - '3306:3306'
deploy:
restart_policy:
condition: unless-stopped
mongo: mongo:
build: ./docker/mongo build: ./docker/mongo
@@ -29,6 +32,9 @@ services:
- mongo:/var/lib/mongodb - mongo:/var/lib/mongodb
ports: ports:
- '27017:27017' - '27017:27017'
deploy:
restart_policy:
condition: unless-stopped
redis: redis:
build: build:
@@ -37,6 +43,9 @@ services:
- "6379" - "6379"
volumes: volumes:
- redis:/data - redis:/data
deploy:
restart_policy:
condition: unless-stopped
# Volumes # Volumes
volumes: volumes:

View File

@@ -1,9 +1,12 @@
import dotenv from 'dotenv'; import dotenv from 'dotenv';
import path from 'path'; import path from 'path';
import { toInteger } from 'lodash';
import { castCommaListEnvVarToArray, parseBoolean } from '@/utils'; import { castCommaListEnvVarToArray, parseBoolean } from '@/utils';
dotenv.config(); dotenv.config();
const API_RATE_LIMIT = process.env.API_RATE_LIMIT?.split(',') || [];
module.exports = { module.exports = {
/** /**
* Your favorite port * Your favorite port
@@ -130,9 +133,9 @@ module.exports = {
blockDuration: 60 * 15, blockDuration: 60 * 15,
}, },
requests: { requests: {
points: 60, points: API_RATE_LIMIT[0] ? toInteger(API_RATE_LIMIT[0]) : 120,
duration: 60, duration: API_RATE_LIMIT[1] ? toInteger(API_RATE_LIMIT[1]) : 60,
blockDuration: 60 * 10, blockDuration: API_RATE_LIMIT[2] ? toInteger(API_RATE_LIMIT[2]) : 60 * 10,
}, },
}, },

View File

@@ -9,6 +9,7 @@ import { compose } from '@/utils';
let toastKeySessionExpired; let toastKeySessionExpired;
let toastKeySomethingWrong; let toastKeySomethingWrong;
let toastTooManyRequests;
function GlobalErrors({ function GlobalErrors({
// #withGlobalErrors // #withGlobalErrors
@@ -41,6 +42,18 @@ function GlobalErrors({
toastKeySomethingWrong, 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) { if (globalErrors.access_denied) {
toastKeySomethingWrong = AppToaster.show( toastKeySomethingWrong = AppToaster.show(
{ {

View File

@@ -176,7 +176,7 @@ function BillFormVendorField() {
name={'vendor_id'} name={'vendor_id'}
items={vendors} items={vendors}
placeholder={<T id={'select_vender_account'} />} placeholder={<T id={'select_vender_account'} />}
onItemChange={(contact) => { onItemSelect={(contact) => {
setFieldValue('vendor_id', contact.id); setFieldValue('vendor_id', contact.id);
setFieldValue('currency_code', contact?.currency_code); setFieldValue('currency_code', contact?.currency_code);
}} }}

View File

@@ -85,7 +85,6 @@ function VendorCreditNoteFormHeaderFields({
name={'exchange_rate'} name={'exchange_rate'}
formGroupProps={{ label: ' ', inline: true }} formGroupProps={{ label: ' ', inline: true }}
/> />
{/* ------- Vendor Credit date ------- */} {/* ------- Vendor Credit date ------- */}
<FastField name={'vendor_credit_date'}> <FastField name={'vendor_credit_date'}>
{({ form, field: { value }, meta: { error, touched } }) => ( {({ form, field: { value }, meta: { error, touched } }) => (
@@ -194,7 +193,7 @@ function VendorCreditFormVendorSelect() {
name={'vendor_id'} name={'vendor_id'}
items={vendors} items={vendors}
placeholder={<T id={'select_vender_account'} />} placeholder={<T id={'select_vender_account'} />}
onItemChange={(contact) => { onItemSelect={(contact) => {
setFieldValue('vendor_id', contact.id); setFieldValue('vendor_id', contact.id);
setFieldValue('currency_code', contact?.currency_code); setFieldValue('currency_code', contact?.currency_code);
}} }}

View File

@@ -248,7 +248,7 @@ function PaymentFormVendorSelect() {
name={'vendor_id'} name={'vendor_id'}
items={vendors} items={vendors}
placeholder={<T id={'select_vender_account'} />} placeholder={<T id={'select_vender_account'} />}
onItemChange={(contact) => { onItemSelect={(contact) => {
setFieldValue('vendor_id', contact.id); setFieldValue('vendor_id', contact.id);
setFieldValue('currency_code', contact?.currency_code); setFieldValue('currency_code', contact?.currency_code);
setPaymentVendorId(contact.id); setPaymentVendorId(contact.id);

View File

@@ -110,7 +110,7 @@ function CreditNoteCustomersSelect() {
name={'customer_id'} name={'customer_id'}
items={customers} items={customers}
placeholder={<T id={'select_customer_account'} />} placeholder={<T id={'select_customer_account'} />}
onItemChange={(customer) => { onItemSelect={(customer) => {
setFieldValue('customer_id', customer.id); setFieldValue('customer_id', customer.id);
setFieldValue('currency_code', customer?.currency_code); setFieldValue('currency_code', customer?.currency_code);
}} }}

View File

@@ -165,7 +165,7 @@ function EstimateFormCustomerSelect() {
name={'customer_id'} name={'customer_id'}
items={customers} items={customers}
placeholder={<T id={'select_customer_account'} />} placeholder={<T id={'select_customer_account'} />}
onItemChange={(customer) => { onItemSelect={(customer) => {
setFieldValue('customer_id', customer.id); setFieldValue('customer_id', customer.id);
setFieldValue('currency_code', customer?.currency_code); setFieldValue('currency_code', customer?.currency_code);
}} }}

View File

@@ -178,7 +178,7 @@ function InvoiceFormCustomerSelect() {
name={'customer_id'} name={'customer_id'}
items={customers} items={customers}
placeholder={<T id={'select_customer_account'} />} placeholder={<T id={'select_customer_account'} />}
onItemChange={(customer) => { onItemSelect={(customer) => {
setFieldValue('customer_id', customer.id); setFieldValue('customer_id', customer.id);
setFieldValue('currency_code', customer?.currency_code); setFieldValue('currency_code', customer?.currency_code);
}} }}

View File

@@ -263,7 +263,7 @@ function PaymentReceiveCustomerSelect() {
name={'customer_id'} name={'customer_id'}
items={customers} items={customers}
placeholder={<T id={'select_customer_account'} />} placeholder={<T id={'select_customer_account'} />}
onItemChange={(customer) => { onItemSelect={(customer) => {
setFieldValue('customer_id', customer.id); setFieldValue('customer_id', customer.id);
setFieldValue('full_amount', ''); setFieldValue('full_amount', '');
setFieldValue('currency_code', customer?.currency_code); setFieldValue('currency_code', customer?.currency_code);

View File

@@ -162,7 +162,7 @@ function ReceiptFormCustomerSelect() {
name={'customer_id'} name={'customer_id'}
items={customers} items={customers}
placeholder={<T id={'select_customer_account'} />} placeholder={<T id={'select_customer_account'} />}
onItemChange={(customer) => { onItemSelect={(customer) => {
setFieldValue('customer_id', customer.id); setFieldValue('customer_id', customer.id);
setFieldValue('currency_code', customer?.currency_code); setFieldValue('currency_code', customer?.currency_code);
}} }}

View File

@@ -60,6 +60,9 @@ export default function useApiRequest() {
if (status === 403) { if (status === 403) {
setGlobalErrors({ access_denied: true }); setGlobalErrors({ access_denied: true });
} }
if (status === 429) {
setGlobalErrors({ too_many_requests: true });
}
if (status === 400) { if (status === 400) {
const lockedError = data.errors.find( const lockedError = data.errors.find(
(error) => error.type === 'TRANSACTIONS_DATE_LOCKED', (error) => error.type === 'TRANSACTIONS_DATE_LOCKED',

View File

@@ -2292,5 +2292,6 @@
"sidebar.projects": "Projects", "sidebar.projects": "Projects",
"sidebar.new_project": "New Project", "sidebar.new_project": "New Project",
"sidebar.new_time_entry": "New Time Entry", "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"
} }

View File

@@ -1,10 +1,12 @@
@import '@/style/variables.scss';
.bigcapital-loading { .bigcapital-loading {
height: 100%; height: 100%;
width: 100%; width: 100%;
position: fixed; position: fixed;
display: flex; display: flex;
background: #fff; background: #fff;
z-index: 999999; z-index: $zindex-dashboard-splash-screen;
.center { .center {
width: auto; width: auto;

View File

@@ -45,3 +45,7 @@ $form-check-input-checked-color: #fff;
$form-check-input-checked-bg-color: $blue1; $form-check-input-checked-bg-color: $blue1;
$form-check-input-checked-bg-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 16 16' enable-background='new 0 0 16 16' xml:space='preserve'><g id='small_tick_1_'><g><path fill='#{$form-check-input-checked-color}' fill-rule='evenodd' clip-rule='evenodd' d='M12,5c-0.28,0-0.53,0.11-0.71,0.29L7,9.59L4.71,7.29C4.53,7.11,4.28,7,4,7C3.45,7,3,7.45,3,8c0,0.28,0.11,0.53,0.29,0.71l3,3C6.47,11.89,6.72,12,7,12s0.53-0.11,0.71-0.29l5-5C12.89,6.53,13,6.28,13,6C13,5.45,12.55,5,12,5z'/></g></g></svg>") !default; $form-check-input-checked-bg-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 16 16' enable-background='new 0 0 16 16' xml:space='preserve'><g id='small_tick_1_'><g><path fill='#{$form-check-input-checked-color}' fill-rule='evenodd' clip-rule='evenodd' d='M12,5c-0.28,0-0.53,0.11-0.71,0.29L7,9.59L4.71,7.29C4.53,7.11,4.28,7,4,7C3.45,7,3,7.45,3,8c0,0.28,0.11,0.53,0.29,0.71l3,3C6.47,11.89,6.72,12,7,12s0.53-0.11,0.71-0.29l5-5C12.89,6.53,13,6.28,13,6C13,5.45,12.55,5,12,5z'/></g></g></svg>") !default;
$form-check-input-indeterminate-bg-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 16 16' enable-background='new 0 0 16 16' xml:space='preserve'><g id='small_tick_1_'><g><path fill='#{$form-check-input-checked-color}' fill-rule='evenodd' clip-rule='evenodd' d='M11,7H5C4.45,7,4,7.45,4,8c0,0.55,0.45,1,1,1h6c0.55,0,1-0.45,1-1C12,7.45,11.55,7,11,7z'/></g></g></svg>") !default; $form-check-input-indeterminate-bg-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 16 16' enable-background='new 0 0 16 16' xml:space='preserve'><g id='small_tick_1_'><g><path fill='#{$form-check-input-checked-color}' fill-rule='evenodd' clip-rule='evenodd' d='M11,7H5C4.45,7,4,7.45,4,8c0,0.55,0.45,1,1,1h6c0.55,0,1-0.45,1-1C12,7.45,11.55,7,11,7z'/></g></g></svg>") !default;
// z-indexs
$zindex-dashboard-splash-screen: 39;
$zindex-toast: 40;