Compare commits

..

1 Commits

Author SHA1 Message Date
Ahmed Bouhuolia
96b16831e9 fix: Organize Plaid env variables for development and sandbox envs 2024-06-03 20:49:16 +02:00
12 changed files with 44 additions and 70 deletions

View File

@@ -75,9 +75,30 @@ PLAID_ENV=sandbox
# Your Plaid keys, which can be found in the Plaid Dashboard.
# https://dashboard.plaid.com/account/keys
PLAID_CLIENT_ID=
PLAID_SECRET=
PLAID_SECRET_DEVELOPMENT=
PLAID_SECRET_SANDBOX=
PLAID_LINK_WEBHOOK=
# (Optional) Redirect URI settings section
# Only required for OAuth redirect URI testing (not common on desktop):
# Sandbox Mode:
# Set the PLAID_SANDBOX_REDIRECT_URI below to 'http://localhost:3001/oauth-link'.
# The OAuth redirect flow requires an endpoint on the developer's website
# that the bank website should redirect to. You will also need to configure
# this redirect URI for your client ID through the Plaid developer dashboard
# at https://dashboard.plaid.com/team/api.
# Development mode:
# When running in development mode, you must use an https:// url.
# You will need to configure this https:// redirect URI in the Plaid developer dashboard.
# Instructions to create a self-signed certificate for localhost can be found at
# https://github.com/plaid/pattern/blob/master/README.md#testing-oauth.
# If your system is not set up to run localhost with https://, you will be unable to test
# the OAuth in development and should leave the PLAID_DEVELOPMENT_REDIRECT_URI blank.
PLAID_SANDBOX_REDIRECT_URI=
PLAID_DEVELOPMENT_REDIRECT_URI=
# https://docs.lemonsqueezy.com/guides/developer-guide/getting-started#create-an-api-key
LEMONSQUEEZY_API_KEY=
LEMONSQUEEZY_STORE_ID=

View File

@@ -93,17 +93,14 @@ services:
- GOTENBERG_URL=${GOTENBERG_URL}
- GOTENBERG_DOCS_URL=${GOTENBERG_DOCS_URL}
# Exchange Rate
- EXCHANGE_RATE_SERVICE=${EXCHANGE_RATE_SERVICE}
- OPEN_EXCHANGE_RATE_APP_ID-${OPEN_EXCHANGE_RATE_APP_ID}
# Bank Sync
- BANKING_CONNECT=${BANKING_CONNECT}
# Plaid
- PLAID_ENV=${PLAID_ENV}
- PLAID_CLIENT_ID=${PLAID_CLIENT_ID}
- PLAID_SECRET=${PLAID_SECRET}
- PLAID_SECRET_DEVELOPMENT=${PLAID_SECRET_DEVELOPMENT}
- PLAID_SECRET_SANDBOX=${PLAID_SECRET_SANDBOX}
- PLAID_LINK_WEBHOOK=${PLAID_LINK_WEBHOOK}
# Lemon Squeez

View File

@@ -4,16 +4,12 @@ import { Router, Response, NextFunction, Request } from 'express';
import { body, param } from 'express-validator';
import BaseController from '@/api/controllers/BaseController';
import { AttachmentsApplication } from '@/services/Attachments/AttachmentsApplication';
import { AttachmentUploadPipeline } from '@/services/Attachments/S3UploadPipeline';
@Service()
export class AttachmentsController extends BaseController {
@Inject()
private attachmentsApplication: AttachmentsApplication;
@Inject()
private uploadPipelineService: AttachmentUploadPipeline;
/**
* Router constructor.
*/
@@ -22,8 +18,7 @@ export class AttachmentsController extends BaseController {
router.post(
'/',
this.uploadPipelineService.validateS3Configured,
this.uploadPipelineService.uploadPipeline().single('file'),
this.attachmentsApplication.uploadPipeline.single('file'),
this.validateUploadedFileExistance,
this.uploadAttachment.bind(this)
);

View File

@@ -71,10 +71,6 @@ function getAllSystemTenants(knex) {
return knex('tenants');
}
function getAllInitializedSystemTenants(knex) {
return knex('tenants').whereNotNull('initializedAt');
}
// module.exports = {
// log,
// success,
@@ -187,7 +183,7 @@ commander
.action(async (cmd) => {
try {
const sysKnex = await initSystemKnex();
const tenants = await getAllInitializedSystemTenants(sysKnex);
const tenants = await getAllSystemTenants(sysKnex);
const tenantsOrgsIds = tenants.map((tenant) => tenant.organizationId);
if (cmd.tenant_id && tenantsOrgsIds.indexOf(cmd.tenant_id) === -1) {
@@ -224,6 +220,7 @@ commander
const oper = migrateTenant(cmd.tenant_id);
migrateOpers.push(oper);
}
Promise.all(migrateOpers).then(() => {
success('All tenants are migrated.');
});
@@ -283,3 +280,4 @@ commander
exit(error);
}
});

View File

@@ -235,6 +235,6 @@ module.exports = {
accessKeyId: process.env.S3_ACCESS_KEY_ID,
secretAccessKey: process.env.S3_SECRET_ACCESS_KEY,
endpoint: process.env.S3_ENDPOINT,
bucket: process.env.S3_BUCKET || 'bigcapital-documents',
bucket: process.env.S3_BUCKET,
},
};

View File

@@ -1,14 +0,0 @@
exports.up = function (knex) {
return knex.schema.createTable('storage', (table) => {
table.increments('id').primary();
table.string('key').notNullable();
table.string('path').notNullable();
table.string('extension').notNullable();
table.integer('expire_in');
table.timestamps();
});
};
exports.down = function (knex) {
return knex.schema.dropTableIfExists('storage');
};

View File

@@ -1,5 +0,0 @@
exports.up = function (knex) {
return knex.schema.dropTableIfExists('storage');
};
exports.down = function (knex) {};

View File

@@ -2,9 +2,11 @@ import { Inject, Service } from 'typedi';
import { UploadDocument } from './UploadDocument';
import { DeleteAttachment } from './DeleteAttachment';
import { GetAttachment } from './GetAttachment';
import { AttachmentUploadPipeline } from './S3UploadPipeline';
import { LinkAttachment } from './LinkAttachment';
import { UnlinkAttachment } from './UnlinkAttachment';
import { getAttachmentPresignedUrl } from './GetAttachmentPresignedUrl';
import type { Multer } from 'multer';
@Service()
export class AttachmentsApplication {
@@ -17,6 +19,9 @@ export class AttachmentsApplication {
@Inject()
private getDocumentService: GetAttachment;
@Inject()
private uploadPipelineService: AttachmentUploadPipeline;
@Inject()
private linkDocumentService: LinkAttachment;
@@ -26,6 +31,14 @@ export class AttachmentsApplication {
@Inject()
private getPresignedUrlService: getAttachmentPresignedUrl;
/**
* Express middleware for uploading attachments to an S3 bucket.
* @returns {Multer}
*/
get uploadPipeline(): Multer {
return this.uploadPipelineService.uploadPipeline();
}
/**
* Saves the metadata of uploaded document to S3 on database.
* @param {number} tenantId

View File

@@ -1,38 +1,12 @@
import multer from 'multer';
import type { Multer } from 'multer';
import type { Multer } from 'multer'
import multerS3 from 'multer-s3';
import { s3 } from '@/lib/S3/S3';
import { Service } from 'typedi';
import config from '@/config';
import { NextFunction, Request, Response } from 'express';
@Service()
export class AttachmentUploadPipeline {
/**
* Middleware to ensure that S3 configuration is properly set before proceeding.
* This function checks if the necessary S3 configuration keys are present and throws an error if any are missing.
*
* @param req The HTTP request object.
* @param res The HTTP response object.
* @param next The callback to pass control to the next middleware function.
*/
public validateS3Configured(req: Request, res: Response, next: NextFunction) {
if (
!config.s3.region ||
!config.s3.accessKeyId ||
!config.s3.secretAccessKey
) {
const missingKeys = [];
if (!config.s3.region) missingKeys.push('region');
if (!config.s3.accessKeyId) missingKeys.push('accessKeyId');
if (!config.s3.secretAccessKey) missingKeys.push('secretAccessKey');
const missing = missingKeys.join(', ');
throw new Error(`S3 configuration error: Missing ${missing}`);
}
next();
}
/**
* Express middleware for uploading attachments to an S3 bucket.
* It utilizes the multer middleware for handling multipart/form-data, specifically for file uploads.

View File

@@ -42,12 +42,7 @@ export const transformPlaidTrxsToCashflowCreate = R.curry(
): CreateUncategorizedTransactionDTO => {
return {
date: plaidTranasction.date,
// Plaid: Positive values when money moves out of the account; negative values
// when money moves in. For example, debit card purchases are positive;
// credit card payments, direct deposits, and refunds are negative.
amount: -1 * plaidTranasction.amount,
amount: plaidTranasction.amount,
description: plaidTranasction.name,
payee: plaidTranasction.payment_meta?.payee,
currencyCode: plaidTranasction.iso_currency_code,