feat: core utilities - CSRF, auth, encryption, PHPMailer
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
42
includes/auth.php
Normal file
42
includes/auth.php
Normal 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
18
includes/csrf.php
Normal 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
17
includes/encryption.php
Normal 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
40
includes/mailer.php
Normal 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
40
vendor/phpmailer/Exception.php
vendored
Normal 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
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
1617
vendor/phpmailer/SMTP.php
vendored
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user