diff --git a/core.php b/core.php index c82f963..64266fc 100644 --- a/core.php +++ b/core.php @@ -4,4 +4,6 @@ require_once __DIR__ . "/version.php"; require_once __DIR__ . "/lib/migrate.php"; +require_once __DIR__ . "/lib/security.php"; + migrate(); \ No newline at end of file diff --git a/html/index.php b/html/index.php index 080c129..e932135 100644 --- a/html/index.php +++ b/html/index.php @@ -3,7 +3,8 @@ require_once __DIR__ . "/../core.php"; require_once __DIR__ . "/../lib/pairing.php"; require_once __DIR__ . "/../lib/rating.php"; -require_once __DIR__ . "/../lib/security.php"; + +ensureSession(); function renderChoice(): void { [$left, $right] = [$_SESSION["left"], $_SESSION["right"]]; @@ -60,8 +61,6 @@ function voteAndNextPairing(int $winner): array { return [$left, $right]; } -session_start(); - [$_SESSION["left"], $_SESSION["right"], $render] = match (true) { isset($_GET["new"]), !isset($_SESSION["left"]) => [...newPairing(), false], isset($_GET["left"]) => [...voteAndNextPairing(LEFT), false], diff --git a/lib/rating.php b/lib/rating.php index c04e7c9..2bb5056 100644 --- a/lib/rating.php +++ b/lib/rating.php @@ -12,8 +12,12 @@ function getEloForMob(int $mob): int { function addMatch(int $mob1, int $mob2, int $winner, string $session): void { global $pdo; - $query = $pdo->prepare("INSERT INTO mm_matches (mob1fk, mob2fk, winner, session) VALUES (?, ?, ?, ?)"); + $query = $pdo->prepare("INSERT INTO mm_matches (mob1fk, mob2fk, winner, session) VALUES (?, ?, ?, ?) RETURNING id"); $query->execute([$mob1, $mob2, $winner, $session]); + + $result = $query->fetch(PDO::FETCH_ASSOC); + + auditLog(AUDIT_EVENT_MATCH_ADDED, session_id(), $result["id"]); } function getMobsWithMetaData($orderBy = "rating", $direction = "DESC"): array { diff --git a/lib/security.php b/lib/security.php index d4acc34..7fdbbe1 100644 --- a/lib/security.php +++ b/lib/security.php @@ -3,3 +3,20 @@ function makeCcrfToken(): string { return bin2hex(random_bytes(8)); } + +const AUDIT_EVENT_SESSION_CREATED = "session_created"; +const AUDIT_EVENT_MATCH_ADDED = "match_added"; + +function auditLog(string $event, string $session, string|null $details) { + global $pdo; + $query = $pdo->prepare("INSERT INTO mm_audit_log (event, session, details) VALUES (?, ?, ?)"); + $query->execute([$event, $session, $details]); +} + +function ensureSession() { + session_start(); + if (!isset($_SESSION["exists"])) { + $_SESSION["exists"] = true; + auditLog(AUDIT_EVENT_SESSION_CREATED, session_id(), null); + } +} \ No newline at end of file diff --git a/migrations/0001_mobsMatchesAndRating.sql b/migrations/0001_mobsMatchesAndRating.sql index cfa2ef0..2650654 100644 --- a/migrations/0001_mobsMatchesAndRating.sql +++ b/migrations/0001_mobsMatchesAndRating.sql @@ -23,7 +23,7 @@ create table mm_matches session varchar(255) ); -create table public.mm_history_cache +create table mm_history_cache ( ratings jsonb not null, last_update bigint not null @@ -201,3 +201,12 @@ FROM ( ON key_dates.id = history.last_update ) AS ratings_at_key_date, jsonb_each(ratings_at_key_date.ratings) AS ratings(key, value); + + +create table mm_audit_log +( + time timestamp default CURRENT_TIMESTAMP not null, + session varchar(255) not null, + event varchar(255) not null, + details text +);