mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-19 14:20:31 +00:00
feat: refactoring middlewares to typescript.
This commit is contained in:
@@ -139,6 +139,7 @@ export default class AuthenticationController extends BaseController{
|
|||||||
const registeredUser: ISystemUser = await this.authService.register(registerDTO);
|
const registeredUser: ISystemUser = await this.authService.register(registerDTO);
|
||||||
|
|
||||||
return res.status(200).send({
|
return res.status(200).send({
|
||||||
|
type: 'success',
|
||||||
code: 'REGISTER.SUCCESS',
|
code: 'REGISTER.SUCCESS',
|
||||||
message: 'Register organization has been success.',
|
message: 'Register organization has been success.',
|
||||||
});
|
});
|
||||||
@@ -153,7 +154,7 @@ export default class AuthenticationController extends BaseController{
|
|||||||
errorReasons.push({ type: 'EMAIL.EXISTS', code: 200 });
|
errorReasons.push({ type: 'EMAIL.EXISTS', code: 200 });
|
||||||
}
|
}
|
||||||
if (errorReasons.length > 0) {
|
if (errorReasons.length > 0) {
|
||||||
return res.status(200).send({ errors: errorReasons });
|
return res.boom.badRequest(null, { errors: errorReasons });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
next();
|
next();
|
||||||
|
|||||||
@@ -173,7 +173,6 @@ export default class ItemsController {
|
|||||||
|
|
||||||
const foundItems: [] = await Item.query().onBuild((builder: any) => {
|
const foundItems: [] = await Item.query().onBuild((builder: any) => {
|
||||||
builder.where('name', item.name);
|
builder.where('name', item.name);
|
||||||
|
|
||||||
if (itemId) {
|
if (itemId) {
|
||||||
builder.whereNot('id', itemId);
|
builder.whereNot('id', itemId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,9 +33,8 @@ import Resources from './controllers/Resources';
|
|||||||
import ExchangeRates from '@/http/controllers/ExchangeRates';
|
import ExchangeRates from '@/http/controllers/ExchangeRates';
|
||||||
import Media from '@/http/controllers/Media';
|
import Media from '@/http/controllers/Media';
|
||||||
import Ping from '@/http/controllers/Ping';
|
import Ping from '@/http/controllers/Ping';
|
||||||
import Agendash from '@/http/controllers/Agendash';
|
|
||||||
import Subscription from '@/http/controllers/Subscription';
|
import Subscription from '@/http/controllers/Subscription';
|
||||||
import LicensesController from '@/http/controllers/Subscription/Licenses';
|
import Licenses from '@/http/controllers/Subscription/Licenses';
|
||||||
|
|
||||||
export default () => {
|
export default () => {
|
||||||
const app = Router();
|
const app = Router();
|
||||||
@@ -45,11 +44,11 @@ export default () => {
|
|||||||
app.use('/auth', Container.get(Authentication).router());
|
app.use('/auth', Container.get(Authentication).router());
|
||||||
app.use('/invite', Container.get(InviteUsers).nonAuthRouter());
|
app.use('/invite', Container.get(InviteUsers).nonAuthRouter());
|
||||||
app.use('/organization', Container.get(Organization).router());
|
app.use('/organization', Container.get(Organization).router());
|
||||||
app.use('/licenses', Container.get(LicensesController).router());
|
app.use('/licenses', Container.get(Licenses).router());
|
||||||
app.use('/subscription', Container.get(Subscription).router());
|
app.use('/subscription', Container.get(Subscription).router());
|
||||||
app.use('/ping', Container.get(Ping).router());
|
app.use('/ping', Container.get(Ping).router());
|
||||||
|
|
||||||
const dashboard = Router();
|
const dashboard = Router();
|
||||||
|
|
||||||
dashboard.use(JWTAuth);
|
dashboard.use(JWTAuth);
|
||||||
dashboard.use(AttachCurrentTenantUser)
|
dashboard.use(AttachCurrentTenantUser)
|
||||||
@@ -77,9 +76,8 @@ export default () => {
|
|||||||
dashboard.use('/purchases', Purchases.router());
|
dashboard.use('/purchases', Purchases.router());
|
||||||
dashboard.use('/resources', Resources.router());
|
dashboard.use('/resources', Resources.router());
|
||||||
dashboard.use('/exchange_rates', ExchangeRates.router());
|
dashboard.use('/exchange_rates', ExchangeRates.router());
|
||||||
dashboard.use('/media', Media.router());
|
dashboard.use('/media', Media.router())
|
||||||
|
|
||||||
app.use('/agendash', Agendash.router());
|
|
||||||
app.use('/', dashboard);
|
app.use('/', dashboard);
|
||||||
|
|
||||||
return app;
|
return app;
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
|
import { Container } from 'typedi';
|
||||||
|
import { Request, Response, NextFunction } from 'express';
|
||||||
|
|
||||||
// eslint-disable-next-line consistent-return
|
export default async (req: Request, res: Response, next: NextFunction) => {
|
||||||
export default async (req, res, next) => {
|
|
||||||
const { Option } = req.models;
|
const { Option } = req.models;
|
||||||
const option = await Option.query().where('key', 'app_configured');
|
const option = await Option.query().where('key', 'app_configured');
|
||||||
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
|
|
||||||
export default (subscriptionSlug = 'main') => async (req, res, next) => {
|
|
||||||
const { tenant } = req;
|
|
||||||
|
|
||||||
if (!tenant) {
|
|
||||||
throw new Error('Should load `TenancyMiddlware` before this middleware.');
|
|
||||||
}
|
|
||||||
const subscription = await tenant
|
|
||||||
.$relatedQuery('subscriptions')
|
|
||||||
.modify('subscriptionBySlug', subscriptionSlug)
|
|
||||||
.first();
|
|
||||||
|
|
||||||
// Validate in case there is no any already subscription.
|
|
||||||
if (!subscription) {
|
|
||||||
return res.status(400).send({
|
|
||||||
errors: [{ type: 'TENANT.HAS.NO.SUBSCRIPTION' }],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// Validate in case the subscription is inactive.
|
|
||||||
else if (subscription.inactive()) {
|
|
||||||
return res.status(400).send({
|
|
||||||
errors: [{ type: 'ORGANIZATION.SUBSCRIPTION.INACTIVE' }],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
next();
|
|
||||||
};
|
|
||||||
33
server/src/http/middleware/SubscriptionMiddleware.ts
Normal file
33
server/src/http/middleware/SubscriptionMiddleware.ts
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
import { Request, Response, NextFunction } from 'express';
|
||||||
|
import { Container } from 'typedi';
|
||||||
|
|
||||||
|
export default (subscriptionSlug = 'main') => async (req: Request, res: Response, next: NextFunction) => {
|
||||||
|
const { tenant, tenantId } = req;
|
||||||
|
const Logger = Container.get('logger');
|
||||||
|
|
||||||
|
if (!tenant) {
|
||||||
|
throw new Error('Should load `TenancyMiddlware` before this middleware.');
|
||||||
|
}
|
||||||
|
Logger.info('[subscription_middleware] trying get tenant main subscription.');
|
||||||
|
const subscription = await tenant
|
||||||
|
.$relatedQuery('subscriptions')
|
||||||
|
.modify('subscriptionBySlug', subscriptionSlug)
|
||||||
|
.first();
|
||||||
|
|
||||||
|
// Validate in case there is no any already subscription.
|
||||||
|
if (!subscription) {
|
||||||
|
Logger.info('[subscription_middleware] tenant has no subscription.', { tenantId });
|
||||||
|
return res.boom.badRequest(
|
||||||
|
'Tenant has no subscription.',
|
||||||
|
{ errors: [{ type: 'TENANT.HAS.NO.SUBSCRIPTION' }] }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// Validate in case the subscription is inactive.
|
||||||
|
else if (subscription.inactive()) {
|
||||||
|
Logger.info('[subscription_middleware] tenant main subscription is expired.', { tenantId });
|
||||||
|
return res.boom.badRequest(null, {
|
||||||
|
errors: [{ type: 'ORGANIZATION.SUBSCRIPTION.INACTIVE' }],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
next();
|
||||||
|
};
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
import { Container } from 'typedi';
|
import { Container } from 'typedi';
|
||||||
|
import { Request, Response, NextFunction } from 'express';
|
||||||
import TenantsManager from '@/system/TenantsManager';
|
import TenantsManager from '@/system/TenantsManager';
|
||||||
import tenantModelsLoader from '@/loaders/tenantModels';
|
import tenantModelsLoader from '@/loaders/tenantModels';
|
||||||
|
|
||||||
export default async (req, res, next) => {
|
export default async (req: Request, res: Response, next: NextFunction) => {
|
||||||
const Logger = Container.get('logger');
|
const Logger = Container.get('logger');
|
||||||
const organizationId = req.headers['organization-id'] || req.query.organization;
|
const organizationId = req.headers['organization-id'] || req.query.organization;
|
||||||
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
const asyncMiddleware = (fn) => (req, res, next) => {
|
|
||||||
Promise.resolve(fn(req, res, next))
|
|
||||||
.catch((error) => {
|
|
||||||
console.log(error);
|
|
||||||
next(error);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export default asyncMiddleware;
|
|
||||||
17
server/src/http/middleware/asyncMiddleware.ts
Normal file
17
server/src/http/middleware/asyncMiddleware.ts
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import logger from "src/loaders/logger";
|
||||||
|
|
||||||
|
import { Request, Response, NextFunction } from 'express';
|
||||||
|
import { Container } from 'typedi';
|
||||||
|
|
||||||
|
export default (
|
||||||
|
fn: (rq: Request, rs: Response, next?: NextFunction) => {}) =>
|
||||||
|
(req: Request, res: Response, next: NextFunction) => {
|
||||||
|
const Logger = Container.get('logger');
|
||||||
|
|
||||||
|
Promise.resolve(fn(req, res, next))
|
||||||
|
.catch((error) => {
|
||||||
|
console.log(error);
|
||||||
|
Logger.error('[async_middleware] error.', { error });
|
||||||
|
next(error);
|
||||||
|
});
|
||||||
|
};
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
|
import { Request, Response, NextFunction } from 'express';
|
||||||
import { Container } from 'typedi';
|
import { Container } from 'typedi';
|
||||||
import jwt from 'jsonwebtoken';
|
import jwt from 'jsonwebtoken';
|
||||||
import config from '@/../config/config';
|
import config from '@/../config/config';
|
||||||
|
|
||||||
const authMiddleware = (req, res, next) => {
|
const authMiddleware = (req: Request, res: Response, next: NextFunction) => {
|
||||||
const Logger = Container.get('logger');
|
const Logger = Container.get('logger');
|
||||||
const token = req.headers['x-access-token'] || req.query.token;
|
const token = req.headers['x-access-token'] || req.query.token;
|
||||||
|
|
||||||
15
server/src/interfaces/Account.ts
Normal file
15
server/src/interfaces/Account.ts
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
|
||||||
|
|
||||||
|
export interface IAccountDTO {
|
||||||
|
name: string,
|
||||||
|
code: string,
|
||||||
|
description: string,
|
||||||
|
accountTypeNumber: number,
|
||||||
|
};
|
||||||
|
|
||||||
|
export interface IAccount {
|
||||||
|
name: string,
|
||||||
|
code: string,
|
||||||
|
description: string,
|
||||||
|
accountTypeNumber: number,
|
||||||
|
};
|
||||||
@@ -46,8 +46,15 @@ import {
|
|||||||
IOptionDTO,
|
IOptionDTO,
|
||||||
IOptionsDTO,
|
IOptionsDTO,
|
||||||
} from './Options';
|
} from './Options';
|
||||||
|
import {
|
||||||
|
IAccount,
|
||||||
|
IAccountDTO,
|
||||||
|
} from './Account';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
IAccount,
|
||||||
|
IAccountDTO,
|
||||||
|
|
||||||
IBillPaymentEntry,
|
IBillPaymentEntry,
|
||||||
IBillPayment,
|
IBillPayment,
|
||||||
IBillPaymentOTD,
|
IBillPaymentOTD,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import express from 'express';
|
import { json, Request, Response, NextFunction } from 'express';
|
||||||
import helmet from 'helmet';
|
import helmet from 'helmet';
|
||||||
import boom from 'express-boom';
|
import boom from 'express-boom';
|
||||||
import errorHandler from 'errorhandler';
|
import errorHandler from 'errorhandler';
|
||||||
@@ -6,6 +6,7 @@ import fileUpload from 'express-fileupload';
|
|||||||
import i18n from 'i18n';
|
import i18n from 'i18n';
|
||||||
import routes from '@/http';
|
import routes from '@/http';
|
||||||
import LoggerMiddleware from '@/http/middleware/LoggerMiddleware';
|
import LoggerMiddleware from '@/http/middleware/LoggerMiddleware';
|
||||||
|
import AgendashController from '@/http/controllers/Agendash';
|
||||||
import config from '@/../config/config';
|
import config from '@/../config/config';
|
||||||
|
|
||||||
export default ({ app }) => {
|
export default ({ app }) => {
|
||||||
@@ -22,7 +23,7 @@ export default ({ app }) => {
|
|||||||
app.use(boom());
|
app.use(boom());
|
||||||
|
|
||||||
// Parses both json and urlencoded.
|
// Parses both json and urlencoded.
|
||||||
app.use(express.json());
|
app.use(json());
|
||||||
|
|
||||||
// Handle multi-media requests.
|
// Handle multi-media requests.
|
||||||
app.use(fileUpload({
|
app.use(fileUpload({
|
||||||
@@ -38,8 +39,11 @@ export default ({ app }) => {
|
|||||||
// Prefix all application routes.
|
// Prefix all application routes.
|
||||||
app.use(config.api.prefix, routes());
|
app.use(config.api.prefix, routes());
|
||||||
|
|
||||||
|
// Agendash application load.
|
||||||
|
app.use('/agendash', AgendashController.router());
|
||||||
|
|
||||||
// catch 404 and forward to error handler
|
// catch 404 and forward to error handler
|
||||||
app.use((req, res, next) => {
|
app.use((req: Request, res: Response, next: NextFunction) => {
|
||||||
return res.boom.notFound();
|
return res.boom.notFound();
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
@@ -3,7 +3,6 @@ import TenancyService from '@/services/Tenancy/TenancyService';
|
|||||||
import { ServiceError } from '@/exceptions';
|
import { ServiceError } from '@/exceptions';
|
||||||
import { IAccountDTO, IAccount } from '@/interfaces';
|
import { IAccountDTO, IAccount } from '@/interfaces';
|
||||||
import { difference } from 'lodash';
|
import { difference } from 'lodash';
|
||||||
import { tenant } from 'config/config';
|
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export default class AccountsService {
|
export default class AccountsService {
|
||||||
@@ -137,6 +136,7 @@ export default class AccountsService {
|
|||||||
public async newAccount(tenantId: number, accountDTO: IAccountDTO) {
|
public async newAccount(tenantId: number, accountDTO: IAccountDTO) {
|
||||||
const { Account } = this.tenancy.models(tenantId);
|
const { Account } = this.tenancy.models(tenantId);
|
||||||
|
|
||||||
|
// Validate the account code uniquiness.
|
||||||
if (accountDTO.code) {
|
if (accountDTO.code) {
|
||||||
await this.isAccountCodeUniqueOrThrowError(tenantId, accountDTO.code);
|
await this.isAccountCodeUniqueOrThrowError(tenantId, accountDTO.code);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ export default class AuthenticationService {
|
|||||||
this.logger.info('[register] Someone trying to register.');
|
this.logger.info('[register] Someone trying to register.');
|
||||||
await this.validateEmailAndPhoneUniqiness(registerDTO);
|
await this.validateEmailAndPhoneUniqiness(registerDTO);
|
||||||
|
|
||||||
this.logger.info('[register] Creating a new tenant org.')
|
this.logger.info('[register] Creating a new tenant organization.')
|
||||||
const tenant = await this.newTenantOrganization();
|
const tenant = await this.newTenantOrganization();
|
||||||
|
|
||||||
this.logger.info('[register] Trying hashing the password.')
|
this.logger.info('[register] Trying hashing the password.')
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import TenancyService from '@/services/Tenancy/TenancyService';
|
|||||||
import { SystemUser } from "@/system/models";
|
import { SystemUser } from "@/system/models";
|
||||||
import { ServiceError, ServiceErrors } from "@/exceptions";
|
import { ServiceError, ServiceErrors } from "@/exceptions";
|
||||||
import { ISystemUser, ISystemUserDTO } from "@/interfaces";
|
import { ISystemUser, ISystemUserDTO } from "@/interfaces";
|
||||||
import { ISystemUser } from "src/interfaces";
|
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export default class UsersService {
|
export default class UsersService {
|
||||||
@@ -20,9 +19,9 @@ export default class UsersService {
|
|||||||
async editUser(tenantId: number, userId: number, userDTO: ISystemUserDTO): Promise<ISystemUser> {
|
async editUser(tenantId: number, userId: number, userDTO: ISystemUserDTO): Promise<ISystemUser> {
|
||||||
const foundUsers = await SystemUser.query()
|
const foundUsers = await SystemUser.query()
|
||||||
.whereNot('id', userId)
|
.whereNot('id', userId)
|
||||||
.andWhere((q) => {
|
.andWhere((query) => {
|
||||||
q.where('email', userDTO.email);
|
query.where('email', userDTO.email);
|
||||||
q.orWhere('phone_number', userDTO.phoneNumber);
|
query.orWhere('phone_number', userDTO.phoneNumber);
|
||||||
})
|
})
|
||||||
.where('tenant_id', tenantId);
|
.where('tenant_id', tenantId);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user