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