<?php
if (!defined('__TYPECHO_ROOT_DIR__')) exit;

function Mirai_hideCheckPassword($cid, $uid, $attrs, $widget, $index = 0) {
    $pwd = isset($attrs['pwd']) ? $attrs['pwd'] : '';
    if ($pwd === '') {
        return ['allowed' => true];
    }

    // Secure session configuration
    if (session_status() === PHP_SESSION_NONE) {
        if (PHP_VERSION_ID >= 70300) {
            session_set_cookie_params([
                'lifetime' => 0,
                'path' => '/',
                'httponly' => true,
                'samesite' => 'Lax'
            ]);
        } else {
            session_set_cookie_params(0, '/; SameSite=Lax', '', false, true);
        }
        @session_start();
    }

    // Check session for previously verified password
    $sessionKey = 'mirai_hide_pwd_verified_' . $cid . '_' . $index;
    if (!empty($_SESSION[$sessionKey])) {
        $storedHash = $_SESSION[$sessionKey];
        if (hash_equals($storedHash, hash('sha256', $pwd))) {
            return ['allowed' => true];
        }
    }

    $inputKey = 'mirai_hide_pwd_' . $cid . '_' . $index;
    $inputPwd = isset($_POST[$inputKey]) ? (string)$_POST[$inputKey] : '';

    if ($inputPwd === '') {
        return ['allowed' => false, 'reason' => 'no_input'];
    }

    // Brute-force protection: max 10 attempts per 5 minutes per content block
    $rateLimitKey = 'mirai_hide_pwd_attempts_' . $cid . '_' . $index;
    $rateLimitTimeKey = 'mirai_hide_pwd_lockout_' . $cid . '_' . $index;
    $maxAttempts = 10;
    $lockoutDuration = 300; // 5 minutes

    if (isset($_SESSION[$rateLimitTimeKey]) && time() < (int)$_SESSION[$rateLimitTimeKey]) {
        $remaining = (int)$_SESSION[$rateLimitTimeKey] - time();
        return ['allowed' => false, 'reason' => 'wrong_password', 'msg' => '尝试次数过多，请' . ceil($remaining / 60) . '分钟后重试'];
    }

    $attempts = isset($_SESSION[$rateLimitKey]) ? (int)$_SESSION[$rateLimitKey] : 0;

    // Use hash comparison to prevent timing attacks
    $inputHash = hash('sha256', $inputPwd);
    $expectedHash = hash('sha256', $pwd);

    if (hash_equals($expectedHash, $inputHash)) {
        // Store verification in session so user doesn't need to re-enter on refresh
        $_SESSION[$sessionKey] = hash('sha256', $pwd);
        unset($_SESSION[$rateLimitKey], $_SESSION[$rateLimitTimeKey]);
        return ['allowed' => true];
    }

    // Increment rate limit counter
    $attempts++;
    $_SESSION[$rateLimitKey] = $attempts;
    if ($attempts >= $maxAttempts) {
        $_SESSION[$rateLimitTimeKey] = time() + $lockoutDuration;
        $_SESSION[$rateLimitKey] = 0;
    }

    return ['allowed' => false, 'reason' => 'wrong_password'];
}
