dbnexus 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +304 -88
- package/dist/api.js +3008 -1085
- package/dist/cli.js +97 -19
- package/dist/web/assets/index-D36Et9tk.js +536 -0
- package/dist/web/index.html +1 -1
- package/package.json +1 -2
- package/dist/web/assets/index-DoAn-9yR.js +0 -517
package/dist/cli.js
CHANGED
|
@@ -33113,7 +33113,7 @@ var import_dotenv = __toESM(require_main(), 1);
|
|
|
33113
33113
|
import Database from "better-sqlite3";
|
|
33114
33114
|
|
|
33115
33115
|
// packages/metadata/dist/schema.js
|
|
33116
|
-
var SCHEMA_VERSION =
|
|
33116
|
+
var SCHEMA_VERSION = 22;
|
|
33117
33117
|
var MIGRATIONS = [
|
|
33118
33118
|
// Version 1: Initial schema
|
|
33119
33119
|
`
|
|
@@ -33598,6 +33598,50 @@ var MIGRATIONS = [
|
|
|
33598
33598
|
CREATE INDEX IF NOT EXISTS idx_backups_created_by ON backups(created_by);
|
|
33599
33599
|
|
|
33600
33600
|
UPDATE schema_version SET version = 21;
|
|
33601
|
+
`,
|
|
33602
|
+
// Version 22: Add is_public to resources + rename settings to user_preferences with user_id
|
|
33603
|
+
`
|
|
33604
|
+
-- Create system user for storing system-wide preferences (if not exists)
|
|
33605
|
+
INSERT OR IGNORE INTO users (id, email, password_hash, role, created_at, updated_at)
|
|
33606
|
+
VALUES ('system', 'system@internal', '', 'admin', datetime('now'), datetime('now'));
|
|
33607
|
+
|
|
33608
|
+
-- Ensure settings table exists (even if empty) to avoid errors in migration
|
|
33609
|
+
CREATE TABLE IF NOT EXISTS settings (
|
|
33610
|
+
key TEXT PRIMARY KEY,
|
|
33611
|
+
value TEXT NOT NULL,
|
|
33612
|
+
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
33613
|
+
);
|
|
33614
|
+
|
|
33615
|
+
-- Create user_preferences table (replaces settings)
|
|
33616
|
+
CREATE TABLE IF NOT EXISTS user_preferences (
|
|
33617
|
+
id TEXT PRIMARY KEY,
|
|
33618
|
+
user_id TEXT NOT NULL,
|
|
33619
|
+
key TEXT NOT NULL,
|
|
33620
|
+
value TEXT NOT NULL,
|
|
33621
|
+
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
33622
|
+
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
|
|
33623
|
+
UNIQUE(user_id, key)
|
|
33624
|
+
);
|
|
33625
|
+
|
|
33626
|
+
-- Migrate existing settings as system defaults (user_id = 'system')
|
|
33627
|
+
INSERT OR IGNORE INTO user_preferences (id, user_id, key, value, updated_at)
|
|
33628
|
+
SELECT hex(randomblob(16)), 'system', key, value, updated_at FROM settings;
|
|
33629
|
+
|
|
33630
|
+
-- Drop old settings table
|
|
33631
|
+
DROP TABLE IF EXISTS settings;
|
|
33632
|
+
|
|
33633
|
+
-- Create index for user preferences
|
|
33634
|
+
CREATE INDEX IF NOT EXISTS idx_user_preferences_user ON user_preferences(user_id);
|
|
33635
|
+
CREATE INDEX IF NOT EXISTS idx_user_preferences_key ON user_preferences(user_id, key);
|
|
33636
|
+
|
|
33637
|
+
-- Add is_public to resources (default 0 = private, only owner can see)
|
|
33638
|
+
ALTER TABLE connections ADD COLUMN is_public INTEGER NOT NULL DEFAULT 0;
|
|
33639
|
+
ALTER TABLE servers ADD COLUMN is_public INTEGER NOT NULL DEFAULT 0;
|
|
33640
|
+
ALTER TABLE projects ADD COLUMN is_public INTEGER NOT NULL DEFAULT 0;
|
|
33641
|
+
ALTER TABLE database_groups ADD COLUMN is_public INTEGER NOT NULL DEFAULT 0;
|
|
33642
|
+
ALTER TABLE saved_queries ADD COLUMN is_public INTEGER NOT NULL DEFAULT 0;
|
|
33643
|
+
|
|
33644
|
+
UPDATE schema_version SET version = 22;
|
|
33601
33645
|
`
|
|
33602
33646
|
];
|
|
33603
33647
|
|
|
@@ -33717,9 +33761,9 @@ var ConnectionRepository = class {
|
|
|
33717
33761
|
const encryptedPwd = input.password ? encryptPassword(input.password) : null;
|
|
33718
33762
|
const connectionType = input.connectionType || this.inferConnectionType(input.host);
|
|
33719
33763
|
this.db.prepare(`
|
|
33720
|
-
INSERT INTO connections (id, name, engine, connection_type, host, port, database, username, encrypted_password, ssl, default_schema, tags, read_only, server_id, project_id, group_id, created_by, created_at, updated_at)
|
|
33721
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
33722
|
-
`).run(id, input.name, input.engine, connectionType, input.host, input.port, input.database, input.username, encryptedPwd, input.ssl ? 1 : 0, input.defaultSchema || null, JSON.stringify(input.tags ?? []), input.readOnly ? 1 : 0, input.serverId || null, input.projectId || null, input.groupId || null, userId || null, now, now);
|
|
33764
|
+
INSERT INTO connections (id, name, engine, connection_type, host, port, database, username, encrypted_password, ssl, default_schema, tags, read_only, server_id, project_id, group_id, is_public, created_by, created_at, updated_at)
|
|
33765
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
33766
|
+
`).run(id, input.name, input.engine, connectionType, input.host, input.port, input.database, input.username, encryptedPwd, input.ssl ? 1 : 0, input.defaultSchema || null, JSON.stringify(input.tags ?? []), input.readOnly ? 1 : 0, input.serverId || null, input.projectId || null, input.groupId || null, input.isPublic ? 1 : 0, userId || null, now, now);
|
|
33723
33767
|
return this.findById(id);
|
|
33724
33768
|
}
|
|
33725
33769
|
/**
|
|
@@ -33775,7 +33819,7 @@ var ConnectionRepository = class {
|
|
|
33775
33819
|
`;
|
|
33776
33820
|
const params = [];
|
|
33777
33821
|
if (userContext && !userContext.isAdmin && userContext.userId) {
|
|
33778
|
-
query += ` WHERE c.created_by = ? OR c.created_by IS NULL`;
|
|
33822
|
+
query += ` WHERE (c.created_by = ? OR c.created_by IS NULL OR c.is_public = 1)`;
|
|
33779
33823
|
params.push(userContext.userId);
|
|
33780
33824
|
}
|
|
33781
33825
|
query += ` ORDER BY p.name, dg.name, c.name`;
|
|
@@ -33800,7 +33844,7 @@ var ConnectionRepository = class {
|
|
|
33800
33844
|
`;
|
|
33801
33845
|
const params = [projectId];
|
|
33802
33846
|
if (userContext && !userContext.isAdmin && userContext.userId) {
|
|
33803
|
-
query += ` AND (c.created_by = ? OR c.created_by IS NULL)`;
|
|
33847
|
+
query += ` AND (c.created_by = ? OR c.created_by IS NULL OR c.is_public = 1)`;
|
|
33804
33848
|
params.push(userContext.userId);
|
|
33805
33849
|
}
|
|
33806
33850
|
query += ` ORDER BY dg.name, c.name`;
|
|
@@ -33825,7 +33869,7 @@ var ConnectionRepository = class {
|
|
|
33825
33869
|
`;
|
|
33826
33870
|
const params = [groupId];
|
|
33827
33871
|
if (userContext && !userContext.isAdmin && userContext.userId) {
|
|
33828
|
-
query += ` AND (c.created_by = ? OR c.created_by IS NULL)`;
|
|
33872
|
+
query += ` AND (c.created_by = ? OR c.created_by IS NULL OR c.is_public = 1)`;
|
|
33829
33873
|
params.push(userContext.userId);
|
|
33830
33874
|
}
|
|
33831
33875
|
query += ` ORDER BY c.name`;
|
|
@@ -33850,7 +33894,7 @@ var ConnectionRepository = class {
|
|
|
33850
33894
|
`;
|
|
33851
33895
|
const params = [];
|
|
33852
33896
|
if (userContext && !userContext.isAdmin && userContext.userId) {
|
|
33853
|
-
query += ` AND (c.created_by = ? OR c.created_by IS NULL)`;
|
|
33897
|
+
query += ` AND (c.created_by = ? OR c.created_by IS NULL OR c.is_public = 1)`;
|
|
33854
33898
|
params.push(userContext.userId);
|
|
33855
33899
|
}
|
|
33856
33900
|
query += ` ORDER BY c.name`;
|
|
@@ -33874,7 +33918,7 @@ var ConnectionRepository = class {
|
|
|
33874
33918
|
`;
|
|
33875
33919
|
const params = [];
|
|
33876
33920
|
if (userContext && !userContext.isAdmin && userContext.userId) {
|
|
33877
|
-
query += ` WHERE c.created_by = ? OR c.created_by IS NULL`;
|
|
33921
|
+
query += ` WHERE (c.created_by = ? OR c.created_by IS NULL OR c.is_public = 1)`;
|
|
33878
33922
|
params.push(userContext.userId);
|
|
33879
33923
|
}
|
|
33880
33924
|
query += ` ORDER BY c.name`;
|
|
@@ -33949,6 +33993,10 @@ var ConnectionRepository = class {
|
|
|
33949
33993
|
updates.push("server_id = ?");
|
|
33950
33994
|
values.push(input.serverId);
|
|
33951
33995
|
}
|
|
33996
|
+
if (input.isPublic !== void 0) {
|
|
33997
|
+
updates.push("is_public = ?");
|
|
33998
|
+
values.push(input.isPublic ? 1 : 0);
|
|
33999
|
+
}
|
|
33952
34000
|
if (updates.length > 0) {
|
|
33953
34001
|
updates.push("updated_at = ?");
|
|
33954
34002
|
values.push((/* @__PURE__ */ new Date()).toISOString());
|
|
@@ -34020,21 +34068,23 @@ var ConnectionRepository = class {
|
|
|
34020
34068
|
projectId: row.project_id || void 0,
|
|
34021
34069
|
groupId: row.group_id || void 0,
|
|
34022
34070
|
createdBy: row.created_by || void 0,
|
|
34071
|
+
isPublic: row.is_public === 1,
|
|
34023
34072
|
serverName: row.server_name,
|
|
34024
34073
|
projectName: row.project_name,
|
|
34025
34074
|
groupName: row.group_name
|
|
34026
34075
|
};
|
|
34027
34076
|
}
|
|
34028
34077
|
/**
|
|
34029
|
-
* Check if user can access a connection
|
|
34078
|
+
* Check if user can access (view) a connection
|
|
34079
|
+
* Accessible if: owner, admin, not private, or created_by is null (legacy)
|
|
34030
34080
|
*/
|
|
34031
34081
|
canAccess(connectionId, userContext) {
|
|
34032
34082
|
if (userContext.isAdmin)
|
|
34033
34083
|
return true;
|
|
34034
|
-
const row = this.db.prepare("SELECT created_by FROM connections WHERE id = ?").get(connectionId);
|
|
34084
|
+
const row = this.db.prepare("SELECT created_by, is_public FROM connections WHERE id = ?").get(connectionId);
|
|
34035
34085
|
if (!row)
|
|
34036
34086
|
return false;
|
|
34037
|
-
return row.created_by === null || row.created_by === userContext.userId;
|
|
34087
|
+
return row.created_by === null || row.created_by === userContext.userId || row.is_public === 1;
|
|
34038
34088
|
}
|
|
34039
34089
|
/**
|
|
34040
34090
|
* Find connections by server ID (filtered by user unless admin)
|
|
@@ -34053,13 +34103,25 @@ var ConnectionRepository = class {
|
|
|
34053
34103
|
`;
|
|
34054
34104
|
const params = [serverId];
|
|
34055
34105
|
if (userContext && !userContext.isAdmin && userContext.userId) {
|
|
34056
|
-
query += ` AND (c.created_by = ? OR c.created_by IS NULL)`;
|
|
34106
|
+
query += ` AND (c.created_by = ? OR c.created_by IS NULL OR c.is_public = 1)`;
|
|
34057
34107
|
params.push(userContext.userId);
|
|
34058
34108
|
}
|
|
34059
34109
|
query += ` ORDER BY c.name`;
|
|
34060
34110
|
const rows = this.db.prepare(query).all(...params);
|
|
34061
34111
|
return rows.map((row) => this.rowToConnection(row));
|
|
34062
34112
|
}
|
|
34113
|
+
/**
|
|
34114
|
+
* Check if user can modify (update/delete) a connection
|
|
34115
|
+
* Only owner or admin can modify
|
|
34116
|
+
*/
|
|
34117
|
+
canModify(connectionId, userContext) {
|
|
34118
|
+
if (userContext.isAdmin)
|
|
34119
|
+
return true;
|
|
34120
|
+
const row = this.db.prepare("SELECT created_by FROM connections WHERE id = ?").get(connectionId);
|
|
34121
|
+
if (!row)
|
|
34122
|
+
return false;
|
|
34123
|
+
return row.created_by === null || row.created_by === userContext.userId;
|
|
34124
|
+
}
|
|
34063
34125
|
};
|
|
34064
34126
|
|
|
34065
34127
|
// packages/metadata/dist/repositories/server.repository.js
|
|
@@ -34096,6 +34158,7 @@ var ServerRepository = class {
|
|
|
34096
34158
|
createdAt: new Date(row.created_at),
|
|
34097
34159
|
updatedAt: new Date(row.updated_at),
|
|
34098
34160
|
createdBy: row.created_by ?? void 0,
|
|
34161
|
+
isPublic: row.is_public === 1,
|
|
34099
34162
|
databaseCount: row.database_count
|
|
34100
34163
|
};
|
|
34101
34164
|
}
|
|
@@ -34148,7 +34211,7 @@ var ServerRepository = class {
|
|
|
34148
34211
|
`;
|
|
34149
34212
|
const params = [];
|
|
34150
34213
|
if (userContext && !userContext.isAdmin && userContext.userId) {
|
|
34151
|
-
query += ` WHERE s.created_by = ? OR s.created_by IS NULL`;
|
|
34214
|
+
query += ` WHERE (s.created_by = ? OR s.created_by IS NULL OR s.is_public = 1)`;
|
|
34152
34215
|
params.push(userContext.userId);
|
|
34153
34216
|
}
|
|
34154
34217
|
query += ` ORDER BY s.name`;
|
|
@@ -34167,7 +34230,7 @@ var ServerRepository = class {
|
|
|
34167
34230
|
`;
|
|
34168
34231
|
const params = [engine];
|
|
34169
34232
|
if (userContext && !userContext.isAdmin && userContext.userId) {
|
|
34170
|
-
query += ` AND (s.created_by = ? OR s.created_by IS NULL)`;
|
|
34233
|
+
query += ` AND (s.created_by = ? OR s.created_by IS NULL OR s.is_public = 1)`;
|
|
34171
34234
|
params.push(userContext.userId);
|
|
34172
34235
|
}
|
|
34173
34236
|
query += ` ORDER BY s.name`;
|
|
@@ -34175,9 +34238,20 @@ var ServerRepository = class {
|
|
|
34175
34238
|
return rows.map((row) => this.rowToServer(row));
|
|
34176
34239
|
}
|
|
34177
34240
|
/**
|
|
34178
|
-
* Check if user can access a server
|
|
34241
|
+
* Check if user can access (view) a server
|
|
34179
34242
|
*/
|
|
34180
34243
|
canAccess(serverId, userContext) {
|
|
34244
|
+
if (userContext.isAdmin)
|
|
34245
|
+
return true;
|
|
34246
|
+
const row = this.db.prepare("SELECT created_by, is_public FROM servers WHERE id = ?").get(serverId);
|
|
34247
|
+
if (!row)
|
|
34248
|
+
return false;
|
|
34249
|
+
return row.created_by === null || row.created_by === userContext.userId || row.is_public === 1;
|
|
34250
|
+
}
|
|
34251
|
+
/**
|
|
34252
|
+
* Check if user can modify (update/delete) a server
|
|
34253
|
+
*/
|
|
34254
|
+
canModify(serverId, userContext) {
|
|
34181
34255
|
if (userContext.isAdmin)
|
|
34182
34256
|
return true;
|
|
34183
34257
|
const row = this.db.prepare("SELECT created_by FROM servers WHERE id = ?").get(serverId);
|
|
@@ -34235,6 +34309,10 @@ var ServerRepository = class {
|
|
|
34235
34309
|
updates.push("stop_command = ?");
|
|
34236
34310
|
values.push(input.stopCommand || null);
|
|
34237
34311
|
}
|
|
34312
|
+
if (input.isPublic !== void 0) {
|
|
34313
|
+
updates.push("is_public = ?");
|
|
34314
|
+
values.push(input.isPublic ? 1 : 0);
|
|
34315
|
+
}
|
|
34238
34316
|
if (updates.length === 0) {
|
|
34239
34317
|
return existing;
|
|
34240
34318
|
}
|
|
@@ -34279,7 +34357,7 @@ var ServerRepository = class {
|
|
|
34279
34357
|
};
|
|
34280
34358
|
|
|
34281
34359
|
// apps/cli/dist/version.js
|
|
34282
|
-
var VERSION = true ? "0.
|
|
34360
|
+
var VERSION = true ? "0.5.0" : "0.1.10";
|
|
34283
34361
|
|
|
34284
34362
|
// apps/cli/dist/commands/init.js
|
|
34285
34363
|
function loadEnvFile(cwd) {
|
|
@@ -34751,7 +34829,7 @@ var PostgresConnector = class {
|
|
|
34751
34829
|
port: this.config.port,
|
|
34752
34830
|
database: this.config.database,
|
|
34753
34831
|
user: this.config.username,
|
|
34754
|
-
password: this.config.password,
|
|
34832
|
+
password: this.config.password ?? "",
|
|
34755
34833
|
ssl: this.config.ssl ? { rejectUnauthorized: this.config.sslVerify ?? false } : false,
|
|
34756
34834
|
connectionTimeoutMillis: 5e3,
|
|
34757
34835
|
max: 1
|
|
@@ -34783,7 +34861,7 @@ var PostgresConnector = class {
|
|
|
34783
34861
|
port: this.config.port,
|
|
34784
34862
|
database: this.config.database,
|
|
34785
34863
|
user: this.config.username,
|
|
34786
|
-
password: this.config.password,
|
|
34864
|
+
password: this.config.password ?? "",
|
|
34787
34865
|
ssl: this.config.ssl ? { rejectUnauthorized: this.config.sslVerify ?? false } : false,
|
|
34788
34866
|
max: 10,
|
|
34789
34867
|
idleTimeoutMillis: 3e4,
|