From d1a42c4b57ac6fca260d73cc6939be07a394aadd Mon Sep 17 00:00:00 2001 From: Simon Date: Fri, 10 Jan 2025 17:09:11 +0700 Subject: [PATCH] handle cookie through text form, #856 --- backend/appsettings/views.py | 52 +++++++++------ frontend/src/api/actions/deleteCookie.ts | 10 +++ frontend/src/api/actions/updateCookie.ts | 14 ++--- frontend/src/api/actions/validateCookie.ts | 10 +++ frontend/src/api/loader/loadCookie.ts | 14 +++++ frontend/src/pages/SettingsApplication.tsx | 73 +++++++++++++++++++++- 6 files changed, 143 insertions(+), 30 deletions(-) create mode 100644 frontend/src/api/actions/deleteCookie.ts create mode 100644 frontend/src/api/actions/validateCookie.ts create mode 100644 frontend/src/api/loader/loadCookie.ts diff --git a/backend/appsettings/views.py b/backend/appsettings/views.py index 26c47acc..e847ebe4 100644 --- a/backend/appsettings/views.py +++ b/backend/appsettings/views.py @@ -189,32 +189,28 @@ class CookieView(ApiBaseView): GET: check if cookie is enabled POST: verify validity of cookie PUT: import cookie + DELETE: revoke the cookie """ permission_classes = [AdminOnly] - @staticmethod - def get(request): + def get(self, request): """handle get request""" # pylint: disable=unused-argument - config = AppConfig().config - valid = RedisArchivist().get_message_dict("cookie:valid") - response = {"cookie_enabled": config["downloads"]["cookie_import"]} - response.update(valid) + validation = self._get_cookie_validation() - return Response(response) + return Response(validation) - @staticmethod - def post(request): - """handle post request""" + def post(self, request): + """handle cookie validation request""" # pylint: disable=unused-argument config = AppConfig().config - validated = CookieHandler(config).validate() + _ = CookieHandler(config).validate() + validation = self._get_cookie_validation() - return Response({"cookie_validated": validated}) + return Response(validation) - @staticmethod - def put(request): + def put(self, request): """handle put request""" # pylint: disable=unused-argument config = AppConfig().config @@ -230,12 +226,30 @@ class CookieView(ApiBaseView): validated = handler.validate() if not validated: handler.revoke() - message = {"cookie_import": "fail", "cookie_validated": validated} - print(f"cookie: {message}") - return Response({"message": message}, status=400) + print("cookie import failed, not valid") + status = 400 + else: + status = 200 - message = {"cookie_import": "done", "cookie_validated": validated} - return Response(message) + validation = self._get_cookie_validation() + return Response(validation, status=status) + + def delete(self, request): + """delete the cookie""" + config = AppConfig().config + handler = CookieHandler(config) + handler.revoke() + return Response({"cookie_enabled": False}) + + @staticmethod + def _get_cookie_validation(): + """get current cookie validation""" + config = AppConfig().config + validation = RedisArchivist().get_message_dict("cookie:valid") + is_enabled = {"cookie_enabled": config["downloads"]["cookie_import"]} + validation.update(is_enabled) + + return validation class TokenView(ApiBaseView): diff --git a/frontend/src/api/actions/deleteCookie.ts b/frontend/src/api/actions/deleteCookie.ts new file mode 100644 index 00000000..c42b8764 --- /dev/null +++ b/frontend/src/api/actions/deleteCookie.ts @@ -0,0 +1,10 @@ +import APIClient from '../../functions/APIClient'; +import { CookieStateType } from '../loader/loadCookie'; + +const deleteCookie = async (): Promise => { + return APIClient('/api/appsettings/cookie/', { + method: 'DELETE', + }); +}; + +export default deleteCookie; diff --git a/frontend/src/api/actions/updateCookie.ts b/frontend/src/api/actions/updateCookie.ts index 0e04d172..7eee5a22 100644 --- a/frontend/src/api/actions/updateCookie.ts +++ b/frontend/src/api/actions/updateCookie.ts @@ -1,16 +1,10 @@ import APIClient from '../../functions/APIClient'; +import { CookieStateType } from '../loader/loadCookie'; -export type ValidatedCookieType = { - cookie_enabled: boolean; - status: boolean; - validated: number; - validated_str: string; - cookie_validated?: boolean; -}; - -const updateCookie = async (): Promise => { +const updateCookie = async (cookie: string): Promise => { return APIClient('/api/appsettings/cookie/', { - method: 'POST', + method: 'PUT', + body: { cookie }, }); }; diff --git a/frontend/src/api/actions/validateCookie.ts b/frontend/src/api/actions/validateCookie.ts new file mode 100644 index 00000000..2faa2f92 --- /dev/null +++ b/frontend/src/api/actions/validateCookie.ts @@ -0,0 +1,10 @@ +import APIClient from '../../functions/APIClient'; +import { CookieStateType } from '../loader/loadCookie'; + +const validateCookie = async (): Promise => { + return APIClient('/api/appsettings/cookie/', { + method: 'POST', + }); +}; + +export default validateCookie; diff --git a/frontend/src/api/loader/loadCookie.ts b/frontend/src/api/loader/loadCookie.ts new file mode 100644 index 00000000..8b94b977 --- /dev/null +++ b/frontend/src/api/loader/loadCookie.ts @@ -0,0 +1,14 @@ +import APIClient from '../../functions/APIClient'; + +export type CookieStateType = { + cookie_enabled: boolean; + status?: boolean; + validated?: number; + validated_str?: string; +}; + +const loadCookie = async (): Promise => { + return APIClient('/api/appsettings/cookie/'); +}; + +export default loadCookie; diff --git a/frontend/src/pages/SettingsApplication.tsx b/frontend/src/pages/SettingsApplication.tsx index c3166b52..0267ca8b 100644 --- a/frontend/src/pages/SettingsApplication.tsx +++ b/frontend/src/pages/SettingsApplication.tsx @@ -13,6 +13,10 @@ import updateAppsettingsConfig from '../api/actions/updateAppsettingsConfig'; import loadApiToken from '../api/loader/loadApiToken'; import InputConfig from '../components/InputConfig'; import ToggleConfig from '../components/ToggleConfig'; +import updateCookie from '../api/actions/updateCookie'; +import loadCookie, { CookieStateType } from '../api/loader/loadCookie'; +import deleteCookie from '../api/actions/deleteCookie'; +import validateCookie from '../api/actions/validateCookie'; type SnapshotType = { id: string; @@ -35,6 +39,7 @@ type SettingsApplicationReponses = { snapshots?: SnapshotListType; appSettingsConfig?: AppSettingsConfigType; apiToken?: string; + cookieState: CookieStateType; }; const SettingsApplication = () => { @@ -74,6 +79,8 @@ const SettingsApplication = () => { const [commentsSort, setCommentsSort] = useState(''); // Cookie + const [cookieFormData, setCookieFormData] = useState(''); + const [showCookieForm, setShowCookieForm] = useState(false); // const [cookieImport, setCookieImport] = useState(false); // const [validatingCookie, setValidatingCookie] = useState(false); // const [cookieResponse, setCookieResponse] = useState(); @@ -92,6 +99,7 @@ const SettingsApplication = () => { const snapshotResponse = await loadSnapshots(); const appSettingsConfig = await loadAppsettingsConfig(); const apiToken = await loadApiToken(); + const cookieState = await loadCookie(); // Subscriptions setVideoPageSize(appSettingsConfig.subscriptions.channel_size); @@ -135,6 +143,7 @@ const SettingsApplication = () => { snapshots: snapshotResponse, appSettingsConfig, apiToken: apiToken.token, + cookieState, }); }; @@ -146,6 +155,23 @@ const SettingsApplication = () => { setRefresh(true); }; + const handleCookieUpdate = async () => { + await updateCookie(cookieFormData); + setCookieFormData(''); + setShowCookieForm(false); + setRefresh(true); + }; + + const handleCookieRevoke = async () => { + await deleteCookie(); + setRefresh(true); + }; + + const handleCookieValidate = async () => { + await validateCookie(); + setRefresh(true); + }; + useEffect(() => { fetchData(); }, []); @@ -436,7 +462,52 @@ const SettingsApplication = () => {
-
+
+
+

Use your cookie for yt-dlp

+
+
+ {response?.cookieState?.cookie_enabled ? ( + <> +

+ Cookie enabled. Last validation:{' '} + + {response.cookieState.validated_str} + + . +

+
+ + +
+ + ) : ( +

Cookie disabled

+ )} + {showCookieForm ? ( + <> +