refactor(phase-2): extract auth CSS to stylesheet, harden session API, fix Firebase v10 error codes

- Move 374-line inline style block from login.php into assets/style.css (Phase 2 section)
- Add auth-page, auth-card, auth-tabs, auth-form, profile-shell and related
  classes to the main stylesheet as the single source of truth for all styles
- Fix Firebase v10 compat SDK error code: auth/invalid-credential now handled
  alongside legacy auth/wrong-password and auth/user-not-found codes
- Harden api/session.php: add Content-Type JSON header, email format validation,
  and a full security documentation comment explaining the token trust model
- Add FOUC comment to partials/head.php clarifying dark-only design intent
This commit is contained in:
2026-05-22 08:22:54 +02:00
parent c9ad44208d
commit 01a6d0f00a
4 changed files with 331 additions and 314 deletions
+40 -18
View File
@@ -1,5 +1,22 @@
<?php
// PHP session synchronizer endpoint for Firebase Auth
/**
* PHP Session Synchronizer for Firebase Auth
*
* This endpoint is called client-side via XHR whenever Firebase Auth detects
* a state change (login or logout). It creates or destroys a PHP session that
* mirrors the Firebase auth state, allowing server-rendered PHP pages to react
* to auth status.
*
* SECURITY NOTE: This endpoint accepts the Firebase UID and email from the
* client POST body and trusts them to set the PHP session. The Firebase ID Token
* is stored but NOT cryptographically verified server-side (which would require
* the Firebase Admin SDK or a REST call to the Google tokeninfo endpoint).
* This is an acceptable trade-off for a low-risk food blog, but for a
* production app handling sensitive data, server-side token verification
* via the Firebase Admin SDK should be implemented.
*/
header('Content-Type: application/json');
if (session_status() === PHP_SESSION_NONE) {
session_start();
@@ -8,32 +25,37 @@ if (session_status() === PHP_SESSION_NONE) {
$action = $_POST['action'] ?? '';
if ($action === 'login') {
$uid = $_POST['uid'] ?? '';
$email = $_POST['email'] ?? '';
$token = $_POST['token'] ?? '';
if ($uid !== '') {
$_SESSION['fc_user'] = [
'uid' => $uid,
'email' => $email,
'token' => $token
];
echo json_encode(['status' => 'success', 'message' => 'Logged in']);
} else {
$uid = trim($_POST['uid'] ?? '');
$email = trim($_POST['email'] ?? '');
$token = trim($_POST['token'] ?? '');
// Validate required fields reject obviously malformed requests early
if ($uid === '' || $email === '' || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
http_response_code(400);
echo json_encode(['status' => 'error', 'message' => 'Missing UID']);
echo json_encode(['status' => 'error', 'message' => 'Invalid or missing uid/email']);
exit;
}
$_SESSION['fc_user'] = [
'uid' => $uid,
'email' => $email,
'token' => $token, // Stored for potential future server-side verification
];
echo json_encode(['status' => 'success', 'message' => 'Logged in']);
} elseif ($action === 'logout') {
$_SESSION = [];
if (ini_get("session.use_cookies")) {
if (ini_get('session.use_cookies')) {
$params = session_get_cookie_params();
setcookie(session_name(), '', time() - 42000,
$params["path"], $params["domain"],
$params["secure"], $params["httponly"]
setcookie(
session_name(), '', time() - 42000,
$params['path'], $params['domain'],
$params['secure'], $params['httponly']
);
}
session_destroy();
echo json_encode(['status' => 'success', 'message' => 'Logged out']);
} else {
http_response_code(400);
echo json_encode(['status' => 'error', 'message' => 'Invalid action']);