mirror of
https://github.com/n8n-io/n8n.git
synced 2025-01-12 05:17:28 -08:00
fix(SSH Node): Replace ~ with /home/username (#6269)
This commit is contained in:
parent
a1b1f24ddf
commit
421949067b
|
@ -5,7 +5,7 @@ import type {
|
||||||
INodeType,
|
INodeType,
|
||||||
INodeTypeDescription,
|
INodeTypeDescription,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
import { BINARY_ENCODING } from 'n8n-workflow';
|
import { BINARY_ENCODING, NodeOperationError } from 'n8n-workflow';
|
||||||
|
|
||||||
import { rm, writeFile } from 'fs/promises';
|
import { rm, writeFile } from 'fs/promises';
|
||||||
|
|
||||||
|
@ -15,6 +15,35 @@ import type { Config } from 'node-ssh';
|
||||||
import { NodeSSH } from 'node-ssh';
|
import { NodeSSH } from 'node-ssh';
|
||||||
import type { Readable } from 'stream';
|
import type { Readable } from 'stream';
|
||||||
|
|
||||||
|
async function resolveHomeDir(
|
||||||
|
this: IExecuteFunctions,
|
||||||
|
path: string,
|
||||||
|
ssh: NodeSSH,
|
||||||
|
itemIndex: number,
|
||||||
|
) {
|
||||||
|
if (path.startsWith('~/')) {
|
||||||
|
let homeDir = (await ssh.execCommand('echo $HOME')).stdout;
|
||||||
|
|
||||||
|
if (homeDir.charAt(homeDir.length - 1) !== '/') {
|
||||||
|
homeDir += '/';
|
||||||
|
}
|
||||||
|
|
||||||
|
return path.replace('~/', homeDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (path.startsWith('~')) {
|
||||||
|
throw new NodeOperationError(
|
||||||
|
this.getNode(),
|
||||||
|
'Invalid path. Replace "~" with home directory or "~/"',
|
||||||
|
{
|
||||||
|
itemIndex,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
export class Ssh implements INodeType {
|
export class Ssh implements INodeType {
|
||||||
description: INodeTypeDescription = {
|
description: INodeTypeDescription = {
|
||||||
displayName: 'SSH',
|
displayName: 'SSH',
|
||||||
|
@ -226,7 +255,7 @@ export class Ssh implements INodeType {
|
||||||
displayOptions: {
|
displayOptions: {
|
||||||
show: {
|
show: {
|
||||||
resource: ['file'],
|
resource: ['file'],
|
||||||
operation: ['upload'],
|
operation: ['upload', 'download'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
default: {},
|
default: {},
|
||||||
|
@ -292,7 +321,12 @@ export class Ssh implements INodeType {
|
||||||
if (resource === 'command') {
|
if (resource === 'command') {
|
||||||
if (operation === 'execute') {
|
if (operation === 'execute') {
|
||||||
const command = this.getNodeParameter('command', i) as string;
|
const command = this.getNodeParameter('command', i) as string;
|
||||||
const cwd = this.getNodeParameter('cwd', i) as string;
|
const cwd = await resolveHomeDir.call(
|
||||||
|
this,
|
||||||
|
this.getNodeParameter('cwd', i) as string,
|
||||||
|
ssh,
|
||||||
|
i,
|
||||||
|
);
|
||||||
returnItems.push({
|
returnItems.push({
|
||||||
json: (await ssh.execCommand(command, { cwd })) as unknown as IDataObject,
|
json: (await ssh.execCommand(command, { cwd })) as unknown as IDataObject,
|
||||||
pairedItem: {
|
pairedItem: {
|
||||||
|
@ -305,7 +339,12 @@ export class Ssh implements INodeType {
|
||||||
if (resource === 'file') {
|
if (resource === 'file') {
|
||||||
if (operation === 'download') {
|
if (operation === 'download') {
|
||||||
const dataPropertyNameDownload = this.getNodeParameter('binaryPropertyName', i);
|
const dataPropertyNameDownload = this.getNodeParameter('binaryPropertyName', i);
|
||||||
const parameterPath = this.getNodeParameter('path', i) as string;
|
const parameterPath = await resolveHomeDir.call(
|
||||||
|
this,
|
||||||
|
this.getNodeParameter('path', i) as string,
|
||||||
|
ssh,
|
||||||
|
i,
|
||||||
|
);
|
||||||
|
|
||||||
const { path } = await tmpFile({ prefix: 'n8n-ssh-' });
|
const { path } = await tmpFile({ prefix: 'n8n-ssh-' });
|
||||||
temporaryFiles.push(path);
|
temporaryFiles.push(path);
|
||||||
|
@ -329,14 +368,20 @@ export class Ssh implements INodeType {
|
||||||
|
|
||||||
items[i] = newItem;
|
items[i] = newItem;
|
||||||
|
|
||||||
|
const fileName = this.getNodeParameter('options.fileName', i, '') as string;
|
||||||
items[i].binary![dataPropertyNameDownload] = await this.nodeHelpers.copyBinaryFile(
|
items[i].binary![dataPropertyNameDownload] = await this.nodeHelpers.copyBinaryFile(
|
||||||
path,
|
path,
|
||||||
parameterPath,
|
fileName || parameterPath,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (operation === 'upload') {
|
if (operation === 'upload') {
|
||||||
const parameterPath = this.getNodeParameter('path', i) as string;
|
const parameterPath = await resolveHomeDir.call(
|
||||||
|
this,
|
||||||
|
this.getNodeParameter('path', i) as string,
|
||||||
|
ssh,
|
||||||
|
i,
|
||||||
|
);
|
||||||
const fileName = this.getNodeParameter('options.fileName', i, '') as string;
|
const fileName = this.getNodeParameter('options.fileName', i, '') as string;
|
||||||
|
|
||||||
const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i);
|
const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i);
|
||||||
|
|
Loading…
Reference in a new issue