Fix MySQL create: sanitize db names, fix empty db_user default, catch RuntimeException

Dots/dashes in names were failing validateName; now stripped to underscores.
Empty db_user field sent as "" (not null) so ?? fallback never fired; fixed
to check for empty string explicitly.  Wrap createMySQL/Postgres in try/catch
so validation errors return 400 JSON instead of 500.  Also pass db_type from
JS (was being sent as db_type not type).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-09 18:42:23 +00:00
parent 8716299201
commit ddd81d73e7
+16 -6
View File
@@ -38,9 +38,10 @@ match ($action) {
}
// Default to active DB engine from settings so autoinstallers use whatever the admin has selected
$activeEngine = $db->fetchOne("SELECT `value` FROM settings WHERE `key`='active_db_engine'")['value'] ?? 'mysql';
$type = $body['type'] ?? ($activeEngine === 'postgresql' ? 'postgresql' : 'mysql');
$dbName = trim($body['db_name'] ?? '');
$dbUser = trim($body['db_user'] ?? $dbName . '_user');
$type = $body['type'] ?? $body['db_type'] ?? ($activeEngine === 'postgresql' ? 'postgresql' : 'mysql');
$dbName = preg_replace('/[^a-zA-Z0-9_]/', '_', trim($body['db_name'] ?? ''));
$rawUser = trim($body['db_user'] ?? '');
$dbUser = $rawUser !== '' ? preg_replace('/[^a-zA-Z0-9_]/', '_', $rawUser) : '';
$dbPass = $body['db_pass'] ?? bin2hex(random_bytes(8));
if (!$dbName) Response::error("db_name required");
@@ -48,11 +49,20 @@ match ($action) {
$acct = $db->fetchOne("SELECT username FROM accounts WHERE id = ?", [$accountId]);
$prefix = $acct['username'] . '_';
if (!str_starts_with($dbName, $prefix)) $dbName = $prefix . $dbName;
// Default db_user from db_name if blank, then prefix
if ($dbUser === '') $dbUser = $dbName . '_user';
if (!str_starts_with($dbUser, $prefix)) $dbUser = $prefix . $dbUser;
// Enforce max length (MySQL username limit is 32, db name 64)
$dbName = substr($dbName, 0, 64);
$dbUser = substr($dbUser, 0, 32);
$id = $type === 'postgresql'
? DatabaseManager::createPostgres($accountId, $dbName, $dbUser, $dbPass)
: DatabaseManager::createMySQL($accountId, $dbName, $dbUser, $dbPass);
try {
$id = $type === 'postgresql'
? DatabaseManager::createPostgres($accountId, $dbName, $dbUser, $dbPass)
: DatabaseManager::createMySQL($accountId, $dbName, $dbUser, $dbPass);
} catch (RuntimeException $e) {
Response::error($e->getMessage());
}
audit('database.create', $dbName, ['type' => $type]);
Response::success(['id' => $id, 'db_name' => $dbName, 'db_user' => $dbUser, 'db_pass' => $dbPass], 'Database created');