| Server IP : 10.200.247.200 / Your IP : 216.73.217.19 Web Server : Apache System : Linux synergy-usa-sites 6.8.0-138-generic #138-Ubuntu SMP PREEMPT_DYNAMIC Fri Jul 31 22:41:49 UTC 2026 x86_64 User : jeremy ( 1001) PHP Version : 8.4.25 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : OFF Directory : /var/www/development/callings.lvsaints.com/ |
Upload File : |
<?php
// Shared helpers: DB connection, sessions, auth, CSRF, escaping.
declare(strict_types=1);
$CONFIG = require __DIR__ . '/config.php';
// --- Force HTTPS ------------------------------------------------------------
// When https_only is on, upgrade any plain-HTTP request before we start the
// session (so the Secure login cookie actually works). Honors a reverse
// proxy's X-Forwarded-Proto. Runs on every page since they all include lib.php.
if (($CONFIG['https_only'] ?? false) && PHP_SAPI !== 'cli') {
$isHttps = (!empty($_SERVER['HTTPS']) && strtolower((string) $_SERVER['HTTPS']) !== 'off')
|| (($_SERVER['HTTP_X_FORWARDED_PROTO'] ?? '') === 'https')
|| ((int) ($_SERVER['SERVER_PORT'] ?? 0) === 443);
if (!$isHttps) {
$host = $_SERVER['HTTP_HOST'] ?? '';
// Only redirect to a sane host — never echo an attacker-supplied Host header.
if ($host !== '' && preg_match('/^[A-Za-z0-9.\-]+(:\d+)?$/', $host)) {
header('Location: https://' . $host . ($_SERVER['REQUEST_URI'] ?? '/'), true, 302);
exit;
}
}
}
// --- Secure session ---------------------------------------------------------
session_set_cookie_params([
'httponly' => true,
'samesite' => 'Lax',
'secure' => $CONFIG['https_only'],
]);
session_start();
// --- Database ---------------------------------------------------------------
function db(): PDO
{
static $pdo = null;
global $CONFIG;
if ($pdo === null) {
$dsn = sprintf(
'mysql:host=%s;port=%d;dbname=%s;charset=utf8mb4',
$CONFIG['db_host'],
$CONFIG['db_port'] ?? 3306,
$CONFIG['db_name']
);
$pdo = new PDO($dsn, $CONFIG['db_user'], $CONFIG['db_pass'], [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
]);
}
return $pdo;
}
// --- Auth -------------------------------------------------------------------
function current_user(): ?array
{
if (empty($_SESSION['user_id'])) {
return null;
}
$stmt = db()->prepare('SELECT id, email, role, ward_id FROM users WHERE id = ?');
$stmt->execute([$_SESSION['user_id']]);
return $stmt->fetch() ?: null;
}
function require_login(): array
{
$user = current_user();
if (!$user) {
header('Location: login.php');
exit;
}
return $user;
}
// Anyone who can edit a board (a ward admin or the super admin).
function require_editor(): array
{
$user = require_login();
if (!in_array($user['role'], ['admin', 'super_admin'], true)) {
http_response_code(403);
exit('Forbidden — admin access required.');
}
return $user;
}
// --- Roles & ward scoping ---------------------------------------------------
function is_super(array $user): bool
{
return $user['role'] === 'super_admin';
}
function can_view_ward(array $user, int $wardId): bool
{
return is_super($user) || (int) $user['ward_id'] === $wardId;
}
function can_edit_ward(array $user, int $wardId): bool
{
if (is_super($user)) {
return true;
}
return $user['role'] === 'admin' && (int) $user['ward_id'] === $wardId;
}
function all_wards(): array
{
return db()->query('SELECT id, name, slug FROM wards ORDER BY name')->fetchAll();
}
function ward_name(int $wardId): string
{
$stmt = db()->prepare('SELECT name FROM wards WHERE id = ?');
$stmt->execute([$wardId]);
$row = $stmt->fetch();
return $row ? $row['name'] : 'Unknown ward';
}
// Which ward is the user acting on right now?
// Regular users are locked to their own ward; super admins can switch
// via ?ward=ID (remembered in the session).
function active_ward_id(array $user): int
{
if (!is_super($user)) {
return (int) $user['ward_id'];
}
$requested = (int) ($_GET['ward'] ?? $_SESSION['active_ward'] ?? 0);
if ($requested) {
$stmt = db()->prepare('SELECT id FROM wards WHERE id = ?');
$stmt->execute([$requested]);
if ($stmt->fetch()) {
$_SESSION['active_ward'] = $requested;
return $requested;
}
}
$first = db()->query('SELECT id FROM wards ORDER BY id LIMIT 1')->fetch();
return $first ? (int) $first['id'] : 0;
}
function slugify(string $s): string
{
$s = strtolower(trim($s));
$s = preg_replace('/[^a-z0-9]+/', '-', $s);
return trim($s, '-') ?: 'ward';
}
// --- CSRF -------------------------------------------------------------------
function csrf_token(): string
{
if (empty($_SESSION['csrf'])) {
$_SESSION['csrf'] = bin2hex(random_bytes(32));
}
return $_SESSION['csrf'];
}
function csrf_check(): void
{
$sent = $_POST['csrf'] ?? '';
if (!hash_equals($_SESSION['csrf'] ?? '', $sent)) {
http_response_code(400);
exit('Bad CSRF token — reload the page and try again.');
}
}
// --- Escaping ---------------------------------------------------------------
function e(?string $s): string
{
return htmlspecialchars((string) $s, ENT_QUOTES, 'UTF-8');
}