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', () => {
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 { 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 = []) => {
const permissions = {};

View File

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

View File

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

View File

@ -1,5 +1,6 @@
import express from 'express';
import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
import { getFilter, convertPropertiesString, getSort } from '../../utils.js';
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);
});
@ -94,16 +95,16 @@ router.get('/neighbors', isAuthenticated, async (req, res) => {
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);
});
// update multiple payments
router.put('/', isAuthenticated, async (req, res) => {
router.put('/', isAuthenticated, checkPermissions('payment', 'edit'), async (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);
});
@ -111,19 +112,19 @@ router.delete('/:id', isAuthenticated, async (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);
});
router.post('/:id/authorise', isAuthenticated, async (req, res) => {
router.post('/:id/authorise', isAuthenticated, checkPermissions('payment', 'authorise'), async (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);
});
router.post('/:id/cancel', isAuthenticated, async (req, res) => {
router.post('/:id/cancel', isAuthenticated, checkPermissions('payment', 'cancel'), async (req, res) => {
cancelPaymentRouteHandler(req, res);
});

View File

@ -1,5 +1,6 @@
import express from 'express';
import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
import { getFilter, convertPropertiesString, getSort } from '../../utils.js';
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);
});
@ -79,11 +80,11 @@ router.get('/neighbors', isAuthenticated, async (req, res) => {
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);
});
router.put('/:id', isAuthenticated, async (req, res) => {
router.put('/:id', isAuthenticated, checkPermissions('taxRecord', 'edit'), async (req, res) => {
editTaxRecordRouteHandler(req, res);
});

View File

@ -1,5 +1,6 @@
import express from 'express';
import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
import { getFilter, convertPropertiesString, getSort } from '../../utils.js';
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);
});
@ -89,16 +90,16 @@ router.get('/neighbors', isAuthenticated, async (req, res) => {
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);
});
// update multiple filament stocks
router.put('/', isAuthenticated, async (req, res) => {
router.put('/', isAuthenticated, checkPermissions('filamentStock', 'edit'), async (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);
});

View File

@ -1,5 +1,6 @@
import express from 'express';
import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
import { getFilter, convertPropertiesString, getSort } from '../../utils.js';
const router = express.Router();
@ -50,7 +51,17 @@ import {
router.get('/', isAuthenticated, async (req, res) => {
const { page, limit, property, search, sort, order } = req.query;
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) => {
@ -72,7 +83,7 @@ router.get('/search', isAuthenticated, async (req, res) => {
searchOrderItemsRouteHandler(req, res, search);
});
router.post('/', isAuthenticated, async (req, res) => {
router.post('/', isAuthenticated, checkPermissions('orderItem', 'new'), async (req, res) => {
newOrderItemRouteHandler(req, res);
});
@ -89,19 +100,28 @@ router.get('/history', isAuthenticated, async (req, res) => {
router.get('/neighbors', isAuthenticated, async (req, res) => {
const { property, search, sort, order, id } = req.query;
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);
});
// update multiple order items
router.put('/', isAuthenticated, async (req, res) => {
router.put('/', isAuthenticated, checkPermissions('orderItem', 'edit'), async (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);
});

View File

@ -1,5 +1,6 @@
import express from 'express';
import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
import { getFilter, convertPropertiesString, getSort } from '../../utils.js';
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);
});
@ -81,16 +82,16 @@ router.get('/neighbors', isAuthenticated, async (req, res) => {
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);
});
// update multiple part stocks
router.put('/', isAuthenticated, async (req, res) => {
router.put('/', isAuthenticated, checkPermissions('partStock', 'edit'), async (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);
});

View File

@ -1,5 +1,6 @@
import express from 'express';
import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
import { getFilter, convertPropertiesString, getSort } from '../../utils.js';
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);
});
@ -78,15 +79,15 @@ router.get('/neighbors', isAuthenticated, async (req, res) => {
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);
});
router.put('/', isAuthenticated, async (req, res) => {
router.put('/', isAuthenticated, checkPermissions('productStock', 'edit'), async (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);
});
@ -94,7 +95,7 @@ router.delete('/:id', isAuthenticated, async (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);
});

View File

@ -1,5 +1,6 @@
import express from 'express';
import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
import { getFilter, convertPropertiesString, getSort } from '../../utils.js';
const router = express.Router();
@ -86,7 +87,7 @@ router.get('/search', isAuthenticated, async (req, res) => {
searchPurchaseOrdersRouteHandler(req, res, search);
});
router.post('/', isAuthenticated, async (req, res) => {
router.post('/', isAuthenticated, checkPermissions('purchaseOrder', 'new'), async (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);
});
router.get('/:id', isAuthenticated, async (req, res) => {
router.get('/:id', isAuthenticated, checkPermissions('purchaseOrder', 'info'), async (req, res) => {
getPurchaseOrderRouteHandler(req, res);
});
// update multiple purchase orders
router.put('/', isAuthenticated, async (req, res) => {
router.put('/', isAuthenticated, checkPermissions('purchaseOrder', 'edit'), async (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);
});
@ -123,15 +124,15 @@ router.delete('/:id', isAuthenticated, async (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);
});
router.post('/:id/acknowledge', isAuthenticated, async (req, res) => {
router.post('/:id/acknowledge', isAuthenticated, checkPermissions('purchaseOrder', 'acknowledge'), async (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);
});

View File

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

View File

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

View File

@ -1,5 +1,6 @@
import express from 'express';
import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
import { getFilter, convertPropertiesString, getSort } from '../../utils.js';
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);
});
@ -70,16 +71,16 @@ router.get('/neighbors', isAuthenticated, async (req, res) => {
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);
});
// update multiple stock events
router.put('/', isAuthenticated, async (req, res) => {
router.put('/', isAuthenticated, checkPermissions('stockEvent', 'edit'), async (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);
});

View File

@ -1,5 +1,6 @@
import express from 'express';
import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
import { getFilter, convertPropertiesString, getSort } from '../../utils.js';
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);
});
@ -67,15 +68,15 @@ router.get('/neighbors', isAuthenticated, async (req, res) => {
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);
});
router.put('/', isAuthenticated, async (req, res) => {
router.put('/', isAuthenticated, checkPermissions('stockLocation', 'edit'), async (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);
});

View File

@ -1,5 +1,6 @@
import express from 'express';
import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
import { getFilter, convertPropertiesString, getSort } from '../../utils.js';
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);
});
@ -76,15 +77,15 @@ router.get('/neighbors', isAuthenticated, async (req, res) => {
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);
});
router.put('/', isAuthenticated, async (req, res) => {
router.put('/', isAuthenticated, checkPermissions('stockTransfer', 'edit'), async (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);
});
@ -92,7 +93,7 @@ router.delete('/:id', isAuthenticated, async (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);
});

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,5 +1,6 @@
import express from 'express';
import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
import { getFilter, convertPropertiesString, getSort } from '../../utils.js';
const router = express.Router();
@ -73,11 +74,11 @@ router.get('/search', isAuthenticated, async (req, res) => {
searchDocumentTemplatesRouteHandler(req, res, search);
});
router.post('/', isAuthenticated, async (req, res) => {
router.post('/', isAuthenticated, checkPermissions('documentTemplate', 'new'), async (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);
});
@ -97,11 +98,11 @@ router.get('/neighbors', isAuthenticated, async (req, res) => {
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);
});
router.post('/:id/download', isAuthenticated, async (req, res) => {
router.post('/:id/download', isAuthenticated, checkPermissions('documentTemplate', 'design'), async (req, res) => {
downloadDocumentTemplateRouteHandler(req, res);
});
@ -109,7 +110,7 @@ router.get('/:id', isAuthenticated, async (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);
});

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,5 +1,6 @@
import express from 'express';
import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
import { getFilter, convertPropertiesString, getSort } from '../../utils.js';
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);
});
@ -81,7 +82,7 @@ router.get('/:id', isAuthenticated, async (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);
});

View File

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

View File

@ -1,5 +1,6 @@
import express from 'express';
import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
import { getFilter, convertPropertiesString, getSort } from '../../utils.js';
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);
});
@ -91,7 +92,7 @@ router.get('/:id', isAuthenticated, async (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);
});

View File

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

View File

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

View File

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

View File

@ -1,5 +1,6 @@
import express from 'express';
import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
import { getFilter, convertPropertiesString, getSort } from '../../utils.js';
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);
});
@ -91,7 +92,7 @@ router.get('/:id', isAuthenticated, async (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);
});

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,5 +1,6 @@
import express from 'express';
import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
const router = express.Router();
@ -59,7 +60,7 @@ router.get('/search', isAuthenticated, async (req, res) => {
// create new gcodeFile
router.post('/', isAuthenticated, async (req, res) => {
router.post('/', isAuthenticated, checkPermissions('gcodeFile', 'new'), async (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);
});
router.get('/:id', isAuthenticated, async (req, res) => {
router.get('/:id', isAuthenticated, checkPermissions('gcodeFile', 'info'), async (req, res) => {
getGCodeFileRouteHandler(req, res);
});
@ -83,7 +84,7 @@ router.get('/:id/content', isAuthenticated, async (req, res) => {
});
// update gcodeFile info
router.put('/:id', isAuthenticated, async (req, res) => {
router.put('/:id', isAuthenticated, checkPermissions('gcodeFile', 'edit'), async (req, res) => {
editGCodeFileRouteHandler(req, res);
});

View File

@ -1,5 +1,6 @@
import express from 'express';
import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
const router = express.Router();
@ -66,7 +67,7 @@ router.get('/search', isAuthenticated, async (req, res) => {
searchJobsRouteHandler(req, res, search);
});
router.post('/', isAuthenticated, async (req, res) => {
router.post('/', isAuthenticated, checkPermissions('job', 'new'), async (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);
});
router.get('/:id', isAuthenticated, async (req, res) => {
router.get('/:id', isAuthenticated, checkPermissions('job', 'info'), async (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);
});

View File

@ -1,5 +1,6 @@
import express from 'express';
import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
import { convertPropertiesString, getFilter, getSort } from '../../utils.js';
import {
deletePrinterProfileRouteHandler,
@ -53,7 +54,7 @@ router.get('/search', isAuthenticated, async (req, res) => {
searchPrinterProfilesRouteHandler(req, res, req.query.search);
});
router.post('/', isAuthenticated, async (req, res) => {
router.post('/', isAuthenticated, checkPermissions('printer', 'newPrinterProfile'), async (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);
});
router.get('/:id', isAuthenticated, async (req, res) => {
router.get('/:id', isAuthenticated, checkPermissions('printerProfile', 'info'), async (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);
});

View File

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

View File

@ -1,5 +1,6 @@
import express from 'express';
import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
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);
});
router.get('/:id', isAuthenticated, async (req, res) => {
router.get('/:id', isAuthenticated, checkPermissions('subJob', 'info'), async (req, res) => {
getSubJobRouteHandler(req, res);
});

View File

@ -1,5 +1,6 @@
import express from 'express';
import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
import { getFilter, convertPropertiesString, getSort } from '../../utils.js';
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);
});
@ -78,11 +79,11 @@ router.get('/neighbors', isAuthenticated, async (req, res) => {
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);
});
router.put('/:id', isAuthenticated, async (req, res) => {
router.put('/:id', isAuthenticated, checkPermissions('client', 'edit'), async (req, res) => {
editClientRouteHandler(req, res);
});

View File

@ -1,5 +1,6 @@
import express from 'express';
import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
import { getFilter, convertPropertiesString, getSort } from '../../utils.js';
const router = express.Router();
@ -83,7 +84,7 @@ router.get('/search', isAuthenticated, async (req, res) => {
searchListingsRouteHandler(req, res, search);
});
router.post('/', isAuthenticated, async (req, res) => {
router.post('/', isAuthenticated, checkPermissions('listing', 'new'), async (req, res) => {
newListingRouteHandler(req, res);
});
@ -95,11 +96,11 @@ router.get('/history', isAuthenticated, async (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);
});
router.post('/:id/unpublish', isAuthenticated, async (req, res) => {
router.post('/:id/unpublish', isAuthenticated, checkPermissions('listing', 'unpublish'), async (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);
});
router.get('/:id', isAuthenticated, async (req, res) => {
router.get('/:id', isAuthenticated, checkPermissions('listing', 'info'), async (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);
});

View File

@ -1,5 +1,6 @@
import express from 'express';
import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
import { getFilter, convertPropertiesString, getSort } from '../../utils.js';
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);
});
@ -83,11 +84,11 @@ router.get('/history', isAuthenticated, async (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);
});
router.post('/:id/unpublish', isAuthenticated, async (req, res) => {
router.post('/:id/unpublish', isAuthenticated, checkPermissions('listingVarient', 'unpublish'), async (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);
});
router.get('/:id', isAuthenticated, async (req, res) => {
router.get('/:id', isAuthenticated, checkPermissions('listingVarient', 'info'), async (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);
});

View File

@ -1,5 +1,6 @@
import express from 'express';
import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions, hasPermission } from '../../database/permissions.js';
import { getFilter, convertPropertiesString, getSort } from '../../utils.js';
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);
});
@ -89,19 +90,31 @@ router.get('/:id/auth/url', isAuthenticated, async (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);
});
router.post('/:id/auth/refresh', isAuthenticated, async (req, res) => {
router.post('/:id/auth/refresh', isAuthenticated, checkPermissions('marketplace', 'refreshToken'), async (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);
});
router.post('/:id/sync/orders', isAuthenticated, async (req, res) => {
router.post('/:id/sync/orders', isAuthenticated, checkPermissions('marketplace', 'syncOrders'), async (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);
});
router.get('/:id', isAuthenticated, async (req, res) => {
router.get('/:id', isAuthenticated, checkPermissions('marketplace', 'info'), async (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);
});

View File

@ -1,5 +1,6 @@
import express from 'express';
import { isAuthenticated } from '../../keycloak.js';
import { checkPermissions } from '../../database/permissions.js';
import { getFilter, convertPropertiesString, getSort } from '../../utils.js';
const router = express.Router();
@ -59,7 +60,7 @@ router.get('/search', isAuthenticated, async (req, res) => {
searchSalesOrdersRouteHandler(req, res, search);
});
router.post('/', isAuthenticated, async (req, res) => {
router.post('/', isAuthenticated, checkPermissions('salesOrder', 'new'), async (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);
});
router.get('/:id', isAuthenticated, async (req, res) => {
router.get('/:id', isAuthenticated, checkPermissions('salesOrder', 'info'), async (req, res) => {
getSalesOrderRouteHandler(req, res);
});
// update multiple sales orders
router.put('/', isAuthenticated, async (req, res) => {
router.put('/', isAuthenticated, checkPermissions('salesOrder', 'edit'), async (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);
});
@ -96,15 +97,15 @@ router.delete('/:id', isAuthenticated, async (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);
});
router.post('/:id/confirm', isAuthenticated, async (req, res) => {
router.post('/:id/confirm', isAuthenticated, checkPermissions('salesOrder', 'confirm'), async (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);
});