mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-18 13:50:31 +00:00
WIP Items module.
This commit is contained in:
115
server/src/http/controllers/Accounts.js
Normal file
115
server/src/http/controllers/Accounts.js
Normal file
@@ -0,0 +1,115 @@
|
||||
import express from 'express';
|
||||
import { check, validationResult } from 'express-validator';
|
||||
import asyncMiddleware from '../middleware/asyncMiddleware';
|
||||
import Account from '@/models/Account';
|
||||
import AccountBalance from '@/models/AccountBalance';
|
||||
import AccountType from '@/models/AccountType';
|
||||
import JWTAuth from '@/http/middleware/jwtAuth';
|
||||
|
||||
export default {
|
||||
/**
|
||||
* Router constructor method.
|
||||
*/
|
||||
router() {
|
||||
const router = express.Router();
|
||||
|
||||
router.use(JWTAuth);
|
||||
router.post('/',
|
||||
this.newAccount.validation,
|
||||
asyncMiddleware(this.newAccount.handler));
|
||||
|
||||
router.get('/:id',
|
||||
this.getAccount.validation,
|
||||
asyncMiddleware(this.getAccount.handler));
|
||||
|
||||
router.delete('/:id',
|
||||
this.deleteAccount.validation,
|
||||
asyncMiddleware(this.deleteAccount.handler));
|
||||
|
||||
return router;
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates a new account.
|
||||
*/
|
||||
newAccount: {
|
||||
validation: [
|
||||
check('name').isLength({ min: 3 }).trim().escape(),
|
||||
check('code').isLength({ max: 10 }).trim().escape(),
|
||||
check('type_id').isNumeric().toInt(),
|
||||
check('description').trim().escape(),
|
||||
],
|
||||
async handler(req, res) {
|
||||
const errors = validationResult(req);
|
||||
|
||||
if (!errors.isEmpty()) {
|
||||
return res.status(422).json({ errors: errors.array() });
|
||||
}
|
||||
|
||||
const { name, code, description } = req.body;
|
||||
const { type_id: typeId } = req.body;
|
||||
|
||||
const foundAccountCodePromise = Account.where('code', code).fetch();
|
||||
const foundAccountTypePromise = AccountType.where('id', typeId).fetch();
|
||||
|
||||
const [foundAccountCode, foundAccountType] = await Promise.all([
|
||||
foundAccountCodePromise,
|
||||
foundAccountTypePromise,
|
||||
]);
|
||||
|
||||
if (!foundAccountCode) {
|
||||
return res.boom.badRequest(null, {
|
||||
errors: [{ type: 'NOT_UNIQUE_CODE', code: 100 }],
|
||||
});
|
||||
}
|
||||
if (!foundAccountType) {
|
||||
return res.boom.badRequest(null, {
|
||||
errors: [{ type: 'NOT_EXIST_ACCOUNT_TYPE', code: 110 }],
|
||||
});
|
||||
}
|
||||
const account = Account.forge({
|
||||
name, code, type_id: typeId, description,
|
||||
});
|
||||
|
||||
await account.save();
|
||||
return res.boom.success({ item: { ...account.attributes } });
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* Get details of the given account.
|
||||
*/
|
||||
getAccount: {
|
||||
valiation: [],
|
||||
async handler(req, res) {
|
||||
const { id } = req.params;
|
||||
const account = await Account.where('id', id).fetch();
|
||||
|
||||
if (!account) {
|
||||
return res.boom.notFound();
|
||||
}
|
||||
|
||||
return res.status(200).send({ item: { ...account.attributes } });
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* Delete the given account.
|
||||
*/
|
||||
deleteAccount: {
|
||||
validation: [],
|
||||
async handler(req, res) {
|
||||
const { id } = req.params;
|
||||
const account = await Account.where('id', id).fetch();
|
||||
|
||||
if (!account) {
|
||||
return res.boom.notFound();
|
||||
}
|
||||
|
||||
await account.destroy();
|
||||
await AccountBalance.where('account_id', id).destroy({ require: false });
|
||||
|
||||
return res.status(200).send({ id: account.previous('id') });
|
||||
},
|
||||
},
|
||||
};
|
||||
184
server/src/http/controllers/Authentication.js
Normal file
184
server/src/http/controllers/Authentication.js
Normal file
@@ -0,0 +1,184 @@
|
||||
|
||||
import express from 'express';
|
||||
import { check, validationResult } from 'express-validator';
|
||||
import path from 'path';
|
||||
import fs from 'fs';
|
||||
import Mustache from 'mustache';
|
||||
import User from '@/models/User';
|
||||
import asyncMiddleware from '../middleware/asyncMiddleware';
|
||||
import PasswordReset from '@/models/PasswordReset';
|
||||
import mail from '@/services/mail';
|
||||
import { hashPassword } from '@/utils';
|
||||
|
||||
export default {
|
||||
/**
|
||||
* Constructor method.
|
||||
*/
|
||||
router() {
|
||||
const router = express.Router();
|
||||
|
||||
router.post('/login',
|
||||
this.login.validation,
|
||||
asyncMiddleware(this.login.handler));
|
||||
|
||||
router.post('/send_reset_password',
|
||||
this.sendResetPassword.validation,
|
||||
asyncMiddleware(this.sendResetPassword.handler));
|
||||
|
||||
router.post('/reset/:token',
|
||||
this.resetPassword.validation,
|
||||
asyncMiddleware(this.resetPassword.handler));
|
||||
|
||||
return router;
|
||||
},
|
||||
|
||||
/**
|
||||
* User login authentication request.
|
||||
*/
|
||||
login: {
|
||||
validation: [
|
||||
check('crediential').isEmail(),
|
||||
check('password').isLength({ min: 5 }),
|
||||
],
|
||||
async handler(req, res) {
|
||||
const validationErrors = validationResult(req);
|
||||
|
||||
if (!validationErrors.isEmpty()) {
|
||||
return res.boom.badData(null, {
|
||||
code: 'validation_error',
|
||||
...validationErrors,
|
||||
});
|
||||
}
|
||||
const { crediential, password } = req.body;
|
||||
|
||||
const user = await User.query({
|
||||
where: { email: crediential },
|
||||
orWhere: { phone_number: crediential },
|
||||
}).fetch();
|
||||
|
||||
if (!user) {
|
||||
return res.boom.badRequest(null, {
|
||||
errors: [{ type: 'INVALID_DETAILS', code: 100 }],
|
||||
});
|
||||
}
|
||||
if (!user.verifyPassword(password)) {
|
||||
return res.boom.badRequest(null, {
|
||||
errors: [{ type: 'INCORRECT_PASSWORD', code: 110 }],
|
||||
});
|
||||
}
|
||||
if (!user.attributes.active) {
|
||||
return res.boom.badRequest(null, {
|
||||
errors: [{ type: 'USER_INACTIVE', code: 120 }],
|
||||
});
|
||||
}
|
||||
user.save({ alst_login_at: new Date() });
|
||||
return res.status(200).send({});
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* Send reset password link via email or SMS.
|
||||
*/
|
||||
sendResetPassword: {
|
||||
validation: [
|
||||
check('email').isEmail(),
|
||||
],
|
||||
// eslint-disable-next-line consistent-return
|
||||
async handler(req, res) {
|
||||
const errors = validationResult(req);
|
||||
|
||||
if (!errors.isEmpty()) {
|
||||
return res.status(422).json({ errors: errors.array() });
|
||||
}
|
||||
const { email } = req.body;
|
||||
const user = User.where('email').fetch();
|
||||
|
||||
if (!user) {
|
||||
return res.status(422).send();
|
||||
}
|
||||
// Delete all stored tokens of reset password that associate to the give email.
|
||||
await PasswordReset.where({ email }).destroy({ require: false });
|
||||
|
||||
const passwordReset = PasswordReset.forge({
|
||||
email,
|
||||
token: '123123',
|
||||
});
|
||||
|
||||
await passwordReset.save();
|
||||
|
||||
const filePath = path.join(__dirname, '../../views/mail/ResetPassword.html');
|
||||
const template = fs.readFileSync(filePath, 'utf8');
|
||||
const rendered = Mustache.render(template, {
|
||||
url: `${req.protocol}://${req.hostname}/reset/${passwordReset.attributes.token}`,
|
||||
first_name: user.attributes.first_name,
|
||||
last_name: user.attributes.last_name,
|
||||
contact_us_email: process.env.CONTACT_US_EMAIL,
|
||||
});
|
||||
|
||||
const mailOptions = {
|
||||
to: user.attributes.email,
|
||||
from: `${process.env.MAIL_FROM_NAME} ${process.env.MAIL_FROM_ADDRESS}`,
|
||||
subject: 'Ratteb Password Reset',
|
||||
html: rendered,
|
||||
};
|
||||
|
||||
// eslint-disable-next-line consistent-return
|
||||
mail.sendMail(mailOptions, (error) => {
|
||||
if (error) {
|
||||
return res.status(400).send();
|
||||
}
|
||||
res.status(200).send({ data: { email: passwordReset.attributes.email } });
|
||||
});
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* Reset password.
|
||||
*/
|
||||
resetPassword: {
|
||||
validation: [
|
||||
check('password').isLength({ min: 5 }),
|
||||
check('reset_password'),
|
||||
],
|
||||
async handler(req, res) {
|
||||
const errors = validationResult(req);
|
||||
|
||||
if (!errors.isEmpty()) {
|
||||
return res.status(422).json({ errors: errors.array() });
|
||||
}
|
||||
const { token } = req.params;
|
||||
const { password } = req.body;
|
||||
|
||||
const tokenModel = await PasswordReset.query((query) => {
|
||||
query.where({ token });
|
||||
query.where('created_at', '>=', Date.now() - 3600000);
|
||||
}).fetch();
|
||||
|
||||
if (!tokenModel) {
|
||||
return res.status(400).send({
|
||||
error: {
|
||||
type: 'token.invalid',
|
||||
message: 'Password reset token is invalid or has expired',
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const user = await User.where({
|
||||
email: tokenModel.attributes.email,
|
||||
});
|
||||
if (!user) {
|
||||
return res.status(400).send({
|
||||
error: { message: 'An unexpected error occurred.' },
|
||||
});
|
||||
}
|
||||
const hashedPassword = await hashPassword(password);
|
||||
|
||||
user.set('password', hashedPassword);
|
||||
await user.save();
|
||||
|
||||
await PasswordReset.where('email', user.get('email')).destroy({ require: false });
|
||||
|
||||
return res.status(200).send({});
|
||||
},
|
||||
},
|
||||
};
|
||||
154
server/src/http/controllers/ItemCategories.js
Normal file
154
server/src/http/controllers/ItemCategories.js
Normal file
@@ -0,0 +1,154 @@
|
||||
import express from 'express';
|
||||
import { check, validationResult } from 'express-validator';
|
||||
import asyncMiddleware from '../middleware/asyncMiddleware';
|
||||
import ItemCategory from '@/models/ItemCategory';
|
||||
// import JWTAuth from '@/http/middleware/jwtAuth';
|
||||
|
||||
export default {
|
||||
/**
|
||||
* Router constructor method.
|
||||
*/
|
||||
router() {
|
||||
const router = express.Router();
|
||||
|
||||
router.post('/:id',
|
||||
this.editCategory.validation,
|
||||
asyncMiddleware(this.editCategory.handler));
|
||||
|
||||
router.post('/',
|
||||
this.newCategory.validation,
|
||||
asyncMiddleware(this.newCategory.handler));
|
||||
|
||||
router.delete('/:id',
|
||||
this.deleteItem.validation,
|
||||
asyncMiddleware(this.deleteItem.handler));
|
||||
|
||||
// router.get('/:id',
|
||||
// this.getCategory.validation,
|
||||
// asyncMiddleware(this.getCategory.handler));
|
||||
|
||||
router.get('/',
|
||||
this.getList.validation,
|
||||
asyncMiddleware(this.getList.validation));
|
||||
|
||||
return router;
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates a new item category.
|
||||
*/
|
||||
newCategory: {
|
||||
validation: [
|
||||
check('name').exists({ checkFalsy: true }).trim().escape(),
|
||||
check('parent_category_id').optional().isNumeric().toInt(),
|
||||
check('description').optional().trim().escape(),
|
||||
],
|
||||
async handler(req, res) {
|
||||
const validationErrors = validationResult(req);
|
||||
|
||||
if (!validationErrors.isEmpty()) {
|
||||
return res.boom.badData(null, {
|
||||
code: 'validation_error', ...validationErrors,
|
||||
});
|
||||
}
|
||||
|
||||
const { name, parent_category_id: parentCategoryId, description } = req.body;
|
||||
|
||||
if (parentCategoryId) {
|
||||
const foundParentCategory = await ItemCategory.where('id', parentCategoryId).fetch();
|
||||
|
||||
if (!foundParentCategory) {
|
||||
return res.boom.notFound('The parent category ID is not found.', {
|
||||
errors: [{ type: 'PARENT_CATEGORY_NOT_FOUND', code: 100 }],
|
||||
});
|
||||
}
|
||||
}
|
||||
const category = await ItemCategory.forge({
|
||||
label: name,
|
||||
parent_category_id: parentCategoryId,
|
||||
description,
|
||||
});
|
||||
|
||||
await category.save();
|
||||
return res.status(200).send({ id: category.get('id') });
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* Edit details of the given category item.
|
||||
*/
|
||||
editCategory: {
|
||||
validation: [
|
||||
check('name').exists({ checkFalsy: true }).trim().escape(),
|
||||
check('parent_category_id').optional().isNumeric().toInt(),
|
||||
check('description').optional().trim().escape(),
|
||||
],
|
||||
async handler(req, res) {
|
||||
const { id } = req.params;
|
||||
const validationErrors = validationResult(req);
|
||||
|
||||
if (!validationErrors.isEmpty()) {
|
||||
return res.boom.badData(null, {
|
||||
code: 'validation_error', ...validationErrors,
|
||||
});
|
||||
}
|
||||
const { name, parent_category_id: parentCategoryId, description } = req.body;
|
||||
|
||||
const itemCategory = await ItemCategory.where('id', id).fetch();
|
||||
|
||||
if (!itemCategory) {
|
||||
return res.boom.notFound();
|
||||
}
|
||||
|
||||
if (parentCategoryId && parentCategoryId !== itemCategory.attributes.parent_category_id) {
|
||||
const foundParentCategory = await ItemCategory.where('id', parentCategoryId).fetch();
|
||||
|
||||
if (!foundParentCategory) {
|
||||
return res.boom.notFound('The parent category ID is not found.', {
|
||||
errors: [{ type: 'PARENT_CATEGORY_NOT_FOUND', code: 100 }],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
await itemCategory.save({
|
||||
label: name,
|
||||
description,
|
||||
parent_category_id: parentCategoryId,
|
||||
});
|
||||
|
||||
return res.status(200).send({ id: itemCategory.id });
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* Delete the give item category.
|
||||
*/
|
||||
deleteItem: {
|
||||
validation: [],
|
||||
async handler(req, res) {
|
||||
const { id } = req.params;
|
||||
const itemCategory = await ItemCategory.where('id', id).fetch();
|
||||
|
||||
if (!itemCategory) {
|
||||
return res.boom.notFound();
|
||||
}
|
||||
await itemCategory.destroy();
|
||||
return res.status(200).send();
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* Retrieve the list of items.
|
||||
*/
|
||||
getList: {
|
||||
validation: [],
|
||||
async handler(req, res) {
|
||||
const items = await ItemCategory.fetch();
|
||||
|
||||
if (!items) {
|
||||
return res.boom.notFound();
|
||||
}
|
||||
return res.status(200).send({ items: items.toJSON() });
|
||||
},
|
||||
},
|
||||
};
|
||||
190
server/src/http/controllers/Items.js
Normal file
190
server/src/http/controllers/Items.js
Normal file
@@ -0,0 +1,190 @@
|
||||
import express from 'express';
|
||||
import { check, validationResult } from 'express-validator';
|
||||
import moment from 'moment';
|
||||
import asyncMiddleware from '../middleware/asyncMiddleware';
|
||||
import Item from '@/models/Item';
|
||||
import Account from '@/models/Account';
|
||||
import ItemCategory from '@/models/ItemCategory';
|
||||
|
||||
export default {
|
||||
|
||||
router() {
|
||||
const router = express.Router();
|
||||
|
||||
// router.post('/:id',
|
||||
// this.editItem.validation,
|
||||
// asyncMiddleware(this.editCategory.handler));
|
||||
|
||||
router.post('/',
|
||||
this.newItem.validation,
|
||||
asyncMiddleware(this.newItem.handler));
|
||||
|
||||
// router.delete('/:id',
|
||||
// this.deleteItem.validation,
|
||||
// asyncMiddleware(this.deleteItem.handler));
|
||||
|
||||
// router.get('/:id',
|
||||
// this.getCategory.validation,
|
||||
// asyncMiddleware(this.getCategory.handler));
|
||||
|
||||
// router.get('/',
|
||||
// this.categoriesList.validation,
|
||||
// asyncMiddleware(this.categoriesList.validation));
|
||||
|
||||
return router;
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates a new item.
|
||||
*/
|
||||
newItem: {
|
||||
validation: [
|
||||
check('name').exists(),
|
||||
check('type_id').exists().isInt(),
|
||||
check('buy_price').exists().isNumeric(),
|
||||
check('cost_price').exists().isNumeric(),
|
||||
check('cost_account_id').exists().isInt(),
|
||||
check('sell_account_id').exists().isInt(),
|
||||
check('category_id').optional().isInt(),
|
||||
check('note').optional(),
|
||||
],
|
||||
async handler(req, res) {
|
||||
const validationErrors = validationResult(req);
|
||||
|
||||
if (!validationErrors.isEmpty()) {
|
||||
return res.boom.badData(null, {
|
||||
code: 'validation_error', ...validationErrors,
|
||||
});
|
||||
}
|
||||
|
||||
const { sell_account_id: sellAccountId, cost_account_id: costAccountId } = req.body;
|
||||
const { category_id: categoryId } = req.body;
|
||||
|
||||
const costAccountPromise = Account.where('id', costAccountId).fetch();
|
||||
const sellAccountPromise = Account.where('id', sellAccountId).fetch();
|
||||
const itemCategoryPromise = (categoryId)
|
||||
? ItemCategory.where('id', categoryId).fetch() : null;
|
||||
|
||||
const [costAccount, sellAccount, itemCategory] = await Promise.all([
|
||||
costAccountPromise, sellAccountPromise, itemCategoryPromise,
|
||||
]);
|
||||
|
||||
const errorReasons = [];
|
||||
|
||||
if (!costAccount) {
|
||||
errorReasons.push({ type: 'COST_ACCOUNT_NOT_FOUND', code: 100 });
|
||||
}
|
||||
if (!sellAccount) {
|
||||
errorReasons.push({ type: 'SELL_ACCOUNT_NOT_FOUND', code: 120 });
|
||||
}
|
||||
if (!itemCategory && categoryId) {
|
||||
errorReasons.push({ type: 'ITEM_CATEGORY_NOT_FOUND', code: 140 });
|
||||
}
|
||||
if (errorReasons.length > 0) {
|
||||
return res.boom.badRequest(null, { errors: errorReasons });
|
||||
}
|
||||
|
||||
const item = Item.forge({
|
||||
name: req.body.name,
|
||||
type_id: 1,
|
||||
buy_price: req.body.buy_price,
|
||||
sell_price: req.body.sell_price,
|
||||
currency_code: req.body.currency_code,
|
||||
note: req.body.note,
|
||||
});
|
||||
|
||||
await item.save();
|
||||
|
||||
return res.status(200).send();
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* Edit the given item.
|
||||
*/
|
||||
editItem: {
|
||||
validation: [],
|
||||
async handler(req, res) {
|
||||
const { id } = req.params;
|
||||
const validationErrors = validationResult(req);
|
||||
|
||||
if (!validationErrors.isEmpty()) {
|
||||
return res.boom.badData(null, {
|
||||
code: 'validation_error', ...validationErrors,
|
||||
});
|
||||
}
|
||||
|
||||
const item = await Item.where('id', id).fetch();
|
||||
|
||||
if (!item) {
|
||||
return res.boom.notFound();
|
||||
}
|
||||
return res.status(200).send();
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* Delete the given item from the storage.
|
||||
*/
|
||||
deleteItem: {
|
||||
validation: [],
|
||||
async handler(req, res) {
|
||||
const { id } = req.params;
|
||||
const item = await Item.where('id', id).fetch();
|
||||
|
||||
if (!item) {
|
||||
return res.boom.notFound(null, {
|
||||
errors: [{ type: 'ITEM_NOT_FOUND', code: 100 }],
|
||||
});
|
||||
}
|
||||
|
||||
await item.destroy();
|
||||
return res.status(200).send();
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* Retrive the list items with pagination meta.
|
||||
*/
|
||||
listItems: {
|
||||
validation: [],
|
||||
async handler(req, res) {
|
||||
const filter = {
|
||||
name: '',
|
||||
description: '',
|
||||
SKU: '',
|
||||
account_id: null,
|
||||
page_size: 10,
|
||||
page: 1,
|
||||
start_date: null,
|
||||
end_date: null,
|
||||
...req.query,
|
||||
};
|
||||
|
||||
const items = await Item.query((query) => {
|
||||
if (filter.description) {
|
||||
query.where('description', 'like', `%${filter.description}%`);
|
||||
}
|
||||
if (filter.description) {
|
||||
query.where('SKU', filter.SKY);
|
||||
}
|
||||
if (filter.name) {
|
||||
query.where('name', filter.name);
|
||||
}
|
||||
if (filter.start_date) {
|
||||
const startDateFormatted = moment(filter.start_date).format('YYYY-MM-DD HH:mm:SS');
|
||||
query.where('created_at', '>=', startDateFormatted);
|
||||
}
|
||||
if (filter.end_date) {
|
||||
const endDateFormatted = moment(filter.end_date).format('YYYY-MM-DD HH:mm:SS');
|
||||
query.where('created_at', '<=', endDateFormatted);
|
||||
}
|
||||
}).fetchPage({
|
||||
page_size: filter.page_size,
|
||||
page: filter.page,
|
||||
});
|
||||
|
||||
return res.status(200).send({ ...items.toJSON() });
|
||||
},
|
||||
},
|
||||
};
|
||||
23
server/src/http/controllers/OAuth2.js
Normal file
23
server/src/http/controllers/OAuth2.js
Normal file
@@ -0,0 +1,23 @@
|
||||
import express from 'express';
|
||||
import OAuthServer from 'express-oauth-server';
|
||||
import OAuthServerModel from '@/models/OAuthServerModel';
|
||||
|
||||
export default {
|
||||
|
||||
/**
|
||||
* Router constructor method.
|
||||
*/
|
||||
router() {
|
||||
const router = express.Router();
|
||||
|
||||
router.oauth = new OAuthServer({
|
||||
model: OAuthServerModel,
|
||||
});
|
||||
|
||||
router.post('/token', router.oauth.token());
|
||||
// router.get('authorize', this.getAuthorize);
|
||||
// router.post('authorize', this.postAuthorize);
|
||||
|
||||
return router;
|
||||
},
|
||||
};
|
||||
0
server/src/http/controllers/Users.js
Normal file
0
server/src/http/controllers/Users.js
Normal file
15
server/src/http/index.js
Normal file
15
server/src/http/index.js
Normal file
@@ -0,0 +1,15 @@
|
||||
// import OAuth2 from '@/http/controllers/OAuth2';
|
||||
import Authentication from '@/http/controllers/Authentication';
|
||||
import Users from '@/http/controllers/Users';
|
||||
import Items from '@/http/controllers/Items';
|
||||
import ItemCategories from '@/http/controllers/ItemCategories';
|
||||
import Accounts from '@/http/controllers/Accounts';
|
||||
|
||||
export default (app) => {
|
||||
// app.use('/api/oauth2', OAuth2.router());
|
||||
app.use('/api/auth', Authentication.router());
|
||||
app.use('/api/users', Users.router());
|
||||
app.use('/api/accounts', Accounts.router());
|
||||
app.use('/api/items', Items.router());
|
||||
app.use('/api/item_categories', ItemCategories.router());
|
||||
};
|
||||
9
server/src/http/middleware/asyncMiddleware.js
Normal file
9
server/src/http/middleware/asyncMiddleware.js
Normal file
@@ -0,0 +1,9 @@
|
||||
const asyncMiddleware = (fn) => (req, res, next) => {
|
||||
Promise.resolve(fn(req, res, next))
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
next(error);
|
||||
});
|
||||
};
|
||||
|
||||
export default asyncMiddleware;
|
||||
34
server/src/http/middleware/jwtAuth.js
Normal file
34
server/src/http/middleware/jwtAuth.js
Normal file
@@ -0,0 +1,34 @@
|
||||
import jwt from 'jsonwebtoken';
|
||||
import User from '@/models/User';
|
||||
|
||||
const authMiddleware = (req, res, next) => {
|
||||
const token = req.headers['x-access-token'] || req.query.token;
|
||||
|
||||
const onError = () => res.status(401).send({
|
||||
success: false,
|
||||
message: 'unauthorized',
|
||||
});
|
||||
|
||||
if (!token) {
|
||||
return onError();
|
||||
}
|
||||
const { JWT_SECRET_KEY } = process.env;
|
||||
|
||||
const verify = new Promise((resolve, reject) => {
|
||||
jwt.verify(token, JWT_SECRET_KEY, async (error, decoded) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
} else {
|
||||
req.user = await User.where('id', decoded._id).fetch();
|
||||
|
||||
if (!req.user) {
|
||||
return onError();
|
||||
}
|
||||
resolve(decoded);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
verify.then(() => { next(); }).catch(onError);
|
||||
};
|
||||
export default authMiddleware;
|
||||
Reference in New Issue
Block a user