PriviMetrics
Version 1.0.9 • 43 files • 278.98 KB
Files
.last_check
admin.php
assets/.htaccess
assets/dashboard-chart.php
assets/dashboard-logic.php
assets/dashboard-modals.php
assets/dashboard-tables.php
assets/dashboard-template.php
assets/trends-template.php
chosen-limits.php
dashboard.php
data/.htaccess
extensions-load.php
extensions.php
extensions.xml
extensions/.htaccess
extensions/extensions_off.txt
functions.php
getCountryFrom/db-ip.php
getCountryFrom/geo-lite.php
getCountryFrom/ip-api-com.php
getCountryFrom/ip-info.php
getCountryFrom/ip-stack.php
getCountryFrom/ip2location-io.php
getCountryFrom/privacy-friendly.php
index.html
install.php
limits-options.php
new_version.php
privimetrics-div.js
privimetrics.php
public.php
scripts.js
settings-config.php
settings.php
signup.php
storage.php
styles-mobile.css
styles.css
trends.css
trends.php
updater/index.php
version.txt
admin.php
<?php
// ===============================================================================
// PriviMetrics - Admin Configuration
// ===============================================================================
// Admin Authentication System
define('ADMIN_USERNAME', 'admin'); // @user-config
// This is hash for password: "admin123" - generate your own using signup.php
define('ADMIN_PASSWORD_HASH', '$2y$10$MGwiiWTPtH6rLi0qMxdKae1VdMMzQxlsFqasRfSGsDFkcXJNeqrVK'); // @user-config
define('ADMIN_EMAIL', ''); // @user-config // Optional email for notifications
if (!file_exists('config.php')) {
die('Configuration file not found. Please run install.php first.');
}
require_once 'config.php';
if (!file_exists('functions.php')) {
die('Functions file not found. Please check your installation.');
}
require_once 'functions.php';
startSecureSession();
// Handle logout
if (isset($_GET['logout'])) {
session_destroy();
header('Location: admin.php');
exit;
}
// Check if already logged in
if (isset($_SESSION['admin_logged_in']) && $_SESSION['admin_logged_in'] === true) {
header('Location: dashboard.php');
exit;
}
$error = '';
// Handle login
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (!isset($_POST['csrf_token']) || !verifyCSRFToken($_POST['csrf_token'])) {
$error = 'Invalid security token. Please try again.';
} else {
$username = sanitize($_POST['username'] ?? '');
$password = $_POST['password'] ?? '';
// Check rate limiting
if (!checkRateLimit('login_' . getClientIP(), 5, 900)) {
$error = 'Too many login attempts. Please try again later.';
} else {
if ($username === ADMIN_USERNAME && verifyPassword($password, ADMIN_PASSWORD_HASH)) {
session_regenerate_id(true);
$_SESSION['admin_logged_in'] = true;
$_SESSION['admin_username'] = $username;
$_SESSION['login_time'] = time();
$_SESSION['created'] = time();
session_write_close();
header('Location: dashboard.php');
exit;
} else {
$error = 'Invalid username or password.';
}
}
}
}
$csrfToken = generateCSRFToken();
$theme = sanitize($_GET['theme'] ?? ($config['default_theme'] ?? 'dark'));
?>
<!DOCTYPE html>
<html lang="en" data-theme="<?= $theme ?>" data-font="<?= htmlspecialchars($settings['ui_font'] ?? 'sora') ?>">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Admin Login - <?= sanitize($config['site_name'] ?? 'PriviMetrics') ?></title>
<style>
:root[data-theme="dark"] {
--bg-primary: #0a0a0a;
--bg-secondary: #151515;
--border-color: #252525;
--text-primary: #e5e5e5;
--text-secondary: #a0a0a0;
--accent: #f1484e;
--accent-hover: #d53b40ff;
--error-bg: #7f1d1d;
--error-border: #991b1b;
--error-text: #fecaca;
}
:root[data-theme="light"] {
--bg-primary: #ffffff;
--bg-secondary: #f9fafb;
--border-color: #e5e7eb;
--text-primary: #111827;
--text-secondary: #6b7280;
--accent: #f1484e;
--accent-hover: #d53b40ff;
--error-bg: #fee2e2;
--error-border: #fecaca;
--error-text: #991b1b;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
background: var(--bg-primary);
color: var(--text-primary);
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding: 20px;
}
.login-container {
background: var(--bg-secondary);
border: 1px solid var(--border-color);
border-radius: 12px;
padding: 40px;
max-width: 400px;
width: 100%;
}
.header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 24px;
}
.logo {
width: 48px;
height: 48px;
border-radius: 10px;
display: flex;
align-items: center;
justify-content: center;
font-weight: 700;
font-size: 20px;
color: white;
background: var(--accent);
}
.theme-toggle {
width: 40px;
height: 40px;
border: 1px solid var(--border-color);
border-radius: 8px;
background: var(--bg-primary);
color: var(--text-primary);
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
text-decoration: none;
font-size: 18px;
}
.theme-toggle:hover {
background: var(--bg-secondary);
}
h1 {
font-size: 24px;
margin-bottom: 8px;
}
p {
color: var(--text-secondary);
margin-bottom: 30px;
font-size: 14px;
}
.form-group {
margin-bottom: 20px;
}
label {
display: block;
margin-bottom: 8px;
font-size: 14px;
font-weight: 500;
}
input {
width: 100%;
padding: 12px 16px;
background: var(--bg-primary);
border: 1px solid var(--border-color);
border-radius: 8px;
color: var(--text-primary);
font-size: 14px;
}
input:focus {
outline: none;
border-color: var(--accent);
}
button {
width: 100%;
padding: 12px 16px;
background: var(--accent);
color: white;
border: none;
border-radius: 8px;
font-size: 14px;
font-weight: 600;
cursor: pointer;
}
button:hover {
background: var(--accent-hover);
}
.error {
padding: 12px 16px;
background: var(--error-bg);
border: 1px solid var(--error-border);
border-radius: 8px;
color: var(--error-text);
font-size: 14px;
margin-bottom: 20px;
}
</style>
</head>
<body>
<div class="login-container">
<div class="header">
<div class="logo">
<?php
$logo = $config['site_logo'] ?? 'PM';
if (str_starts_with($logo, 'img:')) {
$logoFile = substr($logo, 4);
echo '<img src="' . htmlspecialchars($logoFile) . '" alt="' . htmlspecialchars($config['site_name'] ?? 'PriviMetrics') . '" style="height:40px;">';
} else {
echo '<span>' . htmlspecialchars($logo) . '</span>';
}
?>
</div>
<a href="?theme=<?= $theme === 'dark' ? 'light' : 'dark' ?>" class="theme-toggle">
<?= $theme === 'dark' ? '<svg class="icon" viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2"> <circle cx="12" cy="12" r="5" /> <path d="M12 1v2M12 21v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M1 12h2M21 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42" /></svg>' : '<svg class="icon" viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2"> <path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" /></svg>' ?>
</a>
</div>
<h1>Welcome back</h1>
<p>Sign in to your analytics dashboard</p>
<?php if ($error): ?>
<div class="error"><?= sanitize($error) ?></div>
<?php endif; ?>
<form method="post">
<input type="hidden" name="csrf_token" value="<?= $csrfToken ?>">
<div class="form-group">
<label for="username">Username</label>
<input type="text" id="username" name="username" required autofocus>
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" id="password" name="password" required>
</div>
<button type="submit">Sign In</button>
</form>
</div>
</body>
</html>