235 lines
9.5 KiB
PHP
235 lines
9.5 KiB
PHP
<?php
|
|
/**
|
|
* Initial Setup Page for ZitiNexus Router Enrollment UI
|
|
* Forces users to change default credentials on first login
|
|
*/
|
|
|
|
require_once '../includes/auth.php';
|
|
|
|
// Require authentication but allow setup
|
|
AuthManager::requireAuth();
|
|
|
|
// If user doesn't require setup, redirect to dashboard
|
|
if (!AuthManager::requiresSetup()) {
|
|
header('Location: dashboard.php');
|
|
exit;
|
|
}
|
|
|
|
// Handle setup form submission
|
|
$setupError = '';
|
|
$setupSuccess = '';
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'setup') {
|
|
AuthManager::requireCSRF();
|
|
|
|
$currentPassword = $_POST['current_password'] ?? '';
|
|
$newUsername = $_POST['new_username'] ?? '';
|
|
$newPassword = $_POST['new_password'] ?? '';
|
|
$confirmPassword = $_POST['confirm_password'] ?? '';
|
|
|
|
// Validate password confirmation
|
|
if ($newPassword !== $confirmPassword) {
|
|
$setupError = 'New passwords do not match';
|
|
} else {
|
|
$result = AuthManager::completeSetup($currentPassword, $newUsername, $newPassword);
|
|
|
|
if ($result['success']) {
|
|
$setupSuccess = $result['message'];
|
|
// Redirect to login page after successful setup
|
|
header('refresh:3;url=index.php?message=setup_complete');
|
|
} else {
|
|
$setupError = $result['error'];
|
|
}
|
|
}
|
|
}
|
|
|
|
$currentUser = AuthManager::getCurrentUser();
|
|
?>
|
|
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title><?php echo APP_NAME; ?> - Initial Setup</title>
|
|
<link rel="stylesheet" href="assets/css/style.css">
|
|
<link rel="icon" type="image/x-icon" href="assets/images/favicon.ico">
|
|
</head>
|
|
<body>
|
|
<div class="login-container">
|
|
<div class="login-card" style="max-width: 500px;">
|
|
<div class="login-header">
|
|
<div class="logo" style="margin: 0 auto 1rem auto;">Z</div>
|
|
<h1>🔐 Security Setup Required</h1>
|
|
<p>For security reasons, you must change the default credentials before proceeding.</p>
|
|
</div>
|
|
|
|
<?php if ($setupError): ?>
|
|
<div class="alert alert-error">
|
|
<?php echo htmlspecialchars($setupError); ?>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<?php if ($setupSuccess): ?>
|
|
<div class="alert alert-success">
|
|
<?php echo htmlspecialchars($setupSuccess); ?>
|
|
<br><small>You will be redirected to login with your new credentials...</small>
|
|
</div>
|
|
<?php else: ?>
|
|
<form method="POST" id="setupForm">
|
|
<input type="hidden" name="action" value="setup">
|
|
<input type="hidden" name="csrf_token" value="<?php echo generateCSRFToken(); ?>">
|
|
|
|
<div class="form-group">
|
|
<label for="current_password" class="form-label">Current Password</label>
|
|
<input
|
|
type="password"
|
|
id="current_password"
|
|
name="current_password"
|
|
class="form-input"
|
|
placeholder="Enter current password (admin123)"
|
|
required
|
|
autocomplete="current-password"
|
|
>
|
|
<small class="text-sm text-secondary">Enter your current password to verify identity</small>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="new_username" class="form-label">New Username</label>
|
|
<input
|
|
type="text"
|
|
id="new_username"
|
|
name="new_username"
|
|
class="form-input"
|
|
placeholder="Enter new username"
|
|
value="<?php echo htmlspecialchars($currentUser['username']); ?>"
|
|
minlength="3"
|
|
maxlength="20"
|
|
pattern="[a-zA-Z0-9_]+"
|
|
required
|
|
autocomplete="username"
|
|
>
|
|
<small class="text-sm text-secondary">3-20 characters, letters, numbers, and underscores only</small>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="new_password" class="form-label">New Password</label>
|
|
<input
|
|
type="password"
|
|
id="new_password"
|
|
name="new_password"
|
|
class="form-input"
|
|
placeholder="Enter new password"
|
|
minlength="6"
|
|
required
|
|
autocomplete="new-password"
|
|
>
|
|
<small class="text-sm text-secondary">Minimum 6 characters</small>
|
|
<div id="passwordStrength" class="password-strength"></div>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="confirm_password" class="form-label">Confirm New Password</label>
|
|
<input
|
|
type="password"
|
|
id="confirm_password"
|
|
name="confirm_password"
|
|
class="form-input"
|
|
placeholder="Confirm new password"
|
|
minlength="6"
|
|
required
|
|
autocomplete="new-password"
|
|
>
|
|
<small class="text-sm text-secondary">Re-enter your new password</small>
|
|
<div id="passwordMatch" class="password-match"></div>
|
|
</div>
|
|
|
|
<button type="submit" class="btn btn-primary btn-full">
|
|
🔒 Complete Setup
|
|
</button>
|
|
</form>
|
|
|
|
<div style="margin-top: 2rem; padding: 1rem; background: #f8fafc; border-radius: 8px; border-left: 4px solid #2563eb;">
|
|
<h4 style="margin: 0 0 0.5rem 0; color: #1e293b;">Why is this required?</h4>
|
|
<p style="margin: 0; font-size: 0.875rem; color: #64748b;">
|
|
Default credentials pose a security risk. Changing them ensures only authorized users can access your router enrollment system.
|
|
</p>
|
|
</div>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
// Password strength indicator
|
|
document.getElementById('new_password').addEventListener('input', function() {
|
|
const password = this.value;
|
|
const strengthDiv = document.getElementById('passwordStrength');
|
|
|
|
let strength = 0;
|
|
let feedback = '';
|
|
|
|
if (password.length >= 6) strength++;
|
|
if (password.length >= 8) strength++;
|
|
if (/[A-Z]/.test(password)) strength++;
|
|
if (/[0-9]/.test(password)) strength++;
|
|
if (/[^A-Za-z0-9]/.test(password)) strength++;
|
|
|
|
switch (strength) {
|
|
case 0:
|
|
case 1:
|
|
feedback = '<span style="color: #ef4444;">Weak</span>';
|
|
break;
|
|
case 2:
|
|
case 3:
|
|
feedback = '<span style="color: #f59e0b;">Medium</span>';
|
|
break;
|
|
case 4:
|
|
case 5:
|
|
feedback = '<span style="color: #10b981;">Strong</span>';
|
|
break;
|
|
}
|
|
|
|
strengthDiv.innerHTML = password.length > 0 ? 'Strength: ' + feedback : '';
|
|
});
|
|
|
|
// Password match indicator
|
|
function checkPasswordMatch() {
|
|
const password = document.getElementById('new_password').value;
|
|
const confirm = document.getElementById('confirm_password').value;
|
|
const matchDiv = document.getElementById('passwordMatch');
|
|
|
|
if (confirm.length === 0) {
|
|
matchDiv.innerHTML = '';
|
|
return;
|
|
}
|
|
|
|
if (password === confirm) {
|
|
matchDiv.innerHTML = '<span style="color: #10b981;">✓ Passwords match</span>';
|
|
} else {
|
|
matchDiv.innerHTML = '<span style="color: #ef4444;">✗ Passwords do not match</span>';
|
|
}
|
|
}
|
|
|
|
document.getElementById('new_password').addEventListener('input', checkPasswordMatch);
|
|
document.getElementById('confirm_password').addEventListener('input', checkPasswordMatch);
|
|
|
|
// Form validation
|
|
document.getElementById('setupForm').addEventListener('submit', function(e) {
|
|
const password = document.getElementById('new_password').value;
|
|
const confirm = document.getElementById('confirm_password').value;
|
|
|
|
if (password !== confirm) {
|
|
e.preventDefault();
|
|
alert('Passwords do not match!');
|
|
return false;
|
|
}
|
|
|
|
if (password.length < 6) {
|
|
e.preventDefault();
|
|
alert('Password must be at least 6 characters long!');
|
|
return false;
|
|
}
|
|
});
|
|
</script>
|
|
</body>
|
|
</html>
|