Files
QRForge-selfhosted/src/login.php
T
dillard a692304748 Add self-registration: free accounts via email + self-hosted CAPTCHA
New public register.php flow: email + a GD-rendered math CAPTCHA (no
third-party service), a mailed temporary password doubling as email
verification, forced password change on first login. Gated behind a
new ALLOW_SELF_REGISTRATION toggle (default off).

Login moves from username to email (falls back to username for
pre-migration accounts without one yet, mirroring qr-vip's existing
migration 006 pattern) - self-registration needs email as the
identifier. New set_email.php interstitial for legacy accounts.

Adds a small PHPMailer-based Mailer class (SMTP, with an
unauthenticated-relay option via MAIL_SMTP_AUTH=false) since no mail
infrastructure existed in this app before.
2026-07-14 04:05:25 +02:00

158 lines
4.5 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
require_once 'includes/bootstrap.php';
$token = bin2hex(openssl_random_pseudo_bytes(16));
// If User has already logged in, redirect to dashboard page.
if (isset($_SESSION['user_logged_in']) && $_SESSION['user_logged_in'] === TRUE)
{
header('Location: index.php');
exit;
}
// If user has previously selected "remember me option":
if (isset($_COOKIE['series_id']) && isset($_COOKIE['remember_token']))
{
// Get user credentials from cookies.
$series_id = filter_var($_COOKIE['series_id']);
$remember_token = filter_var($_COOKIE['remember_token']);
$db = getDbInstance();
// Get user By series ID:
$db->where('series_id', $series_id);
$row = $db->getOne('users');
if ($db->count >= 1)
{
// User found. verify remember token
if (password_verify($remember_token, $row['remember_token']))
{
$expires = strtotime($row['expires']);
if (time() > $expires) {
clearAuthCookie();
header('Location: login.php');
exit;
}
session_regenerate_id(true);
$_SESSION['user_logged_in'] = TRUE;
$_SESSION['user_id'] = $row['id'];
$_SESSION['type'] = $row['type'];
$_SESSION['username'] = $row['username'];
$_SESSION['must_change_password'] = !empty($row['must_change_password']);
$_SESSION['must_set_email'] = !empty($row['must_set_email']);
$_SESSION['can_view_static'] = !empty($row['can_view_static']);
$_SESSION['can_view_dynamic'] = !empty($row['can_view_dynamic']);
$_SESSION['scope_owner_id'] = qr_compute_scope_owner_id($row);
$_SESSION['last_activity'] = time();
audit_log('login_success_remember');
header('Location: index.php');
exit;
}
else
{
clearAuthCookie();
header('Location: login.php');
exit;
}
}
else
{
clearAuthCookie();
header('Location: login.php');
exit;
}
}
?>
<!DOCTYPE html>
<html lang="en">
<title>Login - QRForge</title>
<?php include './includes/head.php'; ?>
<body class="login-page" style="min-height: 512.391px;">
<div class="login-box">
<div class="login-logo">
<img src="dist/img/brand/logo.svg" alt="QRForge" style="max-width: 260px;">
</div>
<div class="card">
<div class="card-body login-card-body">
<p class="login-box-msg">Sign in to start your session</p>
<?php include './includes/flash_messages.php'; ?>
<form method="POST" action="authenticate.php">
<?php echo csrf_field(); ?>
<div class="input-group mb-3">
<input type="text" name="email" class="form-control" placeholder="Email" required="required">
<div class="input-group-append">
<div class="input-group-text">
<span class="fa fa-user"></span>
</div>
</div>
</div>
<div class="input-group mb-3">
<input type="password" name="password" class="form-control" placeholder="Password" required="required">
<div class="input-group-append">
<div class="input-group-text">
<span class="fas fa-lock"></span>
</div>
</div>
</div>
<div class="row">
<div class="col-8">
<div class="icheck-primary">
<input name="remember" type="checkbox" id="remember">
<label for="remember">
Remember Me
</label>
</div>
</div>
<!-- /.col -->
<div class="col-4">
<button type="submit" class="btn btn-primary btn-block">Sign In</button>
</div>
<!-- /.col -->
</div>
</form>
<?php if (isset($_SESSION['login_failure'])): ?>
<br>
<div class="text-center mb-3">
<div class="card-body p-0">
<div class="alert alert-danger alert-dismissable">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
<?php
echo $_SESSION['login_failure'];
unset($_SESSION['login_failure']);
?>
</div>
</div>
</div>
<?php endif; ?>
<?php if (ALLOW_SELF_REGISTRATION): ?>
<p class="mt-3 text-center"><a href="register.php">Register for free</a></p>
<?php endif; ?>
</div>
<!-- /.login-card-body -->
</div>
</div>
<!-- /.login-box -->
<!-- jQuery -->
<script src="../../plugins/jquery/jquery.min.js"></script>
<!-- Bootstrap 4 -->
<script src="../../plugins/bootstrap/js/bootstrap.bundle.min.js"></script>
<!-- AdminLTE App -->
<script src="../../dist/js/adminlte.js"></script>
</body>
</html>