style: liens sans soulignement, zone illustration en haut des tuiles
This commit is contained in:
+1
-1
File diff suppressed because one or more lines are too long
@@ -4,68 +4,3 @@ parameters:
|
|||||||
message: "#^Unreachable statement \\- code above always terminates\\.$#"
|
message: "#^Unreachable statement \\- code above always terminates\\.$#"
|
||||||
count: 1
|
count: 1
|
||||||
path: src/Repository/ProfileRepository.php
|
path: src/Repository/ProfileRepository.php
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Call to method getCode\\(\\) on an unknown class App\\\\Repository\\\\PDOException\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: src/Repository/UserRepository.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Caught class App\\\\Repository\\\\PDOException not found\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: src/Repository/UserRepository.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Instantiated class App\\\\Repository\\\\InvalidArgumentException not found\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: src/Repository/UserRepository.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Method App\\\\Repository\\\\UserRepository\\:\\:nullIfEmpty\\(\\) is unused\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: src/Repository/UserRepository.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Throwing object of an unknown class App\\\\Repository\\\\InvalidArgumentException\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: src/Repository/UserRepository.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Throwing object of an unknown class App\\\\Repository\\\\PDOException\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: src/Repository/UserRepository.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Class App\\\\Repository\\\\UserRepository constructor invoked with 0 parameters, 1 required\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: src/Service/AuthService.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Call to an undefined method App\\\\Infrastructure\\\\Database\\:\\:getConnection\\(\\)\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: src/Service/MailQueue.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Call to an undefined method App\\\\Infrastructure\\\\Database\\:\\:getConnection\\(\\)\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: src/Service/MailService.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Comparison operation \"\\>\" between 200 and 0 is always true\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: src/Service/MailService.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Constant BASE_PATH not found\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: src/auth.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Parameter \\#1 \\$scope of method Jumbojett\\\\OpenIDConnectClient\\:\\:addScope\\(\\) expects array, string given\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: src/auth.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Constant BASE_PATH not found\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: src/db.php
|
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
define('BASE_PATH', __DIR__);
|
||||||
@@ -7,3 +7,5 @@ parameters:
|
|||||||
- src
|
- src
|
||||||
excludePaths:
|
excludePaths:
|
||||||
- src/Parsedown.php
|
- src/Parsedown.php
|
||||||
|
bootstrapFiles:
|
||||||
|
- phpstan-bootstrap.php
|
||||||
|
|||||||
@@ -90,7 +90,24 @@ h2 {
|
|||||||
letter-spacing: -0.3px;
|
letter-spacing: -0.3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ─── Liens globaux ─────────────────────── */
|
||||||
|
a {
|
||||||
|
color: var(--vl-accent);
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
color: var(--vl-accent-dark);
|
||||||
|
}
|
||||||
|
|
||||||
/* ─── Cards ─────────────────────────────── */
|
/* ─── Cards ─────────────────────────────── */
|
||||||
|
|
||||||
|
.card-cover {
|
||||||
|
height: 120px;
|
||||||
|
border-radius: var(--vl-radius) var(--vl-radius) 0 0;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.card {
|
.card {
|
||||||
border: 1px solid var(--vl-border) !important;
|
border: 1px solid var(--vl-border) !important;
|
||||||
border-radius: var(--vl-radius) !important;
|
border-radius: var(--vl-radius) !important;
|
||||||
@@ -120,6 +137,15 @@ h2 {
|
|||||||
color: var(--vl-text) !important;
|
color: var(--vl-text) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.card-title a {
|
||||||
|
color: var(--vl-text);
|
||||||
|
transition: color 0.15s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-title a:hover {
|
||||||
|
color: var(--vl-accent);
|
||||||
|
}
|
||||||
|
|
||||||
.card-text {
|
.card-text {
|
||||||
color: var(--vl-muted);
|
color: var(--vl-muted);
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ final class UserRepository
|
|||||||
{
|
{
|
||||||
$email = strtolower(trim($email));
|
$email = strtolower(trim($email));
|
||||||
if ($email === '' || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
if ($email === '' || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
||||||
throw new InvalidArgumentException('Email OIDC invalide.');
|
throw new \InvalidArgumentException('Email OIDC invalide.');
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1) Existe déjà ?
|
// 1) Existe déjà ?
|
||||||
@@ -53,7 +53,7 @@ SQL;
|
|||||||
':hash' => $randomHash,
|
':hash' => $randomHash,
|
||||||
]);
|
]);
|
||||||
return (string)$st->fetchColumn();
|
return (string)$st->fetchColumn();
|
||||||
} catch (PDOException $e) {
|
} catch (\PDOException $e) {
|
||||||
// Unique violation sur email (23505) → on relit l’id (race condition)
|
// Unique violation sur email (23505) → on relit l’id (race condition)
|
||||||
if ($e->getCode() === '23505') {
|
if ($e->getCode() === '23505') {
|
||||||
$st = $this->pdo->prepare('SELECT id FROM users WHERE email = :email LIMIT 1');
|
$st = $this->pdo->prepare('SELECT id FROM users WHERE email = :email LIMIT 1');
|
||||||
@@ -67,12 +67,6 @@ SQL;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function nullIfEmpty(?string $v): ?string
|
|
||||||
{
|
|
||||||
$v = trim((string)$v);
|
|
||||||
return $v === '' ? null : $v;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function findByEmail(string $email): ?User
|
public function findByEmail(string $email): ?User
|
||||||
{
|
{
|
||||||
$sql = 'SELECT id, email, password_hash, is_active FROM users WHERE email = :email LIMIT 1';
|
$sql = 'SELECT id, email, password_hash, is_active FROM users WHERE email = :email LIMIT 1';
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ final class AuthService
|
|||||||
|
|
||||||
// Mettre à jour le hash
|
// Mettre à jour le hash
|
||||||
$newHash = password_hash($newPassword, PASSWORD_ARGON2ID);
|
$newHash = password_hash($newPassword, PASSWORD_ARGON2ID);
|
||||||
(new \App\Repository\UserRepository())->updatePassword($row['id'], $newHash);
|
(new \App\Repository\UserRepository(\App\Infrastructure\Database::get()))->updatePassword($row['id'], $newHash);
|
||||||
|
|
||||||
// (Optionnel) rotation session
|
// (Optionnel) rotation session
|
||||||
\App\Infrastructure\Session::regenerate();
|
\App\Infrastructure\Session::regenerate();
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace App\Service;
|
namespace App\Service;
|
||||||
|
|
||||||
use App\Infrastructure\Database;
|
|
||||||
use PDO;
|
use PDO;
|
||||||
use Throwable;
|
use Throwable;
|
||||||
use DateTimeImmutable;
|
use DateTimeImmutable;
|
||||||
@@ -33,9 +32,9 @@ final class MailQueue
|
|||||||
private PDO $pdo;
|
private PDO $pdo;
|
||||||
private MailService $mailService;
|
private MailService $mailService;
|
||||||
|
|
||||||
public function __construct(Database $db, MailService $mailService)
|
public function __construct(\PDO $pdo, MailService $mailService)
|
||||||
{
|
{
|
||||||
$this->pdo = $db->getConnection();
|
$this->pdo = $pdo;
|
||||||
$this->mailService = $mailService;
|
$this->mailService = $mailService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace App\Service;
|
namespace App\Service;
|
||||||
|
|
||||||
use App\Infrastructure\Database;
|
|
||||||
use PHPMailer\PHPMailer\PHPMailer;
|
use PHPMailer\PHPMailer\PHPMailer;
|
||||||
use PHPMailer\PHPMailer\Exception as MailException;
|
use PHPMailer\PHPMailer\Exception as MailException;
|
||||||
use PDO;
|
use PDO;
|
||||||
@@ -38,7 +37,7 @@ final class MailService
|
|||||||
private array $smtpConfig;
|
private array $smtpConfig;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Database $db Retourne un PDO connecté (PostgreSQL recommandé)
|
* @param \PDO $pdo PDO connecté (PostgreSQL recommandé)
|
||||||
* @param array<string,mixed> $smtpConfig [
|
* @param array<string,mixed> $smtpConfig [
|
||||||
* 'host' => 'smtp.example.tld',
|
* 'host' => 'smtp.example.tld',
|
||||||
* 'port' => 587,
|
* 'port' => 587,
|
||||||
@@ -52,9 +51,9 @@ final class MailService
|
|||||||
* 'smtp_options' => [...] (optionnel, cf. PHPMailer::SMTPOptions)
|
* 'smtp_options' => [...] (optionnel, cf. PHPMailer::SMTPOptions)
|
||||||
* ]
|
* ]
|
||||||
*/
|
*/
|
||||||
public function __construct(Database $db, array $smtpConfig)
|
public function __construct(\PDO $pdo, array $smtpConfig)
|
||||||
{
|
{
|
||||||
$this->pdo = $db->getConnection();
|
$this->pdo = $pdo;
|
||||||
$this->smtpConfig = $smtpConfig;
|
$this->smtpConfig = $smtpConfig;
|
||||||
|
|
||||||
$this->mailer = new PHPMailer(true);
|
$this->mailer = new PHPMailer(true);
|
||||||
@@ -204,8 +203,7 @@ final class MailService
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3) Garde-fou global / heure (optionnel)
|
// 3) Garde-fou global / heure
|
||||||
if (self::MAX_GLOBAL_PER_HOUR > 0) {
|
|
||||||
$sql3 = <<<SQL
|
$sql3 = <<<SQL
|
||||||
SELECT COUNT(*)::int
|
SELECT COUNT(*)::int
|
||||||
FROM journal_smtp
|
FROM journal_smtp
|
||||||
@@ -217,7 +215,6 @@ final class MailService
|
|||||||
if ($global1h >= self::MAX_GLOBAL_PER_HOUR) {
|
if ($global1h >= self::MAX_GLOBAL_PER_HOUR) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -23,6 +23,6 @@ function get_oidc_client(): OpenIDConnectClient
|
|||||||
'varlog-client-secret'
|
'varlog-client-secret'
|
||||||
);
|
);
|
||||||
$oidc->setRedirectURL('http://varlog.acegrp.lan/auth/callback.php');
|
$oidc->setRedirectURL('http://varlog.acegrp.lan/auth/callback.php');
|
||||||
$oidc->addScope('openid email profile');
|
$oidc->addScope(['openid', 'email', 'profile']);
|
||||||
return $oidc;
|
return $oidc;
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-1
@@ -2,6 +2,15 @@
|
|||||||
require_once BASE_PATH . '/src/Parsedown.php';
|
require_once BASE_PATH . '/src/Parsedown.php';
|
||||||
$Parsedown = new Parsedown();
|
$Parsedown = new Parsedown();
|
||||||
|
|
||||||
|
$coverGradients = [
|
||||||
|
'linear-gradient(135deg, #e0e7ff 0%, #c7d2fe 100%)',
|
||||||
|
'linear-gradient(135deg, #d1fae5 0%, #a7f3d0 100%)',
|
||||||
|
'linear-gradient(135deg, #fce7f3 0%, #fbcfe8 100%)',
|
||||||
|
'linear-gradient(135deg, #fef3c7 0%, #fde68a 100%)',
|
||||||
|
'linear-gradient(135deg, #dbeafe 0%, #bfdbfe 100%)',
|
||||||
|
'linear-gradient(135deg, #ede9fe 0%, #ddd6fe 100%)',
|
||||||
|
];
|
||||||
|
|
||||||
ob_start();
|
ob_start();
|
||||||
?>
|
?>
|
||||||
|
|
||||||
@@ -9,10 +18,12 @@ ob_start();
|
|||||||
<?php foreach ($posts as $post): ?>
|
<?php foreach ($posts as $post): ?>
|
||||||
<?php
|
<?php
|
||||||
$html = $Parsedown->text($post['content']);
|
$html = $Parsedown->text($post['content']);
|
||||||
$preview = mb_strimwidth(strip_tags($html), 0, 160, '…');
|
$preview = mb_strimwidth(strip_tags($html), 0, 120, '…');
|
||||||
|
$gradient = $coverGradients[$post['id'] % count($coverGradients)];
|
||||||
?>
|
?>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<article class="card h-100">
|
<article class="card h-100">
|
||||||
|
<div class="card-cover" style="background: <?= $gradient ?>"></div>
|
||||||
<div class="card-body d-flex flex-column">
|
<div class="card-body d-flex flex-column">
|
||||||
<h2 class="card-title">
|
<h2 class="card-title">
|
||||||
<a href="route.php?action=view&id=<?= $post['id'] ?>">
|
<a href="route.php?action=view&id=<?= $post['id'] ?>">
|
||||||
|
|||||||
Reference in New Issue
Block a user