feat: add password hashing and JWT utils
Made-with: Cursor
This commit is contained in:
47
src/utils/jwt.ts
Normal file
47
src/utils/jwt.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import * as jose from 'jose';
|
||||
import { env } from '../config/env.js';
|
||||
|
||||
export interface AccessPayload {
|
||||
sub: string;
|
||||
email: string;
|
||||
type: 'access';
|
||||
}
|
||||
|
||||
export interface RefreshPayload {
|
||||
sub: string;
|
||||
sid: string;
|
||||
type: 'refresh';
|
||||
}
|
||||
|
||||
type JwtPayload = AccessPayload | RefreshPayload;
|
||||
|
||||
const secret = new TextEncoder().encode(env.JWT_SECRET);
|
||||
|
||||
export async function signAccessToken(payload: Omit<AccessPayload, 'type'>): Promise<string> {
|
||||
return new jose.SignJWT({ ...payload, type: 'access' })
|
||||
.setProtectedHeader({ alg: 'HS256' })
|
||||
.setIssuedAt()
|
||||
.setExpirationTime(env.JWT_ACCESS_TTL)
|
||||
.sign(secret);
|
||||
}
|
||||
|
||||
export async function signRefreshToken(payload: Omit<RefreshPayload, 'type'>): Promise<string> {
|
||||
return new jose.SignJWT({ ...payload, type: 'refresh' })
|
||||
.setProtectedHeader({ alg: 'HS256' })
|
||||
.setIssuedAt()
|
||||
.setExpirationTime(env.JWT_REFRESH_TTL)
|
||||
.sign(secret);
|
||||
}
|
||||
|
||||
export async function verifyToken(token: string): Promise<JwtPayload> {
|
||||
const { payload } = await jose.jwtVerify(token, secret);
|
||||
return payload as unknown as JwtPayload;
|
||||
}
|
||||
|
||||
export function isAccessPayload(p: JwtPayload): p is AccessPayload {
|
||||
return p.type === 'access';
|
||||
}
|
||||
|
||||
export function isRefreshPayload(p: JwtPayload): p is RefreshPayload {
|
||||
return p.type === 'refresh';
|
||||
}
|
||||
15
src/utils/password.ts
Normal file
15
src/utils/password.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import * as argon2 from 'argon2';
|
||||
|
||||
const HASH_OPTIONS: argon2.Options = {
|
||||
type: argon2.argon2id,
|
||||
memoryCost: 19456,
|
||||
timeCost: 2,
|
||||
};
|
||||
|
||||
export async function hashPassword(plain: string): Promise<string> {
|
||||
return argon2.hash(plain, HASH_OPTIONS);
|
||||
}
|
||||
|
||||
export async function verifyPassword(hash: string, plain: string): Promise<boolean> {
|
||||
return argon2.verify(hash, plain);
|
||||
}
|
||||
Reference in New Issue
Block a user