1.2
This commit is contained in:
parent
1fd0a1b094
commit
e20241ff74
@ -3,6 +3,7 @@ const db = require('../models');
|
||||
const FileDBApi = require('./file');
|
||||
const crypto = require('crypto');
|
||||
const Utils = require('../utils');
|
||||
const { isRestrictedPayrollUser } = require('../../security/payrollAccess');
|
||||
|
||||
|
||||
|
||||
@ -205,12 +206,17 @@ module.exports = class Employee_pay_typesDBApi {
|
||||
|
||||
static async findBy(where, options) {
|
||||
const transaction = (options && options.transaction) || undefined;
|
||||
const currentUser = options?.currentUser;
|
||||
|
||||
const employee_pay_types = await db.employee_pay_types.findOne(
|
||||
{ where },
|
||||
{ transaction },
|
||||
);
|
||||
|
||||
if (employee_pay_types && isRestrictedPayrollUser(currentUser) && employee_pay_types.employeeId !== currentUser.id) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!employee_pay_types) {
|
||||
return employee_pay_types;
|
||||
}
|
||||
@ -249,6 +255,8 @@ module.exports = class Employee_pay_typesDBApi {
|
||||
filter,
|
||||
options
|
||||
) {
|
||||
const currentUser = options?.currentUser;
|
||||
const effectiveEmployeeFilter = isRestrictedPayrollUser(currentUser) ? currentUser.id : filter.employee;
|
||||
const limit = filter.limit || 0;
|
||||
let offset = 0;
|
||||
let where = {};
|
||||
@ -270,12 +278,12 @@ module.exports = class Employee_pay_typesDBApi {
|
||||
model: db.users,
|
||||
as: 'employee',
|
||||
|
||||
where: filter.employee ? {
|
||||
where: effectiveEmployeeFilter ? {
|
||||
[Op.or]: [
|
||||
{ id: { [Op.in]: filter.employee.split('|').map(term => Utils.uuid(term)) } },
|
||||
{ id: { [Op.in]: effectiveEmployeeFilter.split('|').map(term => Utils.uuid(term)) } },
|
||||
{
|
||||
firstName: {
|
||||
[Op.or]: filter.employee.split('|').map(term => ({ [Op.iLike]: `%${term}%` }))
|
||||
[Op.or]: effectiveEmployeeFilter.split('|').map(term => ({ [Op.iLike]: `%${term}%` }))
|
||||
}
|
||||
},
|
||||
]
|
||||
@ -447,7 +455,8 @@ module.exports = class Employee_pay_typesDBApi {
|
||||
}
|
||||
}
|
||||
|
||||
static async findAllAutocomplete(query, limit, offset, ) {
|
||||
static async findAllAutocomplete(query, limit, offset, options) {
|
||||
const currentUser = options?.currentUser;
|
||||
let where = {};
|
||||
|
||||
|
||||
@ -465,6 +474,13 @@ module.exports = class Employee_pay_typesDBApi {
|
||||
};
|
||||
}
|
||||
|
||||
if (isRestrictedPayrollUser(currentUser)) {
|
||||
where = {
|
||||
...where,
|
||||
employeeId: currentUser.id,
|
||||
};
|
||||
}
|
||||
|
||||
const records = await db.employee_pay_types.findAll({
|
||||
attributes: [ 'id', 'active' ],
|
||||
where,
|
||||
|
||||
@ -3,6 +3,7 @@ const db = require('../models');
|
||||
const FileDBApi = require('./file');
|
||||
const crypto = require('crypto');
|
||||
const Utils = require('../utils');
|
||||
const { isRestrictedPayrollUser } = require('../../security/payrollAccess');
|
||||
|
||||
|
||||
|
||||
@ -320,12 +321,17 @@ module.exports = class Job_logsDBApi {
|
||||
|
||||
static async findBy(where, options) {
|
||||
const transaction = (options && options.transaction) || undefined;
|
||||
const currentUser = options?.currentUser;
|
||||
|
||||
const job_logs = await db.job_logs.findOne(
|
||||
{ where },
|
||||
{ transaction },
|
||||
);
|
||||
|
||||
if (job_logs && isRestrictedPayrollUser(currentUser) && job_logs.employeeId !== currentUser.id) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!job_logs) {
|
||||
return job_logs;
|
||||
}
|
||||
@ -382,6 +388,7 @@ module.exports = class Job_logsDBApi {
|
||||
filter,
|
||||
options
|
||||
) {
|
||||
const currentUser = options?.currentUser;
|
||||
const limit = filter.limit || 0;
|
||||
let offset = 0;
|
||||
let where = {};
|
||||
@ -486,6 +493,13 @@ module.exports = class Job_logsDBApi {
|
||||
|
||||
];
|
||||
|
||||
if (isRestrictedPayrollUser(currentUser)) {
|
||||
where = {
|
||||
...where,
|
||||
employeeId: currentUser.id,
|
||||
};
|
||||
}
|
||||
|
||||
if (filter) {
|
||||
if (filter.id) {
|
||||
where = {
|
||||
@ -752,7 +766,8 @@ module.exports = class Job_logsDBApi {
|
||||
}
|
||||
}
|
||||
|
||||
static async findAllAutocomplete(query, limit, offset, ) {
|
||||
static async findAllAutocomplete(query, limit, offset, options) {
|
||||
const currentUser = options?.currentUser;
|
||||
let where = {};
|
||||
|
||||
|
||||
@ -770,6 +785,13 @@ module.exports = class Job_logsDBApi {
|
||||
};
|
||||
}
|
||||
|
||||
if (isRestrictedPayrollUser(currentUser)) {
|
||||
where = {
|
||||
...where,
|
||||
employeeId: currentUser.id,
|
||||
};
|
||||
}
|
||||
|
||||
const records = await db.job_logs.findAll({
|
||||
attributes: [ 'id', 'job_address' ],
|
||||
where,
|
||||
|
||||
@ -3,6 +3,7 @@ const db = require('../models');
|
||||
const FileDBApi = require('./file');
|
||||
const crypto = require('crypto');
|
||||
const Utils = require('../utils');
|
||||
const { isRestrictedPayrollUser } = require('../../security/payrollAccess');
|
||||
|
||||
|
||||
|
||||
@ -218,9 +219,20 @@ module.exports = class Pay_typesDBApi {
|
||||
|
||||
static async findBy(where, options) {
|
||||
const transaction = (options && options.transaction) || undefined;
|
||||
const currentUser = options?.currentUser;
|
||||
const accessInclude = isRestrictedPayrollUser(currentUser) ? [{
|
||||
model: db.employee_pay_types,
|
||||
as: 'employee_pay_types_pay_type',
|
||||
required: true,
|
||||
attributes: [],
|
||||
where: {
|
||||
employeeId: currentUser.id,
|
||||
active: true,
|
||||
},
|
||||
}] : undefined;
|
||||
|
||||
const pay_types = await db.pay_types.findOne(
|
||||
{ where },
|
||||
{ where, include: accessInclude },
|
||||
{ transaction },
|
||||
);
|
||||
|
||||
@ -238,13 +250,15 @@ module.exports = class Pay_typesDBApi {
|
||||
|
||||
|
||||
output.employee_pay_types_pay_type = await pay_types.getEmployee_pay_types_pay_type({
|
||||
transaction
|
||||
transaction,
|
||||
where: isRestrictedPayrollUser(currentUser) ? { employeeId: currentUser.id, active: true } : undefined,
|
||||
});
|
||||
|
||||
|
||||
|
||||
output.job_logs_pay_type = await pay_types.getJob_logs_pay_type({
|
||||
transaction
|
||||
transaction,
|
||||
where: isRestrictedPayrollUser(currentUser) ? { employeeId: currentUser.id } : undefined,
|
||||
});
|
||||
|
||||
|
||||
@ -260,6 +274,7 @@ module.exports = class Pay_typesDBApi {
|
||||
filter,
|
||||
options
|
||||
) {
|
||||
const currentUser = options?.currentUser;
|
||||
const limit = filter.limit || 0;
|
||||
let offset = 0;
|
||||
let where = {};
|
||||
@ -281,6 +296,22 @@ module.exports = class Pay_typesDBApi {
|
||||
|
||||
];
|
||||
|
||||
if (isRestrictedPayrollUser(currentUser)) {
|
||||
include = [
|
||||
{
|
||||
model: db.employee_pay_types,
|
||||
as: 'employee_pay_types_pay_type',
|
||||
required: true,
|
||||
attributes: [],
|
||||
where: {
|
||||
employeeId: currentUser.id,
|
||||
active: true,
|
||||
},
|
||||
},
|
||||
...include,
|
||||
];
|
||||
}
|
||||
|
||||
if (filter) {
|
||||
if (filter.id) {
|
||||
where = {
|
||||
@ -449,7 +480,8 @@ module.exports = class Pay_typesDBApi {
|
||||
}
|
||||
}
|
||||
|
||||
static async findAllAutocomplete(query, limit, offset, ) {
|
||||
static async findAllAutocomplete(query, limit, offset, options) {
|
||||
const currentUser = options?.currentUser;
|
||||
let where = {};
|
||||
|
||||
|
||||
@ -470,6 +502,16 @@ module.exports = class Pay_typesDBApi {
|
||||
const records = await db.pay_types.findAll({
|
||||
attributes: [ 'id', 'name' ],
|
||||
where,
|
||||
include: isRestrictedPayrollUser(currentUser) ? [{
|
||||
model: db.employee_pay_types,
|
||||
as: 'employee_pay_types_pay_type',
|
||||
required: true,
|
||||
attributes: [],
|
||||
where: {
|
||||
employeeId: currentUser.id,
|
||||
active: true,
|
||||
},
|
||||
}] : undefined,
|
||||
limit: limit ? Number(limit) : undefined,
|
||||
offset: offset ? Number(offset) : undefined,
|
||||
orderBy: [['name', 'ASC']],
|
||||
|
||||
@ -3,6 +3,7 @@ const db = require('../models');
|
||||
const FileDBApi = require('./file');
|
||||
const crypto = require('crypto');
|
||||
const Utils = require('../utils');
|
||||
const { isRestrictedPayrollUser } = require('../../security/payrollAccess');
|
||||
|
||||
const bcrypt = require('bcrypt');
|
||||
const config = require('../../config');
|
||||
@ -387,9 +388,19 @@ module.exports = class UsersDBApi {
|
||||
|
||||
static async findBy(where, options) {
|
||||
const transaction = (options && options.transaction) || undefined;
|
||||
const currentUser = options?.currentUser;
|
||||
const effectiveWhere = { ...(where || {}) };
|
||||
|
||||
if (isRestrictedPayrollUser(currentUser)) {
|
||||
if (effectiveWhere.id && Utils.uuid(effectiveWhere.id) !== currentUser.id) {
|
||||
return null;
|
||||
}
|
||||
|
||||
effectiveWhere.id = currentUser.id;
|
||||
}
|
||||
|
||||
const users = await db.users.findOne(
|
||||
{ where },
|
||||
{ where: effectiveWhere },
|
||||
{ transaction },
|
||||
);
|
||||
|
||||
@ -408,6 +419,7 @@ module.exports = class UsersDBApi {
|
||||
|
||||
output.employee_pay_types_employee = await users.getEmployee_pay_types_employee({
|
||||
transaction,
|
||||
where: isRestrictedPayrollUser(currentUser) ? { employeeId: currentUser.id, active: true } : undefined,
|
||||
include: [
|
||||
{
|
||||
model: db.pay_types,
|
||||
@ -460,6 +472,7 @@ module.exports = class UsersDBApi {
|
||||
filter,
|
||||
options
|
||||
) {
|
||||
const currentUser = options?.currentUser;
|
||||
const limit = filter.limit || 0;
|
||||
let offset = 0;
|
||||
let where = {};
|
||||
@ -524,6 +537,13 @@ module.exports = class UsersDBApi {
|
||||
|
||||
];
|
||||
|
||||
if (isRestrictedPayrollUser(currentUser)) {
|
||||
where = {
|
||||
...where,
|
||||
id: currentUser.id,
|
||||
};
|
||||
}
|
||||
|
||||
if (filter) {
|
||||
if (filter.id) {
|
||||
where = {
|
||||
@ -783,7 +803,8 @@ module.exports = class UsersDBApi {
|
||||
}
|
||||
}
|
||||
|
||||
static async findAllAutocomplete(query, limit, offset, ) {
|
||||
static async findAllAutocomplete(query, limit, offset, options) {
|
||||
const currentUser = options?.currentUser;
|
||||
let where = {};
|
||||
|
||||
|
||||
@ -801,6 +822,13 @@ module.exports = class UsersDBApi {
|
||||
};
|
||||
}
|
||||
|
||||
if (isRestrictedPayrollUser(currentUser)) {
|
||||
where = {
|
||||
...where,
|
||||
id: currentUser.id,
|
||||
};
|
||||
}
|
||||
|
||||
const records = await db.users.findAll({
|
||||
attributes: [ 'id', 'firstName' ],
|
||||
where,
|
||||
|
||||
@ -335,7 +335,6 @@ router.get('/count', wrapAsync(async (req, res) => {
|
||||
const currentUser = req.currentUser;
|
||||
const payload = await Employee_pay_typesDBApi.findAll(
|
||||
req.query,
|
||||
null,
|
||||
{ countOnly: true, currentUser }
|
||||
);
|
||||
|
||||
@ -373,7 +372,7 @@ router.get('/autocomplete', async (req, res) => {
|
||||
req.query.query,
|
||||
req.query.limit,
|
||||
req.query.offset,
|
||||
|
||||
{ currentUser: req.currentUser },
|
||||
);
|
||||
|
||||
res.status(200).send(payload);
|
||||
@ -414,6 +413,7 @@ router.get('/autocomplete', async (req, res) => {
|
||||
router.get('/:id', wrapAsync(async (req, res) => {
|
||||
const payload = await Employee_pay_typesDBApi.findBy(
|
||||
{ id: req.params.id },
|
||||
{ currentUser: req.currentUser },
|
||||
);
|
||||
|
||||
|
||||
|
||||
@ -355,7 +355,6 @@ router.get('/count', wrapAsync(async (req, res) => {
|
||||
const currentUser = req.currentUser;
|
||||
const payload = await Job_logsDBApi.findAll(
|
||||
req.query,
|
||||
null,
|
||||
{ countOnly: true, currentUser }
|
||||
);
|
||||
|
||||
@ -393,7 +392,7 @@ router.get('/autocomplete', async (req, res) => {
|
||||
req.query.query,
|
||||
req.query.limit,
|
||||
req.query.offset,
|
||||
|
||||
{ currentUser: req.currentUser },
|
||||
);
|
||||
|
||||
res.status(200).send(payload);
|
||||
@ -434,6 +433,7 @@ router.get('/autocomplete', async (req, res) => {
|
||||
router.get('/:id', wrapAsync(async (req, res) => {
|
||||
const payload = await Job_logsDBApi.findBy(
|
||||
{ id: req.params.id },
|
||||
{ currentUser: req.currentUser },
|
||||
);
|
||||
|
||||
|
||||
|
||||
@ -348,7 +348,6 @@ router.get('/count', wrapAsync(async (req, res) => {
|
||||
const currentUser = req.currentUser;
|
||||
const payload = await Pay_typesDBApi.findAll(
|
||||
req.query,
|
||||
null,
|
||||
{ countOnly: true, currentUser }
|
||||
);
|
||||
|
||||
@ -386,7 +385,7 @@ router.get('/autocomplete', async (req, res) => {
|
||||
req.query.query,
|
||||
req.query.limit,
|
||||
req.query.offset,
|
||||
|
||||
{ currentUser: req.currentUser },
|
||||
);
|
||||
|
||||
res.status(200).send(payload);
|
||||
@ -427,6 +426,7 @@ router.get('/autocomplete', async (req, res) => {
|
||||
router.get('/:id', wrapAsync(async (req, res) => {
|
||||
const payload = await Pay_typesDBApi.findBy(
|
||||
{ id: req.params.id },
|
||||
{ currentUser: req.currentUser },
|
||||
);
|
||||
|
||||
|
||||
|
||||
@ -347,7 +347,6 @@ router.get('/count', wrapAsync(async (req, res) => {
|
||||
const currentUser = req.currentUser;
|
||||
const payload = await UsersDBApi.findAll(
|
||||
req.query,
|
||||
null,
|
||||
{ countOnly: true, currentUser }
|
||||
);
|
||||
|
||||
@ -385,7 +384,7 @@ router.get('/autocomplete', async (req, res) => {
|
||||
req.query.query,
|
||||
req.query.limit,
|
||||
req.query.offset,
|
||||
|
||||
{ currentUser: req.currentUser },
|
||||
);
|
||||
|
||||
res.status(200).send(payload);
|
||||
@ -426,11 +425,12 @@ router.get('/autocomplete', async (req, res) => {
|
||||
router.get('/:id', wrapAsync(async (req, res) => {
|
||||
const payload = await UsersDBApi.findBy(
|
||||
{ id: req.params.id },
|
||||
{ currentUser: req.currentUser },
|
||||
);
|
||||
|
||||
|
||||
|
||||
if (payload) {
|
||||
delete payload.password;
|
||||
|
||||
}
|
||||
|
||||
res.status(200).send(payload);
|
||||
}));
|
||||
|
||||
19
backend/src/security/payrollAccess.js
Normal file
19
backend/src/security/payrollAccess.js
Normal file
@ -0,0 +1,19 @@
|
||||
const PRIVILEGED_PAYROLL_ROLE_NAMES = new Set([
|
||||
'Administrator',
|
||||
'System Owner',
|
||||
'Payroll Manager',
|
||||
'Operations Manager',
|
||||
]);
|
||||
|
||||
function isRestrictedPayrollUser(currentUser) {
|
||||
if (!currentUser?.id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return !PRIVILEGED_PAYROLL_ROLE_NAMES.has(currentUser?.app_role?.name);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
PRIVILEGED_PAYROLL_ROLE_NAMES,
|
||||
isRestrictedPayrollUser,
|
||||
};
|
||||
@ -7,8 +7,28 @@ const csv = require('csv-parser');
|
||||
const axios = require('axios');
|
||||
const config = require('../config');
|
||||
const stream = require('stream');
|
||||
const { isRestrictedPayrollUser } = require('../security/payrollAccess');
|
||||
|
||||
module.exports = class Job_logsService {
|
||||
static async ensureRestrictedPayTypeAccess(payTypeId, currentUser, transaction) {
|
||||
if (!isRestrictedPayrollUser(currentUser) || !payTypeId) {
|
||||
return;
|
||||
}
|
||||
|
||||
const assignment = await db.employee_pay_types.findOne({
|
||||
where: {
|
||||
employeeId: currentUser.id,
|
||||
pay_typeId: payTypeId,
|
||||
active: true,
|
||||
},
|
||||
transaction,
|
||||
});
|
||||
|
||||
if (!assignment) {
|
||||
throw new ValidationError('errors.forbidden.message');
|
||||
}
|
||||
}
|
||||
|
||||
static async create(data, currentUser) {
|
||||
const transaction = await db.sequelize.transaction();
|
||||
try {
|
||||
@ -23,8 +43,16 @@ module.exports = class Job_logsService {
|
||||
customerId = customer.id;
|
||||
}
|
||||
|
||||
const jobPayload = { ...data, customer: customerId };
|
||||
|
||||
if (isRestrictedPayrollUser(currentUser)) {
|
||||
jobPayload.employee = currentUser.id;
|
||||
}
|
||||
|
||||
await Job_logsService.ensureRestrictedPayTypeAccess(jobPayload.pay_type, currentUser, transaction);
|
||||
|
||||
const createdJob = await Job_logsDBApi.create(
|
||||
{ ...data, customer: customerId },
|
||||
jobPayload,
|
||||
{
|
||||
currentUser,
|
||||
transaction,
|
||||
@ -93,7 +121,10 @@ module.exports = class Job_logsService {
|
||||
try {
|
||||
let job_logs = await Job_logsDBApi.findBy(
|
||||
{id},
|
||||
{transaction},
|
||||
{
|
||||
transaction,
|
||||
currentUser,
|
||||
},
|
||||
);
|
||||
|
||||
if (!job_logs) {
|
||||
@ -101,6 +132,10 @@ module.exports = class Job_logsService {
|
||||
'job_logsNotFound',
|
||||
);
|
||||
}
|
||||
|
||||
if (isRestrictedPayrollUser(currentUser) && job_logs.employeeId !== currentUser.id) {
|
||||
throw new ValidationError('errors.forbidden.message');
|
||||
}
|
||||
|
||||
let customerId = data.customer;
|
||||
|
||||
@ -113,9 +148,21 @@ module.exports = class Job_logsService {
|
||||
customerId = customer.id;
|
||||
}
|
||||
|
||||
const jobPayload = { ...data, customer: customerId };
|
||||
|
||||
if (isRestrictedPayrollUser(currentUser)) {
|
||||
jobPayload.employee = currentUser.id;
|
||||
}
|
||||
|
||||
await Job_logsService.ensureRestrictedPayTypeAccess(
|
||||
jobPayload.pay_type !== undefined ? jobPayload.pay_type : job_logs.pay_typeId,
|
||||
currentUser,
|
||||
transaction,
|
||||
);
|
||||
|
||||
const updatedJob_logs = await Job_logsDBApi.update(
|
||||
id,
|
||||
{ ...data, customer: customerId },
|
||||
jobPayload,
|
||||
{
|
||||
currentUser,
|
||||
transaction,
|
||||
|
||||
@ -3,6 +3,7 @@ import { MenuAsideItem } from '../interfaces'
|
||||
import AsideMenuItem from './AsideMenuItem'
|
||||
import {useAppSelector} from "../stores/hooks";
|
||||
import {hasPermission} from "../helpers/userPermissions";
|
||||
import { isBlockedWorkerRoute, isRestrictedPayrollUser } from '../helpers/accessControl';
|
||||
|
||||
type Props = {
|
||||
menu: MenuAsideItem[]
|
||||
@ -18,9 +19,10 @@ export default function AsideMenuList({ menu, isDropdownList = false, className
|
||||
return (
|
||||
<ul className={className}>
|
||||
{menu.map((item, index) => {
|
||||
|
||||
if (!hasPermission(currentUser, item.permissions)) return null;
|
||||
|
||||
if (!hasPermission(currentUser, item.permissions)) return null;
|
||||
|
||||
if (isRestrictedPayrollUser(currentUser) && isBlockedWorkerRoute(item.href)) return null;
|
||||
|
||||
return (
|
||||
<div key={index}>
|
||||
<AsideMenuItem
|
||||
|
||||
24
frontend/src/helpers/accessControl.ts
Normal file
24
frontend/src/helpers/accessControl.ts
Normal file
@ -0,0 +1,24 @@
|
||||
const PRIVILEGED_PAYROLL_ROLE_NAMES = new Set([
|
||||
'Administrator',
|
||||
'System Owner',
|
||||
'Payroll Manager',
|
||||
'Operations Manager',
|
||||
]);
|
||||
|
||||
const BLOCKED_WORKER_ROUTE_PREFIXES = ['/users', '/pay_types', '/employee_pay_types'];
|
||||
|
||||
export function isRestrictedPayrollUser(user: any) {
|
||||
if (!user?.id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return !PRIVILEGED_PAYROLL_ROLE_NAMES.has(user?.app_role?.name);
|
||||
}
|
||||
|
||||
export function isBlockedWorkerRoute(pathname?: string) {
|
||||
if (!pathname) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return BLOCKED_WORKER_ROUTE_PREFIXES.some((prefix) => pathname.startsWith(prefix));
|
||||
}
|
||||
@ -14,6 +14,7 @@ import { useRouter } from 'next/router'
|
||||
import {findMe, logoutUser} from "../stores/authSlice";
|
||||
|
||||
import {hasPermission} from "../helpers/userPermissions";
|
||||
import { isBlockedWorkerRoute, isRestrictedPayrollUser } from '../helpers/accessControl';
|
||||
|
||||
|
||||
type Props = {
|
||||
@ -61,7 +62,15 @@ export default function LayoutAuthenticated({
|
||||
if (!permission || !currentUser) return;
|
||||
|
||||
if (!hasPermission(currentUser, permission)) router.push('/error');
|
||||
}, [currentUser, permission]);
|
||||
}, [currentUser, permission, router]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!currentUser) return;
|
||||
|
||||
if (isRestrictedPayrollUser(currentUser) && isBlockedWorkerRoute(router.pathname)) {
|
||||
router.replace('/my-logs');
|
||||
}
|
||||
}, [currentUser, router, router.pathname]);
|
||||
|
||||
|
||||
const darkMode = useAppSelector((state) => state.style.darkMode)
|
||||
|
||||
@ -11,6 +11,7 @@ import { getPageTitle } from '../config'
|
||||
import Link from "next/link";
|
||||
|
||||
import { hasPermission } from "../helpers/userPermissions";
|
||||
import { isRestrictedPayrollUser } from '../helpers/accessControl';
|
||||
import { fetchWidgets } from '../stores/roles/rolesSlice';
|
||||
import { WidgetCreator } from '../components/WidgetCreator/WidgetCreator';
|
||||
import { SmartWidget } from '../components/SmartWidget/SmartWidget';
|
||||
@ -157,7 +158,7 @@ const Dashboard = () => {
|
||||
|
||||
|
||||
|
||||
{hasPermission(currentUser, 'READ_USERS') && <Link href={'/users/users-list'}>
|
||||
{!isRestrictedPayrollUser(currentUser) && hasPermission(currentUser, 'READ_USERS') && <Link href={'/users/users-list'}>
|
||||
<div
|
||||
className={`${corners !== 'rounded-full'? corners : 'rounded-3xl'} dark:bg-dark-900 ${cardsStyle} dark:border-dark-700 p-6`}
|
||||
>
|
||||
@ -297,7 +298,7 @@ const Dashboard = () => {
|
||||
</div>
|
||||
</Link>}
|
||||
|
||||
{hasPermission(currentUser, 'READ_PAY_TYPES') && <Link href={'/pay_types/pay_types-list'}>
|
||||
{!isRestrictedPayrollUser(currentUser) && hasPermission(currentUser, 'READ_PAY_TYPES') && <Link href={'/pay_types/pay_types-list'}>
|
||||
<div
|
||||
className={`${corners !== 'rounded-full'? corners : 'rounded-3xl'} dark:bg-dark-900 ${cardsStyle} dark:border-dark-700 p-6`}
|
||||
>
|
||||
@ -325,7 +326,7 @@ const Dashboard = () => {
|
||||
</div>
|
||||
</Link>}
|
||||
|
||||
{hasPermission(currentUser, 'READ_EMPLOYEE_PAY_TYPES') && <Link href={'/employee_pay_types/employee_pay_types-list'}>
|
||||
{!isRestrictedPayrollUser(currentUser) && hasPermission(currentUser, 'READ_EMPLOYEE_PAY_TYPES') && <Link href={'/employee_pay_types/employee_pay_types-list'}>
|
||||
<div
|
||||
className={`${corners !== 'rounded-full'? corners : 'rounded-3xl'} dark:bg-dark-900 ${cardsStyle} dark:border-dark-700 p-6`}
|
||||
>
|
||||
|
||||
1
frontend/tsconfig.tsbuildinfo
Normal file
1
frontend/tsconfig.tsbuildinfo
Normal file
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user