(
`/api/v1/settings/${
radarrServices.includes(service as RadarrSettings)
? 'radarr'
: 'sonarr'
}/test`,
{
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({
- hostname,
- apiKey,
- port: Number(port),
- baseUrl,
- useSsl,
- }),
+ hostname,
+ apiKey,
+ port: Number(port),
+ baseUrl,
+ useSsl,
}
);
- if (!res.ok) throw new Error();
- const data: DVRTestResponse = await res.json();
results.push({
type: radarrServices.includes(service as RadarrSettings)
? 'radarr'
: 'sonarr',
id: service.id,
- ...data,
+ ...response.data,
});
} catch {
results.push({
@@ -120,9 +113,8 @@ const OverrideRuleTiles = ({
.flat()
.filter((keywordId) => keywordId)
.map(async (keywordId) => {
- const res = await fetch(`/api/v1/keyword/${keywordId}`);
- if (!res.ok) throw new Error();
- const keyword: Keyword = await res.json();
+ const response = await axios.get(`/api/v1/keyword/${keywordId}`);
+ const keyword: Keyword = response.data;
return keyword;
})
);
@@ -132,11 +124,10 @@ const OverrideRuleTiles = ({
.filter((users) => users)
.join(',');
if (allUsersFromRules) {
- const res = await fetch(
+ const response = await axios.get(
`/api/v1/user?includeIds=${encodeURIComponent(allUsersFromRules)}`
);
- if (!res.ok) throw new Error();
- const users: User[] = (await res.json()).results;
+ const users: User[] = response.data.results;
setUsers(users);
}
setUsers(users);
@@ -295,10 +286,7 @@ const OverrideRuleTiles = ({
>
)}
-
- {intl.formatMessage(messages.advancedNetworkSettings)}
-
-
- {intl.formatMessage(messages.networkDisclaimer, {
- docs: (
-
- {intl.formatMessage(messages.docs)}
-
- ),
- })}
-
-
-
-
- {
- setFieldValue('forceIpv4First', !values.forceIpv4First);
- }}
- />
-
-
diff --git a/src/components/Settings/SettingsPlex.tsx b/src/components/Settings/SettingsPlex.tsx
index 5e2d5d4c0..973c5ede4 100644
--- a/src/components/Settings/SettingsPlex.tsx
+++ b/src/components/Settings/SettingsPlex.tsx
@@ -16,6 +16,7 @@ import {
} from '@heroicons/react/24/solid';
import type { PlexDevice } from '@server/interfaces/api/plexInterfaces';
import type { PlexSettings, TautulliSettings } from '@server/lib/settings';
+import axios from 'axios';
import { Field, Formik } from 'formik';
import { orderBy } from 'lodash';
import { useMemo, useState } from 'react';
@@ -243,15 +244,9 @@ const SettingsPlex = ({ onComplete }: SettingsPlexProps) => {
params.enable = activeLibraries.join(',');
}
- const searchParams = new URLSearchParams({
- sync: params.sync ? 'true' : 'false',
- ...(params.enable ? { enable: params.enable } : {}),
+ await axios.get('/api/v1/settings/plex/library', {
+ params,
});
- const res = await fetch(
- `/api/v1/settings/plex/library?${searchParams.toString()}`
- );
- if (!res.ok) throw new Error();
-
setIsSyncing(false);
revalidate();
};
@@ -270,12 +265,11 @@ const SettingsPlex = ({ onComplete }: SettingsPlexProps) => {
toastId = id;
}
);
- const res = await fetch('/api/v1/settings/plex/devices/servers');
- if (!res.ok) throw new Error();
- const data: PlexDevice[] = await res.json();
-
- if (data) {
- setAvailableServers(data);
+ const response = await axios.get(
+ '/api/v1/settings/plex/devices/servers'
+ );
+ if (response.data) {
+ setAvailableServers(response.data);
}
if (toastId) {
removeToast(toastId);
@@ -298,30 +292,16 @@ const SettingsPlex = ({ onComplete }: SettingsPlexProps) => {
};
const startScan = async () => {
- const res = await fetch('/api/v1/settings/plex/sync', {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({
- start: true,
- }),
+ await axios.post('/api/v1/settings/plex/sync', {
+ start: true,
});
- if (!res.ok) throw new Error();
revalidateSync();
};
const cancelScan = async () => {
- const res = await fetch('/api/v1/settings/plex/sync', {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({
- cancel: true,
- }),
+ await axios.post('/api/v1/settings/plex/sync', {
+ cancel: true,
});
- if (!res.ok) throw new Error();
revalidateSync();
};
@@ -336,19 +316,15 @@ const SettingsPlex = ({ onComplete }: SettingsPlexProps) => {
.join(',');
}
- const searchParams = new URLSearchParams(params.enable ? params : {});
- const res = await fetch(
- `/api/v1/settings/plex/library?${searchParams.toString()}`
- );
- if (!res.ok) throw new Error();
- } else {
- const searchParams = new URLSearchParams({
- enable: [...activeLibraries, libraryId].join(','),
+ await axios.get('/api/v1/settings/plex/library', {
+ params,
+ });
+ } else {
+ await axios.get('/api/v1/settings/plex/library', {
+ params: {
+ enable: [...activeLibraries, libraryId].join(','),
+ },
});
- const res = await fetch(
- `/api/v1/settings/plex/library?${searchParams.toString()}`
- );
- if (!res.ok) throw new Error();
}
if (onComplete) {
@@ -416,19 +392,12 @@ const SettingsPlex = ({ onComplete }: SettingsPlexProps) => {
toastId = id;
}
);
- const res = await fetch('/api/v1/settings/plex', {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({
- ip: values.hostname,
- port: Number(values.port),
- useSsl: values.useSsl,
- webAppUrl: values.webAppUrl,
- } as PlexSettings),
- });
- if (!res.ok) throw new Error();
+ await axios.post('/api/v1/settings/plex', {
+ ip: values.hostname,
+ port: Number(values.port),
+ useSsl: values.useSsl,
+ webAppUrl: values.webAppUrl,
+ } as PlexSettings);
syncLibraries();
@@ -782,27 +751,14 @@ const SettingsPlex = ({ onComplete }: SettingsPlexProps) => {
validationSchema={TautulliSettingsSchema}
onSubmit={async (values) => {
try {
- const res = await fetch('/api/v1/settings/tautulli', {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({
- hostname: values.tautulliHostname,
- port: Number(values.tautulliPort),
- useSsl: values.tautulliUseSsl,
- urlBase: values.tautulliUrlBase,
- apiKey: values.tautulliApiKey,
- externalUrl: values.tautulliExternalUrl,
- } as TautulliSettings),
- });
- if (!res.ok) throw new Error();
-
- if (!res.ok) {
- throw new Error('Failed to fetch');
- }
-
- // Continue with any necessary processing
+ await axios.post('/api/v1/settings/tautulli', {
+ hostname: values.tautulliHostname,
+ port: Number(values.tautulliPort),
+ useSsl: values.tautulliUseSsl,
+ urlBase: values.tautulliUrlBase,
+ apiKey: values.tautulliApiKey,
+ externalUrl: values.tautulliExternalUrl,
+ } as TautulliSettings);
addToast(
intl.formatMessage(messages.toastTautulliSettingsSuccess),
diff --git a/src/components/Settings/SettingsServices.tsx b/src/components/Settings/SettingsServices.tsx
index fbe6c75d0..be39f744d 100644
--- a/src/components/Settings/SettingsServices.tsx
+++ b/src/components/Settings/SettingsServices.tsx
@@ -17,6 +17,7 @@ import { PencilIcon, PlusIcon, TrashIcon } from '@heroicons/react/24/solid';
import type OverrideRule from '@server/entity/OverrideRule';
import type { OverrideRuleResultsResponse } from '@server/interfaces/api/overrideRuleInterfaces';
import type { RadarrSettings, SonarrSettings } from '@server/lib/settings';
+import axios from 'axios';
import { Fragment, useState } from 'react';
import { useIntl } from 'react-intl';
import useSWR, { mutate } from 'swr';
@@ -248,14 +249,9 @@ const SettingsServices = () => {
});
const deleteServer = async () => {
- const res = await fetch(
- `/api/v1/settings/${deleteServerModal.type}/${deleteServerModal.serverId}`,
- {
- method: 'DELETE',
- }
+ await axios.delete(
+ `/api/v1/settings/${deleteServerModal.type}/${deleteServerModal.serverId}`
);
- if (!res.ok) throw new Error();
-
setDeleteServerModal({ open: false, serverId: null, type: 'radarr' });
revalidateRadarr();
revalidateSonarr();
diff --git a/src/components/Settings/SettingsUsers/index.tsx b/src/components/Settings/SettingsUsers/index.tsx
index 8203360bd..7dad9f940 100644
--- a/src/components/Settings/SettingsUsers/index.tsx
+++ b/src/components/Settings/SettingsUsers/index.tsx
@@ -10,6 +10,7 @@ import defineMessages from '@app/utils/defineMessages';
import { ArrowDownOnSquareIcon } from '@heroicons/react/24/outline';
import { MediaServerType } from '@server/constants/server';
import type { MainSettings } from '@server/lib/settings';
+import axios from 'axios';
import { Field, Form, Formik } from 'formik';
import { useIntl } from 'react-intl';
import { useToasts } from 'react-toast-notifications';
@@ -116,29 +117,22 @@ const SettingsUsers = () => {
enableReinitialize
onSubmit={async (values) => {
try {
- const res = await fetch('/api/v1/settings/main', {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({
- localLogin: values.localLogin,
- mediaServerLogin: values.mediaServerLogin,
- newPlexLogin: values.newPlexLogin,
- defaultQuotas: {
- movie: {
- quotaLimit: values.movieQuotaLimit,
- quotaDays: values.movieQuotaDays,
- },
- tv: {
- quotaLimit: values.tvQuotaLimit,
- quotaDays: values.tvQuotaDays,
- },
+ await axios.post('/api/v1/settings/main', {
+ localLogin: values.localLogin,
+ mediaServerLogin: values.mediaServerLogin,
+ newPlexLogin: values.newPlexLogin,
+ defaultQuotas: {
+ movie: {
+ quotaLimit: values.movieQuotaLimit,
+ quotaDays: values.movieQuotaDays,
},
- defaultPermissions: values.defaultPermissions,
- }),
+ tv: {
+ quotaLimit: values.tvQuotaLimit,
+ quotaDays: values.tvQuotaDays,
+ },
+ },
+ defaultPermissions: values.defaultPermissions,
});
- if (!res.ok) throw new Error();
mutate('/api/v1/settings/public');
addToast(intl.formatMessage(messages.toastSettingsSuccess), {
diff --git a/src/components/Settings/SonarrModal/index.tsx b/src/components/Settings/SonarrModal/index.tsx
index 11954734c..9fb28d9d1 100644
--- a/src/components/Settings/SonarrModal/index.tsx
+++ b/src/components/Settings/SonarrModal/index.tsx
@@ -5,6 +5,7 @@ import globalMessages from '@app/i18n/globalMessages';
import defineMessages from '@app/utils/defineMessages';
import { Transition } from '@headlessui/react';
import type { SonarrSettings } from '@server/lib/settings';
+import axios from 'axios';
import { Field, Formik } from 'formik';
import { useCallback, useEffect, useRef, useState } from 'react';
import { useIntl } from 'react-intl';
@@ -163,24 +164,19 @@ const SonarrModal = ({ onClose, sonarr, onSave }: SonarrModalProps) => {
}) => {
setIsTesting(true);
try {
- const res = await fetch('/api/v1/settings/sonarr/test', {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({
+ const response = await axios.post(
+ '/api/v1/settings/sonarr/test',
+ {
hostname,
apiKey,
port: Number(port),
baseUrl,
useSsl,
- }),
- });
- if (!res.ok) throw new Error();
- const data: SonarrTestResponse = await res.json();
+ }
+ );
setIsValidated(true);
- setTestResponse(data);
+ setTestResponse(response.data);
if (initialLoad.current) {
addToast(intl.formatMessage(messages.toastSonarrTestSuccess), {
appearance: 'success',
@@ -297,23 +293,12 @@ const SonarrModal = ({ onClose, sonarr, onSave }: SonarrModalProps) => {
tagRequests: values.tagRequests,
};
if (!sonarr) {
- const res = await fetch('/api/v1/settings/sonarr', {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify(submission),
- });
- if (!res.ok) throw new Error();
+ await axios.post('/api/v1/settings/sonarr', submission);
} else {
- const res = await fetch(`/api/v1/settings/sonarr/${sonarr.id}`, {
- method: 'PUT',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify(submission),
- });
- if (!res.ok) throw new Error();
+ await axios.put(
+ `/api/v1/settings/sonarr/${sonarr.id}`,
+ submission
+ );
}
onSave();
diff --git a/src/components/Setup/JellyfinSetup.tsx b/src/components/Setup/JellyfinSetup.tsx
index 70be6eda8..a8fbc22dd 100644
--- a/src/components/Setup/JellyfinSetup.tsx
+++ b/src/components/Setup/JellyfinSetup.tsx
@@ -4,6 +4,7 @@ import defineMessages from '@app/utils/defineMessages';
import { InformationCircleIcon } from '@heroicons/react/24/solid';
import { ApiErrorCode } from '@server/constants/error';
import { MediaServerType, ServerType } from '@server/constants/server';
+import axios from 'axios';
import { Field, Form, Formik } from 'formik';
import { FormattedMessage, useIntl } from 'react-intl';
import { useToasts } from 'react-toast-notifications';
@@ -112,38 +113,19 @@ function JellyfinSetup({
validationSchema={LoginSchema}
onSubmit={async (values) => {
try {
- // Check if serverType is either 'Jellyfin' or 'Emby'
- // if (serverType !== 'Jellyfin' && serverType !== 'Emby') {
- // throw new Error('Invalid serverType'); // You can customize the error message
- // }
-
- const res = await fetch('/api/v1/auth/jellyfin', {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({
- username: values.username,
- password: values.password,
- hostname: values.hostname,
- port: values.port,
- useSsl: values.useSsl,
- urlBase: values.urlBase,
- email: values.email,
- serverType: serverType,
- }),
+ await axios.post('/api/v1/auth/jellyfin', {
+ username: values.username,
+ password: values.password,
+ hostname: values.hostname,
+ port: values.port,
+ useSsl: values.useSsl,
+ urlBase: values.urlBase,
+ email: values.email,
+ serverType: serverType,
});
- if (!res.ok) throw new Error(res.statusText, { cause: res });
} catch (e) {
- let errorData;
- try {
- errorData = await e.cause?.text();
- errorData = JSON.parse(errorData);
- } catch {
- /* empty */
- }
let errorMessage = null;
- switch (errorData?.message) {
+ switch (e?.response?.data?.message) {
case ApiErrorCode.InvalidUrl:
errorMessage = messages.invalidurlerror;
break;
diff --git a/src/components/Setup/LoginWithPlex.tsx b/src/components/Setup/LoginWithPlex.tsx
index c69212ee8..469788f14 100644
--- a/src/components/Setup/LoginWithPlex.tsx
+++ b/src/components/Setup/LoginWithPlex.tsx
@@ -1,6 +1,7 @@
import PlexLoginButton from '@app/components/Login/PlexLoginButton';
import { useUser } from '@app/hooks/useUser';
import defineMessages from '@app/utils/defineMessages';
+import axios from 'axios';
import { useEffect, useState } from 'react';
import { useIntl } from 'react-intl';
@@ -24,19 +25,9 @@ const LoginWithPlex = ({ onComplete }: LoginWithPlexProps) => {
useEffect(() => {
const login = async () => {
- const res = await fetch('/api/v1/auth/plex', {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({
- authToken,
- }),
- });
- if (!res.ok) throw new Error();
- const data = await res.json();
+ const response = await axios.post('/api/v1/auth/plex', { authToken });
- if (data?.id) {
+ if (response.data?.id) {
revalidate();
}
};
diff --git a/src/components/Setup/SetupLogin.tsx b/src/components/Setup/SetupLogin.tsx
index 16a18770c..768218081 100644
--- a/src/components/Setup/SetupLogin.tsx
+++ b/src/components/Setup/SetupLogin.tsx
@@ -4,6 +4,7 @@ import JellyfinSetup from '@app/components/Setup/JellyfinSetup';
import { useUser } from '@app/hooks/useUser';
import defineMessages from '@app/utils/defineMessages';
import { MediaServerType } from '@server/constants/server';
+import axios from 'axios';
import { useEffect, useState } from 'react';
import { FormattedMessage } from 'react-intl';
@@ -40,19 +41,11 @@ const SetupLogin: React.FC = ({
useEffect(() => {
const login = async () => {
- const res = await fetch('/api/v1/auth/plex', {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({
- authToken: authToken,
- }),
+ const response = await axios.post('/api/v1/auth/plex', {
+ authToken: authToken,
});
- if (!res.ok) throw new Error();
- const data = await res.json();
- if (data?.email) {
+ if (response.data?.email) {
revalidate();
}
};
diff --git a/src/components/Setup/index.tsx b/src/components/Setup/index.tsx
index 8a3d9e664..4d6ea4cef 100644
--- a/src/components/Setup/index.tsx
+++ b/src/components/Setup/index.tsx
@@ -15,6 +15,7 @@ import useSettings from '@app/hooks/useSettings';
import defineMessages from '@app/utils/defineMessages';
import { MediaServerType } from '@server/constants/server';
import type { Library } from '@server/lib/settings';
+import axios from 'axios';
import Image from 'next/image';
import { useRouter } from 'next/router';
import { useCallback, useEffect, useState } from 'react';
@@ -57,27 +58,15 @@ const Setup = () => {
const finishSetup = async () => {
setIsUpdating(true);
- const res = await fetch('/api/v1/settings/initialize', {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- });
- if (!res.ok) throw new Error();
- const data: { initialized: boolean } = await res.json();
+ const response = await axios.post<{ initialized: boolean }>(
+ '/api/v1/settings/initialize'
+ );
setIsUpdating(false);
- if (data.initialized) {
- const mainRes = await fetch('/api/v1/settings/main', {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({ locale }),
- });
- if (!mainRes.ok) throw new Error();
-
+ if (response.data.initialized) {
+ await axios.post('/api/v1/settings/main', { locale });
mutate('/api/v1/settings/public');
+
router.push('/');
}
};
@@ -94,11 +83,9 @@ const Setup = () => {
const endpoint = endpointMap[mediaServerType];
if (!endpoint) return;
- const res = await fetch(endpoint);
- if (!res.ok) throw new Error('Fetch failed');
- const data = await res.json();
+ const response = await axios.get(endpoint);
- const hasEnabledLibraries = data?.libraries?.some(
+ const hasEnabledLibraries = response.data?.libraries?.some(
(library: Library) => library.enabled
);
diff --git a/src/components/TitleCard/ErrorCard.tsx b/src/components/TitleCard/ErrorCard.tsx
index 3333e5bb3..6c386b8c7 100644
--- a/src/components/TitleCard/ErrorCard.tsx
+++ b/src/components/TitleCard/ErrorCard.tsx
@@ -2,6 +2,7 @@ import Button from '@app/components/Common/Button';
import globalMessages from '@app/i18n/globalMessages';
import defineMessages from '@app/utils/defineMessages';
import { CheckIcon, TrashIcon } from '@heroicons/react/24/solid';
+import axios from 'axios';
import { useIntl } from 'react-intl';
import { mutate } from 'swr';
@@ -24,10 +25,7 @@ const ErrorCard = ({ id, tmdbId, tvdbId, type, canExpand }: ErrorCardProps) => {
const intl = useIntl();
const deleteMedia = async () => {
- const res = await fetch(`/api/v1/media/${id}`, {
- method: 'DELETE',
- });
- if (!res.ok) throw new Error();
+ await axios.delete(`/api/v1/media/${id}`);
mutate('/api/v1/media?filter=allavailable&take=20&sort=mediaAdded');
mutate('/api/v1/request?filter=all&take=10&sort=modified&skip=0');
};
diff --git a/src/components/TitleCard/index.tsx b/src/components/TitleCard/index.tsx
index 037afbc85..865e82395 100644
--- a/src/components/TitleCard/index.tsx
+++ b/src/components/TitleCard/index.tsx
@@ -23,6 +23,7 @@ import {
import { MediaStatus } from '@server/constants/media';
import type { Watchlist } from '@server/entity/Watchlist';
import type { MediaType } from '@server/models/Search';
+import axios from 'axios';
import Link from 'next/link';
import { Fragment, useCallback, useEffect, useRef, useState } from 'react';
import { useIntl } from 'react-intl';
@@ -108,21 +109,13 @@ const TitleCard = ({
const onClickWatchlistBtn = async (): Promise => {
setIsUpdating(true);
try {
- const res = await fetch('/api/v1/watchlist', {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({
- tmdbId: id,
- mediaType,
- title,
- }),
+ const response = await axios.post('/api/v1/watchlist', {
+ tmdbId: id,
+ mediaType,
+ title,
});
- if (!res.ok) throw new Error();
- const data: Watchlist = await res.json();
mutate('/api/v1/discover/watchlist');
- if (data) {
+ if (response.data) {
addToast(
{intl.formatMessage(messages.watchlistSuccess, {
@@ -147,11 +140,9 @@ const TitleCard = ({
const onClickDeleteWatchlistBtn = async (): Promise => {
setIsUpdating(true);
try {
- const res = await fetch('/api/v1/watchlist/' + id, {
- method: 'DELETE',
- });
- if (!res.ok) throw new Error();
- if (res.status === 204) {
+ const response = await axios.delete('/api/v1/watchlist/' + id);
+
+ if (response.status === 204) {
addToast(
{intl.formatMessage(messages.watchlistDeleted, {
@@ -182,21 +173,13 @@ const TitleCard = ({
const topNode = cardRef.current;
if (topNode) {
- const res = await fetch('/api/v1/blacklist', {
- method: 'POST',
- headers: {
- Accept: 'application/json',
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({
+ try {
+ await axios.post('/api/v1/blacklist', {
tmdbId: id,
mediaType,
title,
user: user?.id,
- }),
- });
-
- if (res.status === 201) {
+ });
addToast(
{intl.formatMessage(globalMessages.blacklistSuccess, {
@@ -207,21 +190,23 @@ const TitleCard = ({
{ appearance: 'success', autoDismiss: true }
);
setCurrentStatus(MediaStatus.BLACKLISTED);
- } else if (res.status === 412) {
- addToast(
-
- {intl.formatMessage(globalMessages.blacklistDuplicateError, {
- title,
- strong: (msg: React.ReactNode) => {msg},
- })}
- ,
- { appearance: 'info', autoDismiss: true }
- );
- } else {
- addToast(intl.formatMessage(globalMessages.blacklistError), {
- appearance: 'error',
- autoDismiss: true,
- });
+ } catch (e) {
+ if (e?.response?.status === 412) {
+ addToast(
+
+ {intl.formatMessage(globalMessages.blacklistDuplicateError, {
+ title,
+ strong: (msg: React.ReactNode) => {msg},
+ })}
+ ,
+ { appearance: 'info', autoDismiss: true }
+ );
+ } else {
+ addToast(intl.formatMessage(globalMessages.blacklistError), {
+ appearance: 'error',
+ autoDismiss: true,
+ });
+ }
}
setIsUpdating(false);
@@ -239,9 +224,7 @@ const TitleCard = ({
const topNode = cardRef.current;
if (topNode) {
- const res = await fetch('/api/v1/blacklist/' + id, {
- method: 'DELETE',
- });
+ const res = await axios.delete('/api/v1/blacklist/' + id);
if (res.status === 204) {
addToast(
diff --git a/src/components/TvDetails/index.tsx b/src/components/TvDetails/index.tsx
index e90fa9f51..2b49f1aef 100644
--- a/src/components/TvDetails/index.tsx
+++ b/src/components/TvDetails/index.tsx
@@ -57,6 +57,7 @@ import {
import { MediaServerType } from '@server/constants/server';
import type { Crew } from '@server/models/common';
import type { TvDetails as TvDetailsType } from '@server/models/Tv';
+import axios from 'axios';
import { countries } from 'country-flag-icons';
import 'country-flag-icons/3x2/flags.css';
import Link from 'next/link';
@@ -349,32 +350,12 @@ const TvDetails = ({ tv }: TvDetailsProps) => {
const onClickWatchlistBtn = async (): Promise => {
setIsUpdating(true);
- const res = await fetch('/api/v1/watchlist', {
- method: 'POST',
- headers: {
- Accept: 'application/json',
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({
+ try {
+ await axios.post('/api/v1/watchlist', {
tmdbId: tv?.id,
mediaType: MediaType.TV,
title: tv?.name,
- }),
- });
-
- if (!res.ok) {
- addToast(intl.formatMessage(messages.watchlistError), {
- appearance: 'error',
- autoDismiss: true,
});
-
- setIsUpdating(false);
- return;
- }
-
- const data = await res.json();
-
- if (data) {
addToast(
{intl.formatMessage(messages.watchlistSuccess, {
@@ -384,30 +365,25 @@ const TvDetails = ({ tv }: TvDetailsProps) => {
,
{ appearance: 'success', autoDismiss: true }
);
- }
- setIsUpdating(false);
- setToggleWatchlist((prevState) => !prevState);
- };
-
- const onClickDeleteWatchlistBtn = async (): Promise => {
- setIsUpdating(true);
-
- const res = await fetch('/api/v1/watchlist/' + tv?.id, {
- method: 'DELETE',
- });
-
- if (!res.ok) {
+ setIsUpdating(false);
+ setToggleWatchlist((prevState) => !prevState);
+ } catch {
addToast(intl.formatMessage(messages.watchlistError), {
appearance: 'error',
autoDismiss: true,
});
setIsUpdating(false);
- return;
}
+ };
+
+ const onClickDeleteWatchlistBtn = async (): Promise => {
+ setIsUpdating(true);
+
+ try {
+ await axios.delete('/api/v1/watchlist/' + tv?.id);
- if (res.status === 204) {
addToast(
{intl.formatMessage(messages.watchlistDeleted, {
@@ -417,55 +393,60 @@ const TvDetails = ({ tv }: TvDetailsProps) => {
,
{ appearance: 'info', autoDismiss: true }
);
+
setIsUpdating(false);
setToggleWatchlist((prevState) => !prevState);
+ } catch {
+ addToast(intl.formatMessage(messages.watchlistError), {
+ appearance: 'error',
+ autoDismiss: true,
+ });
+
+ setIsUpdating(false);
}
};
const onClickHideItemBtn = async (): Promise => {
setIsBlacklistUpdating(true);
- const res = await fetch('/api/v1/blacklist', {
- method: 'POST',
- headers: {
- Accept: 'application/json',
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({
+ try {
+ const res = await axios.post('/api/v1/blacklist', {
tmdbId: tv?.id,
mediaType: 'tv',
title: tv?.name,
user: user?.id,
- }),
- });
-
- if (res.status === 201) {
- addToast(
-
- {intl.formatMessage(globalMessages.blacklistSuccess, {
- title: tv?.name,
- strong: (msg: React.ReactNode) => {msg},
- })}
- ,
- { appearance: 'success', autoDismiss: true }
- );
-
- revalidate();
- } else if (res.status === 412) {
- addToast(
-
- {intl.formatMessage(globalMessages.blacklistDuplicateError, {
- title: tv?.name,
- strong: (msg: React.ReactNode) => {msg},
- })}
- ,
- { appearance: 'info', autoDismiss: true }
- );
- } else {
- addToast(intl.formatMessage(globalMessages.blacklistError), {
- appearance: 'error',
- autoDismiss: true,
});
+
+ if (res.status === 201) {
+ addToast(
+
+ {intl.formatMessage(globalMessages.blacklistSuccess, {
+ title: tv?.name,
+ strong: (msg: React.ReactNode) => {msg},
+ })}
+ ,
+ { appearance: 'success', autoDismiss: true }
+ );
+
+ revalidate();
+ }
+ } catch (e) {
+ if (e?.response?.status === 412) {
+ addToast(
+
+ {intl.formatMessage(globalMessages.blacklistDuplicateError, {
+ title: tv?.name,
+ strong: (msg: React.ReactNode) => {msg},
+ })}
+ ,
+ { appearance: 'info', autoDismiss: true }
+ );
+ } else {
+ addToast(intl.formatMessage(globalMessages.blacklistError), {
+ appearance: 'error',
+ autoDismiss: true,
+ });
+ }
}
setIsBlacklistUpdating(false);
diff --git a/src/components/UserList/BulkEditModal.tsx b/src/components/UserList/BulkEditModal.tsx
index ef33792e5..d5f72ab95 100644
--- a/src/components/UserList/BulkEditModal.tsx
+++ b/src/components/UserList/BulkEditModal.tsx
@@ -5,6 +5,7 @@ import { Permission, useUser } from '@app/hooks/useUser';
import globalMessages from '@app/i18n/globalMessages';
import defineMessages from '@app/utils/defineMessages';
import { hasPermission } from '@server/lib/permissions';
+import axios from 'axios';
import { useEffect, useState } from 'react';
import { useIntl } from 'react-intl';
import { useToasts } from 'react-toast-notifications';
@@ -45,18 +46,10 @@ const BulkEditModal = ({
const updateUsers = async () => {
try {
setIsSaving(true);
- const res = await fetch('/api/v1/user', {
- method: 'PUT',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({
- ids: selectedUserIds,
- permissions: currentPermission,
- }),
+ const { data: updated } = await axios.put(`/api/v1/user`, {
+ ids: selectedUserIds,
+ permissions: currentPermission,
});
- if (!res.ok) throw new Error();
- const updated: User[] = await res.json();
if (onComplete) {
onComplete(updated);
}
diff --git a/src/components/UserList/JellyfinImportModal.tsx b/src/components/UserList/JellyfinImportModal.tsx
index 7d9493817..738d17e58 100644
--- a/src/components/UserList/JellyfinImportModal.tsx
+++ b/src/components/UserList/JellyfinImportModal.tsx
@@ -6,6 +6,7 @@ import globalMessages from '@app/i18n/globalMessages';
import defineMessages from '@app/utils/defineMessages';
import { MediaServerType } from '@server/constants/server';
import type { UserResultsResponse } from '@server/interfaces/api/userInterfaces';
+import axios from 'axios';
import { useState } from 'react';
import { useIntl } from 'react-intl';
import { useToasts } from 'react-toast-notifications';
@@ -59,17 +60,10 @@ const JellyfinImportModal: React.FC = ({
setImporting(true);
try {
- const res = await fetch('/api/v1/user/import-from-jellyfin', {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({
- jellyfinUserIds: selectedUsers,
- }),
- });
- if (!res.ok) throw new Error();
- const createdUsers = await res.json();
+ const { data: createdUsers } = await axios.post(
+ '/api/v1/user/import-from-jellyfin',
+ { jellyfinUserIds: selectedUsers }
+ );
if (!createdUsers.length) {
throw new Error('No users were imported from Jellyfin.');
diff --git a/src/components/UserList/PlexImportModal.tsx b/src/components/UserList/PlexImportModal.tsx
index 28bbc8981..fcf5441b5 100644
--- a/src/components/UserList/PlexImportModal.tsx
+++ b/src/components/UserList/PlexImportModal.tsx
@@ -3,6 +3,7 @@ import Modal from '@app/components/Common/Modal';
import useSettings from '@app/hooks/useSettings';
import globalMessages from '@app/i18n/globalMessages';
import defineMessages from '@app/utils/defineMessages';
+import axios from 'axios';
import Image from 'next/image';
import { useState } from 'react';
import { useIntl } from 'react-intl';
@@ -47,17 +48,10 @@ const PlexImportModal = ({ onCancel, onComplete }: PlexImportProps) => {
setImporting(true);
try {
- const res = await fetch('/api/v1/user/import-from-plex', {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({
- plexIds: selectedUsers,
- }),
- });
- if (!res.ok) throw new Error();
- const createdUsers = await res.json();
+ const { data: createdUsers } = await axios.post(
+ '/api/v1/user/import-from-plex',
+ { plexIds: selectedUsers }
+ );
if (!Array.isArray(createdUsers) || createdUsers.length === 0) {
throw new Error('No users were imported from Plex.');
diff --git a/src/components/UserList/index.tsx b/src/components/UserList/index.tsx
index 9a9778811..877f95aec 100644
--- a/src/components/UserList/index.tsx
+++ b/src/components/UserList/index.tsx
@@ -28,6 +28,7 @@ import {
import { MediaServerType } from '@server/constants/server';
import type { UserResultsResponse } from '@server/interfaces/api/userInterfaces';
import { hasPermission } from '@server/lib/permissions';
+import axios from 'axios';
import { Field, Form, Formik } from 'formik';
import Link from 'next/link';
import { useRouter } from 'next/router';
@@ -181,10 +182,7 @@ const UserList = () => {
setDeleting(true);
try {
- const res = await fetch(`/api/v1/user/${deleteModal.user?.id}`, {
- method: 'DELETE',
- });
- if (!res.ok) throw new Error();
+ await axios.delete(`/api/v1/user/${deleteModal.user?.id}`);
addToast(intl.formatMessage(messages.userdeleted), {
autoDismiss: true,
@@ -286,34 +284,20 @@ const UserList = () => {
validationSchema={CreateUserSchema}
onSubmit={async (values) => {
try {
- const res = await fetch('/api/v1/user', {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({
- username: values.username,
- email: values.email,
- password: values.genpassword ? null : values.password,
- }),
+ await axios.post('/api/v1/user', {
+ username: values.username,
+ email: values.email,
+ password: values.genpassword ? null : values.password,
});
- if (!res.ok) throw new Error(res.statusText, { cause: res });
addToast(intl.formatMessage(messages.usercreatedsuccess), {
appearance: 'success',
autoDismiss: true,
});
setCreateModal({ isOpen: false });
} catch (e) {
- let errorData;
- try {
- errorData = await e.cause?.text();
- errorData = JSON.parse(errorData);
- } catch {
- /* empty */
- }
addToast(
intl.formatMessage(
- errorData.errors?.includes('USER_EXISTS')
+ e?.response?.data?.errors?.includes('USER_EXISTS')
? messages.usercreatedfailedexisting
: messages.usercreatedfailed
),
diff --git a/src/components/UserProfile/UserSettings/UserGeneralSettings/index.tsx b/src/components/UserProfile/UserSettings/UserGeneralSettings/index.tsx
index e0df3f5d4..b187a22a8 100644
--- a/src/components/UserProfile/UserSettings/UserGeneralSettings/index.tsx
+++ b/src/components/UserProfile/UserSettings/UserGeneralSettings/index.tsx
@@ -16,6 +16,7 @@ import defineMessages from '@app/utils/defineMessages';
import { ArrowDownOnSquareIcon } from '@heroicons/react/24/outline';
import { ApiErrorCode } from '@server/constants/error';
import type { UserSettingsGeneralResponse } from '@server/interfaces/api/userSettingsInterfaces';
+import axios from 'axios';
import { Field, Form, Formik } from 'formik';
import { useRouter } from 'next/router';
import { useEffect, useState } from 'react';
@@ -164,33 +165,24 @@ const UserGeneralSettings = () => {
enableReinitialize
onSubmit={async (values) => {
try {
- const res = await fetch(`/api/v1/user/${user?.id}/settings/main`, {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({
- username: values.displayName,
- email:
- values.email || user?.jellyfinUsername || user?.plexUsername,
- discordId: values.discordId,
- locale: values.locale,
- discoverRegion: values.discoverRegion,
- streamingRegion: values.streamingRegion,
- originalLanguage: values.originalLanguage,
- movieQuotaLimit: movieQuotaEnabled
- ? values.movieQuotaLimit
- : null,
- movieQuotaDays: movieQuotaEnabled
- ? values.movieQuotaDays
- : null,
- tvQuotaLimit: tvQuotaEnabled ? values.tvQuotaLimit : null,
- tvQuotaDays: tvQuotaEnabled ? values.tvQuotaDays : null,
- watchlistSyncMovies: values.watchlistSyncMovies,
- watchlistSyncTv: values.watchlistSyncTv,
- }),
+ await axios.post(`/api/v1/user/${user?.id}/settings/main`, {
+ username: values.displayName,
+ email:
+ values.email || user?.jellyfinUsername || user?.plexUsername,
+ discordId: values.discordId,
+ locale: values.locale,
+ discoverRegion: values.discoverRegion,
+ streamingRegion: values.streamingRegion,
+ originalLanguage: values.originalLanguage,
+ movieQuotaLimit: movieQuotaEnabled
+ ? values.movieQuotaLimit
+ : null,
+ movieQuotaDays: movieQuotaEnabled ? values.movieQuotaDays : null,
+ tvQuotaLimit: tvQuotaEnabled ? values.tvQuotaLimit : null,
+ tvQuotaDays: tvQuotaEnabled ? values.tvQuotaDays : null,
+ watchlistSyncMovies: values.watchlistSyncMovies,
+ watchlistSyncTv: values.watchlistSyncTv,
});
- if (!res.ok) throw new Error(res.statusText, { cause: res });
if (currentUser?.id === user?.id && setLocale) {
setLocale(
@@ -205,14 +197,7 @@ const UserGeneralSettings = () => {
appearance: 'success',
});
} catch (e) {
- let errorData;
- try {
- errorData = await e.cause?.text();
- errorData = JSON.parse(errorData);
- } catch {
- /* empty */
- }
- if (errorData?.message === ApiErrorCode.InvalidEmail) {
+ if (e?.response?.data?.message === ApiErrorCode.InvalidEmail) {
if (values.email) {
addToast(
intl.formatMessage(messages.toastSettingsFailureEmail),
diff --git a/src/components/UserProfile/UserSettings/UserLinkedAccountsSettings/LinkJellyfinModal.tsx b/src/components/UserProfile/UserSettings/UserLinkedAccountsSettings/LinkJellyfinModal.tsx
index 4872e7c15..f4c570ae7 100644
--- a/src/components/UserProfile/UserSettings/UserLinkedAccountsSettings/LinkJellyfinModal.tsx
+++ b/src/components/UserProfile/UserSettings/UserLinkedAccountsSettings/LinkJellyfinModal.tsx
@@ -5,6 +5,7 @@ import { useUser } from '@app/hooks/useUser';
import defineMessages from '@app/utils/defineMessages';
import { Transition } from '@headlessui/react';
import { MediaServerType } from '@server/constants/server';
+import axios from 'axios';
import { Field, Form, Formik } from 'formik';
import { useState } from 'react';
import { useIntl } from 'react-intl';
@@ -80,38 +81,28 @@ const LinkJellyfinModal: React.FC = ({
onSubmit={async ({ username, password }) => {
try {
setError(null);
- const res = await fetch(
+ await axios.post(
`/api/v1/user/${user?.id}/settings/linked-accounts/jellyfin`,
{
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({
- username,
- password,
- }),
+ username,
+ password,
}
);
- if (!res.ok) {
- if (res.status === 401) {
- setError(
- intl.formatMessage(messages.errorUnauthorized, {
- mediaServerName,
- })
- );
- } else if (res.status === 422) {
- setError(
- intl.formatMessage(messages.errorExists, { applicationName })
- );
- } else {
- setError(intl.formatMessage(messages.errorUnknown));
- }
- } else {
- onSave();
- }
+ onSave();
} catch (e) {
- setError(intl.formatMessage(messages.errorUnknown));
+ if (e?.response?.status === 401) {
+ setError(
+ intl.formatMessage(messages.errorUnauthorized, {
+ mediaServerName,
+ })
+ );
+ } else if (e?.response?.status === 422) {
+ setError(
+ intl.formatMessage(messages.errorExists, { applicationName })
+ );
+ } else {
+ setError(intl.formatMessage(messages.errorUnknown));
+ }
}
}}
>
diff --git a/src/components/UserProfile/UserSettings/UserLinkedAccountsSettings/index.tsx b/src/components/UserProfile/UserSettings/UserLinkedAccountsSettings/index.tsx
index c83a15790..ae7e63425 100644
--- a/src/components/UserProfile/UserSettings/UserLinkedAccountsSettings/index.tsx
+++ b/src/components/UserProfile/UserSettings/UserLinkedAccountsSettings/index.tsx
@@ -12,6 +12,7 @@ import defineMessages from '@app/utils/defineMessages';
import PlexOAuth from '@app/utils/plex';
import { TrashIcon } from '@heroicons/react/24/solid';
import { MediaServerType } from '@server/constants/server';
+import axios from 'axios';
import { useRouter } from 'next/router';
import { useMemo, useState } from 'react';
import { useIntl } from 'react-intl';
@@ -91,25 +92,21 @@ const UserLinkedAccountsSettings = () => {
setError(null);
try {
const authToken = await plexOAuth.login();
- const res = await fetch(
+ await axios.post(
`/api/v1/user/${user?.id}/settings/linked-accounts/plex`,
{
- method: 'POST',
- body: JSON.stringify({ authToken }),
+ authToken,
}
);
- if (!res.ok) {
- if (res.status === 401) {
- setError(intl.formatMessage(messages.plexErrorUnauthorized));
- } else if (res.status === 422) {
- setError(intl.formatMessage(messages.plexErrorExists));
- } else {
- setError(intl.formatMessage(messages.errorUnknown));
- }
- } else {
- await revalidateUser();
- }
+ await revalidateUser();
} catch (e) {
+ if (e?.response?.status === 401) {
+ setError(intl.formatMessage(messages.plexErrorUnauthorized));
+ } else if (e?.response?.status === 422) {
+ setError(intl.formatMessage(messages.plexErrorExists));
+ } else {
+ setError(intl.formatMessage(messages.errorUnknown));
+ }
setError(intl.formatMessage(messages.errorUnknown));
}
};
@@ -143,11 +140,9 @@ const UserLinkedAccountsSettings = () => {
const deleteRequest = async (account: string) => {
try {
- const res = await fetch(
- `/api/v1/user/${user?.id}/settings/linked-accounts/${account}`,
- { method: 'DELETE' }
+ await axios.delete(
+ `/api/v1/user/${user?.id}/settings/linked-accounts/${account}`
);
- if (!res.ok) throw new Error();
} catch {
setError(intl.formatMessage(messages.deleteFailed));
}
diff --git a/src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsDiscord.tsx b/src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsDiscord.tsx
index 061805ccb..01650ac0f 100644
--- a/src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsDiscord.tsx
+++ b/src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsDiscord.tsx
@@ -6,6 +6,7 @@ import globalMessages from '@app/i18n/globalMessages';
import defineMessages from '@app/utils/defineMessages';
import { ArrowDownOnSquareIcon } from '@heroicons/react/24/outline';
import type { UserSettingsNotificationsResponse } from '@server/interfaces/api/userSettingsInterfaces';
+import axios from 'axios';
import { Field, Form, Formik } from 'formik';
import { useRouter } from 'next/router';
import { useIntl } from 'react-intl';
@@ -67,28 +68,18 @@ const UserNotificationsDiscord = () => {
enableReinitialize
onSubmit={async (values) => {
try {
- const res = await fetch(
- `/api/v1/user/${user?.id}/settings/notifications`,
- {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({
- pgpKey: data?.pgpKey,
- discordId: values.discordId,
- pushbulletAccessToken: data?.pushbulletAccessToken,
- pushoverApplicationToken: data?.pushoverApplicationToken,
- pushoverUserKey: data?.pushoverUserKey,
- telegramChatId: data?.telegramChatId,
- telegramSendSilently: data?.telegramSendSilently,
- notificationTypes: {
- discord: values.types,
- },
- }),
- }
- );
- if (!res.ok) throw new Error();
+ await axios.post(`/api/v1/user/${user?.id}/settings/notifications`, {
+ pgpKey: data?.pgpKey,
+ discordId: values.discordId,
+ pushbulletAccessToken: data?.pushbulletAccessToken,
+ pushoverApplicationToken: data?.pushoverApplicationToken,
+ pushoverUserKey: data?.pushoverUserKey,
+ telegramChatId: data?.telegramChatId,
+ telegramSendSilently: data?.telegramSendSilently,
+ notificationTypes: {
+ discord: values.types,
+ },
+ });
addToast(intl.formatMessage(messages.discordsettingssaved), {
appearance: 'success',
autoDismiss: true,
diff --git a/src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsEmail.tsx b/src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsEmail.tsx
index 08028a5b5..c1196d5ac 100644
--- a/src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsEmail.tsx
+++ b/src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsEmail.tsx
@@ -11,6 +11,7 @@ import globalMessages from '@app/i18n/globalMessages';
import defineMessages from '@app/utils/defineMessages';
import { ArrowDownOnSquareIcon } from '@heroicons/react/24/outline';
import type { UserSettingsNotificationsResponse } from '@server/interfaces/api/userSettingsInterfaces';
+import axios from 'axios';
import { Form, Formik } from 'formik';
import { useRouter } from 'next/router';
import { useIntl } from 'react-intl';
@@ -66,28 +67,18 @@ const UserEmailSettings = () => {
enableReinitialize
onSubmit={async (values) => {
try {
- const res = await fetch(
- `/api/v1/user/${user?.id}/settings/notifications`,
- {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({
- pgpKey: values.pgpKey,
- discordId: data?.discordId,
- pushbulletAccessToken: data?.pushbulletAccessToken,
- pushoverApplicationToken: data?.pushoverApplicationToken,
- pushoverUserKey: data?.pushoverUserKey,
- telegramChatId: data?.telegramChatId,
- telegramSendSilently: data?.telegramSendSilently,
- notificationTypes: {
- email: values.types,
- },
- }),
- }
- );
- if (!res.ok) throw new Error();
+ await axios.post(`/api/v1/user/${user?.id}/settings/notifications`, {
+ pgpKey: values.pgpKey,
+ discordId: data?.discordId,
+ pushbulletAccessToken: data?.pushbulletAccessToken,
+ pushoverApplicationToken: data?.pushoverApplicationToken,
+ pushoverUserKey: data?.pushoverUserKey,
+ telegramChatId: data?.telegramChatId,
+ telegramSendSilently: data?.telegramSendSilently,
+ notificationTypes: {
+ email: values.types,
+ },
+ });
addToast(intl.formatMessage(messages.emailsettingssaved), {
appearance: 'success',
autoDismiss: true,
diff --git a/src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsPushbullet.tsx b/src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsPushbullet.tsx
index f4f5c1dfa..0a18ad25b 100644
--- a/src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsPushbullet.tsx
+++ b/src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsPushbullet.tsx
@@ -6,6 +6,7 @@ import { useUser } from '@app/hooks/useUser';
import globalMessages from '@app/i18n/globalMessages';
import defineMessages from '@app/utils/defineMessages';
import type { UserSettingsNotificationsResponse } from '@server/interfaces/api/userSettingsInterfaces';
+import axios from 'axios';
import { Form, Formik } from 'formik';
import { useRouter } from 'next/router';
import { useIntl } from 'react-intl';
@@ -64,28 +65,18 @@ const UserPushbulletSettings = () => {
enableReinitialize
onSubmit={async (values) => {
try {
- const res = await fetch(
- `/api/v1/user/${user?.id}/settings/notifications`,
- {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({
- pgpKey: data?.pgpKey,
- discordId: data?.discordId,
- pushbulletAccessToken: values.pushbulletAccessToken,
- pushoverApplicationToken: data?.pushoverApplicationToken,
- pushoverUserKey: data?.pushoverUserKey,
- telegramChatId: data?.telegramChatId,
- telegramSendSilently: data?.telegramSendSilently,
- notificationTypes: {
- pushbullet: values.types,
- },
- }),
- }
- );
- if (!res.ok) throw new Error();
+ await axios.post(`/api/v1/user/${user?.id}/settings/notifications`, {
+ pgpKey: data?.pgpKey,
+ discordId: data?.discordId,
+ pushbulletAccessToken: values.pushbulletAccessToken,
+ pushoverApplicationToken: data?.pushoverApplicationToken,
+ pushoverUserKey: data?.pushoverUserKey,
+ telegramChatId: data?.telegramChatId,
+ telegramSendSilently: data?.telegramSendSilently,
+ notificationTypes: {
+ pushbullet: values.types,
+ },
+ });
addToast(intl.formatMessage(messages.pushbulletsettingssaved), {
appearance: 'success',
autoDismiss: true,
diff --git a/src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsPushover.tsx b/src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsPushover.tsx
index 7834b2c5c..7ab9204de 100644
--- a/src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsPushover.tsx
+++ b/src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsPushover.tsx
@@ -7,6 +7,7 @@ import globalMessages from '@app/i18n/globalMessages';
import defineMessages from '@app/utils/defineMessages';
import type { PushoverSound } from '@server/api/pushover';
import type { UserSettingsNotificationsResponse } from '@server/interfaces/api/userSettingsInterfaces';
+import axios from 'axios';
import { Field, Form, Formik } from 'formik';
import { useRouter } from 'next/router';
import { useIntl } from 'react-intl';
@@ -96,28 +97,18 @@ const UserPushoverSettings = () => {
enableReinitialize
onSubmit={async (values) => {
try {
- const res = await fetch(
- `/api/v1/user/${user?.id}/settings/notifications`,
- {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({
- pgpKey: data?.pgpKey,
- discordId: data?.discordId,
- pushbulletAccessToken: data?.pushbulletAccessToken,
- pushoverApplicationToken: values.pushoverApplicationToken,
- pushoverUserKey: values.pushoverUserKey,
- telegramChatId: data?.telegramChatId,
- telegramSendSilently: data?.telegramSendSilently,
- notificationTypes: {
- pushover: values.types,
- },
- }),
- }
- );
- if (!res.ok) throw new Error();
+ await axios.post(`/api/v1/user/${user?.id}/settings/notifications`, {
+ pgpKey: data?.pgpKey,
+ discordId: data?.discordId,
+ pushbulletAccessToken: data?.pushbulletAccessToken,
+ pushoverApplicationToken: values.pushoverApplicationToken,
+ pushoverUserKey: values.pushoverUserKey,
+ telegramChatId: data?.telegramChatId,
+ telegramSendSilently: data?.telegramSendSilently,
+ notificationTypes: {
+ pushover: values.types,
+ },
+ });
addToast(intl.formatMessage(messages.pushoversettingssaved), {
appearance: 'success',
autoDismiss: true,
diff --git a/src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsTelegram.tsx b/src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsTelegram.tsx
index 92ce5d15a..7d006b676 100644
--- a/src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsTelegram.tsx
+++ b/src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsTelegram.tsx
@@ -6,6 +6,7 @@ import globalMessages from '@app/i18n/globalMessages';
import defineMessages from '@app/utils/defineMessages';
import { ArrowDownOnSquareIcon } from '@heroicons/react/24/outline';
import type { UserSettingsNotificationsResponse } from '@server/interfaces/api/userSettingsInterfaces';
+import axios from 'axios';
import { Field, Form, Formik } from 'formik';
import { useRouter } from 'next/router';
import { useIntl } from 'react-intl';
@@ -90,29 +91,19 @@ const UserTelegramSettings = () => {
enableReinitialize
onSubmit={async (values) => {
try {
- const res = await fetch(
- `/api/v1/user/${user?.id}/settings/notifications`,
- {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({
- pgpKey: data?.pgpKey,
- discordId: data?.discordId,
- pushbulletAccessToken: data?.pushbulletAccessToken,
- pushoverApplicationToken: data?.pushoverApplicationToken,
- pushoverUserKey: data?.pushoverUserKey,
- telegramChatId: values.telegramChatId,
- telegramMessageThreadId: values.telegramMessageThreadId,
- telegramSendSilently: values.telegramSendSilently,
- notificationTypes: {
- telegram: values.types,
- },
- }),
- }
- );
- if (!res.ok) throw new Error();
+ await axios.post(`/api/v1/user/${user?.id}/settings/notifications`, {
+ pgpKey: data?.pgpKey,
+ discordId: data?.discordId,
+ pushbulletAccessToken: data?.pushbulletAccessToken,
+ pushoverApplicationToken: data?.pushoverApplicationToken,
+ pushoverUserKey: data?.pushoverUserKey,
+ telegramChatId: values.telegramChatId,
+ telegramMessageThreadId: values.telegramMessageThreadId,
+ telegramSendSilently: values.telegramSendSilently,
+ notificationTypes: {
+ telegram: values.types,
+ },
+ });
addToast(intl.formatMessage(messages.telegramsettingssaved), {
appearance: 'success',
autoDismiss: true,
diff --git a/src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsWebPush/index.tsx b/src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsWebPush/index.tsx
index de438e3ad..feb542147 100644
--- a/src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsWebPush/index.tsx
+++ b/src/components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsWebPush/index.tsx
@@ -16,6 +16,7 @@ import {
} from '@heroicons/react/24/solid';
import type { UserPushSubscription } from '@server/entity/UserPushSubscription';
import type { UserSettingsNotificationsResponse } from '@server/interfaces/api/userSettingsInterfaces';
+import axios from 'axios';
import { Form, Formik } from 'formik';
import { useRouter } from 'next/router';
import { useEffect, useState } from 'react';
@@ -84,21 +85,12 @@ const UserWebPushSettings = () => {
const parsedSub = JSON.parse(JSON.stringify(sub));
if (parsedSub.keys.p256dh && parsedSub.keys.auth) {
- const res = await fetch('/api/v1/user/registerPushSubscription', {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({
- endpoint: parsedSub.endpoint,
- p256dh: parsedSub.keys.p256dh,
- auth: parsedSub.keys.auth,
- userAgent: navigator.userAgent,
- }),
+ await axios.post('/api/v1/user/registerPushSubscription', {
+ endpoint: parsedSub.endpoint,
+ p256dh: parsedSub.keys.p256dh,
+ auth: parsedSub.keys.auth,
+ userAgent: navigator.userAgent,
});
- if (!res.ok) {
- throw new Error(res.statusText);
- }
setWebPushEnabled(true);
addToast(intl.formatMessage(messages.webpushhasbeenenabled), {
appearance: 'success',
@@ -129,17 +121,11 @@ const UserWebPushSettings = () => {
.then(async (subscription) => {
const parsedSub = JSON.parse(JSON.stringify(subscription));
- const res = await fetch(
+ await axios.delete(
`/api/v1/user/${user?.id}/pushSubscription/${
p256dh ? p256dh : parsedSub.keys.p256dh
- }`,
- {
- method: 'DELETE',
- }
+ }`
);
- if (!res.ok) {
- throw new Error(res.statusText);
- }
if (subscription && (p256dh === parsedSub.keys.p256dh || !p256dh)) {
subscription.unsubscribe();
setWebPushEnabled(false);
@@ -188,17 +174,10 @@ const UserWebPushSettings = () => {
.then(async (subscription) => {
if (subscription) {
const parsedKey = JSON.parse(JSON.stringify(subscription));
- const response = await fetch(
- `/api/v1/user/${user.id}/pushSubscription/${parsedKey.keys.p256dh}`
- );
-
- if (!response.ok) {
- throw new Error(response.statusText);
- }
-
- const currentUserPushSub = {
- data: (await response.json()) as UserPushSubscription,
- };
+ const currentUserPushSub =
+ await axios.get(
+ `/api/v1/user/${user.id}/pushSubscription/${parsedKey.keys.p256dh}`
+ );
if (currentUserPushSub.data.p256dh !== parsedKey.keys.p256dh) {
return;
@@ -233,30 +212,21 @@ const UserWebPushSettings = () => {
enableReinitialize
onSubmit={async (values) => {
try {
- const res = await fetch(
+ await axios.post(
`/api/v1/user/${user?.id}/settings/notifications`,
{
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
+ pgpKey: data?.pgpKey,
+ discordId: data?.discordId,
+ pushbulletAccessToken: data?.pushbulletAccessToken,
+ pushoverApplicationToken: data?.pushoverApplicationToken,
+ pushoverUserKey: data?.pushoverUserKey,
+ telegramChatId: data?.telegramChatId,
+ telegramSendSilently: data?.telegramSendSilently,
+ notificationTypes: {
+ webpush: values.types,
},
- body: JSON.stringify({
- pgpKey: data?.pgpKey,
- discordId: data?.discordId,
- pushbulletAccessToken: data?.pushbulletAccessToken,
- pushoverApplicationToken: data?.pushoverApplicationToken,
- pushoverUserKey: data?.pushoverUserKey,
- telegramChatId: data?.telegramChatId,
- telegramSendSilently: data?.telegramSendSilently,
- notificationTypes: {
- webpush: values.types,
- },
- }),
}
);
- if (!res.ok) {
- throw new Error(res.statusText);
- }
mutate('/api/v1/settings/public');
addToast(intl.formatMessage(messages.webpushsettingssaved), {
appearance: 'success',
diff --git a/src/components/UserProfile/UserSettings/UserPasswordChange/index.tsx b/src/components/UserProfile/UserSettings/UserPasswordChange/index.tsx
index b7f320b06..869b21883 100644
--- a/src/components/UserProfile/UserSettings/UserPasswordChange/index.tsx
+++ b/src/components/UserProfile/UserSettings/UserPasswordChange/index.tsx
@@ -8,6 +8,7 @@ import globalMessages from '@app/i18n/globalMessages';
import ErrorPage from '@app/pages/_error';
import defineMessages from '@app/utils/defineMessages';
import { ArrowDownOnSquareIcon } from '@heroicons/react/24/outline';
+import axios from 'axios';
import { Form, Formik } from 'formik';
import { useRouter } from 'next/router';
import { useIntl } from 'react-intl';
@@ -122,21 +123,11 @@ const UserPasswordChange = () => {
enableReinitialize
onSubmit={async (values, { resetForm }) => {
try {
- const res = await fetch(
- `/api/v1/user/${user?.id}/settings/password`,
- {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({
- currentPassword: values.currentPassword,
- newPassword: values.newPassword,
- confirmPassword: values.confirmPassword,
- }),
- }
- );
- if (!res.ok) throw new Error();
+ await axios.post(`/api/v1/user/${user?.id}/settings/password`, {
+ currentPassword: values.currentPassword,
+ newPassword: values.newPassword,
+ confirmPassword: values.confirmPassword,
+ });
addToast(intl.formatMessage(messages.toastSettingsSuccess), {
autoDismiss: true,
diff --git a/src/components/UserProfile/UserSettings/UserPermissions/index.tsx b/src/components/UserProfile/UserSettings/UserPermissions/index.tsx
index 7f8f30960..3398ae7ea 100644
--- a/src/components/UserProfile/UserSettings/UserPermissions/index.tsx
+++ b/src/components/UserProfile/UserSettings/UserPermissions/index.tsx
@@ -8,6 +8,7 @@ import globalMessages from '@app/i18n/globalMessages';
import ErrorPage from '@app/pages/_error';
import defineMessages from '@app/utils/defineMessages';
import { ArrowDownOnSquareIcon } from '@heroicons/react/24/outline';
+import axios from 'axios';
import { Form, Formik } from 'formik';
import { useRouter } from 'next/router';
import { useIntl } from 'react-intl';
@@ -83,19 +84,10 @@ const UserPermissions = () => {
enableReinitialize
onSubmit={async (values) => {
try {
- const res = await fetch(
- `/api/v1/user/${user?.id}/settings/permissions`,
- {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({
- permissions: values.currentPermissions ?? 0,
- }),
- }
- );
- if (!res.ok) throw new Error();
+ await axios.post(`/api/v1/user/${user?.id}/settings/permissions`, {
+ permissions: values.currentPermissions ?? 0,
+ });
+
addToast(intl.formatMessage(messages.toastSettingsSuccess), {
autoDismiss: true,
appearance: 'success',
diff --git a/src/i18n/locale/en.json b/src/i18n/locale/en.json
index d4269b969..1ade9ff26 100644
--- a/src/i18n/locale/en.json
+++ b/src/i18n/locale/en.json
@@ -943,8 +943,6 @@
"components.Settings.SettingsNetwork.csrfProtectionHoverTip": "Do NOT enable this setting unless you understand what you are doing!",
"components.Settings.SettingsNetwork.csrfProtectionTip": "Set external API access to read-only (requires HTTPS)",
"components.Settings.SettingsNetwork.docs": "documentation",
- "components.Settings.SettingsNetwork.forceIpv4First": "Force IPv4 Resolution First",
- "components.Settings.SettingsNetwork.forceIpv4FirstTip": "Force Jellyseerr to resolve IPv4 addresses first instead of IPv6",
"components.Settings.SettingsNetwork.network": "Network",
"components.Settings.SettingsNetwork.networkDisclaimer": "Network parameters from your container/system should be used instead of these settings. See the {docs} for more information.",
"components.Settings.SettingsNetwork.networksettings": "Network Settings",
diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx
index 1b29d41e8..d79a7904c 100644
--- a/src/pages/_app.tsx
+++ b/src/pages/_app.tsx
@@ -13,10 +13,10 @@ import { UserContext } from '@app/context/UserContext';
import type { User } from '@app/hooks/useUser';
import { Permission, useUser } from '@app/hooks/useUser';
import '@app/styles/globals.css';
-import '@app/utils/fetchOverride';
import { polyfillIntl } from '@app/utils/polyfillIntl';
import { MediaServerType } from '@server/constants/server';
import type { PublicSettingsResponse } from '@server/interfaces/api/settingsInterfaces';
+import axios from 'axios';
import type { AppInitialProps, AppProps } from 'next/app';
import App from 'next/app';
import Head from 'next/head';
@@ -133,8 +133,8 @@ const CoreApp: Omit = ({
useEffect(() => {
const requestsCount = async () => {
- const response = await fetch('/api/v1/request/count');
- return await response.json();
+ const response = await axios.get('/api/v1/request/count');
+ return response.data;
};
// Cast navigator to a type that includes setAppBadge and clearAppBadge
@@ -171,11 +171,7 @@ const CoreApp: Omit = ({
return (
{
- const res = await fetch(resource, init);
- if (!res.ok) throw new Error();
- return await res.json();
- },
+ fetcher: (url) => axios.get(url).then((res) => res.data),
fallback: {
'/api/v1/auth/me': user,
},
@@ -241,15 +237,15 @@ CoreApp.getInitialProps = async (initialProps) => {
if (ctx.res) {
// Check if app is initialized and redirect if necessary
- const res = await fetch(
+ const response = await axios.get(
`http://${process.env.HOST || 'localhost'}:${
process.env.PORT || 5055
}/api/v1/settings/public`
);
- if (!res.ok) throw new Error();
- currentSettings = await res.json();
- const initialized = currentSettings.initialized;
+ currentSettings = response.data;
+
+ const initialized = response.data.initialized;
if (!initialized) {
if (!router.pathname.match(/(setup|login\/plex)/)) {
@@ -261,7 +257,7 @@ CoreApp.getInitialProps = async (initialProps) => {
} else {
try {
// Attempt to get the user by running a request to the local api
- const res = await fetch(
+ const response = await axios.get(
`http://${process.env.HOST || 'localhost'}:${
process.env.PORT || 5055
}/api/v1/auth/me`,
@@ -272,8 +268,7 @@ CoreApp.getInitialProps = async (initialProps) => {
: undefined,
}
);
- if (!res.ok) throw new Error();
- user = await res.json();
+ user = response.data;
if (router.pathname.match(/(setup|login)/)) {
ctx.res.writeHead(307, {
diff --git a/src/pages/collection/[collectionId]/index.tsx b/src/pages/collection/[collectionId]/index.tsx
index da9c6bf03..e555e41e5 100644
--- a/src/pages/collection/[collectionId]/index.tsx
+++ b/src/pages/collection/[collectionId]/index.tsx
@@ -1,5 +1,6 @@
import CollectionDetails from '@app/components/CollectionDetails';
import type { Collection } from '@server/models/Collection';
+import axios from 'axios';
import type { GetServerSideProps, NextPage } from 'next';
interface CollectionPageProps {
@@ -13,7 +14,7 @@ const CollectionPage: NextPage = ({ collection }) => {
export const getServerSideProps: GetServerSideProps<
CollectionPageProps
> = async (ctx) => {
- const res = await fetch(
+ const response = await axios.get(
`http://${process.env.HOST || 'localhost'}:${
process.env.PORT || 5055
}/api/v1/collection/${ctx.query.collectionId}`,
@@ -23,12 +24,10 @@ export const getServerSideProps: GetServerSideProps<
: undefined,
}
);
- if (!res.ok) throw new Error();
- const collection: Collection = await res.json();
return {
props: {
- collection,
+ collection: response.data,
},
};
};
diff --git a/src/pages/movie/[movieId]/index.tsx b/src/pages/movie/[movieId]/index.tsx
index cf2b11b9c..d9788a202 100644
--- a/src/pages/movie/[movieId]/index.tsx
+++ b/src/pages/movie/[movieId]/index.tsx
@@ -1,5 +1,6 @@
import MovieDetails from '@app/components/MovieDetails';
import type { MovieDetails as MovieDetailsType } from '@server/models/Movie';
+import axios from 'axios';
import type { GetServerSideProps, NextPage } from 'next';
interface MoviePageProps {
@@ -13,7 +14,7 @@ const MoviePage: NextPage = ({ movie }) => {
export const getServerSideProps: GetServerSideProps = async (
ctx
) => {
- const res = await fetch(
+ const response = await axios.get(
`http://${process.env.HOST || 'localhost'}:${
process.env.PORT || 5055
}/api/v1/movie/${ctx.query.movieId}`,
@@ -23,12 +24,10 @@ export const getServerSideProps: GetServerSideProps = async (
: undefined,
}
);
- if (!res.ok) throw new Error();
- const movie: MovieDetailsType = await res.json();
return {
props: {
- movie,
+ movie: response.data,
},
};
};
diff --git a/src/pages/tv/[tvId]/index.tsx b/src/pages/tv/[tvId]/index.tsx
index 36fba5fcc..9659d82ca 100644
--- a/src/pages/tv/[tvId]/index.tsx
+++ b/src/pages/tv/[tvId]/index.tsx
@@ -1,5 +1,6 @@
import TvDetails from '@app/components/TvDetails';
import type { TvDetails as TvDetailsType } from '@server/models/Tv';
+import axios from 'axios';
import type { GetServerSideProps, NextPage } from 'next';
interface TvPageProps {
@@ -13,7 +14,7 @@ const TvPage: NextPage = ({ tv }) => {
export const getServerSideProps: GetServerSideProps = async (
ctx
) => {
- const res = await fetch(
+ const response = await axios.get(
`http://${process.env.HOST || 'localhost'}:${
process.env.PORT || 5055
}/api/v1/tv/${ctx.query.tvId}`,
@@ -23,12 +24,10 @@ export const getServerSideProps: GetServerSideProps = async (
: undefined,
}
);
- if (!res.ok) throw new Error();
- const tv: TvDetailsType = await res.json();
return {
props: {
- tv,
+ tv: response.data,
},
};
};
diff --git a/src/utils/fetchOverride.ts b/src/utils/fetchOverride.ts
deleted file mode 100644
index e0a900125..000000000
--- a/src/utils/fetchOverride.ts
+++ /dev/null
@@ -1,46 +0,0 @@
-const getCsrfToken = (): string | null => {
- if (typeof window !== 'undefined') {
- const match = document.cookie.match(/XSRF-TOKEN=([^;]+)/);
- return match ? decodeURIComponent(match[1]) : null;
- }
- return null;
-};
-
-const isSameOrigin = (url: RequestInfo | URL): boolean => {
- const parsedUrl = new URL(
- url instanceof Request ? url.url : url.toString(),
- window.location.origin
- );
- return parsedUrl.origin === window.location.origin;
-};
-
-// We are using a custom fetch implementation to add the X-XSRF-TOKEN heade
-// to all requests. This is required when CSRF protection is enabled.
-if (typeof window !== 'undefined') {
- const originalFetch: typeof fetch = window.fetch;
-
- (window as typeof globalThis).fetch = async (
- input: RequestInfo | URL,
- init?: RequestInit
- ): Promise => {
- if (!isSameOrigin(input)) {
- return originalFetch(input, init);
- }
-
- const csrfToken = getCsrfToken();
-
- const headers = {
- ...(init?.headers || {}),
- ...(csrfToken ? { 'XSRF-TOKEN': csrfToken } : {}),
- };
-
- const newInit: RequestInit = {
- ...init,
- headers,
- };
-
- return originalFetch(input, newInit);
- };
-}
-
-export {};
diff --git a/src/utils/jellyfin.ts b/src/utils/jellyfin.ts
index 59b9b9d7c..2aa91bd73 100644
--- a/src/utils/jellyfin.ts
+++ b/src/utils/jellyfin.ts
@@ -1,3 +1,6 @@
+import type { AxiosError, AxiosResponse } from 'axios';
+import axios from 'axios';
+
interface JellyfinAuthenticationResult {
Id: string;
AccessToken: string;
@@ -15,34 +18,30 @@ class JellyAPI {
resolve: (result: JellyfinAuthenticationResult) => void,
reject: (e: Error) => void
) => {
- fetch(Hostname + '/Users/AuthenticateByName', {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- 'X-Emby-Authorization':
- 'MediaBrowser Client="Jellyfin Web", Device="Firefox", DeviceId="TW96aWxsYS81LjAgKFdpbmRvd3MgTlQgMTAuMDsgV2luNjQ7IHg2NDsgcnY6ODUuMCkgR2Vja28vMjAxMDAxMDEgRmlyZWZveC84NS4wfDE2MTI5MjcyMDM5NzM1", Version="10.8.0"',
- },
- body: JSON.stringify({
- Username: Username,
- Pw: Password,
- }),
- })
- .then((res) => {
- if (!res.ok) {
- throw new Error('Network response was not ok');
+ axios
+ .post(
+ Hostname + '/Users/AuthenticateByName',
+ {
+ Username: Username,
+ Pw: Password,
+ },
+ {
+ headers: {
+ 'X-Emby-Authorization':
+ 'MediaBrowser Client="Jellyfin Web", Device="Firefox", DeviceId="TW96aWxsYS81LjAgKFdpbmRvd3MgTlQgMTAuMDsgV2luNjQ7IHg2NDsgcnY6ODUuMCkgR2Vja28vMjAxMDAxMDEgRmlyZWZveC84NS4wfDE2MTI5MjcyMDM5NzM1", Version="10.8.0"',
+ },
}
- return res.json();
- })
- .then((data) => {
+ )
+ .then((resp: AxiosResponse) => {
const response: JellyfinAuthenticationResult = {
- Id: data.User.Id,
- AccessToken: data.AccessToken,
- ServerId: data.ServerId,
+ Id: resp.data.User.Id,
+ AccessToken: resp.data.AccessToken,
+ ServerId: resp.data.ServerId,
};
resolve(response);
})
- .catch((error) => {
- reject(error);
+ .catch((e: AxiosError) => {
+ reject(e);
});
}
);
diff --git a/src/utils/plex.ts b/src/utils/plex.ts
index 5c0d1906e..dd16c4355 100644
--- a/src/utils/plex.ts
+++ b/src/utils/plex.ts
@@ -1,3 +1,4 @@
+import axios from 'axios';
import Bowser from 'bowser';
interface PlexHeaders extends Record {
@@ -77,14 +78,13 @@ class PlexOAuth {
'You must initialize the plex headers clientside to login'
);
}
- const res = await fetch('https://plex.tv/api/v2/pins?strong=true', {
- method: 'POST',
- headers: this.plexHeaders,
- });
- if (!res.ok) throw new Error();
- const data = await res.json();
+ const response = await axios.post(
+ 'https://plex.tv/api/v2/pins?strong=true',
+ undefined,
+ { headers: this.plexHeaders }
+ );
- this.pin = { id: data.id, code: data.code };
+ this.pin = { id: response.data.id, code: response.data.code };
return this.pin;
}
@@ -136,17 +136,16 @@ class PlexOAuth {
throw new Error('Unable to poll when pin is not initialized.');
}
- const res = await fetch(`https://plex.tv/api/v2/pins/${this.pin.id}`, {
- headers: this.plexHeaders,
- });
- if (!res.ok) throw new Error();
- const data = await res.json();
+ const response = await axios.get(
+ `https://plex.tv/api/v2/pins/${this.pin.id}`,
+ { headers: this.plexHeaders }
+ );
- if (data?.authToken) {
- this.authToken = data.authToken as string;
+ if (response.data?.authToken) {
+ this.authToken = response.data.authToken as string;
this.closePopup();
resolve(this.authToken);
- } else if (!data?.authToken && !this.popup?.closed) {
+ } else if (!response.data?.authToken && !this.popup?.closed) {
setTimeout(executePoll, 1000, resolve, reject);
} else {
reject(new Error('Popup closed without completing login'));