n8n-nodes-sftp-custom 0.1.1 → 0.1.3

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.
@@ -4,7 +4,7 @@ exports.SftpApi = void 0;
4
4
  class SftpApi {
5
5
  constructor() {
6
6
  this.name = 'sftpApi';
7
- this.displayName = 'SFTP API';
7
+ this.displayName = 'SFTP Account';
8
8
  this.properties = [
9
9
  {
10
10
  displayName: 'Host',
@@ -31,6 +31,14 @@ class SftpApi {
31
31
  typeOptions: { password: true },
32
32
  default: '',
33
33
  },
34
+ {
35
+ displayName: 'Host Key Algorithms',
36
+ name: 'algorithms',
37
+ type: 'string',
38
+ default: 'ssh-dss,ssh-rsa,rsa-sha2-256,ecdsa-sha2-nistp256',
39
+ description: 'Comma-separated list of host key algorithms (e.g., ssh-dss,ssh-rsa)',
40
+ placeholder: 'ssh-dss,ssh-rsa,ecdsa-sha2-nistp256',
41
+ },
34
42
  ];
35
43
  }
36
44
  }
@@ -27,8 +27,9 @@ class Sftp {
27
27
  name: 'operation',
28
28
  type: 'options',
29
29
  options: [
30
- { name: 'Connect Test', value: 'connect' },
31
- { name: 'Upload File', value: 'upload' },
30
+ { name: 'Connect', value: 'connect', description: 'Test Connection' },
31
+ { name: 'Upload', value: 'upload', description: 'Upload A File' },
32
+ { name: 'Download', value: 'download', description: 'Download A File' },
32
33
  ],
33
34
  default: 'connect',
34
35
  },
@@ -43,10 +44,10 @@ class Sftp {
43
44
  operation: ['upload'],
44
45
  },
45
46
  },
46
- description: 'Name of the binary property containing the file',
47
+ description: 'Name Of The Binary Property Containing The File',
47
48
  },
48
49
  {
49
- displayName: 'Remote Path',
50
+ displayName: 'Remote Folder Path',
50
51
  name: 'remotePath',
51
52
  type: 'string',
52
53
  default: '/upload/',
@@ -56,7 +57,33 @@ class Sftp {
56
57
  operation: ['upload'],
57
58
  },
58
59
  },
59
- description: 'Remote path where to upload the file',
60
+ description: 'Remote Folder Path Where To Upload The File',
61
+ },
62
+ {
63
+ displayName: 'Remote File Path',
64
+ name: 'remoteFilePath',
65
+ type: 'string',
66
+ default: '',
67
+ required: true,
68
+ displayOptions: {
69
+ show: {
70
+ operation: ['download'],
71
+ },
72
+ },
73
+ description: 'Full Path Of The File To Download (e.g., /path/file.txt)',
74
+ },
75
+ {
76
+ displayName: 'Output Property Name',
77
+ name: 'binaryPropertyOutput',
78
+ type: 'string',
79
+ default: 'data',
80
+ required: true,
81
+ displayOptions: {
82
+ show: {
83
+ operation: ['download'],
84
+ },
85
+ },
86
+ description: 'Name For The Binary Property To Store The Downloaded File',
60
87
  },
61
88
  ],
62
89
  };
@@ -82,7 +109,8 @@ class Sftp {
82
109
  username: credentials.username,
83
110
  password: credentials.password,
84
111
  algorithms: {
85
- serverHostKey: ['ssh-dss', 'ssh-rsa', 'ecdsa-sha2-nistp256'],
112
+ // serverHostKey: ['ssh-dss', 'ssh-rsa', 'ecdsa-sha2-nistp256'],
113
+ serverHostKey: credentials.algorithms.split(',').map(x => x.trim()).filter(x => x),
86
114
  },
87
115
  });
88
116
  });
@@ -107,17 +135,25 @@ class Sftp {
107
135
  conn.end();
108
136
  return reject(err);
109
137
  }
110
- const writeStream = sftp.createWriteStream(remotePath + binaryData.fileName);
111
- writeStream.on('close', () => {
138
+ // const writeStream = sftp.createWriteStream(remotePath + binaryData.fileName);
139
+ // writeStream.on('close', () => {
140
+ // conn.end();
141
+ // resolve(true);
142
+ // });
143
+ // writeStream.on('error', (err: Error) => {
144
+ // conn.end();
145
+ // reject(err);
146
+ // });
147
+ // writeStream.write(fileBuffer);
148
+ // writeStream.end();
149
+ const fullPath = remotePath + binaryData.fileName;
150
+ sftp.writeFile(fullPath, fileBuffer, (err) => {
112
151
  conn.end();
152
+ if (err) {
153
+ return reject(err);
154
+ }
113
155
  resolve(true);
114
156
  });
115
- writeStream.on('error', (err) => {
116
- conn.end();
117
- reject(err);
118
- });
119
- writeStream.write(fileBuffer);
120
- writeStream.end();
121
157
  });
122
158
  });
123
159
  conn.on('error', (err) => {
@@ -129,7 +165,7 @@ class Sftp {
129
165
  username: credentials.username,
130
166
  password: credentials.password,
131
167
  algorithms: {
132
- serverHostKey: ['ssh-dss', 'ssh-rsa', 'ecdsa-sha2-nistp256'],
168
+ serverHostKey: credentials.algorithms.split(',').map(x => x.trim()).filter(x => x),
133
169
  },
134
170
  });
135
171
  });
@@ -143,6 +179,67 @@ class Sftp {
143
179
  return [returnData];
144
180
  }
145
181
  break;
182
+ case 'download':
183
+ const download_items = this.getInputData();
184
+ const download_returnData = [];
185
+ for (let i = 0; i < download_items.length; i++) {
186
+ const remoteFilePath = this.getNodeParameter('remoteFilePath', i);
187
+ const binaryPropertyOutput = this.getNodeParameter('binaryPropertyOutput', i);
188
+ const fileData = await new Promise((resolve, reject) => {
189
+ const conn = new ssh2_1.Client();
190
+ conn.on('ready', () => {
191
+ conn.sftp((err, sftp) => {
192
+ if (err) {
193
+ conn.end();
194
+ return reject(err);
195
+ }
196
+ const chunks = [];
197
+ const readStream = sftp.createReadStream(remoteFilePath);
198
+ readStream.on('data', (chunk) => {
199
+ chunks.push(chunk);
200
+ });
201
+ readStream.on('end', () => {
202
+ conn.end();
203
+ resolve(Buffer.concat(chunks));
204
+ });
205
+ readStream.on('error', (err) => {
206
+ conn.end();
207
+ reject(err);
208
+ });
209
+ });
210
+ });
211
+ conn.on('error', (err) => {
212
+ reject(err);
213
+ });
214
+ conn.connect({
215
+ host: credentials.host,
216
+ port: credentials.port || 22,
217
+ username: credentials.username,
218
+ password: credentials.password,
219
+ algorithms: {
220
+ serverHostKey: credentials.algorithms
221
+ .split(',')
222
+ .map(a => a.trim())
223
+ .filter(a => a),
224
+ },
225
+ });
226
+ });
227
+ const fileName = remoteFilePath.split('/').pop() || 'downloaded-file';
228
+ download_returnData.push({
229
+ json: {
230
+ fileName,
231
+ fileSize: fileData.length,
232
+ },
233
+ binary: {
234
+ [binaryPropertyOutput]: {
235
+ data: fileData.toString('base64'),
236
+ fileName,
237
+ mimeType: 'application/octet-stream',
238
+ },
239
+ },
240
+ });
241
+ }
242
+ return [download_returnData];
146
243
  }
147
244
  throw new Error(`Unknown Operation: ${operation}`);
148
245
  }
@@ -1,15 +1,71 @@
1
- <?xml version="1.0" encoding="utf-8"?>
1
+ <?xml version="1.0" encoding="iso-8859-1"?>
2
2
 
3
3
  <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
4
4
  <!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
5
- <svg height="800px" width="800px" version="1.1" id="_x32_" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
5
+ <svg version="1.1" id="_x35_" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
6
6
  viewBox="0 0 512 512" xml:space="preserve">
7
- <style type="text/css">
8
- .st0{fill:#000000;}
9
- </style>
10
7
  <g>
11
- <path class="st0" d="M0,17.067V153.6h512V17.067H0z M110.933,110.925h-51.2v-51.2h51.2V110.925z"/>
12
- <path class="st0" d="M0,324.267h512V187.733H0V324.267z M59.733,230.391h51.2v51.2h-51.2V230.391z"/>
13
- <path class="st0" d="M0,494.933h512V358.4H0V494.933z M59.733,401.058h51.2v51.2h-51.2V401.058z"/>
8
+ <g>
9
+ <path style="fill:#C191C0;" d="M148.413,10.054v387.402c0,5.519-4.536,10.056-10.056,10.056H10.056
10
+ C4.537,407.512,0,402.975,0,397.456V10.054C0,4.535,4.537,0,10.056,0h128.302C143.877,0,148.413,4.535,148.413,10.054z"/>
11
+ <path style="fill:#C191C0;" d="M96.848,244.003H51.57c-16.602,0-30.185-13.583-30.185-30.185V77.983
12
+ c0-16.602,13.583-30.185,30.185-30.185h45.278c16.602,0,30.185,13.583,30.185,30.185v135.834
13
+ C127.034,230.419,113.45,244.003,96.848,244.003z"/>
14
+ <path style="fill:#FFFFFF;" d="M112.57,244.003H35.849c-7.955,0-14.464-6.509-14.464-14.464V62.262
15
+ c0-7.955,6.509-14.464,14.464-14.464h76.721c7.955,0,14.464,6.509,14.464,14.464v167.277
16
+ C127.034,237.494,120.525,244.003,112.57,244.003z"/>
17
+ <g>
18
+ <path style="opacity:0.2;fill:#171716;" d="M74.209,384.194c-21.486,0-38.967-17.481-38.967-38.967
19
+ c0-21.486,17.481-38.967,38.967-38.967s38.967,17.481,38.967,38.967C113.176,366.714,95.696,384.194,74.209,384.194z"/>
20
+ <circle style="fill:#FFFFFF;" cx="74.209" cy="345.227" r="27.277"/>
21
+ </g>
22
+ <rect x="40.251" y="80.499" style="fill:#C191C0;" width="67.917" height="16.35"/>
23
+ <rect x="40.251" y="129.55" style="fill:#C191C0;" width="67.917" height="16.35"/>
24
+ <rect x="40.251" y="178.601" style="fill:#C191C0;" width="67.917" height="16.35"/>
25
+ <rect y="268.021" style="fill:#FFFFFF;" width="148.413" height="14.818"/>
26
+ <path style="fill:#ED7B84;" d="M330.169,10.054v387.402c0,5.519-4.461,10.056-10.055,10.056H191.886
27
+ c-5.595,0-10.056-4.537-10.056-10.056V10.054C181.831,4.535,186.292,0,191.886,0h128.227C325.708,0,330.169,4.535,330.169,10.054z
28
+ "/>
29
+ <path style="fill:#ED7B84;" d="M278.639,244.003h-45.278c-16.602,0-30.185-13.583-30.185-30.185V77.983
30
+ c0-16.602,13.583-30.185,30.185-30.185h45.278c16.602,0,30.185,13.583,30.185,30.185v135.834
31
+ C308.824,230.419,295.241,244.003,278.639,244.003z"/>
32
+ <path style="fill:#FFFFFF;" d="M294.36,244.003h-76.721c-7.955,0-14.464-6.509-14.464-14.464V62.262
33
+ c0-7.955,6.509-14.464,14.464-14.464h76.721c7.955,0,14.464,6.509,14.464,14.464v167.277
34
+ C308.824,237.494,302.315,244.003,294.36,244.003z"/>
35
+ <g>
36
+ <path style="opacity:0.2;fill:#171716;" d="M256,384.194c-21.486,0-38.967-17.481-38.967-38.967
37
+ c0-21.486,17.481-38.967,38.967-38.967c21.486,0,38.967,17.481,38.967,38.967C294.967,366.714,277.486,384.194,256,384.194z"/>
38
+ <circle style="fill:#FFFFFF;" cx="256" cy="345.227" r="27.277"/>
39
+ </g>
40
+ <rect x="222.041" y="80.499" style="fill:#ED7B84;" width="67.917" height="16.35"/>
41
+ <rect x="222.041" y="129.55" style="fill:#ED7B84;" width="67.917" height="16.35"/>
42
+ <rect x="222.041" y="178.601" style="fill:#ED7B84;" width="67.917" height="16.35"/>
43
+ <rect x="181.794" y="268.018" style="fill:#FFFFFF;" width="148.412" height="14.857"/>
44
+ <path style="fill:#77C7C1;" d="M512,10.054v387.402c0,5.519-4.537,10.056-10.056,10.056H373.642
45
+ c-5.519,0-10.055-4.537-10.055-10.056V10.054C363.587,4.535,368.123,0,373.642,0h128.303C507.463,0,512,4.535,512,10.054z"/>
46
+ <path style="fill:#77C7C1;" d="M460.429,244.003h-45.278c-16.602,0-30.185-13.583-30.185-30.185V77.983
47
+ c0-16.602,13.583-30.185,30.185-30.185h45.278c16.602,0,30.185,13.583,30.185,30.185v135.834
48
+ C490.615,230.419,477.031,244.003,460.429,244.003z"/>
49
+ <path style="fill:#FFFFFF;" d="M476.151,244.003H399.43c-7.955,0-14.464-6.509-14.464-14.464V62.262
50
+ c0-7.955,6.509-14.464,14.464-14.464h76.721c7.955,0,14.464,6.509,14.464,14.464v167.277
51
+ C490.615,237.494,484.106,244.003,476.151,244.003z"/>
52
+ <g>
53
+ <path style="opacity:0.2;fill:#171716;" d="M437.79,384.194c-21.486,0-38.967-17.481-38.967-38.967
54
+ c0-21.486,17.481-38.967,38.967-38.967c21.486,0,38.967,17.481,38.967,38.967C476.757,366.714,459.276,384.194,437.79,384.194z"
55
+ />
56
+ <circle style="fill:#FFFFFF;" cx="437.79" cy="345.227" r="27.277"/>
57
+ </g>
58
+ <rect x="403.832" y="80.499" style="fill:#77C7C1;" width="67.917" height="16.35"/>
59
+ <rect x="403.832" y="129.55" style="fill:#77C7C1;" width="67.917" height="16.35"/>
60
+ <rect x="403.832" y="178.601" style="fill:#77C7C1;" width="67.917" height="16.35"/>
61
+ <rect x="363.584" y="268.018" style="fill:#FFFFFF;" width="148.412" height="14.857"/>
62
+ </g>
63
+ <g style="opacity:0.08;">
64
+ <polygon style="fill:#040000;" points="148.415,407.507 148.415,311.341 52.248,407.507 "/>
65
+ <polygon style="fill:#040000;" points="181.794,282.874 181.794,407.507 330.206,407.507 330.206,282.874 330.206,268.017
66
+ 330.206,129.55 181.794,277.961 "/>
67
+ <polygon style="fill:#040000;" points="459.751,0.004 363.584,96.172 363.584,268.017 363.584,282.874 363.584,407.507
68
+ 511.996,407.507 511.996,282.874 511.996,268.017 511.996,0.004 "/>
69
+ </g>
14
70
  </g>
15
71
  </svg>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-sftp-custom",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "n8n node for SFTP with custom algorithms",
5
5
  "license": "MIT",
6
6
  "homepage": "https://github.com/Genevieve-Lee-221/n8n-nodes-sftp-custom",