n8n-nodes-cred-sync 0.4.7 → 0.6.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/dist/nodes/CredentialShare/CredentialShare.node.d.ts +1 -0
- package/dist/nodes/CredentialShare/CredentialShare.node.js +242 -71
- package/dist/nodes/CredentialShare/CredentialShare.node.js.map +1 -1
- package/dist/nodes/CredentialShare/docker.utils.d.ts +13 -2
- package/dist/nodes/CredentialShare/docker.utils.js +215 -13
- package/dist/nodes/CredentialShare/docker.utils.js.map +1 -1
- package/dist/nodes/CredentialShare/interfaces.d.ts +5 -0
- package/dist/nodes/CredentialShare/postgres.utils.js +26 -8
- package/dist/nodes/CredentialShare/postgres.utils.js.map +1 -1
- package/dist/nodes/CredentialShare/sqlite.utils.d.ts +8 -0
- package/dist/nodes/CredentialShare/sqlite.utils.js +54 -0
- package/dist/nodes/CredentialShare/sqlite.utils.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
|
@@ -5,6 +5,7 @@ export declare class CredentialShare implements INodeType {
|
|
|
5
5
|
loadOptions: {
|
|
6
6
|
getResources(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
|
|
7
7
|
getPostgresContainers(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
|
|
8
|
+
getN8nContainers(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
|
|
8
9
|
getUsers(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
|
|
9
10
|
getCredentials(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
|
|
10
11
|
getSharedCredentials(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
|
|
@@ -5,6 +5,7 @@ const n8n_workflow_1 = require("n8n-workflow");
|
|
|
5
5
|
const ssh_utils_1 = require("./ssh.utils");
|
|
6
6
|
const docker_utils_1 = require("./docker.utils");
|
|
7
7
|
const postgres_utils_1 = require("./postgres.utils");
|
|
8
|
+
const sqlite_utils_1 = require("./sqlite.utils");
|
|
8
9
|
const TEST_API_KEYS = {
|
|
9
10
|
'csh_admin_Kp9mN3xQ7rL2vW8t': 'admin',
|
|
10
11
|
'csh_user_Hs5jR1nY4eB6dG2m': 'user',
|
|
@@ -24,7 +25,7 @@ class CredentialShare {
|
|
|
24
25
|
group: ['transform'],
|
|
25
26
|
version: 1,
|
|
26
27
|
subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
|
|
27
|
-
description: 'Share n8n credentials between users via SSH + Docker + PostgreSQL',
|
|
28
|
+
description: 'Share n8n credentials between users via SSH + Docker + PostgreSQL/SQLite',
|
|
28
29
|
defaults: {
|
|
29
30
|
name: 'Cred Sync',
|
|
30
31
|
},
|
|
@@ -46,7 +47,7 @@ class CredentialShare {
|
|
|
46
47
|
},
|
|
47
48
|
noDataExpression: true,
|
|
48
49
|
default: '',
|
|
49
|
-
description: '
|
|
50
|
+
description: 'Resource type (auto-loaded based on credential mode)',
|
|
50
51
|
},
|
|
51
52
|
{
|
|
52
53
|
displayName: 'Operation',
|
|
@@ -64,7 +65,7 @@ class CredentialShare {
|
|
|
64
65
|
{
|
|
65
66
|
name: 'Change Role',
|
|
66
67
|
value: 'changeRole',
|
|
67
|
-
description: '
|
|
68
|
+
description: 'Change user role (global:owner / admin / member)',
|
|
68
69
|
action: 'Change user role',
|
|
69
70
|
},
|
|
70
71
|
],
|
|
@@ -86,7 +87,7 @@ class CredentialShare {
|
|
|
86
87
|
{
|
|
87
88
|
name: 'Copy to User',
|
|
88
89
|
value: 'share',
|
|
89
|
-
description: '
|
|
90
|
+
description: 'Copy a credential to a user (user gets an independent copy)',
|
|
90
91
|
action: 'Copy credential to user',
|
|
91
92
|
},
|
|
92
93
|
{
|
|
@@ -108,18 +109,32 @@ class CredentialShare {
|
|
|
108
109
|
{
|
|
109
110
|
name: 'View Shared Credentials',
|
|
110
111
|
value: 'viewShared',
|
|
111
|
-
description: '
|
|
112
|
+
description: 'List all credentials shared with you',
|
|
112
113
|
action: 'View shared credentials',
|
|
113
114
|
},
|
|
114
115
|
{
|
|
115
116
|
name: 'Add Credential',
|
|
116
117
|
value: 'addCredential',
|
|
117
|
-
description: '
|
|
118
|
+
description: 'Add a shared credential to this n8n instance',
|
|
118
119
|
action: 'Add a credential',
|
|
119
120
|
},
|
|
120
121
|
],
|
|
121
122
|
default: 'viewShared',
|
|
122
123
|
},
|
|
124
|
+
{
|
|
125
|
+
displayName: 'Database Type',
|
|
126
|
+
name: 'dbType',
|
|
127
|
+
type: 'options',
|
|
128
|
+
noDataExpression: true,
|
|
129
|
+
options: [
|
|
130
|
+
{ name: 'Auto (Detect from n8n)', value: 'auto' },
|
|
131
|
+
{ name: 'PostgreSQL', value: 'postgres' },
|
|
132
|
+
{ name: 'SQLite', value: 'sqlite' },
|
|
133
|
+
],
|
|
134
|
+
default: 'auto',
|
|
135
|
+
displayOptions: { show: { resource: ['user', 'credential'] } },
|
|
136
|
+
description: 'Database type used by n8n (or auto-detect from container)',
|
|
137
|
+
},
|
|
123
138
|
{
|
|
124
139
|
displayName: 'PostgreSQL Container',
|
|
125
140
|
name: 'postgresContainer',
|
|
@@ -129,8 +144,20 @@ class CredentialShare {
|
|
|
129
144
|
},
|
|
130
145
|
required: true,
|
|
131
146
|
default: '',
|
|
132
|
-
displayOptions: { show: { resource: ['user', 'credential'] } },
|
|
133
|
-
description: 'Select the PostgreSQL Docker container
|
|
147
|
+
displayOptions: { show: { resource: ['user', 'credential'], dbType: ['postgres'] } },
|
|
148
|
+
description: 'Select the PostgreSQL Docker container',
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
displayName: 'n8n Container',
|
|
152
|
+
name: 'n8nContainer',
|
|
153
|
+
type: 'options',
|
|
154
|
+
typeOptions: {
|
|
155
|
+
loadOptionsMethod: 'getN8nContainers',
|
|
156
|
+
},
|
|
157
|
+
required: true,
|
|
158
|
+
default: '',
|
|
159
|
+
displayOptions: { show: { resource: ['user', 'credential'], dbType: ['auto', 'sqlite'] } },
|
|
160
|
+
description: 'Select the n8n Docker container',
|
|
134
161
|
},
|
|
135
162
|
{
|
|
136
163
|
displayName: 'User',
|
|
@@ -140,7 +167,7 @@ class CredentialShare {
|
|
|
140
167
|
required: true,
|
|
141
168
|
default: '',
|
|
142
169
|
displayOptions: { show: { resource: ['user'], operation: ['changeRole'] } },
|
|
143
|
-
description: '
|
|
170
|
+
description: 'Select the user whose role you want to change',
|
|
144
171
|
},
|
|
145
172
|
{
|
|
146
173
|
displayName: 'New Role',
|
|
@@ -148,14 +175,14 @@ class CredentialShare {
|
|
|
148
175
|
type: 'options',
|
|
149
176
|
noDataExpression: true,
|
|
150
177
|
options: [
|
|
151
|
-
{ name: 'Owner', value: 'global:owner', description: 'Instance
|
|
152
|
-
{ name: 'Admin', value: 'global:admin', description: '
|
|
153
|
-
{ name: 'Member', value: 'global:member', description: '
|
|
178
|
+
{ name: 'Owner', value: 'global:owner', description: 'Instance owner' },
|
|
179
|
+
{ name: 'Admin', value: 'global:admin', description: 'Administrator' },
|
|
180
|
+
{ name: 'Member', value: 'global:member', description: 'Standard member' },
|
|
154
181
|
],
|
|
155
182
|
required: true,
|
|
156
183
|
default: 'global:member',
|
|
157
184
|
displayOptions: { show: { resource: ['user'], operation: ['changeRole'] } },
|
|
158
|
-
description: '
|
|
185
|
+
description: 'New role to assign to the user',
|
|
159
186
|
},
|
|
160
187
|
{
|
|
161
188
|
displayName: 'Credential',
|
|
@@ -259,7 +286,7 @@ class CredentialShare {
|
|
|
259
286
|
displayOptions: {
|
|
260
287
|
show: { resource: ['shared'], operation: ['addCredential'] },
|
|
261
288
|
},
|
|
262
|
-
description: '
|
|
289
|
+
description: 'Select the credential to add to this n8n instance',
|
|
263
290
|
},
|
|
264
291
|
],
|
|
265
292
|
};
|
|
@@ -287,31 +314,71 @@ class CredentialShare {
|
|
|
287
314
|
const allContainers = await (0, docker_utils_1.listContainers)(sshConfig);
|
|
288
315
|
const postgresContainers = allContainers.filter((c) => {
|
|
289
316
|
const img = (c.image || '').toLowerCase();
|
|
290
|
-
const name = c.name.toLowerCase();
|
|
317
|
+
const name = (c.name || '').toLowerCase();
|
|
291
318
|
const imageIsPostgres = img.includes('postgres') && !img.includes('postgrest') && !img.includes('postgres-meta');
|
|
292
|
-
|
|
319
|
+
const nameIsPostgresDb = /(?:^|[-_])postgres(?:ql)?(?:[-_]|$)/.test(name)
|
|
320
|
+
&& !name.includes('backup') && !name.includes('exporter') && !name.includes('admin');
|
|
321
|
+
return imageIsPostgres || nameIsPostgresDb;
|
|
293
322
|
});
|
|
294
323
|
return postgresContainers.map((pg) => ({
|
|
295
324
|
name: `${pg.name} (${pg.image})`,
|
|
296
325
|
value: pg.name,
|
|
297
326
|
}));
|
|
298
327
|
},
|
|
299
|
-
async
|
|
328
|
+
async getN8nContainers() {
|
|
300
329
|
const credentials = await this.getCredentials('sshCredentialsApi');
|
|
301
330
|
if (credentials.mode === 'user')
|
|
302
331
|
return [];
|
|
303
332
|
const sshConfig = (0, ssh_utils_1.buildSshConfig)(credentials);
|
|
304
|
-
const selectedContainer = this.getCurrentNodeParameter('postgresContainer');
|
|
305
333
|
const allContainers = await (0, docker_utils_1.listContainers)(sshConfig);
|
|
306
|
-
const
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
334
|
+
const n8nContainers = allContainers
|
|
335
|
+
.filter((c) => (0, docker_utils_1.isN8nContainer)(c) && !c.name.includes('worker'));
|
|
336
|
+
return n8nContainers.map((c) => ({
|
|
337
|
+
name: `${c.name} (${c.image})`,
|
|
338
|
+
value: c.name,
|
|
339
|
+
}));
|
|
340
|
+
},
|
|
341
|
+
async getUsers() {
|
|
342
|
+
const credentials = await this.getCredentials('sshCredentialsApi');
|
|
343
|
+
if (credentials.mode === 'user')
|
|
344
|
+
return [];
|
|
345
|
+
const sshConfig = (0, ssh_utils_1.buildSshConfig)(credentials);
|
|
346
|
+
const dbTypeParam = this.getCurrentNodeParameter('dbType') || 'auto';
|
|
347
|
+
if (dbTypeParam === 'postgres') {
|
|
348
|
+
const selectedContainer = this.getCurrentNodeParameter('postgresContainer');
|
|
349
|
+
const allContainers = await (0, docker_utils_1.listContainers)(sshConfig);
|
|
350
|
+
const containers = (0, docker_utils_1.identifyContainers)(allContainers, { requireN8n: false });
|
|
351
|
+
const pg = await (0, docker_utils_1.autoDetectPostgres)(sshConfig, containers, allContainers, selectedContainer || undefined);
|
|
352
|
+
const csvOutput = await (0, docker_utils_1.dockerPsql)(sshConfig, pg, (0, postgres_utils_1.queryListUsers)());
|
|
353
|
+
const users = (0, postgres_utils_1.parseCsvOutput)(csvOutput);
|
|
354
|
+
return users
|
|
355
|
+
.map((u) => ({ name: `${u.firstName} ${u.lastName} (${u.email})`, value: u.id }))
|
|
356
|
+
.sort((a, b) => a.name.localeCompare(b.name));
|
|
357
|
+
}
|
|
358
|
+
const n8nContainerName = this.getCurrentNodeParameter('n8nContainer');
|
|
359
|
+
if (!n8nContainerName)
|
|
360
|
+
return [];
|
|
361
|
+
let resolvedDbType = 'sqlite';
|
|
362
|
+
if (dbTypeParam === 'auto') {
|
|
363
|
+
resolvedDbType = await (0, docker_utils_1.detectDbType)(sshConfig, n8nContainerName);
|
|
364
|
+
}
|
|
365
|
+
if (resolvedDbType === 'postgres') {
|
|
366
|
+
const allContainers = await (0, docker_utils_1.listContainers)(sshConfig);
|
|
367
|
+
const pgContainerName = await (0, docker_utils_1.findPostgresForN8n)(sshConfig, allContainers, n8nContainerName);
|
|
368
|
+
if (!pgContainerName)
|
|
369
|
+
return [];
|
|
370
|
+
const containers = (0, docker_utils_1.identifyContainers)(allContainers, { requireN8n: false });
|
|
371
|
+
const pg = await (0, docker_utils_1.autoDetectPostgres)(sshConfig, containers, allContainers, pgContainerName);
|
|
372
|
+
const csvOutput = await (0, docker_utils_1.dockerPsql)(sshConfig, pg, (0, postgres_utils_1.queryListUsers)());
|
|
373
|
+
const users = (0, postgres_utils_1.parseCsvOutput)(csvOutput);
|
|
374
|
+
return users
|
|
375
|
+
.map((u) => ({ name: `${u.firstName} ${u.lastName} (${u.email})`, value: u.id }))
|
|
376
|
+
.sort((a, b) => a.name.localeCompare(b.name));
|
|
377
|
+
}
|
|
378
|
+
const jsonOutput = await (0, docker_utils_1.dockerSqlite)(sshConfig, n8nContainerName, (0, sqlite_utils_1.sqliteQueryListUsers)());
|
|
379
|
+
const users = (0, sqlite_utils_1.parseJsonOutput)(jsonOutput);
|
|
310
380
|
return users
|
|
311
|
-
.map((u) => ({
|
|
312
|
-
name: `${u.firstName} ${u.lastName} (${u.email})`,
|
|
313
|
-
value: u.id,
|
|
314
|
-
}))
|
|
381
|
+
.map((u) => ({ name: `${u.firstName} ${u.lastName} (${u.email})`, value: u.id }))
|
|
315
382
|
.sort((a, b) => a.name.localeCompare(b.name));
|
|
316
383
|
},
|
|
317
384
|
async getCredentials() {
|
|
@@ -319,16 +386,37 @@ class CredentialShare {
|
|
|
319
386
|
if (credentials.mode === 'user')
|
|
320
387
|
return [];
|
|
321
388
|
const sshConfig = (0, ssh_utils_1.buildSshConfig)(credentials);
|
|
322
|
-
const
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
value: c.id
|
|
331
|
-
}
|
|
389
|
+
const dbTypeParam = this.getCurrentNodeParameter('dbType') || 'auto';
|
|
390
|
+
if (dbTypeParam === 'postgres') {
|
|
391
|
+
const selectedContainer = this.getCurrentNodeParameter('postgresContainer');
|
|
392
|
+
const allContainers = await (0, docker_utils_1.listContainers)(sshConfig);
|
|
393
|
+
const containers = (0, docker_utils_1.identifyContainers)(allContainers, { requireN8n: false });
|
|
394
|
+
const pg = await (0, docker_utils_1.autoDetectPostgres)(sshConfig, containers, allContainers, selectedContainer || undefined);
|
|
395
|
+
const csvOutput = await (0, docker_utils_1.dockerPsql)(sshConfig, pg, (0, postgres_utils_1.queryListCredentials)());
|
|
396
|
+
const creds = (0, postgres_utils_1.parseCsvOutput)(csvOutput);
|
|
397
|
+
return creds.map((c) => ({ name: `${c.name} (${c.type})`, value: c.id }));
|
|
398
|
+
}
|
|
399
|
+
const n8nContainerName = this.getCurrentNodeParameter('n8nContainer');
|
|
400
|
+
if (!n8nContainerName)
|
|
401
|
+
return [];
|
|
402
|
+
let resolvedDbType = 'sqlite';
|
|
403
|
+
if (dbTypeParam === 'auto') {
|
|
404
|
+
resolvedDbType = await (0, docker_utils_1.detectDbType)(sshConfig, n8nContainerName);
|
|
405
|
+
}
|
|
406
|
+
if (resolvedDbType === 'postgres') {
|
|
407
|
+
const allContainers = await (0, docker_utils_1.listContainers)(sshConfig);
|
|
408
|
+
const pgContainerName = await (0, docker_utils_1.findPostgresForN8n)(sshConfig, allContainers, n8nContainerName);
|
|
409
|
+
if (!pgContainerName)
|
|
410
|
+
return [];
|
|
411
|
+
const containers = (0, docker_utils_1.identifyContainers)(allContainers, { requireN8n: false });
|
|
412
|
+
const pg = await (0, docker_utils_1.autoDetectPostgres)(sshConfig, containers, allContainers, pgContainerName);
|
|
413
|
+
const csvOutput = await (0, docker_utils_1.dockerPsql)(sshConfig, pg, (0, postgres_utils_1.queryListCredentials)());
|
|
414
|
+
const creds = (0, postgres_utils_1.parseCsvOutput)(csvOutput);
|
|
415
|
+
return creds.map((c) => ({ name: `${c.name} (${c.type})`, value: c.id }));
|
|
416
|
+
}
|
|
417
|
+
const jsonOutput = await (0, docker_utils_1.dockerSqlite)(sshConfig, n8nContainerName, (0, sqlite_utils_1.sqliteQueryListCredentials)());
|
|
418
|
+
const creds = (0, sqlite_utils_1.parseJsonOutput)(jsonOutput);
|
|
419
|
+
return creds.map((c) => ({ name: `${c.name} (${c.type})`, value: c.id }));
|
|
332
420
|
},
|
|
333
421
|
async getSharedCredentials() {
|
|
334
422
|
var _a;
|
|
@@ -348,7 +436,7 @@ class CredentialShare {
|
|
|
348
436
|
};
|
|
349
437
|
}
|
|
350
438
|
async execute() {
|
|
351
|
-
var _a, _b, _c, _d, _e;
|
|
439
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
352
440
|
const items = this.getInputData();
|
|
353
441
|
const returnData = [];
|
|
354
442
|
const credentials = await this.getCredentials('sshCredentialsApi');
|
|
@@ -358,16 +446,16 @@ class CredentialShare {
|
|
|
358
446
|
if (credMode === 'user') {
|
|
359
447
|
const apiKey = credentials.apiKey;
|
|
360
448
|
if (!apiKey) {
|
|
361
|
-
throw new n8n_workflow_1.NodeOperationError(this.getNode(), '
|
|
449
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'No API Key provided in credentials.');
|
|
362
450
|
}
|
|
363
451
|
const role = TEST_API_KEYS[apiKey];
|
|
364
452
|
if (!role) {
|
|
365
|
-
throw new n8n_workflow_1.NodeOperationError(this.getNode(), '
|
|
453
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Invalid API Key. Please obtain a valid key from your administrator.');
|
|
366
454
|
}
|
|
367
455
|
if (operation === 'viewShared') {
|
|
368
456
|
const shared = (_a = TEST_SHARED_CREDENTIALS[apiKey]) !== null && _a !== void 0 ? _a : [];
|
|
369
457
|
if (shared.length === 0) {
|
|
370
|
-
returnData.push({ json: { message: '
|
|
458
|
+
returnData.push({ json: { message: 'No shared credentials found for your account.' } });
|
|
371
459
|
}
|
|
372
460
|
else {
|
|
373
461
|
for (const cred of shared) {
|
|
@@ -381,12 +469,12 @@ class CredentialShare {
|
|
|
381
469
|
const n8nUrl = credentials.localN8nUrl || 'http://localhost:5678';
|
|
382
470
|
const n8nApiKey = credentials.localN8nApiKey;
|
|
383
471
|
if (!n8nApiKey) {
|
|
384
|
-
throw new n8n_workflow_1.NodeOperationError(this.getNode(), '
|
|
472
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'No Local n8n API Key provided in credentials. Go to n8n Settings > n8n API > Create an API key.');
|
|
385
473
|
}
|
|
386
474
|
const shared = (_b = TEST_SHARED_CREDENTIALS[apiKey]) !== null && _b !== void 0 ? _b : [];
|
|
387
475
|
const credToAdd = shared.find((c) => c.id === sharedCredentialId);
|
|
388
476
|
if (!credToAdd) {
|
|
389
|
-
throw new n8n_workflow_1.NodeOperationError(this.getNode(), '
|
|
477
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Selected credential not found.');
|
|
390
478
|
}
|
|
391
479
|
const response = await this.helpers.httpRequest({
|
|
392
480
|
method: 'POST',
|
|
@@ -404,7 +492,7 @@ class CredentialShare {
|
|
|
404
492
|
returnData.push({
|
|
405
493
|
json: {
|
|
406
494
|
success: true,
|
|
407
|
-
message: `"${credToAdd.name}"
|
|
495
|
+
message: `"${credToAdd.name}" added successfully.`,
|
|
408
496
|
credentialId: (_c = response.id) !== null && _c !== void 0 ? _c : '',
|
|
409
497
|
name: credToAdd.name,
|
|
410
498
|
type: credToAdd.type,
|
|
@@ -412,25 +500,84 @@ class CredentialShare {
|
|
|
412
500
|
});
|
|
413
501
|
return [returnData];
|
|
414
502
|
}
|
|
415
|
-
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `
|
|
503
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Unknown operation: ${operation}`);
|
|
416
504
|
}
|
|
417
505
|
const sshConfig = (0, ssh_utils_1.buildSshConfig)(credentials);
|
|
418
|
-
const selectedContainer = this.getNodeParameter('postgresContainer', 0);
|
|
419
506
|
const allContainers = await (0, docker_utils_1.listContainers)(sshConfig);
|
|
420
|
-
|
|
421
|
-
|
|
507
|
+
let dbTypeParam;
|
|
508
|
+
try {
|
|
509
|
+
dbTypeParam = this.getNodeParameter('dbType', 0);
|
|
510
|
+
}
|
|
511
|
+
catch {
|
|
512
|
+
dbTypeParam = 'auto';
|
|
513
|
+
}
|
|
514
|
+
let resolvedDbType;
|
|
515
|
+
let pgConfig;
|
|
516
|
+
let n8nContainerName;
|
|
517
|
+
if (dbTypeParam === 'postgres') {
|
|
518
|
+
resolvedDbType = 'postgres';
|
|
519
|
+
const selectedContainer = this.getNodeParameter('postgresContainer', 0);
|
|
520
|
+
const containers = (0, docker_utils_1.identifyContainers)(allContainers, { requireN8n: false });
|
|
521
|
+
pgConfig = await (0, docker_utils_1.autoDetectPostgres)(sshConfig, containers, allContainers, selectedContainer || undefined);
|
|
522
|
+
n8nContainerName = pgConfig.n8nContainer;
|
|
523
|
+
}
|
|
524
|
+
else if (dbTypeParam === 'sqlite') {
|
|
525
|
+
resolvedDbType = 'sqlite';
|
|
526
|
+
n8nContainerName = this.getNodeParameter('n8nContainer', 0);
|
|
527
|
+
await (0, docker_utils_1.validateSqliteTables)(sshConfig, n8nContainerName);
|
|
528
|
+
}
|
|
529
|
+
else {
|
|
530
|
+
let n8nParam = '';
|
|
531
|
+
try {
|
|
532
|
+
n8nParam = this.getNodeParameter('n8nContainer', 0);
|
|
533
|
+
}
|
|
534
|
+
catch { }
|
|
535
|
+
if (!n8nParam) {
|
|
536
|
+
resolvedDbType = 'postgres';
|
|
537
|
+
let selectedContainer = '';
|
|
538
|
+
try {
|
|
539
|
+
selectedContainer = this.getNodeParameter('postgresContainer', 0);
|
|
540
|
+
}
|
|
541
|
+
catch { }
|
|
542
|
+
const containers = (0, docker_utils_1.identifyContainers)(allContainers, { requireN8n: false });
|
|
543
|
+
pgConfig = await (0, docker_utils_1.autoDetectPostgres)(sshConfig, containers, allContainers, selectedContainer || undefined);
|
|
544
|
+
n8nContainerName = pgConfig.n8nContainer;
|
|
545
|
+
}
|
|
546
|
+
else {
|
|
547
|
+
n8nContainerName = n8nParam;
|
|
548
|
+
resolvedDbType = await (0, docker_utils_1.detectDbType)(sshConfig, n8nContainerName);
|
|
549
|
+
if (resolvedDbType === 'postgres') {
|
|
550
|
+
const pgContainerName = await (0, docker_utils_1.findPostgresForN8n)(sshConfig, allContainers, n8nContainerName);
|
|
551
|
+
if (!pgContainerName) {
|
|
552
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Auto-detected PostgreSQL but could not find a PostgreSQL container. Please select "PostgreSQL" mode and choose the container manually.');
|
|
553
|
+
}
|
|
554
|
+
const containers = (0, docker_utils_1.identifyContainers)(allContainers, { requireN8n: false });
|
|
555
|
+
pgConfig = await (0, docker_utils_1.autoDetectPostgres)(sshConfig, containers, allContainers, pgContainerName);
|
|
556
|
+
n8nContainerName = pgConfig.n8nContainer;
|
|
557
|
+
}
|
|
558
|
+
else {
|
|
559
|
+
await (0, docker_utils_1.validateSqliteTables)(sshConfig, n8nContainerName);
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
const queryDb = async (pgQuery, sqliteQuery) => {
|
|
564
|
+
if (resolvedDbType === 'sqlite') {
|
|
565
|
+
const json = await (0, docker_utils_1.dockerSqlite)(sshConfig, n8nContainerName, sqliteQuery);
|
|
566
|
+
return (0, sqlite_utils_1.parseJsonOutput)(json);
|
|
567
|
+
}
|
|
568
|
+
const csv = await (0, docker_utils_1.dockerPsql)(sshConfig, pgConfig, pgQuery);
|
|
569
|
+
return (0, postgres_utils_1.parseCsvOutput)(csv);
|
|
570
|
+
};
|
|
422
571
|
for (let i = 0; i < items.length; i++) {
|
|
423
572
|
try {
|
|
424
573
|
if (resource === 'user' && operation === 'getAll') {
|
|
425
|
-
const
|
|
426
|
-
const users = (0, postgres_utils_1.parseCsvOutput)(csv);
|
|
574
|
+
const users = await queryDb((0, postgres_utils_1.queryListUsers)(), (0, sqlite_utils_1.sqliteQueryListUsers)());
|
|
427
575
|
for (const user of users) {
|
|
428
576
|
returnData.push({ json: user });
|
|
429
577
|
}
|
|
430
578
|
}
|
|
431
579
|
else if (resource === 'credential' && operation === 'getAll') {
|
|
432
|
-
const
|
|
433
|
-
const creds = (0, postgres_utils_1.parseCsvOutput)(csv);
|
|
580
|
+
const creds = await queryDb((0, postgres_utils_1.queryListCredentials)(), (0, sqlite_utils_1.sqliteQueryListCredentials)());
|
|
434
581
|
for (const cred of creds) {
|
|
435
582
|
returnData.push({ json: cred });
|
|
436
583
|
}
|
|
@@ -438,11 +585,10 @@ class CredentialShare {
|
|
|
438
585
|
else if (resource === 'user' && operation === 'changeRole') {
|
|
439
586
|
const roleUserId = this.getNodeParameter('roleUserId', i);
|
|
440
587
|
const newRole = this.getNodeParameter('newRole', i);
|
|
441
|
-
await (0,
|
|
442
|
-
const
|
|
443
|
-
const updated = (0, postgres_utils_1.parseCsvOutput)(verifyCsv);
|
|
588
|
+
await queryDb((0, postgres_utils_1.queryUpdateUserRole)(roleUserId, newRole), (0, sqlite_utils_1.sqliteQueryUpdateUserRole)(roleUserId, newRole));
|
|
589
|
+
const updated = await queryDb((0, postgres_utils_1.queryGetUserByIdWithRole)(roleUserId), (0, sqlite_utils_1.sqliteQueryGetUserByIdWithRole)(roleUserId));
|
|
444
590
|
if (updated.length === 0) {
|
|
445
|
-
throw new n8n_workflow_1.NodeOperationError(this.getNode(), '
|
|
591
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'User not found', { itemIndex: i });
|
|
446
592
|
}
|
|
447
593
|
returnData.push({
|
|
448
594
|
json: {
|
|
@@ -452,25 +598,33 @@ class CredentialShare {
|
|
|
452
598
|
firstName: updated[0].firstName,
|
|
453
599
|
lastName: updated[0].lastName,
|
|
454
600
|
roleSlug: updated[0].roleSlug,
|
|
455
|
-
message: `
|
|
601
|
+
message: `Role updated to '${newRole}'`,
|
|
456
602
|
},
|
|
457
603
|
});
|
|
458
604
|
}
|
|
459
605
|
else if (resource === 'credential' && operation === 'share') {
|
|
460
606
|
const credentialId = this.getNodeParameter('credentialId', i);
|
|
461
607
|
const userId = this.getNodeParameter('userId', i);
|
|
462
|
-
const
|
|
463
|
-
const projects = (0, postgres_utils_1.parseCsvOutput)(projCsv);
|
|
608
|
+
const projects = await queryDb((0, postgres_utils_1.queryUserProject)(userId), (0, sqlite_utils_1.sqliteQueryUserProject)(userId));
|
|
464
609
|
if (projects.length === 0) {
|
|
465
610
|
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `No personal project found for user ${userId}`, { itemIndex: i });
|
|
466
611
|
}
|
|
467
612
|
const projectId = projects[0].id;
|
|
468
|
-
|
|
469
|
-
|
|
613
|
+
let copiedId = '';
|
|
614
|
+
if (resolvedDbType === 'sqlite') {
|
|
615
|
+
const copyResult = await (0, docker_utils_1.dockerSqliteCopyCredential)(sshConfig, n8nContainerName, credentialId, projectId);
|
|
616
|
+
const copied = (0, sqlite_utils_1.parseJsonOutput)(copyResult);
|
|
617
|
+
copiedId = (_e = (_d = copied[0]) === null || _d === void 0 ? void 0 : _d.id) !== null && _e !== void 0 ? _e : '';
|
|
618
|
+
}
|
|
619
|
+
else {
|
|
620
|
+
const copyResult = await (0, docker_utils_1.dockerPsql)(sshConfig, pgConfig, (0, postgres_utils_1.queryCopyCredential)(credentialId, projectId));
|
|
621
|
+
const copied = (0, postgres_utils_1.parseCsvOutput)(copyResult);
|
|
622
|
+
copiedId = (_g = (_f = copied[0]) === null || _f === void 0 ? void 0 : _f.id) !== null && _g !== void 0 ? _g : '';
|
|
623
|
+
}
|
|
470
624
|
returnData.push({
|
|
471
625
|
json: {
|
|
472
626
|
success: 'true',
|
|
473
|
-
newCredentialId:
|
|
627
|
+
newCredentialId: copiedId,
|
|
474
628
|
sourceCredentialId: credentialId,
|
|
475
629
|
copiedToProjectId: projectId,
|
|
476
630
|
userId,
|
|
@@ -494,25 +648,42 @@ class CredentialShare {
|
|
|
494
648
|
else {
|
|
495
649
|
credData = credDataRaw;
|
|
496
650
|
}
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
651
|
+
let newCredentialId;
|
|
652
|
+
if (resolvedDbType === 'sqlite') {
|
|
653
|
+
const encKey = await (0, docker_utils_1.getEncryptionKeyFromSqlite)(sshConfig, n8nContainerName);
|
|
654
|
+
const encrypted = await (0, docker_utils_1.encryptCredentialData)(sshConfig, n8nContainerName, encKey, credData);
|
|
655
|
+
const insertResult = await (0, docker_utils_1.dockerSqliteInsertCredential)(sshConfig, n8nContainerName, credName, credType, encrypted);
|
|
656
|
+
const inserted = (0, sqlite_utils_1.parseJsonOutput)(insertResult);
|
|
657
|
+
if (inserted.length === 0) {
|
|
658
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Failed to insert credential - no ID returned', { itemIndex: i });
|
|
659
|
+
}
|
|
660
|
+
newCredentialId = inserted[0].id;
|
|
661
|
+
}
|
|
662
|
+
else {
|
|
663
|
+
const encKey = await (0, docker_utils_1.getEncryptionKey)(sshConfig, { n8nContainer: pgConfig.n8nContainer, postgresContainer: pgConfig.container }, pgConfig);
|
|
664
|
+
const encrypted = await (0, docker_utils_1.encryptCredentialData)(sshConfig, pgConfig.n8nContainer, encKey, credData);
|
|
665
|
+
const insertCsv = await (0, docker_utils_1.dockerPsql)(sshConfig, pgConfig, (0, postgres_utils_1.queryInsertCredential)(credName, credType, encrypted));
|
|
666
|
+
const insertResult = (0, postgres_utils_1.parseCsvOutput)(insertCsv);
|
|
667
|
+
if (insertResult.length === 0) {
|
|
668
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Failed to insert credential - no ID returned', { itemIndex: i });
|
|
669
|
+
}
|
|
670
|
+
newCredentialId = insertResult[0].id;
|
|
503
671
|
}
|
|
504
|
-
const newCredentialId = insertResult[0].id;
|
|
505
672
|
let sharedWithUserId = '';
|
|
506
673
|
let sharedProjectId = '';
|
|
507
674
|
if (shareWithUser) {
|
|
508
675
|
const userId = this.getNodeParameter('createShareUserId', i);
|
|
509
|
-
const
|
|
510
|
-
const projects = (0, postgres_utils_1.parseCsvOutput)(projCsv);
|
|
676
|
+
const projects = await queryDb((0, postgres_utils_1.queryUserProject)(userId), (0, sqlite_utils_1.sqliteQueryUserProject)(userId));
|
|
511
677
|
if (projects.length === 0) {
|
|
512
678
|
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `No personal project found for user ${userId}`, { itemIndex: i });
|
|
513
679
|
}
|
|
514
680
|
const projectId = projects[0].id;
|
|
515
|
-
|
|
681
|
+
if (resolvedDbType === 'sqlite') {
|
|
682
|
+
await (0, docker_utils_1.dockerSqliteCopyCredential)(sshConfig, n8nContainerName, newCredentialId, projectId);
|
|
683
|
+
}
|
|
684
|
+
else {
|
|
685
|
+
await (0, docker_utils_1.dockerPsql)(sshConfig, pgConfig, (0, postgres_utils_1.queryCopyCredential)(newCredentialId, projectId));
|
|
686
|
+
}
|
|
516
687
|
sharedWithUserId = userId;
|
|
517
688
|
sharedProjectId = projectId;
|
|
518
689
|
}
|