fix #29 : envoyer le lien magique par email (envoyer_mail_smtp)
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Infrastructure;
|
||||
|
||||
use PDO;
|
||||
use PDOException;
|
||||
use RuntimeException;
|
||||
|
||||
final class Database
|
||||
{
|
||||
private static ?PDO $pdo = null;
|
||||
|
||||
public static function get(): PDO
|
||||
{
|
||||
if (self::$pdo instanceof PDO) {
|
||||
return self::$pdo;
|
||||
}
|
||||
|
||||
$get = static function (string $k, ?string $default = null): ?string {
|
||||
$v = getenv($k);
|
||||
if ($v !== false && $v !== '') {
|
||||
return (string)$v;
|
||||
}
|
||||
return $_ENV[$k] ?? $default;
|
||||
};
|
||||
|
||||
$dsn = $get('DB_DSN');
|
||||
$user = $get('DB_USER');
|
||||
$pass = $get('DB_PASS');
|
||||
|
||||
if (!$dsn) {
|
||||
$host = $get('DB_HOST', 'localhost');
|
||||
$port = $get('DB_PORT', '5432');
|
||||
$name = $get('DB_NAME');
|
||||
if ($name) {
|
||||
$dsn = sprintf('pgsql:host=%s;port=%s;dbname=%s', $host, $port, $name);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$dsn) {
|
||||
throw new RuntimeException('DB_DSN manquant (ni DB_DSN ni DB_HOST/DB_PORT/DB_NAME).');
|
||||
}
|
||||
|
||||
try {
|
||||
$pdo = new PDO($dsn, (string)($user ?? ''), (string)($pass ?? ''), [
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||
PDO::ATTR_EMULATE_PREPARES => false,
|
||||
]);
|
||||
return self::$pdo = $pdo;
|
||||
} catch (PDOException $e) {
|
||||
throw new RuntimeException('Connexion BDD échouée.', previous: $e);
|
||||
}
|
||||
}
|
||||
|
||||
/** @deprecated Utiliser Database::get() */
|
||||
public static function pdo(): PDO
|
||||
{
|
||||
@trigger_error(__METHOD__.' est déprécié. Utiliser Database::get()', E_USER_DEPRECATED);
|
||||
return self::get();
|
||||
}
|
||||
|
||||
/** @deprecated Utiliser Database::get() */
|
||||
public static function getPdo(): PDO
|
||||
{
|
||||
@trigger_error(__METHOD__.' est déprécié. Utiliser Database::get()', E_USER_DEPRECATED);
|
||||
return self::get();
|
||||
}
|
||||
|
||||
/** @deprecated Utiliser Database::get() */
|
||||
public static function getInstance(): PDO
|
||||
{
|
||||
@trigger_error(__METHOD__.' est déprécié. Utiliser Database::get()', E_USER_DEPRECATED);
|
||||
return self::get();
|
||||
}
|
||||
|
||||
public static function transactional(callable $fn)
|
||||
{
|
||||
$pdo = self::get();
|
||||
try {
|
||||
$pdo->beginTransaction();
|
||||
$ret = $fn($pdo);
|
||||
$pdo->commit();
|
||||
return $ret;
|
||||
} catch (\Throwable $e) {
|
||||
if ($pdo->inTransaction()) {
|
||||
$pdo->rollBack();
|
||||
}
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Infrastructure;
|
||||
|
||||
use PDO;
|
||||
|
||||
final class DbAdapter
|
||||
{
|
||||
public static function pdo(): PDO
|
||||
{
|
||||
if (!empty($GLOBALS['pdo']) && $GLOBALS['pdo'] instanceof PDO) {
|
||||
return $GLOBALS['pdo'];
|
||||
}
|
||||
$dsn = getenv('DB_DSN') ?: ($_ENV['DB_DSN'] ?? null);
|
||||
$user = getenv('DB_USER') ?: ($_ENV['DB_USER'] ?? null);
|
||||
$pass = getenv('DB_PASS') ?: ($_ENV['DB_PASS'] ?? null);
|
||||
if (!$dsn) {
|
||||
$host = getenv('DB_HOST') ?: ($_ENV['DB_HOST'] ?? 'localhost');
|
||||
$port = getenv('DB_PORT') ?: ($_ENV['DB_PORT'] ?? '5432');
|
||||
$name = getenv('DB_NAME') ?: ($_ENV['DB_NAME'] ?? null);
|
||||
if ($name) {
|
||||
$dsn = sprintf('pgsql:host=%s;port=%s;dbname=%s', $host, $port, $name);
|
||||
}
|
||||
}
|
||||
if (!$dsn) {
|
||||
throw new \RuntimeException('Aucun DSN pour initialiser PDO');
|
||||
}
|
||||
return new PDO($dsn, (string)$user, (string)$pass, [
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||
PDO::ATTR_EMULATE_PREPARES => false,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Infrastructure;
|
||||
|
||||
final class Session
|
||||
{
|
||||
public static function startSecure(string $name): void
|
||||
{
|
||||
if (session_status() === PHP_SESSION_ACTIVE) {
|
||||
return;
|
||||
}
|
||||
|
||||
session_name($name);
|
||||
session_set_cookie_params([
|
||||
'lifetime' => 0,
|
||||
'path' => '/',
|
||||
'domain' => '',
|
||||
'secure' => true,
|
||||
'httponly' => true,
|
||||
'samesite' => 'Strict',
|
||||
]);
|
||||
session_start();
|
||||
|
||||
// Verrouillage basique contre session hijacking
|
||||
$key = '_sess_fingerprint';
|
||||
$fp = hash('xxh3', ($_SERVER['REMOTE_ADDR'] ?? '') . '|' . ($_SERVER['HTTP_USER_AGENT'] ?? ''));
|
||||
if (!isset($_SESSION[$key])) {
|
||||
$_SESSION[$key] = $fp;
|
||||
} elseif ($_SESSION[$key] !== $fp) {
|
||||
session_regenerate_id(true);
|
||||
$_SESSION = [];
|
||||
$_SESSION[$key] = $fp;
|
||||
}
|
||||
}
|
||||
|
||||
public static function regenerate(): void
|
||||
{
|
||||
session_regenerate_id(true);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user