mirror of
https://github.com/sct/overseerr.git
synced 2025-09-17 17:24:35 +02:00
feat(ui): Add separate permissions for 4K auto approval (#908)
* Clarify & fix permission descriptions * Automatically check & disable auto-approve permission options when 'Manage Requests' permission is selected
This commit is contained in:
@@ -14,6 +14,9 @@ export enum Permission {
|
|||||||
REQUEST_4K_TV = 4096,
|
REQUEST_4K_TV = 4096,
|
||||||
REQUEST_ADVANCED = 8192,
|
REQUEST_ADVANCED = 8192,
|
||||||
REQUEST_VIEW = 16384,
|
REQUEST_VIEW = 16384,
|
||||||
|
AUTO_APPROVE_4K = 32768,
|
||||||
|
AUTO_APPROVE_4K_MOVIE = 65536,
|
||||||
|
AUTO_APPROVE_4K_TV = 131072,
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PermissionCheckOptions {
|
export interface PermissionCheckOptions {
|
||||||
|
@@ -213,13 +213,29 @@ requestRoutes.post(
|
|||||||
requestedBy: requestUser,
|
requestedBy: requestUser,
|
||||||
// If the user is an admin or has the "auto approve" permission, automatically approve the request
|
// If the user is an admin or has the "auto approve" permission, automatically approve the request
|
||||||
status:
|
status:
|
||||||
req.user?.hasPermission(Permission.AUTO_APPROVE) ||
|
req.user?.hasPermission(
|
||||||
req.user?.hasPermission(Permission.AUTO_APPROVE_MOVIE)
|
req.body.is4k
|
||||||
|
? Permission.AUTO_APPROVE_4K
|
||||||
|
: Permission.AUTO_APPROVE
|
||||||
|
) ||
|
||||||
|
req.user?.hasPermission(
|
||||||
|
req.body.is4k
|
||||||
|
? Permission.AUTO_APPROVE_4K_MOVIE
|
||||||
|
: Permission.AUTO_APPROVE_MOVIE
|
||||||
|
)
|
||||||
? MediaRequestStatus.APPROVED
|
? MediaRequestStatus.APPROVED
|
||||||
: MediaRequestStatus.PENDING,
|
: MediaRequestStatus.PENDING,
|
||||||
modifiedBy:
|
modifiedBy:
|
||||||
req.user?.hasPermission(Permission.AUTO_APPROVE) ||
|
req.user?.hasPermission(
|
||||||
req.user?.hasPermission(Permission.AUTO_APPROVE_MOVIE)
|
req.body.is4k
|
||||||
|
? Permission.AUTO_APPROVE_4K
|
||||||
|
: Permission.AUTO_APPROVE
|
||||||
|
) ||
|
||||||
|
req.user?.hasPermission(
|
||||||
|
req.body.is4k
|
||||||
|
? Permission.AUTO_APPROVE_4K_MOVIE
|
||||||
|
: Permission.AUTO_APPROVE_MOVIE
|
||||||
|
)
|
||||||
? req.user
|
? req.user
|
||||||
: undefined,
|
: undefined,
|
||||||
is4k: req.body.is4k,
|
is4k: req.body.is4k,
|
||||||
@@ -274,13 +290,29 @@ requestRoutes.post(
|
|||||||
requestedBy: requestUser,
|
requestedBy: requestUser,
|
||||||
// If the user is an admin or has the "auto approve" permission, automatically approve the request
|
// If the user is an admin or has the "auto approve" permission, automatically approve the request
|
||||||
status:
|
status:
|
||||||
req.user?.hasPermission(Permission.AUTO_APPROVE) ||
|
req.user?.hasPermission(
|
||||||
req.user?.hasPermission(Permission.AUTO_APPROVE_TV)
|
req.body.is4k
|
||||||
|
? Permission.AUTO_APPROVE_4K
|
||||||
|
: Permission.AUTO_APPROVE
|
||||||
|
) ||
|
||||||
|
req.user?.hasPermission(
|
||||||
|
req.body.is4k
|
||||||
|
? Permission.AUTO_APPROVE_4K_TV
|
||||||
|
: Permission.AUTO_APPROVE_TV
|
||||||
|
)
|
||||||
? MediaRequestStatus.APPROVED
|
? MediaRequestStatus.APPROVED
|
||||||
: MediaRequestStatus.PENDING,
|
: MediaRequestStatus.PENDING,
|
||||||
modifiedBy:
|
modifiedBy:
|
||||||
req.user?.hasPermission(Permission.AUTO_APPROVE) ||
|
req.user?.hasPermission(
|
||||||
req.user?.hasPermission(Permission.AUTO_APPROVE_TV)
|
req.body.is4k
|
||||||
|
? Permission.AUTO_APPROVE_4K
|
||||||
|
: Permission.AUTO_APPROVE
|
||||||
|
) ||
|
||||||
|
req.user?.hasPermission(
|
||||||
|
req.body.is4k
|
||||||
|
? Permission.AUTO_APPROVE_4K_TV
|
||||||
|
: Permission.AUTO_APPROVE_TV
|
||||||
|
)
|
||||||
? req.user
|
? req.user
|
||||||
: undefined,
|
: undefined,
|
||||||
is4k: req.body.is4k,
|
is4k: req.body.is4k,
|
||||||
@@ -293,8 +325,16 @@ requestRoutes.post(
|
|||||||
new SeasonRequest({
|
new SeasonRequest({
|
||||||
seasonNumber: sn,
|
seasonNumber: sn,
|
||||||
status:
|
status:
|
||||||
req.user?.hasPermission(Permission.AUTO_APPROVE) ||
|
req.user?.hasPermission(
|
||||||
req.user?.hasPermission(Permission.AUTO_APPROVE_TV)
|
req.body.is4k
|
||||||
|
? Permission.AUTO_APPROVE_4K
|
||||||
|
: Permission.AUTO_APPROVE
|
||||||
|
) ||
|
||||||
|
req.user?.hasPermission(
|
||||||
|
req.body.is4k
|
||||||
|
? Permission.AUTO_APPROVE_4K_TV
|
||||||
|
: Permission.AUTO_APPROVE_TV
|
||||||
|
)
|
||||||
? MediaRequestStatus.APPROVED
|
? MediaRequestStatus.APPROVED
|
||||||
: MediaRequestStatus.PENDING,
|
: MediaRequestStatus.PENDING,
|
||||||
})
|
})
|
||||||
|
@@ -9,27 +9,36 @@ export const messages = defineMessages({
|
|||||||
'Full administrator access. Bypasses all permission checks.',
|
'Full administrator access. Bypasses all permission checks.',
|
||||||
users: 'Manage Users',
|
users: 'Manage Users',
|
||||||
usersDescription:
|
usersDescription:
|
||||||
'Grants permission to manage Overseerr users. Users with this permission cannot modify users with Administrator privilege, or grant it.',
|
'Grants permission to manage Overseerr users. Users with this permission cannot modify users with or grant the Admin privilege.',
|
||||||
settings: 'Manage Settings',
|
settings: 'Manage Settings',
|
||||||
settingsDescription:
|
settingsDescription:
|
||||||
'Grants permission to modify all Overseerr settings. A user must have this permission to grant it to others.',
|
'Grants permission to modify all Overseerr settings. A user must have this permission to grant it to others.',
|
||||||
managerequests: 'Manage Requests',
|
managerequests: 'Manage Requests',
|
||||||
managerequestsDescription:
|
managerequestsDescription:
|
||||||
'Grants permission to manage Overseerr requests. This includes approving and denying requests.',
|
'Grants permission to manage Overseerr requests. This includes approving and denying requests. All requests made by a user with this permission will be automatically approved regardless of whether or not they have Auto-Approve permissions.',
|
||||||
request: 'Request',
|
request: 'Request',
|
||||||
requestDescription: 'Grants permission to request movies and series.',
|
requestDescription: 'Grants permission to request movies and series.',
|
||||||
vote: 'Vote',
|
vote: 'Vote',
|
||||||
voteDescription:
|
voteDescription:
|
||||||
'Grants permission to vote on requests (voting not yet implemented)',
|
'Grants permission to vote on requests (voting not yet implemented).',
|
||||||
autoapprove: 'Auto Approve',
|
autoapprove: 'Auto-Approve',
|
||||||
autoapproveDescription:
|
autoapproveDescription:
|
||||||
'Grants auto approval for any requests made by this user.',
|
'Grants automatic approval for all non-4K requests made by this user.',
|
||||||
autoapproveMovies: 'Auto Approve Movies',
|
autoapproveMovies: 'Auto-Approve Movies',
|
||||||
autoapproveMoviesDescription:
|
autoapproveMoviesDescription:
|
||||||
'Grants auto approve for movie requests made by this user.',
|
'Grants automatic approval for non-4K movie requests made by this user.',
|
||||||
autoapproveSeries: 'Auto Approve Series',
|
autoapproveSeries: 'Auto-Approve Series',
|
||||||
autoapproveSeriesDescription:
|
autoapproveSeriesDescription:
|
||||||
'Grants auto approve for series requests made by this user.',
|
'Grants automatic approval for non-4K series requests made by this user.',
|
||||||
|
autoapprove4k: 'Auto-Approve 4K',
|
||||||
|
autoapprove4kDescription:
|
||||||
|
'Grants automatic approval for all 4K requests made by this user.',
|
||||||
|
autoapprove4kMovies: 'Auto-Approve 4K Movies',
|
||||||
|
autoapprove4kMoviesDescription:
|
||||||
|
'Grants automatic approval for 4K movie requests made by this user.',
|
||||||
|
autoapprove4kSeries: 'Auto-Approve 4K Series',
|
||||||
|
autoapprove4kSeriesDescription:
|
||||||
|
'Grants automatic approval for 4K series requests made by this user.',
|
||||||
request4k: 'Request 4K',
|
request4k: 'Request 4K',
|
||||||
request4kDescription: 'Grants permission to request 4K movies and series.',
|
request4kDescription: 'Grants permission to request 4K movies and series.',
|
||||||
request4kMovies: 'Request 4K Movies',
|
request4kMovies: 'Request 4K Movies',
|
||||||
@@ -38,9 +47,9 @@ export const messages = defineMessages({
|
|||||||
request4kTvDescription: 'Grants permission to request 4K Series.',
|
request4kTvDescription: 'Grants permission to request 4K Series.',
|
||||||
advancedrequest: 'Advanced Requests',
|
advancedrequest: 'Advanced Requests',
|
||||||
advancedrequestDescription:
|
advancedrequestDescription:
|
||||||
'Grants permission to use advanced request options. (Ex. Changing servers/profiles/paths)',
|
'Grants permission to use advanced request options (e.g., changing servers, profiles, or paths).',
|
||||||
viewrequests: 'View Requests',
|
viewrequests: 'View Requests',
|
||||||
viewrequestsDescription: "Grants permission to view other user's requests.",
|
viewrequestsDescription: "Grants permission to view other users' requests.",
|
||||||
});
|
});
|
||||||
|
|
||||||
interface PermissionEditProps {
|
interface PermissionEditProps {
|
||||||
@@ -145,6 +154,30 @@ export const PermissionEdit: React.FC<PermissionEditProps> = ({
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: 'autoapprove4k',
|
||||||
|
name: intl.formatMessage(messages.autoapprove4k),
|
||||||
|
description: intl.formatMessage(messages.autoapprove4kDescription),
|
||||||
|
permission: Permission.AUTO_APPROVE_4K,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
id: 'autoapprove4k-movies',
|
||||||
|
name: intl.formatMessage(messages.autoapprove4kMovies),
|
||||||
|
description: intl.formatMessage(
|
||||||
|
messages.autoapprove4kMoviesDescription
|
||||||
|
),
|
||||||
|
permission: Permission.AUTO_APPROVE_4K_MOVIE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'autoapprove4k-tv',
|
||||||
|
name: intl.formatMessage(messages.autoapprove4kSeries),
|
||||||
|
description: intl.formatMessage(
|
||||||
|
messages.autoapprove4kSeriesDescription
|
||||||
|
),
|
||||||
|
permission: Permission.AUTO_APPROVE_4K_TV,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@@ -25,12 +25,23 @@ const PermissionOption: React.FC<PermissionOptionProps> = ({
|
|||||||
user,
|
user,
|
||||||
parent,
|
parent,
|
||||||
}) => {
|
}) => {
|
||||||
|
const autoApprovePermissions = [
|
||||||
|
Permission.AUTO_APPROVE,
|
||||||
|
Permission.AUTO_APPROVE_MOVIE,
|
||||||
|
Permission.AUTO_APPROVE_TV,
|
||||||
|
Permission.AUTO_APPROVE_4K,
|
||||||
|
Permission.AUTO_APPROVE_4K_MOVIE,
|
||||||
|
Permission.AUTO_APPROVE_4K_TV,
|
||||||
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div
|
<div
|
||||||
className={`relative flex items-start first:mt-0 mt-4 ${
|
className={`relative flex items-start first:mt-0 mt-4 ${
|
||||||
(option.permission !== Permission.ADMIN &&
|
(option.permission !== Permission.ADMIN &&
|
||||||
hasPermission(Permission.ADMIN, currentPermission)) ||
|
hasPermission(Permission.ADMIN, currentPermission)) ||
|
||||||
|
(autoApprovePermissions.includes(option.permission) &&
|
||||||
|
hasPermission(Permission.MANAGE_REQUESTS, currentPermission)) ||
|
||||||
(!!parent?.permission &&
|
(!!parent?.permission &&
|
||||||
hasPermission(parent.permission, currentPermission)) ||
|
hasPermission(parent.permission, currentPermission)) ||
|
||||||
(user && user.id !== 1 && option.permission === Permission.ADMIN) ||
|
(user && user.id !== 1 && option.permission === Permission.ADMIN) ||
|
||||||
@@ -49,6 +60,8 @@ const PermissionOption: React.FC<PermissionOptionProps> = ({
|
|||||||
disabled={
|
disabled={
|
||||||
(option.permission !== Permission.ADMIN &&
|
(option.permission !== Permission.ADMIN &&
|
||||||
hasPermission(Permission.ADMIN, currentPermission)) ||
|
hasPermission(Permission.ADMIN, currentPermission)) ||
|
||||||
|
(autoApprovePermissions.includes(option.permission) &&
|
||||||
|
hasPermission(Permission.MANAGE_REQUESTS, currentPermission)) ||
|
||||||
(!!parent?.permission &&
|
(!!parent?.permission &&
|
||||||
hasPermission(parent.permission, currentPermission)) ||
|
hasPermission(parent.permission, currentPermission)) ||
|
||||||
(user &&
|
(user &&
|
||||||
@@ -68,7 +81,9 @@ const PermissionOption: React.FC<PermissionOptionProps> = ({
|
|||||||
checked={
|
checked={
|
||||||
hasPermission(option.permission, currentPermission) ||
|
hasPermission(option.permission, currentPermission) ||
|
||||||
(!!parent?.permission &&
|
(!!parent?.permission &&
|
||||||
hasPermission(parent.permission, currentPermission))
|
hasPermission(parent.permission, currentPermission)) ||
|
||||||
|
(autoApprovePermissions.includes(option.permission) &&
|
||||||
|
hasPermission(Permission.MANAGE_REQUESTS, currentPermission))
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -100,8 +100,14 @@ const MovieRequestModal: React.FC<RequestModalProps> = ({
|
|||||||
if (response.data) {
|
if (response.data) {
|
||||||
if (onComplete) {
|
if (onComplete) {
|
||||||
onComplete(
|
onComplete(
|
||||||
hasPermission(Permission.AUTO_APPROVE) ||
|
hasPermission(
|
||||||
hasPermission(Permission.AUTO_APPROVE_MOVIE)
|
is4k ? Permission.AUTO_APPROVE_4K : Permission.AUTO_APPROVE
|
||||||
|
) ||
|
||||||
|
hasPermission(
|
||||||
|
is4k
|
||||||
|
? Permission.AUTO_APPROVE_4K_MOVIE
|
||||||
|
: Permission.AUTO_APPROVE_MOVIE
|
||||||
|
)
|
||||||
? MediaStatus.PROCESSING
|
? MediaStatus.PROCESSING
|
||||||
: MediaStatus.PENDING
|
: MediaStatus.PENDING
|
||||||
);
|
);
|
||||||
@@ -275,8 +281,14 @@ const MovieRequestModal: React.FC<RequestModalProps> = ({
|
|||||||
iconSvg={<DownloadIcon className="w-6 h-6" />}
|
iconSvg={<DownloadIcon className="w-6 h-6" />}
|
||||||
>
|
>
|
||||||
{(hasPermission(Permission.MANAGE_REQUESTS) ||
|
{(hasPermission(Permission.MANAGE_REQUESTS) ||
|
||||||
hasPermission(Permission.AUTO_APPROVE) ||
|
hasPermission(
|
||||||
hasPermission(Permission.AUTO_APPROVE_MOVIE)) && (
|
is4k ? Permission.AUTO_APPROVE_4K : Permission.AUTO_APPROVE
|
||||||
|
) ||
|
||||||
|
hasPermission(
|
||||||
|
is4k
|
||||||
|
? Permission.AUTO_APPROVE_4K_MOVIE
|
||||||
|
: Permission.AUTO_APPROVE_MOVIE
|
||||||
|
)) && (
|
||||||
<p className="mt-6">
|
<p className="mt-6">
|
||||||
<Alert title={intl.formatMessage(messages.autoapproval)} type="info">
|
<Alert title={intl.formatMessage(messages.autoapproval)} type="info">
|
||||||
{intl.formatMessage(messages.requestadmin)}
|
{intl.formatMessage(messages.requestadmin)}
|
||||||
|
@@ -365,8 +365,12 @@ const TvRequestModal: React.FC<RequestModalProps> = ({
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
{(hasPermission(Permission.MANAGE_REQUESTS) ||
|
{(hasPermission(Permission.MANAGE_REQUESTS) ||
|
||||||
hasPermission(Permission.AUTO_APPROVE) ||
|
hasPermission(
|
||||||
hasPermission(Permission.AUTO_APPROVE_TV)) &&
|
is4k ? Permission.AUTO_APPROVE_4K : Permission.AUTO_APPROVE
|
||||||
|
) ||
|
||||||
|
hasPermission(
|
||||||
|
is4k ? Permission.AUTO_APPROVE_4K_TV : Permission.AUTO_APPROVE_TV
|
||||||
|
)) &&
|
||||||
!editRequest && (
|
!editRequest && (
|
||||||
<p className="mt-6">
|
<p className="mt-6">
|
||||||
<Alert
|
<Alert
|
||||||
|
@@ -94,15 +94,21 @@
|
|||||||
"components.PermissionEdit.admin": "Admin",
|
"components.PermissionEdit.admin": "Admin",
|
||||||
"components.PermissionEdit.adminDescription": "Full administrator access. Bypasses all permission checks.",
|
"components.PermissionEdit.adminDescription": "Full administrator access. Bypasses all permission checks.",
|
||||||
"components.PermissionEdit.advancedrequest": "Advanced Requests",
|
"components.PermissionEdit.advancedrequest": "Advanced Requests",
|
||||||
"components.PermissionEdit.advancedrequestDescription": "Grants permission to use advanced request options; e.g. changing servers, profiles, or paths.",
|
"components.PermissionEdit.advancedrequestDescription": "Grants permission to use advanced request options (e.g., changing servers, profiles, or paths).",
|
||||||
"components.PermissionEdit.autoapprove": "Auto-Approve",
|
"components.PermissionEdit.autoapprove": "Auto-Approve",
|
||||||
"components.PermissionEdit.autoapproveDescription": "Grants automatic approval for all requests made by this user.",
|
"components.PermissionEdit.autoapprove4k": "Auto-Approve 4K",
|
||||||
|
"components.PermissionEdit.autoapprove4kDescription": "Grants automatic approval for all 4K requests made by this user.",
|
||||||
|
"components.PermissionEdit.autoapprove4kMovies": "Auto-Approve 4K Movies",
|
||||||
|
"components.PermissionEdit.autoapprove4kMoviesDescription": "Grants automatic approval for 4K movie requests made by this user.",
|
||||||
|
"components.PermissionEdit.autoapprove4kSeries": "Auto-Approve 4K Series",
|
||||||
|
"components.PermissionEdit.autoapprove4kSeriesDescription": "Grants automatic approval for 4K series requests made by this user.",
|
||||||
|
"components.PermissionEdit.autoapproveDescription": "Grants automatic approval for all non-4K requests made by this user.",
|
||||||
"components.PermissionEdit.autoapproveMovies": "Auto-Approve Movies",
|
"components.PermissionEdit.autoapproveMovies": "Auto-Approve Movies",
|
||||||
"components.PermissionEdit.autoapproveMoviesDescription": "Grants automatic approval for movie requests made by this user.",
|
"components.PermissionEdit.autoapproveMoviesDescription": "Grants automatic approval for non-4K movie requests made by this user.",
|
||||||
"components.PermissionEdit.autoapproveSeries": "Auto-Approve Series",
|
"components.PermissionEdit.autoapproveSeries": "Auto-Approve Series",
|
||||||
"components.PermissionEdit.autoapproveSeriesDescription": "Grants automatic approval for series requests made by this user.",
|
"components.PermissionEdit.autoapproveSeriesDescription": "Grants automatic approval for non-4K series requests made by this user.",
|
||||||
"components.PermissionEdit.managerequests": "Manage Requests",
|
"components.PermissionEdit.managerequests": "Manage Requests",
|
||||||
"components.PermissionEdit.managerequestsDescription": "Grants permission to manage Overseerr requests. This includes approving and denying requests.",
|
"components.PermissionEdit.managerequestsDescription": "Grants permission to manage Overseerr requests. This includes approving and denying requests. All requests made by a user with this permission will be automatically approved regardless of whether or not they have Auto-Approve permissions.",
|
||||||
"components.PermissionEdit.request": "Request",
|
"components.PermissionEdit.request": "Request",
|
||||||
"components.PermissionEdit.request4k": "Request 4K",
|
"components.PermissionEdit.request4k": "Request 4K",
|
||||||
"components.PermissionEdit.request4kDescription": "Grants permission to request 4K movies and series.",
|
"components.PermissionEdit.request4kDescription": "Grants permission to request 4K movies and series.",
|
||||||
@@ -114,9 +120,9 @@
|
|||||||
"components.PermissionEdit.settings": "Manage Settings",
|
"components.PermissionEdit.settings": "Manage Settings",
|
||||||
"components.PermissionEdit.settingsDescription": "Grants permission to modify all Overseerr settings. A user must have this permission to grant it to others.",
|
"components.PermissionEdit.settingsDescription": "Grants permission to modify all Overseerr settings. A user must have this permission to grant it to others.",
|
||||||
"components.PermissionEdit.users": "Manage Users",
|
"components.PermissionEdit.users": "Manage Users",
|
||||||
"components.PermissionEdit.usersDescription": "Grants permission to manage Overseerr users. Users with this permission cannot modify users with Administrator privilege, or grant it.",
|
"components.PermissionEdit.usersDescription": "Grants permission to manage Overseerr users. Users with this permission cannot modify users with or grant the Admin privilege.",
|
||||||
"components.PermissionEdit.viewrequests": "View Requests",
|
"components.PermissionEdit.viewrequests": "View Requests",
|
||||||
"components.PermissionEdit.viewrequestsDescription": "Grants permission to view other user's requests.",
|
"components.PermissionEdit.viewrequestsDescription": "Grants permission to view other users' requests.",
|
||||||
"components.PermissionEdit.vote": "Vote",
|
"components.PermissionEdit.vote": "Vote",
|
||||||
"components.PermissionEdit.voteDescription": "Grants permission to vote on requests (voting not yet implemented).",
|
"components.PermissionEdit.voteDescription": "Grants permission to vote on requests (voting not yet implemented).",
|
||||||
"components.PersonDetails.appearsin": "Appears in",
|
"components.PersonDetails.appearsin": "Appears in",
|
||||||
|
Reference in New Issue
Block a user