installation du réperttoire www/live afin de gérer le vérificateur d'accès à la page live (wasm et api)
This commit is contained in:
@@ -44,12 +44,6 @@ define("NIVEAU_ACCES_MINI_EDITEUR", 50);
|
||||
define("NIVEAU_ACCES_MAXI", 99);
|
||||
|
||||
|
||||
//=====================================================================
|
||||
// Types d'utilisateurs :
|
||||
define("TYPE_UTILISATEUR_INCONNU", 0);
|
||||
define("TYPE_UTILISATEUR_PARTICULIER", 1);
|
||||
define("TYPE_UTILISATEUR_PROFESSIONNEL", 2);
|
||||
|
||||
|
||||
//=====================================================================
|
||||
// Informations générales :
|
||||
@@ -61,12 +55,6 @@ define("SOCIETE", "Koriolan");
|
||||
define("ANNEE_CREATION", 2019);
|
||||
|
||||
|
||||
//=====================================================================
|
||||
// Paramètres de traitement des données, maps...
|
||||
define ("DATE_SEUIL_1", 90);
|
||||
define ("DATE_SEUIL_2", 180);
|
||||
define ("CLE_PRIMAIRE_BATEAU_DEMO", 25); // Bateau "DEMO". Les données de ce bateau sont décalées dans le temps chaque matin à 00hxx.
|
||||
|
||||
|
||||
//=====================================================================
|
||||
// Répertoires et fichiers :
|
||||
@@ -76,39 +64,16 @@ if (PRODUCTION)
|
||||
{
|
||||
define("REPERTOIRE_BATEAUX", REPERTOIRE_HOME."/bateaux"); // Pas de '/' de terminaison
|
||||
define("REPERTOIRE_BATEAUX_ARCHIVES", REPERTOIRE_HOME."/bateaux_archives"); // Pas de '/' de terminaison
|
||||
define("REPERTOIRE_FICHIERS_CRON", REPERTOIRE_HOME."/cron/prod"); // Pas de '/' de terminaison
|
||||
define("REPERTOIRE_LOGS", REPERTOIRE_HOME."/logs/prod"); // Pas de '/' de terminaison
|
||||
define("NB_JOURS_AVANT_SUPPRESSION_FICHIERS_ARCHIVES", 90);
|
||||
define("NB_JOURS_AVANT_SUPPRESSION_FICHIERS_ANOMALIES", 180);
|
||||
define("NB_JOURS_AVANT_SUPPRESSION_FICHIERS_LOGS", 90);
|
||||
}
|
||||
else
|
||||
{
|
||||
define("REPERTOIRE_BATEAUX", REPERTOIRE_HOME."/bateaux_dev"); // Pas de '/' de terminaison
|
||||
define("REPERTOIRE_BATEAUX_ARCHIVES", REPERTOIRE_HOME."/bateaux_dev_archives"); // Pas de '/' de terminaison
|
||||
define("REPERTOIRE_FICHIERS_CRON", REPERTOIRE_HOME."/cron/dev"); // Pas de '/' de terminaison
|
||||
define("REPERTOIRE_LOGS", REPERTOIRE_HOME."/logs/dev"); // Pas de '/' de terminaison
|
||||
define("NB_JOURS_AVANT_SUPPRESSION_FICHIERS_ARCHIVES", 30);
|
||||
define("NB_JOURS_AVANT_SUPPRESSION_FICHIERS_ANOMALIES", 30);
|
||||
define("NB_JOURS_AVANT_SUPPRESSION_FICHIERS_LOGS", 30);
|
||||
}
|
||||
|
||||
define("REPERTOIRE_VERSIONS", REPERTOIRE_HOME."/versions"); // Pas de '/' de terminaison
|
||||
define("REPERTOIRE_VERSIONS_SHIPHEART", REPERTOIRE_VERSIONS.'/shipheart'); // Pas de '/' de terminaison
|
||||
|
||||
define("REPERTOIRE_LOGS_UPLOADS", REPERTOIRE_LOGS."/uploads"); // Pas de '/' de terminaison
|
||||
define("REPERTOIRE_LOGS_SYNTHESE", REPERTOIRE_LOGS."/synthese"); // Pas de '/' de terminaison
|
||||
|
||||
define("PREFIXE_REPERTOIRE_BATEAU_ARCHIVES", "bateau_"); // La clé primaire du bateau dans TB_Bateaux est ajouté pour former le nom du répertoire du bateau dans 'bateaux_archives' (ou 'bateaux_dev_archives' pour DEV).
|
||||
|
||||
define("SOUS_REPERTOIRE_BATEAU_ANOMALIES", "uploads_anomalies"); // Pas de '/' de terminaison
|
||||
define("SOUS_REPERTOIRE_BATEAU_ARCHIVES", "uploads_ok"); // Pas de '/' de terminaison
|
||||
define("SOUS_REPERTOIRE_BATEAU_HISTORIQUE_BDD", "bdd_historique"); // Pas de '/' de terminaison
|
||||
define("SOUS_REPERTOIRE_BATEAU_TEMP", "temp"); // Pas de '/' de terminaison
|
||||
|
||||
|
||||
define("PREFIXE_FICHIER_SAUVEGARDE_BDD_BATEAU", "sauvegarde_bdd_"); // Le nom de la base de données est ensuite ajouté à la suite, avant le marqueur SQL. Par exemple 'sauvegarde_bdd_Bateau_22.sql'
|
||||
|
||||
|
||||
//=====================================================================
|
||||
// Types de fichiers :
|
||||
@@ -159,20 +124,6 @@ define("ETAT_CARTE_EN_PANNE", 2);
|
||||
define("ETAT_CARTE_REBUT", 3);
|
||||
|
||||
|
||||
//=====================================================================
|
||||
// Types et Sous_types d'historique :
|
||||
// A REVOIR COMPLETEMENT DEPUIS LE FICHIER 'gestion_bdd.h' de l'appli en C
|
||||
define ("SYSTEME", 1000);
|
||||
define ("SYSTEME_REINIT", 1001); // Réinitialisation de l'application
|
||||
define ("SYSTEME_ERREUR_MYSQL", 1002);
|
||||
define ("SYSTEME_CONNEXION_USER", 1003);
|
||||
define ("SYSTEME_REINIT_MDP_USER", 1004);
|
||||
define ("SYSTEME_REBOOT", 1005); // Reboot du système
|
||||
define ("SYSTEME_ARRET", 1006); // Arrêt du système (Shutdown -h)
|
||||
define ("SYSTEME_REINIT_BOX", 1007);
|
||||
define ("SYSTEME_TIME_OUT_CONNEXION", 1008);
|
||||
define ("SYSTEME_REINIT_TEIOT", 1009);
|
||||
define ("SYSTEME_DECONNEXION_USER", 1010);
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// Indique si ce répertoire correspond à un site/tâche de PROD ou de DEV - isolé de config.php (synthèse §49) pour
|
||||
// pouvoir être lu seul par les scripts qui n'ont besoin que des définitions (vérificateur du Live distant, appelé à
|
||||
// chaque requête : il ne charge pas fonctions.php, et donc ni TCPDF, ni l'envoi d'e-mails, etc.).
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
define("PRODUCTION", false); // 'true' pour les sites/tâches accessibles au public, ou 'false' pour les sites/tâches de test
|
||||
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
//************************************************************************************************************
|
||||
// live/auth.php - Ouverture d'une session Live (synthèse §49).
|
||||
// Appelé via https://b<N>.ship2net.fr/_auth?ticket=... (routeur Traefik dédié, SANS ForwardAuth), juste après le
|
||||
// clic sur "Live" dans le portail. Consomme le ticket (60 s, usage unique, lié au bateau), crée une session et pose
|
||||
// le cookie HttpOnly propre au sous-domaine du bateau, puis renvoie vers l'application.
|
||||
//************************************************************************************************************
|
||||
require_once(__DIR__."/commun.php");
|
||||
|
||||
$id_bateau = Bateau_depuis_hote($_SERVER['HTTP_HOST'] ?? '');
|
||||
$ticket = $_GET['ticket'] ?? '';
|
||||
if ($id_bateau == 0 || !is_string($ticket) || preg_match('/^[0-9a-f]{64}$/', $ticket) !== 1)
|
||||
{
|
||||
Page_refus(400, "Lien Live invalide", "Ce lien n'est pas valide. Ouvrez le Live depuis la page du bateau, sur le portail.");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$db = Connexion_live();
|
||||
|
||||
// Purge des tickets et sessions périmés depuis plus d'un jour (ici : appelé rarement, à chaque ouverture de session) :
|
||||
$db->query("DELETE FROM TB_Tickets_live WHERE Expiration < NOW() - INTERVAL 1 DAY");
|
||||
$db->query("DELETE FROM TB_Sessions_live WHERE Expiration < NOW() - INTERVAL 1 DAY");
|
||||
|
||||
// Consommation du ticket : toutes les conditions DANS la mise à jour (usage unique, même en cas de requêtes simultanées) :
|
||||
$empreinte_ticket = hash('sha256', $ticket);
|
||||
$stmt = $db->prepare("UPDATE TB_Tickets_live SET Date_utilisation=NOW()
|
||||
WHERE Empreinte=? AND ID_Bateau=? AND Date_utilisation IS NULL AND Expiration > NOW()");
|
||||
$stmt->bind_param('si', $empreinte_ticket, $id_bateau);
|
||||
$stmt->execute();
|
||||
$consomme = ($stmt->affected_rows == 1);
|
||||
$stmt->close();
|
||||
if (!$consomme) Page_refus(403, "Lien Live expiré", "Ce lien a expiré ou a déjà été utilisé. Ouvrez à nouveau le Live depuis la page du bateau, sur le portail.");
|
||||
|
||||
$stmt = $db->prepare("SELECT ID_Shipmember FROM TB_Tickets_live WHERE Empreinte=?");
|
||||
$stmt->bind_param('s', $empreinte_ticket);
|
||||
$stmt->execute();
|
||||
$id_shipmember = (int)$stmt->get_result()->fetch_row()[0];
|
||||
$stmt->close();
|
||||
|
||||
if (!Droit_live($db, $id_shipmember, $id_bateau)) Page_refus(403, "Accès refusé", "Vous n'avez pas (ou plus) accès à ce bateau.");
|
||||
|
||||
// Durée de session (TB_Configuration, heures) :
|
||||
$duree = DUREE_SESSION_LIVE_DEFAUT;
|
||||
$resultat = $db->query("SELECT Valeur FROM TB_Configuration WHERE Nom='Duree_session_live' AND Validite=1");
|
||||
if ($ligne = $resultat->fetch_row()) $duree = max(1, (int)$ligne[0]);
|
||||
|
||||
// Création de la session : seule l'empreinte de la valeur du cookie est enregistrée :
|
||||
$valeur_cookie = bin2hex(random_bytes(32));
|
||||
$empreinte_session = hash('sha256', $valeur_cookie);
|
||||
$stmt = $db->prepare("INSERT INTO TB_Sessions_live (Empreinte, ID_Shipmember, ID_Bateau, Expiration) VALUES (?, ?, ?, NOW() + INTERVAL ? HOUR)");
|
||||
$stmt->bind_param('siii', $empreinte_session, $id_shipmember, $id_bateau, $duree);
|
||||
$stmt->execute();
|
||||
$stmt->close();
|
||||
$db->close();
|
||||
}
|
||||
catch (Throwable $e)
|
||||
{
|
||||
error_log("live/auth.php : ".$e->getMessage());
|
||||
Page_refus(503, "Service momentanément indisponible", "Le Live ne peut pas être ouvert pour l'instant. Réessayez dans quelques instants.");
|
||||
}
|
||||
|
||||
// Cookie propre à CE sous-domaine (pas d'attribut domain), inaccessible au code de la page (HttpOnly) :
|
||||
setcookie(NOM_COOKIE_LIVE, $valeur_cookie, [
|
||||
'expires' => time() + $duree * 3600,
|
||||
'path' => '/',
|
||||
'secure' => true,
|
||||
'httponly' => true,
|
||||
'samesite' => 'Lax',
|
||||
]);
|
||||
header('Cache-Control: no-store');
|
||||
header('Location: /', true, 303); // L'URL du ticket disparaît de la barre d'adresse
|
||||
exit();
|
||||
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
//************************************************************************************************************
|
||||
// live/commun.php - Fonctions communes du vérificateur du Live distant (synthèse §49).
|
||||
//
|
||||
// Le dossier /var/www/live est servi par le conteneur ship2net-php sur un port INTERNE (8081), joint uniquement
|
||||
// par Traefik : aucun routeur public ne mène à ce port, et il est hors de /var/www/html (le site public). Il ne
|
||||
// charge que les définitions (connexion à la base), pas fonctions.php : il est appelé à chaque requête vers un
|
||||
// bateau (fichiers du wasm et API).
|
||||
//************************************************************************************************************
|
||||
|
||||
require_once(__DIR__."/../config/production.php");
|
||||
require_once(__DIR__."/../config/definitions.php");
|
||||
|
||||
const NOM_COOKIE_LIVE = "ship2net_live";
|
||||
const DUREE_SESSION_LIVE_DEFAUT = 4; // heures, si TB_Configuration.Duree_session_live est absente
|
||||
|
||||
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); // Erreurs SQL en exceptions (traitées : refus par défaut)
|
||||
|
||||
|
||||
//************************************************************************************************************
|
||||
// Fonction : Numéro du bateau visé, d'après le nom d'hôte de la requête d'origine (b<N>.ship2net.fr).
|
||||
// Reçoit : Le nom d'hôte
|
||||
// Retour : Le numéro (entier > 0), ou 0 si le nom ne correspond pas
|
||||
//************************************************************************************************************
|
||||
function Bateau_depuis_hote($hote)
|
||||
{
|
||||
$hote = strtolower(preg_replace('/:\d+$/', '', trim((string)$hote))); // sans port éventuel
|
||||
if (preg_match('/^b([1-9][0-9]{0,9})\.'.preg_quote(URL_SITE, '/').'$/', $hote, $m) !== 1) return 0;
|
||||
return (int)$m[1];
|
||||
}
|
||||
|
||||
|
||||
//************************************************************************************************************
|
||||
// Fonction : Connexion à la base principale (mêmes paramètres que le site).
|
||||
// Retour : L'objet mysqli (exception en cas d'échec)
|
||||
//************************************************************************************************************
|
||||
function Connexion_live()
|
||||
{
|
||||
return new mysqli(BDD_HOST, BDD_USER, BDD_PASSWORD, BDD_DATABASE);
|
||||
}
|
||||
|
||||
|
||||
//************************************************************************************************************
|
||||
// Fonction : Page d'explication renvoyée au navigateur (ticket invalide, session expirée...), avec un lien vers le
|
||||
// portail. Le code HTTP est fourni par l'appelant.
|
||||
//************************************************************************************************************
|
||||
function Page_refus($code_http, $titre, $texte)
|
||||
{
|
||||
http_response_code($code_http);
|
||||
header('Content-Type: text/html; charset=UTF-8');
|
||||
header('Cache-Control: no-store');
|
||||
echo '<!DOCTYPE html><html lang="fr"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1">'
|
||||
.'<title>'.htmlspecialchars($titre).'</title>'
|
||||
.'<style>body{font-family:-apple-system,Segoe UI,Roboto,Arial,sans-serif;color:#004563;text-align:center;padding:3em 1em}'
|
||||
.'a{display:inline-block;margin-top:1.5em;padding:.6em 1.5em;border-radius:1em;background:#004563;color:#fff;text-decoration:none}</style>'
|
||||
.'</head><body><h1>'.htmlspecialchars($titre).'</h1><p>'.htmlspecialchars($texte).'</p>'
|
||||
.'<a href="https://'.URL_SITE.'/shipmembers.php">'.htmlspecialchars("Retour au portail Ship2net").'</a></body></html>';
|
||||
exit();
|
||||
}
|
||||
|
||||
|
||||
//************************************************************************************************************
|
||||
// Fonction : Le ShipMember a-t-il droit au Live de ce bateau EN CE MOMENT ? Compte valide, et : administrateur, ou
|
||||
// accès 'actif' non expiré au bateau. Appelée à l'ouverture de la session ET à chaque requête : un accès
|
||||
// suspendu ou révoqué depuis le portail coupe le Live immédiatement.
|
||||
// Retour : true si autorisé
|
||||
//************************************************************************************************************
|
||||
function Droit_live($db, $id_shipmember, $id_bateau)
|
||||
{
|
||||
$stmt = $db->prepare("SELECT 1 FROM TB_Shipmembers M
|
||||
WHERE M.ID=? AND M.Validite=1
|
||||
AND (M.Niveau_acces >= ?
|
||||
OR EXISTS (SELECT 1 FROM TB_Lien_bateau_shipmember L
|
||||
WHERE L.ID_Shipmember=M.ID AND L.ID_Bateau=? AND L.Statut='actif' AND L.Fin_validite >= NOW()))");
|
||||
$niveau_admin = NIVEAU_ACCES_MINI_ADMINISTRATEUR;
|
||||
$stmt->bind_param('iii', $id_shipmember, $niveau_admin, $id_bateau);
|
||||
$stmt->execute();
|
||||
$autorise = ($stmt->get_result()->num_rows == 1);
|
||||
$stmt->close();
|
||||
return $autorise;
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
//************************************************************************************************************
|
||||
// live/verifier.php - Vérification d'une session Live, appelée par Traefik (middleware ForwardAuth) pour CHAQUE
|
||||
// requête vers un bateau (fichiers du wasm comme API) - synthèse §49.
|
||||
// Traefik transmet les en-têtes de la requête d'origine (cookie compris) et indique l'hôte d'origine dans
|
||||
// X-Forwarded-Host (qu'il réécrit lui-même : non falsifiable par le client, et ce port n'est joignable que par lui).
|
||||
// Réponse 200 : Traefik laisse passer la requête vers le CM5. Toute autre réponse est renvoyée telle quelle au
|
||||
// navigateur. Refus par défaut : toute anomalie (base injoignable comprise) aboutit à un refus.
|
||||
//************************************************************************************************************
|
||||
require_once(__DIR__."/commun.php");
|
||||
|
||||
$id_bateau = Bateau_depuis_hote($_SERVER['HTTP_X_FORWARDED_HOST'] ?? '');
|
||||
$valeur_cookie = $_COOKIE[NOM_COOKIE_LIVE] ?? '';
|
||||
|
||||
$autorise = false;
|
||||
if ($id_bateau > 0 && is_string($valeur_cookie) && preg_match('/^[0-9a-f]{64}$/', $valeur_cookie) === 1)
|
||||
{
|
||||
try
|
||||
{
|
||||
$db = Connexion_live();
|
||||
$empreinte = hash('sha256', $valeur_cookie);
|
||||
$stmt = $db->prepare("SELECT ID_Shipmember FROM TB_Sessions_live WHERE Empreinte=? AND ID_Bateau=? AND Expiration > NOW()");
|
||||
$stmt->bind_param('si', $empreinte, $id_bateau);
|
||||
$stmt->execute();
|
||||
$ligne = $stmt->get_result()->fetch_row();
|
||||
$stmt->close();
|
||||
if ($ligne) $autorise = Droit_live($db, (int)$ligne[0], $id_bateau);
|
||||
$db->close();
|
||||
}
|
||||
catch (Throwable $e)
|
||||
{
|
||||
error_log("live/verifier.php : ".$e->getMessage());
|
||||
$autorise = false;
|
||||
}
|
||||
}
|
||||
|
||||
if ($autorise)
|
||||
{
|
||||
http_response_code(200);
|
||||
exit();
|
||||
}
|
||||
|
||||
// Refus : page explicative pour une navigation (le navigateur affiche une page), réponse brève pour l'API (appels du wasm) :
|
||||
$accept = $_SERVER['HTTP_ACCEPT'] ?? '';
|
||||
if (strpos($accept, 'text/html') !== false)
|
||||
{
|
||||
Page_refus(401, "Session Live expirée", "Votre session Live a expiré, ou votre accès à ce bateau a changé. Ouvrez à nouveau le Live depuis la page du bateau, sur le portail.");
|
||||
}
|
||||
http_response_code(401);
|
||||
header('Content-Type: text/plain; charset=UTF-8');
|
||||
header('Cache-Control: no-store');
|
||||
echo "Session Live absente ou expirée";
|
||||
@@ -0,0 +1,47 @@
|
||||
-- ============================================================================
|
||||
-- Live distant (lot 2, synthèse §49) : tickets et sessions d'accès au wasm d'un bateau via b<N>.ship2net.fr.
|
||||
--
|
||||
-- Parcours : le portail crée un TICKET (aléatoire, 60 s, usage unique, lié à un ShipMember et un bateau) et
|
||||
-- redirige vers https://b<N>.ship2net.fr/_auth?ticket=... ; le vérificateur (VPS, port interne) consomme le
|
||||
-- ticket et crée une SESSION (aléatoire, Duree_session_live heures), portée par un cookie HttpOnly propre au
|
||||
-- sous-domaine du bateau ; Traefik (ForwardAuth) fait vérifier cette session à chaque requête, avec contrôle de
|
||||
-- l'accès en base à ce moment-là (un accès suspendu ou révoqué coupe le Live immédiatement).
|
||||
--
|
||||
-- Ni le ticket ni la session ne sont stockés en clair : seule leur empreinte SHA-256 l'est (une fuite de la
|
||||
-- table ne permet pas d'ouvrir de session).
|
||||
-- ============================================================================
|
||||
|
||||
CREATE TABLE TB_Tickets_live (
|
||||
ID INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
Empreinte CHAR(64) CHARACTER SET ascii COLLATE ascii_bin NOT NULL COMMENT 'SHA-256 (hexadécimal) du ticket - jamais le ticket lui-même',
|
||||
ID_Shipmember INT(10) UNSIGNED NOT NULL COMMENT 'ShipMember pour qui le ticket a été émis',
|
||||
ID_Bateau INT(10) UNSIGNED NOT NULL COMMENT 'Bateau visé : le ticket n''est valable que sur b<ID_Bateau>.ship2net.fr',
|
||||
Expiration DATETIME NOT NULL COMMENT 'Création + 60 s',
|
||||
Date_utilisation DATETIME NULL DEFAULT NULL COMMENT 'Renseignée à la consommation : un ticket ne sert qu''une fois',
|
||||
Date_creation TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (ID),
|
||||
UNIQUE KEY uk_ticket_empreinte (Empreinte),
|
||||
KEY idx_ticket_expiration (Expiration),
|
||||
CONSTRAINT fk_ticket_live_shipmember FOREIGN KEY (ID_Shipmember) REFERENCES TB_Shipmembers (ID),
|
||||
CONSTRAINT fk_ticket_live_bateau FOREIGN KEY (ID_Bateau) REFERENCES TB_Bateaux (Cle_primaire)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_uca1400_ai_ci
|
||||
COMMENT='Tickets d''ouverture d''une session Live (60 s, usage unique) - synthèse §49';
|
||||
|
||||
CREATE TABLE TB_Sessions_live (
|
||||
ID INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
Empreinte CHAR(64) CHARACTER SET ascii COLLATE ascii_bin NOT NULL COMMENT 'SHA-256 (hexadécimal) de la valeur du cookie - jamais la valeur elle-même',
|
||||
ID_Shipmember INT(10) UNSIGNED NOT NULL,
|
||||
ID_Bateau INT(10) UNSIGNED NOT NULL COMMENT 'La session n''est valable que sur b<ID_Bateau>.ship2net.fr',
|
||||
Expiration DATETIME NOT NULL COMMENT 'Création + Duree_session_live heures (TB_Configuration)',
|
||||
Date_creation TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (ID),
|
||||
UNIQUE KEY uk_session_empreinte (Empreinte),
|
||||
KEY idx_session_expiration (Expiration),
|
||||
CONSTRAINT fk_session_live_shipmember FOREIGN KEY (ID_Shipmember) REFERENCES TB_Shipmembers (ID),
|
||||
CONSTRAINT fk_session_live_bateau FOREIGN KEY (ID_Bateau) REFERENCES TB_Bateaux (Cle_primaire)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_uca1400_ai_ci
|
||||
COMMENT='Sessions Live ouvertes (cookie HttpOnly par sous-domaine de bateau) - synthèse §49';
|
||||
|
||||
INSERT INTO TB_Configuration (Validite, Nom, Description, Valeur)
|
||||
VALUES (1, 'Duree_session_live',
|
||||
'Durée (heures) d''une session Live distante, ouverte depuis le bouton Live du portail', '4');
|
||||
Reference in New Issue
Block a user