Update index.js

This commit is contained in:
fanategorius
2026-07-06 16:27:52 +03:00
committed by GitHub
parent b98df89971
commit b6ea7b9d92
+85 -76
View File
@@ -1,92 +1,101 @@
(function(OC, window, $, undefined) { <?php
'use strict';
$(document).ready(function() { namespace OCA\OCCWeb\Controller;
var sqlMode = false;
var term = $('body').terminal(function(command, term) { use OCP\AppFramework\Controller;
if (command === '') { use OCP\IRequest;
return; use OCP\IDBConnection;
use OCP\AppFramework\Http\JSONResponse;
use OCP\IGroupManager;
use OCP\IUserSession;
class DbController extends Controller
{
private $db;
private $groupManager;
private $userSession;
public function __construct(
$AppName,
IRequest $request,
IDBConnection $db,
IGroupManager $groupManager,
IUserSession $userSession
) {
parent::__construct($AppName, $request);
$this->db = $db;
$this->groupManager = $groupManager;
$this->userSession = $userSession;
} }
// Команды переключения режимов /**
if (command === ':sql') { * @NoCSRFRequired
sqlMode = true; */
term.set_prompt('sql $ '); public function query()
term.echo('SQL mode enabled. Type :occ to return to OCC mode.'); {
return; // Проверка прав администратора
$user = $this->userSession->getUser();
if (!$user) {
return new JSONResponse(['error' => 'Not authenticated'], 401);
} }
if (command === ':occ') { if (!$this->groupManager->isAdmin($user->getUID())) {
sqlMode = false; return new JSONResponse(['error' => 'Admin privileges required'], 403);
term.set_prompt('occ $ ');
term.echo('OCC mode enabled.');
return;
} }
if (command === ':help') { $sql = $this->request->getParam('sql', '');
term.echo('Available commands:');
term.echo(' :sql - Switch to SQL mode'); if (empty(trim($sql))) {
term.echo(' :occ - Switch to OCC mode'); return new JSONResponse(['success' => false, 'error' => 'Empty query']);
term.echo(' :help - Show this help');
term.echo('');
term.echo('In OCC mode: execute Nextcloud occ commands');
term.echo('In SQL mode: execute SQL queries directly');
return;
} }
term.pause(); // Разделяем запросы по точке с запятой. Все запросы выполняются
// последовательно на одном и том же соединении с БД (в рамках
// одного HTTP-запроса), поэтому SET сохраняет своё значение
// для current_setting() в последующих запросах пачки.
$queries = array_values(array_filter(array_map('trim', explode(';', $sql)), function ($q) {
return $q !== '';
}));
if (sqlMode) { $results = [];
// SQL режим
$.post(OC.generateUrl('/apps/occweb/db/query'), { foreach ($queries as $query) {
sql: command $isSelect = stripos($query, 'SELECT') === 0;
}, function(response) { $isSet = stripos($query, 'SET ') === 0;
if (response.success) {
response.results.forEach(function(result) { try {
if (result.type === 'select') { $stmt = $this->db->prepare($query);
term.echo('Query: ' + result.query); $stmt->execute();
term.echo('Rows: ' + result.count);
if (result.data.length > 0) { if ($isSelect) {
term.echo(JSON.stringify(result.data, null, 2)); $rows = $stmt->fetchAll();
$results[] = [
'query' => $query,
'type' => 'select',
'count' => count($rows),
'data' => $rows
];
} else { } else {
term.echo('(no results)'); $affected = $stmt->rowCount();
$results[] = [
'query' => $query,
'type' => $isSet ? 'set' : 'write',
'affected_rows' => $affected
];
} }
} else if (result.type === 'write') { } catch (\Exception $e) {
term.echo('Query: ' + result.query); $results[] = [
term.echo('Affected rows: ' + result.affected_rows); 'query' => $query,
} else if (result.type === 'set') { 'type' => 'error',
term.echo('Skipped: ' + result.query); 'error' => $e->getMessage()
];
// Останавливаемся на первой ошибке: не продолжаем выполнять
// оставшиеся запросы пачки (например, серию DELETE),
// если один из предыдущих шагов не выполнился.
break;
} }
term.echo('');
});
} else {
term.echo('ERROR: ' + response.error);
} }
term.resume();
}).fail(function(xhr, status, error) {
term.echo('ERROR: Request failed - ' + error);
term.resume();
});
} else {
// OCC режим
$.post(OC.generateUrl('/apps/occweb/cmd'), {
command: command
}, function(response) {
term.echo('\n' + response).resume();
}).fail(function(xhr, status, error) {
term.echo('ERROR: Request failed - ' + error);
term.resume();
});
}
}, {
prompt: 'occ $ ',
name: 'occweb',
greetings: 'Nextcloud OCC Web Terminal\nType :help for available commands\n',
onBlur: function() {
return false;
}
});
});
})(OC, window, jQuery); return new JSONResponse(['success' => true, 'results' => $results]);
}
}