tested and fixed
This commit is contained in:
parent
7a2ab7dd5b
commit
c9e679ec4c
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"debug": true,
|
||||
"port": "8081",
|
||||
"dbuser": "bsfe",
|
||||
"dbhost": "localhost",
|
||||
"dbport": "5432",
|
||||
"dbpassword": "Ch@NgEME!",
|
||||
"dbname": "bsfe",
|
||||
"secret": "SECRET!11!1!"
|
||||
}
|
|
@ -4,6 +4,7 @@
|
|||
"user duplicate": "Such user already exists!",
|
||||
"user invalid syntax": "Invalid syntax in one of user's parameters!",
|
||||
"user already in group": "User is already in group!",
|
||||
"user not found": "User does not exists!",
|
||||
"username taken": "Username is taken!",
|
||||
"username not found": "Such username not found!",
|
||||
"username required": "Username is required!",
|
||||
|
@ -15,8 +16,6 @@
|
|||
"group not an owner": "You are not an owner of this group!",
|
||||
"group not a member": "You are not a member of this group!",
|
||||
"abstract product not found": "Such abstract product is not found!",
|
||||
"hash without file": "Please, supply a hash of an image!",
|
||||
"file without hash": "Please, supply an image!",
|
||||
"abstract product invalid syntax": "Invalid syntax in one of user's parameters!",
|
||||
"barcode not found": "Such barcode not found!",
|
||||
"barcode duplicate": "Such barcode already exists!",
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
"user duplicate": "Такой пользователь уже существует!",
|
||||
"user invalid syntax": "Неправильный синткасис в одном из параметров пользователя!",
|
||||
"user already in group": "Пользователь уже в группе!",
|
||||
"user not found": "Пользователь не существует!",
|
||||
"username taken": "Имя пользователя занято!",
|
||||
"username not found": "Такое имя пользователя не найдено!",
|
||||
"username required": "Требуется имя пользователя!",
|
||||
|
@ -15,8 +16,6 @@
|
|||
"group not an owner": "Вы не владелец этой группы!",
|
||||
"group not a member": "Вы не участник этой группы!",
|
||||
"abstract product not found": "Такой абстрактный продукт не найден!",
|
||||
"hash without file": "Пожалуйста, укажите хеш изображения!",
|
||||
"file without hash": "Пожалуйста, укажите изображение!",
|
||||
"abstract product invalid syntax": "Неправильный синткасис в одном из параметров абстрактного продукта!",
|
||||
"barcode not found": "Такой штрихкод не найден!",
|
||||
"barcode duplicate": "Такой штрихкод уже существует!",
|
||||
|
|
|
@ -4,14 +4,17 @@ import path from 'path';
|
|||
import customError from '../response/customError.js';
|
||||
import responseCodes from '../response/responseCodes.js';
|
||||
import translate from '../utils/translate.js';
|
||||
import { createHash } from 'crypto';
|
||||
|
||||
const TAG = "/controllers/abstractproduct.js";
|
||||
|
||||
class AbstractProductController {
|
||||
async create(req, res) {
|
||||
const { groupId, localId, barcode, name, net_weight, image_filename, category, unit } = req.body;
|
||||
const { groupId, localId, barcode, name, net_weight, category, unit } = req.body;
|
||||
|
||||
const tempPath = req.file.path;
|
||||
const image_buffer = fs.readFileSync(tempPath);
|
||||
const image_filename = createHash('md5').update(image_buffer).digest('hex');
|
||||
const targetPath = path.join(path.resolve(path.dirname('')), `/uploads/${image_filename}.png`);
|
||||
|
||||
if (path.extname(req.file.originalname).toLowerCase() !== ".png") {
|
||||
|
@ -27,11 +30,18 @@ class AbstractProductController {
|
|||
}
|
||||
|
||||
async update(req, res) {
|
||||
let { groupId, localId, barcode, name, net_weight, image_filename, category, unit } = req.body;
|
||||
let { groupId, localId, barcode, name, net_weight, category, unit } = req.body;
|
||||
|
||||
const tempPath = req.file.path;
|
||||
const targetPath = path.join(path.resolve(path.dirname('')) + `/uploads/${image_filename}.png`);
|
||||
var tempPath, image_buffer, image_filename, targetPath;
|
||||
|
||||
if (req.file) {
|
||||
tempPath = req.file.path;
|
||||
image_buffer = fs.readFileSync(tempPath);
|
||||
image_filename = createHash('md5').update(image_buffer).digest('hex');
|
||||
targetPath = path.join(path.resolve(path.dirname('')) + `/uploads/${image_filename}.png`);
|
||||
fs.copyFileSync(tempPath, targetPath);
|
||||
fs.rmSync(tempPath);
|
||||
}
|
||||
|
||||
if (barcode) await AbstractProductService.updateBarcode(groupId, localId, barcode);
|
||||
|
||||
|
@ -39,16 +49,7 @@ class AbstractProductController {
|
|||
|
||||
if (net_weight) await AbstractProductService.updateNetWeight(groupId, localId, net_weight);
|
||||
|
||||
if (image_filename && tempPath) {
|
||||
fs.copyFileSync(tempPath, targetPath);
|
||||
fs.rmSync(tempPath);
|
||||
await AbstractProductService.updateImageFilename(groupId, localId, image_filename);
|
||||
} else if (image_filename && !tempPath) {
|
||||
throw new customError(`Abstract product update image hash without file`, responseCodes.responses.abstractproducts.hash_without_file);
|
||||
} else if (!image_file && tempPath) {
|
||||
fs.rmSync(tempPath);
|
||||
throw new customError(`Abstract product update file without image hash`, responseCodes.responses.abstractproducts.file_without_hash);
|
||||
}
|
||||
if (tempPath) await AbstractProductService.updateImageFilename(groupId, localId, image_filename);
|
||||
|
||||
if (category) await AbstractProductService.updateCategory(groupId, localId, category);
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import CategoryService from "../services/category.js";
|
||||
import translate from "../utils/translate.js";
|
||||
import responseCodes from "../response/responseCodes.js";
|
||||
|
||||
const TAG = "controllers/category.js";
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import jwt from 'jsonwebtoken';
|
|||
import config from '../../config.json' with {type: "json"};
|
||||
import log from '../utils/log.js';
|
||||
import translate from '../utils/translate.js';
|
||||
import responseCodes from '../response/responseCodes.js';
|
||||
|
||||
const TAG = "/controllers/group.js";
|
||||
|
||||
|
@ -16,7 +17,7 @@ class GroupController {
|
|||
|
||||
log.info(`New group with name ${groupName} was just created by user ${user.login.username}`);
|
||||
|
||||
UserService.joinGroup(user.login.id, status.id);
|
||||
await UserService.joinGroup(user.login.id, status.id);
|
||||
return res.status(200).send(translate(req.headers["accept-language"], responseCodes.responses.general.ok));
|
||||
}
|
||||
async join(req, res) {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import ProductService from '../services/product.js';
|
||||
import translate from '../utils/translate.js';
|
||||
import responseCodes from '../response/responseCodes.js';
|
||||
|
||||
const TAG = "/controllers/product.js"
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import genToken from '../utils/jwt.js';
|
|||
import AbstractProductService from '../services/abstractproduct.js';
|
||||
import ProductService from '../services/product.js';
|
||||
import translate from '../utils/translate.js';
|
||||
import responseCodes from '../response/responseCodes.js';
|
||||
|
||||
const TAG = "/controllers/userjs"
|
||||
|
||||
|
@ -25,7 +26,7 @@ class UserController {
|
|||
if (!bcrypt.compareSync(password, user.password)) return res.status(401).send("Wrong password");
|
||||
|
||||
const token = genToken(user);
|
||||
return res.status(200).send(translate(req.headers["accept-language"], responseCodes.responses.general.ok));
|
||||
return res.status(200).send(token);
|
||||
}
|
||||
|
||||
async synchronize(req, res) {
|
||||
|
@ -36,7 +37,7 @@ class UserController {
|
|||
result.products = await ProductService.getAll(groupId);
|
||||
result.categories = await CategoryService.getAll(groupId);
|
||||
|
||||
return res.status(200).send(translate(req.headers["accept-language"], responseCodes.responses.general.ok));
|
||||
return res.status(200).send(result);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import log from '../utils/log.js'
|
||||
import jwt from 'jsonwebtoken';
|
||||
import config from '../../config.json' with {type: "json"};
|
||||
import GroupService from '../services/group.js';
|
||||
|
@ -26,10 +25,15 @@ const requirePassword = async (req, res, next) => {
|
|||
|
||||
const authenticate = async (req, res, next) => {
|
||||
if (req.method == "OPTIONS") next();
|
||||
|
||||
if (!req.headers.authorization) throw new customError(`authenticate no authorization header`, responseCodes.responses.authentication.not_found);
|
||||
|
||||
const token = req.headers.authorization.split(' ')[1];
|
||||
if (!token) throw new customError(`authenticate no authorization token in header`, responseCodes.responses.authentication.not_found);
|
||||
|
||||
let user = jwt.decode(token, config.secret);
|
||||
|
||||
await UserService.getByUsername(user.login.username)
|
||||
|
||||
if (!jwt.verify(token, config.secret)) throw new customError(`authenticate token is invalid`, responseCodes.responses.authentication.invalid);
|
||||
|
||||
next();
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
import customError from '../response/customError.js';
|
||||
import responseCodes from '../response/responseCodes.js';
|
||||
import GroupService from '../services/group.js';
|
||||
|
||||
const groupExists = async (req, res, next) => {
|
||||
let groupId = req.params.groupId || req.body.groupId;
|
||||
|
||||
let group = await GroupService.getById(groupId);
|
||||
|
||||
if (!group) throw new customError(`group does not exists`, responseCodes.responses.groups.id_not_found);
|
||||
next();
|
||||
};
|
||||
|
||||
const localIdExists = async (req, res, next) => {
|
||||
let localId = req.params.localId || req.body.localId;
|
||||
|
||||
if (!localId) throw new customError(`local id is not specified`, responseCodes.responses.general.invalid_syntax);
|
||||
next();
|
||||
}
|
||||
|
||||
export default { groupExists, localIdExists }
|
|
@ -1,6 +1,6 @@
|
|||
import log from "../utils/log";
|
||||
import customError from "./customError";
|
||||
import responses from './responseCodes';
|
||||
import log from "../utils/log.js";
|
||||
import customError from "./customError.js";
|
||||
import responses from './responseCodes.js';
|
||||
import translate from '../utils/translate.js';
|
||||
|
||||
const errorHandler = (err, req, res) => {
|
||||
|
@ -9,7 +9,7 @@ const errorHandler = (err, req, res) => {
|
|||
let language = req.headers["accept-language"];
|
||||
|
||||
if (err instanceof customError) {
|
||||
return res.status(responses.getHTTPCode(err.code)).send(translate(language, code));
|
||||
return res.status(responses.getHTTPCode(err.code)).send(translate(language, err.code));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
import fs from 'fs';
|
||||
|
||||
const responses = {
|
||||
authentication: {
|
||||
not_found: "authentication not found",
|
||||
|
@ -8,7 +6,8 @@ const responses = {
|
|||
user: {
|
||||
duplicate: "user duplicate",
|
||||
invalid_syntax: "user invalid syntax",
|
||||
already_in_group: "user already in group"
|
||||
already_in_group: "user already in group",
|
||||
not_found: "user not found"
|
||||
},
|
||||
usernames: {
|
||||
duplicate: "username taken",
|
||||
|
@ -28,8 +27,6 @@ const responses = {
|
|||
},
|
||||
abstractproducts: {
|
||||
not_found: "abstract product not found",
|
||||
hash_without_file: "hash without file",
|
||||
file_without_hash: "file without hash",
|
||||
invalid_syntax: "abstract product invalid syntax"
|
||||
},
|
||||
barcode: {
|
||||
|
@ -95,7 +92,7 @@ const responses = {
|
|||
}
|
||||
|
||||
const getHTTPCode = (type) => {
|
||||
switch (code) {
|
||||
switch (type) {
|
||||
case responses.general.ok:
|
||||
return 200
|
||||
case responses.general.invalid_syntax:
|
||||
|
@ -118,6 +115,8 @@ const getHTTPCode = (type) => {
|
|||
return 409
|
||||
case responses.user.invalid_syntax:
|
||||
return 400
|
||||
case responses.user.not_found:
|
||||
return 404
|
||||
|
||||
|
||||
case responses.usernames.duplicate:
|
||||
|
@ -145,10 +144,6 @@ const getHTTPCode = (type) => {
|
|||
|
||||
case responses.abstractproducts.not_found:
|
||||
return 404
|
||||
case responses.abstractproducts.file_without_hash:
|
||||
return 400
|
||||
case responses.abstractproducts.hash_without_file:
|
||||
return 400
|
||||
case responses.abstractproducts.invalid_syntax:
|
||||
return 400
|
||||
|
||||
|
@ -166,15 +161,6 @@ const getHTTPCode = (type) => {
|
|||
case responses.abstractproductname.too_long:
|
||||
return 400
|
||||
|
||||
case responses.abstractproducts.file_without_hash:
|
||||
return 400
|
||||
case responses.abstractproducts.hash_without_file:
|
||||
return 400
|
||||
case responses.abstractproducts.invalid_syntax:
|
||||
return 400
|
||||
case responses.abstractproducts.not_found:
|
||||
return 404
|
||||
|
||||
case responses.amount.invalid_syntax:
|
||||
return 400
|
||||
case responses.amount.too_long:
|
||||
|
|
|
@ -4,6 +4,7 @@ import AbstractProductController from '../controllers/abstractproduct.js';
|
|||
import multer from 'multer';
|
||||
import path from 'path';
|
||||
import tryHandler from '../response/errorHandler.js';
|
||||
import existance from '../middlewares/existance.js';
|
||||
|
||||
const upload = multer(({
|
||||
dest: path.join(path.resolve(path.dirname('')), "/temp")
|
||||
|
@ -12,6 +13,6 @@ const upload = multer(({
|
|||
const AbstractProductRouter = new Router();
|
||||
|
||||
AbstractProductRouter.post('/create', upload.single("file"), tryHandler(auth.authenticate), tryHandler(auth.userIsInGroup), tryHandler(AbstractProductController.create));
|
||||
AbstractProductRouter.post('/update', upload.single("file"), tryHandler(auth.authenticate), tryHandler(auth.userIsInGroup), tryHandler(AbstractProductController.update));
|
||||
AbstractProductRouter.post('/update', upload.single("file"), tryHandler(auth.authenticate), tryHandler(auth.userIsInGroup), tryHandler(existance.localIdExists), tryHandler(AbstractProductController.update));
|
||||
|
||||
export default AbstractProductRouter;
|
|
@ -2,10 +2,11 @@ import { Router } from 'express';
|
|||
import auth from '../middlewares/auth.js';
|
||||
import CategoryController from '../controllers/category.js';
|
||||
import tryHandler from '../response/errorHandler.js';
|
||||
import existance from '../middlewares/existance.js';
|
||||
|
||||
const CategoryRouter = new Router();
|
||||
|
||||
CategoryRouter.post('/create', tryHandler(auth.authenticate), tryHandler(CategoryController.create));
|
||||
CategoryRouter.post('/update', tryHandler(auth.authenticate), tryHandler(CategoryController.update));
|
||||
CategoryRouter.post('/create', tryHandler(auth.authenticate), tryHandler(existance.groupExists), tryHandler(CategoryController.create));
|
||||
CategoryRouter.post('/update', tryHandler(auth.authenticate), tryHandler(existance.groupExists), tryHandler(existance.localIdExists), tryHandler(CategoryController.update));
|
||||
|
||||
export default CategoryRouter;
|
|
@ -2,11 +2,12 @@ import { Router } from 'express';
|
|||
import auth from '../middlewares/auth.js';
|
||||
import GroupController from '../controllers/group.js';
|
||||
import tryHandler from '../response/errorHandler.js';
|
||||
import existance from '../middlewares/existance.js';
|
||||
|
||||
const GroupRouter = new Router();
|
||||
|
||||
GroupRouter.post('/create/:groupName', tryHandler(auth.authenticate), tryHandler(GroupController.create));
|
||||
GroupRouter.post('/join/:groupId', tryHandler(auth.authenticate), tryHandler(auth.requirePassword), tryHandler(auth.checkGroupPassword), tryHandler(GroupController.join));
|
||||
GroupRouter.post('/password/:groupId', tryHandler(auth.authenticate), tryHandler(auth.authorizeGroupOwner), tryHandler(auth.requirePassword), tryHandler(GroupController.updatePassword));
|
||||
GroupRouter.post('/join/:groupId', tryHandler(auth.authenticate), tryHandler(existance.groupExists), tryHandler(auth.requirePassword), tryHandler(auth.checkGroupPassword), tryHandler(GroupController.join));
|
||||
GroupRouter.post('/password/:groupId', tryHandler(auth.authenticate), tryHandler(existance.groupExists), tryHandler(auth.authorizeGroupOwner), tryHandler(auth.requirePassword), tryHandler(GroupController.updatePassword));
|
||||
|
||||
export default GroupRouter;
|
|
@ -2,10 +2,11 @@ import { Router } from 'express';
|
|||
import auth from '../middlewares/auth.js';
|
||||
import ProductController from '../controllers/product.js'
|
||||
import tryHandler from '../response/errorHandler.js';
|
||||
import existance from '../middlewares/existance.js';
|
||||
|
||||
const ProductRouter = new Router();
|
||||
|
||||
ProductRouter.post('/create', tryHandler(auth.authenticate), tryHandler(auth.userIsInGroup), tryHandler(ProductController.create));
|
||||
ProductRouter.post('/update', tryHandler(auth.authenticate), tryHandler(auth.userIsInGroup), tryHandler(ProductController.update));
|
||||
ProductRouter.post('/create', tryHandler(auth.authenticate), tryHandler(existance.groupExists), tryHandler(auth.userIsInGroup), tryHandler(ProductController.create));
|
||||
ProductRouter.post('/update', tryHandler(auth.authenticate), tryHandler(existance.groupExists), tryHandler(existance.localIdExists), tryHandler(auth.userIsInGroup), tryHandler(ProductController.update));
|
||||
|
||||
export default ProductRouter;
|
|
@ -1,7 +1,5 @@
|
|||
import db from '../db.js';
|
||||
import statuses from '../utils/status.js';
|
||||
import errorHandler from '../utils/pgerrorhandler.js';
|
||||
import tryHandler from '../response/errorHandler.js';
|
||||
import responses from '../response/responseCodes.js';
|
||||
import customError from '../response/customError.js';
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import db from '../db.js';
|
||||
import customError from '../response/customError.js';
|
||||
import responseCodes from '../response/responseCodes.js';
|
||||
import statuses from '../utils/status.js';
|
||||
|
||||
class CategoryService {
|
||||
async create(groupId, categoryId, name) {
|
||||
|
|
|
@ -5,14 +5,14 @@ import errorHandler from '../utils/pgerrorhandler.js';
|
|||
|
||||
class GroupService {
|
||||
async create(name, creatorId) {
|
||||
let res = await db.query("INSERT INTO groups (name, admin_id) VALUES ($1, $2) RETURNING ID", [name, creatorId]).catch((e) => errorHandler(e, "group"));
|
||||
let res = await db.query("INSERT INTO groups (name, admin_id) VALUES ($1, $2) RETURNING ID", [name, creatorId]).catch((e) => errorHandler(e, "groups"));
|
||||
|
||||
return res.rows[0];
|
||||
}
|
||||
|
||||
async getById(id) {
|
||||
let res = (await db.query("SELECT * FROM groups WHERE id = $1", [id]));
|
||||
if (res.rowCount == 0) throw new customError(`getByUd group not found`, responseCodes.responses.groups.id_not_found);
|
||||
if (res.rowCount == 0) throw new customError(`getById group not found`, responseCodes.responses.groups.id_not_found);
|
||||
return res.rows[0];
|
||||
}
|
||||
|
||||
|
|
|
@ -1,21 +1,20 @@
|
|||
import db from '../db.js'
|
||||
import customError from '../response/customError.js';
|
||||
import responseCodes from '../response/responseCodes.js';
|
||||
import statuses from '../utils/status.js';
|
||||
import bcrypt from 'bcrypt';
|
||||
import errorHandler from '../utils/pgerrorhandler.js';
|
||||
|
||||
class UserService {
|
||||
async create(username, password) {
|
||||
await db.query("INSERT INTO users (username, password) VALUES ($1, $2)", [username, bcrypt.hashSync(password, 12)]).catch((e) => {
|
||||
errorHandler(e, "user");
|
||||
})
|
||||
return statuses.ok;
|
||||
}
|
||||
|
||||
async getByUsername(username) {
|
||||
let user = (await db.query("SELECT * FROM Users WHERE username = $1", [username])).rows;
|
||||
if (user == undefined) throw new customError(`getByUsername user not found`, responseCodes.responses.usernames.not_found);
|
||||
return (user[0]);
|
||||
let user = (await db.query("SELECT * FROM Users WHERE username = $1", [username]));
|
||||
if (user.rowCount == 0) throw new customError(`getByUsername user not found`, responseCodes.responses.usernames.not_found);
|
||||
return user.rows[0];
|
||||
}
|
||||
|
||||
async getAll() {
|
||||
|
@ -31,7 +30,6 @@ class UserService {
|
|||
async joinGroup(userId, groupId) {
|
||||
if (await (this.isInGroup(userId, groupId))) throw new customError(`joinGroup user already in group`, responseCodes.responses.user.already_in_group);
|
||||
await db.query("UPDATE Users SET groups = array_append(groups, $1::integer) WHERE ID = $2", [groupId, userId]);
|
||||
return statuses.ok;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ import responseCodes from "../response/responseCodes.js";
|
|||
const errorHandler = (e, obj) => {
|
||||
switch (e.code) {
|
||||
case '23505':
|
||||
throw new customError(`Duplicate ${obj}`, responseCodes.responses[obs].duplicate)
|
||||
throw new customError(`Duplicate ${obj}`, responseCodes.responses[obj].duplicate)
|
||||
case '22007':
|
||||
throw new customError(`Invalid syntax ${obj}`, responseCodes.responses.general.invalid_syntax)
|
||||
case '22001':
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
import fs from 'fs';
|
||||
|
||||
const translate = (language, code) => {
|
||||
if (!language) language = "en-US"
|
||||
if (!code) code = "unknown"
|
||||
return JSON.parse(fs.readFileSync(`../../messages/${language}/msgs.json`).toString())[code]
|
||||
return JSON.parse(fs.readFileSync(`./messages/${language}/msgs.json`).toString())[code];
|
||||
}
|
||||
|
||||
export default translate
|
Loading…
Reference in New Issue