mirror of
https://github.com/n8n-io/n8n.git
synced 2025-03-05 20:50:17 -08:00
fix(NextCloud Node): Fix folder list with Nextcloud v24 (#3386)
* initial fix for v24 folder listing * implemented new credential methods * Nodelinter fixes
This commit is contained in:
parent
ed69c3cc18
commit
5f3bed3d4e
|
@ -1,9 +1,11 @@
|
|||
import {
|
||||
ICredentialDataDecryptedObject,
|
||||
ICredentialTestRequest,
|
||||
ICredentialType,
|
||||
IHttpRequestOptions,
|
||||
INodeProperties,
|
||||
} from 'n8n-workflow';
|
||||
|
||||
|
||||
export class NextCloudApi implements ICredentialType {
|
||||
name = 'nextCloudApi';
|
||||
displayName = 'NextCloud API';
|
||||
|
@ -29,4 +31,18 @@ export class NextCloudApi implements ICredentialType {
|
|||
default: '',
|
||||
},
|
||||
];
|
||||
async authenticate(credentials: ICredentialDataDecryptedObject, requestOptions: IHttpRequestOptions): Promise<IHttpRequestOptions> {
|
||||
requestOptions.auth = {
|
||||
username: credentials.user as string,
|
||||
password: credentials.password as string,
|
||||
};
|
||||
return requestOptions;
|
||||
}
|
||||
test: ICredentialTestRequest = {
|
||||
request: {
|
||||
baseURL: '={{$credentials.webDavUrl.replace(\'/remote.php/webdav\', \'\')}}',
|
||||
url: '/ocs/v1.php/cloud/capabilities',
|
||||
headers: {'OCS-APIRequest': true},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
@ -2,7 +2,11 @@ import {
|
|||
IExecuteFunctions,
|
||||
IHookFunctions,
|
||||
} from 'n8n-core';
|
||||
import { NodeApiError, NodeOperationError, } from 'n8n-workflow';
|
||||
|
||||
import {
|
||||
JsonObject,
|
||||
NodeApiError,
|
||||
} from 'n8n-workflow';
|
||||
|
||||
import {
|
||||
OptionsWithUri,
|
||||
|
@ -20,8 +24,17 @@ import {
|
|||
export async function nextCloudApiRequest(this: IHookFunctions | IExecuteFunctions, method: string, endpoint: string, body: object | string | Buffer, headers?: object, encoding?: null | undefined, query?: object): Promise<any> { // tslint:disable-line:no-any
|
||||
const resource = this.getNodeParameter('resource', 0);
|
||||
const operation = this.getNodeParameter('operation', 0);
|
||||
const authenticationMethod = this.getNodeParameter('authentication', 0);
|
||||
|
||||
const options: OptionsWithUri = {
|
||||
let credentials;
|
||||
|
||||
if (authenticationMethod === 'accessToken') {
|
||||
credentials = await this.getCredentials('nextCloudApi') as { webDavUrl: string };
|
||||
} else {
|
||||
credentials = await this.getCredentials('nextCloudOAuth2Api') as { webDavUrl: string };
|
||||
}
|
||||
|
||||
let options: OptionsWithUri = {
|
||||
headers,
|
||||
method,
|
||||
body,
|
||||
|
@ -34,35 +47,16 @@ export async function nextCloudApiRequest(this: IHookFunctions | IExecuteFunctio
|
|||
options.encoding = null;
|
||||
}
|
||||
|
||||
const authenticationMethod = this.getNodeParameter('authentication', 0);
|
||||
options.uri = `${credentials.webDavUrl}/${encodeURI(endpoint)}`;
|
||||
if (resource === 'user' && operation === 'create') {
|
||||
options.uri = options.uri.replace('/remote.php/webdav', '');
|
||||
}
|
||||
|
||||
const credentialType = authenticationMethod === 'accessToken' ? 'nextCloudApi' : 'nextCloudOAuth2Api';
|
||||
|
||||
try {
|
||||
if (authenticationMethod === 'accessToken') {
|
||||
const credentials = await this.getCredentials('nextCloudApi');
|
||||
|
||||
options.auth = {
|
||||
user: credentials.user as string,
|
||||
pass: credentials.password as string,
|
||||
};
|
||||
|
||||
options.uri = `${credentials.webDavUrl}/${encodeURI(endpoint)}`;
|
||||
|
||||
if (resource === 'user' || operation === 'share') {
|
||||
options.uri = options.uri.replace('/remote.php/webdav', '');
|
||||
}
|
||||
return await this.helpers.request(options);
|
||||
} else {
|
||||
const credentials = await this.getCredentials('nextCloudOAuth2Api');
|
||||
|
||||
options.uri = `${credentials.webDavUrl}/${encodeURI(endpoint)}`;
|
||||
|
||||
if (resource === 'user' && operation === 'create') {
|
||||
options.uri = options.uri.replace('/remote.php/webdav', '');
|
||||
}
|
||||
|
||||
return await this.helpers.requestOAuth2!.call(this, 'nextCloudOAuth2Api', options);
|
||||
}
|
||||
} catch (error) {
|
||||
throw new NodeApiError(this.getNode(), error);
|
||||
return await this.helpers.requestWithAuthentication.call(this, credentialType, options);
|
||||
} catch(error) {
|
||||
throw new NodeApiError(this.getNode(), error as JsonObject);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { IExecuteFunctions } from 'n8n-core';
|
||||
import { NodeApiError } from 'n8n-workflow';
|
||||
|
||||
import {
|
||||
IDataObject,
|
||||
|
@ -22,7 +23,7 @@ export class NextCloud implements INodeType {
|
|||
description: INodeTypeDescription = {
|
||||
displayName: 'Nextcloud',
|
||||
name: 'nextCloud',
|
||||
icon: 'file:nextcloud.png',
|
||||
icon: 'file:nextcloud.svg',
|
||||
group: ['input'],
|
||||
version: 1,
|
||||
subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
|
||||
|
@ -305,7 +306,7 @@ export class NextCloud implements INodeType {
|
|||
},
|
||||
},
|
||||
placeholder: '/invoices/2019/invoice_1.pdf',
|
||||
description: 'The path to delete. Can be a single file or a whole folder. The path should start with "/"',
|
||||
description: 'The path to delete. Can be a single file or a whole folder. The path should start with "/".',
|
||||
},
|
||||
|
||||
// ----------------------------------
|
||||
|
@ -372,7 +373,7 @@ export class NextCloud implements INodeType {
|
|||
},
|
||||
},
|
||||
placeholder: '/invoices/2019/invoice_1.pdf',
|
||||
description: 'The file path of the file to download. Has to contain the full path. The path should start with "/"',
|
||||
description: 'The file path of the file to download. Has to contain the full path. The path should start with "/".',
|
||||
},
|
||||
{
|
||||
displayName: 'Binary Property',
|
||||
|
@ -499,7 +500,7 @@ export class NextCloud implements INodeType {
|
|||
},
|
||||
},
|
||||
placeholder: '/invoices/2019/invoice_1.pdf',
|
||||
description: 'The file path of the file to share. Has to contain the full path. The path should start with "/"',
|
||||
description: 'The file path of the file to share. Has to contain the full path. The path should start with "/".',
|
||||
},
|
||||
{
|
||||
displayName: 'Share Type',
|
||||
|
@ -720,7 +721,7 @@ export class NextCloud implements INodeType {
|
|||
},
|
||||
},
|
||||
placeholder: '/invoices/2019',
|
||||
description: 'The folder to create. The parent folder has to exist. The path should start with "/"',
|
||||
description: 'The folder to create. The parent folder has to exist. The path should start with "/".',
|
||||
},
|
||||
|
||||
// ----------------------------------
|
||||
|
@ -808,7 +809,7 @@ export class NextCloud implements INodeType {
|
|||
},
|
||||
options: [
|
||||
{
|
||||
displayName: 'Display name',
|
||||
displayName: 'Display Name',
|
||||
name: 'displayName',
|
||||
type: 'string',
|
||||
default: '',
|
||||
|
@ -1287,7 +1288,7 @@ export class NextCloud implements INodeType {
|
|||
}
|
||||
|
||||
if (data.ocs.meta.status !== 'ok') {
|
||||
return reject(new Error(data.ocs.meta.message || data.ocs.meta.status));
|
||||
return reject(new NodeApiError(this.getNode(), data.ocs.meta.message || data.ocs.meta.status));
|
||||
}
|
||||
|
||||
resolve(data.ocs.data as IDataObject);
|
||||
|
@ -1307,7 +1308,7 @@ export class NextCloud implements INodeType {
|
|||
}
|
||||
|
||||
if (data.ocs.meta.status !== 'ok') {
|
||||
return reject(new Error(data.ocs.meta.message || data.ocs.meta.status));
|
||||
return reject(new NodeApiError(this.getNode(), data.ocs.meta.message || data.ocs.meta.status));
|
||||
}
|
||||
|
||||
if (operation === 'delete' || operation === 'update') {
|
||||
|
@ -1328,7 +1329,7 @@ export class NextCloud implements INodeType {
|
|||
}
|
||||
|
||||
if (data.ocs.meta.status !== 'ok') {
|
||||
return reject(new Error(data.ocs.meta.message));
|
||||
return reject(new NodeApiError(this.getNode(), data.ocs.meta.message));
|
||||
}
|
||||
|
||||
if (typeof (data.ocs.data.users.element) === 'string') {
|
||||
|
@ -1366,7 +1367,6 @@ export class NextCloud implements INodeType {
|
|||
(jsonResponseData['d:multistatus'] as IDataObject)['d:response'] !== undefined &&
|
||||
(jsonResponseData['d:multistatus'] as IDataObject)['d:response'] !== null) {
|
||||
let skippedFirst = false;
|
||||
|
||||
// @ts-ignore
|
||||
if (Array.isArray(jsonResponseData['d:multistatus']['d:response'])) {
|
||||
// @ts-ignore
|
||||
|
@ -1379,7 +1379,12 @@ export class NextCloud implements INodeType {
|
|||
|
||||
newItem.path = item['d:href'].slice(19);
|
||||
|
||||
const props = item['d:propstat'][0]['d:prop'];
|
||||
let props: IDataObject = {};
|
||||
if (Array.isArray(item['d:propstat'])) {
|
||||
props = item['d:propstat'][0]['d:prop'] as IDataObject;
|
||||
} else {
|
||||
props = item['d:propstat']['d:prop'] as IDataObject;
|
||||
}
|
||||
|
||||
// Get the props and save them under a proper name
|
||||
for (const propName of Object.keys(propNames)) {
|
||||
|
@ -1393,6 +1398,7 @@ export class NextCloud implements INodeType {
|
|||
} else {
|
||||
newItem.type = 'folder';
|
||||
}
|
||||
// @ts-ignore
|
||||
newItem.eTag = props['d:getetag'].slice(1, -1);
|
||||
|
||||
returnData.push(newItem as IDataObject);
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 828 B |
1
packages/nodes-base/nodes/NextCloud/nextcloud.svg
Normal file
1
packages/nodes-base/nodes/NextCloud/nextcloud.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 76 51" fill="#fff" fill-rule="evenodd" stroke="#000" stroke-linecap="round" stroke-linejoin="round"><use xlink:href="#A" x=".5" y=".5"/><symbol id="A" overflow="visible"><path d="M37.533 0c-7.77 0-14.355 5.268-16.396 12.379-1.778-3.819-5.597-6.453-10.075-6.453C5.004 5.926 0 10.931 0 17.054a11.16 11.16 0 0 0 11.128 11.128c4.412 0 8.297-2.634 10.075-6.453a16.99 16.99 0 0 0 16.33 12.379c7.704 0 14.289-5.202 16.396-12.248 1.778 3.687 5.597 6.256 9.943 6.256A11.16 11.16 0 0 0 75 16.989c0-6.124-5.004-11.062-11.128-11.062-4.346 0-8.165 2.568-9.943 6.256C51.822 5.202 45.303 0 37.533 0zm0 6.519a10.48 10.48 0 0 1 10.535 10.536A10.48 10.48 0 0 1 37.533 27.59a10.48 10.48 0 0 1-10.536-10.535A10.48 10.48 0 0 1 37.533 6.519zm-26.405 5.926a4.58 4.58 0 0 1 4.609 4.609 4.58 4.58 0 0 1-4.609 4.609 4.58 4.58 0 0 1-4.609-4.609 4.58 4.58 0 0 1 4.609-4.609zm52.744 0a4.58 4.58 0 0 1 4.609 4.609 4.609 4.609 0 1 1-9.218 0c.066-2.568 2.041-4.609 4.609-4.609zM19.176 41.957c1.827 0 2.85 1.301 2.85 3.252 0 .186-.155.341-.341.341H16.76c.031 1.734 1.239 2.726 2.633 2.726a2.89 2.89 0 0 0 1.796-.619c.186-.124.341-.093.434.093l.093.155c.093.155.062.31-.093.434a3.84 3.84 0 0 1-2.261.743c-2.013 0-3.562-1.456-3.562-3.562.031-2.23 1.518-3.562 3.376-3.562zm1.889 2.911c-.062-1.425-.929-2.137-1.92-2.137-1.146 0-2.137.743-2.354 2.137h4.274zm10.253-1.92v-.774-1.611c0-.217.124-.341.341-.341h.248c.217 0 .31.124.31.341v1.611h1.394c.217 0 .341.124.341.341v.093c0 .217-.124.31-.341.31h-1.394v3.407c0 1.58.96 1.766 1.487 1.796.279.031.372.093.372.341v.186c0 .217-.093.31-.372.31-1.487 0-2.385-.898-2.385-2.509v-3.5zm7.093-.991c1.177 0 1.92.496 2.261.774.155.124.186.279.031.465l-.093.155c-.124.186-.279.186-.465.062-.31-.217-.898-.619-1.703-.619-1.487 0-2.664 1.115-2.664 2.757 0 1.611 1.177 2.726 2.664 2.726.96 0 1.611-.434 1.92-.712.186-.124.31-.093.434.093l.093.124c.093.186.062.31-.093.465a3.81 3.81 0 0 1-2.416.867c-2.013 0-3.562-1.456-3.562-3.562.031-2.106 1.58-3.593 3.593-3.593zm4.119-2.199c0-.217-.124-.341.093-.341h.248c.217 0 .558.124.558.341v7.403c0 .867.403.96.712.991.155 0 .279.093.279.31v.217c0 .217-.093.341-.341.341-.557 0-1.549-.186-1.549-1.673v-7.589zm6.35 2.199c1.982 0 3.593 1.518 3.593 3.531 0 2.044-1.611 3.593-3.593 3.593s-3.593-1.549-3.593-3.593c0-2.013 1.611-3.531 3.593-3.531zm0 6.319c1.456 0 2.633-1.177 2.633-2.788 0-1.549-1.177-2.695-2.633-2.695a2.67 2.67 0 0 0-2.664 2.695c.031 1.58 1.208 2.788 2.664 2.788zm15.456-6.319a2.45 2.45 0 0 1 2.23 1.363h.031s-.031-.217-.031-.526v-3.066c0-.217-.093-.341.124-.341h.248c.217 0 .558.124.558.341v8.827c0 .217-.093.341-.31.341h-.217c-.217 0-.341-.093-.341-.31v-.527c0-.248.062-.434.062-.434h-.031s-.589 1.425-2.354 1.425c-1.827 0-2.973-1.456-2.973-3.562-.062-2.106 1.208-3.531 3.004-3.531h0zm.031 6.319c1.146 0 2.199-.805 2.199-2.757 0-1.394-.712-2.726-2.168-2.726-1.208 0-2.199.991-2.199 2.726.031 1.673.898 2.757 2.168 2.757zm-56.558.65h.248c.217 0 .341-.124.341-.341v-6.628c0-1.053 1.146-1.796 2.447-1.796s2.447.743 2.447 1.796v6.659c0 .217.124.341.341.341h.248c.217 0 .31-.124.31-.341v-6.721c0-1.766-1.765-2.633-3.376-2.633h0 0 0 0c-1.549 0-3.314.867-3.314 2.633v6.69c0 .217.093.341.31.341zm51.695-6.814h-.248c-.217 0-.341.124-.341.341v3.748c0 1.053-.681 2.013-2.013 2.013-1.301 0-2.013-.96-2.013-2.013v-3.748c0-.217-.124-.341-.341-.341H54.3c-.217 0-.31.124-.31.341v3.996c0 1.765 1.301 2.633 2.912 2.633h0 0 0 0c1.611 0 2.911-.867 2.911-2.633v-3.996c.031-.217-.093-.341-.31-.341h0zm-30.664-.031c-.062 0-.155.062-.217.155l-1.239 1.487-.929 1.115-1.425-1.704-.774-.929c-.062-.093-.155-.124-.217-.124s-.155.031-.248.093l-.186.155c-.155.124-.155.279-.031.465l1.239 1.487 1.053 1.239-1.518 1.827h0l-.774.929c-.124.155-.124.341.031.496l.186.155c.155.124.31.093.465-.062l1.239-1.487.929-1.115 1.425 1.704h0l.774.929c.124.155.31.186.465.031l.186-.155c.155-.124.155-.279.031-.465l-1.239-1.487-1.053-1.239 1.518-1.827h0l.774-.929c.124-.155.124-.341-.031-.495l-.186-.186c-.093-.062-.155-.093-.248-.062h0z" fill="#0082c9" fill-rule="nonzero" stroke="none"/></symbol></svg>
|
After Width: | Height: | Size: 4 KiB |
Loading…
Reference in a new issue