Skip to content

Commit

Permalink
refactor: move session still exist check
Browse files Browse the repository at this point in the history
  • Loading branch information
rharkor committed May 27, 2024
1 parent cd9a4bc commit 9308a2b
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 43 deletions.
47 changes: 47 additions & 0 deletions apps/app/src/components/auth/require-auth.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@ import { headers } from "next/headers"
import { redirect } from "next/navigation"
import { NextResponse } from "next/server"
import { getServerSession } from "next-auth"
import { z } from "zod"

import { sessionsSchema } from "@/api/me/schemas"
import { authRoutes } from "@/constants/auth"
import { nextAuthOptions } from "@/lib/auth"
import { redis } from "@/lib/redis"
import { logger } from "@next-boilerplate/lib"

export default async function requireAuth(callbackUrl?: string) {
Expand Down Expand Up @@ -34,5 +37,49 @@ export async function getAuthApi() {
return { session: null, error: NextResponse.json({ error: "Unauthorized" }, { status: 401 }) }
}

//* Verify that the session still exists
if (session.user?.uuid) {
const id = session.user.id
const uuid = session.user.uuid
const getRedisSession = async () => {
const key = `session:${id}:${uuid}`
const loginSession = await redis.get(key)
if (!loginSession) {
logger.debug("Session not found", uuid)
return true
}

//* Save last used at
//? Only if lastUsedAt is older than 1 minute (avoid spamming the redis server)
const data = JSON.parse(loginSession) as z.infer<ReturnType<typeof sessionsSchema>>
if (data.lastUsedAt) {
const lastUsedAt = new Date(data.lastUsedAt)
const now = new Date()
const diff = now.getTime() - lastUsedAt.getTime()
if (diff > 1000 * 60) {
return
}
}
//? Update session lastUsed
const remainingTtl = await redis.ttl(key)
//! Do not await to make the requests faster
redis.setex(
key,
remainingTtl,
JSON.stringify({
...(JSON.parse(loginSession) as object),
lastUsedAt: new Date(),
})
)
return
}
const res = await getRedisSession()

// If res is true it means that the session is not found
if (res === true) {
return { session: null, error: NextResponse.json({ error: "Unauthorized" }, { status: 401 }) }
}
}

return { session, error: null }
}
43 changes: 0 additions & 43 deletions apps/app/src/lib/auth/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,49 +194,6 @@ export const nextAuthOptions: NextAuthOptions = {
// logger.debug("User not found", token.id)
return {} as Session
}
//* Verify that the session still exists
if (dbUser.hasPassword && (!token.uuid || typeof token.uuid !== "string")) {
logger.debug("Missing token uuid")
return {} as Session
}
if (token.uuid) {
const getRedisSession = async () => {
const key = `session:${dbUser.id}:${token.uuid}`
const loginSession = await redis.get(key)
if (!loginSession) {
logger.debug("Session not found", token.uuid)
return {} as Session
}

//? Only if lastUsedAt is older than 1 minute (avoid spamming the redis server)
const data = JSON.parse(loginSession) as z.infer<ReturnType<typeof sessionsSchema>>
if (data.lastUsedAt) {
const lastUsedAt = new Date(data.lastUsedAt)
const now = new Date()
const diff = now.getTime() - lastUsedAt.getTime()
if (diff > 1000 * 60) {
return
}
}
//? Update session lastUsed
const remainingTtl = await redis.ttl(key)
//! Do not await to make the requests faster
redis.setex(
key,
remainingTtl,
JSON.stringify({
...(JSON.parse(loginSession) as object),
lastUsedAt: new Date(),
})
)
return
}
const res = await getRedisSession()

if (res !== undefined) {
return res
}
}
//* Fill session with user data
const username = dbUser.username
const role = dbUser.role
Expand Down

0 comments on commit 9308a2b

Please sign in to comment.