Implement caching and permission checks for user permissions

This commit introduces a caching mechanism for user permissions using Redis, enhancing performance by reducing database queries. The `permissions.js` file has been updated to include functions for saving and retrieving user permissions from Redis, as well as middleware for checking permissions in various routes. Additionally, tests have been added to ensure the correctness of the permission logic and caching behavior, improving the overall security and efficiency of the application.
This commit is contained in:
Tom Butcher 2026-08-20 19:35:15 +01:00
parent 1c51766da6
commit bce5afad7e
50 changed files with 583 additions and 204 deletions

View File

@ -1,4 +1,32 @@
import { applyPermissionSettingsList } from '../permissions.js'; import { jest } from '@jest/globals';
const redisMock = {
getKey: jest.fn(),
setKey: jest.fn(),
};
const lean = jest.fn();
const select = jest.fn(() => ({ lean }));
const findById = jest.fn(() => ({ select }));
const userModel = { findById };
jest.unstable_mockModule('../redis.js', () => ({
redisServer: redisMock,
}));
jest.unstable_mockModule('mongoose', () => ({
default: {
model: jest.fn(() => userModel),
},
}));
const {
applyPermissionSettingsList,
checkPermissions,
hasPermission,
getUserPermissionsCacheKey,
saveUserPermissionsToRedis,
} = await import('../permissions.js');
describe('applyPermissionSettingsList', () => { describe('applyPermissionSettingsList', () => {
it('applies permission settings in order and inherits intermediate values', () => { it('applies permission settings in order and inherits intermediate values', () => {
@ -54,3 +82,95 @@ describe('applyPermissionSettingsList', () => {
}); });
}); });
}); });
describe('saveUserPermissionsToRedis', () => {
beforeEach(() => {
jest.clearAllMocks();
});
it('saves permissions under permissions:userID', async () => {
const permissions = { user: { info: true } };
await saveUserPermissionsToRedis('user-1', permissions);
expect(redisMock.setKey).toHaveBeenCalledWith('permissions:user-1', permissions);
});
});
describe('hasPermission', () => {
beforeEach(() => {
jest.clearAllMocks();
redisMock.getKey.mockResolvedValue(null);
redisMock.setKey.mockResolvedValue(undefined);
lean.mockResolvedValue(null);
});
it('returns true when the cached permission is allowed', async () => {
redisMock.getKey.mockResolvedValue({ printer: { edit: true } });
await expect(hasPermission({ _id: 'user-1' }, 'printer', 'edit')).resolves.toBe(true);
expect(redisMock.getKey).toHaveBeenCalledWith(getUserPermissionsCacheKey('user-1'));
expect(findById).not.toHaveBeenCalled();
});
it('returns false when the cached permission is denied or missing', async () => {
redisMock.getKey.mockResolvedValue({ printer: { edit: false } });
await expect(hasPermission('user-1', 'printer', 'edit')).resolves.toBe(false);
await expect(hasPermission('user-1', 'printer', 'delete')).resolves.toBe(false);
});
it('loads permissions from mongodb when redis is empty and caches them', async () => {
lean.mockResolvedValue({
permissions: { job: { info: true, edit: false } },
});
await expect(hasPermission('user-2', 'job', 'info')).resolves.toBe(true);
expect(findById).toHaveBeenCalledWith('user-2');
expect(select).toHaveBeenCalledWith('permissions');
expect(redisMock.setKey).toHaveBeenCalledWith('permissions:user-2', {
job: { info: true, edit: false },
});
});
it('returns false when the user or action cannot be resolved', async () => {
await expect(hasPermission(null, 'job', 'info')).resolves.toBe(false);
await expect(hasPermission('user-1', '', 'info')).resolves.toBe(false);
expect(redisMock.getKey).not.toHaveBeenCalled();
});
});
describe('checkPermissions middleware', () => {
const json = jest.fn();
const status = jest.fn(() => ({ json }));
const next = jest.fn();
const res = { status };
beforeEach(() => {
jest.clearAllMocks();
redisMock.getKey.mockResolvedValue(null);
redisMock.setKey.mockResolvedValue(undefined);
lean.mockResolvedValue(null);
});
it('calls next when the user is allowed', async () => {
redisMock.getKey.mockResolvedValue({ part: { edit: true } });
const req = { user: { _id: 'user-1' } };
await checkPermissions('part', 'edit')(req, res, next);
expect(next).toHaveBeenCalledWith();
expect(status).not.toHaveBeenCalled();
});
it('returns 403 when the user is not allowed', async () => {
redisMock.getKey.mockResolvedValue({ part: { edit: false } });
const req = { user: { _id: 'user-1' } };
await checkPermissions('part', 'edit')(req, res, next);
expect(status).toHaveBeenCalledWith(403);
expect(json).toHaveBeenCalledWith({ error: 'Forbidden', code: 'FORBIDDEN' });
expect(next).not.toHaveBeenCalled();
});
});

View File

@ -1,4 +1,65 @@
import mongoose from 'mongoose'; import mongoose from 'mongoose';
import { redisServer } from './redis.js';
import config from '../config.js';
import log4js from 'log4js';
const logger = log4js.getLogger('Permissions');
logger.level = config.server.logLevel;
export const getUserPermissionsCacheKey = (userId) => `permissions:${userId}`;
export const saveUserPermissionsToRedis = async (userId, permissions = {}) => {
if (!userId) {
return;
}
await redisServer.setKey(getUserPermissionsCacheKey(userId), permissions || {});
};
const getUserId = (user) => {
if (!user) return null;
if (typeof user === 'string') return user;
if (user._id) return user._id._id || user._id;
return user;
};
const loadPermissionsFromMongo = async (userId) => {
const userDoc = await mongoose.model('user').findById(userId).select('permissions').lean();
return userDoc?.permissions || {};
};
export const hasPermission = async (user, objectType, action) => {
const userId = getUserId(user);
if (!userId || !objectType || !action) {
return false;
}
logger.debug(`Checking permission: ${userId}, ${objectType}, ${action}`);
const cacheKey = getUserPermissionsCacheKey(userId);
let permissions = await redisServer.getKey(cacheKey);
if (permissions == null) {
permissions = await loadPermissionsFromMongo(userId);
await saveUserPermissionsToRedis(userId, permissions);
}
return permissions?.[objectType]?.[action] === true;
};
export const checkPermissions = (objectType, action) => async (req, res, next) => {
try {
const allowed = await hasPermission(req.user, objectType, action);
if (!allowed) {
return res.status(403).json({ error: 'Forbidden', code: 'FORBIDDEN' });
}
return next();
} catch (err) {
return next(err);
}
};
export const applyPermissionSettingsList = (settingsList = []) => { export const applyPermissionSettingsList = (settingsList = []) => {
const permissions = {}; const permissions = {};

View File

@ -4,6 +4,7 @@ import {
applyPermissionSettingsList, applyPermissionSettingsList,
resolvePermissionSettings, resolvePermissionSettings,
resolveReferencedDocs, resolveReferencedDocs,
saveUserPermissionsToRedis,
} from '../../permissions.js'; } from '../../permissions.js';
const { Schema } = mongoose; const { Schema } = mongoose;
@ -47,6 +48,7 @@ userSchema.statics.recalculate = async function (user, actingUser) {
if (user && typeof user === 'object' && !user._bsontype) { if (user && typeof user === 'object' && !user._bsontype) {
user.permissions = permissions; user.permissions = permissions;
} }
await saveUserPermissionsToRedis(userId, permissions);
const { editObject } = await import('../../database.js'); const { editObject } = await import('../../database.js');
await editObject({ await editObject({

View File

@ -1,5 +1,6 @@
import express from 'express'; import express from 'express';
import { isAuthenticated } from '../../keycloak.js'; import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions, hasPermission } from '../../database/permissions.js';
import { getFilter, convertPropertiesString, getSort } from '../../utils.js'; import { getFilter, convertPropertiesString, getSort } from '../../utils.js';
const router = express.Router(); const router = express.Router();
@ -19,15 +20,15 @@ const listAllowedFilters = [
]; ];
const listAllowedSorters = ['createdAt', 'state', 'updatedAt', 'invoiceDate', 'dueDate']; const listAllowedSorters = ['createdAt', 'state', 'updatedAt', 'invoiceDate', 'dueDate'];
const propertiesAllowedFilters = [ const propertiesAllowedFilters = [
'vendor', 'vendor',
'client', 'client',
'orderType', 'orderType',
'order', 'order',
'state.type', 'state.type',
'value', 'value',
'vendor._id', 'vendor._id',
'client._id', 'client._id',
]; ];
import { import {
listInvoicesRouteHandler, listInvoicesRouteHandler,
getInvoiceRouteHandler, getInvoiceRouteHandler,
@ -43,15 +44,24 @@ import {
postInvoiceRouteHandler, postInvoiceRouteHandler,
searchInvoicesRouteHandler, searchInvoicesRouteHandler,
getInvoicePropertyValuesRouteHandler, getInvoicePropertyValuesRouteHandler,
getInvoiceNeighborsRouteHandler,
getInvoiceNeighborsRouteHandler
} from '../../services/finance/invoices.js'; } from '../../services/finance/invoices.js';
// list of invoices // list of invoices
router.get('/', isAuthenticated, async (req, res) => { router.get('/', isAuthenticated, async (req, res) => {
const { page, limit, property, search, sort, order } = req.query; const { page, limit, property, search, sort, order } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
listInvoicesRouteHandler(req, res, page, limit, property, filter, search, getSort(sort, listAllowedSorters), order); listInvoicesRouteHandler(
req,
res,
page,
limit,
property,
filter,
search,
getSort(sort, listAllowedSorters),
order
);
}); });
router.get('/properties', isAuthenticated, async (req, res) => { router.get('/properties', isAuthenticated, async (req, res) => {
@ -73,8 +83,7 @@ router.get('/search', isAuthenticated, async (req, res) => {
searchInvoicesRouteHandler(req, res, search); searchInvoicesRouteHandler(req, res, search);
}); });
router.post('/', isAuthenticated, checkPermissions('invoice', 'new'), async (req, res) => {
router.post('/', isAuthenticated, async (req, res) => {
newInvoiceRouteHandler(req, res); newInvoiceRouteHandler(req, res);
}); });
@ -91,19 +100,28 @@ router.get('/history', isAuthenticated, async (req, res) => {
router.get('/neighbors', isAuthenticated, async (req, res) => { router.get('/neighbors', isAuthenticated, async (req, res) => {
const { property, search, sort, order, id } = req.query; const { property, search, sort, order, id } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
getInvoiceNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getInvoiceNeighborsRouteHandler(
req,
res,
property,
filter,
search,
getSort(sort, listAllowedSorters),
order,
id
);
}); });
router.get('/:id', isAuthenticated, async (req, res) => { router.get('/:id', isAuthenticated, checkPermissions('invoice', 'info'), async (req, res) => {
getInvoiceRouteHandler(req, res); getInvoiceRouteHandler(req, res);
}); });
// update multiple invoices // update multiple invoices
router.put('/', isAuthenticated, async (req, res) => { router.put('/', isAuthenticated, checkPermissions('invoice', 'edit'), async (req, res) => {
editMultipleInvoicesRouteHandler(req, res); editMultipleInvoicesRouteHandler(req, res);
}); });
router.put('/:id', isAuthenticated, async (req, res) => { router.put('/:id', isAuthenticated, checkPermissions('invoice', 'edit'), async (req, res) => {
editInvoiceRouteHandler(req, res); editInvoiceRouteHandler(req, res);
}); });
@ -111,16 +129,26 @@ router.delete('/:id', isAuthenticated, async (req, res) => {
deleteInvoiceRouteHandler(req, res); deleteInvoiceRouteHandler(req, res);
}); });
router.post('/:id/post', isAuthenticated, async (req, res) => { router.post('/:id/post', isAuthenticated, checkPermissions('invoice', 'post'), async (req, res) => {
postInvoiceRouteHandler(req, res); postInvoiceRouteHandler(req, res);
}); });
router.post('/:id/acknowledge', isAuthenticated, async (req, res) => { router.post(
acknowledgeInvoiceRouteHandler(req, res); '/:id/acknowledge',
}); isAuthenticated,
checkPermissions('invoice', 'acknowledge'),
async (req, res) => {
acknowledgeInvoiceRouteHandler(req, res);
}
);
router.post('/:id/cancel', isAuthenticated, async (req, res) => { router.post(
cancelInvoiceRouteHandler(req, res); '/:id/cancel',
}); isAuthenticated,
checkPermissions('invoice', 'cancel'),
async (req, res) => {
cancelInvoiceRouteHandler(req, res);
}
);
export default router; export default router;

View File

@ -1,5 +1,6 @@
import express from 'express'; import express from 'express';
import { isAuthenticated } from '../../keycloak.js'; import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
import { getFilter, convertPropertiesString, getSort } from '../../utils.js'; import { getFilter, convertPropertiesString, getSort } from '../../utils.js';
const router = express.Router(); const router = express.Router();
@ -74,7 +75,7 @@ router.get('/search', isAuthenticated, async (req, res) => {
}); });
router.post('/', isAuthenticated, async (req, res) => { router.post('/', isAuthenticated, checkPermissions('invoice', 'newPayment'), async (req, res) => {
newPaymentRouteHandler(req, res); newPaymentRouteHandler(req, res);
}); });
@ -94,16 +95,16 @@ router.get('/neighbors', isAuthenticated, async (req, res) => {
getPaymentNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getPaymentNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id);
}); });
router.get('/:id', isAuthenticated, async (req, res) => { router.get('/:id', isAuthenticated, checkPermissions('payment', 'info'), async (req, res) => {
getPaymentRouteHandler(req, res); getPaymentRouteHandler(req, res);
}); });
// update multiple payments // update multiple payments
router.put('/', isAuthenticated, async (req, res) => { router.put('/', isAuthenticated, checkPermissions('payment', 'edit'), async (req, res) => {
editMultiplePaymentsRouteHandler(req, res); editMultiplePaymentsRouteHandler(req, res);
}); });
router.put('/:id', isAuthenticated, async (req, res) => { router.put('/:id', isAuthenticated, checkPermissions('payment', 'edit'), async (req, res) => {
editPaymentRouteHandler(req, res); editPaymentRouteHandler(req, res);
}); });
@ -111,19 +112,19 @@ router.delete('/:id', isAuthenticated, async (req, res) => {
deletePaymentRouteHandler(req, res); deletePaymentRouteHandler(req, res);
}); });
router.post('/:id/post', isAuthenticated, async (req, res) => { router.post('/:id/post', isAuthenticated, checkPermissions('payment', 'post'), async (req, res) => {
postPaymentRouteHandler(req, res); postPaymentRouteHandler(req, res);
}); });
router.post('/:id/authorise', isAuthenticated, async (req, res) => { router.post('/:id/authorise', isAuthenticated, checkPermissions('payment', 'authorise'), async (req, res) => {
authorisePaymentRouteHandler(req, res); authorisePaymentRouteHandler(req, res);
}); });
router.post('/:id/decline', isAuthenticated, async (req, res) => { router.post('/:id/decline', isAuthenticated, checkPermissions('payment', 'decline'), async (req, res) => {
declinePaymentRouteHandler(req, res); declinePaymentRouteHandler(req, res);
}); });
router.post('/:id/cancel', isAuthenticated, async (req, res) => { router.post('/:id/cancel', isAuthenticated, checkPermissions('payment', 'cancel'), async (req, res) => {
cancelPaymentRouteHandler(req, res); cancelPaymentRouteHandler(req, res);
}); });

View File

@ -1,5 +1,6 @@
import express from 'express'; import express from 'express';
import { isAuthenticated } from '../../keycloak.js'; import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
import { getFilter, convertPropertiesString, getSort } from '../../utils.js'; import { getFilter, convertPropertiesString, getSort } from '../../utils.js';
const router = express.Router(); const router = express.Router();
@ -59,7 +60,7 @@ router.get('/search', isAuthenticated, async (req, res) => {
}); });
router.post('/', isAuthenticated, async (req, res) => { router.post('/', isAuthenticated, checkPermissions('taxRecord', 'new'), async (req, res) => {
newTaxRecordRouteHandler(req, res); newTaxRecordRouteHandler(req, res);
}); });
@ -79,11 +80,11 @@ router.get('/neighbors', isAuthenticated, async (req, res) => {
getTaxRecordNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getTaxRecordNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id);
}); });
router.get('/:id', isAuthenticated, async (req, res) => { router.get('/:id', isAuthenticated, checkPermissions('taxRecord', 'info'), async (req, res) => {
getTaxRecordRouteHandler(req, res); getTaxRecordRouteHandler(req, res);
}); });
router.put('/:id', isAuthenticated, async (req, res) => { router.put('/:id', isAuthenticated, checkPermissions('taxRecord', 'edit'), async (req, res) => {
editTaxRecordRouteHandler(req, res); editTaxRecordRouteHandler(req, res);
}); });

View File

@ -1,5 +1,6 @@
import express from 'express'; import express from 'express';
import { isAuthenticated } from '../../keycloak.js'; import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
import { getFilter, convertPropertiesString, getSort } from '../../utils.js'; import { getFilter, convertPropertiesString, getSort } from '../../utils.js';
const router = express.Router(); const router = express.Router();
@ -69,7 +70,7 @@ router.get('/search', isAuthenticated, async (req, res) => {
}); });
router.post('/', isAuthenticated, async (req, res) => { router.post('/', isAuthenticated, checkPermissions('filamentStock', 'new'), async (req, res) => {
newFilamentStockRouteHandler(req, res); newFilamentStockRouteHandler(req, res);
}); });
@ -89,16 +90,16 @@ router.get('/neighbors', isAuthenticated, async (req, res) => {
getFilamentStockNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getFilamentStockNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id);
}); });
router.get('/:id', isAuthenticated, async (req, res) => { router.get('/:id', isAuthenticated, checkPermissions('filamentStock', 'info'), async (req, res) => {
getFilamentStockRouteHandler(req, res); getFilamentStockRouteHandler(req, res);
}); });
// update multiple filament stocks // update multiple filament stocks
router.put('/', isAuthenticated, async (req, res) => { router.put('/', isAuthenticated, checkPermissions('filamentStock', 'edit'), async (req, res) => {
editMultipleFilamentStocksRouteHandler(req, res); editMultipleFilamentStocksRouteHandler(req, res);
}); });
router.put('/:id', isAuthenticated, async (req, res) => { router.put('/:id', isAuthenticated, checkPermissions('filamentStock', 'edit'), async (req, res) => {
editFilamentStockRouteHandler(req, res); editFilamentStockRouteHandler(req, res);
}); });

View File

@ -1,5 +1,6 @@
import express from 'express'; import express from 'express';
import { isAuthenticated } from '../../keycloak.js'; import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
import { getFilter, convertPropertiesString, getSort } from '../../utils.js'; import { getFilter, convertPropertiesString, getSort } from '../../utils.js';
const router = express.Router(); const router = express.Router();
@ -50,7 +51,17 @@ import {
router.get('/', isAuthenticated, async (req, res) => { router.get('/', isAuthenticated, async (req, res) => {
const { page, limit, property, search, sort, order } = req.query; const { page, limit, property, search, sort, order } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
listOrderItemsRouteHandler(req, res, page, limit, property, filter, search, getSort(sort, listAllowedSorters), order); listOrderItemsRouteHandler(
req,
res,
page,
limit,
property,
filter,
search,
getSort(sort, listAllowedSorters),
order
);
}); });
router.get('/properties', isAuthenticated, async (req, res) => { router.get('/properties', isAuthenticated, async (req, res) => {
@ -72,7 +83,7 @@ router.get('/search', isAuthenticated, async (req, res) => {
searchOrderItemsRouteHandler(req, res, search); searchOrderItemsRouteHandler(req, res, search);
}); });
router.post('/', isAuthenticated, async (req, res) => { router.post('/', isAuthenticated, checkPermissions('orderItem', 'new'), async (req, res) => {
newOrderItemRouteHandler(req, res); newOrderItemRouteHandler(req, res);
}); });
@ -89,19 +100,28 @@ router.get('/history', isAuthenticated, async (req, res) => {
router.get('/neighbors', isAuthenticated, async (req, res) => { router.get('/neighbors', isAuthenticated, async (req, res) => {
const { property, search, sort, order, id } = req.query; const { property, search, sort, order, id } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
getOrderItemNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getOrderItemNeighborsRouteHandler(
req,
res,
property,
filter,
search,
getSort(sort, listAllowedSorters),
order,
id
);
}); });
router.get('/:id', isAuthenticated, async (req, res) => { router.get('/:id', isAuthenticated, checkPermissions('orderItem', 'info'), async (req, res) => {
getOrderItemRouteHandler(req, res); getOrderItemRouteHandler(req, res);
}); });
// update multiple order items // update multiple order items
router.put('/', isAuthenticated, async (req, res) => { router.put('/', isAuthenticated, checkPermissions('orderItem', 'edit'), async (req, res) => {
editMultipleOrderItemsRouteHandler(req, res); editMultipleOrderItemsRouteHandler(req, res);
}); });
router.put('/:id', isAuthenticated, async (req, res) => { router.put('/:id', isAuthenticated, checkPermissions('orderItem', 'edit'), async (req, res) => {
editOrderItemRouteHandler(req, res); editOrderItemRouteHandler(req, res);
}); });

View File

@ -1,5 +1,6 @@
import express from 'express'; import express from 'express';
import { isAuthenticated } from '../../keycloak.js'; import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
import { getFilter, convertPropertiesString, getSort } from '../../utils.js'; import { getFilter, convertPropertiesString, getSort } from '../../utils.js';
const router = express.Router(); const router = express.Router();
@ -61,7 +62,7 @@ router.get('/search', isAuthenticated, async (req, res) => {
}); });
router.post('/', isAuthenticated, async (req, res) => { router.post('/', isAuthenticated, checkPermissions('partStock', 'new'), async (req, res) => {
newPartStockRouteHandler(req, res); newPartStockRouteHandler(req, res);
}); });
@ -81,16 +82,16 @@ router.get('/neighbors', isAuthenticated, async (req, res) => {
getPartStockNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getPartStockNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id);
}); });
router.get('/:id', isAuthenticated, async (req, res) => { router.get('/:id', isAuthenticated, checkPermissions('partStock', 'info'), async (req, res) => {
getPartStockRouteHandler(req, res); getPartStockRouteHandler(req, res);
}); });
// update multiple part stocks // update multiple part stocks
router.put('/', isAuthenticated, async (req, res) => { router.put('/', isAuthenticated, checkPermissions('partStock', 'edit'), async (req, res) => {
editMultiplePartStocksRouteHandler(req, res); editMultiplePartStocksRouteHandler(req, res);
}); });
router.put('/:id', isAuthenticated, async (req, res) => { router.put('/:id', isAuthenticated, checkPermissions('partStock', 'edit'), async (req, res) => {
editPartStockRouteHandler(req, res); editPartStockRouteHandler(req, res);
}); });

View File

@ -1,5 +1,6 @@
import express from 'express'; import express from 'express';
import { isAuthenticated } from '../../keycloak.js'; import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
import { getFilter, convertPropertiesString, getSort } from '../../utils.js'; import { getFilter, convertPropertiesString, getSort } from '../../utils.js';
const router = express.Router(); const router = express.Router();
@ -60,7 +61,7 @@ router.get('/search', isAuthenticated, async (req, res) => {
}); });
router.post('/', isAuthenticated, async (req, res) => { router.post('/', isAuthenticated, checkPermissions('productStock', 'new'), async (req, res) => {
newProductStockRouteHandler(req, res); newProductStockRouteHandler(req, res);
}); });
@ -78,15 +79,15 @@ router.get('/neighbors', isAuthenticated, async (req, res) => {
getProductStockNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getProductStockNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id);
}); });
router.get('/:id', isAuthenticated, async (req, res) => { router.get('/:id', isAuthenticated, checkPermissions('productStock', 'info'), async (req, res) => {
getProductStockRouteHandler(req, res); getProductStockRouteHandler(req, res);
}); });
router.put('/', isAuthenticated, async (req, res) => { router.put('/', isAuthenticated, checkPermissions('productStock', 'edit'), async (req, res) => {
editMultipleProductStocksRouteHandler(req, res); editMultipleProductStocksRouteHandler(req, res);
}); });
router.put('/:id', isAuthenticated, async (req, res) => { router.put('/:id', isAuthenticated, checkPermissions('productStock', 'edit'), async (req, res) => {
editProductStockRouteHandler(req, res); editProductStockRouteHandler(req, res);
}); });
@ -94,7 +95,7 @@ router.delete('/:id', isAuthenticated, async (req, res) => {
deleteProductStockRouteHandler(req, res); deleteProductStockRouteHandler(req, res);
}); });
router.post('/:id/post', isAuthenticated, async (req, res) => { router.post('/:id/post', isAuthenticated, checkPermissions('productStock', 'post'), async (req, res) => {
postProductStockRouteHandler(req, res); postProductStockRouteHandler(req, res);
}); });

View File

@ -1,5 +1,6 @@
import express from 'express'; import express from 'express';
import { isAuthenticated } from '../../keycloak.js'; import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
import { getFilter, convertPropertiesString, getSort } from '../../utils.js'; import { getFilter, convertPropertiesString, getSort } from '../../utils.js';
const router = express.Router(); const router = express.Router();
@ -86,7 +87,7 @@ router.get('/search', isAuthenticated, async (req, res) => {
searchPurchaseOrdersRouteHandler(req, res, search); searchPurchaseOrdersRouteHandler(req, res, search);
}); });
router.post('/', isAuthenticated, async (req, res) => { router.post('/', isAuthenticated, checkPermissions('purchaseOrder', 'new'), async (req, res) => {
newPurchaseOrderRouteHandler(req, res); newPurchaseOrderRouteHandler(req, res);
}); });
@ -106,16 +107,16 @@ router.get('/neighbors', isAuthenticated, async (req, res) => {
getPurchaseOrderNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getPurchaseOrderNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id);
}); });
router.get('/:id', isAuthenticated, async (req, res) => { router.get('/:id', isAuthenticated, checkPermissions('purchaseOrder', 'info'), async (req, res) => {
getPurchaseOrderRouteHandler(req, res); getPurchaseOrderRouteHandler(req, res);
}); });
// update multiple purchase orders // update multiple purchase orders
router.put('/', isAuthenticated, async (req, res) => { router.put('/', isAuthenticated, checkPermissions('purchaseOrder', 'edit'), async (req, res) => {
editMultiplePurchaseOrdersRouteHandler(req, res); editMultiplePurchaseOrdersRouteHandler(req, res);
}); });
router.put('/:id', isAuthenticated, async (req, res) => { router.put('/:id', isAuthenticated, checkPermissions('purchaseOrder', 'edit'), async (req, res) => {
editPurchaseOrderRouteHandler(req, res); editPurchaseOrderRouteHandler(req, res);
}); });
@ -123,15 +124,15 @@ router.delete('/:id', isAuthenticated, async (req, res) => {
deletePurchaseOrderRouteHandler(req, res); deletePurchaseOrderRouteHandler(req, res);
}); });
router.post('/:id/post', isAuthenticated, async (req, res) => { router.post('/:id/post', isAuthenticated, checkPermissions('purchaseOrder', 'post'), async (req, res) => {
postPurchaseOrderRouteHandler(req, res); postPurchaseOrderRouteHandler(req, res);
}); });
router.post('/:id/acknowledge', isAuthenticated, async (req, res) => { router.post('/:id/acknowledge', isAuthenticated, checkPermissions('purchaseOrder', 'acknowledge'), async (req, res) => {
acknowledgePurchaseOrderRouteHandler(req, res); acknowledgePurchaseOrderRouteHandler(req, res);
}); });
router.post('/:id/cancel', isAuthenticated, async (req, res) => { router.post('/:id/cancel', isAuthenticated, checkPermissions('purchaseOrder', 'cancel'), async (req, res) => {
cancelPurchaseOrderRouteHandler(req, res); cancelPurchaseOrderRouteHandler(req, res);
}); });

View File

@ -1,5 +1,6 @@
import express from 'express'; import express from 'express';
import { isAuthenticated } from '../../keycloak.js'; import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
import { getFilter, convertPropertiesString, getSort } from '../../utils.js'; import { getFilter, convertPropertiesString, getSort } from '../../utils.js';
const router = express.Router(); const router = express.Router();
@ -17,7 +18,14 @@ const listAllowedFilters = [
'updatedAt', 'updatedAt',
'_reference', '_reference',
]; ];
const listAllowedSorters = ['createdAt', 'state', 'updatedAt', 'shippedAt', 'expectedAt', 'deliveredAt']; const listAllowedSorters = [
'createdAt',
'state',
'updatedAt',
'shippedAt',
'expectedAt',
'deliveredAt',
];
const propertiesAllowedFilters = [ const propertiesAllowedFilters = [
'orderType', 'orderType',
'order', 'order',
@ -48,7 +56,17 @@ import {
router.get('/', isAuthenticated, async (req, res) => { router.get('/', isAuthenticated, async (req, res) => {
const { page, limit, property, search, sort, order } = req.query; const { page, limit, property, search, sort, order } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
listShipmentsRouteHandler(req, res, page, limit, property, filter, search, getSort(sort, listAllowedSorters), order); listShipmentsRouteHandler(
req,
res,
page,
limit,
property,
filter,
search,
getSort(sort, listAllowedSorters),
order
);
}); });
router.get('/properties', isAuthenticated, async (req, res) => { router.get('/properties', isAuthenticated, async (req, res) => {
@ -56,7 +74,11 @@ router.get('/properties', isAuthenticated, async (req, res) => {
const filter = await getFilter(req.query, propertiesAllowedFilters, false); const filter = await getFilter(req.query, propertiesAllowedFilters, false);
var masterFilter = {}; var masterFilter = {};
if (req.query.masterFilter) { if (req.query.masterFilter) {
masterFilter = await getFilter(JSON.parse(req.query.masterFilter), propertiesAllowedFilters, true); masterFilter = await getFilter(
JSON.parse(req.query.masterFilter),
propertiesAllowedFilters,
true
);
} }
listShipmentsByPropertiesRouteHandler(req, res, properties, filter, masterFilter); listShipmentsByPropertiesRouteHandler(req, res, properties, filter, masterFilter);
}); });
@ -70,7 +92,7 @@ router.get('/search', isAuthenticated, async (req, res) => {
searchShipmentsRouteHandler(req, res, search); searchShipmentsRouteHandler(req, res, search);
}); });
router.post('/', isAuthenticated, async (req, res) => { router.post('/', isAuthenticated, checkPermissions('shipment', 'new'), async (req, res) => {
newShipmentRouteHandler(req, res); newShipmentRouteHandler(req, res);
}); });
@ -87,19 +109,28 @@ router.get('/history', isAuthenticated, async (req, res) => {
router.get('/neighbors', isAuthenticated, async (req, res) => { router.get('/neighbors', isAuthenticated, async (req, res) => {
const { property, search, sort, order, id } = req.query; const { property, search, sort, order, id } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
getShipmentNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getShipmentNeighborsRouteHandler(
req,
res,
property,
filter,
search,
getSort(sort, listAllowedSorters),
order,
id
);
}); });
router.get('/:id', isAuthenticated, async (req, res) => { router.get('/:id', isAuthenticated, checkPermissions('shipment', 'info'), async (req, res) => {
getShipmentRouteHandler(req, res); getShipmentRouteHandler(req, res);
}); });
// update multiple shipments // update multiple shipments
router.put('/', isAuthenticated, async (req, res) => { router.put('/', isAuthenticated, checkPermissions('shipment', 'edit'), async (req, res) => {
editMultipleShipmentsRouteHandler(req, res); editMultipleShipmentsRouteHandler(req, res);
}); });
router.put('/:id', isAuthenticated, async (req, res) => { router.put('/:id', isAuthenticated, checkPermissions('shipment', 'edit'), async (req, res) => {
editShipmentRouteHandler(req, res); editShipmentRouteHandler(req, res);
}); });
@ -107,16 +138,31 @@ router.delete('/:id', isAuthenticated, async (req, res) => {
deleteShipmentRouteHandler(req, res); deleteShipmentRouteHandler(req, res);
}); });
router.post('/:id/ship', isAuthenticated, async (req, res) => { router.post(
shipShipmentRouteHandler(req, res); '/:id/ship',
}); isAuthenticated,
checkPermissions('shipment', 'ship'),
async (req, res) => {
shipShipmentRouteHandler(req, res);
}
);
router.post('/:id/receive', isAuthenticated, async (req, res) => { router.post(
receiveShipmentRouteHandler(req, res); '/:id/receive',
}); isAuthenticated,
checkPermissions('shipment', 'receive'),
async (req, res) => {
receiveShipmentRouteHandler(req, res);
}
);
router.post('/:id/cancel', isAuthenticated, async (req, res) => { router.post(
cancelShipmentRouteHandler(req, res); '/:id/cancel',
}); isAuthenticated,
checkPermissions('shipment', 'cancel'),
async (req, res) => {
cancelShipmentRouteHandler(req, res);
}
);
export default router; export default router;

View File

@ -1,5 +1,6 @@
import express from 'express'; import express from 'express';
import { isAuthenticated } from '../../keycloak.js'; import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
import { parseFilter, getFilter, getSort } from '../../utils.js'; import { parseFilter, getFilter, getSort } from '../../utils.js';
const router = express.Router(); const router = express.Router();
@ -45,7 +46,7 @@ router.get('/', isAuthenticated, async (req, res) => {
}); });
// Create new stock audit // Create new stock audit
router.post('/', isAuthenticated, async (req, res) => { router.post('/', isAuthenticated, checkPermissions('stockAudit', 'new'), async (req, res) => {
newStockAuditRouteHandler(req, res); newStockAuditRouteHandler(req, res);
}); });
@ -71,12 +72,12 @@ router.get('/neighbors', isAuthenticated, async (req, res) => {
}); });
// Get specific stock audit // Get specific stock audit
router.get('/:id', isAuthenticated, async (req, res) => { router.get('/:id', isAuthenticated, checkPermissions('stockAudit', 'info'), async (req, res) => {
getStockAuditRouteHandler(req, res); getStockAuditRouteHandler(req, res);
}); });
// Update stock audit // Update stock audit
router.put('/:id', isAuthenticated, async (req, res) => { router.put('/:id', isAuthenticated, checkPermissions('stockAudit', 'edit'), async (req, res) => {
updateStockAuditRouteHandler(req, res); updateStockAuditRouteHandler(req, res);
}); });

View File

@ -1,5 +1,6 @@
import express from 'express'; import express from 'express';
import { isAuthenticated } from '../../keycloak.js'; import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
import { getFilter, convertPropertiesString, getSort } from '../../utils.js'; import { getFilter, convertPropertiesString, getSort } from '../../utils.js';
const router = express.Router(); const router = express.Router();
@ -50,7 +51,7 @@ router.get('/search', isAuthenticated, async (req, res) => {
}); });
router.post('/', isAuthenticated, async (req, res) => { router.post('/', isAuthenticated, checkPermissions('stockEvent', 'new'), async (req, res) => {
newStockEventRouteHandler(req, res); newStockEventRouteHandler(req, res);
}); });
@ -70,16 +71,16 @@ router.get('/neighbors', isAuthenticated, async (req, res) => {
getStockEventNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getStockEventNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id);
}); });
router.get('/:id', isAuthenticated, async (req, res) => { router.get('/:id', isAuthenticated, checkPermissions('stockEvent', 'info'), async (req, res) => {
getStockEventRouteHandler(req, res); getStockEventRouteHandler(req, res);
}); });
// update multiple stock events // update multiple stock events
router.put('/', isAuthenticated, async (req, res) => { router.put('/', isAuthenticated, checkPermissions('stockEvent', 'edit'), async (req, res) => {
editMultipleStockEventsRouteHandler(req, res); editMultipleStockEventsRouteHandler(req, res);
}); });
router.put('/:id', isAuthenticated, async (req, res) => { router.put('/:id', isAuthenticated, checkPermissions('stockEvent', 'edit'), async (req, res) => {
editStockEventRouteHandler(req, res); editStockEventRouteHandler(req, res);
}); });

View File

@ -1,5 +1,6 @@
import express from 'express'; import express from 'express';
import { isAuthenticated } from '../../keycloak.js'; import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
import { getFilter, convertPropertiesString, getSort } from '../../utils.js'; import { getFilter, convertPropertiesString, getSort } from '../../utils.js';
const router = express.Router(); const router = express.Router();
@ -49,7 +50,7 @@ router.get('/search', isAuthenticated, async (req, res) => {
}); });
router.post('/', isAuthenticated, async (req, res) => { router.post('/', isAuthenticated, checkPermissions('stockLocation', 'new'), async (req, res) => {
newStockLocationRouteHandler(req, res); newStockLocationRouteHandler(req, res);
}); });
@ -67,15 +68,15 @@ router.get('/neighbors', isAuthenticated, async (req, res) => {
getStockLocationNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getStockLocationNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id);
}); });
router.get('/:id', isAuthenticated, async (req, res) => { router.get('/:id', isAuthenticated, checkPermissions('stockLocation', 'info'), async (req, res) => {
getStockLocationRouteHandler(req, res); getStockLocationRouteHandler(req, res);
}); });
router.put('/', isAuthenticated, async (req, res) => { router.put('/', isAuthenticated, checkPermissions('stockLocation', 'edit'), async (req, res) => {
editMultipleStockLocationsRouteHandler(req, res); editMultipleStockLocationsRouteHandler(req, res);
}); });
router.put('/:id', isAuthenticated, async (req, res) => { router.put('/:id', isAuthenticated, checkPermissions('stockLocation', 'edit'), async (req, res) => {
editStockLocationRouteHandler(req, res); editStockLocationRouteHandler(req, res);
}); });

View File

@ -1,5 +1,6 @@
import express from 'express'; import express from 'express';
import { isAuthenticated } from '../../keycloak.js'; import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
import { getFilter, convertPropertiesString, getSort } from '../../utils.js'; import { getFilter, convertPropertiesString, getSort } from '../../utils.js';
const router = express.Router(); const router = express.Router();
@ -58,7 +59,7 @@ router.get('/search', isAuthenticated, async (req, res) => {
}); });
router.post('/', isAuthenticated, async (req, res) => { router.post('/', isAuthenticated, checkPermissions('stockTransfer', 'new'), async (req, res) => {
newStockTransferRouteHandler(req, res); newStockTransferRouteHandler(req, res);
}); });
@ -76,15 +77,15 @@ router.get('/neighbors', isAuthenticated, async (req, res) => {
getStockTransferNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getStockTransferNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id);
}); });
router.get('/:id', isAuthenticated, async (req, res) => { router.get('/:id', isAuthenticated, checkPermissions('stockTransfer', 'info'), async (req, res) => {
getStockTransferRouteHandler(req, res); getStockTransferRouteHandler(req, res);
}); });
router.put('/', isAuthenticated, async (req, res) => { router.put('/', isAuthenticated, checkPermissions('stockTransfer', 'edit'), async (req, res) => {
editMultipleStockTransfersRouteHandler(req, res); editMultipleStockTransfersRouteHandler(req, res);
}); });
router.put('/:id', isAuthenticated, async (req, res) => { router.put('/:id', isAuthenticated, checkPermissions('stockTransfer', 'edit'), async (req, res) => {
editStockTransferRouteHandler(req, res); editStockTransferRouteHandler(req, res);
}); });
@ -92,7 +93,7 @@ router.delete('/:id', isAuthenticated, async (req, res) => {
deleteStockTransferRouteHandler(req, res); deleteStockTransferRouteHandler(req, res);
}); });
router.post('/:id/post', isAuthenticated, async (req, res) => { router.post('/:id/post', isAuthenticated, checkPermissions('stockTransfer', 'post'), async (req, res) => {
postStockTransferRouteHandler(req, res); postStockTransferRouteHandler(req, res);
}); });

View File

@ -1,5 +1,6 @@
import express from 'express'; import express from 'express';
import { isAuthenticated } from '../../keycloak.js'; import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
import { getFilter, convertPropertiesString, getSort } from '../../utils.js'; import { getFilter, convertPropertiesString, getSort } from '../../utils.js';
const router = express.Router(); const router = express.Router();
@ -55,7 +56,7 @@ router.get('/search', isAuthenticated, async (req, res) => {
searchAppPasswordsRouteHandler(req, res, search); searchAppPasswordsRouteHandler(req, res, search);
}); });
router.post('/', isAuthenticated, async (req, res) => { router.post('/', isAuthenticated, checkPermissions('user', 'newAppPassword'), async (req, res) => {
newAppPasswordRouteHandler(req, res); newAppPasswordRouteHandler(req, res);
}); });
@ -67,7 +68,7 @@ router.get('/history', isAuthenticated, async (req, res) => {
getAppPasswordHistoryRouteHandler(req, res); getAppPasswordHistoryRouteHandler(req, res);
}); });
router.post('/:id/regenerateSecret', isAuthenticated, async (req, res) => { router.post('/:id/regenerateSecret', isAuthenticated, checkPermissions('appPassword', 'regenerateSecret'), async (req, res) => {
regenerateSecretRouteHandler(req, res); regenerateSecretRouteHandler(req, res);
}); });
@ -81,7 +82,7 @@ router.get('/:id', isAuthenticated, async (req, res) => {
getAppPasswordRouteHandler(req, res); getAppPasswordRouteHandler(req, res);
}); });
router.put('/:id', isAuthenticated, async (req, res) => { router.put('/:id', isAuthenticated, checkPermissions('appPassword', 'edit'), async (req, res) => {
editAppPasswordRouteHandler(req, res); editAppPasswordRouteHandler(req, res);
}); });

View File

@ -1,5 +1,6 @@
import express from 'express'; import express from 'express';
import { isAuthenticated } from '../../keycloak.js'; import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
import { getFilter, convertPropertiesString, getSort } from '../../utils.js'; import { getFilter, convertPropertiesString, getSort } from '../../utils.js';
const router = express.Router(); const router = express.Router();
@ -59,7 +60,7 @@ router.get('/search', isAuthenticated, async (req, res) => {
searchCouriersRouteHandler(req, res, search); searchCouriersRouteHandler(req, res, search);
}); });
router.post('/', isAuthenticated, async (req, res) => { router.post('/', isAuthenticated, checkPermissions('courier', 'new'), async (req, res) => {
newCourierRouteHandler(req, res); newCourierRouteHandler(req, res);
}); });
@ -83,7 +84,7 @@ router.get('/:id', isAuthenticated, async (req, res) => {
getCourierRouteHandler(req, res); getCourierRouteHandler(req, res);
}); });
router.put('/:id', isAuthenticated, async (req, res) => { router.put('/:id', isAuthenticated, checkPermissions('courier', 'edit'), async (req, res) => {
editCourierRouteHandler(req, res); editCourierRouteHandler(req, res);
}); });

View File

@ -1,5 +1,6 @@
import express from 'express'; import express from 'express';
import { isAuthenticated } from '../../keycloak.js'; import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
import { getFilter, convertPropertiesString, getSort } from '../../utils.js'; import { getFilter, convertPropertiesString, getSort } from '../../utils.js';
const router = express.Router(); const router = express.Router();
@ -83,7 +84,7 @@ router.get('/search', isAuthenticated, async (req, res) => {
searchCourierServicesRouteHandler(req, res, search); searchCourierServicesRouteHandler(req, res, search);
}); });
router.post('/', isAuthenticated, async (req, res) => { router.post('/', isAuthenticated, checkPermissions('courierService', 'new'), async (req, res) => {
newCourierServiceRouteHandler(req, res); newCourierServiceRouteHandler(req, res);
}); });
@ -107,7 +108,7 @@ router.get('/:id', isAuthenticated, async (req, res) => {
getCourierServiceRouteHandler(req, res); getCourierServiceRouteHandler(req, res);
}); });
router.put('/:id', isAuthenticated, async (req, res) => { router.put('/:id', isAuthenticated, checkPermissions('courierService', 'edit'), async (req, res) => {
editCourierServiceRouteHandler(req, res); editCourierServiceRouteHandler(req, res);
}); });

View File

@ -1,5 +1,6 @@
import express from 'express'; import express from 'express';
import { isAuthenticated } from '../../keycloak.js'; import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
import { getFilter, convertPropertiesString, getSort } from '../../utils.js'; import { getFilter, convertPropertiesString, getSort } from '../../utils.js';
const router = express.Router(); const router = express.Router();
@ -57,7 +58,7 @@ router.get('/search', isAuthenticated, async (req, res) => {
searchDocumentJobsRouteHandler(req, res, search); searchDocumentJobsRouteHandler(req, res, search);
}); });
router.post('/', isAuthenticated, async (req, res) => { router.post('/', isAuthenticated, checkPermissions('documentJob', 'new'), async (req, res) => {
newDocumentJobRouteHandler(req, res); newDocumentJobRouteHandler(req, res);
}); });
@ -81,7 +82,7 @@ router.get('/:id', isAuthenticated, async (req, res) => {
getDocumentJobRouteHandler(req, res); getDocumentJobRouteHandler(req, res);
}); });
router.put('/:id', isAuthenticated, async (req, res) => { router.put('/:id', isAuthenticated, checkPermissions('documentJob', 'edit'), async (req, res) => {
editDocumentJobRouteHandler(req, res); editDocumentJobRouteHandler(req, res);
}); });

View File

@ -1,5 +1,6 @@
import express from 'express'; import express from 'express';
import { isAuthenticated } from '../../keycloak.js'; import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
import { getFilter, convertPropertiesString, getSort } from '../../utils.js'; import { getFilter, convertPropertiesString, getSort } from '../../utils.js';
const router = express.Router(); const router = express.Router();
@ -58,7 +59,7 @@ router.get('/search', isAuthenticated, async (req, res) => {
searchDocumentPrintersRouteHandler(req, res, search); searchDocumentPrintersRouteHandler(req, res, search);
}); });
router.post('/', isAuthenticated, async (req, res) => { router.post('/', isAuthenticated, checkPermissions('documentPrinter', 'new'), async (req, res) => {
newDocumentPrinterRouteHandler(req, res); newDocumentPrinterRouteHandler(req, res);
}); });
@ -82,7 +83,7 @@ router.get('/:id', isAuthenticated, async (req, res) => {
getDocumentPrinterRouteHandler(req, res); getDocumentPrinterRouteHandler(req, res);
}); });
router.put('/:id', isAuthenticated, async (req, res) => { router.put('/:id', isAuthenticated, checkPermissions('documentPrinter', 'edit'), async (req, res) => {
editDocumentPrinterRouteHandler(req, res); editDocumentPrinterRouteHandler(req, res);
}); });

View File

@ -1,5 +1,6 @@
import express from 'express'; import express from 'express';
import { isAuthenticated } from '../../keycloak.js'; import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
import { getFilter, convertPropertiesString, getSort } from '../../utils.js'; import { getFilter, convertPropertiesString, getSort } from '../../utils.js';
const router = express.Router(); const router = express.Router();
@ -49,7 +50,7 @@ router.get('/search', isAuthenticated, async (req, res) => {
searchDocumentSizesRouteHandler(req, res, search); searchDocumentSizesRouteHandler(req, res, search);
}); });
router.post('/', isAuthenticated, async (req, res) => { router.post('/', isAuthenticated, checkPermissions('documentSize', 'new'), async (req, res) => {
newDocumentSizeRouteHandler(req, res); newDocumentSizeRouteHandler(req, res);
}); });
@ -73,7 +74,7 @@ router.get('/:id', isAuthenticated, async (req, res) => {
getDocumentSizeRouteHandler(req, res); getDocumentSizeRouteHandler(req, res);
}); });
router.put('/:id', isAuthenticated, async (req, res) => { router.put('/:id', isAuthenticated, checkPermissions('documentSize', 'edit'), async (req, res) => {
editDocumentSizeRouteHandler(req, res); editDocumentSizeRouteHandler(req, res);
}); });

View File

@ -1,5 +1,6 @@
import express from 'express'; import express from 'express';
import { isAuthenticated } from '../../keycloak.js'; import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
import { getFilter, convertPropertiesString, getSort } from '../../utils.js'; import { getFilter, convertPropertiesString, getSort } from '../../utils.js';
const router = express.Router(); const router = express.Router();
@ -73,11 +74,11 @@ router.get('/search', isAuthenticated, async (req, res) => {
searchDocumentTemplatesRouteHandler(req, res, search); searchDocumentTemplatesRouteHandler(req, res, search);
}); });
router.post('/', isAuthenticated, async (req, res) => { router.post('/', isAuthenticated, checkPermissions('documentTemplate', 'new'), async (req, res) => {
newDocumentTemplateRouteHandler(req, res); newDocumentTemplateRouteHandler(req, res);
}); });
router.post('/format', isAuthenticated, async (req, res) => { router.post('/format', isAuthenticated, checkPermissions('documentTemplate', 'design'), async (req, res) => {
formatDocumentTemplateRouteHandler(req, res); formatDocumentTemplateRouteHandler(req, res);
}); });
@ -97,11 +98,11 @@ router.get('/neighbors', isAuthenticated, async (req, res) => {
getDocumentTemplateNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getDocumentTemplateNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id);
}); });
router.post('/:id/preview', isAuthenticated, async (req, res) => { router.post('/:id/preview', isAuthenticated, checkPermissions('documentTemplate', 'design'), async (req, res) => {
previewDocumentTemplateRouteHandler(req, res); previewDocumentTemplateRouteHandler(req, res);
}); });
router.post('/:id/download', isAuthenticated, async (req, res) => { router.post('/:id/download', isAuthenticated, checkPermissions('documentTemplate', 'design'), async (req, res) => {
downloadDocumentTemplateRouteHandler(req, res); downloadDocumentTemplateRouteHandler(req, res);
}); });
@ -109,7 +110,7 @@ router.get('/:id', isAuthenticated, async (req, res) => {
getDocumentTemplateRouteHandler(req, res); getDocumentTemplateRouteHandler(req, res);
}); });
router.put('/:id', isAuthenticated, async (req, res) => { router.put('/:id', isAuthenticated, checkPermissions('documentTemplate', 'edit'), async (req, res) => {
editDocumentTemplateRouteHandler(req, res); editDocumentTemplateRouteHandler(req, res);
}); });

View File

@ -1,5 +1,6 @@
import express from 'express'; import express from 'express';
import { isAuthenticated } from '../../keycloak.js'; import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
import { convertPropertiesString, getFilter, parseFilter, getSort } from '../../utils.js'; import { convertPropertiesString, getFilter, parseFilter, getSort } from '../../utils.js';
const router = express.Router(); const router = express.Router();
@ -79,7 +80,7 @@ router.get('/search', isAuthenticated, async (req, res) => {
searchFilamentsRouteHandler(req, res, search); searchFilamentsRouteHandler(req, res, search);
}); });
router.post('/', isAuthenticated, async (req, res) => { router.post('/', isAuthenticated, checkPermissions('filament', 'new'), async (req, res) => {
newFilamentRouteHandler(req, res); newFilamentRouteHandler(req, res);
}); });
@ -104,12 +105,12 @@ router.get('/:id', isAuthenticated, async (req, res) => {
}); });
// update filaments info // update filaments info
router.put('/', isAuthenticated, async (req, res) => { router.put('/', isAuthenticated, checkPermissions('filament', 'edit'), async (req, res) => {
editMultipleFilamentsRouteHandler(req, res); editMultipleFilamentsRouteHandler(req, res);
}); });
// update filament info // update filament info
router.put('/:id', isAuthenticated, async (req, res) => { router.put('/:id', isAuthenticated, checkPermissions('filament', 'edit'), async (req, res) => {
editFilamentRouteHandler(req, res); editFilamentRouteHandler(req, res);
}); });

View File

@ -1,5 +1,6 @@
import express from 'express'; import express from 'express';
import { isAuthenticated } from '../../keycloak.js'; import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
import { getFilter, convertPropertiesString, getSort } from '../../utils.js'; import { getFilter, convertPropertiesString, getSort } from '../../utils.js';
const router = express.Router(); const router = express.Router();
@ -67,7 +68,7 @@ router.get('/search', isAuthenticated, async (req, res) => {
searchFilamentSkusRouteHandler(req, res, search); searchFilamentSkusRouteHandler(req, res, search);
}); });
router.post('/', isAuthenticated, async (req, res) => { router.post('/', isAuthenticated, checkPermissions('filament', 'newFilamentSku'), async (req, res) => {
newFilamentSkuRouteHandler(req, res); newFilamentSkuRouteHandler(req, res);
}); });
@ -89,7 +90,7 @@ router.get('/:id', isAuthenticated, async (req, res) => {
getFilamentSkuRouteHandler(req, res); getFilamentSkuRouteHandler(req, res);
}); });
router.put('/:id', isAuthenticated, async (req, res) => { router.put('/:id', isAuthenticated, checkPermissions('filamentSku', 'edit'), async (req, res) => {
editFilamentSkuRouteHandler(req, res); editFilamentSkuRouteHandler(req, res);
}); });

View File

@ -1,5 +1,6 @@
import express from 'express'; import express from 'express';
import { isAuthenticated } from '../../keycloak.js'; import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
import { getFilter, convertPropertiesString, getSort } from '../../utils.js'; import { getFilter, convertPropertiesString, getSort } from '../../utils.js';
const router = express.Router(); const router = express.Router();
@ -61,7 +62,7 @@ router.get('/search', isAuthenticated, async (req, res) => {
searchFilesRouteHandler(req, res, search); searchFilesRouteHandler(req, res, search);
}); });
router.post('/', isAuthenticated, async (req, res) => { router.post('/', isAuthenticated, checkPermissions('file', 'new'), async (req, res) => {
newFileRouteHandler(req, res); newFileRouteHandler(req, res);
}); });
@ -97,7 +98,7 @@ router.get('/:id/thumbnail', isAuthenticated, async (req, res) => {
getFileThumbnailRouteHandler(req, res); getFileThumbnailRouteHandler(req, res);
}); });
router.put('/:id', isAuthenticated, async (req, res) => { router.put('/:id', isAuthenticated, checkPermissions('file', 'edit'), async (req, res) => {
editFileRouteHandler(req, res); editFileRouteHandler(req, res);
}); });

View File

@ -1,5 +1,6 @@
import express from 'express'; import express from 'express';
import { isAuthenticated } from '../../keycloak.js'; import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
import { getFilter, convertPropertiesString, getSort } from '../../utils.js'; import { getFilter, convertPropertiesString, getSort } from '../../utils.js';
const router = express.Router(); const router = express.Router();
@ -57,7 +58,7 @@ router.get('/search', isAuthenticated, async (req, res) => {
searchHostsRouteHandler(req, res, search); searchHostsRouteHandler(req, res, search);
}); });
router.post('/', isAuthenticated, async (req, res) => { router.post('/', isAuthenticated, checkPermissions('host', 'new'), async (req, res) => {
newHostRouteHandler(req, res); newHostRouteHandler(req, res);
}); });
@ -81,7 +82,7 @@ router.get('/:id', isAuthenticated, async (req, res) => {
getHostRouteHandler(req, res); getHostRouteHandler(req, res);
}); });
router.put('/:id', isAuthenticated, async (req, res) => { router.put('/:id', isAuthenticated, checkPermissions('host', 'edit'), async (req, res) => {
editHostRouteHandler(req, res); editHostRouteHandler(req, res);
}); });

View File

@ -1,5 +1,6 @@
import express from 'express'; import express from 'express';
import { isAuthenticated } from '../../keycloak.js'; import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
import { convertPropertiesString, getFilter, parseFilter, getSort } from '../../utils.js'; import { convertPropertiesString, getFilter, parseFilter, getSort } from '../../utils.js';
const router = express.Router(); const router = express.Router();
@ -57,7 +58,7 @@ router.get('/search', isAuthenticated, async (req, res) => {
searchMaterialsRouteHandler(req, res, search); searchMaterialsRouteHandler(req, res, search);
}); });
router.post('/', isAuthenticated, async (req, res) => { router.post('/', isAuthenticated, checkPermissions('material', 'new'), async (req, res) => {
newMaterialRouteHandler(req, res); newMaterialRouteHandler(req, res);
}); });
@ -82,7 +83,7 @@ router.get('/:id', isAuthenticated, async (req, res) => {
}); });
// update material info // update material info
router.put('/:id', isAuthenticated, async (req, res) => { router.put('/:id', isAuthenticated, checkPermissions('material', 'edit'), async (req, res) => {
editMaterialRouteHandler(req, res); editMaterialRouteHandler(req, res);
}); });

View File

@ -1,5 +1,6 @@
import express from 'express'; import express from 'express';
import { isAuthenticated } from '../../keycloak.js'; import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
import { getFilter, convertPropertiesString, getSort } from '../../utils.js'; import { getFilter, convertPropertiesString, getSort } from '../../utils.js';
const router = express.Router(); const router = express.Router();
@ -57,7 +58,7 @@ router.get('/search', isAuthenticated, async (req, res) => {
}); });
router.post('/', isAuthenticated, async (req, res) => { router.post('/', isAuthenticated, checkPermissions('noteType', 'new'), async (req, res) => {
newNoteTypeRouteHandler(req, res); newNoteTypeRouteHandler(req, res);
}); });
@ -81,7 +82,7 @@ router.get('/:id', isAuthenticated, async (req, res) => {
getNoteTypeRouteHandler(req, res); getNoteTypeRouteHandler(req, res);
}); });
router.put('/:id', isAuthenticated, async (req, res) => { router.put('/:id', isAuthenticated, checkPermissions('noteType', 'edit'), async (req, res) => {
editNoteTypeRouteHandler(req, res); editNoteTypeRouteHandler(req, res);
}); });

View File

@ -1,5 +1,6 @@
import express from 'express'; import express from 'express';
import { isAuthenticated } from '../../keycloak.js'; import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
import { getFilter, convertPropertiesString, getSort } from '../../utils.js'; import { getFilter, convertPropertiesString, getSort } from '../../utils.js';
const router = express.Router(); const router = express.Router();
@ -28,15 +29,24 @@ import {
getPartHistoryRouteHandler, getPartHistoryRouteHandler,
searchPartsRouteHandler, searchPartsRouteHandler,
getPartPropertyValuesRouteHandler, getPartPropertyValuesRouteHandler,
getPartNeighborsRouteHandler,
getPartNeighborsRouteHandler
} from '../../services/management/parts.js'; } from '../../services/management/parts.js';
// list of parts // list of parts
router.get('/', isAuthenticated, async (req, res) => { router.get('/', isAuthenticated, async (req, res) => {
const { page, limit, property, search, sort, order } = req.query; const { page, limit, property, search, sort, order } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
listPartsRouteHandler(req, res, page, limit, property, filter, search, getSort(sort, listAllowedSorters), order); listPartsRouteHandler(
req,
res,
page,
limit,
property,
filter,
search,
getSort(sort, listAllowedSorters),
order
);
}); });
router.get('/properties', isAuthenticated, async (req, res) => { router.get('/properties', isAuthenticated, async (req, res) => {
@ -59,7 +69,7 @@ router.get('/search', isAuthenticated, async (req, res) => {
searchPartsRouteHandler(req, res, search); searchPartsRouteHandler(req, res, search);
}); });
router.post('/', isAuthenticated, async (req, res) => { router.post('/', isAuthenticated, checkPermissions('part', 'new'), async (req, res) => {
newPartRouteHandler(req, res); newPartRouteHandler(req, res);
}); });
@ -76,14 +86,23 @@ router.get('/history', isAuthenticated, async (req, res) => {
router.get('/neighbors', isAuthenticated, async (req, res) => { router.get('/neighbors', isAuthenticated, async (req, res) => {
const { property, search, sort, order, id } = req.query; const { property, search, sort, order, id } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
getPartNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getPartNeighborsRouteHandler(
req,
res,
property,
filter,
search,
getSort(sort, listAllowedSorters),
order,
id
);
}); });
router.get('/:id', isAuthenticated, async (req, res) => { router.get('/:id', isAuthenticated, async (req, res) => {
getPartRouteHandler(req, res); getPartRouteHandler(req, res);
}); });
router.put('/:id', isAuthenticated, async (req, res) => { router.put('/:id', isAuthenticated, checkPermissions('part', 'edit'), async (req, res) => {
editPartRouteHandler(req, res); editPartRouteHandler(req, res);
}); });

View File

@ -1,5 +1,6 @@
import express from 'express'; import express from 'express';
import { isAuthenticated } from '../../keycloak.js'; import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
import { getFilter, convertPropertiesString, getSort } from '../../utils.js'; import { getFilter, convertPropertiesString, getSort } from '../../utils.js';
const router = express.Router(); const router = express.Router();
@ -69,7 +70,7 @@ router.get('/search', isAuthenticated, async (req, res) => {
}); });
router.post('/', isAuthenticated, async (req, res) => { router.post('/', isAuthenticated, checkPermissions('part', 'newPartSku'), async (req, res) => {
newPartSkuRouteHandler(req, res); newPartSkuRouteHandler(req, res);
}); });
@ -91,7 +92,7 @@ router.get('/:id', isAuthenticated, async (req, res) => {
getPartSkuRouteHandler(req, res); getPartSkuRouteHandler(req, res);
}); });
router.put('/:id', isAuthenticated, async (req, res) => { router.put('/:id', isAuthenticated, checkPermissions('partSku', 'edit'), async (req, res) => {
editPartSkuRouteHandler(req, res); editPartSkuRouteHandler(req, res);
}); });

View File

@ -1,5 +1,6 @@
import express from 'express'; import express from 'express';
import { isAuthenticated } from '../../keycloak.js'; import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
import { getFilter, convertPropertiesString, getSort } from '../../utils.js'; import { getFilter, convertPropertiesString, getSort } from '../../utils.js';
const router = express.Router(); const router = express.Router();
@ -57,7 +58,7 @@ router.get('/search', isAuthenticated, async (req, res) => {
searchPermissionSettingsRouteHandler(req, res, search); searchPermissionSettingsRouteHandler(req, res, search);
}); });
router.post('/', isAuthenticated, async (req, res) => { router.post('/', isAuthenticated, checkPermissions('permissionSetting', 'new'), async (req, res) => {
newPermissionSettingsRouteHandler(req, res); newPermissionSettingsRouteHandler(req, res);
}); });
@ -88,7 +89,7 @@ router.get('/:id', isAuthenticated, async (req, res) => {
getPermissionSettingsRouteHandler(req, res); getPermissionSettingsRouteHandler(req, res);
}); });
router.put('/:id', isAuthenticated, async (req, res) => { router.put('/:id', isAuthenticated, checkPermissions('permissionSetting', 'edit'), async (req, res) => {
editPermissionSettingsRouteHandler(req, res); editPermissionSettingsRouteHandler(req, res);
}); });

View File

@ -1,5 +1,6 @@
import express from 'express'; import express from 'express';
import { isAuthenticated } from '../../keycloak.js'; import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
import { convertPropertiesString, getFilter, getSort } from '../../utils.js'; import { convertPropertiesString, getFilter, getSort } from '../../utils.js';
import { import {
deleteProductCategoryRouteHandler, deleteProductCategoryRouteHandler,
@ -48,7 +49,7 @@ router.get('/search', isAuthenticated, async (req, res) => {
searchProductCategoriesRouteHandler(req, res, search); searchProductCategoriesRouteHandler(req, res, search);
}); });
router.post('/', isAuthenticated, async (req, res) => { router.post('/', isAuthenticated, checkPermissions('productCategory', 'new'), async (req, res) => {
newProductCategoryRouteHandler(req, res); newProductCategoryRouteHandler(req, res);
}); });
@ -70,7 +71,7 @@ router.get('/:id', isAuthenticated, async (req, res) => {
getProductCategoryRouteHandler(req, res); getProductCategoryRouteHandler(req, res);
}); });
router.put('/:id', isAuthenticated, async (req, res) => { router.put('/:id', isAuthenticated, checkPermissions('productCategory', 'edit'), async (req, res) => {
editProductCategoryRouteHandler(req, res); editProductCategoryRouteHandler(req, res);
}); });

View File

@ -1,5 +1,6 @@
import express from 'express'; import express from 'express';
import { isAuthenticated } from '../../keycloak.js'; import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
import { getFilter, convertPropertiesString, getSort } from '../../utils.js'; import { getFilter, convertPropertiesString, getSort } from '../../utils.js';
const router = express.Router(); const router = express.Router();
@ -69,7 +70,7 @@ router.get('/search', isAuthenticated, async (req, res) => {
searchProductsRouteHandler(req, res, search); searchProductsRouteHandler(req, res, search);
}); });
router.post('/', isAuthenticated, async (req, res) => { router.post('/', isAuthenticated, checkPermissions('product', 'new'), async (req, res) => {
newProductRouteHandler(req, res); newProductRouteHandler(req, res);
}); });
@ -93,7 +94,7 @@ router.get('/:id', isAuthenticated, async (req, res) => {
getProductRouteHandler(req, res); getProductRouteHandler(req, res);
}); });
router.put('/:id', isAuthenticated, async (req, res) => { router.put('/:id', isAuthenticated, checkPermissions('product', 'edit'), async (req, res) => {
editProductRouteHandler(req, res); editProductRouteHandler(req, res);
}); });

View File

@ -1,5 +1,6 @@
import express from 'express'; import express from 'express';
import { isAuthenticated } from '../../keycloak.js'; import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
import { getFilter, convertPropertiesString, getSort } from '../../utils.js'; import { getFilter, convertPropertiesString, getSort } from '../../utils.js';
const router = express.Router(); const router = express.Router();
@ -69,7 +70,7 @@ router.get('/search', isAuthenticated, async (req, res) => {
}); });
router.post('/', isAuthenticated, async (req, res) => { router.post('/', isAuthenticated, checkPermissions('product', 'newProductSku'), async (req, res) => {
newProductSkuRouteHandler(req, res); newProductSkuRouteHandler(req, res);
}); });
@ -91,7 +92,7 @@ router.get('/:id', isAuthenticated, async (req, res) => {
getProductSkuRouteHandler(req, res); getProductSkuRouteHandler(req, res);
}); });
router.put('/:id', isAuthenticated, async (req, res) => { router.put('/:id', isAuthenticated, checkPermissions('productSku', 'edit'), async (req, res) => {
editProductSkuRouteHandler(req, res); editProductSkuRouteHandler(req, res);
}); });

View File

@ -1,5 +1,6 @@
import express from 'express'; import express from 'express';
import { isAuthenticated } from '../../keycloak.js'; import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
import { getFilter, convertPropertiesString, getSort } from '../../utils.js'; import { getFilter, convertPropertiesString, getSort } from '../../utils.js';
const router = express.Router(); const router = express.Router();
@ -67,7 +68,7 @@ router.get('/search', isAuthenticated, async (req, res) => {
searchTaxRatesRouteHandler(req, res, search); searchTaxRatesRouteHandler(req, res, search);
}); });
router.post('/', isAuthenticated, async (req, res) => { router.post('/', isAuthenticated, checkPermissions('taxRate', 'new'), async (req, res) => {
newTaxRateRouteHandler(req, res); newTaxRateRouteHandler(req, res);
}); });
@ -91,7 +92,7 @@ router.get('/:id', isAuthenticated, async (req, res) => {
getTaxRateRouteHandler(req, res); getTaxRateRouteHandler(req, res);
}); });
router.put('/:id', isAuthenticated, async (req, res) => { router.put('/:id', isAuthenticated, checkPermissions('taxRate', 'edit'), async (req, res) => {
editTaxRateRouteHandler(req, res); editTaxRateRouteHandler(req, res);
}); });

View File

@ -1,5 +1,6 @@
import express from 'express'; import express from 'express';
import { isAuthenticated } from '../../keycloak.js'; import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
import { getFilter, convertPropertiesString, getSort } from '../../utils.js'; import { getFilter, convertPropertiesString, getSort } from '../../utils.js';
const router = express.Router(); const router = express.Router();
@ -57,7 +58,7 @@ router.get('/search', isAuthenticated, async (req, res) => {
searchUserGroupsRouteHandler(req, res, search); searchUserGroupsRouteHandler(req, res, search);
}); });
router.post('/', isAuthenticated, async (req, res) => { router.post('/', isAuthenticated, checkPermissions('userGroup', 'new'), async (req, res) => {
newUserGroupRouteHandler(req, res); newUserGroupRouteHandler(req, res);
}); });
@ -88,7 +89,7 @@ router.get('/:id', isAuthenticated, async (req, res) => {
getUserGroupRouteHandler(req, res); getUserGroupRouteHandler(req, res);
}); });
router.put('/:id', isAuthenticated, async (req, res) => { router.put('/:id', isAuthenticated, checkPermissions('userGroup', 'edit'), async (req, res) => {
editUserGroupRouteHandler(req, res); editUserGroupRouteHandler(req, res);
}); });

View File

@ -1,5 +1,6 @@
import express from 'express'; import express from 'express';
import { isAuthenticated } from '../../keycloak.js'; import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
import { convertPropertiesString, getFilter, getSort } from '../../utils.js'; import { convertPropertiesString, getFilter, getSort } from '../../utils.js';
const router = express.Router(); const router = express.Router();
@ -80,11 +81,11 @@ router.get('/:id', isAuthenticated, async (req, res) => {
}); });
// update user info // update user info
router.put('/:id', isAuthenticated, async (req, res) => { router.put('/:id', isAuthenticated, checkPermissions('user', 'edit'), async (req, res) => {
editUserRouteHandler(req, res); editUserRouteHandler(req, res);
}); });
router.post('/:id/setAppPassword', isAuthenticated, async (req, res) => { router.post('/:id/setAppPassword', isAuthenticated, checkPermissions('user', 'newAppPassword'), async (req, res) => {
setAppPasswordRouteHandler(req, res); setAppPasswordRouteHandler(req, res);
}); });

View File

@ -1,5 +1,6 @@
import express from 'express'; import express from 'express';
import { isAuthenticated } from '../../keycloak.js'; import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
import { getFilter, convertPropertiesString, getSort } from '../../utils.js'; import { getFilter, convertPropertiesString, getSort } from '../../utils.js';
const router = express.Router(); const router = express.Router();
@ -57,7 +58,7 @@ router.get('/search', isAuthenticated, async (req, res) => {
searchVendorsRouteHandler(req, res, search); searchVendorsRouteHandler(req, res, search);
}); });
router.post('/', isAuthenticated, async (req, res) => { router.post('/', isAuthenticated, checkPermissions('vendor', 'new'), async (req, res) => {
newVendorRouteHandler(req, res); newVendorRouteHandler(req, res);
}); });
@ -81,7 +82,7 @@ router.get('/:id', isAuthenticated, async (req, res) => {
getVendorRouteHandler(req, res); getVendorRouteHandler(req, res);
}); });
router.put('/:id', isAuthenticated, async (req, res) => { router.put('/:id', isAuthenticated, checkPermissions('vendor', 'edit'), async (req, res) => {
editVendorRouteHandler(req, res); editVendorRouteHandler(req, res);
}); });

View File

@ -1,5 +1,6 @@
import express from 'express'; import express from 'express';
import { isAuthenticated } from '../../keycloak.js'; import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
import { convertPropertiesString, getFilter, getSort } from '../../utils.js'; import { convertPropertiesString, getFilter, getSort } from '../../utils.js';
import { import {
deleteFilamentProfileRouteHandler, deleteFilamentProfileRouteHandler,
@ -10,8 +11,7 @@ import {
newFilamentProfileRouteHandler, newFilamentProfileRouteHandler,
searchFilamentProfilesRouteHandler, searchFilamentProfilesRouteHandler,
getFilamentProfilePropertyValuesRouteHandler, getFilamentProfilePropertyValuesRouteHandler,
getFilamentProfileNeighborsRouteHandler,
getFilamentProfileNeighborsRouteHandler
} from '../../services/production/filamentprofiles.js'; } from '../../services/production/filamentprofiles.js';
const router = express.Router(); const router = express.Router();
@ -23,7 +23,17 @@ const propertiesAllowedFilters = ['name'];
router.get('/', isAuthenticated, async (req, res) => { router.get('/', isAuthenticated, async (req, res) => {
const { page, limit, property, search, sort, order } = req.query; const { page, limit, property, search, sort, order } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
listFilamentProfilesRouteHandler(req, res, page, limit, property, filter, search, getSort(sort, listAllowedSorters), order); listFilamentProfilesRouteHandler(
req,
res,
page,
limit,
property,
filter,
search,
getSort(sort, listAllowedSorters),
order
);
}); });
router.get('/properties', isAuthenticated, async (req, res) => { router.get('/properties', isAuthenticated, async (req, res) => {
@ -45,23 +55,42 @@ router.get('/search', isAuthenticated, async (req, res) => {
searchFilamentProfilesRouteHandler(req, res, req.query.search); searchFilamentProfilesRouteHandler(req, res, req.query.search);
}); });
router.post('/', isAuthenticated, async (req, res) => { router.post('/', isAuthenticated, checkPermissions('filamentProfile', 'new'), async (req, res) => {
newFilamentProfileRouteHandler(req, res); newFilamentProfileRouteHandler(req, res);
}); });
router.get('/neighbors', isAuthenticated, async (req, res) => { router.get('/neighbors', isAuthenticated, async (req, res) => {
const { property, search, sort, order, id } = req.query; const { property, search, sort, order, id } = req.query;
const filter = await getFilter(req.query, listAllowedFilters); const filter = await getFilter(req.query, listAllowedFilters);
getFilamentProfileNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getFilamentProfileNeighborsRouteHandler(
req,
res,
property,
filter,
search,
getSort(sort, listAllowedSorters),
order,
id
);
}); });
router.get('/:id', isAuthenticated, async (req, res) => { router.get(
getFilamentProfileRouteHandler(req, res); '/:id',
}); isAuthenticated,
checkPermissions('filamentProfile', 'info'),
async (req, res) => {
getFilamentProfileRouteHandler(req, res);
}
);
router.put('/:id', isAuthenticated, async (req, res) => { router.put(
editFilamentProfileRouteHandler(req, res); '/:id',
}); isAuthenticated,
checkPermissions('filamentProfile', 'edit'),
async (req, res) => {
editFilamentProfileRouteHandler(req, res);
}
);
router.delete('/:id', isAuthenticated, async (req, res) => { router.delete('/:id', isAuthenticated, async (req, res) => {
deleteFilamentProfileRouteHandler(req, res); deleteFilamentProfileRouteHandler(req, res);

View File

@ -1,5 +1,6 @@
import express from 'express'; import express from 'express';
import { isAuthenticated } from '../../keycloak.js'; import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
const router = express.Router(); const router = express.Router();
@ -59,7 +60,7 @@ router.get('/search', isAuthenticated, async (req, res) => {
// create new gcodeFile // create new gcodeFile
router.post('/', isAuthenticated, async (req, res) => { router.post('/', isAuthenticated, checkPermissions('gcodeFile', 'new'), async (req, res) => {
newGCodeFileRouteHandler(req, res); newGCodeFileRouteHandler(req, res);
}); });
@ -74,7 +75,7 @@ router.get('/neighbors', isAuthenticated, async (req, res) => {
getGCodeFileNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getGCodeFileNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id);
}); });
router.get('/:id', isAuthenticated, async (req, res) => { router.get('/:id', isAuthenticated, checkPermissions('gcodeFile', 'info'), async (req, res) => {
getGCodeFileRouteHandler(req, res); getGCodeFileRouteHandler(req, res);
}); });
@ -83,7 +84,7 @@ router.get('/:id/content', isAuthenticated, async (req, res) => {
}); });
// update gcodeFile info // update gcodeFile info
router.put('/:id', isAuthenticated, async (req, res) => { router.put('/:id', isAuthenticated, checkPermissions('gcodeFile', 'edit'), async (req, res) => {
editGCodeFileRouteHandler(req, res); editGCodeFileRouteHandler(req, res);
}); });

View File

@ -1,5 +1,6 @@
import express from 'express'; import express from 'express';
import { isAuthenticated } from '../../keycloak.js'; import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
const router = express.Router(); const router = express.Router();
@ -66,7 +67,7 @@ router.get('/search', isAuthenticated, async (req, res) => {
searchJobsRouteHandler(req, res, search); searchJobsRouteHandler(req, res, search);
}); });
router.post('/', isAuthenticated, async (req, res) => { router.post('/', isAuthenticated, checkPermissions('job', 'new'), async (req, res) => {
newJobRouteHandler(req, res); newJobRouteHandler(req, res);
}); });
@ -86,11 +87,11 @@ router.get('/neighbors', isAuthenticated, async (req, res) => {
getJobNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getJobNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id);
}); });
router.get('/:id', isAuthenticated, async (req, res) => { router.get('/:id', isAuthenticated, checkPermissions('job', 'info'), async (req, res) => {
getJobRouteHandler(req, res); getJobRouteHandler(req, res);
}); });
router.put('/:id', isAuthenticated, async (req, res) => { router.put('/:id', isAuthenticated, checkPermissions('job', 'edit'), async (req, res) => {
editJobRouteHandler(req, res); editJobRouteHandler(req, res);
}); });

View File

@ -1,5 +1,6 @@
import express from 'express'; import express from 'express';
import { isAuthenticated } from '../../keycloak.js'; import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
import { convertPropertiesString, getFilter, getSort } from '../../utils.js'; import { convertPropertiesString, getFilter, getSort } from '../../utils.js';
import { import {
deletePrinterProfileRouteHandler, deletePrinterProfileRouteHandler,
@ -53,7 +54,7 @@ router.get('/search', isAuthenticated, async (req, res) => {
searchPrinterProfilesRouteHandler(req, res, req.query.search); searchPrinterProfilesRouteHandler(req, res, req.query.search);
}); });
router.post('/', isAuthenticated, async (req, res) => { router.post('/', isAuthenticated, checkPermissions('printer', 'newPrinterProfile'), async (req, res) => {
newPrinterProfileRouteHandler(req, res); newPrinterProfileRouteHandler(req, res);
}); });
@ -63,11 +64,11 @@ router.get('/neighbors', isAuthenticated, async (req, res) => {
getPrinterProfileNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getPrinterProfileNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id);
}); });
router.get('/:id', isAuthenticated, async (req, res) => { router.get('/:id', isAuthenticated, checkPermissions('printerProfile', 'info'), async (req, res) => {
getPrinterProfileRouteHandler(req, res); getPrinterProfileRouteHandler(req, res);
}); });
router.put('/:id', isAuthenticated, async (req, res) => { router.put('/:id', isAuthenticated, checkPermissions('printerProfile', 'edit'), async (req, res) => {
editPrinterProfileRouteHandler(req, res); editPrinterProfileRouteHandler(req, res);
}); });

View File

@ -1,5 +1,6 @@
import express from 'express'; import express from 'express';
import { isAuthenticated } from '../../keycloak.js'; import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
const router = express.Router(); const router = express.Router();
import { import {
@ -58,7 +59,7 @@ router.get('/search', isAuthenticated, async (req, res) => {
}); });
// create new printer // create new printer
router.post('/', isAuthenticated, async (req, res) => { router.post('/', isAuthenticated, checkPermissions('printer', 'new'), async (req, res) => {
newPrinterRouteHandler(req, res); newPrinterRouteHandler(req, res);
}); });
@ -78,12 +79,12 @@ router.get('/stats', isAuthenticated, async (req, res) => {
getPrinterStatsRouteHandler(req, res); getPrinterStatsRouteHandler(req, res);
}); });
router.get('/:id', isAuthenticated, async (req, res) => { router.get('/:id', isAuthenticated, checkPermissions('printer', 'info'), async (req, res) => {
getPrinterRouteHandler(req, res); getPrinterRouteHandler(req, res);
}); });
// update printer info // update printer info
router.put('/:id', isAuthenticated, async (req, res) => { router.put('/:id', isAuthenticated, checkPermissions('printer', 'edit'), async (req, res) => {
editPrinterRouteHandler(req, res); editPrinterRouteHandler(req, res);
}); });

View File

@ -1,5 +1,6 @@
import express from 'express'; import express from 'express';
import { isAuthenticated } from '../../keycloak.js'; import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
const router = express.Router(); const router = express.Router();
@ -80,7 +81,7 @@ router.get('/neighbors', isAuthenticated, async (req, res) => {
getSubJobNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getSubJobNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id);
}); });
router.get('/:id', isAuthenticated, async (req, res) => { router.get('/:id', isAuthenticated, checkPermissions('subJob', 'info'), async (req, res) => {
getSubJobRouteHandler(req, res); getSubJobRouteHandler(req, res);
}); });

View File

@ -1,5 +1,6 @@
import express from 'express'; import express from 'express';
import { isAuthenticated } from '../../keycloak.js'; import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
import { getFilter, convertPropertiesString, getSort } from '../../utils.js'; import { getFilter, convertPropertiesString, getSort } from '../../utils.js';
const router = express.Router(); const router = express.Router();
@ -58,7 +59,7 @@ router.get('/search', isAuthenticated, async (req, res) => {
}); });
router.post('/', isAuthenticated, async (req, res) => { router.post('/', isAuthenticated, checkPermissions('client', 'new'), async (req, res) => {
newClientRouteHandler(req, res); newClientRouteHandler(req, res);
}); });
@ -78,11 +79,11 @@ router.get('/neighbors', isAuthenticated, async (req, res) => {
getClientNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getClientNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id);
}); });
router.get('/:id', isAuthenticated, async (req, res) => { router.get('/:id', isAuthenticated, checkPermissions('client', 'info'), async (req, res) => {
getClientRouteHandler(req, res); getClientRouteHandler(req, res);
}); });
router.put('/:id', isAuthenticated, async (req, res) => { router.put('/:id', isAuthenticated, checkPermissions('client', 'edit'), async (req, res) => {
editClientRouteHandler(req, res); editClientRouteHandler(req, res);
}); });

View File

@ -1,5 +1,6 @@
import express from 'express'; import express from 'express';
import { isAuthenticated } from '../../keycloak.js'; import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
import { getFilter, convertPropertiesString, getSort } from '../../utils.js'; import { getFilter, convertPropertiesString, getSort } from '../../utils.js';
const router = express.Router(); const router = express.Router();
@ -83,7 +84,7 @@ router.get('/search', isAuthenticated, async (req, res) => {
searchListingsRouteHandler(req, res, search); searchListingsRouteHandler(req, res, search);
}); });
router.post('/', isAuthenticated, async (req, res) => { router.post('/', isAuthenticated, checkPermissions('listing', 'new'), async (req, res) => {
newListingRouteHandler(req, res); newListingRouteHandler(req, res);
}); });
@ -95,11 +96,11 @@ router.get('/history', isAuthenticated, async (req, res) => {
getListingHistoryRouteHandler(req, res); getListingHistoryRouteHandler(req, res);
}); });
router.post('/:id/publish', isAuthenticated, async (req, res) => { router.post('/:id/publish', isAuthenticated, checkPermissions('listing', 'publish'), async (req, res) => {
publishListingRouteHandler(req, res); publishListingRouteHandler(req, res);
}); });
router.post('/:id/unpublish', isAuthenticated, async (req, res) => { router.post('/:id/unpublish', isAuthenticated, checkPermissions('listing', 'unpublish'), async (req, res) => {
unpublishListingRouteHandler(req, res); unpublishListingRouteHandler(req, res);
}); });
@ -109,11 +110,11 @@ router.get('/neighbors', isAuthenticated, async (req, res) => {
getListingNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getListingNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id);
}); });
router.get('/:id', isAuthenticated, async (req, res) => { router.get('/:id', isAuthenticated, checkPermissions('listing', 'info'), async (req, res) => {
getListingRouteHandler(req, res); getListingRouteHandler(req, res);
}); });
router.put('/:id', isAuthenticated, async (req, res) => { router.put('/:id', isAuthenticated, checkPermissions('listing', 'edit'), async (req, res) => {
editListingRouteHandler(req, res); editListingRouteHandler(req, res);
}); });

View File

@ -1,5 +1,6 @@
import express from 'express'; import express from 'express';
import { isAuthenticated } from '../../keycloak.js'; import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
import { getFilter, convertPropertiesString, getSort } from '../../utils.js'; import { getFilter, convertPropertiesString, getSort } from '../../utils.js';
const router = express.Router(); const router = express.Router();
@ -71,7 +72,7 @@ router.get('/search', isAuthenticated, async (req, res) => {
}); });
router.post('/', isAuthenticated, async (req, res) => { router.post('/', isAuthenticated, checkPermissions('listing', 'newListingVarient'), async (req, res) => {
newListingVarientRouteHandler(req, res); newListingVarientRouteHandler(req, res);
}); });
@ -83,11 +84,11 @@ router.get('/history', isAuthenticated, async (req, res) => {
getListingVarientHistoryRouteHandler(req, res); getListingVarientHistoryRouteHandler(req, res);
}); });
router.post('/:id/publish', isAuthenticated, async (req, res) => { router.post('/:id/publish', isAuthenticated, checkPermissions('listingVarient', 'publish'), async (req, res) => {
publishListingVarientRouteHandler(req, res); publishListingVarientRouteHandler(req, res);
}); });
router.post('/:id/unpublish', isAuthenticated, async (req, res) => { router.post('/:id/unpublish', isAuthenticated, checkPermissions('listingVarient', 'unpublish'), async (req, res) => {
unpublishListingVarientRouteHandler(req, res); unpublishListingVarientRouteHandler(req, res);
}); });
@ -97,11 +98,11 @@ router.get('/neighbors', isAuthenticated, async (req, res) => {
getListingVarientNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getListingVarientNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id);
}); });
router.get('/:id', isAuthenticated, async (req, res) => { router.get('/:id', isAuthenticated, checkPermissions('listingVarient', 'info'), async (req, res) => {
getListingVarientRouteHandler(req, res); getListingVarientRouteHandler(req, res);
}); });
router.put('/:id', isAuthenticated, async (req, res) => { router.put('/:id', isAuthenticated, checkPermissions('listingVarient', 'edit'), async (req, res) => {
editListingVarientRouteHandler(req, res); editListingVarientRouteHandler(req, res);
}); });

View File

@ -1,5 +1,6 @@
import express from 'express'; import express from 'express';
import { isAuthenticated } from '../../keycloak.js'; import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions, hasPermission } from '../../database/permissions.js';
import { getFilter, convertPropertiesString, getSort } from '../../utils.js'; import { getFilter, convertPropertiesString, getSort } from '../../utils.js';
const router = express.Router(); const router = express.Router();
@ -73,7 +74,7 @@ router.get('/search', isAuthenticated, async (req, res) => {
}); });
router.post('/', isAuthenticated, async (req, res) => { router.post('/', isAuthenticated, checkPermissions('marketplace', 'new'), async (req, res) => {
newMarketplaceRouteHandler(req, res); newMarketplaceRouteHandler(req, res);
}); });
@ -89,19 +90,31 @@ router.get('/:id/auth/url', isAuthenticated, async (req, res) => {
getMarketplaceAuthUrlRouteHandler(req, res); getMarketplaceAuthUrlRouteHandler(req, res);
}); });
router.post('/:id/auth/exchange', isAuthenticated, async (req, res) => { router.post('/:id/auth/exchange', isAuthenticated, async (req, res, next) => {
try {
const allowed =
(await hasPermission(req.user, 'marketplace', 'connect')) ||
(await hasPermission(req.user, 'marketplace', 'reconnect'));
if (!allowed) {
return res.status(403).json({ error: 'Forbidden', code: 'FORBIDDEN' });
}
return next();
} catch (err) {
return next(err);
}
}, async (req, res) => {
exchangeMarketplaceAuthCodeRouteHandler(req, res); exchangeMarketplaceAuthCodeRouteHandler(req, res);
}); });
router.post('/:id/auth/refresh', isAuthenticated, async (req, res) => { router.post('/:id/auth/refresh', isAuthenticated, checkPermissions('marketplace', 'refreshToken'), async (req, res) => {
refreshMarketplaceAuthRouteHandler(req, res); refreshMarketplaceAuthRouteHandler(req, res);
}); });
router.post('/:id/sync/items', isAuthenticated, async (req, res) => { router.post('/:id/sync/items', isAuthenticated, checkPermissions('marketplace', 'syncListings'), async (req, res) => {
syncMarketplaceItemsRouteHandler(req, res); syncMarketplaceItemsRouteHandler(req, res);
}); });
router.post('/:id/sync/orders', isAuthenticated, async (req, res) => { router.post('/:id/sync/orders', isAuthenticated, checkPermissions('marketplace', 'syncOrders'), async (req, res) => {
syncMarketplaceOrdersRouteHandler(req, res); syncMarketplaceOrdersRouteHandler(req, res);
}); });
@ -116,11 +129,11 @@ router.get('/neighbors', isAuthenticated, async (req, res) => {
getMarketplaceNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getMarketplaceNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id);
}); });
router.get('/:id', isAuthenticated, async (req, res) => { router.get('/:id', isAuthenticated, checkPermissions('marketplace', 'info'), async (req, res) => {
getMarketplaceRouteHandler(req, res); getMarketplaceRouteHandler(req, res);
}); });
router.put('/:id', isAuthenticated, async (req, res) => { router.put('/:id', isAuthenticated, checkPermissions('marketplace', 'edit'), async (req, res) => {
editMarketplaceRouteHandler(req, res); editMarketplaceRouteHandler(req, res);
}); });

View File

@ -1,5 +1,6 @@
import express from 'express'; import express from 'express';
import { isAuthenticated } from '../../keycloak.js'; import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
import { getFilter, convertPropertiesString, getSort } from '../../utils.js'; import { getFilter, convertPropertiesString, getSort } from '../../utils.js';
const router = express.Router(); const router = express.Router();
@ -59,7 +60,7 @@ router.get('/search', isAuthenticated, async (req, res) => {
searchSalesOrdersRouteHandler(req, res, search); searchSalesOrdersRouteHandler(req, res, search);
}); });
router.post('/', isAuthenticated, async (req, res) => { router.post('/', isAuthenticated, checkPermissions('salesOrder', 'new'), async (req, res) => {
newSalesOrderRouteHandler(req, res); newSalesOrderRouteHandler(req, res);
}); });
@ -79,16 +80,16 @@ router.get('/neighbors', isAuthenticated, async (req, res) => {
getSalesOrderNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id); getSalesOrderNeighborsRouteHandler(req, res, property, filter, search, getSort(sort, listAllowedSorters), order, id);
}); });
router.get('/:id', isAuthenticated, async (req, res) => { router.get('/:id', isAuthenticated, checkPermissions('salesOrder', 'info'), async (req, res) => {
getSalesOrderRouteHandler(req, res); getSalesOrderRouteHandler(req, res);
}); });
// update multiple sales orders // update multiple sales orders
router.put('/', isAuthenticated, async (req, res) => { router.put('/', isAuthenticated, checkPermissions('salesOrder', 'edit'), async (req, res) => {
editMultipleSalesOrdersRouteHandler(req, res); editMultipleSalesOrdersRouteHandler(req, res);
}); });
router.put('/:id', isAuthenticated, async (req, res) => { router.put('/:id', isAuthenticated, checkPermissions('salesOrder', 'edit'), async (req, res) => {
editSalesOrderRouteHandler(req, res); editSalesOrderRouteHandler(req, res);
}); });
@ -96,15 +97,15 @@ router.delete('/:id', isAuthenticated, async (req, res) => {
deleteSalesOrderRouteHandler(req, res); deleteSalesOrderRouteHandler(req, res);
}); });
router.post('/:id/post', isAuthenticated, async (req, res) => { router.post('/:id/post', isAuthenticated, checkPermissions('salesOrder', 'post'), async (req, res) => {
postSalesOrderRouteHandler(req, res); postSalesOrderRouteHandler(req, res);
}); });
router.post('/:id/confirm', isAuthenticated, async (req, res) => { router.post('/:id/confirm', isAuthenticated, checkPermissions('salesOrder', 'confirm'), async (req, res) => {
confirmSalesOrderRouteHandler(req, res); confirmSalesOrderRouteHandler(req, res);
}); });
router.post('/:id/cancel', isAuthenticated, async (req, res) => { router.post('/:id/cancel', isAuthenticated, checkPermissions('salesOrder', 'cancel'), async (req, res) => {
cancelSalesOrderRouteHandler(req, res); cancelSalesOrderRouteHandler(req, res);
}); });