Skip to content

Commit

Permalink
Create RefreshSession High Order Component
Browse files Browse the repository at this point in the history
The RefreshSession HOC adds 2 pieces of logic to the components:

1. it refreshes the session each 5 minutes, so if a token is expired
it will try to refresh after 5minutes.
2. it checks if the token is expired on the window focus, and if it is
expired it will try to refresh the token.

This component is basically a wrapper for those funcionalities and
it was made as a HOC instead of a hooks because it needed to be used
within `providers.tsx` but it needed to be under `SessionProvider` since
it uses the `useSession` hook.
  • Loading branch information
negreirosleo authored and dmtrek14 committed Dec 14, 2023
1 parent e4d53dd commit 2e6c68f
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 5 deletions.
38 changes: 38 additions & 0 deletions frontend/src/app/auth/RefreshSession.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { useSession } from 'next-auth/react'
import { useEffect } from 'react'

const FIVE_MINUTES_IN_MILISSECONDS = 1000 * 60 * 5

export const RefreshSession = ({ children }: { children: React.ReactNode }) => {
// update() triggers the jwt callback on next-auth/route.ts
const { update, data } = useSession({
required: true
})

// Refresh the session on a time interval
useEffect(() => {
// TIP: You can also use `navigator.onLine` and some extra event handlers
// to check if the user is online and only update the session if they are.
// https://developer.mozilla.org/en-US/docs/Web/API/Navigator/onLine
const interval = setInterval(() => update(), FIVE_MINUTES_IN_MILISSECONDS)
return () => clearInterval(interval)
}, [update])

// Refresh the session on window re-focus if the token is expired
useEffect(() => {
const visibilityHandler = () => {
if (
document.visibilityState === 'visible' &&
data?.accessTokenExpires &&
Date.now() > data.accessTokenExpires
) {
update()
}
}

window.addEventListener('visibilitychange', visibilityHandler, false)
return () => window.removeEventListener('visibilitychange', visibilityHandler, false)
}, [data, update])

return children
}
13 changes: 8 additions & 5 deletions frontend/src/app/providers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,20 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { SessionProvider } from 'next-auth/react'
import { theme } from '@/ui/theme'
import { AlertProvider } from '@/ui/Alert/AlertProvider'
import { RefreshSession } from './auth/RefreshSession'

const queryClient = new QueryClient()

export const Providers = ({ children }: { children: React.ReactNode }) => {
return (
<SessionProvider basePath="/web/v2/api/auth">
<QueryClientProvider client={queryClient}>
<AlertProvider>
<CssVarsProvider theme={theme}>{children}</CssVarsProvider>
</AlertProvider>
</QueryClientProvider>
<RefreshSession>
<QueryClientProvider client={queryClient}>
<AlertProvider>
<CssVarsProvider theme={theme}>{children}</CssVarsProvider>
</AlertProvider>
</QueryClientProvider>
</RefreshSession>
</SessionProvider>
)
}

0 comments on commit 2e6c68f

Please sign in to comment.