forked from nextjs/saas-starter
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsession.ts
More file actions
61 lines (53 loc) · 1.67 KB
/
session.ts
File metadata and controls
61 lines (53 loc) · 1.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import { compare, hash } from 'bcryptjs';
import { SignJWT, jwtVerify } from 'jose';
import { cookies } from 'next/headers';
import { cache } from 'react';
import { NewUser } from '@/lib/db/schema';
const key = new TextEncoder().encode(process.env.AUTH_SECRET);
const SALT_ROUNDS = 10;
export async function hashPassword(password: string) {
return hash(password, SALT_ROUNDS);
}
export async function comparePasswords(
plainTextPassword: string,
hashedPassword: string
) {
return compare(plainTextPassword, hashedPassword);
}
type SessionData = {
user: { id: number };
expires: string;
};
export async function signToken(payload: SessionData) {
return await new SignJWT(payload)
.setProtectedHeader({ alg: 'HS256' })
.setIssuedAt()
.setExpirationTime('1 day from now')
.sign(key);
}
// ⚡ OPTIMIZATION: Memoize JWT verification to avoid redundant decoding/verification in the same request.
export const verifyToken = cache(async (input: string) => {
const { payload } = await jwtVerify(input, key, {
algorithms: ['HS256'],
});
return payload as SessionData;
});
export async function getSession() {
const session = (await cookies()).get('session')?.value;
if (!session) return null;
return await verifyToken(session);
}
export async function setSession(user: NewUser) {
const expiresInOneDay = new Date(Date.now() + 24 * 60 * 60 * 1000);
const session: SessionData = {
user: { id: user.id! },
expires: expiresInOneDay.toISOString(),
};
const encryptedSession = await signToken(session);
(await cookies()).set('session', encryptedSession, {
expires: expiresInOneDay,
httpOnly: true,
secure: true,
sameSite: 'lax',
});
}