v1.0.0.6
Publisium
- <?php
-
- declare(strict_types=1);
-
- require_once __DIR__ . '/includes/config.php';
- require_once __DIR__ . '/includes/database.php';
- require_once __DIR__ . '/includes/user-auth.php';
- require_once __DIR__ . '/includes/csrf.php';
- require_once __DIR__ . '/includes/language.php';
- require_once __DIR__ . '/includes/site-front.php';
- require_once __DIR__ . '/includes/asset.php';
- require_once __DIR__ . '/includes/antibot.php';
- require_once __DIR__ . '/includes/login-throttle.php';
-
- header('X-Robots-Tag: noindex, nofollow');
- UserAuth::boot();
- AntiBot::boot('user');
- if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
- AntiBot::refresh('user');
- }
-
- $settings = SiteFront::settings();
- $loginEnabled = ($settings['login_enabled'] ?? '1') !== '0';
-
- if (isset($_GET['logout'])) {
- UserAuth::logout();
- header('Location: user-login.php');
- exit;
- }
-
- if (UserAuth::check()) {
- header('Location: ' . SiteFront::homeUrl());
- exit;
- }
-
- if (!$loginEnabled) {
- $siteName = Config::get('APP_NAME', 'Publisium');
- ?>
- <!DOCTYPE html>
- <html lang="<?= htmlspecialchars(Languages::htmlLang(), ENT_QUOTES) ?>">
-
- <head>
- <meta charset="utf-8">
- <meta name="viewport" content="width=device-width, initial-scale=1">
- <meta name="robots" content="noindex, nofollow">
- <title><?= htmlspecialchars(Language::get('auth_login_button', 'Log in')) ?> - <?= htmlspecialchars($siteName) ?></title>
- <?= Asset::favicon() ?>
- <?= Asset::css('assets/site.css') ?>
- <style>
- <?= SiteFront::renderFontFaces() ?><?= SiteFront::fontVariablesCss() ?>
- </style>
- <?php if (!empty($settings['custom_css'])): ?>
- <style>
- <?= $settings['custom_css'] ?>
- </style>
- <?php endif; ?>
- </head>
-
- <body class="auth-page" data-theme="light">
- <script>
- (function() {
- try {
- var t = localStorage.getItem('publisium_theme');
- if (t === 'dark' || t === 'light') {
- document.body.setAttribute('data-theme', t);
- } else if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
- document.body.setAttribute('data-theme', 'dark');
- }
- } catch (e) {}
- })();
- </script>
- <div class="auth-card auth-card-disabled">
- <h1><?= htmlspecialchars($siteName) ?></h1>
- <p class="auth-subtitle"><?= htmlspecialchars(Language::get('auth_login_disabled', 'Reader login is temporarily disabled. Please check back later.')) ?></p>
- </div>
- </body>
-
- </html>
- <?php
- exit;
- }
-
- $error = null;
- $mode = ($_GET['mode'] ?? 'login') === 'register' ? 'register' : 'login';
-
- if ($_SERVER['REQUEST_METHOD'] === 'POST') {
- if (!Csrf::verify($_POST['csrf_token'] ?? null)) {
- $error = Language::get('auth_session_expired', 'Your session expired. Please try again.');
- } elseif (!AntiBot::verify('user', $_POST['antibot_answer'] ?? null, $_POST['antibot_started'] ?? null, $_POST['website'] ?? null)) {
- $error = Language::get('auth_security_code_wrong', 'The security code was wrong. Please try again.');
- } else {
- $formAction = $_POST['form_action'] ?? '';
-
- if ($formAction === 'login') {
- $email = trim((string) ($_POST['email'] ?? ''));
- $password = (string) ($_POST['password'] ?? '');
-
- if ($email === '' || $password === '') {
- $error = Language::get('auth_enter_email_password', 'Enter your email and password.');
- $mode = 'login';
- } elseif (($wait = LoginThrottle::secondsUntilAllowed('reader', $email)) > 0) {
- $error = str_replace('{minutes}', (string) max(1, (int) ceil($wait / 60)), Language::get('auth_too_many_attempts', 'Too many wrong tries. Please wait about {minutes} min and try again.'));
- $mode = 'login';
- } elseif (UserAuth::attemptLogin($email, $password)) {
- LoginThrottle::clear('reader', $email);
- header('Location: ' . SiteFront::homeUrl());
- exit;
- } else {
- LoginThrottle::recordFailure('reader', $email);
- $error = Language::get('auth_wrong_credentials', 'That email or password doesn’t match. Try again.');
- $mode = 'login';
- }
- }
-
- if ($formAction === 'register') {
- $email = trim((string) ($_POST['email'] ?? ''));
- $password = (string) ($_POST['password'] ?? '');
- $passwordConfirm = (string) ($_POST['password_confirm'] ?? '');
- $displayName = trim((string) ($_POST['display_name'] ?? ''));
-
- if ($password !== $passwordConfirm) {
- $error = Language::get('auth_passwords_mismatch', 'The passwords don’t match.');
- $mode = 'register';
- } else {
- [$success, $registerError] = UserAuth::register($email, $password, $displayName);
- if ($success) {
- header('Location: ' . SiteFront::homeUrl());
- exit;
- }
- $error = $registerError;
- $mode = 'register';
- }
- }
- }
- }
-
- $siteName = Config::get('APP_NAME', 'Publisium');
-
- ?>
- <!DOCTYPE html>
- <html lang="<?= htmlspecialchars(Languages::htmlLang(), ENT_QUOTES) ?>">
-
- <head>
- <meta charset="utf-8">
- <meta name="viewport" content="width=device-width, initial-scale=1">
- <meta name="robots" content="noindex, nofollow">
- <title><?= $mode === 'register' ? htmlspecialchars(Language::get('auth_register_button', 'Create account')) : htmlspecialchars(Language::get('auth_login_button', 'Log in')) ?> - <?= htmlspecialchars($siteName) ?></title>
- <?= Asset::favicon() ?>
- <?= Asset::css('assets/site.css') ?>
- <style>
- <?= SiteFront::renderFontFaces() ?><?= SiteFront::fontVariablesCss() ?>
- </style>
- <?php if (!empty($settings['custom_css'])): ?>
- <style>
- <?= $settings['custom_css'] ?>
- </style>
- <?php endif; ?>
- </head>
-
- <body class="auth-page" data-theme="light">
- <script>
- (function() {
- try {
- var t = localStorage.getItem('publisium_theme');
- if (t === 'dark' || t === 'light') {
- document.body.setAttribute('data-theme', t);
- } else if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
- document.body.setAttribute('data-theme', 'dark');
- }
- } catch (e) {}
- })();
- </script>
- <div class="auth-card">
- <h1><?= htmlspecialchars($siteName) ?></h1>
- <p class="auth-subtitle"><?= htmlspecialchars(Language::get('auth_reader_account', 'Reader account')) ?></p>
-
- <div class="auth-tabs">
- <a href="user-login.php?mode=login" class="<?= $mode === 'login' ? 'active' : '' ?>"><?= htmlspecialchars(Language::get('auth_login_button', 'Log in')) ?></a>
- <a href="user-login.php?mode=register" class="<?= $mode === 'register' ? 'active' : '' ?>"><?= htmlspecialchars(Language::get('auth_register_button', 'Create account')) ?></a>
- </div>
-
- <?php if ($error !== null): ?>
- <div class="auth-error"><?= htmlspecialchars($error) ?></div>
- <?php endif; ?>
-
- <?php if ($mode === 'login'): ?>
- <form method="post">
- <?= Csrf::field() ?>
- <?= AntiBot::field('user') ?>
- <input type="hidden" name="form_action" value="login">
- <label><?= htmlspecialchars(Language::get('auth_email', 'Email')) ?></label>
- <input type="email" name="email" required autofocus>
- <label><?= htmlspecialchars(Language::get('auth_password', 'Password')) ?></label>
- <input type="password" name="password" required>
- <div class="antibot-box">
- <div class="antibot-image"><?= AntiBot::image('user') ?></div>
- <label for="antibot-answer"><?= htmlspecialchars(Language::get('auth_security_code', 'Security code')) ?></label>
- <input id="antibot-answer" type="text" name="antibot_answer" required inputmode="text" autocomplete="off" maxlength="6" spellcheck="false">
- </div>
- <button type="submit"><?= htmlspecialchars(Language::get('auth_login_button', 'Log in')) ?></button>
- </form>
- <?php else: ?>
- <form method="post">
- <?= Csrf::field() ?>
- <?= AntiBot::field('user') ?>
- <input type="hidden" name="form_action" value="register">
- <label><?= htmlspecialchars(Language::get('auth_display_name', 'Display name')) ?></label>
- <input type="text" name="display_name">
- <label><?= htmlspecialchars(Language::get('auth_email', 'Email')) ?></label>
- <input type="email" name="email" required>
- <label><?= htmlspecialchars(Language::get('auth_password', 'Password')) ?></label>
- <input type="password" name="password" required minlength="8">
- <label><?= htmlspecialchars(Language::get('auth_confirm_password', 'Confirm password')) ?></label>
- <input type="password" name="password_confirm" required minlength="8">
- <div class="antibot-box">
- <div class="antibot-image"><?= AntiBot::image('user') ?></div>
- <label for="antibot-answer"><?= htmlspecialchars(Language::get('auth_security_code', 'Security code')) ?></label>
- <input id="antibot-answer" type="text" name="antibot_answer" required inputmode="text" autocomplete="off" maxlength="6" spellcheck="false">
- </div>
- <button type="submit"><?= htmlspecialchars(Language::get('auth_register_button', 'Create account')) ?></button>
- </form>
- <?php endif; ?>
-
- </div>
- </body>
-
- </html>
-