From ccb265cb2e2624492390fbd4fc3cc7f9afb0c500 Mon Sep 17 00:00:00 2001 From: Rakov Date: Wed, 4 Oct 2023 17:13:58 +0300 Subject: [PATCH 1/2] Revert "fix(#699): auth token" This reverts commit fc3a3c052c5667985c24a7d4425b60d618dcc43e. --- public/silent-refresh.html | 41 +++---------------- src/features/AuthStore/hooks/useAuth.tsx | 28 ++----------- src/features/SystemSettings/hooks.tsx | 1 - src/helpers/cookie/index.tsx | 2 +- src/requests/getCredentials.tsx | 51 ------------------------ 5 files changed, 9 insertions(+), 114 deletions(-) delete mode 100644 src/requests/getCredentials.tsx diff --git a/public/silent-refresh.html b/public/silent-refresh.html index 56cfb515..852cc138 100644 --- a/public/silent-refresh.html +++ b/public/silent-refresh.html @@ -1,46 +1,15 @@ - - - + - - \ No newline at end of file + diff --git a/src/features/AuthStore/hooks/useAuth.tsx b/src/features/AuthStore/hooks/useAuth.tsx index 41ec48e9..115a0a28 100644 --- a/src/features/AuthStore/hooks/useAuth.tsx +++ b/src/features/AuthStore/hooks/useAuth.tsx @@ -14,7 +14,7 @@ import isString from 'lodash/isString' import isBoolean from 'lodash/isBoolean' import includes from 'lodash/includes' -import { PAGES, isIOS } from 'config' +import { PAGES } from 'config' import { addLanguageUrlParam, @@ -24,7 +24,6 @@ import { setCookie, removeCookie, isMatchPage, - getDomain, } from 'helpers' import { @@ -66,14 +65,6 @@ export const useAuth = () => { }) } - const parseJwt = (value: string) => { - const base64Url = value.split('.')[1] - const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/') - const jsonPayload = decodeURIComponent(window.atob(base64).split('').map((c) => `%${(`00${c.charCodeAt(0).toString(16)}`).slice(-2)}`).join('')) - - return JSON.parse(jsonPayload) - } - const login = useCallback(async () => { userManager.signinRedirect({ extraQueryParams: { lang } }) }, [lang]) @@ -88,7 +79,6 @@ export const useAuth = () => { removeToken() if (key !== 'saveToken') { removeCookie('access_token') - removeCookie('refresh_token') } // eslint-disable-next-line react-hooks/exhaustive-deps }, [lang]) @@ -168,21 +158,12 @@ export const useAuth = () => { } } - const saveRefreshToken = (value: string) => { - const ref = parseJwt(value) - const expires = `expires=${new Date((ref.exp * 1000)).toUTCString()}` - document.cookie = `refresh_token=${value};${expires};path=/;domain=${getDomain()};secure;SameSite=None` - } - - const signinRedirectCallback = useCallback(async (refreshToken: string | null) => { + const signinRedirectCallback = useCallback(() => { setPage(history.location.pathname) userManager.signinRedirectCallback() .then((loadedUser) => { storeUser(loadedUser) - - if (isIOS && refreshToken) saveRefreshToken(refreshToken) - queryParamStorage.clear() if (page.includes(PAGES.useraccount)) { history.push(PAGES.home) @@ -206,13 +187,10 @@ export const useAuth = () => { const searchToken = urlSearch.get('access_token') const searchRefToken = urlSearch.get('id_token') const searchExp = urlSearch.get('expires_in') - const refreshToken = urlSearch.get('refresh_token') const isRedirectedBackFromAuthProvider = Boolean(searchToken && searchRefToken && searchExp) - isRedirectedBackFromAuthProvider - ? signinRedirectCallback(refreshToken) - : checkUser() + isRedirectedBackFromAuthProvider ? signinRedirectCallback() : checkUser() // eslint-disable-next-line react-hooks/exhaustive-deps }, [ checkUser, diff --git a/src/features/SystemSettings/hooks.tsx b/src/features/SystemSettings/hooks.tsx index fb200f3e..8ab7df2e 100644 --- a/src/features/SystemSettings/hooks.tsx +++ b/src/features/SystemSettings/hooks.tsx @@ -38,7 +38,6 @@ export const useSystemSettings = () => { setSelectedApi(api.value) removeToken() removeCookie('access_token') - removeCookie('refresh_token') window.location.reload() } diff --git a/src/helpers/cookie/index.tsx b/src/helpers/cookie/index.tsx index 87b22f22..cbad2d33 100644 --- a/src/helpers/cookie/index.tsx +++ b/src/helpers/cookie/index.tsx @@ -29,7 +29,7 @@ export const checkCookie = (name: string) => { return token[0] } -export const getDomain = () => ( +const getDomain = () => ( process.env.NODE_ENV === 'development' ? 'localhost' : '.insports.tv' diff --git a/src/requests/getCredentials.tsx b/src/requests/getCredentials.tsx deleted file mode 100644 index dce5eb7e..00000000 --- a/src/requests/getCredentials.tsx +++ /dev/null @@ -1,51 +0,0 @@ -import { AUTH_SERVICE } from 'config' -import { ClientIds } from 'config/clients/types' - -export type TokenFailedResponse = { - error?: { - code: number, - message: string, - }, - ok: false, -} - -type TokenResponse = { - access_token: string, - id_token: string, - refresh_token: string, -} - -type TokenProps = { - client_id: ClientIds, - email?: 'string', - grant_type?: 'password' | 'refresh_token', - id_token?: 'string', - password?: 'string', - refresh_token: string, -} - -export const getCredentials = async ({ - client_id, - grant_type = 'refresh_token', - refresh_token, -}: TokenProps): Promise => { - const url = new URL(`${AUTH_SERVICE}/token`) - - const credetials = await fetch(url, { - body: JSON.stringify({ - client_id, - grant_type, - refresh_token, - }), - headers: { - 'Content-Type': 'application/json', - }, - method: 'POST', - }) - - const body: TokenResponse | TokenFailedResponse = await credetials.json() - - if ('ok' in body) return Promise.reject(body.error) - - return Promise.resolve(body) -} -- 2.30.2 From 7a2423568aba3cebd4f5a8ff7001deba135c80d7 Mon Sep 17 00:00:00 2001 From: Rakov Date: Thu, 5 Oct 2023 10:42:32 +0300 Subject: [PATCH 2/2] fix(refresh): save refresh lff facr --- public/silent-refresh.html | 23 ++++++++++---- src/features/AuthStore/hooks/useAuth.tsx | 38 +++++++++++++++++++----- src/features/SystemSettings/hooks.tsx | 5 ++-- src/helpers/token/index.tsx | 13 ++++++++ 4 files changed, 65 insertions(+), 14 deletions(-) diff --git a/public/silent-refresh.html b/public/silent-refresh.html index 852cc138..840a0cce 100644 --- a/public/silent-refresh.html +++ b/public/silent-refresh.html @@ -1,15 +1,28 @@ + + - + - + + \ No newline at end of file diff --git a/src/features/AuthStore/hooks/useAuth.tsx b/src/features/AuthStore/hooks/useAuth.tsx index 115a0a28..965206b9 100644 --- a/src/features/AuthStore/hooks/useAuth.tsx +++ b/src/features/AuthStore/hooks/useAuth.tsx @@ -14,7 +14,11 @@ import isString from 'lodash/isString' import isBoolean from 'lodash/isBoolean' import includes from 'lodash/includes' -import { PAGES } from 'config' +import { + PAGES, + isFacrClient, + isLffClient, +} from 'config' import { addLanguageUrlParam, @@ -24,6 +28,10 @@ import { setCookie, removeCookie, isMatchPage, + REFRESH_TOKEN_KEY, + removeRefreshToken, + writeRefreshToken, + readRefreshToken, } from 'helpers' import { @@ -77,6 +85,7 @@ export const useAuth = () => { userManager.signoutRedirect({ post_logout_redirect_uri: urlWithLang }) }) removeToken() + removeRefreshToken() if (key !== 'saveToken') { removeCookie('access_token') } @@ -158,12 +167,18 @@ export const useAuth = () => { } } - const signinRedirectCallback = useCallback(() => { + const signinRedirectCallback = useCallback(async (refreshToken: string | null) => { setPage(history.location.pathname) userManager.signinRedirectCallback() .then((loadedUser) => { storeUser(loadedUser) + + if ( + refreshToken + && (isLffClient || isFacrClient) + ) writeRefreshToken(refreshToken) + queryParamStorage.clear() if (page.includes(PAGES.useraccount)) { history.push(PAGES.home) @@ -175,7 +190,7 @@ export const useAuth = () => { setPage('') setSearch('') }).catch(login) - // eslint-disable-next-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks/exhaustive-deps }, [ login, storeUser, @@ -187,11 +202,14 @@ export const useAuth = () => { const searchToken = urlSearch.get('access_token') const searchRefToken = urlSearch.get('id_token') const searchExp = urlSearch.get('expires_in') + const refreshToken = urlSearch.get(REFRESH_TOKEN_KEY) const isRedirectedBackFromAuthProvider = Boolean(searchToken && searchRefToken && searchExp) - isRedirectedBackFromAuthProvider ? signinRedirectCallback() : checkUser() - // eslint-disable-next-line react-hooks/exhaustive-deps + isRedirectedBackFromAuthProvider + ? signinRedirectCallback(refreshToken) + : checkUser() + // eslint-disable-next-line react-hooks/exhaustive-deps }, [ checkUser, signinRedirectCallback, @@ -221,7 +239,7 @@ export const useAuth = () => { }, [reChekNewDevice]) useEffect(() => { - if (!needCheckNewDeviсe && !user) return undefined + if (!needCheckNewDeviсe || !user) return undefined const startCheckDevice = setInterval(checkNewDevice, 20000) isNewDeviceLogin && clearInterval(startCheckDevice) return () => clearInterval(startCheckDevice) @@ -240,7 +258,13 @@ export const useAuth = () => { // библиотека oidc-client не поддерживает обновление токена только на 1 вкладке // @ts-ignore if (window.isMaster()) { - userManager.signinSilent().catch(logout) + // safari ограничивает доступ к куке через крос доменные запросы + // передаем рефреш токен через квери параметры + userManager.signinSilent({ + extraQueryParams: (isLffClient || isFacrClient) && { + refresh_token: readRefreshToken(), + }, + }).catch(logout) } } // если запросы вернули 401 | 403 diff --git a/src/features/SystemSettings/hooks.tsx b/src/features/SystemSettings/hooks.tsx index 8ab7df2e..575d7168 100644 --- a/src/features/SystemSettings/hooks.tsx +++ b/src/features/SystemSettings/hooks.tsx @@ -9,8 +9,8 @@ import { SELECTED_API_KEY } from 'helpers/selectedApi' import { useToggle } from 'hooks/useToggle' import { useLocalStore } from 'hooks/useStorage' -import { removeToken } from '../../helpers' -import { removeCookie } from '../../helpers/cookie' +import { removeRefreshToken, removeToken } from 'helpers' +import { removeCookie } from 'helpers/cookie' type FormElement = HTMLFormElement & { api: HTMLInputElement & { @@ -37,6 +37,7 @@ export const useSystemSettings = () => { const { api } = e.currentTarget setSelectedApi(api.value) removeToken() + removeRefreshToken() removeCookie('access_token') window.location.reload() } diff --git a/src/helpers/token/index.tsx b/src/helpers/token/index.tsx index 0c4e59f8..6665e79e 100644 --- a/src/helpers/token/index.tsx +++ b/src/helpers/token/index.tsx @@ -1,4 +1,5 @@ export const TOKEN_KEY = 'token' +export const REFRESH_TOKEN_KEY = 'refresh_token' export const readToken = () => ( localStorage.getItem(TOKEN_KEY) @@ -11,3 +12,15 @@ export const writeToken = (token: string) => ( export const removeToken = () => ( localStorage.removeItem(TOKEN_KEY) ) + +export const removeRefreshToken = () => { + localStorage.removeItem(REFRESH_TOKEN_KEY) +} + +export const writeRefreshToken = (token: string) => ( + localStorage.setItem(REFRESH_TOKEN_KEY, token) +) + +export const readRefreshToken = () => ( + localStorage.getItem(REFRESH_TOKEN_KEY) +) -- 2.30.2