"use server"; import argon2 from "argon2"; import { redirect } from "next/navigation"; import { z } from "zod"; import { db } from "@/lib/db"; import { hashToken } from "@/app/(publico)/recuperar-senha/actions"; const redefinirSenhaSchema = z .object({ token: z.string().min(1), senha: z.string().min(8, "A senha precisa ter pelo menos 8 caracteres."), confirmarSenha: z.string() }) .refine((data) => data.senha === data.confirmarSenha, { path: ["confirmarSenha"], message: "As senhas nao conferem." }); export type RedefinirSenhaState = { ok: boolean; message?: string; }; export async function redefinirSenha( _state: RedefinirSenhaState, formData: FormData ): Promise { const parsed = redefinirSenhaSchema.safeParse({ token: formData.get("token"), senha: formData.get("senha"), confirmarSenha: formData.get("confirmarSenha") }); if (!parsed.success) { return { ok: false, message: parsed.error.issues[0]?.message ?? "Revise os dados informados." }; } const tokenHash = hashToken(parsed.data.token); const resetToken = await db.passwordResetToken.findUnique({ where: { tokenHash }, select: { id: true, userId: true, expiraEm: true, usadoEm: true } }); if (!resetToken || resetToken.usadoEm || resetToken.expiraEm < new Date()) { return { ok: false, message: "Link invalido ou expirado." }; } await db.$transaction([ db.user.update({ where: { id: resetToken.userId }, data: { senhaHash: await argon2.hash(parsed.data.senha) } }), db.passwordResetToken.update({ where: { id: resetToken.id }, data: { usadoEm: new Date() } }) ]); redirect("/login"); }