feat: refactoring middlewares to typescript.

This commit is contained in:
Ahmed Bouhuolia
2020-09-06 23:36:37 +02:00
parent df0f842681
commit d3870974c0
17 changed files with 97 additions and 56 deletions

View File

@@ -139,6 +139,7 @@ export default class AuthenticationController extends BaseController{
const registeredUser: ISystemUser = await this.authService.register(registerDTO);
return res.status(200).send({
type: 'success',
code: 'REGISTER.SUCCESS',
message: 'Register organization has been success.',
});
@@ -153,7 +154,7 @@ export default class AuthenticationController extends BaseController{
errorReasons.push({ type: 'EMAIL.EXISTS', code: 200 });
}
if (errorReasons.length > 0) {
return res.status(200).send({ errors: errorReasons });
return res.boom.badRequest(null, { errors: errorReasons });
}
}
next();

View File

@@ -173,7 +173,6 @@ export default class ItemsController {
const foundItems: [] = await Item.query().onBuild((builder: any) => {
builder.where('name', item.name);
if (itemId) {
builder.whereNot('id', itemId);
}

View File

@@ -33,9 +33,8 @@ import Resources from './controllers/Resources';
import ExchangeRates from '@/http/controllers/ExchangeRates';
import Media from '@/http/controllers/Media';
import Ping from '@/http/controllers/Ping';
import Agendash from '@/http/controllers/Agendash';
import Subscription from '@/http/controllers/Subscription';
import LicensesController from '@/http/controllers/Subscription/Licenses';
import Licenses from '@/http/controllers/Subscription/Licenses';
export default () => {
const app = Router();
@@ -45,11 +44,11 @@ export default () => {
app.use('/auth', Container.get(Authentication).router());
app.use('/invite', Container.get(InviteUsers).nonAuthRouter());
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('/ping', Container.get(Ping).router());
const dashboard = Router();
const dashboard = Router();
dashboard.use(JWTAuth);
dashboard.use(AttachCurrentTenantUser)
@@ -77,9 +76,8 @@ export default () => {
dashboard.use('/purchases', Purchases.router());
dashboard.use('/resources', Resources.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);
return app;

View File

@@ -1,6 +1,7 @@
import { Container } from 'typedi';
import { Request, Response, NextFunction } from 'express';
// eslint-disable-next-line consistent-return
export default async (req, res, next) => {
export default async (req: Request, res: Response, next: NextFunction) => {
const { Option } = req.models;
const option = await Option.query().where('key', 'app_configured');

View File

@@ -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();
};

View 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();
};

View File

@@ -1,8 +1,9 @@
import { Container } from 'typedi';
import { Request, Response, NextFunction } from 'express';
import TenantsManager from '@/system/TenantsManager';
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 organizationId = req.headers['organization-id'] || req.query.organization;

View File

@@ -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;

View 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);
});
};

View File

@@ -1,8 +1,9 @@
import { Request, Response, NextFunction } from 'express';
import { Container } from 'typedi';
import jwt from 'jsonwebtoken';
import config from '@/../config/config';
const authMiddleware = (req, res, next) => {
const authMiddleware = (req: Request, res: Response, next: NextFunction) => {
const Logger = Container.get('logger');
const token = req.headers['x-access-token'] || req.query.token;

View 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,
};

View File

@@ -46,8 +46,15 @@ import {
IOptionDTO,
IOptionsDTO,
} from './Options';
import {
IAccount,
IAccountDTO,
} from './Account';
export {
IAccount,
IAccountDTO,
IBillPaymentEntry,
IBillPayment,
IBillPaymentOTD,

View File

@@ -1,4 +1,4 @@
import express from 'express';
import { json, Request, Response, NextFunction } from 'express';
import helmet from 'helmet';
import boom from 'express-boom';
import errorHandler from 'errorhandler';
@@ -6,6 +6,7 @@ import fileUpload from 'express-fileupload';
import i18n from 'i18n';
import routes from '@/http';
import LoggerMiddleware from '@/http/middleware/LoggerMiddleware';
import AgendashController from '@/http/controllers/Agendash';
import config from '@/../config/config';
export default ({ app }) => {
@@ -22,7 +23,7 @@ export default ({ app }) => {
app.use(boom());
// Parses both json and urlencoded.
app.use(express.json());
app.use(json());
// Handle multi-media requests.
app.use(fileUpload({
@@ -38,8 +39,11 @@ export default ({ app }) => {
// Prefix all application routes.
app.use(config.api.prefix, routes());
// Agendash application load.
app.use('/agendash', AgendashController.router());
// catch 404 and forward to error handler
app.use((req, res, next) => {
app.use((req: Request, res: Response, next: NextFunction) => {
return res.boom.notFound();
})
};

View File

@@ -3,7 +3,6 @@ import TenancyService from '@/services/Tenancy/TenancyService';
import { ServiceError } from '@/exceptions';
import { IAccountDTO, IAccount } from '@/interfaces';
import { difference } from 'lodash';
import { tenant } from 'config/config';
@Service()
export default class AccountsService {
@@ -137,6 +136,7 @@ export default class AccountsService {
public async newAccount(tenantId: number, accountDTO: IAccountDTO) {
const { Account } = this.tenancy.models(tenantId);
// Validate the account code uniquiness.
if (accountDTO.code) {
await this.isAccountCodeUniqueOrThrowError(tenantId, accountDTO.code);
}

View File

@@ -126,7 +126,7 @@ export default class AuthenticationService {
this.logger.info('[register] Someone trying to register.');
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();
this.logger.info('[register] Trying hashing the password.')

View File

@@ -3,7 +3,6 @@ import TenancyService from '@/services/Tenancy/TenancyService';
import { SystemUser } from "@/system/models";
import { ServiceError, ServiceErrors } from "@/exceptions";
import { ISystemUser, ISystemUserDTO } from "@/interfaces";
import { ISystemUser } from "src/interfaces";
@Service()
export default class UsersService {
@@ -20,9 +19,9 @@ export default class UsersService {
async editUser(tenantId: number, userId: number, userDTO: ISystemUserDTO): Promise<ISystemUser> {
const foundUsers = await SystemUser.query()
.whereNot('id', userId)
.andWhere((q) => {
q.where('email', userDTO.email);
q.orWhere('phone_number', userDTO.phoneNumber);
.andWhere((query) => {
query.where('email', userDTO.email);
query.orWhere('phone_number', userDTO.phoneNumber);
})
.where('tenant_id', tenantId);