Browse Source

fix: change useBackendUrl to possibly be undefined, add checks to avoid useless requests to nonexistent backend

pull/938/head
qtchaos 1 year ago
parent
commit
fcf42a4e8a
No known key found for this signature in database
GPG Key ID: 7DA98B2B9EF06A90
  1. 2
      src/backend/accounts/progress.ts
  2. 6
      src/hooks/auth/useAuth.ts
  3. 2
      src/hooks/auth/useBackendUrl.ts
  4. 3
      src/pages/Settings.tsx
  5. 2
      src/pages/onboarding/OnboardingProxy.tsx
  6. 14
      src/pages/parts/admin/BackendTestPart.tsx
  7. 3
      src/pages/parts/auth/LoginFormPart.tsx
  8. 6
      src/pages/parts/auth/TrustBackendPart.tsx
  9. 5
      src/pages/parts/auth/VerifyPassphrasePart.tsx
  10. 2
      src/pages/parts/settings/AccountActionsPart.tsx
  11. 1
      src/pages/parts/settings/DeviceListPart.tsx
  12. 7
      src/pages/parts/settings/SidebarPart.tsx
  13. 1
      src/stores/bookmarks/BookmarkSyncer.tsx
  14. 1
      src/stores/progress/ProgressSyncer.tsx
  15. 1
      src/stores/subtitles/SettingsSyncer.tsx

2
src/backend/accounts/progress.ts

@ -2,7 +2,6 @@ import { ofetch } from "ofetch"; @@ -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( @@ -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),

6
src/hooks/auth/useAuth.ts

@ -63,6 +63,7 @@ export function useAuth() { @@ -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() { @@ -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() { @@ -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() { @@ -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() { @@ -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);

2
src/hooks/auth/useBackendUrl.ts

@ -1,7 +1,7 @@ @@ -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;
}

3
src/pages/Settings.tsx

@ -70,6 +70,7 @@ export function AccountSettings(props: { @@ -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() { @@ -144,7 +145,7 @@ export function SettingsPage() {
);
const saveChanges = useCallback(async () => {
if (account) {
if (account && backendUrl) {
if (
state.appLanguage.changed ||
state.theme.changed ||

2
src/pages/onboarding/OnboardingProxy.tsx

@ -43,7 +43,7 @@ export function OnboardingProxyPage() { @@ -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],
});

14
src/pages/parts/admin/BackendTestPart.tsx

@ -32,13 +32,21 @@ export function BackendTestPart() { @@ -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() { @@ -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,
});
}

3
src/pages/parts/auth/LoginFormPart.tsx

@ -52,6 +52,9 @@ export function LoginFormPart(props: LoginFormPartProps) { @@ -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);

6
src/pages/parts/auth/TrustBackendPart.tsx

@ -22,8 +22,12 @@ interface TrustBackendPartProps { @@ -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();

5
src/pages/parts/auth/VerifyPassphrasePart.tsx

@ -47,6 +47,8 @@ export function VerifyPassphrase(props: VerifyPassphraseProps) { @@ -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) { @@ -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, {

2
src/pages/parts/settings/AccountActionsPart.tsx

@ -18,7 +18,7 @@ export function AccountActionsPart() { @@ -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();

1
src/pages/parts/settings/DeviceListPart.tsx

@ -24,6 +24,7 @@ export function Device(props: { @@ -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]);

7
src/pages/parts/settings/SidebarPart.tsx

@ -14,9 +14,9 @@ import { useAuthStore } from "@/stores/auth"; @@ -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() { @@ -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() { @@ -159,7 +160,7 @@ export function SidebarPart() {
<SecureBadge url={backendUrl} />
</div>
<p className="text-white">
{backendUrl.replace(/https?:\/\//, "")}
{backendUrl?.replace(/https?:\/\//, "") ?? "—"}
</p>
</div>

1
src/stores/bookmarks/BookmarkSyncer.tsx

@ -60,6 +60,7 @@ export function BookmarkSyncer() { @@ -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(

1
src/stores/progress/ProgressSyncer.tsx

@ -62,6 +62,7 @@ export function ProgressSyncer() { @@ -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(

1
src/stores/subtitles/SettingsSyncer.tsx

@ -16,6 +16,7 @@ export function SettingsSyncer() { @@ -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…
Cancel
Save