T.ME/BIBIL_0DAY
CasperSecurity


Server : Apache/2
System : Linux server-15-235-50-60 5.15.0-164-generic #174-Ubuntu SMP Fri Nov 14 20:25:16 UTC 2025 x86_64
User : gositeme ( 1004)
PHP Version : 8.2.29
Disable Function : exec,system,passthru,shell_exec,proc_close,proc_open,dl,popen,show_source,posix_kill,posix_mkfifo,posix_getpwuid,posix_setpgid,posix_setsid,posix_setuid,posix_setgid,posix_seteuid,posix_setegid,posix_uname
Directory :  /home/gositeme/backups/lavocat.quebec/backup-20250730-021618/src/pages/auth/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/gositeme/backups/lavocat.quebec/backup-20250730-021618/src/pages/auth/reset-password.tsx
import { useState, useEffect } from 'react';
import { useRouter } from 'next/router';
import type { NextPage } from 'next';
import Link from 'next/link';
import { Lock } from 'lucide-react';
import LayoutWithSidebar from '../../components/LayoutWithSidebar';
import BackButton from '../../components/BackButton';

const ResetPasswordPage: NextPage = () => {
  const [password, setPassword] = useState('');
  const [confirmPassword, setConfirmPassword] = useState('');
  const [error, setError] = useState('');
  const [success, setSuccess] = useState('');
  const [isLoading, setIsLoading] = useState(false);
  const [isMobile, setIsMobile] = useState(false);
  const [language, setLanguage] = useState<'fr' | 'en'>('fr');
  const router = useRouter();
  const { token } = router.query;

  // Mobile detection
  useEffect(() => {
    const checkMobile = () => {
      setIsMobile(window.innerWidth < 768);
    };
    checkMobile();
    window.addEventListener('resize', checkMobile);
    return () => window.removeEventListener('resize', checkMobile);
  }, []);

  const handleLanguageToggle = () => {
    const newLang = language === 'fr' ? 'en' : 'fr';
    setLanguage(newLang);
  };

  const validateForm = () => {
    if (!password.trim()) {
      setError('Password is required.');
      return false;
    }
    if (!confirmPassword.trim()) {
      setError('Please confirm your password.');
      return false;
    }
    if (password !== confirmPassword) {
      setError('Passwords do not match.');
      return false;
    }
    if (password.length < 8) {
      setError('Password must be at least 8 characters long.');
      return false;
    }
    return true;
  };

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    setError('');
    setSuccess('');

    if (!validateForm()) {
      return;
    }

    if (!token) {
      setError('Invalid reset token.');
      return;
    }

    setIsLoading(true);

    try {
      const response = await fetch('/api/auth/reset-password', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ token, password }),
      });

      const data = await response.json();

      if (!response.ok) {
        throw new Error(data.message || 'Password reset failed.');
      }

      setSuccess('Password reset successfully! You can now login with your new password.');
      
      // Redirect to login after success
      setTimeout(() => {
        router.push('/auth/login');
      }, 3000);

    } catch (err: any) {
      console.error('Reset password error:', err);
      setError(err.message || 'An unexpected error occurred.');
    } finally {
      setIsLoading(false);
    }
  };

  return (
    <LayoutWithSidebar>
      <div className={`min-h-screen flex items-center justify-center bg-gradient-to-br from-blue-50 to-indigo-50 ${isMobile ? 'py-4 px-4' : 'py-12 px-4 sm:px-6 lg:px-8'}`}>
        <div className={`w-full space-y-8 bg-white rounded-xl shadow-lg ${isMobile ? 'max-w-full p-6' : 'max-w-md p-8'}`}>
          <BackButton />
          <div>
            <h2 className={`mt-6 text-center font-extrabold text-gray-900 ${isMobile ? 'text-2xl' : 'text-3xl'}`}>
              Reset Password
            </h2>
            <p className={`mt-2 text-center text-gray-600 ${isMobile ? 'text-sm' : 'text-sm'}`}>
              Enter your new password below.
            </p>
          </div>

          <form className="mt-8 space-y-6" onSubmit={handleSubmit}>
            {error && (
              <div className={`bg-red-100 border border-red-400 text-red-700 rounded relative ${isMobile ? 'px-3 py-2 text-sm' : 'px-4 py-3'}`}>
                {error}
              </div>
            )}
            {success && (
              <div className={`bg-green-100 border border-green-400 text-green-700 rounded relative ${isMobile ? 'px-3 py-2 text-sm' : 'px-4 py-3'}`}>
                {success}
              </div>
            )}
            <div className="rounded-md shadow-sm -space-y-px">
              <div className={isMobile ? 'mb-4' : ''}>
                <label htmlFor="password" className="block text-sm font-medium text-gray-700">
                  New Password
                </label>
                <div className="mt-1 relative rounded-md shadow-sm">
                  <div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
                    <Lock className="h-5 w-5 text-gray-400" aria-hidden="true" />
                  </div>
                  <input
                    id="password"
                    name="password"
                    type="password"
                    autoComplete="new-password"
                    required
                    value={password}
                    onChange={(e) => {
                      setPassword(e.target.value);
                      setError('');
                    }}
                    className={`block w-full pl-10 border border-gray-300 rounded-md focus:outline-none focus:ring-primary focus:border-primary ${isMobile ? 'px-3 py-3 text-base' : 'px-3 py-2 sm:text-sm'}`}
                    placeholder="Enter your new password"
                    disabled={isLoading}
                  />
                </div>
              </div>
              <div className={isMobile ? 'mb-4' : ''}>
                <label htmlFor="confirmPassword" className="block text-sm font-medium text-gray-700">
                  Confirm Password
                </label>
                <div className="mt-1 relative rounded-md shadow-sm">
                  <div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
                    <Lock className="h-5 w-5 text-gray-400" aria-hidden="true" />
                  </div>
                  <input
                    id="confirmPassword"
                    name="confirmPassword"
                    type="password"
                    autoComplete="new-password"
                    required
                    value={confirmPassword}
                    onChange={(e) => {
                      setConfirmPassword(e.target.value);
                      setError('');
                    }}
                    className={`block w-full pl-10 border border-gray-300 rounded-md focus:outline-none focus:ring-primary focus:border-primary ${isMobile ? 'px-3 py-3 text-base' : 'px-3 py-2 sm:text-sm'}`}
                    placeholder="Confirm your new password"
                    disabled={isLoading}
                  />
                </div>
              </div>
            </div>

            <div>
              <button
                type="submit"
                className={`group relative w-full flex justify-center border border-transparent font-medium rounded-md text-white bg-primary hover:bg-primary-dark focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary disabled:opacity-50 disabled:cursor-not-allowed ${isMobile ? 'py-3 px-4 text-base' : 'py-2 px-4 text-sm'}`}
                disabled={isLoading}
              >
                {isLoading ? 'Resetting...' : 'Reset Password'}
              </button>
            </div>

            <div className="text-center">
              <p className={`text-gray-600 ${isMobile ? 'text-sm' : 'text-sm'}`}>
                Remember your password?{' '}
                <Link href={language === 'en' ? '/en/auth/login' : '/auth/login'} className="font-medium text-primary hover:text-primary-dark">
                  Sign in
                </Link>
              </p>
            </div>
          </form>
        </div>
      </div>
    </LayoutWithSidebar>
  );
};

export default ResetPasswordPage; 

CasperSecurity Mini