feat: roles, permissions, grille full-width, SSO display name
- Admin/roles : tableau des roles avec edition par role (/admin/role/<nom>) - Permissions par role : cases a cocher groupees (Articles, Acces & lecture) - Nouvelles capacites : propose/validate/publish articles (own/all), view_previews - Nom technique auto-genere depuis le label (JS + fallback serveur) - Blocage suppression du dernier administrateur - user_capabilities table ajoutee en DB - Navbar : dropdown unique (nom + Mon identite + Administration + Deconnexion) - SSO callback : preserve le nom personnalise, ne l ecrase plus a la connexion - Grille articles : CSS Grid auto-fill full-width, hauteur uniforme par ligne - CSP : add_files.js et post_confirm.js externalises
This commit is contained in:
+34
-22
@@ -139,19 +139,48 @@ if (!$email) {
|
||||
}
|
||||
|
||||
// Nom d'affichage depuis les claims SSO
|
||||
$displayName = '';
|
||||
$ssoName = '';
|
||||
if (!empty($claims['given_name']) || !empty($claims['family_name'])) {
|
||||
$displayName = trim(($claims['given_name'] ?? '') . ' ' . ($claims['family_name'] ?? ''));
|
||||
$ssoName = trim(($claims['given_name'] ?? '') . ' ' . ($claims['family_name'] ?? ''));
|
||||
} elseif (!empty($claims['name'])) {
|
||||
$displayName = trim($claims['name']);
|
||||
$ssoName = trim($claims['name']);
|
||||
} elseif (!empty($claims['preferred_username'])) {
|
||||
$displayName = trim($claims['preferred_username']);
|
||||
$ssoName = trim($claims['preferred_username']);
|
||||
}
|
||||
|
||||
// Charge le nom personnalisé depuis la base (prioritaire sur le SSO)
|
||||
require_once dirname(__DIR__, 2) . '/src/auth.php';
|
||||
$pdo = dbPdo();
|
||||
$dbName = '';
|
||||
if ($pdo) {
|
||||
try {
|
||||
$st = $pdo->prepare('SELECT display_name FROM user_profiles WHERE email = :e');
|
||||
$st->execute([':e' => strtolower(trim($email))]);
|
||||
$dbName = (string)($st->fetchColumn() ?: '');
|
||||
} catch (\Throwable) {}
|
||||
}
|
||||
|
||||
if ($dbName !== '') {
|
||||
// Nom personnalisé existant → on le conserve, le SSO ne l'écrase pas
|
||||
$sessionName = $dbName;
|
||||
} else {
|
||||
// Première connexion → on persiste le nom SSO
|
||||
$sessionName = $ssoName;
|
||||
if ($ssoName !== '' && $pdo) {
|
||||
try {
|
||||
$pdo->prepare(
|
||||
'INSERT INTO user_profiles (email, display_name, updated_at)
|
||||
VALUES (:e, :n, now())
|
||||
ON CONFLICT (email) DO NOTHING'
|
||||
)->execute([':e' => strtolower(trim($email)), ':n' => $ssoName]);
|
||||
} catch (\Throwable) {}
|
||||
}
|
||||
}
|
||||
|
||||
// Ouvre la session authentifiée
|
||||
session_regenerate_id(true);
|
||||
$_SESSION['user_email'] = strtolower(trim($email));
|
||||
$_SESSION['user_display_name'] = $displayName;
|
||||
$_SESSION['user_display_name'] = $sessionName;
|
||||
$_SESSION['oidc'] = [
|
||||
'issuer' => $OIDC_ISSUER,
|
||||
'sub' => $claims['sub'] ?? null,
|
||||
@@ -160,23 +189,6 @@ $_SESSION['oidc'] = [
|
||||
'expires_at' => time() + (int)($tokens['expires_in'] ?? 3600),
|
||||
];
|
||||
|
||||
// Persiste le nom d'affichage en base (seulement s'il vient du SSO et que la table existe)
|
||||
if ($displayName !== '') {
|
||||
require_once dirname(__DIR__, 2) . '/src/auth.php';
|
||||
$pdo = dbPdo();
|
||||
if ($pdo) {
|
||||
try {
|
||||
$st = $pdo->prepare(
|
||||
'INSERT INTO user_profiles (email, display_name, updated_at)
|
||||
VALUES (:e, :n, now())
|
||||
ON CONFLICT (email) DO NOTHING'
|
||||
);
|
||||
$st->execute([':e' => strtolower(trim($email)), ':n' => $displayName]);
|
||||
} catch (\Throwable) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$target = $_SESSION['oidc_return_to'] ?? '/';
|
||||
unset($_SESSION['oidc_return_to'], $_SESSION['oidc_flow']);
|
||||
if (!is_string($target) || $target === '' || $target[0] !== '/') {
|
||||
|
||||
Reference in New Issue
Block a user