fix: recover full admin.js from server, fix port redirects and account create validation

- admin.js: 1292 lines of features were on server but not in repo — recovered and committed
- admin.js: impersonation redirect now uses location.origin instead of hardcoded :8880 port
- accounts.php: pre-validate email uniqueness and username before INSERT to prevent SQLSTATE 23000
- accounts.php: wrap user INSERT + AccountManager::create() in single transaction for full rollback

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LP9Q4kfCAYAjJnsbHBrViZ
This commit is contained in:
2026-06-20 05:33:31 +00:00
parent 7185fcca5f
commit b077226581
2 changed files with 1489 additions and 186 deletions
+26 -15
View File
@@ -69,23 +69,34 @@ match ($action) {
$required = ['username','domain','email','password'];
foreach ($required as $f) { if (empty($body[$f])) Response::error("$f is required"); }
// Create user account
$userId = (int)$db->insert(
"INSERT INTO users (username, password, email, role, status, reseller_id) VALUES (?,?,?,?,?,?)",
[
$body['username'],
password_hash($body['password'], PASSWORD_BCRYPT),
$body['email'],
'user',
'active',
$user['role'] === 'reseller' ? $user['uid'] : null,
]
);
$body['user_id'] = $userId;
if (!filter_var($body['email'], FILTER_VALIDATE_EMAIL)) Response::error("Invalid email address");
if ($db->fetchOne("SELECT id FROM users WHERE email = ?", [$body['email']])) Response::error("Email already in use by another account");
if ($db->fetchOne("SELECT id FROM users WHERE username = ?", [$body['username']])) Response::error("Username already taken");
// Wrap user creation + account provisioning in a single transaction
$db->beginTransaction();
try {
$userId = (int)$db->insert(
"INSERT INTO users (username, password, email, role, status, reseller_id) VALUES (?,?,?,?,?,?)",
[
$body['username'],
password_hash($body['password'], PASSWORD_BCRYPT),
$body['email'],
'user',
'active',
$user['role'] === 'reseller' ? $user['uid'] : null,
]
);
$body['user_id'] = $userId;
$result = AccountManager::create($body);
$db->commit();
} catch (Throwable $e) {
$db->rollBack();
throw $e;
}
$result = AccountManager::create($body);
audit('account.create', $body['domain'], $result);
// Send welcome email to user + admin notification
Notifier::accountCreated(array_merge($body, ['email' => $body['email']]), $body['password']);
Response::success($result, 'Account created successfully');
})(),
+1463 -171
View File
File diff suppressed because it is too large Load Diff