fix(issues): only allow edit of own comments & do not allow non-admin delete of issues with comments (#2248)

pull/2251/head
TheCatLady 3 years ago committed by GitHub
parent 0828b008ba
commit bba09d69c1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -302,7 +302,7 @@ issueRoutes.delete('/:issueId', async (req, res, next) => {
if (
!req.user?.hasPermission(Permission.MANAGE_ISSUES) &&
issue.createdBy.id !== req.user?.id
(issue.createdBy.id !== req.user?.id || issue.comments.length > 1)
) {
return next({
status: 401,

@ -68,13 +68,10 @@ issueCommentRoutes.put<
where: { id: Number(req.params.commentId) },
});
if (
!req.user?.hasPermission([Permission.MANAGE_ISSUES], { type: 'or' }) &&
comment.user.id !== req.user?.id
) {
if (comment.user.id !== req.user?.id) {
return next({
status: 403,
message: 'You do not have permission to edit this comment.',
message: 'You can only edit your own comments.',
});
}

@ -39,7 +39,7 @@ const IssueComment: React.FC<IssueCommentProps> = ({
const intl = useIntl();
const [showDeleteModal, setShowDeleteModal] = useState(false);
const [isEditing, setIsEditing] = useState(false);
const { user, hasPermission } = useUser();
const { hasPermission } = useUser();
const EditCommentSchema = Yup.object().shape({
newMessage: Yup.string().required(
@ -59,8 +59,6 @@ const IssueComment: React.FC<IssueCommentProps> = ({
}
};
const belongsToUser = comment.user.id === user?.id;
return (
<div
className={`flex ${
@ -98,7 +96,7 @@ const IssueComment: React.FC<IssueCommentProps> = ({
</Link>
<div className="relative flex-1">
<div className="w-full rounded-md shadow ring-1 ring-gray-500">
{(belongsToUser || hasPermission(Permission.MANAGE_ISSUES)) && (
{(isActiveUser || hasPermission(Permission.MANAGE_ISSUES)) && (
<Menu
as="div"
className="absolute z-40 inline-block text-left top-2 right-1"
@ -129,20 +127,22 @@ const IssueComment: React.FC<IssueCommentProps> = ({
className="absolute right-0 w-56 mt-2 origin-top-right bg-gray-700 rounded-md shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none"
>
<div className="py-1">
<Menu.Item>
{({ active }) => (
<button
onClick={() => setIsEditing(true)}
className={`block w-full text-left px-4 py-2 text-sm ${
active
? 'bg-gray-600 text-white'
: 'text-gray-100'
}`}
>
{intl.formatMessage(messages.edit)}
</button>
)}
</Menu.Item>
{isActiveUser && (
<Menu.Item>
{({ active }) => (
<button
onClick={() => setIsEditing(true)}
className={`block w-full text-left px-4 py-2 text-sm ${
active
? 'bg-gray-600 text-white'
: 'text-gray-100'
}`}
>
{intl.formatMessage(messages.edit)}
</button>
)}
</Menu.Item>
)}
<Menu.Item>
{({ active }) => (
<button

@ -15,20 +15,22 @@ const messages = defineMessages({
});
interface IssueDescriptionProps {
issueId: number;
description: string;
belongsToUser: boolean;
commentCount: number;
onEdit: (newDescription: string) => void;
onDelete: () => void;
}
const IssueDescription: React.FC<IssueDescriptionProps> = ({
issueId,
description,
belongsToUser,
commentCount,
onEdit,
onDelete,
}) => {
const intl = useIntl();
const { user, hasPermission } = useUser();
const { hasPermission } = useUser();
const [isEditing, setIsEditing] = useState(false);
return (
@ -37,7 +39,7 @@ const IssueDescription: React.FC<IssueDescriptionProps> = ({
<div className="font-semibold text-gray-100 lg:text-xl">
{intl.formatMessage(messages.description)}
</div>
{(hasPermission(Permission.MANAGE_ISSUES) || user?.id === issueId) && (
{(hasPermission(Permission.MANAGE_ISSUES) || belongsToUser) && (
<Menu as="div" className="relative inline-block text-left">
{({ open }) => (
<>
@ -63,35 +65,39 @@ const IssueDescription: React.FC<IssueDescriptionProps> = ({
className="absolute right-0 w-56 mt-2 origin-top-right bg-gray-700 rounded-md shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none"
>
<div className="py-1">
<Menu.Item>
{({ active }) => (
<button
onClick={() => setIsEditing(true)}
className={`block w-full text-left px-4 py-2 text-sm ${
active
? 'bg-gray-600 text-white'
: 'text-gray-100'
}`}
>
{intl.formatMessage(messages.edit)}
</button>
)}
</Menu.Item>
<Menu.Item>
{({ active }) => (
<button
onClick={() => onDelete()}
className={`block w-full text-left px-4 py-2 text-sm ${
active
? 'bg-gray-600 text-white'
: 'text-gray-100'
}`}
>
{intl.formatMessage(messages.deleteissue)}
</button>
)}
</Menu.Item>
{belongsToUser && (
<Menu.Item>
{({ active }) => (
<button
onClick={() => setIsEditing(true)}
className={`block w-full text-left px-4 py-2 text-sm ${
active
? 'bg-gray-600 text-white'
: 'text-gray-100'
}`}
>
{intl.formatMessage(messages.edit)}
</button>
)}
</Menu.Item>
)}
{(hasPermission(Permission.MANAGE_ISSUES) ||
!commentCount) && (
<Menu.Item>
{({ active }) => (
<button
onClick={() => onDelete()}
className={`block w-full text-left px-4 py-2 text-sm ${
active
? 'bg-gray-600 text-white'
: 'text-gray-100'
}`}
>
{intl.formatMessage(messages.deleteissue)}
</button>
)}
</Menu.Item>
)}
</div>
</Menu.Items>
</Transition>

@ -260,7 +260,7 @@ const IssueDetails: React.FC = () => {
username: (
<Link
href={
issueData.createdBy.id === currentUser?.id
belongsToUser
? '/profile'
: `/users/${issueData.createdBy.id}`
}
@ -294,8 +294,9 @@ const IssueDetails: React.FC = () => {
<div className="relative z-10 flex mt-6 text-gray-300">
<div className="flex-1 lg:pr-4">
<IssueDescription
issueId={issueData.id}
description={firstComment.message}
belongsToUser={belongsToUser}
commentCount={otherComments.length}
onEdit={(newMessage) => {
editFirstComment(newMessage);
}}

Loading…
Cancel
Save