Upgraded to 1.1.0
1.1.0 (2025-10-09)
- **User Notifications System** - In-app notification center with 7 notification types, filtering, pagination
- **Advanced Session Management** - Database-backed sessions with geolocation (country, city, ISP)
- **Remote Session Control** - Terminate any device instantly with immediate logout validation
- **Enhanced Profile Page** - Sidebar navigation with 4 tabs, hash-based routing (#profile, #security, #sessions)
- **MVC Architecture Refactoring** - 3 new Helpers (Layout, Domain, Session), ~265 lines cleaned from views
- **Geolocation Tracking** - IP-based location detection using ip-api.com, country flags with flag-icons
- **Device Detection** - Browser & device type parsing (Chrome/Firefox/Safari, Desktop/Mobile/Tablet)
- **Auto-Detected Cron Paths** - Settings show actual installation paths (thanks @jadeops)
- **Welcome Notifications** - Sent to new users on registration or fresh install
- **Upgrade Notifications** - Admins notified on system updates with version & migration count
- **Web-Based Installer** - Replaces CLI, auto-generates encryption key, one-time password display
- **Web-Based Updater** - `/install/update` for running new migrations with smart detection
- **User Registration** - Full signup flow with email verification, password reset, resend verification
- **User Management** - CRUD for users with filtering, sorting, pagination (admin-only)
- **Remember Me** - 30-day secure tokens linked to sessions, cascade deletion on logout
- **Session Validator** - Middleware validates sessions on every request for instant remote logout
- **Consistent UI/UX** - Unified filtering, sorting, pagination across Domains, Users, Notifications, TLD Registry
- **Smart Migrations** - Consolidated schema for fresh installs, incremental for upgrades
- **XSS Protection** - htmlspecialchars() applied across all user-facing data (thanks @jadeops)
2025-10-09 18:02:46 +03:00
|
|
|
<?php
|
|
|
|
|
$title = 'Edit User';
|
|
|
|
|
$pageTitle = 'Edit User';
|
|
|
|
|
$pageDescription = 'Update user information and permissions';
|
|
|
|
|
$pageIcon = 'fas fa-user-edit';
|
|
|
|
|
ob_start();
|
|
|
|
|
?>
|
|
|
|
|
|
|
|
|
|
<form method="POST" action="/users/update" class="max-w-2xl">
|
Add CSRF, CAPTCHA, and input validation improvements
Introduces CSRF protection to all sensitive controller actions, integrates configurable CAPTCHA (reCAPTCHA v2/v3, Turnstile) for authentication and registration flows, and centralizes input validation via a new InputValidator helper. Adds new helpers and services for CSRF and CAPTCHA, updates settings and migration for CAPTCHA configuration, and enhances logging and error handling in TLD registry import processes. Also improves validation for user, domain, group, and profile inputs throughout the application.
2025-10-10 00:04:12 +03:00
|
|
|
<?= csrf_field() ?>
|
Upgraded to 1.1.0
1.1.0 (2025-10-09)
- **User Notifications System** - In-app notification center with 7 notification types, filtering, pagination
- **Advanced Session Management** - Database-backed sessions with geolocation (country, city, ISP)
- **Remote Session Control** - Terminate any device instantly with immediate logout validation
- **Enhanced Profile Page** - Sidebar navigation with 4 tabs, hash-based routing (#profile, #security, #sessions)
- **MVC Architecture Refactoring** - 3 new Helpers (Layout, Domain, Session), ~265 lines cleaned from views
- **Geolocation Tracking** - IP-based location detection using ip-api.com, country flags with flag-icons
- **Device Detection** - Browser & device type parsing (Chrome/Firefox/Safari, Desktop/Mobile/Tablet)
- **Auto-Detected Cron Paths** - Settings show actual installation paths (thanks @jadeops)
- **Welcome Notifications** - Sent to new users on registration or fresh install
- **Upgrade Notifications** - Admins notified on system updates with version & migration count
- **Web-Based Installer** - Replaces CLI, auto-generates encryption key, one-time password display
- **Web-Based Updater** - `/install/update` for running new migrations with smart detection
- **User Registration** - Full signup flow with email verification, password reset, resend verification
- **User Management** - CRUD for users with filtering, sorting, pagination (admin-only)
- **Remember Me** - 30-day secure tokens linked to sessions, cascade deletion on logout
- **Session Validator** - Middleware validates sessions on every request for instant remote logout
- **Consistent UI/UX** - Unified filtering, sorting, pagination across Domains, Users, Notifications, TLD Registry
- **Smart Migrations** - Consolidated schema for fresh installs, incremental for upgrades
- **XSS Protection** - htmlspecialchars() applied across all user-facing data (thanks @jadeops)
2025-10-09 18:02:46 +03:00
|
|
|
<input type="hidden" name="id" value="<?= $user['id'] ?>">
|
|
|
|
|
|
|
|
|
|
<div class="bg-white rounded-lg border border-gray-200 overflow-hidden">
|
|
|
|
|
<div class="px-6 py-4 border-b border-gray-200 bg-gray-50">
|
|
|
|
|
<h3 class="text-lg font-semibold text-gray-900">User Information</h3>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="p-6 space-y-4">
|
|
|
|
|
<!-- Full Name -->
|
|
|
|
|
<div>
|
|
|
|
|
<label for="full_name" class="block text-sm font-medium text-gray-700 mb-2">
|
|
|
|
|
Full Name <span class="text-red-500">*</span>
|
|
|
|
|
</label>
|
|
|
|
|
<input type="text" id="full_name" name="full_name" required
|
|
|
|
|
value="<?= htmlspecialchars($user['full_name'] ?? '') ?>"
|
|
|
|
|
class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-primary">
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- Username (Read-only) -->
|
|
|
|
|
<div>
|
|
|
|
|
<label for="username" class="block text-sm font-medium text-gray-700 mb-2">
|
|
|
|
|
Username
|
|
|
|
|
</label>
|
|
|
|
|
<input type="text" id="username" value="<?= htmlspecialchars($user['username']) ?>" readonly
|
|
|
|
|
class="w-full px-3 py-2 border border-gray-300 rounded-lg bg-gray-50 text-gray-500 cursor-not-allowed">
|
|
|
|
|
<p class="text-xs text-gray-500 mt-1">Username cannot be changed</p>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- Email -->
|
|
|
|
|
<div>
|
|
|
|
|
<label for="email" class="block text-sm font-medium text-gray-700 mb-2">
|
|
|
|
|
Email Address <span class="text-red-500">*</span>
|
|
|
|
|
</label>
|
|
|
|
|
<input type="email" id="email" name="email" required
|
|
|
|
|
value="<?= htmlspecialchars($user['email']) ?>"
|
|
|
|
|
class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-primary">
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- Role -->
|
|
|
|
|
<div>
|
|
|
|
|
<label for="role" class="block text-sm font-medium text-gray-700 mb-2">
|
|
|
|
|
Role <span class="text-red-500">*</span>
|
|
|
|
|
</label>
|
|
|
|
|
<select id="role" name="role" required
|
|
|
|
|
class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-primary">
|
|
|
|
|
<option value="user" <?= $user['role'] === 'user' ? 'selected' : '' ?>>User</option>
|
|
|
|
|
<option value="admin" <?= $user['role'] === 'admin' ? 'selected' : '' ?>>Admin</option>
|
|
|
|
|
</select>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- Status -->
|
|
|
|
|
<div class="flex items-start">
|
|
|
|
|
<div class="flex items-center h-5">
|
|
|
|
|
<input type="checkbox" id="is_active" name="is_active" value="1"
|
|
|
|
|
<?= $user['is_active'] ? 'checked' : '' ?>
|
|
|
|
|
class="w-4 h-4 text-primary border-gray-300 rounded focus:ring-primary">
|
|
|
|
|
</div>
|
|
|
|
|
<div class="ml-3">
|
|
|
|
|
<label for="is_active" class="text-sm font-medium text-gray-700">
|
|
|
|
|
Active
|
|
|
|
|
</label>
|
|
|
|
|
<p class="text-xs text-gray-500">Inactive users cannot log in</p>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- Password (Optional) -->
|
|
|
|
|
<div class="border-t border-gray-200 pt-4 mt-4">
|
|
|
|
|
<h4 class="text-sm font-semibold text-gray-900 mb-3">Change Password (Optional)</h4>
|
|
|
|
|
|
|
|
|
|
<div>
|
|
|
|
|
<label for="password" class="block text-sm font-medium text-gray-700 mb-2">
|
|
|
|
|
New Password
|
|
|
|
|
</label>
|
|
|
|
|
<input type="password" id="password" name="password" minlength="8"
|
|
|
|
|
class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-primary">
|
|
|
|
|
<p class="text-xs text-gray-500 mt-1">Leave blank to keep current password. Minimum 8 characters if changing.</p>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- Account Info -->
|
|
|
|
|
<div class="bg-gray-50 border border-gray-200 rounded-lg p-3 mt-4">
|
|
|
|
|
<div class="grid grid-cols-2 gap-3 text-xs">
|
|
|
|
|
<div>
|
|
|
|
|
<span class="text-gray-600">Email Verified:</span>
|
|
|
|
|
<span class="font-semibold <?= $user['email_verified'] ? 'text-green-600' : 'text-red-600' ?>">
|
|
|
|
|
<?= $user['email_verified'] ? 'Yes' : 'No' ?>
|
|
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div>
|
|
|
|
|
<span class="text-gray-600">Member Since:</span>
|
|
|
|
|
<span class="font-semibold text-gray-900">
|
|
|
|
|
<?= date('M d, Y', strtotime($user['created_at'])) ?>
|
|
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div>
|
|
|
|
|
<span class="text-gray-600">Last Login:</span>
|
|
|
|
|
<span class="font-semibold text-gray-900">
|
|
|
|
|
<?= $user['last_login'] ? date('M d, Y H:i', strtotime($user['last_login'])) : 'Never' ?>
|
|
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="px-6 py-4 border-t border-gray-200 bg-gray-50 flex items-center justify-between">
|
|
|
|
|
<a href="/users" class="text-gray-600 hover:text-gray-800 text-sm font-medium">
|
|
|
|
|
<i class="fas fa-arrow-left mr-1"></i> Cancel
|
|
|
|
|
</a>
|
|
|
|
|
<button type="submit" class="inline-flex items-center px-4 py-2.5 bg-primary text-white text-sm rounded-lg hover:bg-primary-dark transition-colors font-medium">
|
|
|
|
|
<i class="fas fa-save mr-2"></i>
|
|
|
|
|
Update User
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</form>
|
|
|
|
|
|
|
|
|
|
<?php
|
|
|
|
|
$content = ob_get_clean();
|
|
|
|
|
require __DIR__ . '/../layout/base.php';
|
|
|
|
|
?>
|
|
|
|
|
|