diff --git a/overseerr-api.yml b/overseerr-api.yml index c28079dbc..cf7224484 100644 --- a/overseerr-api.yml +++ b/overseerr-api.yml @@ -1537,7 +1537,7 @@ paths: schema: $ref: '#/components/schemas/MainSettings' /settings/main/regenerate: - get: + post: summary: Get main settings with newly-generated API key description: Returns main settings in a JSON object, using the new API key. tags: @@ -1612,21 +1612,50 @@ paths: $ref: '#/components/schemas/PlexLibrary' /settings/plex/sync: get: + summary: Get status of full Plex library sync + description: Returns sync progress in a JSON array. + tags: + - settings + responses: + '200': + description: Status of Plex sync + content: + application/json: + schema: + type: object + properties: + running: + type: boolean + example: false + progress: + type: number + example: 0 + total: + type: number + example: 100 + currentLibrary: + $ref: '#/components/schemas/PlexLibrary' + libraries: + type: array + items: + $ref: '#/components/schemas/PlexLibrary' + post: summary: Start full Plex library sync description: Runs a full Plex library sync and returns the progress in a JSON array. tags: - settings - parameters: - - in: query - name: cancel - schema: - type: boolean - example: false - - in: query - name: start - schema: - type: boolean - example: false + requestBody: + content: + application/json: + schema: + type: object + properties: + cancel: + type: boolean + example: false + start: + type: boolean + example: false responses: '200': description: Status of Plex sync @@ -1946,7 +1975,7 @@ paths: schema: $ref: '#/components/schemas/PublicSettings' /settings/initialize: - get: + post: summary: Initialize application description: Sets the app as initialized, allowing the user to navigate to pages other than the setup page. tags: @@ -1990,7 +2019,7 @@ paths: type: boolean example: false /settings/jobs/{jobId}/run: - get: + post: summary: Invoke a specific job description: Invokes a specific job to run. Will return the new job status in JSON format. tags: @@ -2025,7 +2054,7 @@ paths: type: boolean example: false /settings/jobs/{jobId}/cancel: - get: + post: summary: Cancel a specific job description: Cancels a specific job. Will return the new job status in JSON format. tags: @@ -2095,7 +2124,7 @@ paths: vsize: type: number /settings/cache/{cacheId}/flush: - get: + post: summary: Flush a specific cache description: Flushes all data from the cache ID provided tags: @@ -2511,7 +2540,7 @@ paths: - email - password /auth/logout: - get: + post: summary: Sign out and clear session cookie description: Completely clear the session cookie and associated values, effectively signing the user out. tags: @@ -3187,10 +3216,10 @@ paths: schema: $ref: '#/components/schemas/MediaRequest' /request/{requestId}/{status}: - get: - summary: Update a requests status + post: + summary: Update a request's status description: | - Updates a requests status to approved or declined. Also returns the request in a JSON object. + Updates a request's status to approved or declined. Also returns the request in a JSON object. Requires the `MANAGE_REQUESTS` permission or `ADMIN`. tags: @@ -3681,9 +3710,9 @@ paths: '204': description: Succesfully removed media item /media/{mediaId}/{status}: - get: + post: summary: Update media status - description: Updates a medias status and returns the media in JSON format + description: Updates a media item's status and returns the media in JSON format tags: - media parameters: @@ -3702,12 +3731,15 @@ paths: schema: type: string enum: [available, partial, processing, pending, unknown] - - in: query - name: is4k - description: 4K Status - example: false - schema: - type: boolean + requestBody: + content: + application/json: + schema: + type: object + properties: + is4k: + type: boolean + example: false responses: '200': description: Returned media diff --git a/server/routes/auth.ts b/server/routes/auth.ts index bb20b9ca0..efa212e49 100644 --- a/server/routes/auth.ts +++ b/server/routes/auth.ts @@ -184,7 +184,7 @@ authRoutes.post('/local', async (req, res, next) => { } }); -authRoutes.get('/logout', (req, res, next) => { +authRoutes.post('/logout', (req, res, next) => { req.session?.destroy((err) => { if (err) { return next({ diff --git a/server/routes/media.ts b/server/routes/media.ts index f6c6a505f..c77f77084 100644 --- a/server/routes/media.ts +++ b/server/routes/media.ts @@ -82,7 +82,7 @@ mediaRoutes.get('/', async (req, res, next) => { } }); -mediaRoutes.get< +mediaRoutes.post< { id: string; status: 'available' | 'partial' | 'processing' | 'pending' | 'unknown'; @@ -102,7 +102,7 @@ mediaRoutes.get< return next({ status: 404, message: 'Media does not exist.' }); } - const is4k = Boolean(req.query.is4k); + const is4k = Boolean(req.body.is4k); switch (req.params.status) { case 'available': diff --git a/server/routes/request.ts b/server/routes/request.ts index 7a23ebff9..a97bac0a3 100644 --- a/server/routes/request.ts +++ b/server/routes/request.ts @@ -489,7 +489,7 @@ requestRoutes.post<{ } ); -requestRoutes.get<{ +requestRoutes.post<{ requestId: string; status: 'pending' | 'approve' | 'decline'; }>( diff --git a/server/routes/settings/index.ts b/server/routes/settings/index.ts index 61dabe217..0099d28cb 100644 --- a/server/routes/settings/index.ts +++ b/server/routes/settings/index.ts @@ -54,7 +54,7 @@ settingsRoutes.post('/main', (req, res) => { return res.status(200).json(settings.main); }); -settingsRoutes.get('/main/regenerate', (req, res, next) => { +settingsRoutes.post('/main/regenerate', (req, res, next) => { const settings = getSettings(); const main = settings.regenerateApiKey(); @@ -210,10 +210,14 @@ settingsRoutes.get('/plex/library', async (req, res) => { return res.status(200).json(settings.plex.libraries); }); -settingsRoutes.get('/plex/sync', (req, res) => { - if (req.query.cancel) { +settingsRoutes.get('/plex/sync', (_req, res) => { + return res.status(200).json(jobPlexFullSync.status()); +}); + +settingsRoutes.post('/plex/sync', (req, res) => { + if (req.body.cancel) { jobPlexFullSync.cancel(); - } else if (req.query.start) { + } else if (req.body.start) { jobPlexFullSync.run(); } return res.status(200).json(jobPlexFullSync.status()); @@ -231,7 +235,7 @@ settingsRoutes.get('/jobs', (_req, res) => { ); }); -settingsRoutes.get<{ jobId: string }>('/jobs/:jobId/run', (req, res, next) => { +settingsRoutes.post<{ jobId: string }>('/jobs/:jobId/run', (req, res, next) => { const scheduledJob = scheduledJobs.find((job) => job.id === req.params.jobId); if (!scheduledJob) { @@ -249,7 +253,7 @@ settingsRoutes.get<{ jobId: string }>('/jobs/:jobId/run', (req, res, next) => { }); }); -settingsRoutes.get<{ jobId: string }>( +settingsRoutes.post<{ jobId: string }>( '/jobs/:jobId/cancel', (req, res, next) => { const scheduledJob = scheduledJobs.find( @@ -286,7 +290,7 @@ settingsRoutes.get('/cache', (req, res) => { ); }); -settingsRoutes.get<{ cacheId: AvailableCacheIds }>( +settingsRoutes.post<{ cacheId: AvailableCacheIds }>( '/cache/:cacheId/flush', (req, res, next) => { const cache = cacheManager.getCache(req.params.cacheId); @@ -300,7 +304,7 @@ settingsRoutes.get<{ cacheId: AvailableCacheIds }>( } ); -settingsRoutes.get( +settingsRoutes.post( '/initialize', isAuthenticated(Permission.ADMIN), (_req, res) => { diff --git a/src/components/Layout/UserDropdown/index.tsx b/src/components/Layout/UserDropdown/index.tsx index 16a40a5af..302574a78 100644 --- a/src/components/Layout/UserDropdown/index.tsx +++ b/src/components/Layout/UserDropdown/index.tsx @@ -16,7 +16,7 @@ const UserDropdown: React.FC = () => { useClickOutside(dropdownRef, () => setDropdownOpen(false)); const logout = async () => { - const response = await axios.get('/api/v1/auth/logout'); + const response = await axios.post('/api/v1/auth/logout'); if (response.data?.status === 'ok') { revalidate(); @@ -24,16 +24,16 @@ const UserDropdown: React.FC = () => { }; return ( -
+
{ leaveTo="transform opacity-0 scale-95" >
logout()} > diff --git a/src/components/MovieDetails/index.tsx b/src/components/MovieDetails/index.tsx index f23130a14..4804d238d 100644 --- a/src/components/MovieDetails/index.tsx +++ b/src/components/MovieDetails/index.tsx @@ -123,10 +123,8 @@ const MovieDetails: React.FC = ({ movie }) => { }; const markAvailable = async (is4k = false) => { - await axios.get(`/api/v1/media/${data?.mediaInfo?.id}/available`, { - params: { - is4k, - }, + await axios.post(`/api/v1/media/${data?.mediaInfo?.id}/available`, { + is4k, }); revalidate(); }; diff --git a/src/components/RequestBlock/index.tsx b/src/components/RequestBlock/index.tsx index aa925aef2..28966d2f5 100644 --- a/src/components/RequestBlock/index.tsx +++ b/src/components/RequestBlock/index.tsx @@ -30,7 +30,7 @@ const RequestBlock: React.FC = ({ request, onUpdate }) => { const updateRequest = async (type: 'approve' | 'decline'): Promise => { setIsUpdating(true); - await axios.get(`/api/v1/request/${request.id}/${type}`); + await axios.post(`/api/v1/request/${request.id}/${type}`); if (onUpdate) { onUpdate(); diff --git a/src/components/RequestButton/index.tsx b/src/components/RequestButton/index.tsx index 0f3ad6da1..ce3868785 100644 --- a/src/components/RequestButton/index.tsx +++ b/src/components/RequestButton/index.tsx @@ -83,7 +83,7 @@ const RequestButton: React.FC = ({ request: MediaRequest, type: 'approve' | 'decline' ) => { - const response = await axios.get(`/api/v1/request/${request.id}/${type}`); + const response = await axios.post(`/api/v1/request/${request.id}/${type}`); if (response) { onUpdate(); @@ -100,7 +100,7 @@ const RequestButton: React.FC = ({ await Promise.all( requests.map(async (request) => { - return axios.get(`/api/v1/request/${request.id}/${type}`); + return axios.post(`/api/v1/request/${request.id}/${type}`); }) ); diff --git a/src/components/RequestCard/index.tsx b/src/components/RequestCard/index.tsx index 858e8e465..5697cfdda 100644 --- a/src/components/RequestCard/index.tsx +++ b/src/components/RequestCard/index.tsx @@ -62,7 +62,7 @@ const RequestCard: React.FC = ({ request }) => { }); const modifyRequest = async (type: 'approve' | 'decline') => { - const response = await axios.get(`/api/v1/request/${request.id}/${type}`); + const response = await axios.post(`/api/v1/request/${request.id}/${type}`); if (response) { revalidate(); diff --git a/src/components/RequestList/RequestItem/index.tsx b/src/components/RequestList/RequestItem/index.tsx index d7e3cae37..32d2c33c0 100644 --- a/src/components/RequestList/RequestItem/index.tsx +++ b/src/components/RequestList/RequestItem/index.tsx @@ -70,7 +70,7 @@ const RequestItem: React.FC = ({ const [isRetrying, setRetrying] = useState(false); const modifyRequest = async (type: 'approve' | 'decline') => { - const response = await axios.get(`/api/v1/request/${request.id}/${type}`); + const response = await axios.post(`/api/v1/request/${request.id}/${type}`); if (response) { revalidate(); diff --git a/src/components/Settings/SettingsJobsCache/index.tsx b/src/components/Settings/SettingsJobsCache/index.tsx index 0a3c87d92..3ba68520f 100644 --- a/src/components/Settings/SettingsJobsCache/index.tsx +++ b/src/components/Settings/SettingsJobsCache/index.tsx @@ -63,7 +63,7 @@ const SettingsJobs: React.FC = () => { } const runJob = async (job: Job) => { - await axios.get(`/api/v1/settings/jobs/${job.id}/run`); + await axios.post(`/api/v1/settings/jobs/${job.id}/run`); addToast( intl.formatMessage(messages.jobstarted, { jobname: job.name, @@ -77,7 +77,7 @@ const SettingsJobs: React.FC = () => { }; const cancelJob = async (job: Job) => { - await axios.get(`/api/v1/settings/jobs/${job.id}/cancel`); + await axios.post(`/api/v1/settings/jobs/${job.id}/cancel`); addToast(intl.formatMessage(messages.jobcancelled, { jobname: job.name }), { appearance: 'error', autoDismiss: true, @@ -86,7 +86,7 @@ const SettingsJobs: React.FC = () => { }; const flushCache = async (cache: CacheItem) => { - await axios.get(`/api/v1/settings/cache/${cache.id}/flush`); + await axios.post(`/api/v1/settings/cache/${cache.id}/flush`); addToast( intl.formatMessage(messages.cacheflushed, { cachename: cache.name }), { diff --git a/src/components/Settings/SettingsMain.tsx b/src/components/Settings/SettingsMain.tsx index 50dfa1534..9fa92d07f 100644 --- a/src/components/Settings/SettingsMain.tsx +++ b/src/components/Settings/SettingsMain.tsx @@ -70,7 +70,7 @@ const SettingsMain: React.FC = () => { const regenerate = async () => { try { - await axios.get('/api/v1/settings/main/regenerate'); + await axios.post('/api/v1/settings/main/regenerate'); revalidate(); addToast(intl.formatMessage(messages.toastApiKeySuccess), { diff --git a/src/components/Settings/SettingsPlex.tsx b/src/components/Settings/SettingsPlex.tsx index db1c80f7d..e22a89245 100644 --- a/src/components/Settings/SettingsPlex.tsx +++ b/src/components/Settings/SettingsPlex.tsx @@ -212,19 +212,15 @@ const SettingsPlex: React.FC = ({ onComplete }) => { }; const startScan = async () => { - await axios.get('/api/v1/settings/plex/sync', { - params: { - start: true, - }, + await axios.post('/api/v1/settings/plex/sync', { + start: true, }); revalidateSync(); }; const cancelScan = async () => { - await axios.get('/api/v1/settings/plex/sync', { - params: { - cancel: true, - }, + await axios.post('/api/v1/settings/plex/sync', { + cancel: true, }); revalidateSync(); }; diff --git a/src/components/Setup/index.tsx b/src/components/Setup/index.tsx index b6d3de18a..e0a21e5f6 100644 --- a/src/components/Setup/index.tsx +++ b/src/components/Setup/index.tsx @@ -35,7 +35,7 @@ const Setup: React.FC = () => { const finishSetup = async () => { setIsUpdating(false); - const response = await axios.get<{ initialized: boolean }>( + const response = await axios.post<{ initialized: boolean }>( '/api/v1/settings/initialize' ); diff --git a/src/components/TvDetails/index.tsx b/src/components/TvDetails/index.tsx index 389c9b2b5..f19ca4983 100644 --- a/src/components/TvDetails/index.tsx +++ b/src/components/TvDetails/index.tsx @@ -127,10 +127,8 @@ const TvDetails: React.FC = ({ tv }) => { }; const markAvailable = async (is4k = false) => { - await axios.get(`/api/v1/media/${data?.mediaInfo?.id}/available`, { - params: { - is4k, - }, + await axios.post(`/api/v1/media/${data?.mediaInfo?.id}/available`, { + is4k, }); revalidate(); };