dbgate-api 5.2.8 → 5.3.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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "dbgate-api",
3
3
  "main": "src/index.js",
4
- "version": "5.2.8",
4
+ "version": "5.3.0",
5
5
  "homepage": "https://dbgate.org/",
6
6
  "repository": {
7
7
  "type": "git",
@@ -26,10 +26,10 @@
26
26
  "compare-versions": "^3.6.0",
27
27
  "cors": "^2.8.5",
28
28
  "cross-env": "^6.0.3",
29
- "dbgate-query-splitter": "^4.9.3",
30
- "dbgate-sqltree": "^5.2.8",
31
- "dbgate-tools": "^5.2.8",
32
- "dbgate-datalib": "^5.2.8",
29
+ "dbgate-datalib": "^5.3.0",
30
+ "dbgate-query-splitter": "^4.10.1",
31
+ "dbgate-sqltree": "^5.3.0",
32
+ "dbgate-tools": "^5.3.0",
33
33
  "debug": "^4.3.4",
34
34
  "diff": "^5.0.0",
35
35
  "diff2html": "^3.4.13",
@@ -52,16 +52,15 @@
52
52
  "ncp": "^2.0.0",
53
53
  "node-cron": "^2.0.3",
54
54
  "on-finished": "^2.4.1",
55
- "pinomin": "^1.0.1",
55
+ "pinomin": "^1.0.4",
56
56
  "portfinder": "^1.0.28",
57
57
  "rimraf": "^3.0.0",
58
58
  "simple-encryptor": "^4.0.0",
59
59
  "ssh2": "^1.11.0",
60
- "tar": "^6.0.5",
61
- "uuid": "^3.4.0"
60
+ "tar": "^6.0.5"
62
61
  },
63
62
  "scripts": {
64
- "start": "env-cmd node src/index.js --listen-api",
63
+ "start": "env-cmd -f .env node src/index.js --listen-api",
65
64
  "start:portal": "env-cmd -f env/portal/.env node src/index.js --listen-api",
66
65
  "start:singledb": "env-cmd -f env/singledb/.env node src/index.js --listen-api",
67
66
  "start:auth": "env-cmd -f env/auth/.env node src/index.js --listen-api",
@@ -74,7 +73,7 @@
74
73
  "devDependencies": {
75
74
  "@types/fs-extra": "^9.0.11",
76
75
  "@types/lodash": "^4.14.149",
77
- "dbgate-types": "^5.2.8",
76
+ "dbgate-types": "^5.3.0",
78
77
  "env-cmd": "^10.1.0",
79
78
  "node-loader": "^1.0.2",
80
79
  "nodemon": "^2.0.2",
@@ -84,7 +83,6 @@
84
83
  },
85
84
  "optionalDependencies": {
86
85
  "better-sqlite3": "9.6.0",
87
- "msnodesqlv8": "^4.2.1",
88
- "oracledb": "^5.5.0"
86
+ "msnodesqlv8": "^4.2.1"
89
87
  }
90
88
  }
@@ -1,12 +1,12 @@
1
1
  const fs = require('fs-extra');
2
2
  const readline = require('readline');
3
+ const crypto = require('crypto');
3
4
  const path = require('path');
4
5
  const { archivedir, clearArchiveLinksCache, resolveArchiveFolder } = require('../utility/directories');
5
6
  const socket = require('../utility/socket');
6
7
  const loadFilesRecursive = require('../utility/loadFilesRecursive');
7
8
  const getJslFileName = require('../utility/getJslFileName');
8
9
  const { getLogger } = require('dbgate-tools');
9
- const uuidv1 = require('uuid/v1');
10
10
  const dbgateApi = require('../shell');
11
11
  const jsldata = require('./jsldata');
12
12
  const platformInfo = require('../utility/platformInfo');
@@ -127,7 +127,7 @@ module.exports = {
127
127
  return true;
128
128
  }
129
129
 
130
- const tmpchangedFilePath = path.join(resolveArchiveFolder(folder), `${file}-${uuidv1()}.jsonl`);
130
+ const tmpchangedFilePath = path.join(resolveArchiveFolder(folder), `${file}-${crypto.randomUUID()}.jsonl`);
131
131
  const reader = await dbgateApi.modifyJsonLinesReader({
132
132
  fileName: changedFilePath,
133
133
  changeSet,
@@ -1,14 +1,14 @@
1
1
  const axios = require('axios');
2
2
  const jwt = require('jsonwebtoken');
3
3
  const getExpressPath = require('../utility/getExpressPath');
4
- const uuidv1 = require('uuid/v1');
5
4
  const { getLogins } = require('../utility/hasPermission');
6
5
  const { getLogger } = require('dbgate-tools');
7
6
  const AD = require('activedirectory2').promiseWrapper;
7
+ const crypto = require('crypto');
8
8
 
9
9
  const logger = getLogger('auth');
10
10
 
11
- const tokenSecret = uuidv1();
11
+ const tokenSecret = crypto.randomUUID();
12
12
 
13
13
  function shouldAuthorizeApi() {
14
14
  const logins = getLogins();
@@ -90,6 +90,24 @@ module.exports = {
90
90
  ) {
91
91
  return { error: `Username ${login} not allowed to log in` };
92
92
  }
93
+
94
+ const groups =
95
+ process.env.OAUTH_GROUP_FIELD && payload && payload[process.env.OAUTH_GROUP_FIELD]
96
+ ? payload[process.env.OAUTH_GROUP_FIELD]
97
+ : [];
98
+
99
+ const allowedGroups =
100
+ process.env.OAUTH_ALLOWED_GROUPS
101
+ ? process.env.OAUTH_ALLOWED_GROUPS.split(',').map(group => group.toLowerCase().trim())
102
+ : [];
103
+
104
+ if (
105
+ process.env.OAUTH_ALLOWED_GROUPS &&
106
+ !groups.some(group => allowedGroups.includes(group.toLowerCase().trim()))
107
+ ) {
108
+ return { error: `Username ${login} does not belong to an allowed group` };
109
+ }
110
+
93
111
  if (access_token) {
94
112
  return {
95
113
  accessToken: jwt.sign({ login }, tokenSecret, { expiresIn: getTokenLifetime() }),
@@ -61,6 +61,7 @@ function getPortalCollections() {
61
61
  useDatabaseUrl: !!process.env[`URL_${id}`],
62
62
  databaseFile: process.env[`FILE_${id}`],
63
63
  socketPath: process.env[`SOCKET_PATH_${id}`],
64
+ serviceName: process.env[`SERVICE_NAME_${id}`],
64
65
  authType: process.env[`AUTH_TYPE_${id}`] || (process.env[`SOCKET_PATH_${id}`] ? 'socket' : undefined),
65
66
  defaultDatabase:
66
67
  process.env[`DATABASE_${id}`] ||
@@ -1,4 +1,3 @@
1
- const uuidv1 = require('uuid/v1');
2
1
  const connections = require('./connections');
3
2
  const archive = require('./archive');
4
3
  const socket = require('../utility/socket');
@@ -30,6 +29,7 @@ const processArgs = require('../utility/processArgs');
30
29
  const { testConnectionPermission } = require('../utility/hasPermission');
31
30
  const { MissingCredentialsError } = require('../utility/exceptions');
32
31
  const pipeForkLogs = require('../utility/pipeForkLogs');
32
+ const crypto = require('crypto');
33
33
 
34
34
  const logger = getLogger('databaseConnections');
35
35
 
@@ -137,7 +137,7 @@ module.exports = {
137
137
 
138
138
  /** @param {import('dbgate-types').OpenedDatabaseConnection} conn */
139
139
  sendRequest(conn, message) {
140
- const msgid = uuidv1();
140
+ const msgid = crypto.randomUUID();
141
141
  const promise = new Promise((resolve, reject) => {
142
142
  this.requests[msgid] = [resolve, reject];
143
143
  try {
@@ -1,6 +1,6 @@
1
- const uuidv1 = require('uuid/v1');
2
1
  const fs = require('fs-extra');
3
2
  const path = require('path');
3
+ const crypto = require('crypto');
4
4
  const { filesdir, archivedir, resolveArchiveFolder, uploadsdir, appdir } = require('../utility/directories');
5
5
  const getChartExport = require('../utility/getChartExport');
6
6
  const { hasPermission } = require('../utility/hasPermission');
@@ -164,7 +164,7 @@ module.exports = {
164
164
 
165
165
  generateUploadsFile_meta: true,
166
166
  async generateUploadsFile({ extension }) {
167
- const fileName = `${uuidv1()}.${extension || 'html'}`;
167
+ const fileName = `${crypto.randomUUID()}.${extension || 'html'}`;
168
168
  return {
169
169
  fileName,
170
170
  filePath: path.join(uploadsdir(), fileName),
@@ -1,7 +1,7 @@
1
+ const crypto = require('crypto');
1
2
  const _ = require('lodash');
2
3
  const path = require('path');
3
4
  const fs = require('fs-extra');
4
- const uuidv1 = require('uuid/v1');
5
5
  const byline = require('byline');
6
6
  const socket = require('../utility/socket');
7
7
  const { fork } = require('child_process');
@@ -165,7 +165,7 @@ module.exports = {
165
165
 
166
166
  start_meta: true,
167
167
  async start({ script }) {
168
- const runid = uuidv1();
168
+ const runid = crypto.randomUUID()
169
169
 
170
170
  if (script.type == 'json') {
171
171
  const js = jsonScriptToJavascript(script);
@@ -213,7 +213,7 @@ module.exports = {
213
213
  loadReader_meta: true,
214
214
  async loadReader({ functionName, props }) {
215
215
  const promise = new Promise((resolve, reject) => {
216
- const runid = uuidv1();
216
+ const runid = crypto.randomUUID();
217
217
  this.requests[runid] = [resolve, reject];
218
218
  this.startCore(runid, loaderScriptTemplate(functionName, props, runid));
219
219
  });
@@ -1,7 +1,6 @@
1
1
  const connections = require('./connections');
2
2
  const socket = require('../utility/socket');
3
3
  const { fork } = require('child_process');
4
- const uuidv1 = require('uuid/v1');
5
4
  const _ = require('lodash');
6
5
  const AsyncLock = require('async-lock');
7
6
  const { handleProcessCommunication } = require('../utility/processComm');
@@ -152,7 +151,7 @@ module.exports = {
152
151
  },
153
152
 
154
153
  ping_meta: true,
155
- async ping({ conidArray }) {
154
+ async ping({ conidArray, strmid }) {
156
155
  await Promise.all(
157
156
  _.uniq(conidArray).map(async conid => {
158
157
  const last = this.lastPinged[conid];
@@ -169,6 +168,7 @@ module.exports = {
169
168
  }
170
169
  })
171
170
  );
171
+ socket.setStreamIdFilter(strmid, { conid: conidArray });
172
172
  return { status: 'ok' };
173
173
  },
174
174
 
@@ -200,7 +200,7 @@ module.exports = {
200
200
  },
201
201
 
202
202
  sendRequest(conn, message) {
203
- const msgid = uuidv1();
203
+ const msgid = crypto.randomUUID();
204
204
  const promise = new Promise((resolve, reject) => {
205
205
  this.requests[msgid] = [resolve, reject];
206
206
  try {
@@ -240,4 +240,20 @@ module.exports = {
240
240
  if (opened.connection.isReadOnly) return false;
241
241
  return this.loadDataCore('summaryCommand', { conid, command, row });
242
242
  },
243
+
244
+ getOpenedConnectionReport() {
245
+ return this.opened.map(con => ({
246
+ status: con.status,
247
+ versionText: con.version?.versionText,
248
+ databaseCount: con.databases.length,
249
+ connection: _.pick(con.connection, [
250
+ 'engine',
251
+ 'useSshTunnel',
252
+ 'authType',
253
+ 'trustServerCertificate',
254
+ 'useSsl',
255
+ 'sshMode',
256
+ ]),
257
+ }));
258
+ },
243
259
  };
@@ -1,5 +1,5 @@
1
+ const crypto = require('crypto');
1
2
  const _ = require('lodash');
2
- const uuidv1 = require('uuid/v1');
3
3
  const connections = require('./connections');
4
4
  const socket = require('../utility/socket');
5
5
  const { fork } = require('child_process');
@@ -85,7 +85,7 @@ module.exports = {
85
85
 
86
86
  create_meta: true,
87
87
  async create({ conid, database }) {
88
- const sesid = uuidv1();
88
+ const sesid = crypto.randomUUID();
89
89
  const connection = await connections.getCore({ conid });
90
90
  const subprocess = fork(
91
91
  global['API_PACKAGE'] || process.argv[1],
@@ -1,8 +1,17 @@
1
+ const crypto = require('crypto');
1
2
  const path = require('path');
2
- const { uploadsdir } = require('../utility/directories');
3
- const uuidv1 = require('uuid/v1');
3
+ const { uploadsdir, getLogsFilePath } = require('../utility/directories');
4
4
  const { getLogger } = require('dbgate-tools');
5
5
  const logger = getLogger('uploads');
6
+ const axios = require('axios');
7
+ const os = require('os');
8
+ const fs = require('fs/promises');
9
+ const { read } = require('./queryHistory');
10
+ const platformInfo = require('../utility/platformInfo');
11
+ const _ = require('lodash');
12
+ const serverConnections = require('./serverConnections');
13
+ const config = require('./config');
14
+ const gistSecret = require('../gistSecret');
6
15
 
7
16
  module.exports = {
8
17
  upload_meta: {
@@ -15,7 +24,7 @@ module.exports = {
15
24
  res.json(null);
16
25
  return;
17
26
  }
18
- const uploadName = uuidv1();
27
+ const uploadName = crypto.randomUUID();
19
28
  const filePath = path.join(uploadsdir(), uploadName);
20
29
  logger.info(`Uploading file ${data.name}, size=${data.size}`);
21
30
 
@@ -35,4 +44,86 @@ module.exports = {
35
44
  get(req, res) {
36
45
  res.sendFile(path.join(uploadsdir(), req.query.file));
37
46
  },
47
+
48
+ async getGistToken() {
49
+ const settings = await config.getSettings();
50
+
51
+ return settings['other.gistCreateToken'] || gistSecret;
52
+ },
53
+
54
+ uploadErrorToGist_meta: true,
55
+ async uploadErrorToGist() {
56
+ const logs = await fs.readFile(getLogsFilePath(), { encoding: 'utf-8' });
57
+ const connections = await serverConnections.getOpenedConnectionReport();
58
+ try {
59
+ const response = await axios.default.post(
60
+ 'https://api.github.com/gists',
61
+ {
62
+ description: 'DbGate error report',
63
+ public: false,
64
+ files: {
65
+ 'logs.jsonl': {
66
+ content: logs,
67
+ },
68
+ 'os.json': {
69
+ content: JSON.stringify(
70
+ {
71
+ release: os.release(),
72
+ arch: os.arch(),
73
+ machine: os.machine(),
74
+ platform: os.platform(),
75
+ type: os.type(),
76
+ },
77
+ null,
78
+ 2
79
+ ),
80
+ },
81
+ 'platform.json': {
82
+ content: JSON.stringify(
83
+ _.omit(
84
+ {
85
+ ...platformInfo,
86
+ },
87
+ ['defaultKeyfile', 'sshAuthSock']
88
+ ),
89
+ null,
90
+ 2
91
+ ),
92
+ },
93
+ 'connections.json': {
94
+ content: JSON.stringify(connections, null, 2),
95
+ },
96
+ },
97
+ },
98
+ {
99
+ headers: {
100
+ Authorization: `token ${await this.getGistToken()}`,
101
+ 'Content-Type': 'application/json',
102
+ Accept: 'application/vnd.github.v3+json',
103
+ },
104
+ }
105
+ );
106
+
107
+ return response.data;
108
+ } catch (err) {
109
+ logger.error({ err }, 'Error uploading gist');
110
+
111
+ return {
112
+ apiErrorMessage: err.message,
113
+ };
114
+ // console.error('Error creating gist:', error.response ? error.response.data : error.message);
115
+ }
116
+ },
117
+
118
+ deleteGist_meta: true,
119
+ async deleteGist({ url }) {
120
+ const response = await axios.default.delete(url, {
121
+ headers: {
122
+ Authorization: `token ${await this.getGistToken()}`,
123
+ 'Content-Type': 'application/json',
124
+ Accept: 'application/vnd.github.v3+json',
125
+ },
126
+ });
127
+ return true;
128
+ },
38
129
  };
@@ -1,5 +1,5 @@
1
1
 
2
2
  module.exports = {
3
- version: '5.2.8',
4
- buildTime: '2024-05-17T04:41:36.747Z'
3
+ version: '5.3.0',
4
+ buildTime: '2024-06-07T08:19:32.117Z'
5
5
  };
@@ -0,0 +1,2 @@
1
+
2
+ module.exports = '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';
package/src/index.js CHANGED
@@ -1,4 +1,4 @@
1
- const { setLogger, getLogger, setLoggerName } = require('dbgate-tools');
1
+ const { setLogConfig, getLogger, setLoggerName } = require('dbgate-tools');
2
2
  const processArgs = require('./utility/processArgs');
3
3
  const fs = require('fs');
4
4
  const moment = require('moment');
@@ -30,22 +30,27 @@ function configureLogger() {
30
30
  setLogsFilePath(logsFilePath);
31
31
  setLoggerName('main');
32
32
 
33
- const logger = createLogger({
33
+ const consoleLogLevel = process.env.CONSOLE_LOG_LEVEL || process.env.LOG_LEVEL || 'info';
34
+ const fileLogLevel = process.env.FILE_LOG_LEVEL || process.env.LOG_LEVEL || 'debug';
35
+
36
+ const logConfig = {
34
37
  base: { pid: process.pid },
35
38
  targets: [
36
39
  {
37
40
  type: 'console',
38
41
  // @ts-ignore
39
- level: process.env.CONSOLE_LOG_LEVEL || process.env.LOG_LEVEL || 'info',
42
+ level: consoleLogLevel,
40
43
  },
41
44
  {
42
45
  type: 'stream',
43
46
  // @ts-ignore
44
- level: process.env.FILE_LOG_LEVEL || process.env.LOG_LEVEL || 'info',
47
+ level: fileLogLevel,
45
48
  stream: fs.createWriteStream(logsFilePath, { flags: 'a' }),
46
49
  },
47
50
  ],
48
- });
51
+ };
52
+
53
+ // logger.info(`Initialized logging, console log level: ${consoleLogLevel}, file log level: ${fileLogLevel}`);
49
54
 
50
55
  // const streams = [];
51
56
  // if (!platformInfo.isElectron) {
@@ -83,14 +88,15 @@ function configureLogger() {
83
88
  // },
84
89
  // });
85
90
 
86
- setLogger(logger);
91
+ // @ts-ignore
92
+ setLogConfig(logConfig);
87
93
  }
88
94
 
89
95
  if (processArgs.listenApi) {
90
96
  configureLogger();
91
97
  }
92
98
 
93
- const shell = require('./shell');
99
+ const shell = require('./shell/index');
94
100
  const dbgateTools = require('dbgate-tools');
95
101
 
96
102
  global['DBGATE_TOOLS'] = dbgateTools;
package/src/main.js CHANGED
@@ -77,6 +77,7 @@ function start() {
77
77
  }
78
78
 
79
79
  app.get(getExpressPath('/stream'), async function (req, res) {
80
+ const strmid = req.query.strmid;
80
81
  res.set({
81
82
  'Cache-Control': 'no-cache',
82
83
  'Content-Type': 'text/event-stream',
@@ -87,9 +88,9 @@ function start() {
87
88
 
88
89
  // Tell the client to retry every 10 seconds if connectivity is lost
89
90
  res.write('retry: 10000\n\n');
90
- socket.addSseResponse(res);
91
+ socket.addSseResponse(res, strmid);
91
92
  onFinished(req, () => {
92
- socket.removeSseResponse(res);
93
+ socket.removeSseResponse(strmid);
93
94
  });
94
95
  });
95
96
 
@@ -2,6 +2,6 @@
2
2
  // this file is generated automatically by script fillNativeModules.js, do not edit it manually
3
3
  const content = {};
4
4
 
5
- content.oracledb = () => require('oracledb');content['better-sqlite3'] = () => require('better-sqlite3');
5
+ content['better-sqlite3'] = () => require('better-sqlite3');
6
6
 
7
7
  module.exports = content;
@@ -1,4 +1,4 @@
1
- const uuidv1 = require('uuid/v1');
1
+ const crypto = require('crypto');
2
2
  const path = require('path');
3
3
  const fs = require('fs');
4
4
  const _ = require('lodash');
@@ -31,7 +31,7 @@ class TableWriter {
31
31
  }
32
32
 
33
33
  initializeFromQuery(structure, resultIndex) {
34
- this.jslid = uuidv1();
34
+ this.jslid = crypto.randomUUID();
35
35
  this.currentFile = path.join(jsldir(), `${this.jslid}.jsonl`);
36
36
  fs.writeFileSync(
37
37
  this.currentFile,
@@ -1,11 +1,11 @@
1
+ const crypto = require('crypto');
1
2
  const path = require('path');
2
- const uuidv1 = require('uuid/v1');
3
3
  const { uploadsdir } = require('../utility/directories');
4
4
  const { downloadFile } = require('../utility/downloader');
5
5
 
6
6
  async function download(url) {
7
7
  if (url && url.match(/(^http:\/\/)|(^https:\/\/)/)) {
8
- const tmpFile = path.join(uploadsdir(), uuidv1());
8
+ const tmpFile = path.join(uploadsdir(), crypto.randomUUID());
9
9
  await downloadFile(url, tmpFile);
10
10
  return tmpFile;
11
11
  }
@@ -1,5 +1,5 @@
1
+ const crypto = require('crypto');
1
2
  const { fork } = require('child_process');
2
- const uuidv1 = require('uuid/v1');
3
3
  const { handleProcessCommunication } = require('./processComm');
4
4
  const processArgs = require('../utility/processArgs');
5
5
  const pipeForkLogs = require('./pipeForkLogs');
@@ -67,7 +67,7 @@ class DatastoreProxy {
67
67
 
68
68
  async getRows(offset, limit) {
69
69
  await this.ensureSubprocess();
70
- const msgid = uuidv1();
70
+ const msgid = crypto.randomUUID();
71
71
  const promise = new Promise((resolve, reject) => {
72
72
  this.requests[msgid] = [resolve, reject];
73
73
  try {
@@ -81,7 +81,7 @@ class DatastoreProxy {
81
81
  }
82
82
 
83
83
  async notifyChangedCore() {
84
- const msgid = uuidv1();
84
+ const msgid = crypto.randomUUID();
85
85
  const promise = new Promise((resolve, reject) => {
86
86
  this.requests[msgid] = [resolve, reject];
87
87
  try {
@@ -1,6 +1,6 @@
1
+ const crypto = require('crypto');
1
2
  const AsyncLock = require('async-lock');
2
3
  const fs = require('fs-extra');
3
- const uuidv1 = require('uuid/v1');
4
4
 
5
5
  const lock = new AsyncLock();
6
6
 
@@ -57,7 +57,7 @@ class JsonLinesDatabase {
57
57
  ? obj
58
58
  : {
59
59
  ...obj,
60
- _id: uuidv1(),
60
+ _id: crypto.randomUUID(),
61
61
  };
62
62
  this.data.push(elem);
63
63
  await this._save();
@@ -1,3 +1,4 @@
1
+ const crypto = require('crypto');
1
2
  const fs = require('fs');
2
3
  const os = require('os');
3
4
  const rimraf = require('rimraf');
@@ -8,7 +9,6 @@ const stableStringify = require('json-stable-stringify');
8
9
  const { evaluateCondition } = require('dbgate-sqltree');
9
10
  const requirePluginFunction = require('./requirePluginFunction');
10
11
  const esort = require('external-sorting');
11
- const uuidv1 = require('uuid/v1');
12
12
  const { jsldir } = require('./directories');
13
13
  const LineReader = require('./LineReader');
14
14
 
@@ -28,7 +28,7 @@ class JsonLinesDatastore {
28
28
  }
29
29
 
30
30
  static async sortFile(infile, outfile, sort) {
31
- const tempDir = path.join(os.tmpdir(), uuidv1());
31
+ const tempDir = path.join(os.tmpdir(), crypto.randomUUID());
32
32
  fs.mkdirSync(tempDir);
33
33
 
34
34
  await esort
@@ -52,7 +52,7 @@ async function connectUtility(driver, storedConnection, connectionMode, addition
52
52
  throw new Error(tunnel.message);
53
53
  }
54
54
 
55
- connection.server = '127.0.0.1';
55
+ connection.server = 'localhost';
56
56
  connection.port = tunnel.localPort;
57
57
  }
58
58
 
@@ -1,7 +1,7 @@
1
+ const crypto = require('crypto');
1
2
  // const pacote = require('pacote');
2
3
  const axios = require('axios');
3
4
  // const tarballExtract = require('tarball-extract');
4
- const uuidv1 = require('uuid/v1');
5
5
  const path = require('path');
6
6
  const fs = require('fs');
7
7
  const zlib = require('zlib');
@@ -38,9 +38,9 @@ async function downloadPackage(packageName, directory) {
38
38
 
39
39
  const tarball = infoResp.data.versions[latest].dist.tarball;
40
40
 
41
- const tmpFile = path.join(uploadsdir(), uuidv1() + '.tgz');
41
+ const tmpFile = path.join(uploadsdir(), crypto.randomUUID() + '.tgz');
42
42
  await downloadFile(tarball, tmpFile);
43
- const tmpDir = path.join(uploadsdir(), uuidv1());
43
+ const tmpDir = path.join(uploadsdir(), crypto.randomUUID());
44
44
  fs.mkdirSync(tmpDir);
45
45
  await extractTarball(tmpFile, tmpDir);
46
46
  await copyDirectory(path.join(tmpDir, 'package'), directory);
@@ -1,7 +1,7 @@
1
1
  const _ = require('lodash');
2
2
  const stableStringify = require('json-stable-stringify');
3
3
 
4
- const sseResponses = [];
4
+ const sseResponses = {};
5
5
  let electronSender = null;
6
6
  let pingConfigured = false;
7
7
 
@@ -12,12 +12,15 @@ module.exports = {
12
12
  pingConfigured = true;
13
13
  }
14
14
  },
15
- addSseResponse(value) {
16
- sseResponses.push(value);
15
+ addSseResponse(value, strmid) {
16
+ sseResponses[strmid] = {
17
+ ...sseResponses[strmid],
18
+ response: value,
19
+ };
17
20
  this.ensurePing();
18
21
  },
19
- removeSseResponse(value) {
20
- _.remove(sseResponses, x => x == value);
22
+ removeSseResponse(strmid) {
23
+ delete sseResponses[strmid];
21
24
  },
22
25
  setElectronSender(value) {
23
26
  electronSender = value;
@@ -27,8 +30,25 @@ module.exports = {
27
30
  if (electronSender) {
28
31
  electronSender.send(message, data == null ? null : data);
29
32
  }
30
- for (const res of sseResponses) {
31
- res.write(`event: ${message}\ndata: ${stableStringify(data == null ? null : data)}\n\n`);
33
+ for (const strmid in sseResponses) {
34
+ let skipThisStream = false;
35
+ if (sseResponses[strmid].filter) {
36
+ for (const key in sseResponses[strmid].filter) {
37
+ if (data && data[key]) {
38
+ if (!sseResponses[strmid].filter[key].includes(data[key])) {
39
+ skipThisStream = true;
40
+ break;
41
+ }
42
+ }
43
+ }
44
+ }
45
+ if (skipThisStream) {
46
+ continue;
47
+ }
48
+
49
+ sseResponses[strmid].response?.write(
50
+ `event: ${message}\ndata: ${stableStringify(data == null ? null : data)}\n\n`
51
+ );
32
52
  }
33
53
  },
34
54
  emitChanged(key, params = undefined) {
@@ -36,4 +56,10 @@ module.exports = {
36
56
  this.emit('changed-cache', { key, ...params });
37
57
  // this.emit(key);
38
58
  },
59
+ setStreamIdFilter(strmid, filter) {
60
+ sseResponses[strmid] = {
61
+ ...sseResponses[strmid],
62
+ filter,
63
+ };
64
+ },
39
65
  };
@@ -1,5 +1,5 @@
1
+ const crypto = require('crypto');
1
2
  const { getLogger } = require('dbgate-tools');
2
- const uuidv1 = require('uuid/v1');
3
3
  const { getSshTunnel } = require('./sshTunnel');
4
4
  const logger = getLogger('sshTunnelProxy');
5
5
 
@@ -22,7 +22,7 @@ function handleGetSshTunnelResponse({ msgid, response }, subprocess) {
22
22
 
23
23
  async function getSshTunnelProxy(connection) {
24
24
  if (!process.send) return getSshTunnel(connection);
25
- const msgid = uuidv1();
25
+ const msgid = crypto.randomUUID();
26
26
  process.send({ msgtype: 'getsshtunnel-request', msgid, connection });
27
27
  return new Promise((resolve, reject) => {
28
28
  dispatchedMessages[msgid] = { resolve, reject };