Merge pull request 'Add user registration page' (#4) from feat/user-registration into master
Reviewed-on: #4 Reviewed-by: rafaga21 <rafaelminaya20@hotmail.com>
This commit was merged in pull request #4.
This commit is contained in:
@@ -2112,6 +2112,24 @@ textarea.form-input {
|
|||||||
margin-bottom: 1.25rem;
|
margin-bottom: 1.25rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.auth-footer {
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 1rem;
|
||||||
|
padding-top: 1rem;
|
||||||
|
border-top: 1px solid var(--border-color);
|
||||||
|
color: var(--text-muted);
|
||||||
|
font-size: 0.85rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.auth-footer a {
|
||||||
|
color: var(--accent);
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.auth-footer a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
/* ==========================================================================
|
/* ==========================================================================
|
||||||
Error Pages
|
Error Pages
|
||||||
========================================================================== */
|
========================================================================== */
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ $router->get('/dashboard/refresh-metrics', [DashboardController::class, 'refresh
|
|||||||
|
|
||||||
$router->get('/login', [AuthController::class, 'loginForm']);
|
$router->get('/login', [AuthController::class, 'loginForm']);
|
||||||
$router->post('/login', [AuthController::class, 'login'], [CSRFMiddleware::class, RateLimitMiddleware::class]);
|
$router->post('/login', [AuthController::class, 'login'], [CSRFMiddleware::class, RateLimitMiddleware::class]);
|
||||||
|
$router->get('/register', [AuthController::class, 'registerForm']);
|
||||||
|
$router->post('/register', [AuthController::class, 'register'], [CSRFMiddleware::class]);
|
||||||
$router->get('/logout', [AuthController::class, 'logout']);
|
$router->get('/logout', [AuthController::class, 'logout']);
|
||||||
|
|
||||||
$router->get('/profile', [AuthController::class, 'profile'], [AuthMiddleware::class]);
|
$router->get('/profile', [AuthController::class, 'profile'], [AuthMiddleware::class]);
|
||||||
|
|||||||
@@ -80,6 +80,65 @@ class AuthController
|
|||||||
$this->view->redirect($intended);
|
$this->view->redirect($intended);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function registerForm(): void
|
||||||
|
{
|
||||||
|
if (Session::has('user_id')) {
|
||||||
|
$this->view->redirect('/dashboard');
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->view->setLayout('auth');
|
||||||
|
$this->view->display('auth.register', [
|
||||||
|
'title' => 'Register - ServerManager',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function register(): void
|
||||||
|
{
|
||||||
|
$validator = new Validator();
|
||||||
|
$rules = [
|
||||||
|
'username' => 'required|min:3|max:50',
|
||||||
|
'email' => 'required|email',
|
||||||
|
'password' => 'required|min:8',
|
||||||
|
'confirm_password' => 'required|match:password',
|
||||||
|
];
|
||||||
|
|
||||||
|
if (!$validator->validate($_POST, $rules)) {
|
||||||
|
Session::setFlash('error', $validator->getFirstError());
|
||||||
|
$this->view->redirect('/register');
|
||||||
|
}
|
||||||
|
|
||||||
|
$username = $_POST['username'];
|
||||||
|
$email = $_POST['email'];
|
||||||
|
|
||||||
|
$existing = $this->userModel->findByUsername($username);
|
||||||
|
if ($existing) {
|
||||||
|
Session::setFlash('error', 'Username already exists.');
|
||||||
|
$this->view->redirect('/register');
|
||||||
|
}
|
||||||
|
|
||||||
|
$existingEmail = $this->userModel->findByEmail($email);
|
||||||
|
if ($existingEmail) {
|
||||||
|
Session::setFlash('error', 'Email already registered.');
|
||||||
|
$this->view->redirect('/register');
|
||||||
|
}
|
||||||
|
|
||||||
|
$id = $this->userModel->create([
|
||||||
|
'username' => $username,
|
||||||
|
'email' => $email,
|
||||||
|
'password' => $_POST['password'],
|
||||||
|
'role' => 'operator',
|
||||||
|
'is_active' => 1,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->auditService->log('user_registered', 'user', $id, [
|
||||||
|
'username' => $username,
|
||||||
|
'role' => 'operator',
|
||||||
|
]);
|
||||||
|
|
||||||
|
Session::setFlash('success', 'Account created. You can now log in.');
|
||||||
|
$this->view->redirect('/login');
|
||||||
|
}
|
||||||
|
|
||||||
public function logout(): void
|
public function logout(): void
|
||||||
{
|
{
|
||||||
$this->auditService->log(
|
$this->auditService->log(
|
||||||
|
|||||||
@@ -43,5 +43,8 @@
|
|||||||
<i class="fas fa-sign-in-alt"></i> Sign In
|
<i class="fas fa-sign-in-alt"></i> Sign In
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="auth-footer">
|
||||||
|
<p>Don't have an account? <a href="/register">Register</a></p>
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
46
views/auth/register.php
Normal file
46
views/auth/register.php
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
<div class="auth-card">
|
||||||
|
<div class="auth-header">
|
||||||
|
<i class="fas fa-server auth-logo"></i>
|
||||||
|
<h1>ServerManager</h1>
|
||||||
|
<p>Create your account</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php if ($flash = \ServerManager\Core\Session::getFlash('error')): ?>
|
||||||
|
<div class="alert alert-error"><i class="fas fa-exclamation-circle"></i> <?= htmlspecialchars($flash[0]) ?></div>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<form method="POST" action="/register" class="auth-form" id="registerForm">
|
||||||
|
<input type="hidden" name="_csrf_token" value="<?= $this->csrfToken() ?>">
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="username"><i class="fas fa-user"></i> Username</label>
|
||||||
|
<input type="text" id="username" name="username" class="form-input" placeholder="Choose a username" required autofocus autocomplete="username">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="email"><i class="fas fa-envelope"></i> Email</label>
|
||||||
|
<input type="email" id="email" name="email" class="form-input" placeholder="your@email.com" required autocomplete="email">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="password"><i class="fas fa-lock"></i> Password</label>
|
||||||
|
<div class="input-group">
|
||||||
|
<input type="password" id="password" name="password" class="form-input" placeholder="At least 8 characters" required autocomplete="new-password">
|
||||||
|
<button type="button" class="input-toggle-password" tabindex="-1"><i class="fas fa-eye"></i></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="confirm_password"><i class="fas fa-lock"></i> Confirm Password</label>
|
||||||
|
<input type="password" id="confirm_password" name="confirm_password" class="form-input" placeholder="Repeat password" required autocomplete="new-password">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<button type="submit" class="btn btn-primary btn-block"><i class="fas fa-user-plus"></i> Create Account</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="auth-footer">
|
||||||
|
<p>Already have an account? <a href="/login">Sign in</a></p>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
Reference in New Issue
Block a user