n8n-nodes-smbclient 1.1.1 → 1.1.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/.dockerignore +8 -0
- package/Readme.md +52 -0
- package/dist/nodes/Smb2/SmbClientWrapper.js +9 -5
- package/dist/nodes/Smb2/SmbClientWrapper.js.map +1 -1
- package/dist/package.json +1 -1
- package/docker/Dockerfile +44 -0
- package/docker/entrypoint.sh +31 -0
- package/docker-compose.yml +63 -0
- package/nodes/Smb2/SmbClientWrapper.ts +23 -12
- package/package.json +1 -1
package/.dockerignore
ADDED
package/Readme.md
CHANGED
|
@@ -94,6 +94,58 @@ The node provides detailed error messages for common SMB issues:
|
|
|
94
94
|
- Quota issues
|
|
95
95
|
- File sharing violations
|
|
96
96
|
|
|
97
|
+
## Local testing with Docker Compose
|
|
98
|
+
|
|
99
|
+
A ready-to-use stack is provided to test the node from the n8n UI against a
|
|
100
|
+
throwaway Samba server. It spins up two services:
|
|
101
|
+
|
|
102
|
+
- **n8n** — built from `docker/Dockerfile` with the `samba-client` CLI baked in
|
|
103
|
+
(the node shells out to it) and this package auto-installed into
|
|
104
|
+
`~/.n8n/nodes` on startup.
|
|
105
|
+
- **smb** — a disposable Samba server (`dperson/samba`) exposing a writable
|
|
106
|
+
share `n8nshare` for the user `n8n` / `n8npass`.
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
# 1. Build the node (the container loads the compiled dist/, not the .ts)
|
|
110
|
+
npm run build
|
|
111
|
+
|
|
112
|
+
# 2. Start the stack
|
|
113
|
+
docker compose up --build
|
|
114
|
+
|
|
115
|
+
# 3. Open http://localhost:5678
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
In n8n, create an **Smbclient (SMB2) API** credential with:
|
|
119
|
+
|
|
120
|
+
| Field | Value |
|
|
121
|
+
| ---------- | ---------- |
|
|
122
|
+
| Server | `smb` |
|
|
123
|
+
| Share Name | `n8nshare` |
|
|
124
|
+
| User Name | `n8n` |
|
|
125
|
+
| Password | `n8npass` |
|
|
126
|
+
| Domain | _(empty)_ |
|
|
127
|
+
| Port | `445` |
|
|
128
|
+
|
|
129
|
+
Then add the **SMB2 using smbclient** node and try the operations (List, Upload,
|
|
130
|
+
Download, …) against the share.
|
|
131
|
+
|
|
132
|
+
After changing the node code, rebuild and reinstall it into the running n8n:
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
npm run build
|
|
136
|
+
REINSTALL_SMB_NODE=true docker compose up -d --force-recreate n8n
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
The n8n version is configurable (defaults to the latest stable 2.x):
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
N8N_VERSION=2.23.3 docker compose up --build
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
> n8n 2.x ships as a hardened Alpine image without a package manager, so the
|
|
146
|
+
> Dockerfile installs `samba-client` in a matching Alpine stage and copies the
|
|
147
|
+
> binary and its libraries into the final image.
|
|
148
|
+
|
|
97
149
|
## Running local (Development)
|
|
98
150
|
|
|
99
151
|
> Required podman and n8nio image setup
|
|
@@ -8,7 +8,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
10
|
const debug = (0, util_1.debuglog)('n8n-nodes-smbclient');
|
|
11
|
-
const SMB_FAILURE_RE = /NT_STATUS_(?!OK\b)[A-Z0-9_]+/;
|
|
11
|
+
const SMB_FAILURE_RE = /NT_STATUS_(?!OK\b|NO_MORE_FILES\b|NO_MORE_ENTRIES\b)[A-Z0-9_]+/;
|
|
12
12
|
const SMB_ERROR_HINTS = [
|
|
13
13
|
[/EACCES/i, 'Access Denied - Check your permissions for this file/folder'],
|
|
14
14
|
[/ENOENT/i, 'File/Path Not Found'],
|
|
@@ -76,7 +76,6 @@ class SmbClientWrapper {
|
|
|
76
76
|
throw new n8n_workflow_1.NodeOperationError(this.node, `smbclient failed. cmd="${safeCmd}" stderr="${safeErr}"`);
|
|
77
77
|
}
|
|
78
78
|
async runOne(cmd) {
|
|
79
|
-
var _a, _b;
|
|
80
79
|
const args = [...this.buildBaseArgs(), '-c', cmd];
|
|
81
80
|
const { username, password, domain } = this.auth;
|
|
82
81
|
const rawCmd = [this.smbclientPath, ...args].join(' ');
|
|
@@ -89,10 +88,15 @@ class SmbClientWrapper {
|
|
|
89
88
|
}));
|
|
90
89
|
}
|
|
91
90
|
catch (err) {
|
|
92
|
-
|
|
91
|
+
stdout = typeof (err === null || err === void 0 ? void 0 : err.stdout) === 'string' ? err.stdout : '';
|
|
92
|
+
stderr = typeof (err === null || err === void 0 ? void 0 : err.stderr) === 'string' ? err.stderr : '';
|
|
93
|
+
const couldNotRun = typeof (err === null || err === void 0 ? void 0 : err.code) !== 'number' || (err === null || err === void 0 ? void 0 : err.killed) === true;
|
|
94
|
+
if (couldNotRun || SMB_FAILURE_RE.test(`${stdout}\n${stderr}`)) {
|
|
95
|
+
this.fail(safeCmd, stderr.trim() || stdout.trim() || (err === null || err === void 0 ? void 0 : err.message));
|
|
96
|
+
}
|
|
93
97
|
}
|
|
94
|
-
if (
|
|
95
|
-
this.fail(safeCmd, stderr);
|
|
98
|
+
if (SMB_FAILURE_RE.test(`${stdout}\n${stderr}`)) {
|
|
99
|
+
this.fail(safeCmd, stderr.trim() || stdout.trim());
|
|
96
100
|
}
|
|
97
101
|
return stdout !== null && stdout !== void 0 ? stdout : '';
|
|
98
102
|
}
|
|
@@ -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":";;;AAkCA,4CAQC;AA4PD,gDA2BC;AAjUD,+CAMsB;AACtB,yCAAsC;AACtC,2DAA8C;AAE9C,+BAAgC;AAEhC,MAAM,KAAK,GAAG,IAAA,eAAQ,EAAC,qBAAqB,CAAC,CAAC;AAS9C,MAAM,cAAc,GAAG,gEAAgE,CAAC;AAExF,MAAM,eAAe,GAA4B;IAChD,CAAC,SAAS,EAAE,6DAA6D,CAAC;IAC1E,CAAC,SAAS,EAAE,qBAAqB,CAAC;IAClC,CAAC,UAAU,EAAE,iBAAiB,CAAC;IAC/B,CAAC,WAAW,EAAE,sBAAsB,CAAC;IACrC,CAAC,eAAe,EAAE,sDAAsD,CAAC;IACzE,CAAC,gBAAgB,EAAE,2DAA2D,CAAC;IAC/E,CAAC,mBAAmB,EAAE,qEAAqE,CAAC;CAE5F,CAAC;AAEF,SAAgB,gBAAgB,CAAC,KAAU;;IAC1C,MAAM,GAAG,GAAG,MAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,OAAO,mCAAI,MAAM,CAAC,KAAK,CAAC,CAAC;IAC5C,KAAK,MAAM,CAAC,EAAE,EAAE,QAAQ,CAAC,IAAI,eAAe,EAAE,CAAC;QAC9C,IAAI,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YAClB,OAAO,GAAG,QAAQ,KAAK,GAAG,GAAG,CAAC;QAC/B,CAAC;IACF,CAAC;IACD,OAAO,GAAG,CAAC;AACZ,CAAC;AAED,MAAM,aAAa,GAAG,IAAA,qBAAS,EAAC,6BAAQ,CAAC,CAAC;AAC1C,MAAM,SAAS,GAAG,CAAC,CAAS,EAAU,EAAE;IACvC,IAAI,CAAC,CAAC;QAAE,OAAO,CAAC,CAAC;IACjB,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;IACrC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;IACrC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,mBAAmB,EAAE,OAAO,CAAC,CAAC;IAC5C,OAAO,CAAC,CAAC;AACV,CAAC,CAAC;AACF,MAAM,WAAW,GAAG,CAAC,KAAa,EAAE,OAAkC,EAAU,EAAE;IACjF,IAAI,MAAM,GAAG,KAAK,CAAC;IACnB,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC9B,IAAI,MAAM,EAAE,CAAC;YACZ,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3C,CAAC;IACF,CAAC;IACD,OAAO,MAAM,CAAC;AACf,CAAC,CAAC;AAEF,MAAa,gBAAgB;IAC5B,YACS,IAAqB,EACrB,gBAAwB,WAAW,EACnC,IAAW;QAFX,SAAI,GAAJ,IAAI,CAAiB;QACrB,kBAAa,GAAb,aAAa,CAAsB;QACnC,SAAI,GAAJ,IAAI,CAAO;IACjB,CAAC;IAEI,aAAa;QACpB,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC;QAG9D,IAAI,QAAQ,GAAG,GAAG,CAAC;QACnB,IAAI,QAAQ,EAAE,CAAC;YACd,IAAI,CAAC,MAAM,EAAE,CAAC;gBACb,QAAQ,GAAG,GAAG,QAAQ,IAAI,QAAQ,aAAR,QAAQ,cAAR,QAAQ,GAAI,EAAE,EAAE,CAAC;YAC5C,CAAC;iBAAM,CAAC;gBACP,QAAQ,GAAG,GAAG,MAAM,IAAI,QAAQ,IAAI,QAAQ,aAAR,QAAQ,cAAR,QAAQ,GAAI,EAAE,EAAE,CAAC;YACtD,CAAC;QACF,CAAC;QACD,MAAM,QAAQ,GAAG,OAAO,IAAI,KAAK,KAAK,EAAE,CAAC;QACzC,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;IACzC,CAAC;IAEO,IAAI,CAAC,OAAe,EAAE,MAAc;QAC3C,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC;QACjD,MAAM,OAAO,GAAG,WAAW,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,0BAA0B,EAAE;YAChF,QAAQ;YACR,QAAQ;YACR,MAAM;SACN,CAAC,CAAC;QAGH,MAAM,IAAI,iCAAkB,CAAC,IAAI,CAAC,IAAI,EAAE,0BAA0B,OAAO,aAAa,OAAO,GAAG,CAAC,CAAC;IACnG,CAAC;IAEO,KAAK,CAAC,MAAM,CAAC,GAAW;QAC/B,MAAM,IAAI,GAAG,CAAC,GAAG,IAAI,CAAC,aAAa,EAAE,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;QAElD,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC;QAEjD,MAAM,MAAM,GAAG,CAAC,IAAI,CAAC,aAAa,EAAE,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACvD,MAAM,OAAO,GAAG,WAAW,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;QAE7E,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,IAAI,CAAC;YACJ,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,aAAa,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,EAAE;gBACnE,SAAS,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI;aAC3B,CAAC,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAMnB,MAAM,GAAG,OAAO,CAAA,GAAG,aAAH,GAAG,uBAAH,GAAG,CAAE,MAAM,CAAA,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;YAC3D,MAAM,GAAG,OAAO,CAAA,GAAG,aAAH,GAAG,uBAAH,GAAG,CAAE,MAAM,CAAA,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;YAC3D,MAAM,WAAW,GAAG,OAAO,CAAA,GAAG,aAAH,GAAG,uBAAH,GAAG,CAAE,IAAI,CAAA,KAAK,QAAQ,IAAI,CAAA,GAAG,aAAH,GAAG,uBAAH,GAAG,CAAE,MAAM,MAAK,IAAI,CAAC;YAC1E,IAAI,WAAW,IAAI,cAAc,CAAC,IAAI,CAAC,GAAG,MAAM,KAAK,MAAM,EAAE,CAAC,EAAE,CAAC;gBAChE,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,EAAE,IAAI,MAAM,CAAC,IAAI,EAAE,KAAI,GAAG,aAAH,GAAG,uBAAH,GAAG,CAAE,OAAO,CAAA,CAAC,CAAC;YACpE,CAAC;QACF,CAAC;QAID,IAAI,cAAc,CAAC,IAAI,CAAC,GAAG,MAAM,KAAK,MAAM,EAAE,CAAC,EAAE,CAAC;YACjD,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,EAAE,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QACpD,CAAC;QAED,OAAO,MAAM,aAAN,MAAM,cAAN,MAAM,GAAI,EAAE,CAAC;IACrB,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,UAAkB;;QAC5B,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,YAAY,UAAU,GAAG,CAAC,CAAC;QACzD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAkB,CAAC;QACvC,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACpC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC/B,IAAI,CAAC,IAAI,CAAC,KAAK,SAAS;gBAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QACtE,CAAC;QACD,MAAM,KAAK,GAAG,CAAC,MAAA,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,mCAAI,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACvE,OAAO;YACN,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS;YAC7D,UAAU,EAAE,MAAA,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,mCAAI,SAAS;YAChD,UAAU,EAAE,MAAA,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,mCAAI,SAAS;YAChD,SAAS,EAAE,MAAA,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,mCAAI,SAAS;YAC9C,UAAU,EAAE,MAAA,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,mCAAI,SAAS;YAChD,UAAU,EAAE,KAAK;YACjB,WAAW,EAAE,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC;SAChC,CAAC;IACH,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,GAAW;QACrB,MAAM,aAAa,GAAG,CAAC,GAAG,aAAH,GAAG,cAAH,GAAG,GAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QACzC,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC;QAEjD,MAAM,OAAO,GACZ,aAAa,IAAI,aAAa,KAAK,GAAG,IAAI,aAAa,KAAK,GAAG;YAC9D,CAAC,CAAC,OAAO,OAAO,OAAO;YACvB,CAAC,CAAC,IAAI,CAAC;QAET,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAEvC,MAAM,KAAK,GAAG,GAAG;aACf,KAAK,CAAC,IAAI,CAAC;aACX,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;aACpB,MAAM,CAAC,OAAO,CAAC,CAAC;QAElB,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;;YAEjC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBACxB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBAG9B,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;oBACjD,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;oBACtB,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;oBACnC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;oBACtB,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;oBACtB,MAAM,IAAI,GAAG,MAAA,KAAK,CAAC,CAAC,CAAC,mCAAI,EAAE,CAAC;oBAC5B,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;oBAClD,OAAO;wBACN,IAAI;wBACJ,IAAI;wBACJ,IAAI;wBACJ,IAAI;wBACJ,UAAU;wBACV,WAAW,EAAE,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC;qBACrB,CAAC;gBACnB,CAAC;gBAGD,OAAO;oBACN,IAAI,EAAE,IAAI;oBACV,IAAI,EAAE,CAAC;oBACP,UAAU,EAAE,EAAE;oBACd,WAAW,EAAE,KAAK;iBACF,CAAC;YACnB,CAAC;YAKD,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;YACjD,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAGlC,IAAI,MAAM,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;gBACxB,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;gBACvC,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;gBACvC,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;gBACtC,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;gBACxC,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;gBAC1C,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;gBAC1C,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;gBAEvC,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBAC1D,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;gBAClC,MAAM,UAAU,GAAG,CAAC,IAAI,aAAJ,IAAI,cAAJ,IAAI,GAAI,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;gBAE1D,OAAO;oBACN,IAAI;oBACJ,IAAI;oBACJ,IAAI,EAAE,GAAG,OAAO,IAAI,KAAK,IAAI,GAAG,IAAI,IAAI,IAAI,IAAI,EAAE;oBAClD,IAAI;oBACJ,UAAU;oBACV,WAAW,EAAE,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC;iBACrB,CAAC;YACnB,CAAC;YAGD,OAAO;gBACN,IAAI,EAAE,IAAI;gBACV,IAAI,EAAE,CAAC;gBACP,UAAU,EAAE,EAAE;gBACd,WAAW,EAAE,KAAK;aACF,CAAC;QACnB,CAAC,CAAC,CAAC;QAEH,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;YAC9B,IAAI,CAAC,KAAK;gBAAE,OAAO,KAAK,CAAC;YAGzB,IAAI,KAAK,CAAC,IAAI,KAAK,GAAG,IAAI,KAAK,CAAC,IAAI,KAAK,IAAI;gBAAE,OAAO,KAAK,CAAC;YAG5D,IAAI,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC,IAAI,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;gBACxF,OAAO,KAAK,CAAC;YACd,CAAC;YAGD,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC9B,OAAO,KAAK,CAAC;YACd,CAAC;YAED,OAAO,IAAI,CAAC;QACb,CAAC,CAAC,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,UAAkB,EAAE,SAAiB;QAC9C,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,UAAU,MAAM,SAAS,GAAG,CAAC,CAAC;IACzD,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,SAAiB,EAAE,UAAkB;QAC9C,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,SAAS,MAAM,UAAU,GAAG,CAAC,CAAC;IACzD,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,SAAiB;QAC5B,MAAM,IAAI,CAAC,MAAM,CAAC,UAAU,SAAS,GAAG,CAAC,CAAC;IAC3C,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,SAAiB;QAC5B,MAAM,IAAI,CAAC,MAAM,CAAC,UAAU,SAAS,GAAG,CAAC,CAAC;IAC3C,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,UAAkB;QAC3B,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,UAAU,GAAG,CAAC,CAAC;IAC1C,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,OAAe,EAAE,OAAe;QAC5C,MAAM,IAAI,CAAC,MAAM,CAAC,WAAW,OAAO,MAAM,OAAO,GAAG,CAAC,CAAC;IACvD,CAAC;IAGD,KAAK,CAAC,KAAK;IAEX,CAAC;IAEO,YAAY,CAAC,KAAa;QACjC,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC3C,CAAC;CACD;AAtOD,4CAsOC;AAEM,KAAK,UAAU,kBAAkB;;IAGvC,IAAI,CAAC;QACJ,MAAM,WAAW,GAAG,CAAC,MAAM,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,CAA+B,CAAC;QAEzF,KAAK,CACJ,mCAAmC,EACnC,WAAW,CAAC,IAAI,EAChB,WAAW,CAAC,KAAK,EACjB,MAAA,WAAW,CAAC,MAAM,mCAAI,EAAE,EACxB,WAAW,CAAC,QAAQ,CACpB,CAAC;QACF,MAAM,aAAa,GAAG,IAAI,CAAC,gBAAgB,CAAC,eAAe,EAAE,CAAC,EAAE,WAAW,CAAW,CAAC;QACvF,MAAM,MAAM,GAAG,IAAI,gBAAgB,CAAC,WAAW,EAAE,aAAa,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;QAGhF,MAAM,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAEtB,OAAO,EAAE,MAAM,EAAE,CAAC;IACnB,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACrB,KAAK,CAAC,mBAAmB,EAAE,KAAK,CAAC,CAAC;QAClC,MAAM,aAAa,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC;QAC9C,MAAM,IAAI,2BAAY,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE;YAC7C,OAAO,EAAE,oCAAoC,aAAa,EAAE;SAC5D,CAAC,CAAC;IACJ,CAAC;AACF,CAAC"}
|
package/dist/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "n8n-nodes-smbclient",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.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",
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# n8n image preloaded with the samba-client CLI that n8n-nodes-smbclient
|
|
2
|
+
# shells out to. The community node itself is installed at startup by
|
|
3
|
+
# entrypoint.sh from the source mounted at /opt/code-temp.
|
|
4
|
+
#
|
|
5
|
+
# n8n 2.x ships as a Docker Hardened Image (Alpine, no package manager), so we
|
|
6
|
+
# can't `apk add` directly. Instead we install samba-client in a matching plain
|
|
7
|
+
# Alpine and copy the resulting files (smbclient + its dependency libraries)
|
|
8
|
+
# into the final image.
|
|
9
|
+
|
|
10
|
+
# Declared before the first FROM so it can be used in the stage-2 FROM line.
|
|
11
|
+
ARG N8N_VERSION=2.23.3
|
|
12
|
+
|
|
13
|
+
# ---- Stage 1: collect smbclient + its dependency files ----
|
|
14
|
+
FROM alpine:3.23 AS smb
|
|
15
|
+
RUN set -eux; \
|
|
16
|
+
apk add --no-cache samba-client 2>&1 | tee /tmp/apk.log; \
|
|
17
|
+
smbclient --version; \
|
|
18
|
+
mkdir -p /export; \
|
|
19
|
+
# Copy every file owned by samba-client and the packages it pulled in.
|
|
20
|
+
# Base Alpine packages (musl, etc.) are already in the hardened image, so
|
|
21
|
+
# they never appear in the "Installing" lines and aren't copied/clobbered.
|
|
22
|
+
for p in $(grep -oE 'Installing [^ ]+' /tmp/apk.log | awk '{print $2}'); do \
|
|
23
|
+
apk info -L "$p" | grep -E '^(usr/|lib/|etc/)' | while read -r f; do \
|
|
24
|
+
[ -e "/$f" ] || continue; \
|
|
25
|
+
mkdir -p "/export/$(dirname "$f")"; \
|
|
26
|
+
cp -a "/$f" "/export/$f"; \
|
|
27
|
+
done; \
|
|
28
|
+
done
|
|
29
|
+
|
|
30
|
+
# ---- Stage 2: n8n + smbclient ----
|
|
31
|
+
FROM n8nio/n8n:${N8N_VERSION}
|
|
32
|
+
|
|
33
|
+
USER root
|
|
34
|
+
|
|
35
|
+
COPY --from=smb /export/ /
|
|
36
|
+
# Fail the build early if smbclient can't run (missing lib, etc.).
|
|
37
|
+
RUN smbclient --version
|
|
38
|
+
|
|
39
|
+
COPY docker/entrypoint.sh /usr/local/bin/smbclient-node-entrypoint.sh
|
|
40
|
+
RUN chmod +x /usr/local/bin/smbclient-node-entrypoint.sh
|
|
41
|
+
|
|
42
|
+
USER node
|
|
43
|
+
|
|
44
|
+
ENTRYPOINT ["tini", "--", "/usr/local/bin/smbclient-node-entrypoint.sh"]
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
# Installs the locally-built n8n-nodes-smbclient package (mounted at
|
|
3
|
+
# /opt/code-temp) into n8n's user nodes directory, then starts n8n.
|
|
4
|
+
#
|
|
5
|
+
# The host must run `npm run build` (or `pnpm build`) first so that
|
|
6
|
+
# /opt/code-temp/dist exists — n8n loads the compiled files, not the .ts.
|
|
7
|
+
set -e
|
|
8
|
+
|
|
9
|
+
SOURCE_DIR="/opt/code-temp"
|
|
10
|
+
NODES_DIR="/home/node/.n8n/nodes"
|
|
11
|
+
PKG_NAME="n8n-nodes-smbclient"
|
|
12
|
+
|
|
13
|
+
if [ ! -d "$SOURCE_DIR/dist" ]; then
|
|
14
|
+
echo "WARNING: $SOURCE_DIR/dist not found."
|
|
15
|
+
echo " Run 'npm run build' on the host, then restart this container."
|
|
16
|
+
fi
|
|
17
|
+
|
|
18
|
+
mkdir -p "$NODES_DIR"
|
|
19
|
+
cd "$NODES_DIR"
|
|
20
|
+
|
|
21
|
+
[ -f package.json ] || echo '{"name":"installed-nodes","private":true}' >package.json
|
|
22
|
+
|
|
23
|
+
if [ ! -d "node_modules/$PKG_NAME" ] || [ "${REINSTALL_SMB_NODE:-false}" = "true" ]; then
|
|
24
|
+
echo "Installing $PKG_NAME from $SOURCE_DIR ..."
|
|
25
|
+
npm install "$SOURCE_DIR" --no-audit --no-fund --loglevel error
|
|
26
|
+
else
|
|
27
|
+
echo "$PKG_NAME already installed (set REINSTALL_SMB_NODE=true to refresh after a rebuild)."
|
|
28
|
+
fi
|
|
29
|
+
|
|
30
|
+
# Hand off to n8n's own entrypoint.
|
|
31
|
+
exec /docker-entrypoint.sh "$@"
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
name: n8n-nodes-smbclient-dev
|
|
2
|
+
|
|
3
|
+
# Local stack to test the SMB2 node end-to-end from the n8n UI:
|
|
4
|
+
# - n8n: built with the samba-client CLI + this node auto-installed
|
|
5
|
+
# - smb: a throwaway Samba server with a ready-to-use share
|
|
6
|
+
#
|
|
7
|
+
# Usage:
|
|
8
|
+
# 1. npm run build # produce dist/ on the host
|
|
9
|
+
# 2. docker compose up --build
|
|
10
|
+
# 3. open http://localhost:5678 and create an "Smbclient (SMB2) API" credential:
|
|
11
|
+
# Server: smb
|
|
12
|
+
# Share Name: n8nshare
|
|
13
|
+
# User Name: n8n
|
|
14
|
+
# Password: n8npass
|
|
15
|
+
# Domain: (leave empty)
|
|
16
|
+
# Port: 445
|
|
17
|
+
#
|
|
18
|
+
# After editing the node code: `npm run build`, then
|
|
19
|
+
# REINSTALL_SMB_NODE=true docker compose up -d --force-recreate n8n
|
|
20
|
+
|
|
21
|
+
services:
|
|
22
|
+
n8n:
|
|
23
|
+
build:
|
|
24
|
+
context: .
|
|
25
|
+
dockerfile: docker/Dockerfile
|
|
26
|
+
args:
|
|
27
|
+
N8N_VERSION: ${N8N_VERSION:-2.23.3}
|
|
28
|
+
container_name: n8n-smbclient
|
|
29
|
+
restart: unless-stopped
|
|
30
|
+
ports:
|
|
31
|
+
- "5678:5678"
|
|
32
|
+
environment:
|
|
33
|
+
- N8N_SECURE_COOKIE=false
|
|
34
|
+
- N8N_RUNNERS_ENABLED=true
|
|
35
|
+
- GENERIC_TIMEZONE=${TZ:-UTC}
|
|
36
|
+
- TZ=${TZ:-UTC}
|
|
37
|
+
# set to true to reinstall the node from /opt/code-temp on next start
|
|
38
|
+
- REINSTALL_SMB_NODE=${REINSTALL_SMB_NODE:-false}
|
|
39
|
+
volumes:
|
|
40
|
+
- n8n_data:/home/node/.n8n
|
|
41
|
+
# the built package, installed into ~/.n8n/nodes by the entrypoint
|
|
42
|
+
- ./:/opt/code-temp:ro
|
|
43
|
+
depends_on:
|
|
44
|
+
- smb
|
|
45
|
+
|
|
46
|
+
smb:
|
|
47
|
+
image: dperson/samba
|
|
48
|
+
container_name: n8n-smbclient-samba
|
|
49
|
+
restart: unless-stopped
|
|
50
|
+
# -u "user;password"
|
|
51
|
+
# -s "name;path;browseable;readonly;guest;users;admins"
|
|
52
|
+
command: >-
|
|
53
|
+
-p
|
|
54
|
+
-u "n8n;n8npass"
|
|
55
|
+
-s "n8nshare;/share;yes;no;no;n8n;n8n"
|
|
56
|
+
ports:
|
|
57
|
+
- "1445:445" # host:container — only needed to inspect the share from the host
|
|
58
|
+
volumes:
|
|
59
|
+
- smb_data:/share
|
|
60
|
+
|
|
61
|
+
volumes:
|
|
62
|
+
n8n_data:
|
|
63
|
+
smb_data:
|
|
@@ -12,11 +12,14 @@ import { debuglog } from 'util';
|
|
|
12
12
|
|
|
13
13
|
const debug = debuglog('n8n-nodes-smbclient');
|
|
14
14
|
|
|
15
|
-
// smbclient
|
|
16
|
-
//
|
|
17
|
-
//
|
|
18
|
-
//
|
|
19
|
-
|
|
15
|
+
// smbclient's exit code is unreliable — it can exit non-zero even when the
|
|
16
|
+
// requested command actually succeeded (notably `del`/`rename` against some
|
|
17
|
+
// Windows servers, which complete the operation but still return a failure
|
|
18
|
+
// status). The reliable signal is whether its output contains a genuine
|
|
19
|
+
// NT_STATUS_* error code. We therefore key success/failure off this pattern
|
|
20
|
+
// rather than the exit code. Excluded: NT_STATUS_OK (success) and the benign
|
|
21
|
+
// end-of-listing markers emitted during normal `ls`/`del` wildcard expansion.
|
|
22
|
+
const SMB_FAILURE_RE = /NT_STATUS_(?!OK\b|NO_MORE_FILES\b|NO_MORE_ENTRIES\b)[A-Z0-9_]+/;
|
|
20
23
|
|
|
21
24
|
const SMB_ERROR_HINTS: Array<[RegExp, string]> = [
|
|
22
25
|
[/EACCES/i, 'Access Denied - Check your permissions for this file/folder'],
|
|
@@ -107,15 +110,23 @@ export class SmbClientWrapper {
|
|
|
107
110
|
maxBuffer: 10 * 1024 * 1024,
|
|
108
111
|
}));
|
|
109
112
|
} catch (err: any) {
|
|
110
|
-
//
|
|
111
|
-
|
|
113
|
+
// execFile rejects both when smbclient can't be run (spawn error,
|
|
114
|
+
// timeout/kill) and when it merely exits non-zero. The latter is not a
|
|
115
|
+
// reliable failure signal, so only treat it as an error when smbclient
|
|
116
|
+
// could not run at all, or when its output reports a real NT_STATUS_*
|
|
117
|
+
// failure. Otherwise keep its output and fall through as success.
|
|
118
|
+
stdout = typeof err?.stdout === 'string' ? err.stdout : '';
|
|
119
|
+
stderr = typeof err?.stderr === 'string' ? err.stderr : '';
|
|
120
|
+
const couldNotRun = typeof err?.code !== 'number' || err?.killed === true;
|
|
121
|
+
if (couldNotRun || SMB_FAILURE_RE.test(`${stdout}\n${stderr}`)) {
|
|
122
|
+
this.fail(safeCmd, stderr.trim() || stdout.trim() || err?.message);
|
|
123
|
+
}
|
|
112
124
|
}
|
|
113
125
|
|
|
114
|
-
//
|
|
115
|
-
//
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
this.fail(safeCmd, stderr);
|
|
126
|
+
// smbclient sometimes reports a failed command in its output while still
|
|
127
|
+
// exiting cleanly, so check the output regardless of the exit code.
|
|
128
|
+
if (SMB_FAILURE_RE.test(`${stdout}\n${stderr}`)) {
|
|
129
|
+
this.fail(safeCmd, stderr.trim() || stdout.trim());
|
|
119
130
|
}
|
|
120
131
|
|
|
121
132
|
return stdout ?? '';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "n8n-nodes-smbclient",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.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",
|