Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
d6fb98b
fix: add missing comma after date column in CSV export
lettimepassby Jun 24, 2026
4c1c73f
fix(mysql): allow public key retrieval for JDBC connections
Zxc4wonder Jun 29, 2026
ed13f08
fix: prevent unaudited resource action SQL injection
Zxc4wonder Jul 13, 2026
c25629f
fix: avoid auditing resource property queries as commands
Zxc4wonder Jul 13, 2026
417c59f
fix: harden WebSocket session binding and export paths
Zxc4wonder Jul 14, 2026
f12ec1e
fix: validate database identifier before JDBC URL interpolation
Zxc4wonder Jul 15, 2026
791362a
feat(frontend): add Dameng SQL formatter and editor fallbacks
Zxc4wonder Jul 20, 2026
8592066
Merge pull request #192 from jumpserver/pr@dev@fix_sql_format
Zxc4wonder Jul 20, 2026
c92accc
fix: preserve Oracle connection error details
Zxc4wonder Jul 20, 2026
859717c
Merge pull request #194 from jumpserver/pr@dev@fix_oracle_connection
Zxc4wonder Jul 20, 2026
557c65e
Merge pull request #173 from jumpserver/pr@dev@fix_mysql_connection
Zxc4wonder Jul 21, 2026
27810bc
Merge pull request #180 from jumpserver/pr@dev@fix_resource_action
Zxc4wonder Jul 21, 2026
1f9f503
Merge pull request #182 from jumpserver/pr@dev@fix_ws_hardening
Zxc4wonder Jul 21, 2026
cd263a4
Merge pull request #185 from jumpserver/pr@dev@fix_jdbc_injection
Zxc4wonder Jul 21, 2026
4ce1532
Merge pull request #172 from lettimepassby/pr@dev@fix_add_missing_com…
Zxc4wonder Jul 21, 2026
5a828b9
fix: normalize JDBC temporal values before Gson serialization
Zxc4wonder Jul 23, 2026
ecf0582
fix: make large SQL chunk transfer reliable
Zxc4wonder Jul 23, 2026
d1ac37d
Merge pull request #197 from jumpserver/pr@dev@fix_gson_issues
Zxc4wonder Jul 24, 2026
0b9dc84
fix:some bugs
Zxc4wonder Jul 24, 2026
70ec59c
Merge pull request #202 from jumpserver/pr@dev@fix_chen_bugs
Zxc4wonder Jul 24, 2026
48fa565
upgrade wisp for es9 (#204)
LeeEirc Jul 27, 2026
9eaf4be
fix: escape double quotes in CSV exports
Zxc4wonder Jul 27, 2026
6d53ae1
Merge pull request #205 from jumpserver/pr@dev@fix_data_export
Zxc4wonder Jul 27, 2026
ed5dce7
fix: support LocalDateTime serialization in WebSocket packets
Zxc4wonder Jul 29, 2026
979f61a
Merge pull request #209 from jumpserver/pr@dev@fix_mysql_time
Zxc4wonder Jul 29, 2026
8391230
Revert "fix: support LocalDateTime serialization in WebSocket packets"
Zxc4wonder Jul 29, 2026
e934ad6
Merge pull request #211 from jumpserver/revert-209-pr@dev@fix_mysql_time
Zxc4wonder Jul 29, 2026
e032b5f
fix: block disabled paste before editor handling
Zxc4wonder Aug 4, 2026
5499ddc
Merge pull request #216 from jumpserver/pr@dev@fix_rbac_paste
Zxc4wonder Aug 4, 2026
ca95dc4
fix(oracle): restore Oracle parser and reject implicit SQL splits
Zxc4wonder Aug 6, 2026
885e511
Merge pull request #220 from jumpserver/pr@dev@fix_oracle_parser
Zxc4wonder Aug 6, 2026
148d3ae
build(druid): upgrade custom dependency
Zxc4wonder Aug 11, 2026
e7d3362
perf: Update Dockerfile with new base image tag
github-actions[bot] Aug 11, 2026
a1ed889
Merge pull request #222 from jumpserver/pr@dev@feat_druid_upgrade
Zxc4wonder Aug 11, 2026
b14a664
fix: honor SQL Server encrypt platform setting
Zxc4wonder Aug 13, 2026
5704861
Merge pull request #224 from jumpserver/pr@dev@fix_sqlserver_conn
Zxc4wonder Aug 14, 2026
b192bd1
fix: use explicit resource actions for tree double click
Zxc4wonder Jul 29, 2026
e50b7bb
Merge pull request #226 from jumpserver/pr@dev@fix_double_click
Zxc4wonder Aug 17, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM jumpserver/chen-base:20260701_092702 AS stage-build
FROM jumpserver/chen-base:20260811_065334 AS stage-build
ENV LANG=en_US.UTF-8

WORKDIR /opt/chen/
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile-base
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ RUN set -ex \
&& dpkg -i check_linux_${TARGETARCH}.deb \
&& rm -f check_linux_${TARGETARCH}.deb

ARG WISP_VERSION=v0.2.13
ARG WISP_VERSION=v0.2.14
RUN set -ex \
&& wget https://github.com/jumpserver/wisp/releases/download/${WISP_VERSION}/wisp_linux_${TARGETARCH}.deb \
&& dpkg -i wisp_linux_${TARGETARCH}.deb \
Expand Down
4 changes: 2 additions & 2 deletions backend/framework/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@
</dependency>

<dependency>
<groupId>com.alibaba</groupId>
<groupId>com.jumpserver</groupId>
<artifactId>druid</artifactId>
<version>1.2.18</version>
<version>1.2.28-jms-chen.1</version>
</dependency>

<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,8 @@
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.Optional;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;

@Slf4j
Expand All @@ -51,6 +50,7 @@ public class QueryConsole extends AbstractConsole {
private StateManager<QueryConsoleState> stateManager;
private final Map<String, DataView> dataViews = new HashMap<>();
private volatile Map<String, String> allowedContexts = Map.of();
private final SQLChunkTransferManager sqlChunkTransfers = new SQLChunkTransferManager();

private static final Gson GSON = new Gson();

Expand Down Expand Up @@ -92,15 +92,13 @@ public void onConnect(Connect connect) {
try {
var currentContext = this.getSqlActuator().getCurrentSchema();

if (StringUtils.isEmpty(currentContext) && !StringUtils.isEmpty(context)) {
if (StringUtils.isNotEmpty(context)
&& !StringUtils.equals(currentContext, context)) {
this.getSqlActuator().changeSchema(context);
this.getState().setCurrentContext(context);
} else {
if (!StringUtils.isEmpty(context) && !currentContext.equals(context)) {
this.getSqlActuator().changeSchema(context);
this.getState().setCurrentContext(context);
}
}
this.getState().setCurrentContext(
StringUtils.defaultIfEmpty(context, currentContext)
);

var schemas = this.getSqlActuator().getSchemas();
this.replaceAllowedContexts(schemas);
Expand Down Expand Up @@ -168,7 +166,7 @@ private void onAction(QueryConsoleAction action) {
this.handleSQLChunk(action);
}
case QueryConsoleAction.ACTION_RUN_SQL_COMPLETE -> {
this.handleSQLComplete();
this.handleSQLComplete(action);
}

case QueryConsoleAction.ACTION_RUN_SQL_FILE -> {
Expand All @@ -184,6 +182,7 @@ private void onAction(QueryConsoleAction action) {


case QueryConsoleAction.ACTION_CANCEL -> {
this.sqlChunkTransfers.cancelAll();
this.onCancel();
this.getState().setInQuery(false);
this.stateManager.commit();
Expand All @@ -195,65 +194,26 @@ private void onAction(QueryConsoleAction action) {
}
}

private final ConcurrentHashMap<Integer, String> sqlChunks = new ConcurrentHashMap<>();
private CountDownLatch latch;
private int expectedChunks = -1;

private void handleSQLChunk(QueryConsoleAction action) {
var data = (Map<String, Object>) action.getData();
var chunk = (String) data.get("chunk");
var index = (Integer) data.get("index");
var total = (Integer) data.get("total");

synchronized (this) {
if (expectedChunks == -1) {
expectedChunks = total;
latch = new CountDownLatch(total);
}
}

if (sqlChunks.putIfAbsent(index, chunk) == null) {
latch.countDown();
Optional<String> sql;
try {
sql = this.sqlChunkTransfers.receiveChunk(action.getData());
} catch (IllegalArgumentException | IllegalStateException e) {
this.getConsoleLogger().error("Invalid SQL chunk transfer: %s", e.getMessage());
return;
}
sql.ifPresent(this::onSQL);
}

/**
* 处理分段 SQL 接收完成
*/
private void handleSQLComplete() {
private void handleSQLComplete(QueryConsoleAction action) {
Optional<String> sql;
try {

// 等待所有分段接收完成
boolean completed = latch.await(10, TimeUnit.SECONDS); // 超时10秒

if (!completed) {
this.getConsoleLogger().error("read sql message timeout!!");
return;
}

// 按照索引顺序合并所有分段
StringBuilder sqlBuilder = new StringBuilder();
for (int i = 0; i < expectedChunks; i++) {
sqlBuilder.append(sqlChunks.get(i));
}

// 合并完成后清理缓存
var sql = sqlBuilder.toString();
sqlChunks.clear();
expectedChunks = -1;

// 执行完整 SQL
this.getState().setInQuery(true);
this.stateManager.commit();

this.onSQL(sql);

} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
this.getState().setInQuery(false);
this.stateManager.commit();
sql = this.sqlChunkTransfers.receiveComplete(action.getData());
} catch (IllegalArgumentException | IllegalStateException e) {
this.getConsoleLogger().error("Invalid SQL chunk transfer: %s", e.getMessage());
return;
}
sql.ifPresent(this::onSQL);
}

private void onDataViewAction(DataViewAction action) {
Expand Down Expand Up @@ -538,6 +498,7 @@ private void sendDataView(DataView dataView, boolean clearOthers) {

@Override
public void close() {
this.sqlChunkTransfers.close();
if (this.currentPlan != null) {
// flush
var session = SessionManager.getCurrentSession();
Expand Down
Loading