-
Notifications
You must be signed in to change notification settings - Fork 70
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
9a05f2e
commit f6f8771
Showing
1 changed file
with
60 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,44 +1,85 @@ | ||
// this file includes the session management logic for | ||
// creating, verifying, and deleting sessions with server-side tokens. | ||
// This file includes the session management logic | ||
|
||
'server-only'; | ||
import 'server-only'; | ||
|
||
import { db } from '@/drizzle/db'; | ||
import { sessions } from '@/drizzle/schema'; | ||
import jwt from 'jsonwebtoken'; | ||
import { cookies } from 'next/headers'; | ||
import { eq } from 'drizzle-orm'; | ||
|
||
// TODO: Replace with secret key from environment variables | ||
const secretKey = 'yourSecretKey'; | ||
|
||
// Option 1: Client-side stateless session with cookies | Optimistic auth check | ||
// Option 2: Server-side sessions with tokens stored in a database | Secure auth check | ||
|
||
export async function createSession(id: number) { | ||
const token = jwt.sign({ id }, secretKey, { | ||
expiresIn: '1h', | ||
}); | ||
|
||
// Option 1: Storing server-side tokens | ||
const expiresAt = new Date(Date.now() + 60 * 60 * 1000); | ||
|
||
const serverToken = await db | ||
.insert(sessions) | ||
.values({ | ||
userId: id, | ||
token, | ||
expiresAt, | ||
}) | ||
.returning({ token: sessions.token }); | ||
|
||
// Option 2: Stateless session | ||
// Option 1: Send cookie from server to client | ||
cookies().set('token', token, { | ||
httpOnly: true, | ||
secure: true, | ||
expires: new Date(Date.now() + 3600), | ||
expires: expiresAt, | ||
sameSite: 'lax', | ||
path: '/', | ||
}); | ||
|
||
// Option 2: Store token in database | ||
await db.insert(sessions).values({ | ||
userId: id, | ||
token, | ||
expiresAt, | ||
}); | ||
} | ||
|
||
// Option 1: Optimistically check for token in cookies | ||
export async function verifyClientSession() { | ||
const token = cookies().get('token')?.value; | ||
|
||
if (!token) return null; | ||
|
||
const { id } = jwt.verify(token, secretKey) as { id: number }; | ||
|
||
return { isAuth: true, userId: id }; | ||
} | ||
|
||
export async function verifySession() {} | ||
// Option 2: Securely check for token in the database | ||
export async function verifyServerSession() { | ||
const token = cookies().get('token')?.value; | ||
|
||
if (!token) return null; | ||
|
||
// This is nuts | ||
try { | ||
const data = await db | ||
.select({ | ||
expiresAt: sessions.expiresAt, | ||
userId: sessions.userId, | ||
}) | ||
.from(sessions) | ||
.where(eq(sessions.token, token)); | ||
|
||
export function updateSession() {} | ||
if (!data || data[0].expiresAt < new Date()) return null; | ||
|
||
return { isAuth: true, userId: data[0].userId }; | ||
} catch (error) { | ||
return null; | ||
} | ||
} | ||
|
||
export function deleteSesssion() {} | ||
export function updateSession() { | ||
// Option 1 | ||
// Option 2 | ||
} | ||
|
||
export function deleteSession() { | ||
// Option 1 | ||
cookies().delete('token'); | ||
|
||
// Option 2 | ||
} |