websockets

This commit is contained in:
2024-11-12 21:22:13 +03:00
parent 0608ccda6d
commit 66bfba3b8e
8 changed files with 336 additions and 7 deletions

View File

@@ -6,6 +6,7 @@ import customError from '../response/customError.js';
import responseCodes from '../response/responseCodes.js';
import translate from '../utils/translate.js';
import { createHash } from 'crypto';
import notify from '../utils/notify.js';
const TAG = "/controllers/abstractproduct.js";
@@ -29,6 +30,11 @@ class AbstractProductController {
fs.rmSync(tempPath);
await AbstractProductService.create(groupId, localId, barcode, name, net_weight, image_filename, category, unit);
notify(req.headers.authorization.split(' ')[1], groupId, 'create', 'abstractproduct', {
localId, barcode, name, net_weight, image_filename, category, unit
});
return res.status(200).send(translate(req.headers["accept-language"], responseCodes.responses.general.ok));
}
@@ -58,6 +64,15 @@ class AbstractProductController {
if (unit) await AbstractProductService.updateUnit(groupId, localId, unit);
let data = { localId }
if (barcode) data.barcode = barcode
if (name) data.name = name
if (net_weight) data.net_weight = net_weight
if (category) data.category = category
if (unit) data.unit = unit
notify(req.headers.authorization.split(' ')[1], groupId, 'update', 'abstractproduct', data);
return res.status(200).send(translate(req.headers["accept-language"], responseCodes.responses.general.ok));
}
@@ -85,6 +100,8 @@ class AbstractProductController {
await AbstractProductService.delete(groupId, localId)
notify(req.headers.authorization.split(' ')[1], groupId, 'delete', 'abstractproduct', { localId });
return res.status(200).send(translate(req.headers["accept-language"], responseCodes.responses.general.ok))
}
};

View File

@@ -1,8 +1,7 @@
import CategoryService from "../services/category.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";
import notify from "../utils/notify.js";
const TAG = "controllers/category.js";
@@ -12,6 +11,10 @@ class CategoryController {
await CategoryService.create(groupId, localId, categoryName);
notify(req.headers.authorization.split(' ')[1], groupId, 'create', 'category', {
localId, categoryName
});
return res.status(200).send(translate(req.headers["accept-language"], responseCodes.responses.general.ok));
}
@@ -20,6 +23,11 @@ class CategoryController {
await CategoryService.update(groupId, localId, categoryName);
let data = { localId }
if (categoryName) data.categoryName = categoryName
notify(req.headers.authorization.split(' ')[1], groupId, 'update', 'category', data);
return res.status(200).send(translate(req.headers["accept-language"], responseCodes.responses.general.ok));
}
@@ -36,6 +44,8 @@ class CategoryController {
await CategoryService.delete(groupId, localId);
notify(req.headers.authorization.split(' ')[1], groupId, 'delete', 'category', { localId });
return res.status(200).send(translate(req.headers["accept-language"], responseCodes.responses.general.ok))
}
};

View File

@@ -10,10 +10,13 @@ class AbstractProductController {
await ProductService.create(groupId, localId, abstract_product_id, amount, date_of_production, expiry_date);
notify(req.headers.authorization.split(' ')[1], groupId, 'create', 'product', {
localId, abstract_product_id, amount, date_of_production, expiry_date
});
return res.status(200).send(translate(req.headers["accept-language"], responseCodes.responses.general.ok));
}
async update(req, res) {
let { groupId, localId, abstract_product_id, amount, date_of_production, expiry_date } = req.body;
@@ -25,6 +28,14 @@ class AbstractProductController {
if (expiry_date) await ProductService.updateExpiryDate(groupId, localId, expiry_date);
let data = { localId };
if (abstract_product_id) data.abstract_product_id = abstract_product_id
if (amount) data.amount = amount
if (date_of_production) data.date_of_production = date_of_production
if (expiry_date) data.expiry_date = expiry_date
notify(req.headers.authorization.split(' ')[1], groupId, 'update', 'product', data);
return res.status(200).send(translate(req.headers["accept-language"], responseCodes.responses.general.ok));
}
@@ -43,6 +54,8 @@ class AbstractProductController {
await ProductService.delete(id)
notify(req.headers.authorization.split(' ')[1], groupId, 'delete', 'product', { localId });
return res.status(200).send(translate(req.headers["accept-language"], responseCodes.responses.general.ok));
}
};

View File

@@ -1,5 +1,6 @@
import express from 'express';
import UserRouter from './routers/user.js';
import UserService from './services/user.js';
import GroupRouter from './routers/group.js';
import AbstractProductRouter from './routers/abstractproduct.js';
import log from './utils/log.js';
@@ -8,7 +9,15 @@ import config from '../config.json' with {type: "json"};
import ProductRouter from './routers/product.js';
import CategoryRouter from './routers/category.js';
import { WebSocketServer } from 'ws';
import http from 'http'
import jwt from 'jsonwebtoken';
const app = express();
const server = http.createServer(app);
const wss = new WebSocketServer({ port: config.wsport });
const clients = []
app.use(express.urlencoded({ extended: false, limit: "200mb", parameterLimit: 100000 }));
app.use(express.json({ limit: "200mb", parameterLimit: 1000000 }));
@@ -23,6 +32,42 @@ app.get('/status', (req, res) => {
return res.status(200).send("All OK");
});
wss.on('connection', (client) => {
client.on('message', async (message) => {
let parsed = JSON.parse(message)
let token = parsed.token
let currentGroup = parsed.currentGroup
if (!jwt.verify(token, config.secret)) {
client.send("Invalid token");
return
}
if (!await UserService.isInGroup(jwt.decode(token, config.secret).login.id, currentGroup)) {
client.send("Not a member of specified group")
return
}
clients.push({
socket: client,
token,
currentGroup
});
});
client.on('close', () => {
for (let i = 0; i < clients.length; i++) {
if (clients[i].socket == client) {
clients.splice(i, 1);
break;
}
}
})
});
app.listen(config.port, () => {
log.info(`Application has started on port ${config.port}`)
});
});
export default clients;

26
src/utils/notify.js Normal file
View File

@@ -0,0 +1,26 @@
import clients from '../index.js';
import jwt from 'jsonwebtoken';
import config from '../../config.json' with {type: "json"};
const notify = (token, groupId, action, item, data) => {
let login = jwt.decode(token, config.secret).login
let userIdCurrent = login.id
let payload = {
action,
item,
groupId,
data
}
clients.forEach(client => {
if (client.currentGroup == groupId) {
let userIdFromToken = jwt.decode(client.token, config.secret).login.id
if (userIdCurrent == userIdFromToken) return;
client.socket.send(payload)
}
});
}
export default notify;