archetecture security fix
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
import jwt from 'jsonwebtoken'
|
||||
|
||||
export type ActorType = 'admin' | 'employee' | 'renter'
|
||||
|
||||
export type ActorTokenPayload = jwt.JwtPayload & {
|
||||
sub: string
|
||||
type: ActorType
|
||||
sessionVersion?: number
|
||||
last2faAt?: number
|
||||
}
|
||||
|
||||
const ISSUER = 'rentaldrivego-api'
|
||||
const ALG: jwt.Algorithm[] = ['HS256']
|
||||
|
||||
function getJwtSecret() {
|
||||
const secret = process.env.JWT_SECRET
|
||||
if (!secret) throw new Error('JWT_SECRET is required')
|
||||
return secret
|
||||
}
|
||||
|
||||
export function signActorToken(
|
||||
actorId: string,
|
||||
actorType: ActorType,
|
||||
options: Pick<jwt.SignOptions, 'expiresIn'> & { sessionVersion?: number; last2faAt?: number } = {},
|
||||
) {
|
||||
const { sessionVersion, last2faAt, ...signOptions } = options
|
||||
return jwt.sign(
|
||||
{
|
||||
sub: actorId,
|
||||
type: actorType,
|
||||
...(sessionVersion === undefined ? {} : { sessionVersion }),
|
||||
...(last2faAt === undefined ? {} : { last2faAt }),
|
||||
},
|
||||
getJwtSecret(),
|
||||
{
|
||||
algorithm: 'HS256',
|
||||
issuer: ISSUER,
|
||||
audience: actorType,
|
||||
expiresIn: signOptions.expiresIn ?? '8h',
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
export function verifyActorToken(token: string, expectedType: ActorType): ActorTokenPayload {
|
||||
const payload = jwt.verify(token, getJwtSecret(), {
|
||||
algorithms: ALG,
|
||||
issuer: ISSUER,
|
||||
audience: expectedType,
|
||||
}) as jwt.JwtPayload
|
||||
|
||||
if (typeof payload.sub !== 'string' || payload.type !== expectedType) {
|
||||
throw new Error('Invalid actor token')
|
||||
}
|
||||
|
||||
return payload as ActorTokenPayload
|
||||
}
|
||||
|
||||
export function verifyAnyActorToken(token: string): ActorTokenPayload {
|
||||
const decoded = jwt.decode(token) as jwt.JwtPayload | null
|
||||
const actorType = decoded?.type
|
||||
|
||||
if (actorType !== 'admin' && actorType !== 'employee' && actorType !== 'renter') {
|
||||
throw new Error('Invalid actor token')
|
||||
}
|
||||
|
||||
return verifyActorToken(token, actorType)
|
||||
}
|
||||
Reference in New Issue
Block a user