n8n-nodes-smbclient 1.0.0 → 1.0.2
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/.github/workflows/npm-publish.yml +6 -6
- package/.github/workflows/one-shot-npm-publish.yml +6 -6
- package/credentials/Smb2Api.credentials.ts +1 -5
- package/dist/credentials/Smb2Api.credentials.js.map +1 -1
- package/dist/nodes/Smb2/Smb2.node.js +30 -17
- package/dist/nodes/Smb2/Smb2.node.js.map +1 -1
- package/dist/nodes/Smb2/SmbClientWrapper.d.ts +3 -2
- package/dist/nodes/Smb2/SmbClientWrapper.js +42 -23
- package/dist/nodes/Smb2/SmbClientWrapper.js.map +1 -1
- package/dist/nodes/Smb2/SmbEntryHelpers.d.ts +3 -3
- package/dist/nodes/Smb2/SmbEntryHelpers.js +4 -6
- package/dist/nodes/Smb2/SmbEntryHelpers.js.map +1 -1
- package/dist/nodes/Smb2/interfaces.d.ts +2 -2
- package/dist/package.json +9 -7
- package/eslint.config.mjs +45 -33
- package/nodes/Smb2/Smb2.node.json +1 -1
- package/nodes/Smb2/Smb2.node.ts +49 -32
- package/nodes/Smb2/SmbClientWrapper.ts +80 -51
- package/nodes/Smb2/SmbEntryHelpers.ts +33 -32
- package/nodes/Smb2/interfaces.ts +10 -9
- package/package.json +9 -7
- package/renovate.json +6 -0
|
@@ -11,20 +11,20 @@ jobs:
|
|
|
11
11
|
build:
|
|
12
12
|
runs-on: ubuntu-latest
|
|
13
13
|
steps:
|
|
14
|
-
- uses: actions/checkout@
|
|
15
|
-
- uses: actions/setup-node@
|
|
14
|
+
- uses: actions/checkout@v6
|
|
15
|
+
- uses: actions/setup-node@v6
|
|
16
16
|
with:
|
|
17
|
-
node-version:
|
|
17
|
+
node-version: 24
|
|
18
18
|
- run: npm ci
|
|
19
19
|
|
|
20
20
|
publish-npm:
|
|
21
21
|
needs: build
|
|
22
22
|
runs-on: ubuntu-latest
|
|
23
23
|
steps:
|
|
24
|
-
- uses: actions/checkout@
|
|
25
|
-
- uses: actions/setup-node@
|
|
24
|
+
- uses: actions/checkout@v6
|
|
25
|
+
- uses: actions/setup-node@v6
|
|
26
26
|
with:
|
|
27
|
-
node-version:
|
|
27
|
+
node-version: 24
|
|
28
28
|
registry-url: https://registry.npmjs.org/
|
|
29
29
|
- run: npm ci
|
|
30
30
|
- run: npm publish
|
|
@@ -9,20 +9,20 @@ jobs:
|
|
|
9
9
|
build:
|
|
10
10
|
runs-on: ubuntu-latest
|
|
11
11
|
steps:
|
|
12
|
-
- uses: actions/checkout@
|
|
13
|
-
- uses: actions/setup-node@
|
|
12
|
+
- uses: actions/checkout@v6
|
|
13
|
+
- uses: actions/setup-node@v6
|
|
14
14
|
with:
|
|
15
|
-
node-version:
|
|
15
|
+
node-version: 24
|
|
16
16
|
- run: npm ci
|
|
17
17
|
|
|
18
18
|
publish-npm:
|
|
19
19
|
needs: build
|
|
20
20
|
runs-on: ubuntu-latest
|
|
21
21
|
steps:
|
|
22
|
-
- uses: actions/checkout@
|
|
23
|
-
- uses: actions/setup-node@
|
|
22
|
+
- uses: actions/checkout@v6
|
|
23
|
+
- uses: actions/setup-node@v6
|
|
24
24
|
with:
|
|
25
|
-
node-version:
|
|
25
|
+
node-version: 24
|
|
26
26
|
registry-url: https://registry.npmjs.org/
|
|
27
27
|
- run: npm ci
|
|
28
28
|
- run: npm publish
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Smb2Api.credentials.js","sourceRoot":"","sources":["../../credentials/Smb2Api.credentials.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"Smb2Api.credentials.js","sourceRoot":"","sources":["../../credentials/Smb2Api.credentials.ts"],"names":[],"mappings":";;;AAEA,MAAa,OAAO;IAApB;QACC,SAAI,GAAG,SAAS,CAAC;QACjB,gBAAW,GAAG,sBAAsB,CAAC;QAErC,SAAI,GAAS,eAAe,CAAC;QAC7B,eAAU,GAAsB;YAC/B;gBACC,WAAW,EAAE,QAAQ;gBACrB,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,QAAQ;gBACd,QAAQ,EAAE,IAAI;gBACd,OAAO,EAAE,EAAE;aACX;YACD;gBACC,WAAW,EAAE,WAAW;gBACxB,IAAI,EAAE,UAAU;gBAChB,IAAI,EAAE,QAAQ;gBACd,QAAQ,EAAE,IAAI;gBACd,OAAO,EAAE,EAAE;aACX;YACD;gBACC,WAAW,EAAE,UAAU;gBACvB,IAAI,EAAE,UAAU;gBAChB,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE;oBACZ,QAAQ,EAAE,IAAI;iBACd;gBACD,gBAAgB,EAAE,IAAI;gBACtB,QAAQ,EAAE,IAAI;gBACd,OAAO,EAAE,EAAE;aACX;YACD;gBACC,WAAW,EAAE,QAAQ;gBACrB,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,EAAE;aACX;YACD;gBACC,WAAW,EAAE,MAAM;gBACnB,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,GAAG;aACZ;YACD;gBACC,WAAW,EAAE,YAAY;gBACzB,IAAI,EAAE,OAAO;gBACb,IAAI,EAAE,QAAQ;gBACd,QAAQ,EAAE,IAAI;gBACd,OAAO,EAAE,EAAE;aACX;YACD;gBACC,WAAW,EAAE,iBAAiB;gBAC9B,IAAI,EAAE,gBAAgB;gBACtB,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,0BAA0B;gBACvC,OAAO,EAAE,KAAK;aACd;YACD;gBACC,WAAW,EAAE,iBAAiB;gBAC9B,IAAI,EAAE,gBAAgB;gBACtB,WAAW,EAAE,uBAAuB;gBACpC,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,KAAK;aACd;SACD,CAAC;IACH,CAAC;CAAA;AAjED,0BAiEC"}
|
|
@@ -38,33 +38,47 @@ class Smb2 {
|
|
|
38
38
|
noDataExpression: true,
|
|
39
39
|
options: [
|
|
40
40
|
{
|
|
41
|
-
name: 'Delete File',
|
|
42
|
-
|
|
41
|
+
name: 'Delete File',
|
|
42
|
+
value: 'del',
|
|
43
|
+
description: 'Delete a file',
|
|
44
|
+
action: 'Delete a file',
|
|
43
45
|
},
|
|
44
46
|
{
|
|
45
|
-
name: 'Get File',
|
|
46
|
-
|
|
47
|
+
name: 'Get File',
|
|
48
|
+
value: 'get',
|
|
49
|
+
description: 'Download a file from SMB',
|
|
50
|
+
action: 'Get a file',
|
|
47
51
|
},
|
|
48
52
|
{
|
|
49
|
-
name: 'List Directory',
|
|
50
|
-
|
|
53
|
+
name: 'List Directory',
|
|
54
|
+
value: 'list',
|
|
55
|
+
description: 'List a directory',
|
|
56
|
+
action: 'List a directory',
|
|
51
57
|
},
|
|
52
58
|
{
|
|
53
|
-
name: 'Make Directory',
|
|
54
|
-
|
|
59
|
+
name: 'Make Directory',
|
|
60
|
+
value: 'mkdir',
|
|
61
|
+
description: 'Create a directory',
|
|
62
|
+
action: 'Create a directory',
|
|
55
63
|
},
|
|
56
64
|
{
|
|
57
|
-
name: 'Remove Directory',
|
|
58
|
-
|
|
65
|
+
name: 'Remove Directory',
|
|
66
|
+
value: 'rmdir',
|
|
67
|
+
description: 'Remove a directory',
|
|
68
|
+
action: 'Remove a directory',
|
|
59
69
|
},
|
|
60
70
|
{
|
|
61
|
-
name: 'Stat',
|
|
62
|
-
|
|
71
|
+
name: 'Stat',
|
|
72
|
+
value: 'stat',
|
|
73
|
+
description: 'Get file/folder metadata',
|
|
74
|
+
action: 'Get file folder metadata',
|
|
63
75
|
},
|
|
64
76
|
{
|
|
65
|
-
name: 'Upload File',
|
|
66
|
-
|
|
67
|
-
|
|
77
|
+
name: 'Upload File',
|
|
78
|
+
value: 'put',
|
|
79
|
+
description: 'Upload a file',
|
|
80
|
+
action: 'Upload a file',
|
|
81
|
+
},
|
|
68
82
|
],
|
|
69
83
|
default: 'list',
|
|
70
84
|
},
|
|
@@ -164,8 +178,7 @@ class Smb2 {
|
|
|
164
178
|
throw new n8n_workflow_1.NodeOperationError(this.getNode(), (err === null || err === void 0 ? void 0 : err.message) || 'SMB operation failed');
|
|
165
179
|
}
|
|
166
180
|
finally {
|
|
167
|
-
await client.close().catch(() => {
|
|
168
|
-
});
|
|
181
|
+
await client.close().catch(() => { });
|
|
169
182
|
}
|
|
170
183
|
return this.prepareOutputData(out);
|
|
171
184
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Smb2.node.js","sourceRoot":"","sources":["../../../nodes/Smb2/Smb2.node.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"Smb2.node.js","sourceRoot":"","sources":["../../../nodes/Smb2/Smb2.node.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { IExecuteFunctions, INode, ITriggerFunctions } from
|
|
2
|
-
import { Smb2Credentials, SmbListEntry, SmbStat } from
|
|
1
|
+
import { IExecuteFunctions, INode, ITriggerFunctions } from 'n8n-workflow';
|
|
2
|
+
import { Smb2Credentials, SmbListEntry, SmbStat } from './interfaces';
|
|
3
3
|
export declare function getReadableError(error: any): string;
|
|
4
4
|
export declare class SmbClientWrapper {
|
|
5
5
|
private auth;
|
|
@@ -16,6 +16,7 @@ export declare class SmbClientWrapper {
|
|
|
16
16
|
rmdir(remoteDir: string): Promise<void>;
|
|
17
17
|
del(remotePath: string): Promise<void>;
|
|
18
18
|
close(): Promise<void>;
|
|
19
|
+
private escapeSmbArg;
|
|
19
20
|
}
|
|
20
21
|
export declare function connectToSmbServer(this: IExecuteFunctions | ITriggerFunctions): Promise<{
|
|
21
22
|
client: SmbClientWrapper;
|
|
@@ -7,15 +7,15 @@ const n8n_workflow_1 = require("n8n-workflow");
|
|
|
7
7
|
const node_util_1 = require("node:util");
|
|
8
8
|
const node_child_process_1 = require("node:child_process");
|
|
9
9
|
const util_1 = require("util");
|
|
10
|
-
const debug = (0, util_1.debuglog)(
|
|
10
|
+
const debug = (0, util_1.debuglog)('n8n-nodes-smbclient');
|
|
11
11
|
const SMB_ERROR_HINTS = [
|
|
12
|
-
[/EACCES/i,
|
|
13
|
-
[/ENOENT/i,
|
|
14
|
-
[/ENOTDIR/i,
|
|
15
|
-
[/ETIMEOUT/i,
|
|
16
|
-
[/ECONNREFUSED/i,
|
|
17
|
-
[/LOGON failure/i,
|
|
18
|
-
[/bad network name/i,
|
|
12
|
+
[/EACCES/i, 'Access Denied - Check your permissions for this file/folder'],
|
|
13
|
+
[/ENOENT/i, 'File/Path Not Found'],
|
|
14
|
+
[/ENOTDIR/i, 'Not a directory'],
|
|
15
|
+
[/ETIMEOUT/i, 'Connection timed out'],
|
|
16
|
+
[/ECONNREFUSED/i, 'Could not connect to SMB server - Connection refused'],
|
|
17
|
+
[/LOGON failure/i, 'Logon Failure - Check your username, password, and domain'],
|
|
18
|
+
[/bad network name/i, 'Bad Network Name - The specified share does not exist on the server'],
|
|
19
19
|
];
|
|
20
20
|
function getReadableError(error) {
|
|
21
21
|
var _a;
|
|
@@ -31,11 +31,20 @@ const execFileAsync = (0, node_util_1.promisify)(node_child_process_1.execFile);
|
|
|
31
31
|
const redactCmd = (s) => {
|
|
32
32
|
if (!s)
|
|
33
33
|
return s;
|
|
34
|
-
s = s.replace(/-U\s
|
|
35
|
-
s = s.replace(/-A\s
|
|
34
|
+
s = s.replace(/-U\s+\S+/g, '-U ***');
|
|
35
|
+
s = s.replace(/-A\s+\S+/g, '-A ***');
|
|
36
36
|
s = s.replace(/\/\/[^/\s]+\/\S+/g, '//***');
|
|
37
37
|
return s;
|
|
38
38
|
};
|
|
39
|
+
const maskSecrets = (value, secrets) => {
|
|
40
|
+
let result = value;
|
|
41
|
+
for (const secret of secrets) {
|
|
42
|
+
if (secret) {
|
|
43
|
+
result = result.split(secret).join('***');
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return result;
|
|
47
|
+
};
|
|
39
48
|
class SmbClientWrapper {
|
|
40
49
|
constructor(auth, smbclientPath = 'smbclient', node) {
|
|
41
50
|
this.auth = auth;
|
|
@@ -59,25 +68,25 @@ class SmbClientWrapper {
|
|
|
59
68
|
async runOne(cmd) {
|
|
60
69
|
var _a, _b;
|
|
61
70
|
const args = [...this.buildBaseArgs(), '-c', cmd];
|
|
71
|
+
const { username, password, domain } = this.auth;
|
|
72
|
+
const rawCmd = [this.smbclientPath, ...args].join(' ');
|
|
73
|
+
const safeCmd = maskSecrets(redactCmd(rawCmd), [username, password, domain]);
|
|
62
74
|
try {
|
|
63
75
|
const { stdout, stderr } = await execFileAsync(this.smbclientPath, args, {
|
|
64
76
|
maxBuffer: 10 * 1024 * 1024,
|
|
65
77
|
});
|
|
66
78
|
if (stderr && /NT_STATUS|Error|failed/i.test(stderr)) {
|
|
67
|
-
const
|
|
68
|
-
const safeCmd = redactCmd([this.smbclientPath, ...args].join(' ')).replace(username, '***').replace(password, '***');
|
|
79
|
+
const safeErr = maskSecrets(stderr.trim(), [username, password, domain]);
|
|
69
80
|
throw new n8n_workflow_1.NodeOperationError(this.node, {
|
|
70
|
-
message: `smbclient failed. cmd="${safeCmd}" stderr="${
|
|
81
|
+
message: `smbclient failed. cmd="${safeCmd}" stderr="${safeErr}"`,
|
|
71
82
|
});
|
|
72
83
|
}
|
|
73
84
|
return stdout !== null && stdout !== void 0 ? stdout : '';
|
|
74
85
|
}
|
|
75
86
|
catch (err) {
|
|
76
|
-
const
|
|
77
|
-
const safeCmd = redactCmd((err === null || err === void 0 ? void 0 : err.cmd) || [this.smbclientPath, ...args].join(' ')).replace(username, '***').replace(password, '***');
|
|
78
|
-
const msg = (((_b = (_a = err === null || err === void 0 ? void 0 : err.stderr) === null || _a === void 0 ? void 0 : _a.trim) === null || _b === void 0 ? void 0 : _b.call(_a)) || (err === null || err === void 0 ? void 0 : err.message) || 'smbclient command failed').replace(username, '***').replace(password, '***');
|
|
87
|
+
const safeErr = maskSecrets(((_b = (_a = err === null || err === void 0 ? void 0 : err.stderr) === null || _a === void 0 ? void 0 : _a.trim) === null || _b === void 0 ? void 0 : _b.call(_a)) || (err === null || err === void 0 ? void 0 : err.message) || 'smbclient command failed', [username, password, domain]);
|
|
79
88
|
throw new n8n_workflow_1.NodeOperationError(this.node, {
|
|
80
|
-
message: `smbclient failed. cmd="${safeCmd}" stderr="${
|
|
89
|
+
message: `smbclient failed. cmd="${safeCmd}" stderr="${safeErr}"`,
|
|
81
90
|
});
|
|
82
91
|
}
|
|
83
92
|
}
|
|
@@ -102,7 +111,12 @@ class SmbClientWrapper {
|
|
|
102
111
|
};
|
|
103
112
|
}
|
|
104
113
|
async list(dir) {
|
|
105
|
-
const
|
|
114
|
+
const normalizedDir = (dir !== null && dir !== void 0 ? dir : '').trim();
|
|
115
|
+
const safeDir = this.escapeSmbArg(normalizedDir);
|
|
116
|
+
const command = normalizedDir && normalizedDir !== '/' && normalizedDir !== '.'
|
|
117
|
+
? `cd "${safeDir}"; ls`
|
|
118
|
+
: 'ls';
|
|
119
|
+
const out = await this.runOne(command);
|
|
106
120
|
const lines = out
|
|
107
121
|
.split('\n')
|
|
108
122
|
.map((l) => l.trim())
|
|
@@ -210,22 +224,27 @@ class SmbClientWrapper {
|
|
|
210
224
|
}
|
|
211
225
|
async close() {
|
|
212
226
|
}
|
|
227
|
+
escapeSmbArg(value) {
|
|
228
|
+
return String(value).replace(/"/g, '\\"');
|
|
229
|
+
}
|
|
213
230
|
}
|
|
214
231
|
exports.SmbClientWrapper = SmbClientWrapper;
|
|
215
232
|
async function connectToSmbServer() {
|
|
216
233
|
var _a;
|
|
217
234
|
try {
|
|
218
|
-
const credentials = (await this.getCredentials(
|
|
219
|
-
debug(
|
|
235
|
+
const credentials = (await this.getCredentials('smb2Api'));
|
|
236
|
+
debug('Connecting to //%s/%s as (%s\\%s)', credentials.host, credentials.share, (_a = credentials.domain) !== null && _a !== void 0 ? _a : '', credentials.username);
|
|
220
237
|
const smbclientPath = this.getNodeParameter('smbclientPath', 0, 'smbclient');
|
|
221
238
|
const client = new SmbClientWrapper(credentials, smbclientPath, this.getNode());
|
|
222
|
-
await client.list(
|
|
239
|
+
await client.list('');
|
|
223
240
|
return { client };
|
|
224
241
|
}
|
|
225
242
|
catch (error) {
|
|
226
|
-
debug(
|
|
243
|
+
debug('Connect error: %O', error);
|
|
227
244
|
const readableError = getReadableError(error);
|
|
228
|
-
throw new n8n_workflow_1.NodeApiError(this.getNode(), error, {
|
|
245
|
+
throw new n8n_workflow_1.NodeApiError(this.getNode(), error, {
|
|
246
|
+
message: `Failed to connect to SMB server: ${readableError}`,
|
|
247
|
+
});
|
|
229
248
|
}
|
|
230
249
|
}
|
|
231
250
|
//# sourceMappingURL=SmbClientWrapper.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SmbClientWrapper.js","sourceRoot":"","sources":["../../../nodes/Smb2/SmbClientWrapper.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"SmbClientWrapper.js","sourceRoot":"","sources":["../../../nodes/Smb2/SmbClientWrapper.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { IExecuteFunctions } from
|
|
2
|
-
import { SmbClientWrapper } from
|
|
3
|
-
import { Operation, OpHandler } from
|
|
1
|
+
import { IExecuteFunctions } from 'n8n-workflow';
|
|
2
|
+
import { SmbClientWrapper } from './SmbClientWrapper';
|
|
3
|
+
import { Operation, OpHandler } from './interfaces';
|
|
4
4
|
declare const buildClient: (ctx: IExecuteFunctions) => Promise<SmbClientWrapper>;
|
|
5
5
|
declare const handlers: Record<Operation, OpHandler>;
|
|
6
6
|
export { handlers, buildClient };
|
|
@@ -11,7 +11,7 @@ const node_os_1 = __importDefault(require("node:os"));
|
|
|
11
11
|
const node_crypto_1 = __importDefault(require("node:crypto"));
|
|
12
12
|
const SmbClientWrapper_1 = require("./SmbClientWrapper");
|
|
13
13
|
const promises_1 = __importDefault(require("node:fs/promises"));
|
|
14
|
-
const debug = (0, util_1.debuglog)(
|
|
14
|
+
const debug = (0, util_1.debuglog)('n8n-nodes-smbclient');
|
|
15
15
|
const str = (ctx, i, name, def = '') => ctx.getNodeParameter(name, i, def);
|
|
16
16
|
const tmpFile = (prefix) => node_path_1.default.join(node_os_1.default.tmpdir(), `n8n-smb-${prefix}-${Date.now()}-${node_crypto_1.default.randomUUID()}`);
|
|
17
17
|
const toBinary = async (ctx, buf, fileName, mime, outProp, extraJson = {}) => {
|
|
@@ -21,7 +21,7 @@ const toBinary = async (ctx, buf, fileName, mime, outProp, extraJson = {}) => {
|
|
|
21
21
|
const buildClient = async (ctx) => {
|
|
22
22
|
const smbclientPath = str(ctx, 0, 'smbclientPath', 'smbclient');
|
|
23
23
|
const { host, username, password, domain, share } = (await ctx.getCredentials('smb2Api'));
|
|
24
|
-
debug(
|
|
24
|
+
debug('Connecting to //%s/%s as (%s\\%s)', host, share, domain !== null && domain !== void 0 ? domain : '', username);
|
|
25
25
|
return new SmbClientWrapper_1.SmbClientWrapper({ host, username, password, domain, share }, smbclientPath, ctx.getNode());
|
|
26
26
|
};
|
|
27
27
|
exports.buildClient = buildClient;
|
|
@@ -48,8 +48,7 @@ const handleGet = async (ctx, i, client) => {
|
|
|
48
48
|
const tmp = tmpFile('get');
|
|
49
49
|
await client.get(remotePath, tmp);
|
|
50
50
|
const buf = await promises_1.default.readFile(tmp);
|
|
51
|
-
await promises_1.default.unlink(tmp).catch(() => {
|
|
52
|
-
});
|
|
51
|
+
await promises_1.default.unlink(tmp).catch(() => { });
|
|
53
52
|
return toBinary(ctx, buf, outFile, outMime, outProp, { remotePath });
|
|
54
53
|
};
|
|
55
54
|
const handlePut = async (ctx, i, client) => {
|
|
@@ -70,8 +69,7 @@ const handlePut = async (ctx, i, client) => {
|
|
|
70
69
|
await promises_1.default.writeFile(tmp, text, 'utf8');
|
|
71
70
|
}
|
|
72
71
|
await client.put(tmp, remotePath);
|
|
73
|
-
await promises_1.default.unlink(tmp).catch(() => {
|
|
74
|
-
});
|
|
72
|
+
await promises_1.default.unlink(tmp).catch(() => { });
|
|
75
73
|
return { json: { remotePath, uploaded: true } };
|
|
76
74
|
};
|
|
77
75
|
const handleMkdir = async (ctx, i, client) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SmbEntryHelpers.js","sourceRoot":"","sources":["../../../nodes/Smb2/SmbEntryHelpers.ts"],"names":[],"mappings":";;;;;;AAAA,+
|
|
1
|
+
{"version":3,"file":"SmbEntryHelpers.js","sourceRoot":"","sources":["../../../nodes/Smb2/SmbEntryHelpers.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { IExecuteFunctions, INodeExecutionData } from
|
|
2
|
-
import { SmbClientWrapper } from
|
|
1
|
+
import { IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
|
|
2
|
+
import { SmbClientWrapper } from './SmbClientWrapper';
|
|
3
3
|
interface Smb2Credentials {
|
|
4
4
|
host: string;
|
|
5
5
|
share: string;
|
package/dist/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "n8n-nodes-smbclient",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "Transfer files via Samba (SMB2) and smbclient package with n8n, some of the base work are based on https://github.com/drudge/n8n-nodes-smb work.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"n8n-community-node-package",
|
|
@@ -38,30 +38,32 @@
|
|
|
38
38
|
]
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
|
+
"@eslint/compat": "^2.0.3",
|
|
41
42
|
"@eslint/eslintrc": "^3.3.1",
|
|
42
|
-
"@eslint/js": "^
|
|
43
|
+
"@eslint/js": "^10.0.0",
|
|
43
44
|
"@types/node": "^24.9.2",
|
|
44
45
|
"@typescript-eslint/parser": "^8.46.2",
|
|
45
|
-
"eslint": "^
|
|
46
|
+
"eslint": "^10.0.0",
|
|
46
47
|
"eslint-plugin-n8n-nodes-base": "^1.16.4",
|
|
47
|
-
"globals": "^
|
|
48
|
+
"globals": "^17.0.0",
|
|
48
49
|
"gulp": "^5.0.1",
|
|
49
50
|
"prettier": "^3.6.2",
|
|
50
51
|
"typescript": "^5.9.3"
|
|
51
52
|
},
|
|
52
53
|
"peerDependencies": {
|
|
53
|
-
"n8n-workflow": "^1.115.0"
|
|
54
|
+
"n8n-workflow": "^1.115.0 || ^2.0.0"
|
|
54
55
|
},
|
|
55
56
|
"dependencies": {
|
|
56
57
|
"tmp-promise": "^3.0.3"
|
|
57
58
|
},
|
|
58
59
|
"overrides": {
|
|
59
60
|
"form-data": "^4.0.4",
|
|
60
|
-
"axios": "1.
|
|
61
|
+
"axios": "1.13.6"
|
|
61
62
|
},
|
|
62
63
|
"pnpm": {
|
|
63
64
|
"onlyBuiltDependencies": [
|
|
64
|
-
"eslint-plugin-n8n-nodes-base"
|
|
65
|
+
"eslint-plugin-n8n-nodes-base",
|
|
66
|
+
"isolated-vm"
|
|
65
67
|
]
|
|
66
68
|
}
|
|
67
69
|
}
|
package/eslint.config.mjs
CHANGED
|
@@ -6,81 +6,93 @@ import path from "node:path";
|
|
|
6
6
|
import {fileURLToPath} from "node:url";
|
|
7
7
|
import js from "@eslint/js";
|
|
8
8
|
import {FlatCompat} from "@eslint/eslintrc";
|
|
9
|
+
import {fixupPluginRules, fixupConfigRules} from "@eslint/compat";
|
|
9
10
|
|
|
10
11
|
const __filename = fileURLToPath(import.meta.url);
|
|
11
12
|
const __dirname = path.dirname(__filename);
|
|
13
|
+
|
|
12
14
|
const compat = new FlatCompat({
|
|
13
15
|
baseDirectory: __dirname,
|
|
14
16
|
recommendedConfig: js.configs.recommended,
|
|
15
|
-
allConfig: js.configs.all
|
|
17
|
+
allConfig: js.configs.all,
|
|
16
18
|
});
|
|
17
19
|
|
|
20
|
+
const n8nNodesBaseCompat = fixupPluginRules(n8nNodesBase);
|
|
21
|
+
|
|
18
22
|
export default defineConfig([
|
|
19
|
-
globalIgnores([
|
|
23
|
+
globalIgnores([
|
|
24
|
+
"**/.eslintrc.js",
|
|
25
|
+
"**/*.js",
|
|
26
|
+
"**/node_modules/**/*",
|
|
27
|
+
"**/dist/**/*",
|
|
28
|
+
]),
|
|
29
|
+
|
|
20
30
|
{
|
|
21
31
|
languageOptions: {
|
|
22
32
|
globals: {
|
|
23
33
|
...globals.browser,
|
|
24
34
|
...globals.node,
|
|
25
35
|
},
|
|
26
|
-
|
|
27
36
|
parser: tsParser,
|
|
28
|
-
ecmaVersion:
|
|
37
|
+
ecmaVersion: "latest",
|
|
29
38
|
sourceType: "module",
|
|
30
|
-
|
|
31
39
|
parserOptions: {
|
|
32
40
|
project: ["./tsconfig.json"],
|
|
33
41
|
extraFileExtensions: [".json"],
|
|
34
42
|
},
|
|
35
43
|
},
|
|
36
44
|
},
|
|
45
|
+
|
|
37
46
|
{
|
|
38
47
|
files: ["**/package.json"],
|
|
39
|
-
extends: compat.extends("plugin:n8n-nodes-base/community"),
|
|
40
|
-
|
|
41
48
|
plugins: {
|
|
42
|
-
"n8n-nodes-base":
|
|
49
|
+
"n8n-nodes-base": n8nNodesBaseCompat,
|
|
43
50
|
},
|
|
44
|
-
|
|
51
|
+
extends: fixupConfigRules(
|
|
52
|
+
compat.extends("plugin:n8n-nodes-base/community"),
|
|
53
|
+
),
|
|
45
54
|
rules: {
|
|
46
55
|
"n8n-nodes-base/community-package-json-name-still-default": "off",
|
|
47
56
|
"n8n-nodes-base/community-package-json-license-missing": "off",
|
|
48
|
-
"n8n-nodes-base/community-package-json-author-missing": "off"
|
|
57
|
+
"n8n-nodes-base/community-package-json-author-missing": "off",
|
|
49
58
|
},
|
|
50
59
|
},
|
|
51
|
-
{
|
|
52
|
-
files: ["./credentials/**/*.ts"],
|
|
53
|
-
extends: compat.extends("plugin:n8n-nodes-base/credentials"),
|
|
54
60
|
|
|
61
|
+
{
|
|
62
|
+
files: ["**/credentials/**/*.ts"],
|
|
55
63
|
plugins: {
|
|
56
|
-
"n8n-nodes-base":
|
|
64
|
+
"n8n-nodes-base": n8nNodesBaseCompat,
|
|
57
65
|
},
|
|
58
|
-
|
|
66
|
+
extends: fixupConfigRules(
|
|
67
|
+
compat.extends("plugin:n8n-nodes-base/credentials"),
|
|
68
|
+
),
|
|
59
69
|
rules: {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
70
|
+
"n8n-nodes-base/cred-class-field-authenticate-type-assertion": "error",
|
|
71
|
+
"n8n-nodes-base/cred-class-field-display-name-missing-oauth2": "error",
|
|
72
|
+
"n8n-nodes-base/cred-class-field-display-name-miscased": "error",
|
|
73
|
+
"n8n-nodes-base/cred-class-field-documentation-url-missing": "off",
|
|
74
|
+
"n8n-nodes-base/cred-class-field-documentation-url-miscased": "off",
|
|
75
|
+
"n8n-nodes-base/cred-class-field-name-missing-oauth2": "error",
|
|
76
|
+
"n8n-nodes-base/cred-class-field-name-unsuffixed": "error",
|
|
77
|
+
"n8n-nodes-base/cred-class-field-name-uppercase-first-char": "error",
|
|
78
|
+
"n8n-nodes-base/cred-class-field-properties-assertion": "error",
|
|
79
|
+
"n8n-nodes-base/cred-class-field-type-options-password-missing": "error",
|
|
80
|
+
"n8n-nodes-base/cred-class-name-missing-oauth2-suffix": "error",
|
|
81
|
+
"n8n-nodes-base/cred-class-name-unsuffixed": "error",
|
|
82
|
+
"n8n-nodes-base/cred-filename-against-convention": "error",
|
|
73
83
|
},
|
|
74
84
|
},
|
|
75
|
-
{
|
|
76
|
-
files: ["./nodes/**/*.ts"],
|
|
77
|
-
extends: compat.extends("plugin:n8n-nodes-base/nodes"),
|
|
78
85
|
|
|
86
|
+
{
|
|
87
|
+
files: ["**/nodes/**/*.ts"],
|
|
79
88
|
plugins: {
|
|
80
|
-
"n8n-nodes-base":
|
|
89
|
+
"n8n-nodes-base": n8nNodesBaseCompat,
|
|
81
90
|
},
|
|
82
|
-
|
|
91
|
+
extends: fixupConfigRules(
|
|
92
|
+
compat.extends("plugin:n8n-nodes-base/nodes"),
|
|
93
|
+
),
|
|
83
94
|
rules: {
|
|
95
|
+
|
|
84
96
|
'n8n-nodes-base/node-class-description-credentials-name-unsuffixed': 'error',
|
|
85
97
|
'n8n-nodes-base/node-class-description-display-name-unsuffixed-trigger-node': 'error',
|
|
86
98
|
'n8n-nodes-base/node-class-description-empty-string': 'error',
|
package/nodes/Smb2/Smb2.node.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import type {
|
|
2
|
-
IExecuteFunctions,
|
|
2
|
+
IExecuteFunctions,
|
|
3
|
+
INodeExecutionData,
|
|
3
4
|
INodeType,
|
|
4
|
-
INodeTypeDescription
|
|
5
|
+
INodeTypeDescription,
|
|
5
6
|
} from 'n8n-workflow';
|
|
6
|
-
import {Operation} from
|
|
7
|
-
import {buildClient, handlers} from
|
|
7
|
+
import { Operation } from './interfaces';
|
|
8
|
+
import { buildClient, handlers } from './SmbEntryHelpers';
|
|
8
9
|
import { NodeOperationError } from 'n8n-workflow';
|
|
9
10
|
export class Smb2 implements INodeType {
|
|
10
11
|
description: INodeTypeDescription = {
|
|
@@ -43,33 +44,47 @@ export class Smb2 implements INodeType {
|
|
|
43
44
|
noDataExpression: true,
|
|
44
45
|
options: [
|
|
45
46
|
{
|
|
46
|
-
name: 'Delete File',
|
|
47
|
-
|
|
47
|
+
name: 'Delete File',
|
|
48
|
+
value: 'del',
|
|
49
|
+
description: 'Delete a file',
|
|
50
|
+
action: 'Delete a file',
|
|
48
51
|
},
|
|
49
52
|
{
|
|
50
|
-
name: 'Get File',
|
|
51
|
-
|
|
53
|
+
name: 'Get File',
|
|
54
|
+
value: 'get',
|
|
55
|
+
description: 'Download a file from SMB',
|
|
56
|
+
action: 'Get a file',
|
|
52
57
|
},
|
|
53
58
|
{
|
|
54
|
-
name: 'List Directory',
|
|
55
|
-
|
|
59
|
+
name: 'List Directory',
|
|
60
|
+
value: 'list',
|
|
61
|
+
description: 'List a directory',
|
|
62
|
+
action: 'List a directory',
|
|
56
63
|
},
|
|
57
64
|
{
|
|
58
|
-
name: 'Make Directory',
|
|
59
|
-
|
|
65
|
+
name: 'Make Directory',
|
|
66
|
+
value: 'mkdir',
|
|
67
|
+
description: 'Create a directory',
|
|
68
|
+
action: 'Create a directory',
|
|
60
69
|
},
|
|
61
70
|
{
|
|
62
|
-
name: 'Remove Directory',
|
|
63
|
-
|
|
71
|
+
name: 'Remove Directory',
|
|
72
|
+
value: 'rmdir',
|
|
73
|
+
description: 'Remove a directory',
|
|
74
|
+
action: 'Remove a directory',
|
|
64
75
|
},
|
|
65
76
|
{
|
|
66
|
-
name: 'Stat',
|
|
67
|
-
|
|
77
|
+
name: 'Stat',
|
|
78
|
+
value: 'stat',
|
|
79
|
+
description: 'Get file/folder metadata',
|
|
80
|
+
action: 'Get file folder metadata',
|
|
68
81
|
},
|
|
69
82
|
{
|
|
70
|
-
name: 'Upload File',
|
|
71
|
-
|
|
72
|
-
|
|
83
|
+
name: 'Upload File',
|
|
84
|
+
value: 'put',
|
|
85
|
+
description: 'Upload a file',
|
|
86
|
+
action: 'Upload a file',
|
|
87
|
+
},
|
|
73
88
|
],
|
|
74
89
|
default: 'list',
|
|
75
90
|
},
|
|
@@ -104,11 +119,11 @@ export class Smb2 implements INodeType {
|
|
|
104
119
|
name: 'putSource',
|
|
105
120
|
type: 'options',
|
|
106
121
|
options: [
|
|
107
|
-
{name: 'Binary Property', value: 'binary'},
|
|
108
|
-
{name: 'Text', value: 'text'},
|
|
122
|
+
{ name: 'Binary Property', value: 'binary' },
|
|
123
|
+
{ name: 'Text', value: 'text' },
|
|
109
124
|
],
|
|
110
125
|
default: 'binary',
|
|
111
|
-
displayOptions: {show: {operation: ['put']}},
|
|
126
|
+
displayOptions: { show: { operation: ['put'] } },
|
|
112
127
|
},
|
|
113
128
|
{
|
|
114
129
|
displayName: 'Binary Property',
|
|
@@ -116,17 +131,17 @@ export class Smb2 implements INodeType {
|
|
|
116
131
|
type: 'string',
|
|
117
132
|
default: 'data',
|
|
118
133
|
displayOptions: {
|
|
119
|
-
show: {operation: ['put'], putSource: ['binary']},
|
|
134
|
+
show: { operation: ['put'], putSource: ['binary'] },
|
|
120
135
|
},
|
|
121
136
|
},
|
|
122
137
|
{
|
|
123
138
|
displayName: 'Text Content',
|
|
124
139
|
name: 'textContent',
|
|
125
140
|
type: 'string',
|
|
126
|
-
typeOptions: {rows: 4},
|
|
141
|
+
typeOptions: { rows: 4 },
|
|
127
142
|
default: '',
|
|
128
143
|
displayOptions: {
|
|
129
|
-
show: {operation: ['put'], putSource: ['text']},
|
|
144
|
+
show: { operation: ['put'], putSource: ['text'] },
|
|
130
145
|
},
|
|
131
146
|
},
|
|
132
147
|
|
|
@@ -136,7 +151,7 @@ export class Smb2 implements INodeType {
|
|
|
136
151
|
name: 'outBinaryPropertyName',
|
|
137
152
|
type: 'string',
|
|
138
153
|
default: 'data',
|
|
139
|
-
displayOptions: {show: {operation: ['get']}},
|
|
154
|
+
displayOptions: { show: { operation: ['get'] } },
|
|
140
155
|
},
|
|
141
156
|
{
|
|
142
157
|
displayName: 'File Name (Output)',
|
|
@@ -144,14 +159,14 @@ export class Smb2 implements INodeType {
|
|
|
144
159
|
type: 'string',
|
|
145
160
|
default: '',
|
|
146
161
|
placeholder: 'example.txt',
|
|
147
|
-
displayOptions: {show: {operation: ['get']}},
|
|
162
|
+
displayOptions: { show: { operation: ['get'] } },
|
|
148
163
|
},
|
|
149
164
|
{
|
|
150
165
|
displayName: 'MIME Type (Output)',
|
|
151
166
|
name: 'outMimeType',
|
|
152
167
|
type: 'string',
|
|
153
168
|
default: 'application/octet-stream',
|
|
154
|
-
displayOptions: {show: {operation: ['get']}},
|
|
169
|
+
displayOptions: { show: { operation: ['get'] } },
|
|
155
170
|
},
|
|
156
171
|
],
|
|
157
172
|
};
|
|
@@ -172,11 +187,13 @@ export class Smb2 implements INodeType {
|
|
|
172
187
|
out.push(await handler(this, i, client));
|
|
173
188
|
}
|
|
174
189
|
} catch (err) {
|
|
175
|
-
console.error(err)
|
|
176
|
-
throw new NodeOperationError(
|
|
190
|
+
console.error(err);
|
|
191
|
+
throw new NodeOperationError(
|
|
192
|
+
this.getNode(),
|
|
193
|
+
(err as Error)?.message || 'SMB operation failed',
|
|
194
|
+
);
|
|
177
195
|
} finally {
|
|
178
|
-
await client.close().catch(() => {
|
|
179
|
-
});
|
|
196
|
+
await client.close().catch(() => {});
|
|
180
197
|
}
|
|
181
198
|
|
|
182
199
|
return this.prepareOutputData(out);
|
|
@@ -1,23 +1,25 @@
|
|
|
1
1
|
import {
|
|
2
2
|
IExecuteFunctions,
|
|
3
|
-
INode,
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
|
|
3
|
+
INode,
|
|
4
|
+
ITriggerFunctions,
|
|
5
|
+
NodeApiError,
|
|
6
|
+
NodeOperationError,
|
|
7
|
+
} from 'n8n-workflow';
|
|
8
|
+
import { promisify } from 'node:util';
|
|
9
|
+
import { execFile } from 'node:child_process';
|
|
10
|
+
import { Smb2Credentials, SmbListEntry, SmbStat } from './interfaces';
|
|
11
|
+
import { debuglog } from 'util';
|
|
12
|
+
|
|
13
|
+
const debug = debuglog('n8n-nodes-smbclient');
|
|
12
14
|
// Refaire une map d’erreurs si besoin
|
|
13
15
|
const SMB_ERROR_HINTS: Array<[RegExp, string]> = [
|
|
14
|
-
[/EACCES/i,
|
|
15
|
-
[/ENOENT/i,
|
|
16
|
-
[/ENOTDIR/i,
|
|
17
|
-
[/ETIMEOUT/i,
|
|
18
|
-
[/ECONNREFUSED/i,
|
|
19
|
-
[/LOGON failure/i,
|
|
20
|
-
[/bad network name/i,
|
|
16
|
+
[/EACCES/i, 'Access Denied - Check your permissions for this file/folder'],
|
|
17
|
+
[/ENOENT/i, 'File/Path Not Found'],
|
|
18
|
+
[/ENOTDIR/i, 'Not a directory'],
|
|
19
|
+
[/ETIMEOUT/i, 'Connection timed out'],
|
|
20
|
+
[/ECONNREFUSED/i, 'Could not connect to SMB server - Connection refused'],
|
|
21
|
+
[/LOGON failure/i, 'Logon Failure - Check your username, password, and domain'],
|
|
22
|
+
[/bad network name/i, 'Bad Network Name - The specified share does not exist on the server'],
|
|
21
23
|
// etc.
|
|
22
24
|
];
|
|
23
25
|
|
|
@@ -31,35 +33,41 @@ export function getReadableError(error: any): string {
|
|
|
31
33
|
return msg;
|
|
32
34
|
}
|
|
33
35
|
|
|
34
|
-
|
|
35
36
|
const execFileAsync = promisify(execFile);
|
|
36
37
|
const redactCmd = (s: string): string => {
|
|
37
38
|
if (!s) return s;
|
|
38
|
-
s = s.replace(/-U\s
|
|
39
|
-
s = s.replace(/-A\s
|
|
39
|
+
s = s.replace(/-U\s+\S+/g, '-U ***');
|
|
40
|
+
s = s.replace(/-A\s+\S+/g, '-A ***');
|
|
40
41
|
s = s.replace(/\/\/[^/\s]+\/\S+/g, '//***');
|
|
41
42
|
return s;
|
|
42
|
-
}
|
|
43
|
+
};
|
|
44
|
+
const maskSecrets = (value: string, secrets: Array<string | undefined>): string => {
|
|
45
|
+
let result = value;
|
|
46
|
+
for (const secret of secrets) {
|
|
47
|
+
if (secret) {
|
|
48
|
+
result = result.split(secret).join('***');
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return result;
|
|
52
|
+
};
|
|
43
53
|
|
|
44
54
|
export class SmbClientWrapper {
|
|
45
55
|
constructor(
|
|
46
56
|
private auth: Smb2Credentials,
|
|
47
57
|
private smbclientPath: string = 'smbclient',
|
|
48
|
-
private node: INode
|
|
49
|
-
) {
|
|
50
|
-
}
|
|
51
|
-
|
|
58
|
+
private node: INode,
|
|
59
|
+
) {}
|
|
52
60
|
|
|
53
61
|
private buildBaseArgs(): string[] {
|
|
54
|
-
const {host, username, password, domain, share} = this.auth;
|
|
62
|
+
const { host, username, password, domain, share } = this.auth;
|
|
55
63
|
|
|
56
|
-
// Anonymous if no username supplied
|
|
64
|
+
// Anonymous if no username supplied
|
|
57
65
|
let userPart = '%';
|
|
58
66
|
if (username) {
|
|
59
67
|
if (!domain) {
|
|
60
|
-
userPart = `${username}%${password ?? ''}
|
|
68
|
+
userPart = `${username}%${password ?? ''}`;
|
|
61
69
|
} else {
|
|
62
|
-
userPart = `${domain}/${username}%${password ?? ''}
|
|
70
|
+
userPart = `${domain}/${username}%${password ?? ''}`;
|
|
63
71
|
}
|
|
64
72
|
}
|
|
65
73
|
const hostPart = `\\\\${host}\\${share}`;
|
|
@@ -69,29 +77,36 @@ export class SmbClientWrapper {
|
|
|
69
77
|
private async runOne(cmd: string): Promise<string> {
|
|
70
78
|
const args = [...this.buildBaseArgs(), '-c', cmd];
|
|
71
79
|
|
|
80
|
+
const { username, password, domain } = this.auth;
|
|
81
|
+
|
|
82
|
+
const rawCmd = [this.smbclientPath, ...args].join(' ');
|
|
83
|
+
const safeCmd = maskSecrets(redactCmd(rawCmd), [username, password, domain]);
|
|
84
|
+
|
|
72
85
|
try {
|
|
73
|
-
const {stdout, stderr} = await execFileAsync(this.smbclientPath, args, {
|
|
86
|
+
const { stdout, stderr } = await execFileAsync(this.smbclientPath, args, {
|
|
74
87
|
maxBuffer: 10 * 1024 * 1024,
|
|
75
88
|
});
|
|
76
|
-
|
|
89
|
+
|
|
90
|
+
// smbclient sometimes prints warnings to stderr; detect real errors
|
|
77
91
|
if (stderr && /NT_STATUS|Error|failed/i.test(stderr)) {
|
|
78
|
-
const
|
|
79
|
-
|
|
92
|
+
const safeErr = maskSecrets(stderr.trim(), [username, password, domain]);
|
|
93
|
+
|
|
80
94
|
throw new NodeOperationError(this.node, {
|
|
81
|
-
message: `smbclient failed. cmd="${safeCmd}" stderr="${
|
|
95
|
+
message: `smbclient failed. cmd="${safeCmd}" stderr="${safeErr}"`,
|
|
82
96
|
});
|
|
83
97
|
}
|
|
98
|
+
|
|
84
99
|
return stdout ?? '';
|
|
85
|
-
} catch (err) {
|
|
100
|
+
} catch (err: any) {
|
|
101
|
+
const safeErr = maskSecrets(
|
|
102
|
+
err?.stderr?.trim?.() || err?.message || 'smbclient command failed',
|
|
103
|
+
[username, password, domain],
|
|
104
|
+
);
|
|
86
105
|
|
|
87
|
-
const {username, password} = this.auth;
|
|
88
|
-
const safeCmd = redactCmd(err?.cmd || [this.smbclientPath, ...args].join(' ')).replace(username, '***').replace(password, '***');
|
|
89
|
-
const msg = (err?.stderr?.trim?.() || err?.message || 'smbclient command failed').replace(username, '***').replace(password, '***');
|
|
90
106
|
throw new NodeOperationError(this.node, {
|
|
91
|
-
message: `smbclient failed. cmd="${safeCmd}" stderr="${
|
|
92
|
-
})
|
|
107
|
+
message: `smbclient failed. cmd="${safeCmd}" stderr="${safeErr}"`,
|
|
108
|
+
});
|
|
93
109
|
}
|
|
94
|
-
|
|
95
110
|
}
|
|
96
111
|
|
|
97
112
|
async stat(remotePath: string): Promise<SmbStat> {
|
|
@@ -114,7 +129,16 @@ export class SmbClientWrapper {
|
|
|
114
129
|
}
|
|
115
130
|
|
|
116
131
|
async list(dir: string): Promise<SmbListEntry[]> {
|
|
117
|
-
const out = await this.runOne(`ls "${dir}"`);
|
|
132
|
+
// const out = await this.runOne(`ls "${dir}"`);
|
|
133
|
+
const normalizedDir = (dir ?? '').trim();
|
|
134
|
+
const safeDir = this.escapeSmbArg(normalizedDir);
|
|
135
|
+
|
|
136
|
+
const command =
|
|
137
|
+
normalizedDir && normalizedDir !== '/' && normalizedDir !== '.'
|
|
138
|
+
? `cd "${safeDir}"; ls`
|
|
139
|
+
: 'ls';
|
|
140
|
+
|
|
141
|
+
const out = await this.runOne(command);
|
|
118
142
|
|
|
119
143
|
const lines = out
|
|
120
144
|
.split('\n')
|
|
@@ -230,7 +254,6 @@ export class SmbClientWrapper {
|
|
|
230
254
|
});
|
|
231
255
|
}
|
|
232
256
|
|
|
233
|
-
|
|
234
257
|
async get(remotePath: string, localPath: string): Promise<void> {
|
|
235
258
|
await this.runOne(`get "${remotePath}" "${localPath}"`);
|
|
236
259
|
}
|
|
@@ -251,35 +274,41 @@ export class SmbClientWrapper {
|
|
|
251
274
|
await this.runOne(`del "${remotePath}"`);
|
|
252
275
|
}
|
|
253
276
|
|
|
254
|
-
// No persistent connection to close for smbclient CLI, but keep API parity.
|
|
277
|
+
// No persistent connection to close for smbclient CLI, but keep API parity.
|
|
255
278
|
async close(): Promise<void> {
|
|
256
279
|
/* no-op */
|
|
257
280
|
}
|
|
281
|
+
|
|
282
|
+
private escapeSmbArg(value: string): string {
|
|
283
|
+
return String(value).replace(/"/g, '\\"');
|
|
284
|
+
}
|
|
258
285
|
}
|
|
259
286
|
|
|
260
287
|
export async function connectToSmbServer(
|
|
261
|
-
this: IExecuteFunctions | ITriggerFunctions
|
|
288
|
+
this: IExecuteFunctions | ITriggerFunctions,
|
|
262
289
|
): Promise<{ client: SmbClientWrapper }> {
|
|
263
290
|
try {
|
|
264
|
-
const credentials = (await this.getCredentials(
|
|
291
|
+
const credentials = (await this.getCredentials('smb2Api')) as unknown as Smb2Credentials;
|
|
265
292
|
|
|
266
293
|
debug(
|
|
267
|
-
|
|
294
|
+
'Connecting to //%s/%s as (%s\\%s)',
|
|
268
295
|
credentials.host,
|
|
269
296
|
credentials.share,
|
|
270
|
-
credentials.domain ??
|
|
297
|
+
credentials.domain ?? '',
|
|
271
298
|
credentials.username,
|
|
272
299
|
);
|
|
273
300
|
const smbclientPath = this.getNodeParameter('smbclientPath', 0, 'smbclient') as string;
|
|
274
301
|
const client = new SmbClientWrapper(credentials, smbclientPath, this.getNode());
|
|
275
302
|
|
|
276
303
|
// Optionnel: tester existence ou list root pour vérifier la connexion
|
|
277
|
-
await client.list(
|
|
304
|
+
await client.list(''); // ou client.exists(".");
|
|
278
305
|
|
|
279
|
-
return {client};
|
|
306
|
+
return { client };
|
|
280
307
|
} catch (error: any) {
|
|
281
|
-
debug(
|
|
308
|
+
debug('Connect error: %O', error);
|
|
282
309
|
const readableError = getReadableError(error);
|
|
283
|
-
throw new NodeApiError(this.getNode(), error, {
|
|
310
|
+
throw new NodeApiError(this.getNode(), error, {
|
|
311
|
+
message: `Failed to connect to SMB server: ${readableError}`,
|
|
312
|
+
});
|
|
284
313
|
}
|
|
285
314
|
}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import {debuglog} from
|
|
2
|
-
import {IExecuteFunctions, INodeExecutionData, NodeOperationError} from
|
|
3
|
-
import path from
|
|
4
|
-
import os from
|
|
5
|
-
import crypto from
|
|
6
|
-
import {SmbClientWrapper} from
|
|
7
|
-
import {Operation, OpHandler, Smb2Credentials, SmbListEntry} from
|
|
8
|
-
import fs from
|
|
9
|
-
|
|
10
|
-
const debug = debuglog(
|
|
1
|
+
import { debuglog } from 'util';
|
|
2
|
+
import { IExecuteFunctions, INodeExecutionData, NodeOperationError } from 'n8n-workflow';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import os from 'node:os';
|
|
5
|
+
import crypto from 'node:crypto';
|
|
6
|
+
import { SmbClientWrapper } from './SmbClientWrapper';
|
|
7
|
+
import { Operation, OpHandler, Smb2Credentials, SmbListEntry } from './interfaces';
|
|
8
|
+
import fs from 'node:fs/promises';
|
|
9
|
+
|
|
10
|
+
const debug = debuglog('n8n-nodes-smbclient');
|
|
11
11
|
const str = (ctx: IExecuteFunctions, i: number, name: string, def = ''): string =>
|
|
12
12
|
ctx.getNodeParameter(name, i, def) as string;
|
|
13
13
|
|
|
@@ -23,27 +23,27 @@ const toBinary = async (
|
|
|
23
23
|
extraJson: Record<string, unknown> = {},
|
|
24
24
|
): Promise<INodeExecutionData> => {
|
|
25
25
|
const binary = await ctx.helpers.prepareBinaryData(buf, fileName, mime);
|
|
26
|
-
return {json: {fileName, ...extraJson}, binary: {[outProp]: binary}};
|
|
26
|
+
return { json: { fileName, ...extraJson }, binary: { [outProp]: binary } };
|
|
27
27
|
};
|
|
28
28
|
|
|
29
29
|
const buildClient = async (ctx: IExecuteFunctions): Promise<SmbClientWrapper> => {
|
|
30
30
|
const smbclientPath = str(ctx, 0, 'smbclientPath', 'smbclient');
|
|
31
|
-
const {host, username, password, domain, share} = (await ctx.getCredentials(
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
domain
|
|
37
|
-
|
|
31
|
+
const { host, username, password, domain, share } = (await ctx.getCredentials(
|
|
32
|
+
'smb2Api',
|
|
33
|
+
)) as unknown as Smb2Credentials;
|
|
34
|
+
debug('Connecting to //%s/%s as (%s\\%s)', host, share, domain ?? '', username);
|
|
35
|
+
return new SmbClientWrapper(
|
|
36
|
+
{ host, username, password, domain, share },
|
|
37
|
+
smbclientPath,
|
|
38
|
+
ctx.getNode(),
|
|
38
39
|
);
|
|
39
|
-
return new SmbClientWrapper({host, username, password, domain, share}, smbclientPath, ctx.getNode());
|
|
40
40
|
};
|
|
41
41
|
|
|
42
42
|
/* ---------- Handlers (take ctx instead of this) ---------- */
|
|
43
43
|
const handleStat: OpHandler = async (ctx, i, client) => {
|
|
44
44
|
const remotePath = str(ctx, i, 'remotePath');
|
|
45
45
|
const stat = await client.stat(remotePath);
|
|
46
|
-
return {json: {remotePath, ...stat}};
|
|
46
|
+
return { json: { remotePath, ...stat } };
|
|
47
47
|
};
|
|
48
48
|
|
|
49
49
|
const handleList: OpHandler = async (ctx, i, client) => {
|
|
@@ -57,7 +57,7 @@ const handleList: OpHandler = async (ctx, i, client) => {
|
|
|
57
57
|
!/blocks available/i.test(e?.date || '') &&
|
|
58
58
|
!/^\d+$/.test(e.name),
|
|
59
59
|
);
|
|
60
|
-
return {json: {directory, entries: filtered}};
|
|
60
|
+
return { json: { directory, entries: filtered } };
|
|
61
61
|
};
|
|
62
62
|
|
|
63
63
|
const handleGet: OpHandler = async (ctx, i, client) => {
|
|
@@ -69,9 +69,8 @@ const handleGet: OpHandler = async (ctx, i, client) => {
|
|
|
69
69
|
const tmp = tmpFile('get');
|
|
70
70
|
await client.get(remotePath, tmp);
|
|
71
71
|
const buf = await fs.readFile(tmp);
|
|
72
|
-
await fs.unlink(tmp).catch(() => {
|
|
73
|
-
});
|
|
74
|
-
return toBinary(ctx, buf, outFile, outMime, outProp, {remotePath});
|
|
72
|
+
await fs.unlink(tmp).catch(() => {});
|
|
73
|
+
return toBinary(ctx, buf, outFile, outMime, outProp, { remotePath });
|
|
75
74
|
};
|
|
76
75
|
|
|
77
76
|
const handlePut: OpHandler = async (ctx, i, client) => {
|
|
@@ -83,7 +82,10 @@ const handlePut: OpHandler = async (ctx, i, client) => {
|
|
|
83
82
|
const binProp = str(ctx, i, 'binaryPropertyName', 'data');
|
|
84
83
|
const item = ctx.getInputData()[i];
|
|
85
84
|
if (!item.binary || !item.binary[binProp]) {
|
|
86
|
-
throw new NodeOperationError(
|
|
85
|
+
throw new NodeOperationError(
|
|
86
|
+
ctx.getNode(),
|
|
87
|
+
`Binary property "${binProp}" not found on item ${i}`,
|
|
88
|
+
);
|
|
87
89
|
}
|
|
88
90
|
const buffer = await ctx.helpers.getBinaryDataBuffer(i, binProp);
|
|
89
91
|
await fs.writeFile(tmp, buffer);
|
|
@@ -93,27 +95,26 @@ const handlePut: OpHandler = async (ctx, i, client) => {
|
|
|
93
95
|
}
|
|
94
96
|
|
|
95
97
|
await client.put(tmp, remotePath);
|
|
96
|
-
await fs.unlink(tmp).catch(() => {
|
|
97
|
-
}
|
|
98
|
-
return {json: {remotePath, uploaded: true}};
|
|
98
|
+
await fs.unlink(tmp).catch(() => {});
|
|
99
|
+
return { json: { remotePath, uploaded: true } };
|
|
99
100
|
};
|
|
100
101
|
|
|
101
102
|
const handleMkdir: OpHandler = async (ctx, i, client) => {
|
|
102
103
|
const directory = str(ctx, i, 'directory');
|
|
103
104
|
await client.mkdir(directory);
|
|
104
|
-
return {json: {directory, created: true}};
|
|
105
|
+
return { json: { directory, created: true } };
|
|
105
106
|
};
|
|
106
107
|
|
|
107
108
|
const handleRmdir: OpHandler = async (ctx, i, client) => {
|
|
108
109
|
const directory = str(ctx, i, 'directory');
|
|
109
110
|
await client.rmdir(directory);
|
|
110
|
-
return {json: {directory, removed: true}};
|
|
111
|
+
return { json: { directory, removed: true } };
|
|
111
112
|
};
|
|
112
113
|
|
|
113
114
|
const handleDel: OpHandler = async (ctx, i, client) => {
|
|
114
115
|
const remotePath = str(ctx, i, 'remotePath');
|
|
115
116
|
await client.del(remotePath);
|
|
116
|
-
return {json: {remotePath, deleted: true}};
|
|
117
|
+
return { json: { remotePath, deleted: true } };
|
|
117
118
|
};
|
|
118
119
|
|
|
119
120
|
const handlers: Record<Operation, OpHandler> = {
|
|
@@ -126,4 +127,4 @@ const handlers: Record<Operation, OpHandler> = {
|
|
|
126
127
|
del: handleDel,
|
|
127
128
|
};
|
|
128
129
|
|
|
129
|
-
export {handlers, buildClient}
|
|
130
|
+
export { handlers, buildClient };
|
package/nodes/Smb2/interfaces.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {IExecuteFunctions, INodeExecutionData} from
|
|
2
|
-
import {SmbClientWrapper} from
|
|
1
|
+
import { IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
|
|
2
|
+
import { SmbClientWrapper } from './SmbClientWrapper';
|
|
3
3
|
|
|
4
4
|
interface Smb2Credentials {
|
|
5
5
|
host: string;
|
|
@@ -7,8 +7,8 @@ interface Smb2Credentials {
|
|
|
7
7
|
domain?: string;
|
|
8
8
|
username: string;
|
|
9
9
|
password: string;
|
|
10
|
-
port?: number;
|
|
11
|
-
maxProtocol?: string;
|
|
10
|
+
port?: number; // samba-client may not support explicit port
|
|
11
|
+
maxProtocol?: string; // passed through
|
|
12
12
|
// timeout options (if supported)
|
|
13
13
|
}
|
|
14
14
|
|
|
@@ -31,9 +31,10 @@ type SmbStat = {
|
|
|
31
31
|
isDirectory?: boolean;
|
|
32
32
|
};
|
|
33
33
|
type Operation = 'stat' | 'list' | 'get' | 'put' | 'mkdir' | 'rmdir' | 'del';
|
|
34
|
-
type OpHandler = (
|
|
34
|
+
type OpHandler = (
|
|
35
|
+
ctx: IExecuteFunctions,
|
|
36
|
+
i: number,
|
|
37
|
+
client: SmbClientWrapper,
|
|
38
|
+
) => Promise<INodeExecutionData>;
|
|
35
39
|
|
|
36
|
-
export {
|
|
37
|
-
SmbStat, SmbListEntry, Smb2Credentials, Operation
|
|
38
|
-
, OpHandler
|
|
39
|
-
}
|
|
40
|
+
export { SmbStat, SmbListEntry, Smb2Credentials, Operation, OpHandler };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "n8n-nodes-smbclient",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "Transfer files via Samba (SMB2) and smbclient package with n8n, some of the base work are based on https://github.com/drudge/n8n-nodes-smb work.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"n8n-community-node-package",
|
|
@@ -38,30 +38,32 @@
|
|
|
38
38
|
]
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
|
+
"@eslint/compat": "^2.0.3",
|
|
41
42
|
"@eslint/eslintrc": "^3.3.1",
|
|
42
|
-
"@eslint/js": "^
|
|
43
|
+
"@eslint/js": "^10.0.0",
|
|
43
44
|
"@types/node": "^24.9.2",
|
|
44
45
|
"@typescript-eslint/parser": "^8.46.2",
|
|
45
|
-
"eslint": "^
|
|
46
|
+
"eslint": "^10.0.0",
|
|
46
47
|
"eslint-plugin-n8n-nodes-base": "^1.16.4",
|
|
47
|
-
"globals": "^
|
|
48
|
+
"globals": "^17.0.0",
|
|
48
49
|
"gulp": "^5.0.1",
|
|
49
50
|
"prettier": "^3.6.2",
|
|
50
51
|
"typescript": "^5.9.3"
|
|
51
52
|
},
|
|
52
53
|
"peerDependencies": {
|
|
53
|
-
"n8n-workflow": "^1.115.0"
|
|
54
|
+
"n8n-workflow": "^1.115.0 || ^2.0.0"
|
|
54
55
|
},
|
|
55
56
|
"dependencies": {
|
|
56
57
|
"tmp-promise": "^3.0.3"
|
|
57
58
|
},
|
|
58
59
|
"overrides": {
|
|
59
60
|
"form-data": "^4.0.4",
|
|
60
|
-
"axios": "1.
|
|
61
|
+
"axios": "1.13.6"
|
|
61
62
|
},
|
|
62
63
|
"pnpm": {
|
|
63
64
|
"onlyBuiltDependencies": [
|
|
64
|
-
"eslint-plugin-n8n-nodes-base"
|
|
65
|
+
"eslint-plugin-n8n-nodes-base",
|
|
66
|
+
"isolated-vm"
|
|
65
67
|
]
|
|
66
68
|
}
|
|
67
69
|
}
|