HotTRDealsBackend/db/refreshToken.db.js
2026-01-25 17:50:56 +00:00

107 lines
2.9 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// db/refreshToken.db.js
const prisma = require("./client")
function toDate(x) {
if (!x) return null
if (x instanceof Date) return x
const d = new Date(x)
return Number.isNaN(d.getTime()) ? null : d
}
async function createRefreshToken(userId, input = {}) {
const data = {
userId: Number(userId),
tokenHash: input.tokenHash, // required
familyId: input.familyId, // required
jti: input.jti, // required
expiresAt: toDate(input.expiresAt) || new Date(Date.now() + 1000 * 60 * 60 * 24 * 30),
createdByIp: input.createdByIp ?? null,
userAgent: input.userAgent ?? null,
}
return prisma.refreshToken.create({ data })
}
async function findRefreshTokenByHash(tokenHash, options = {}) {
return prisma.refreshToken.findUnique({
where: { tokenHash },
select: options.select || undefined,
include: options.include || undefined,
})
}
async function revokeRefreshTokenById(id, meta = {}) {
return prisma.refreshToken.update({
where: { id },
data: {
revokedAt: meta.revokedAt ?? new Date(),
// optional audit
createdByIp: meta.createdByIp ?? undefined,
userAgent: meta.userAgent ?? undefined,
},
})
}
async function revokeRefreshTokenByHash(tokenHash, meta = {}) {
return prisma.refreshToken.update({
where: { tokenHash },
data: {
revokedAt: meta.revokedAt ?? new Date(),
createdByIp: meta.createdByIp ?? undefined,
userAgent: meta.userAgent ?? undefined,
},
})
}
// Rotation: eski token -> revoked + replacedById set, yeni token create
async function rotateRefreshToken({ oldId, newToken = {}, meta = {} }) {
return prisma.$transaction(async (tx) => {
const created = await tx.refreshToken.create({
data: {
userId: Number(newToken.userId),
tokenHash: newToken.tokenHash,
familyId: newToken.familyId,
jti: newToken.jti,
expiresAt: toDate(newToken.expiresAt),
createdByIp: meta.createdByIp ?? null,
userAgent: meta.userAgent ?? null,
},
})
const revoked = await tx.refreshToken.update({
where: { id: oldId },
data: {
revokedAt: meta.revokedAt ?? new Date(),
replacedById: created.id,
},
})
return { created, revoked }
})
}
// Reuse tespiti / güvenlik: aynı ailedeki tüm tokenları revoke et
async function revokeRefreshTokenFamily(familyId) {
return prisma.refreshToken.updateMany({
where: { familyId, revokedAt: null },
data: { revokedAt: new Date() },
})
}
async function revokeAllUserRefreshTokens(userId) {
return prisma.refreshToken.updateMany({
where: { userId: Number(userId), revokedAt: null },
data: { revokedAt: new Date() },
})
}
module.exports = {
createRefreshToken,
findRefreshTokenByHash,
revokeRefreshTokenById,
revokeRefreshTokenByHash,
rotateRefreshToken,
revokeRefreshTokenFamily,
revokeAllUserRefreshTokens,
}