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> {
|
export async function createRefreshToken(userId: string): Promise<string> {
|
||||||
const token = createOpaqueToken()
|
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
|
return token
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function rotateRefreshToken(refreshToken: string): Promise<AuthUser | null> {
|
export async function rotateRefreshToken(refreshToken: string): Promise<AuthUser | null> {
|
||||||
|
const tokenHash = hashToken(refreshToken)
|
||||||
const tokenJson = await redis.send('GETDEL', [refreshTokenKey(refreshToken)])
|
const tokenJson = await redis.send('GETDEL', [refreshTokenKey(refreshToken)])
|
||||||
if (typeof tokenJson !== 'string') return null
|
if (typeof tokenJson !== 'string') return null
|
||||||
|
|
||||||
const token = parseStoredRefreshToken(tokenJson)
|
const token = parseStoredRefreshToken(tokenJson)
|
||||||
if (!token) return null
|
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)
|
return findUserById(token.userId)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function revokeRefreshToken(refreshToken: string): Promise<void> {
|
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> {
|
export async function createHandoffToken(userId: string, audienceApp: string): Promise<string> {
|
||||||
|
|||||||
Reference in New Issue
Block a user