This commit is contained in:
+38
-2
@@ -453,22 +453,58 @@ export async function verifyPasswordResetCode(email: string, code: string): Prom
|
||||
|
||||
export async function createRefreshToken(userId: string): Promise<string> {
|
||||
const token = createOpaqueToken()
|
||||
await redis.set(refreshTokenKey(token), JSON.stringify({ userId }), 'EX', config.refreshTokenTtlSeconds)
|
||||
const expiresAt = new Date(Date.now() + config.refreshTokenTtlSeconds * 1000)
|
||||
|
||||
await Promise.all([
|
||||
redis.set(refreshTokenKey(token), JSON.stringify({ userId }), 'EX', config.refreshTokenTtlSeconds),
|
||||
prisma.refreshToken.create({
|
||||
data: {
|
||||
userId,
|
||||
tokenHash: hashToken(token),
|
||||
expiresAt
|
||||
}
|
||||
})
|
||||
])
|
||||
|
||||
return token
|
||||
}
|
||||
|
||||
export async function rotateRefreshToken(refreshToken: string): Promise<AuthUser | null> {
|
||||
const tokenHash = hashToken(refreshToken)
|
||||
const tokenJson = await redis.send('GETDEL', [refreshTokenKey(refreshToken)])
|
||||
if (typeof tokenJson !== 'string') return null
|
||||
|
||||
const token = parseStoredRefreshToken(tokenJson)
|
||||
if (!token) return null
|
||||
|
||||
const storedToken = await prisma.refreshToken.findUnique({
|
||||
where: { tokenHash },
|
||||
select: { id: true, userId: true, revokedAt: true, expiresAt: true }
|
||||
})
|
||||
|
||||
if (!storedToken || storedToken.userId !== token.userId || storedToken.revokedAt || storedToken.expiresAt <= new Date()) {
|
||||
return null
|
||||
}
|
||||
|
||||
await prisma.refreshToken.update({
|
||||
where: { id: storedToken.id },
|
||||
data: { revokedAt: new Date() }
|
||||
})
|
||||
|
||||
return findUserById(token.userId)
|
||||
}
|
||||
|
||||
export async function revokeRefreshToken(refreshToken: string): Promise<void> {
|
||||
await redis.del(refreshTokenKey(refreshToken))
|
||||
await Promise.all([
|
||||
redis.del(refreshTokenKey(refreshToken)),
|
||||
prisma.refreshToken.updateMany({
|
||||
where: {
|
||||
tokenHash: hashToken(refreshToken),
|
||||
revokedAt: null
|
||||
},
|
||||
data: { revokedAt: new Date() }
|
||||
})
|
||||
])
|
||||
}
|
||||
|
||||
export async function createHandoffToken(userId: string, audienceApp: string): Promise<string> {
|
||||
|
||||
Reference in New Issue
Block a user