42 lines
1.0 KiB
TypeScript
42 lines
1.0 KiB
TypeScript
import jwt from 'jsonwebtoken'
|
|
import type { PublicUser, Role, UserRecord } from '../shared/types.js'
|
|
|
|
export const getJwtSecret = (): string => {
|
|
const secret = process.env.JWT_SECRET
|
|
return secret && secret.trim().length > 0 ? secret : 'dev-jwt-secret'
|
|
}
|
|
|
|
export const signToken = (user: PublicUser): string => {
|
|
return jwt.sign(
|
|
{
|
|
sub: user.id,
|
|
username: user.username,
|
|
role: user.role,
|
|
},
|
|
getJwtSecret(),
|
|
{ expiresIn: '7d' },
|
|
)
|
|
}
|
|
|
|
export const verifyToken = (
|
|
token: string,
|
|
): { userId: string; username: string; role: Role } | null => {
|
|
try {
|
|
const decoded = jwt.verify(token, getJwtSecret()) as {
|
|
sub?: string
|
|
username?: string
|
|
role?: Role
|
|
}
|
|
if (!decoded?.sub || !decoded.role || !decoded.username) return null
|
|
return { userId: decoded.sub, username: decoded.username, role: decoded.role }
|
|
} catch {
|
|
return null
|
|
}
|
|
}
|
|
|
|
export const toPublicUser = (u: UserRecord): PublicUser => {
|
|
const { passwordHash: _pw, ...rest } = u
|
|
return rest
|
|
}
|
|
|