aboutsummaryrefslogtreecommitdiffstats
path: root/src/app/Views/auth
diff options
context:
space:
mode:
authorThomas Vanbesien <tvanbesi@proton.me>2026-03-21 21:35:51 +0100
committerThomas Vanbesien <tvanbesi@proton.me>2026-03-21 21:35:51 +0100
commitbc54c8c31e7f50a7a365f9b4d22fe8c74a29f61a (patch)
tree73a88384b9e472386d244119a0b4e4aa028c8b32 /src/app/Views/auth
parentd1ef15fa39935bfa0420c5ac2b8c269e294c9a6d (diff)
downloadcamagru-bc54c8c31e7f50a7a365f9b4d22fe8c74a29f61a.tar.gz
camagru-bc54c8c31e7f50a7a365f9b4d22fe8c74a29f61a.zip
Add user authentication with email verification and password reset
Implements registration, login/logout, email verification via token, and password reset flow. Includes CSRF protection, flash messages, MailPit for dev email testing, and security docs in README.
Diffstat (limited to 'src/app/Views/auth')
-rw-r--r--src/app/Views/auth/forgot-password.php13
-rw-r--r--src/app/Views/auth/login.php17
-rw-r--r--src/app/Views/auth/register.php23
-rw-r--r--src/app/Views/auth/reset-password.php17
4 files changed, 70 insertions, 0 deletions
diff --git a/src/app/Views/auth/forgot-password.php b/src/app/Views/auth/forgot-password.php
new file mode 100644
index 0000000..c0eb25e
--- /dev/null
+++ b/src/app/Views/auth/forgot-password.php
@@ -0,0 +1,13 @@
+<?php // Forgot password form: enter email to receive a reset link.?>
+<div class="auth-page">
+ <h1>Forgot password</h1>
+ <?php include __DIR__ . '/../partials/flash.php'; ?>
+ <form method="POST" action="/forgot-password" class="auth-form">
+ <?= \App\Csrf::field() ?>
+ <label for="email">Email</label>
+ <input type="email" id="email" name="email" required>
+
+ <button type="submit">Send reset link</button>
+ </form>
+ <p><a href="/login">Back to login</a></p>
+</div>
diff --git a/src/app/Views/auth/login.php b/src/app/Views/auth/login.php
new file mode 100644
index 0000000..da9e7e5
--- /dev/null
+++ b/src/app/Views/auth/login.php
@@ -0,0 +1,17 @@
+<?php // Login form.?>
+<div class="auth-page">
+ <h1>Login</h1>
+ <?php include __DIR__ . '/../partials/flash.php'; ?>
+ <form method="POST" action="/login" class="auth-form">
+ <?= \App\Csrf::field() ?>
+ <label for="username">Username</label>
+ <input type="text" id="username" name="username" required>
+
+ <label for="password">Password</label>
+ <input type="password" id="password" name="password" required>
+
+ <button type="submit">Log in</button>
+ </form>
+ <p><a href="/forgot-password">Forgot your password?</a></p>
+ <p>Don't have an account? <a href="/register">Register</a></p>
+</div>
diff --git a/src/app/Views/auth/register.php b/src/app/Views/auth/register.php
new file mode 100644
index 0000000..f98102e
--- /dev/null
+++ b/src/app/Views/auth/register.php
@@ -0,0 +1,23 @@
+<?php // Registration form.?>
+<div class="auth-page">
+ <h1>Register</h1>
+ <?php include __DIR__ . '/../partials/flash.php'; ?>
+ <form method="POST" action="/register" class="auth-form">
+ <?= \App\Csrf::field() ?>
+ <label for="username">Username</label>
+ <input type="text" id="username" name="username" required
+ pattern="[a-zA-Z0-9_]{3,20}" title="3-20 characters: letters, numbers, underscores">
+
+ <label for="email">Email</label>
+ <input type="email" id="email" name="email" required>
+
+ <label for="password">Password</label>
+ <input type="password" id="password" name="password" required minlength="8">
+
+ <label for="password_confirm">Confirm password</label>
+ <input type="password" id="password_confirm" name="password_confirm" required minlength="8">
+
+ <button type="submit">Register</button>
+ </form>
+ <p>Already have an account? <a href="/login">Log in</a></p>
+</div>
diff --git a/src/app/Views/auth/reset-password.php b/src/app/Views/auth/reset-password.php
new file mode 100644
index 0000000..dfdcab2
--- /dev/null
+++ b/src/app/Views/auth/reset-password.php
@@ -0,0 +1,17 @@
+<?php // Reset password form: set a new password using a valid reset token.?>
+<div class="auth-page">
+ <h1>Reset password</h1>
+ <?php include __DIR__ . '/../partials/flash.php'; ?>
+ <form method="POST" action="/reset-password" class="auth-form">
+ <?= \App\Csrf::field() ?>
+ <input type="hidden" name="token" value="<?= htmlspecialchars($_GET['token'] ?? '') ?>">
+
+ <label for="password">New password</label>
+ <input type="password" id="password" name="password" required minlength="8">
+
+ <label for="password_confirm">Confirm new password</label>
+ <input type="password" id="password_confirm" name="password_confirm" required minlength="8">
+
+ <button type="submit">Reset password</button>
+ </form>
+</div>