Spaces:
Runtime error
Runtime error
File size: 1,628 Bytes
24727a3 4a31b63 24727a3 4a31b63 24727a3 4a31b63 24727a3 4a31b63 24727a3 4a31b63 24727a3 4a31b63 24727a3 | 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 | import jwt from 'jsonwebtoken'
import { randomUUID } from 'crypto'
import { config } from '../config/index.js'
import { safeRedis } from '../config/redis.js'
const ISS = 'templyn-api'
const AUD_CLIENT = 'templyn-client'
const AUD_ADMIN = 'templyn-admin'
export function signAccessToken(userId, role) {
return jwt.sign(
{ sub: userId, role, type: 'access', jti: randomUUID(), iss: ISS, aud: role === 'CLIENT' ? AUD_CLIENT : AUD_ADMIN },
config.JWT_ACCESS_SECRET,
{ expiresIn: config.JWT_ACCESS_EXPIRES }
)
}
export function signRefreshToken(userId) {
return jwt.sign(
{ sub: userId, type: 'refresh', jti: randomUUID(), iss: ISS, aud: AUD_CLIENT },
config.JWT_REFRESH_SECRET,
{ expiresIn: config.JWT_REFRESH_EXPIRES }
)
}
export function verifyAccessToken(token) {
const decoded = jwt.verify(token, config.JWT_ACCESS_SECRET)
if (decoded.iss !== ISS) throw new Error('Invalid issuer')
return decoded
}
export function verifyRefreshToken(token) {
const decoded = jwt.verify(token, config.JWT_REFRESH_SECRET)
if (decoded.iss !== ISS) throw new Error('Invalid issuer')
return decoded
}
export async function blacklistToken(token) {
const decoded = jwt.decode(token)
if (!decoded?.exp) return
const ttl = decoded.exp - Math.floor(Date.now() / 1000)
if (ttl > 0) await safeRedis.setex(`blacklist:${token}`, ttl, '1')
}
export async function verifySocketToken(token) {
try {
const decoded = verifyAccessToken(token)
const isBlacklisted = await safeRedis.get(`blacklist:${token}`)
if (isBlacklisted) return null
return decoded
} catch {
return null
}
}
|