GitGram — reset-password.php — GitGram
PassGram / main / v6.00 / reset-password.php3,086 B↓ Raw
<?php
/**
 * PassGram v3.0 - Password Reset Entry Point
 *
 * Users arrive here via a link generated by an admin.
 * Token is validated; on success the user sets a new password.
 */

require_once __DIR__ . '/autoload.php';

use PassGram\Core\Config;
use PassGram\Core\Session;
use PassGram\Core\Database;
use PassGram\Security\CSRF;
use PassGram\Security\Encryption;
use PassGram\Models\User;
use PassGram\Models\PasswordReset;
use PassGram\Helpers\Validator;
use PassGram\Helpers\Logger;
use PassGram\Helpers\Sanitizer;

// Check if installed
$config = Config::getInstance(__DIR__ . '/config');
if (!$config->isInstalled() || !file_exists(__DIR__ . '/data/users.json.enc')) {
    header('Location: /setup.php');
    exit;
}

Session::start();

$masterKey = hex2bin($config->get('security.master_application_key'));
$encryption = new Encryption($masterKey, $config->get('security.encryption'));
$db         = new Database($encryption, $config->database());
$csrf       = new CSRF();
$validator  = new Validator($config);
$logger     = new Logger($config->get('database.activity_log'));
$userModel  = new User($db, $config, $validator);
$resetModel = new PasswordReset($db);

$token = Sanitizer::trim($_GET['token'] ?? $_POST['token'] ?? '');
$reset = $token ? $resetModel->validate($token) : null;

if ($_SERVER['REQUEST_METHOD'] === 'POST') {

    if (!$csrf->validatePost()) {
        Session::flash('error', 'Invalid security token. Please try again.');
        header('Location: /reset-password.php?token=' . urlencode($token));
        exit;
    }

    if (!$reset) {
        Session::flash('error', 'Invalid or expired reset link.');
        header('Location: /reset-password.php');
        exit;
    }

    $password        = $_POST['password'] ?? '';
    $confirmPassword = $_POST['confirm_password'] ?? '';

    if ($password !== $confirmPassword) {
        Session::flash('error', 'Passwords do not match.');
        header('Location: /reset-password.php?token=' . urlencode($token));
        exit;
    }

    try {
        $userModel->updatePassword($reset['user_id'], $password);
        $resetModel->consume($token);

        $logger->info("Password reset completed for user ID {$reset['user_id']}");

        Session::flash('success', 'Password updated successfully. You can now log in.');
        header('Location: /login.php');
        exit;

    } catch (\Exception $e) {
        $logger->error('Password reset error: ' . $e->getMessage());
        Session::flash('error', $e->getMessage());
        header('Location: /reset-password.php?token=' . urlencode($token));
        exit;
    }

} else {
    // GET — display form
    $user = $reset ? $userModel->findById($reset['user_id']) : null;

    $data = [
        'csrf_token'  => $csrf->getToken(),
        'token'       => $token,
        'valid_token' => (bool) $reset,
        'username'    => $user['username'] ?? '',
        'error'       => Session::flash('error'),
        'success'     => Session::flash('success'),
    ];

    extract($data);
    require __DIR__ . '/src/Views/auth/reset_password.php';
}
Ready
GitGram