feat: core utilities - CSRF, auth, encryption, PHPMailer

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Gestoría LP
2026-03-01 23:28:54 +00:00
parent 10bc97e8b9
commit 322fc78f2b
7 changed files with 7299 additions and 0 deletions

42
includes/auth.php Normal file
View File

@@ -0,0 +1,42 @@
<?php
require_once __DIR__ . '/db.php';
function authStart(): void {
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
}
function authCheck(): bool {
authStart();
return !empty($_SESSION['user_id']);
}
function authRequire(): void {
if (!authCheck()) {
header('Location: login.php');
exit;
}
}
function authLogin(string $username, string $password): bool {
$db = getDB();
$stmt = $db->prepare('SELECT id, password_hash FROM usuarios WHERE username = ?');
$stmt->execute([$username]);
$user = $stmt->fetch();
if ($user && password_verify($password, $user['password_hash'])) {
authStart();
session_regenerate_id(true);
$_SESSION['user_id'] = $user['id'];
$_SESSION['username'] = $username;
return true;
}
return false;
}
function authLogout(): void {
authStart();
$_SESSION = [];
session_destroy();
}

18
includes/csrf.php Normal file
View File

@@ -0,0 +1,18 @@
<?php
function csrfToken(): string {
if (session_status() === PHP_SESSION_NONE) session_start();
if (empty($_SESSION['csrf_token'])) {
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}
return $_SESSION['csrf_token'];
}
function csrfField(): string {
return '<input type="hidden" name="csrf_token" value="' . htmlspecialchars(csrfToken()) . '">';
}
function csrfValidate(): bool {
if (session_status() === PHP_SESSION_NONE) session_start();
$token = $_POST['csrf_token'] ?? '';
return hash_equals($_SESSION['csrf_token'] ?? '', $token);
}

17
includes/encryption.php Normal file
View File

@@ -0,0 +1,17 @@
<?php
require_once __DIR__ . '/config.php';
function encryptData(string $plaintext): string {
$iv = random_bytes(16);
$key = hash('sha256', ENCRYPTION_KEY, true);
$encrypted = openssl_encrypt($plaintext, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv);
return base64_encode($iv . $encrypted);
}
function decryptData(string $ciphertext): string {
$data = base64_decode($ciphertext);
$iv = substr($data, 0, 16);
$encrypted = substr($data, 16);
$key = hash('sha256', ENCRYPTION_KEY, true);
return openssl_decrypt($encrypted, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv);
}

40
includes/mailer.php Normal file
View File

@@ -0,0 +1,40 @@
<?php
require_once __DIR__ . '/config.php';
require_once __DIR__ . '/../vendor/phpmailer/PHPMailer.php';
require_once __DIR__ . '/../vendor/phpmailer/SMTP.php';
require_once __DIR__ . '/../vendor/phpmailer/Exception.php';
use PHPMailer\PHPMailer\PHPMailer;
function sendEmail(string $subject, string $htmlBody, ?string $toEmail = null): bool {
$mail = new PHPMailer(true);
try {
$mail->isSMTP();
$mail->Host = SMTP_HOST;
$mail->SMTPAuth = true;
$mail->Username = SMTP_USER;
$mail->Password = SMTP_PASS;
$mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS;
$mail->Port = SMTP_PORT;
$mail->CharSet = 'UTF-8';
$mail->setFrom(SMTP_USER, SMTP_FROM_NAME);
$mail->addAddress($toEmail ?? SMTP_USER);
$mail->isHTML(true);
$mail->Subject = $subject;
$mail->Body = $htmlBody;
$mail->AltBody = strip_tags($htmlBody);
$mail->send();
return true;
} catch (\Exception $e) {
error_log('Email error: ' . $e->getMessage());
return false;
}
}
function buildWhatsAppLink(string $serviceName, string $clientName, string $phone): string {
$message = "Hola, soy *{$clientName}* y estoy interesado/a en el servicio de *{$serviceName}*. Mi teléfono es {$phone}. Acabo de enviar mi solicitud por la página web.";
return 'https://wa.me/' . WHATSAPP_NUMBER . '?text=' . urlencode($message);
}

40
vendor/phpmailer/Exception.php vendored Normal file
View File

@@ -0,0 +1,40 @@
<?php
/**
* PHPMailer Exception class.
* PHP Version 5.5.
*
* @see https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project
*
* @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
* @author Jim Jagielski (jimjag) <jimjag@gmail.com>
* @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
* @author Brent R. Matzelle (original founder)
* @copyright 2012 - 2020 Marcus Bointon
* @copyright 2010 - 2012 Jim Jagielski
* @copyright 2004 - 2009 Andy Prevost
* @license https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html GNU Lesser General Public License
* @note This program is distributed in the hope that it will be useful - WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*/
namespace PHPMailer\PHPMailer;
/**
* PHPMailer exception handler.
*
* @author Marcus Bointon <phpmailer@synchromedia.co.uk>
*/
class Exception extends \Exception
{
/**
* Prettify error message output.
*
* @return string
*/
public function errorMessage()
{
return '<strong>' . htmlspecialchars($this->getMessage(), ENT_COMPAT | ENT_HTML401) . "</strong><br />\n";
}
}

5525
vendor/phpmailer/PHPMailer.php vendored Normal file

File diff suppressed because it is too large Load Diff

1617
vendor/phpmailer/SMTP.php vendored Normal file

File diff suppressed because it is too large Load Diff