mirror of
https://github.com/sussy-code/smov.git
synced 2024-12-20 14:37:43 +01:00
fix: change useBackendUrl to possibly be undefined, add checks to avoid useless requests to nonexistent backend
This commit is contained in:
parent
b18269b40e
commit
fcf42a4e8a
15 changed files with 42 additions and 14 deletions
|
@ -2,7 +2,6 @@ import { ofetch } from "ofetch";
|
||||||
|
|
||||||
import { getAuthHeaders } from "@/backend/accounts/auth";
|
import { getAuthHeaders } from "@/backend/accounts/auth";
|
||||||
import { ProgressResponse } from "@/backend/accounts/user";
|
import { ProgressResponse } from "@/backend/accounts/user";
|
||||||
import { BACKEND_URL } from "@/setup/constants";
|
|
||||||
import { AccountWithToken } from "@/stores/auth";
|
import { AccountWithToken } from "@/stores/auth";
|
||||||
import { ProgressMediaItem, ProgressUpdateItem } from "@/stores/progress";
|
import { ProgressMediaItem, ProgressUpdateItem } from "@/stores/progress";
|
||||||
|
|
||||||
|
@ -104,7 +103,6 @@ export async function removeProgress(
|
||||||
episodeId?: string,
|
episodeId?: string,
|
||||||
seasonId?: string,
|
seasonId?: string,
|
||||||
) {
|
) {
|
||||||
if (!BACKEND_URL) return;
|
|
||||||
await ofetch(`/users/${account.userId}/progress/${id}`, {
|
await ofetch(`/users/${account.userId}/progress/${id}`, {
|
||||||
method: "DELETE",
|
method: "DELETE",
|
||||||
headers: getAuthHeaders(account.token),
|
headers: getAuthHeaders(account.token),
|
||||||
|
|
|
@ -63,6 +63,7 @@ export function useAuth() {
|
||||||
|
|
||||||
const login = useCallback(
|
const login = useCallback(
|
||||||
async (loginData: LoginData) => {
|
async (loginData: LoginData) => {
|
||||||
|
if (!backendUrl) return;
|
||||||
const keys = await keysFromMnemonic(loginData.mnemonic);
|
const keys = await keysFromMnemonic(loginData.mnemonic);
|
||||||
const publicKeyBase64Url = bytesToBase64Url(keys.publicKey);
|
const publicKeyBase64Url = bytesToBase64Url(keys.publicKey);
|
||||||
const { challenge } = await getLoginChallengeToken(
|
const { challenge } = await getLoginChallengeToken(
|
||||||
|
@ -87,7 +88,7 @@ export function useAuth() {
|
||||||
);
|
);
|
||||||
|
|
||||||
const logout = useCallback(async () => {
|
const logout = useCallback(async () => {
|
||||||
if (!currentAccount) return;
|
if (!currentAccount || !backendUrl) return;
|
||||||
try {
|
try {
|
||||||
await removeSession(
|
await removeSession(
|
||||||
backendUrl,
|
backendUrl,
|
||||||
|
@ -102,6 +103,7 @@ export function useAuth() {
|
||||||
|
|
||||||
const register = useCallback(
|
const register = useCallback(
|
||||||
async (registerData: RegistrationData) => {
|
async (registerData: RegistrationData) => {
|
||||||
|
if (!backendUrl) return;
|
||||||
const { challenge } = await getRegisterChallengeToken(
|
const { challenge } = await getRegisterChallengeToken(
|
||||||
backendUrl,
|
backendUrl,
|
||||||
registerData.recaptchaToken,
|
registerData.recaptchaToken,
|
||||||
|
@ -134,6 +136,7 @@ export function useAuth() {
|
||||||
progressItems: Record<string, ProgressMediaItem>,
|
progressItems: Record<string, ProgressMediaItem>,
|
||||||
bookmarks: Record<string, BookmarkMediaItem>,
|
bookmarks: Record<string, BookmarkMediaItem>,
|
||||||
) => {
|
) => {
|
||||||
|
if (!backendUrl) return;
|
||||||
if (
|
if (
|
||||||
Object.keys(progressItems).length === 0 &&
|
Object.keys(progressItems).length === 0 &&
|
||||||
Object.keys(bookmarks).length === 0
|
Object.keys(bookmarks).length === 0
|
||||||
|
@ -159,6 +162,7 @@ export function useAuth() {
|
||||||
|
|
||||||
const restore = useCallback(
|
const restore = useCallback(
|
||||||
async (account: AccountWithToken) => {
|
async (account: AccountWithToken) => {
|
||||||
|
if (!backendUrl) return;
|
||||||
let user: { user: UserResponse; session: SessionResponse };
|
let user: { user: UserResponse; session: SessionResponse };
|
||||||
try {
|
try {
|
||||||
user = await getUser(backendUrl, account.token);
|
user = await getUser(backendUrl, account.token);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { conf } from "@/setup/config";
|
import { conf } from "@/setup/config";
|
||||||
import { useAuthStore } from "@/stores/auth";
|
import { useAuthStore } from "@/stores/auth";
|
||||||
|
|
||||||
export function useBackendUrl() {
|
export function useBackendUrl(): string | undefined {
|
||||||
const backendUrl = useAuthStore((s) => s.backendUrl);
|
const backendUrl = useAuthStore((s) => s.backendUrl);
|
||||||
return backendUrl ?? conf().BACKEND_URL;
|
return backendUrl ?? conf().BACKEND_URL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,6 +70,7 @@ export function AccountSettings(props: {
|
||||||
const url = useBackendUrl();
|
const url = useBackendUrl();
|
||||||
const { account } = props;
|
const { account } = props;
|
||||||
const [sessionsResult, execSessions] = useAsyncFn(() => {
|
const [sessionsResult, execSessions] = useAsyncFn(() => {
|
||||||
|
if (!url) return Promise.resolve([]);
|
||||||
return getSessions(url, account);
|
return getSessions(url, account);
|
||||||
}, [account, url]);
|
}, [account, url]);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -144,7 +145,7 @@ export function SettingsPage() {
|
||||||
);
|
);
|
||||||
|
|
||||||
const saveChanges = useCallback(async () => {
|
const saveChanges = useCallback(async () => {
|
||||||
if (account) {
|
if (account && backendUrl) {
|
||||||
if (
|
if (
|
||||||
state.appLanguage.changed ||
|
state.appLanguage.changed ||
|
||||||
state.theme.changed ||
|
state.theme.changed ||
|
||||||
|
|
|
@ -43,7 +43,7 @@ export function OnboardingProxyPage() {
|
||||||
throw new Error("onboarding.proxy.input.errorNotProxy");
|
throw new Error("onboarding.proxy.input.errorNotProxy");
|
||||||
setProxySet([url]);
|
setProxySet([url]);
|
||||||
|
|
||||||
if (account) {
|
if (account && backendUrl) {
|
||||||
await updateSettings(backendUrl, account, {
|
await updateSettings(backendUrl, account, {
|
||||||
proxyUrls: [url],
|
proxyUrls: [url],
|
||||||
});
|
});
|
||||||
|
|
|
@ -32,13 +32,21 @@ export function BackendTestPart() {
|
||||||
value: null,
|
value: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (!backendUrl) {
|
||||||
|
return setStatus({
|
||||||
|
hasTested: true,
|
||||||
|
success: false,
|
||||||
|
errorText: "Backend URL is not set",
|
||||||
|
value: null,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const backendData = await getBackendMeta(backendUrl);
|
const backendData = await getBackendMeta(backendUrl);
|
||||||
return setStatus({
|
return setStatus({
|
||||||
hasTested: true,
|
hasTested: true,
|
||||||
success: true,
|
success: true,
|
||||||
errorText:
|
errorText: "",
|
||||||
"Failed to call backend, double check the URL key and your internet connection",
|
|
||||||
value: backendData,
|
value: backendData,
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
@ -46,7 +54,7 @@ export function BackendTestPart() {
|
||||||
hasTested: true,
|
hasTested: true,
|
||||||
success: false,
|
success: false,
|
||||||
errorText:
|
errorText:
|
||||||
"Failed to call backend, double check the URL key and your internet connection",
|
"Failed to call backend, double check the URL, your internet connection, and ensure CORS is properly configured on your backend.",
|
||||||
value: null,
|
value: null,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,6 +52,9 @@ export function LoginFormPart(props: LoginFormPartProps) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!account)
|
||||||
|
throw new Error(t("auth.login.validationError") ?? undefined);
|
||||||
|
|
||||||
await importData(account, progressItems, bookmarkItems);
|
await importData(account, progressItems, bookmarkItems);
|
||||||
|
|
||||||
await restore(account);
|
await restore(account);
|
||||||
|
|
|
@ -22,8 +22,12 @@ interface TrustBackendPartProps {
|
||||||
export function TrustBackendPart(props: TrustBackendPartProps) {
|
export function TrustBackendPart(props: TrustBackendPartProps) {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const backendUrl = useBackendUrl();
|
const backendUrl = useBackendUrl();
|
||||||
const hostname = useMemo(() => new URL(backendUrl).hostname, [backendUrl]);
|
const hostname = useMemo(
|
||||||
|
() => (backendUrl ? new URL(backendUrl).hostname : ""),
|
||||||
|
[backendUrl],
|
||||||
|
);
|
||||||
const result = useAsync(() => {
|
const result = useAsync(() => {
|
||||||
|
if (!backendUrl) return Promise.resolve(null);
|
||||||
return getBackendMeta(backendUrl);
|
return getBackendMeta(backendUrl);
|
||||||
}, [backendUrl]);
|
}, [backendUrl]);
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
|
@ -47,6 +47,8 @@ export function VerifyPassphrase(props: VerifyPassphraseProps) {
|
||||||
|
|
||||||
const [result, execute] = useAsyncFn(
|
const [result, execute] = useAsyncFn(
|
||||||
async (inputMnemonic: string) => {
|
async (inputMnemonic: string) => {
|
||||||
|
if (!backendUrl)
|
||||||
|
throw new Error(t("auth.verify.noBackendUrl") ?? undefined);
|
||||||
if (!props.mnemonic || !props.userData)
|
if (!props.mnemonic || !props.userData)
|
||||||
throw new Error(t("auth.verify.invalidData") ?? undefined);
|
throw new Error(t("auth.verify.invalidData") ?? undefined);
|
||||||
|
|
||||||
|
@ -68,6 +70,9 @@ export function VerifyPassphrase(props: VerifyPassphraseProps) {
|
||||||
recaptchaToken,
|
recaptchaToken,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (!account)
|
||||||
|
throw new Error(t("auth.verify.registrationFailed") ?? undefined);
|
||||||
|
|
||||||
await importData(account, progressItems, bookmarkItems);
|
await importData(account, progressItems, bookmarkItems);
|
||||||
|
|
||||||
await updateSettings(backendUrl, account, {
|
await updateSettings(backendUrl, account, {
|
||||||
|
|
|
@ -18,7 +18,7 @@ export function AccountActionsPart() {
|
||||||
const deleteModal = useModal("account-delete");
|
const deleteModal = useModal("account-delete");
|
||||||
|
|
||||||
const [deleteResult, deleteExec] = useAsyncFn(async () => {
|
const [deleteResult, deleteExec] = useAsyncFn(async () => {
|
||||||
if (!account) return;
|
if (!account || !url) return;
|
||||||
await deleteUser(url, account);
|
await deleteUser(url, account);
|
||||||
await logout();
|
await logout();
|
||||||
deleteModal.hide();
|
deleteModal.hide();
|
||||||
|
|
|
@ -24,6 +24,7 @@ export function Device(props: {
|
||||||
const token = useAuthStore((s) => s.account?.token);
|
const token = useAuthStore((s) => s.account?.token);
|
||||||
const [result, exec] = useAsyncFn(async () => {
|
const [result, exec] = useAsyncFn(async () => {
|
||||||
if (!token) throw new Error("No token present");
|
if (!token) throw new Error("No token present");
|
||||||
|
if (!url) throw new Error("No backend set");
|
||||||
await removeSession(url, token, props.id);
|
await removeSession(url, token, props.id);
|
||||||
props.onRemove?.();
|
props.onRemove?.();
|
||||||
}, [url, token, props.id]);
|
}, [url, token, props.id]);
|
||||||
|
|
|
@ -14,9 +14,9 @@ import { useAuthStore } from "@/stores/auth";
|
||||||
|
|
||||||
const rem = 16;
|
const rem = 16;
|
||||||
|
|
||||||
function SecureBadge(props: { url: string }) {
|
function SecureBadge(props: { url: string | undefined }) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const secure = props.url.startsWith("https://");
|
const secure = props.url ? props.url.startsWith("https://") : false;
|
||||||
return (
|
return (
|
||||||
<div className="flex items-center gap-1 -mx-1 ml-3 px-1 rounded bg-largeCard-background font-bold">
|
<div className="flex items-center gap-1 -mx-1 ml-3 px-1 rounded bg-largeCard-background font-bold">
|
||||||
<Icon icon={secure ? Icons.LOCK : Icons.UNLOCK} />
|
<Icon icon={secure ? Icons.LOCK : Icons.UNLOCK} />
|
||||||
|
@ -68,6 +68,7 @@ export function SidebarPart() {
|
||||||
const backendUrl = useBackendUrl();
|
const backendUrl = useBackendUrl();
|
||||||
|
|
||||||
const backendMeta = useAsync(async () => {
|
const backendMeta = useAsync(async () => {
|
||||||
|
if (!backendUrl) return;
|
||||||
return getBackendMeta(backendUrl);
|
return getBackendMeta(backendUrl);
|
||||||
}, [backendUrl]);
|
}, [backendUrl]);
|
||||||
|
|
||||||
|
@ -159,7 +160,7 @@ export function SidebarPart() {
|
||||||
<SecureBadge url={backendUrl} />
|
<SecureBadge url={backendUrl} />
|
||||||
</div>
|
</div>
|
||||||
<p className="text-white">
|
<p className="text-white">
|
||||||
{backendUrl.replace(/https?:\/\//, "")}
|
{backendUrl?.replace(/https?:\/\//, "") ?? "—"}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -60,6 +60,7 @@ export function BookmarkSyncer() {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const interval = setInterval(() => {
|
const interval = setInterval(() => {
|
||||||
(async () => {
|
(async () => {
|
||||||
|
if (!url) return;
|
||||||
const state = useBookmarkStore.getState();
|
const state = useBookmarkStore.getState();
|
||||||
const user = useAuthStore.getState();
|
const user = useAuthStore.getState();
|
||||||
await syncBookmarks(
|
await syncBookmarks(
|
||||||
|
|
|
@ -62,6 +62,7 @@ export function ProgressSyncer() {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const interval = setInterval(() => {
|
const interval = setInterval(() => {
|
||||||
(async () => {
|
(async () => {
|
||||||
|
if (!url) return;
|
||||||
const state = useProgressStore.getState();
|
const state = useProgressStore.getState();
|
||||||
const user = useAuthStore.getState();
|
const user = useAuthStore.getState();
|
||||||
await syncProgress(
|
await syncProgress(
|
||||||
|
|
|
@ -16,6 +16,7 @@ export function SettingsSyncer() {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const interval = setInterval(() => {
|
const interval = setInterval(() => {
|
||||||
(async () => {
|
(async () => {
|
||||||
|
if (!url) return;
|
||||||
const state = useSubtitleStore.getState();
|
const state = useSubtitleStore.getState();
|
||||||
const user = useAuthStore.getState();
|
const user = useAuthStore.getState();
|
||||||
if (state.lastSync.lastSelectedLanguage === state.lastSelectedLanguage)
|
if (state.lastSync.lastSelectedLanguage === state.lastSelectedLanguage)
|
||||||
|
|
Loading…
Reference in a new issue