Files
saladeaula.digital/apps/studio.saladeaula.digital/app/middleware/auth.ts

70 lines
1.9 KiB
TypeScript

import { userContext } from '@/context'
import { createSessionStorage } from '@/lib/session'
import { createAuth, type User } from '@/lib/auth'
import { decodeJwt } from 'jose'
import { redirect, type LoaderFunctionArgs } from 'react-router'
import type { OAuth2Strategy } from 'remix-auth-oauth2'
export const authMiddleware = async (
{ request, context }: LoaderFunctionArgs,
next
): Promise<Response> => {
const sessionStorage = createSessionStorage(context.cloudflare.env)
const authenticator = createAuth(context.cloudflare.env)
const strategy = authenticator.get<OAuth2Strategy<User>>('oidc')
const session = await sessionStorage.getSession(request.headers.get('cookie'))
let user = session.get('user') as User | null
session.set('returnTo', new URL(request.url).toString())
if (!user) {
console.log('There is no user logged in')
return redirect('/login', {
headers: new Headers({
'Set-Cookie': await sessionStorage.commitSession(session)
})
})
}
try {
const accessToken = decodeJwt(user.accessToken) as { exp: number }
const exp = accessToken.exp * 1000
const leeway = 30 * 1000
if (Date.now() > exp - leeway) {
// @ts-ignore
const tokens = await strategy.refreshToken(user.refreshToken)
user = {
...user,
accessToken: tokens.accessToken(),
refreshToken: tokens.refreshToken()
}
session.set('user', user)
}
} catch (error) {
console.error(error)
// If refreshing the token fails, remove the user from the current session
// so the user is forced to sign in again
session.unset('user')
return redirect('/', {
headers: new Headers({
'Set-Cookie': await sessionStorage.commitSession(session)
})
})
}
context.set(userContext, user)
const response = await next()
response.headers.set(
'Set-Cookie',
await sessionStorage.commitSession(session)
)
return response
}