From 2c8a602aa7e4b65d9365aa138dd702538571996c Mon Sep 17 00:00:00 2001 From: LASER-Yi Date: Tue, 23 Aug 2022 23:13:46 +0800 Subject: [PATCH] Improve authentication and fix #1901 --- frontend/src/App/index.tsx | 6 ++++-- frontend/src/apis/hooks/system.ts | 4 ++-- frontend/src/apis/raw/client.ts | 19 +++++++++++++------ frontend/src/modules/socketio/index.ts | 20 ++++++++++++++++++++ frontend/src/types/window.d.ts | 2 +- frontend/src/utilities/event.ts | 4 ++-- 6 files changed, 42 insertions(+), 13 deletions(-) diff --git a/frontend/src/App/index.tsx b/frontend/src/App/index.tsx index c3451ae0b..09a8ef792 100644 --- a/frontend/src/App/index.tsx +++ b/frontend/src/App/index.tsx @@ -24,8 +24,10 @@ const App: FunctionComponent = () => { setCriticalError(detail.message); }); - useWindowEvent("app-login-required", () => { - navigate("/login"); + useWindowEvent("app-auth-changed", (ev) => { + if (!ev.detail.authenticated) { + navigate("/login"); + } }); useWindowEvent("app-online-status", ({ detail }) => { diff --git a/frontend/src/apis/hooks/system.ts b/frontend/src/apis/hooks/system.ts index 96af55849..24691c4b6 100644 --- a/frontend/src/apis/hooks/system.ts +++ b/frontend/src/apis/hooks/system.ts @@ -1,5 +1,5 @@ import { Environment } from "@/utilities"; -import { setLoginRequired } from "@/utilities/event"; +import { setAuthenticated } from "@/utilities/event"; import { useMemo } from "react"; import { useMutation, useQuery, useQueryClient } from "react-query"; import { QueryKeys } from "../queries/keys"; @@ -173,7 +173,7 @@ export function useSystem() { () => api.system.logout(), { onSuccess: () => { - setLoginRequired(); + setAuthenticated(false); client.clear(); }, } diff --git a/frontend/src/apis/raw/client.ts b/frontend/src/apis/raw/client.ts index 5bdcf5888..5f9f4eb26 100644 --- a/frontend/src/apis/raw/client.ts +++ b/frontend/src/apis/raw/client.ts @@ -1,7 +1,7 @@ -import SocketIO from "@/modules/socketio"; +import socketio from "@/modules/socketio"; import { notification } from "@/modules/task"; import { LOG } from "@/utilities/console"; -import { setLoginRequired } from "@/utilities/event"; +import { setAuthenticated } from "@/utilities/event"; import { showNotification } from "@mantine/notifications"; import Axios, { AxiosError, AxiosInstance, CancelTokenSource } from "axios"; import { Environment } from "../../utilities"; @@ -17,17 +17,19 @@ function GetErrorMessage(data: unknown, defaultMsg = "Unknown error"): string { class BazarrClient { axios!: AxiosInstance; source!: CancelTokenSource; + bIsAuthenticated: boolean; constructor() { + this.bIsAuthenticated = false; const baseUrl = `${Environment.baseUrl}/api/`; - LOG("info", "initializing BazarrClient with", baseUrl); - this.initialize(baseUrl, Environment.apiKey); - SocketIO.initialize(); + socketio.initialize(); } initialize(url: string, apikey?: string) { + LOG("info", "initializing BazarrClient with baseUrl", url); + this.axios = Axios.create({ baseURL: url, }); @@ -45,6 +47,10 @@ class BazarrClient { this.axios.interceptors.response.use( (resp) => { if (resp.status >= 200 && resp.status < 300) { + if (!this.bIsAuthenticated) { + this.bIsAuthenticated = true; + setAuthenticated(true); + } return Promise.resolve(resp); } else { const error: BackendError = { @@ -78,7 +84,8 @@ class BazarrClient { const { code, message } = error; switch (code) { case 401: - setLoginRequired(); + this.bIsAuthenticated = false; + setAuthenticated(false); return; } LOG("error", "A error has occurred", code); diff --git a/frontend/src/modules/socketio/index.ts b/frontend/src/modules/socketio/index.ts index abd5fb0f6..18934b39a 100644 --- a/frontend/src/modules/socketio/index.ts +++ b/frontend/src/modules/socketio/index.ts @@ -51,10 +51,30 @@ class SocketIOClient { } initialize() { + LOG("info", "Initializing Socket.IO client..."); this.reducers.push(...createDefaultReducer()); + + window.addEventListener("app-auth-changed", (ev) => { + const authenticated = ev.detail.authenticated; + LOG("info", "Authentication status change to", authenticated); + if (authenticated) { + this.connect(); + } else { + this.disconnect(); + } + }); + } + + connect() { + LOG("info", "Connecting Socket.IO client..."); this.socket.connect(); } + disconnect() { + LOG("info", "Disconnecting Socket.IO client..."); + this.socket.disconnect(); + } + addReducer(reducer: SocketIO.Reducer) { this.reducers.push(reducer); } diff --git a/frontend/src/types/window.d.ts b/frontend/src/types/window.d.ts index 170fc2b4b..9f320e9d9 100644 --- a/frontend/src/types/window.d.ts +++ b/frontend/src/types/window.d.ts @@ -10,8 +10,8 @@ declare global { } interface WindowEventMap { + "app-auth-changed": CustomEvent<{ authenticated: boolean }>; "app-critical-error": CustomEvent<{ message: string }>; - "app-login-required": CustomEvent; "app-online-status": CustomEvent<{ online: boolean }>; } } diff --git a/frontend/src/utilities/event.ts b/frontend/src/utilities/event.ts index b75fc83e7..60fbd63e1 100644 --- a/frontend/src/utilities/event.ts +++ b/frontend/src/utilities/event.ts @@ -7,8 +7,8 @@ function createEvent< return new CustomEvent

(event, { bubbles: true, detail: payload }); } -export function setLoginRequired() { - const event = createEvent("app-login-required", {}); +export function setAuthenticated(authenticated: boolean) { + const event = createEvent("app-auth-changed", { authenticated }); window.dispatchEvent(event); }