136 lines
5.9 KiB
TypeScript
136 lines
5.9 KiB
TypeScript
import { use, useEffect, useState } from 'react';
|
||
import Layout from '../../components/layout';
|
||
import axiosInstance from "../../src/axiosSecure";
|
||
import common from '../../src/helpers/common';
|
||
import { EventLogType } from '@prisma/client';
|
||
import { useRouter } from "next/router";
|
||
|
||
export default function ResetPassword(req, res) {
|
||
const [email, setEmail] = useState('');
|
||
const [message, setMessage] = useState('');
|
||
const [resetToken, setResetToken] = useState(req.query?.resetToken || '');
|
||
const [isConfirmed, setIsConfirmed] = useState(false);
|
||
const router = useRouter();
|
||
|
||
|
||
useEffect(async () => {
|
||
if (resetToken) {
|
||
const prisma = common.getPrismaClient();
|
||
let eventLog = await prisma.eventLog.findUnique({
|
||
where: {
|
||
content: resetToken,
|
||
type: EventLogType.PasswordResetEmailConfirmed,
|
||
date: {
|
||
gt: new Date(new Date().getTime() - 24 * 60 * 60 * 1000) //24 hours
|
||
}
|
||
}
|
||
});
|
||
if (eventLog) {
|
||
setIsConfirmed(true);
|
||
}
|
||
}
|
||
}, [resetToken]);
|
||
|
||
const handleResetRequest = async (event) => {
|
||
event.preventDefault();
|
||
// Call your email API endpoint here
|
||
try {
|
||
const response = await axiosInstance.post('/api/email?action=account&emailaction=resetPassword', { email },
|
||
{ headers: { 'Content-Type': 'application/json' } });
|
||
if (response.data.message) {
|
||
setMessage(response.data.message);
|
||
} else {
|
||
if (response.ok) {
|
||
setMessage('Провери твоя имейл за инструкции как да промениш паролата си.');
|
||
} else {
|
||
if (response.error) {
|
||
setMessage(response.error);
|
||
}
|
||
}
|
||
}
|
||
} catch (error) {
|
||
setMessage(error.message);
|
||
}
|
||
};
|
||
|
||
const setNewPassword = async (event) => {
|
||
event.preventDefault();
|
||
|
||
try {
|
||
const prisma = common.getPrismaClient();
|
||
const user = await prisma.user.findUnique({
|
||
where: {
|
||
email
|
||
}
|
||
});
|
||
if (!user) {
|
||
throw new Error('Няма потребител с този имейл.');
|
||
}
|
||
|
||
const passHash = await crypto.hash(event.target.newPassword.value, 10);
|
||
await prisma.user.update({
|
||
where: {
|
||
email
|
||
},
|
||
data: {
|
||
passwordHashLocalAccount: passHash
|
||
}
|
||
});
|
||
setMessage('Паролата беше успешно променена.');
|
||
router.push('/auth/signin');
|
||
|
||
} catch (error) {
|
||
setMessage(error.message);
|
||
}
|
||
}
|
||
|
||
|
||
return (
|
||
<Layout>
|
||
<div className="min-h-screen flex items-center justify-center">
|
||
<div className="w-full max-w-md p-8 space-y-6 bg-white shadow-lg rounded-lg">
|
||
<h1 className="text-xl font-bold text-center">Променете паролата си</h1>
|
||
<form onSubmit={handleResetRequest} className="space-y-4">
|
||
{!isConfirmed &&
|
||
<div>
|
||
<label htmlFor="email" className="block text-sm font-medium text-gray-700">имейл</label>
|
||
<input
|
||
id="email"
|
||
type="email"
|
||
required
|
||
value={email}
|
||
onChange={(e) => setEmail(e.target.value)}
|
||
className="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
|
||
/>
|
||
</div>}
|
||
|
||
{isConfirmed &&
|
||
<div>
|
||
<label htmlFor="newPassword" className="block text-sm font-medium text-gray-700">имейл</label>
|
||
<input
|
||
id="newPassword"
|
||
type="password"
|
||
required
|
||
value={newPassword}
|
||
onChange={(e) => setNewPassword(e.target.value)}
|
||
className="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
|
||
/>
|
||
</div>}
|
||
<div>
|
||
<button type="submit" className="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700">
|
||
Изпрати линк за промяна на паролата
|
||
</button>
|
||
<button type="button" className="mt-4 w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-blue-600 hover:text-blue-700 focus:outline-none"
|
||
onClick={() => window.location.href = '/auth/signin'}
|
||
>
|
||
страница за вход
|
||
</button>
|
||
</div>
|
||
{message && <div className="text-center text-sm text-gray-500">{message}</div>}
|
||
</form>
|
||
</div>
|
||
</div>
|
||
</Layout>
|
||
);
|
||
}
|