From 315829717f0b00250687dbf9e8204cf894c065d2 Mon Sep 17 00:00:00 2001 From: Samuel Ojo <88172184+greatsamist@users.noreply.github.com> Date: Fri, 26 Jul 2024 10:59:12 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9A=A1fixes=20#746=20App=20takes=20you=20to?= =?UTF-8?q?=20login=20screen=20after=20being=20logged=20in=20for=20a=20whi?= =?UTF-8?q?le=20(#817)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # 😵 Post-Mortem 😵 Fixes #746 ## Summary Fixed a bug that takes users to the login screen after being logged in for a while. ## Impact - **Services Affected**:Authentication service, user session management - **User Impact**: Users will no longer be unexpectedly logged out after an hour of inactivity. This change improves user experience by extending the session duration to 30 days. ## Root Cause Analysis The Privy token was set to expire after an hour, causing users to be redirected to the login screen to log in again after the token expired. ## Resolution and Recovery Instead of using the auth token, we now use the Privy refresh token. The Privy refresh token takes 30 days to expire, can only be used once, and is refreshed with a new one upon use. This change ensures that users remain logged in for up to 30 days without interruption. ## Lessons Learned 1. Ensure token expiration times are aligned with user session expectations to avoid unexpected logouts. 2. Implement a refresh token strategy to extend session durations securely. 3. Regularly review and update authentication and session management strategies to enhance user experience and security --- .../authorization/CheckAuthorization.tsx | 7 +------ .../app/components/misc/SignInUserButton.tsx | 17 ++++++++++++++++- packages/app/package.json | 4 ++-- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/packages/app/components/authorization/CheckAuthorization.tsx b/packages/app/components/authorization/CheckAuthorization.tsx index f7eaf49f5..5bec0515c 100644 --- a/packages/app/components/authorization/CheckAuthorization.tsx +++ b/packages/app/components/authorization/CheckAuthorization.tsx @@ -2,7 +2,6 @@ import { apiUrl } from '@/lib/utils/utils'; import { cookies } from 'next/headers'; const CheckAuthorization = async () => { - const privyToken = cookies().get('privy-token'); const userSession = cookies().get('user-session'); const userAddress = cookies().get('user-address'); const res = await fetch(`${apiUrl()}/auth/verify-token`, { @@ -14,12 +13,8 @@ const CheckAuthorization = async () => { headers: { 'Content-Type': 'application/json' }, }); const resData = await res.json(); - const isAuthorized = - !!userAddress?.value && - !!privyToken?.value && - !!userSession?.value && - resData.data; + !!userAddress?.value && !!userSession?.value && resData.data; return isAuthorized; }; diff --git a/packages/app/components/misc/SignInUserButton.tsx b/packages/app/components/misc/SignInUserButton.tsx index 15d24e736..08410f4ec 100644 --- a/packages/app/components/misc/SignInUserButton.tsx +++ b/packages/app/components/misc/SignInUserButton.tsx @@ -4,7 +4,7 @@ import { useLogin, useLogout, usePrivy } from '@privy-io/react-auth'; import { deleteSession, storeSession } from '@/lib/actions/auth'; import { apiUrl } from '@/lib/utils/utils'; import { Loader2 } from 'lucide-react'; -import { useState } from 'react'; +import React, { useEffect, useState } from 'react'; interface SignInUserButtonProps { className?: string; @@ -18,6 +18,11 @@ export const SignInUserButton = ({ const { ready, authenticated } = usePrivy(); const [isLoading, setIsLoading] = useState(false); + const privyRefreshToken = localStorage.getItem('privy:refresh_token'); + const parsePrivyRefreshToken = privyRefreshToken + ? JSON.parse(privyRefreshToken) + : null; + const getSession = async () => { const privyToken = localStorage.getItem('privy:token'); const token = privyToken ? JSON.parse(privyToken) : null; @@ -36,6 +41,16 @@ export const SignInUserButton = ({ }); }; + useEffect(() => { + if (!parsePrivyRefreshToken) logout(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [parsePrivyRefreshToken]); + + useEffect(() => { + if (!parsePrivyRefreshToken) logout(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [parsePrivyRefreshToken]); + const { login } = useLogin({ onComplete: () => { getSession(); diff --git a/packages/app/package.json b/packages/app/package.json index 03fe6dacb..ab1c063bc 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -17,7 +17,7 @@ "@livekit/components-react": "^1.5.3", "@livekit/components-styles": "^1.0.9", "@livepeer/react": "^4.1.8", - "@privy-io/react-auth": "^1.64.0", + "@privy-io/react-auth": "^1.76.2", "@radix-ui/react-accordion": "^1.1.2", "@radix-ui/react-alert-dialog": "^1.0.5", "@radix-ui/react-aspect-ratio": "^1.0.3", @@ -97,9 +97,9 @@ "zod": "^3.22.4" }, "devDependencies": { - "@types/lodash": "^4.17.7", "@tailwindcss/typography": "^0.5.13", "@types/fuzzy-search": "^2.1.5", + "@types/lodash": "^4.17.7", "@types/node": "20.14.11", "@types/react": "18.2.37", "@types/react-color": "^3.0.11",