mirror of
https://github.com/sct/overseerr.git
synced 2025-09-17 17:24:35 +02:00
fix: add missing route guards to issues pages (#2235)
* fix: users should always be able to view their own issues * fix: apply route guards to issues pages instead * fix(api): only allow users w/ issue perms to edit comments / delete issues
This commit is contained in:
@@ -68,7 +68,7 @@ issueRoutes.get<Record<string, string>, IssueResultsResponse>(
|
|||||||
return next({
|
return next({
|
||||||
status: 403,
|
status: 403,
|
||||||
message:
|
message:
|
||||||
'You do not have permission to view issues created by other users',
|
'You do not have permission to view issues reported by other users',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
query = query.andWhere('createdBy.id = :id', { id: req.user?.id });
|
query = query.andWhere('createdBy.id = :id', { id: req.user?.id });
|
||||||
@@ -291,35 +291,41 @@ issueRoutes.post<{ issueId: string; status: string }, Issue>(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
issueRoutes.delete('/:issueId', async (req, res, next) => {
|
issueRoutes.delete(
|
||||||
const issueRepository = getRepository(Issue);
|
'/:issueId',
|
||||||
|
isAuthenticated([Permission.MANAGE_ISSUES, Permission.CREATE_ISSUES], {
|
||||||
|
type: 'or',
|
||||||
|
}),
|
||||||
|
async (req, res, next) => {
|
||||||
|
const issueRepository = getRepository(Issue);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const issue = await issueRepository.findOneOrFail({
|
const issue = await issueRepository.findOneOrFail({
|
||||||
where: { id: Number(req.params.issueId) },
|
where: { id: Number(req.params.issueId) },
|
||||||
relations: ['createdBy'],
|
relations: ['createdBy'],
|
||||||
});
|
|
||||||
|
|
||||||
if (
|
|
||||||
!req.user?.hasPermission(Permission.MANAGE_ISSUES) &&
|
|
||||||
(issue.createdBy.id !== req.user?.id || issue.comments.length > 1)
|
|
||||||
) {
|
|
||||||
return next({
|
|
||||||
status: 401,
|
|
||||||
message: 'You do not have permission to delete this issue.',
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (
|
||||||
|
!req.user?.hasPermission(Permission.MANAGE_ISSUES) &&
|
||||||
|
(issue.createdBy.id !== req.user?.id || issue.comments.length > 1)
|
||||||
|
) {
|
||||||
|
return next({
|
||||||
|
status: 401,
|
||||||
|
message: 'You do not have permission to delete this issue.',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
await issueRepository.remove(issue);
|
||||||
|
|
||||||
|
return res.status(204).send();
|
||||||
|
} catch (e) {
|
||||||
|
logger.error('Something went wrong deleting an issue.', {
|
||||||
|
label: 'API',
|
||||||
|
errorMessage: e.message,
|
||||||
|
});
|
||||||
|
next({ status: 404, message: 'Issue not found.' });
|
||||||
}
|
}
|
||||||
|
|
||||||
await issueRepository.remove(issue);
|
|
||||||
|
|
||||||
return res.status(204).send();
|
|
||||||
} catch (e) {
|
|
||||||
logger.error('Something went wrong deleting an issue.', {
|
|
||||||
label: 'API',
|
|
||||||
errorMessage: e.message,
|
|
||||||
});
|
|
||||||
next({ status: 404, message: 'Issue not found.' });
|
|
||||||
}
|
}
|
||||||
});
|
);
|
||||||
|
|
||||||
export default issueRoutes;
|
export default issueRoutes;
|
||||||
|
@@ -500,9 +500,26 @@ requestRoutes.get('/:requestId', async (req, res, next) => {
|
|||||||
relations: ['requestedBy', 'modifiedBy'],
|
relations: ['requestedBy', 'modifiedBy'],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (
|
||||||
|
request.requestedBy.id !== req.user?.id &&
|
||||||
|
!req.user?.hasPermission(
|
||||||
|
[Permission.MANAGE_REQUESTS, Permission.REQUEST_VIEW],
|
||||||
|
{ type: 'or' }
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
return next({
|
||||||
|
status: 403,
|
||||||
|
message: 'You do not have permission to view this request.',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return res.status(200).json(request);
|
return res.status(200).json(request);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
next({ status: 404, message: 'Request not found' });
|
logger.debug('Failed to retrieve request.', {
|
||||||
|
label: 'API',
|
||||||
|
errorMessage: e.message,
|
||||||
|
});
|
||||||
|
next({ status: 404, message: 'Request not found.' });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -1,8 +1,20 @@
|
|||||||
import { NextPage } from 'next';
|
import { NextPage } from 'next';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import IssueDetails from '../../../components/IssueDetails';
|
import IssueDetails from '../../../components/IssueDetails';
|
||||||
|
import useRouteGuard from '../../../hooks/useRouteGuard';
|
||||||
|
import { Permission } from '../../../hooks/useUser';
|
||||||
|
|
||||||
const IssuePage: NextPage = () => {
|
const IssuePage: NextPage = () => {
|
||||||
|
useRouteGuard(
|
||||||
|
[
|
||||||
|
Permission.MANAGE_ISSUES,
|
||||||
|
Permission.CREATE_ISSUES,
|
||||||
|
Permission.VIEW_ISSUES,
|
||||||
|
],
|
||||||
|
{
|
||||||
|
type: 'or',
|
||||||
|
}
|
||||||
|
);
|
||||||
return <IssueDetails />;
|
return <IssueDetails />;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -1,8 +1,20 @@
|
|||||||
import { NextPage } from 'next';
|
import { NextPage } from 'next';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import IssueList from '../../components/IssueList';
|
import IssueList from '../../components/IssueList';
|
||||||
|
import useRouteGuard from '../../hooks/useRouteGuard';
|
||||||
|
import { Permission } from '../../hooks/useUser';
|
||||||
|
|
||||||
const IssuePage: NextPage = () => {
|
const IssuePage: NextPage = () => {
|
||||||
|
useRouteGuard(
|
||||||
|
[
|
||||||
|
Permission.MANAGE_ISSUES,
|
||||||
|
Permission.CREATE_ISSUES,
|
||||||
|
Permission.VIEW_ISSUES,
|
||||||
|
],
|
||||||
|
{
|
||||||
|
type: 'or',
|
||||||
|
}
|
||||||
|
);
|
||||||
return <IssueList />;
|
return <IssueList />;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user