base commit
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
import crypto from 'node:crypto'
|
||||
import bcrypt from 'bcryptjs'
|
||||
import { prisma } from './prisma.js'
|
||||
import { sendLoginCodeEmail } from './email.js'
|
||||
|
||||
export function normalizeEmail(email) {
|
||||
return String(email || '').trim().toLowerCase()
|
||||
}
|
||||
|
||||
export function randomCode6() {
|
||||
return String(Math.floor(100000 + Math.random() * 900000))
|
||||
}
|
||||
|
||||
export function sha256(input) {
|
||||
return crypto.createHash('sha256').update(input).digest('hex')
|
||||
}
|
||||
|
||||
export async function issueEmailCode({ email, purpose, userId = null }) {
|
||||
const code = randomCode6()
|
||||
const expiresAt = new Date(Date.now() + 10 * 60 * 1000)
|
||||
await prisma.authCode.create({
|
||||
data: {
|
||||
email,
|
||||
purpose,
|
||||
userId,
|
||||
codeHash: sha256(`${email}:${purpose}:${code}:${userId ?? ''}`),
|
||||
expiresAt,
|
||||
},
|
||||
})
|
||||
await sendLoginCodeEmail({ to: email, code })
|
||||
}
|
||||
|
||||
export async function verifyEmailCode({ email, purpose, code, userId = null }) {
|
||||
const now = new Date()
|
||||
const codeHash = sha256(`${email}:${purpose}:${code}:${userId ?? ''}`)
|
||||
|
||||
const found = await prisma.authCode.findFirst({
|
||||
where: {
|
||||
email,
|
||||
purpose,
|
||||
userId,
|
||||
codeHash,
|
||||
usedAt: null,
|
||||
expiresAt: { gt: now },
|
||||
},
|
||||
orderBy: { createdAt: 'desc' },
|
||||
})
|
||||
if (!found) return false
|
||||
|
||||
await prisma.authCode.update({
|
||||
where: { id: found.id },
|
||||
data: { usedAt: now },
|
||||
})
|
||||
return true
|
||||
}
|
||||
|
||||
export async function hashPassword(password) {
|
||||
return bcrypt.hash(password, 10)
|
||||
}
|
||||
|
||||
export async function verifyPassword(password, passwordHash) {
|
||||
return bcrypt.compare(password, passwordHash)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user