From a8d29b5b2688c62c7ecd9c896a886a2bce96a47f Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Sun, 31 Mar 2024 23:00:12 +0200 Subject: [PATCH] Fix authorization tokens usage on the android player --- front/packages/models/src/login.ts | 26 ++++++++++++++++++++++ front/packages/ui/src/player/video.tsx | 13 +++-------- front/packages/ui/src/player/video.web.tsx | 2 +- 3 files changed, 30 insertions(+), 11 deletions(-) diff --git a/front/packages/models/src/login.ts b/front/packages/models/src/login.ts index 17cf5c9c..9b910179 100644 --- a/front/packages/models/src/login.ts +++ b/front/packages/models/src/login.ts @@ -24,6 +24,7 @@ import { Account, Token, TokenP, getCurrentApiUrl } from "./accounts"; import { UserP } from "./resources"; import { addAccount, getCurrentAccount, removeAccounts, updateAccount } from "./account-internal"; import { Platform } from "react-native"; +import { useEffect, useRef, useState } from "react"; type Result = | { ok: true; value: A; error?: undefined } @@ -137,6 +138,31 @@ export const getTokenWJ = async ( export const getToken = async (): Promise => (await getTokenWJ())[0]; +export const useToken = () => { + const account = getCurrentAccount(); + const refresher = useRef(null); + const [token, setToken] = useState( + account ? `${account.token.token_type} ${account.token.access_token}` : null, + ); + + useEffect(() => { + async function run() { + const nToken = await getTokenWJ(); + setToken(nToken[0]); + if (refresher.current) clearTimeout(refresher.current); + if (nToken[1]) + refresher.current = setTimeout(run, nToken[1].expire_at.getTime() - Date.now()); + } + run(); + return () => { + if (refresher.current) clearTimeout(refresher.current); + }; + }, [account]); + + if (!token) return null; + return token; +}; + export const logout = () => { removeAccounts((x) => x.selected); }; diff --git a/front/packages/ui/src/player/video.tsx b/front/packages/ui/src/player/video.tsx index 4bd497ff..59ce0d4e 100644 --- a/front/packages/ui/src/player/video.tsx +++ b/front/packages/ui/src/player/video.tsx @@ -33,7 +33,7 @@ declare module "react-native-video" { export * from "react-native-video"; -import { Audio, Subtitle, getToken } from "@kyoo/models"; +import { Audio, Subtitle, getToken, useToken } from "@kyoo/models"; import { IconButton, Menu } from "@kyoo/primitives"; import { ComponentProps, forwardRef, useEffect, useRef } from "react"; import { atom, useAtom, useAtomValue, useSetAtom } from "jotai"; @@ -67,20 +67,13 @@ const Video = forwardRef(function Video( ref, ) { const { css } = useYoshiki(); - const token = useRef(null); + const token = useToken(); const setInfo = useSetAtom(infoAtom); const [video, setVideo] = useAtom(videoAtom); const audio = useAtomValue(audioAtom); const subtitle = useAtomValue(subtitleAtom); const mode = useAtomValue(playModeAtom); - useEffect(() => { - async function run() { - token.current = await getToken(); - } - run(); - }, [source]); - useEffect(() => { if (mode === PlayMode.Hls) setVideo(-1); }, [mode, setVideo]); @@ -92,7 +85,7 @@ const Video = forwardRef(function Video( source={{ ...source, headers: { - Authorization: `Bearer: ${token.current}`, + ...(token ? { Authorization: token } : {}), "X-CLIENT-ID": clientId, }, }} diff --git a/front/packages/ui/src/player/video.web.tsx b/front/packages/ui/src/player/video.web.tsx index c3f1fd02..a0454ab3 100644 --- a/front/packages/ui/src/player/video.web.tsx +++ b/front/packages/ui/src/player/video.web.tsx @@ -70,7 +70,7 @@ const initHls = (): Hls => { hls = new Hls({ xhrSetup: async (xhr) => { const token = await getToken(); - if (token) xhr.setRequestHeader("Authorization", `Bearer: ${token}`); + if (token) xhr.setRequestHeader("Authorization", token); xhr.setRequestHeader("X-CLIENT-ID", client_id); }, autoStartLoad: false,