You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
48 lines
1.5 KiB
48 lines
1.5 KiB
import { SecurePassword, hash256 } from "@blitzjs/auth" |
|
import { resolver } from "@blitzjs/rpc" |
|
import db from "db" |
|
import { ResetPassword } from "../validations" |
|
import login from "./login" |
|
|
|
export class ResetPasswordError extends Error { |
|
name = "ResetPasswordError" |
|
message = "Reset password link is invalid or it has expired." |
|
} |
|
|
|
export default resolver.pipe(resolver.zod(ResetPassword), async ({ password, token }, ctx) => { |
|
// 1. Try to find this token in the database |
|
const hashedToken = hash256(token) |
|
const possibleToken = await db.token.findFirst({ |
|
where: { hashedToken, type: "RESET_PASSWORD" }, |
|
include: { user: true }, |
|
}) |
|
|
|
// 2. If token not found, error |
|
if (!possibleToken) { |
|
throw new ResetPasswordError() |
|
} |
|
const savedToken = possibleToken |
|
|
|
// 3. Delete token so it can't be used again |
|
await db.token.delete({ where: { id: savedToken.id } }) |
|
|
|
// 4. If token has expired, error |
|
if (savedToken.expiresAt < new Date()) { |
|
throw new ResetPasswordError() |
|
} |
|
|
|
// 5. Since token is valid, now we can update the user's password |
|
const hashedPassword = await SecurePassword.hash(password.trim()) |
|
const user = await db.user.update({ |
|
where: { id: savedToken.userId }, |
|
data: { hashedPassword }, |
|
}) |
|
|
|
// 6. Revoke all existing login sessions for this user |
|
await db.session.deleteMany({ where: { userId: user.id } }) |
|
|
|
// 7. Now log the user in with the new credentials |
|
await login({ email: user.email, password }, ctx) |
|
|
|
return true |
|
})
|
|
|