Merge pull request #792 from n8n-io/Dropbox-OAuth2-Support

Dropbox o auth2 support
This commit is contained in:
Ricardo Espinoza 2020-07-23 21:24:39 -04:00 committed by GitHub
commit 546995aa4f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 167 additions and 53 deletions

View file

@ -3,7 +3,6 @@ import {
NodePropertyTypes,
} from 'n8n-workflow';
export class DropboxApi implements ICredentialType {
name = 'dropboxApi';
displayName = 'Dropbox API';

View file

@ -0,0 +1,47 @@
import {
ICredentialType,
NodePropertyTypes,
} from 'n8n-workflow';
export class DropboxOAuth2Api implements ICredentialType {
name = 'dropboxOAuth2Api';
extends = [
'oAuth2Api',
];
displayName = 'Dropbox OAuth2 API';
properties = [
{
displayName: 'Authorization URL',
name: 'authUrl',
type: 'hidden' as NodePropertyTypes,
default: 'https://www.dropbox.com/oauth2/authorize',
required: true,
},
{
displayName: 'Access Token URL',
name: 'accessTokenUrl',
type: 'hidden' as NodePropertyTypes,
default: 'https://api.dropboxapi.com/oauth2/token',
required: true,
},
{
displayName: 'Scope',
name: 'scope',
type: 'hidden' as NodePropertyTypes,
default: '',
},
{
displayName: 'Auth URI Query Parameters',
name: 'authQueryParameters',
type: 'hidden' as NodePropertyTypes,
default: '',
},
{
displayName: 'Authentication',
name: 'authentication',
type: 'hidden' as NodePropertyTypes,
default: 'header',
},
];
}

View file

@ -11,8 +11,8 @@ import {
} from 'n8n-workflow';
import {
OptionsWithUri
} from 'request';
dropboxApiRequest
} from './GenericFunctions';
export class Dropbox implements INodeType {
description: INodeTypeDescription = {
@ -25,7 +25,7 @@ export class Dropbox implements INodeType {
description: 'Access data on Dropbox',
defaults: {
name: 'Dropbox',
color: '#0061FF',
color: '#0062ff',
},
inputs: ['main'],
outputs: ['main'],
@ -33,9 +33,44 @@ export class Dropbox implements INodeType {
{
name: 'dropboxApi',
required: true,
}
displayOptions: {
show: {
authentication: [
'accessToken',
],
},
},
},
{
name: 'dropboxOAuth2Api',
required: true,
displayOptions: {
show: {
authentication: [
'oAuth2',
],
},
},
},
],
properties: [
{
displayName: 'Authentication',
name: 'authentication',
type: 'options',
options: [
{
name: 'Access Token',
value: 'accessToken',
},
{
name: 'OAuth2',
value: 'oAuth2',
}
],
default: 'accessToken',
description: 'Means of authenticating with the service.',
},
{
displayName: 'Resource',
name: 'resource',
@ -443,11 +478,6 @@ export class Dropbox implements INodeType {
const items = this.getInputData();
const returnData: IDataObject[] = [];
const credentials = this.getCredentials('dropboxApi');
if (credentials === undefined) {
throw new Error('No credentials got returned!');
}
const resource = this.getNodeParameter('resource', 0) as string;
const operation = this.getNodeParameter('operation', 0) as string;
@ -455,16 +485,13 @@ export class Dropbox implements INodeType {
let endpoint = '';
let requestMethod = '';
let body: IDataObject | Buffer;
let isJson = false;
let query: IDataObject = {};
let options;
const query: IDataObject = {};
let headers: IDataObject;
const headers: IDataObject = {};
for (let i = 0; i < items.length; i++) {
body = {};
headers = {
'Authorization': `Bearer ${credentials.accessToken}`,
};
if (resource === 'file') {
if (operation === 'download') {
@ -496,6 +523,9 @@ export class Dropbox implements INodeType {
endpoint = 'https://content.dropboxapi.com/2/files/upload';
if (this.getNodeParameter('binaryData', i) === true) {
options = { json: false };
// Is binary file to upload
const item = items[i];
@ -523,7 +553,6 @@ export class Dropbox implements INodeType {
// ----------------------------------
requestMethod = 'POST';
isJson = true;
body = {
path: this.getNodeParameter('path', i) as string,
};
@ -536,7 +565,6 @@ export class Dropbox implements INodeType {
// ----------------------------------
requestMethod = 'POST';
isJson = true;
body = {
path: this.getNodeParameter('path', i) as string,
limit: 2000,
@ -556,7 +584,6 @@ export class Dropbox implements INodeType {
// ----------------------------------
requestMethod = 'POST';
isJson = true;
body = {
from_path: this.getNodeParameter('path', i) as string,
to_path: this.getNodeParameter('toPath', i) as string,
@ -570,7 +597,6 @@ export class Dropbox implements INodeType {
// ----------------------------------
requestMethod = 'POST';
isJson = true;
body = {
path: this.getNodeParameter('path', i) as string,
};
@ -583,7 +609,6 @@ export class Dropbox implements INodeType {
// ----------------------------------
requestMethod = 'POST';
isJson = true;
body = {
from_path: this.getNodeParameter('path', i) as string,
to_path: this.getNodeParameter('toPath', i) as string,
@ -595,40 +620,15 @@ export class Dropbox implements INodeType {
throw new Error(`The resource "${resource}" is not known!`);
}
const options: OptionsWithUri = {
headers,
method: requestMethod,
uri: endpoint,
qs: query,
json: isJson,
};
if (Object.keys(body).length) {
options.body = body;
}
if (resource === 'file' && operation === 'download') {
// Return the data as a buffer
options.encoding = null;
options = { encoding: null };
}
let responseData;
try {
responseData = await this.helpers.request(options);
} catch (error) {
if (error.statusCode === 401) {
// Return a clear error
throw new Error('The Dropbox credentials are not valid!');
}
let responseData = await dropboxApiRequest.call(this, requestMethod, endpoint, body, query, headers, options);
if (error.error && error.error.error_summary) {
// Try to return the error prettier
throw new Error(`Dropbox error response [${error.statusCode}]: ${error.error.error_summary}`);
}
// If that data does not exist for some reason return the actual error
throw error;
if (resource === 'file' && operation === 'upload') {
responseData = JSON.parse(responseData);
}
if (resource === 'file' && operation === 'download') {
@ -650,7 +650,7 @@ export class Dropbox implements INodeType {
const dataPropertyNameDownload = this.getNodeParameter('binaryPropertyName', i) as string;
const filePathDownload = this.getNodeParameter('path', i) as string;
items[i].binary![dataPropertyNameDownload] = await this.helpers.prepareBinaryData(responseData, filePathDownload);
items[i].binary![dataPropertyNameDownload] = await this.helpers.prepareBinaryData(Buffer.from(responseData), filePathDownload);
} else if (resource === 'folder' && operation === 'list') {
@ -677,8 +677,6 @@ export class Dropbox implements INodeType {
returnData.push(newItem as IDataObject);
}
} else if (resource === 'file' && operation === 'upload') {
returnData.push(JSON.parse(responseData) as IDataObject);
} else {
returnData.push(responseData as IDataObject);
}

View file

@ -0,0 +1,69 @@
import {
IExecuteFunctions,
IHookFunctions,
} from 'n8n-core';
import {
OptionsWithUri,
} from 'request';
import {
IDataObject,
} from 'n8n-workflow';
/**
* Make an API request to Dropbox
*
* @param {IHookFunctions} this
* @param {string} method
* @param {string} url
* @param {object} body
* @returns {Promise<any>}
*/
export async function dropboxApiRequest(this: IHookFunctions | IExecuteFunctions, method: string, endpoint: string, body: object, query: IDataObject = {}, headers?: object, option: IDataObject = {}): Promise<any> {// tslint:disable-line:no-any
const options: OptionsWithUri = {
headers,
method,
qs: query,
body,
uri: endpoint,
json: true,
};
if (!Object.keys(body).length) {
delete options.body;
}
Object.assign(options, option);
const authenticationMethod = this.getNodeParameter('authentication', 0) as string;
try {
if (authenticationMethod === 'accessToken') {
const credentials = this.getCredentials('dropboxApi') as IDataObject;
options.headers!['Authorization'] = `Bearer ${credentials.accessToken}`;
return await this.helpers.request(options);
} else {
return await this.helpers.requestOAuth2.call(this, 'dropboxOAuth2Api', options);
}
} catch (error) {
if (error.statusCode === 401) {
// Return a clear error
throw new Error('The Dropbox credentials are not valid!');
}
if (error.error && error.error.error_summary) {
// Try to return the error prettier
throw new Error(
`Dropbox error response [${error.statusCode}]: ${error.error.error_summary}`
);
}
// If that data does not exist for some reason return the actual error
throw error;
}
}

View file

@ -52,6 +52,7 @@
"dist/credentials/DriftApi.credentials.js",
"dist/credentials/DriftOAuth2Api.credentials.js",
"dist/credentials/DropboxApi.credentials.js",
"dist/credentials/DropboxOAuth2Api.credentials.js",
"dist/credentials/EventbriteApi.credentials.js",
"dist/credentials/EventbriteOAuth2Api.credentials.js",
"dist/credentials/FacebookGraphApi.credentials.js",