diff --git a/packages/nodes-base/credentials/HubspotOAuth2Api.credentials.ts b/packages/nodes-base/credentials/HubspotOAuth2Api.credentials.ts new file mode 100644 index 0000000000..775211cbc9 --- /dev/null +++ b/packages/nodes-base/credentials/HubspotOAuth2Api.credentials.ts @@ -0,0 +1,59 @@ +import { + ICredentialType, + NodePropertyTypes, +} from 'n8n-workflow'; + +export class HubspotOAuth2Api implements ICredentialType { + name = 'hubspotOAuth2Api'; + extends = [ + 'oAuth2Api', + ]; + displayName = 'Hubspot OAuth2 API'; + properties = [ + { + displayName: 'Authorization URL', + name: 'authUrl', + type: 'hidden' as NodePropertyTypes, + default: 'https://app.hubspot.com/oauth/authorize', + required: true, + }, + { + displayName: 'Access Token URL', + name: 'accessTokenUrl', + type: 'hidden' as NodePropertyTypes, + default: 'https://api.hubapi.com/oauth/v1/token', + required: true, + }, + { + displayName: 'Scope', + name: 'scope', + type: 'string' as NodePropertyTypes, + default: '', + }, + { + displayName: 'Auth URI Query Parameters', + name: 'authQueryParameters', + type: 'hidden' as NodePropertyTypes, + default: 'grant_type=authorization_code', + }, + { + displayName: 'Authentication', + name: 'authentication', + type: 'options' as NodePropertyTypes, + options: [ + { + name: 'Body', + value: 'body', + description: 'Send credentials in body', + }, + { + name: 'Header', + value: 'header', + description: 'Send credentials as Basic Auth header', + }, + ], + default: 'header', + description: 'Resource to consume.', + }, + ]; +} diff --git a/packages/nodes-base/nodes/Hubspot/GenericFunctions.ts b/packages/nodes-base/nodes/Hubspot/GenericFunctions.ts index 969c392cdd..eb414b82aa 100644 --- a/packages/nodes-base/nodes/Hubspot/GenericFunctions.ts +++ b/packages/nodes-base/nodes/Hubspot/GenericFunctions.ts @@ -14,12 +14,8 @@ import { } from 'n8n-workflow'; export async function hubspotApiRequest(this: IHookFunctions | IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, method: string, endpoint: string, body: any = {}, query: IDataObject = {}, uri?: string): Promise { // tslint:disable-line:no-any + const authenticationMethod = this.getNodeParameter('authentication', 0); - const node = this.getNode(); - const credentialName = Object.keys(node.credentials!)[0]; - const credentials = this.getCredentials(credentialName); - - query!.hapikey = credentials!.apiKey as string; const options: OptionsWithUri = { method, qs: query, @@ -28,8 +24,18 @@ export async function hubspotApiRequest(this: IHookFunctions | IExecuteFunctions json: true, useQuerystring: true, }; + try { - return await this.helpers.request!(options); + if (authenticationMethod === 'accessToken') { + const credentials = this.getCredentials('hubspotApi'); + + options.qs.hapikey = credentials!.apiKey as string; + + return await this.helpers.request!(options); + } else { + // @ts-ignore + return await this.helpers.requestOAuth2!.call(this, 'hubspotOAuth2Api', options, 'Bearer'); + } } catch (error) { if (error.response && error.response.body && error.response.body.errors) { // Try to return the error prettier diff --git a/packages/nodes-base/nodes/Hubspot/Hubspot.node.ts b/packages/nodes-base/nodes/Hubspot/Hubspot.node.ts index 6c1d7be400..bed4606042 100644 --- a/packages/nodes-base/nodes/Hubspot/Hubspot.node.ts +++ b/packages/nodes-base/nodes/Hubspot/Hubspot.node.ts @@ -73,9 +73,44 @@ export class Hubspot implements INodeType { { name: 'hubspotApi', required: true, - } + displayOptions: { + show: { + authentication: [ + 'accessToken', + ], + }, + }, + }, + { + name: 'hubspotOAuth2Api', + 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: 'The method of authentication.', + }, { displayName: 'Resource', name: 'resource', diff --git a/packages/nodes-base/nodes/Hubspot/HubspotTrigger.node.ts b/packages/nodes-base/nodes/Hubspot/HubspotTrigger.node.ts index 25028f88e8..38fd678d58 100644 --- a/packages/nodes-base/nodes/Hubspot/HubspotTrigger.node.ts +++ b/packages/nodes-base/nodes/Hubspot/HubspotTrigger.node.ts @@ -37,6 +37,24 @@ export class HubspotTrigger implements INodeType { { name: 'hubspotDeveloperApi', required: true, + displayOptions: { + show: { + authentication: [ + 'developerApi', + ], + }, + }, + }, + { + name: 'hubspotOAuth2Api', + required: true, + displayOptions: { + show: { + authentication: [ + 'oAuth2', + ], + }, + }, }, ], webhooks: [ @@ -54,6 +72,23 @@ export class HubspotTrigger implements INodeType { }, ], properties: [ + { + displayName: 'Authentication', + name: 'authentication', + type: 'options', + options: [ + { + name: 'Developer API', + value: 'developerApi', + }, + { + name: 'OAuth2', + value: 'oAuth2', + }, + ], + default: 'developerApi', + description: 'The method of authentication.', + }, { displayName: 'App ID', name: 'appId', @@ -246,7 +281,21 @@ export class HubspotTrigger implements INodeType { }; async webhook(this: IWebhookFunctions): Promise { - const credentials = this.getCredentials('hubspotDeveloperApi'); + + const authenticationMethod = this.getNodeParameter('authentication') as string; + + let credentials : IDataObject; + + if (authenticationMethod === 'hubspotDeveloperApi') { + credentials = this.getCredentials('hubspotDeveloperApi') as IDataObject; + } else { + credentials = this.getCredentials('hubspotOAuth2Api') as IDataObject; + } + + if (credentials === undefined) { + throw new Error('No credentials found!'); + } + const req = this.getRequestObject(); const bodyData = req.body; const headerData = this.getHeaderData(); diff --git a/packages/nodes-base/package.json b/packages/nodes-base/package.json index 8a3c76c261..7b90d3e2a9 100644 --- a/packages/nodes-base/package.json +++ b/packages/nodes-base/package.json @@ -356,11 +356,340 @@ "/dist/", "/node_modules/" ], - "moduleFileExtensions": [ - "ts", - "tsx", - "js", - "json" - ] - } + "n8n": { + "credentials": [ + "dist/credentials/ActiveCampaignApi.credentials.js", + "dist/credentials/AgileCrmApi.credentials.js", + "dist/credentials/AcuitySchedulingApi.credentials.js", + "dist/credentials/AirtableApi.credentials.js", + "dist/credentials/Amqp.credentials.js", + "dist/credentials/AsanaApi.credentials.js", + "dist/credentials/Aws.credentials.js", + "dist/credentials/AffinityApi.credentials.js", + "dist/credentials/BannerbearApi.credentials.js", + "dist/credentials/BitbucketApi.credentials.js", + "dist/credentials/BitlyApi.credentials.js", + "dist/credentials/ChargebeeApi.credentials.js", + "dist/credentials/ClearbitApi.credentials.js", + "dist/credentials/ClickUpApi.credentials.js", + "dist/credentials/ClockifyApi.credentials.js", + "dist/credentials/CockpitApi.credentials.js", + "dist/credentials/CodaApi.credentials.js", + "dist/credentials/CopperApi.credentials.js", + "dist/credentials/CalendlyApi.credentials.js", + "dist/credentials/DisqusApi.credentials.js", + "dist/credentials/DriftApi.credentials.js", + "dist/credentials/DropboxApi.credentials.js", + "dist/credentials/EventbriteApi.credentials.js", + "dist/credentials/FacebookGraphApi.credentials.js", + "dist/credentials/FreshdeskApi.credentials.js", + "dist/credentials/FileMaker.credentials.js", + "dist/credentials/FlowApi.credentials.js", + "dist/credentials/GithubApi.credentials.js", + "dist/credentials/GithubOAuth2Api.credentials.js", + "dist/credentials/GitlabApi.credentials.js", + "dist/credentials/GoogleApi.credentials.js", + "dist/credentials/GoogleCalendarOAuth2Api.credentials.js", + "dist/credentials/GoogleOAuth2Api.credentials.js", + "dist/credentials/GoogleSheetsOAuth2Api.credentials.js", + "dist/credentials/GumroadApi.credentials.js", + "dist/credentials/HarvestApi.credentials.js", + "dist/credentials/HelpScoutOAuth2Api.credentials.js", + "dist/credentials/HttpBasicAuth.credentials.js", + "dist/credentials/HttpDigestAuth.credentials.js", + "dist/credentials/HttpHeaderAuth.credentials.js", + "dist/credentials/HubspotApi.credentials.js", + "dist/credentials/HubspotDeveloperApi.credentials.js", + "dist/credentials/HubspotOAuth2Api.credentials.js", + "dist/credentials/HunterApi.credentials.js", + "dist/credentials/Imap.credentials.js", + "dist/credentials/IntercomApi.credentials.js", + "dist/credentials/InvoiceNinjaApi.credentials.js", + "dist/credentials/JiraSoftwareCloudApi.credentials.js", + "dist/credentials/JiraSoftwareServerApi.credentials.js", + "dist/credentials/JotFormApi.credentials.js", + "dist/credentials/KeapOAuth2Api.credentials.js", + "dist/credentials/LinkFishApi.credentials.js", + "dist/credentials/MailchimpApi.credentials.js", + "dist/credentials/MailgunApi.credentials.js", + "dist/credentials/MailjetEmailApi.credentials.js", + "dist/credentials/MailjetSmsApi.credentials.js", + "dist/credentials/MandrillApi.credentials.js", + "dist/credentials/MattermostApi.credentials.js", + "dist/credentials/MauticApi.credentials.js", + "dist/credentials/MicrosoftExcelOAuth2Api.credentials.js", + "dist/credentials/MicrosoftOAuth2Api.credentials.js", + "dist/credentials/MicrosoftOneDriveOAuth2Api.credentials.js", + "dist/credentials/MoceanApi.credentials.js", + "dist/credentials/MondayComApi.credentials.js", + "dist/credentials/MongoDb.credentials.js", + "dist/credentials/Msg91Api.credentials.js", + "dist/credentials/MySql.credentials.js", + "dist/credentials/NextCloudApi.credentials.js", + "dist/credentials/OAuth1Api.credentials.js", + "dist/credentials/OAuth2Api.credentials.js", + "dist/credentials/OpenWeatherMapApi.credentials.js", + "dist/credentials/PagerDutyApi.credentials.js", + "dist/credentials/PayPalApi.credentials.js", + "dist/credentials/PipedriveApi.credentials.js", + "dist/credentials/Postgres.credentials.js", + "dist/credentials/Redis.credentials.js", + "dist/credentials/RocketchatApi.credentials.js", + "dist/credentials/RundeckApi.credentials.js", + "dist/credentials/ShopifyApi.credentials.js", + "dist/credentials/SalesforceOAuth2Api.credentials.js", + "dist/credentials/SlackApi.credentials.js", + "dist/credentials/SlackOAuth2Api.credentials.js", + "dist/credentials/Sms77Api.credentials.js", + "dist/credentials/Smtp.credentials.js", + "dist/credentials/StripeApi.credentials.js", + "dist/credentials/SalesmateApi.credentials.js", + "dist/credentials/SegmentApi.credentials.js", + "dist/credentials/SurveyMonkeyApi.credentials.js", + "dist/credentials/TelegramApi.credentials.js", + "dist/credentials/TodoistApi.credentials.js", + "dist/credentials/TrelloApi.credentials.js", + "dist/credentials/TwilioApi.credentials.js", + "dist/credentials/TwitterOAuth1Api.credentials.js", + "dist/credentials/TypeformApi.credentials.js", + "dist/credentials/TogglApi.credentials.js", + "dist/credentials/UpleadApi.credentials.js", + "dist/credentials/VeroApi.credentials.js", + "dist/credentials/WebflowApi.credentials.js", + "dist/credentials/WooCommerceApi.credentials.js", + "dist/credentials/WordpressApi.credentials.js", + "dist/credentials/ZendeskApi.credentials.js", + "dist/credentials/ZohoOAuth2Api.credentials.js", + "dist/credentials/ZulipApi.credentials.js" + ], + "nodes": [ + "dist/nodes/ActiveCampaign/ActiveCampaign.node.js", + "dist/nodes/ActiveCampaign/ActiveCampaignTrigger.node.js", + "dist/nodes/AgileCrm/AgileCrm.node.js", + "dist/nodes/Airtable/Airtable.node.js", + "dist/nodes/AcuityScheduling/AcuitySchedulingTrigger.node.js", + "dist/nodes/Amqp/Amqp.node.js", + "dist/nodes/Amqp/AmqpTrigger.node.js", + "dist/nodes/Asana/Asana.node.js", + "dist/nodes/Asana/AsanaTrigger.node.js", + "dist/nodes/Affinity/Affinity.node.js", + "dist/nodes/Affinity/AffinityTrigger.node.js", + "dist/nodes/Aws/AwsLambda.node.js", + "dist/nodes/Aws/S3/AwsS3.node.js", + "dist/nodes/Aws/AwsSes.node.js", + "dist/nodes/Aws/AwsSns.node.js", + "dist/nodes/Aws/AwsSnsTrigger.node.js", + "dist/nodes/Bannerbear/Bannerbear.node.js", + "dist/nodes/Bitbucket/BitbucketTrigger.node.js", + "dist/nodes/Bitly/Bitly.node.js", + "dist/nodes/Calendly/CalendlyTrigger.node.js", + "dist/nodes/Chargebee/Chargebee.node.js", + "dist/nodes/Chargebee/ChargebeeTrigger.node.js", + "dist/nodes/Clearbit/Clearbit.node.js", + "dist/nodes/ClickUp/ClickUp.node.js", + "dist/nodes/ClickUp/ClickUpTrigger.node.js", + "dist/nodes/Clockify/ClockifyTrigger.node.js", + "dist/nodes/Cockpit/Cockpit.node.js", + "dist/nodes/Coda/Coda.node.js", + "dist/nodes/Copper/CopperTrigger.node.js", + "dist/nodes/Cron.node.js", + "dist/nodes/Crypto.node.js", + "dist/nodes/DateTime.node.js", + "dist/nodes/Discord/Discord.node.js", + "dist/nodes/Disqus/Disqus.node.js", + "dist/nodes/Drift/Drift.node.js", + "dist/nodes/Dropbox/Dropbox.node.js", + "dist/nodes/EditImage.node.js", + "dist/nodes/EmailReadImap.node.js", + "dist/nodes/EmailSend.node.js", + "dist/nodes/ErrorTrigger.node.js", + "dist/nodes/Eventbrite/EventbriteTrigger.node.js", + "dist/nodes/ExecuteCommand.node.js", + "dist/nodes/ExecuteWorkflow.node.js", + "dist/nodes/Facebook/FacebookGraphApi.node.js", + "dist/nodes/FileMaker/FileMaker.node.js", + "dist/nodes/Freshdesk/Freshdesk.node.js", + "dist/nodes/Flow/Flow.node.js", + "dist/nodes/Flow/FlowTrigger.node.js", + "dist/nodes/Function.node.js", + "dist/nodes/FunctionItem.node.js", + "dist/nodes/Github/Github.node.js", + "dist/nodes/Github/GithubTrigger.node.js", + "dist/nodes/Gitlab/Gitlab.node.js", + "dist/nodes/Gitlab/GitlabTrigger.node.js", + "dist/nodes/Google/Calendar/GoogleCalendar.node.js", + "dist/nodes/Google/Drive/GoogleDrive.node.js", + "dist/nodes/Google/Sheet/GoogleSheets.node.js", + "dist/nodes/GraphQL/GraphQL.node.js", + "dist/nodes/Gumroad/GumroadTrigger.node.js", + "dist/nodes/Harvest/Harvest.node.js", + "dist/nodes/HelpScout/HelpScout.node.js", + "dist/nodes/HelpScout/HelpScoutTrigger.node.js", + "dist/nodes/HtmlExtract/HtmlExtract.node.js", + "dist/nodes/HttpRequest.node.js", + "dist/nodes/Hubspot/Hubspot.node.js", + "dist/nodes/Hubspot/HubspotTrigger.node.js", + "dist/nodes/Hunter/Hunter.node.js", + "dist/nodes/If.node.js", + "dist/nodes/Intercom/Intercom.node.js", + "dist/nodes/Interval.node.js", + "dist/nodes/InvoiceNinja/InvoiceNinja.node.js", + "dist/nodes/InvoiceNinja/InvoiceNinjaTrigger.node.js", + "dist/nodes/Jira/Jira.node.js", + "dist/nodes/JotForm/JotFormTrigger.node.js", + "dist/nodes/Keap/Keap.node.js", + "dist/nodes/Keap/KeapTrigger.node.js", + "dist/nodes/LinkFish/LinkFish.node.js", + "dist/nodes/Mailchimp/Mailchimp.node.js", + "dist/nodes/Mailchimp/MailchimpTrigger.node.js", + "dist/nodes/Mailgun/Mailgun.node.js", + "dist/nodes/Mailjet/Mailjet.node.js", + "dist/nodes/Mailjet/MailjetTrigger.node.js", + "dist/nodes/Mandrill/Mandrill.node.js", + "dist/nodes/Mattermost/Mattermost.node.js", + "dist/nodes/Mautic/Mautic.node.js", + "dist/nodes/Mautic/MauticTrigger.node.js", + "dist/nodes/Merge.node.js", + "dist/nodes/Microsoft/Excel/MicrosoftExcel.node.js", + "dist/nodes/Microsoft/OneDrive/MicrosoftOneDrive.node.js", + "dist/nodes/MoveBinaryData.node.js", + "dist/nodes/Mocean/Mocean.node.js", + "dist/nodes/MondayCom/MondayCom.node.js", + "dist/nodes/MongoDb/MongoDb.node.js", + "dist/nodes/MoveBinaryData.node.js", + "dist/nodes/Msg91/Msg91.node.js", + "dist/nodes/MySql/MySql.node.js", + "dist/nodes/NextCloud/NextCloud.node.js", + "dist/nodes/NoOp.node.js", + "dist/nodes/OpenWeatherMap.node.js", + "dist/nodes/PagerDuty/PagerDuty.node.js", + "dist/nodes/PayPal/PayPal.node.js", + "dist/nodes/PayPal/PayPalTrigger.node.js", + "dist/nodes/Pipedrive/Pipedrive.node.js", + "dist/nodes/Pipedrive/PipedriveTrigger.node.js", + "dist/nodes/Postgres/Postgres.node.js", + "dist/nodes/ReadBinaryFile.node.js", + "dist/nodes/ReadBinaryFiles.node.js", + "dist/nodes/ReadPdf.node.js", + "dist/nodes/Redis/Redis.node.js", + "dist/nodes/RenameKeys.node.js", + "dist/nodes/Rocketchat/Rocketchat.node.js", + "dist/nodes/RssFeedRead.node.js", + "dist/nodes/Rundeck/Rundeck.node.js", + "dist/nodes/Salesforce/Salesforce.node.js", + "dist/nodes/Set.node.js", + "dist/nodes/Shopify/Shopify.node.js", + "dist/nodes/Shopify/ShopifyTrigger.node.js", + "dist/nodes/Slack/Slack.node.js", + "dist/nodes/Sms77/Sms77.node.js", + "dist/nodes/SplitInBatches.node.js", + "dist/nodes/SpreadsheetFile.node.js", + "dist/nodes/SseTrigger.node.js", + "dist/nodes/Start.node.js", + "dist/nodes/Stripe/StripeTrigger.node.js", + "dist/nodes/Switch.node.js", + "dist/nodes/Salesmate/Salesmate.node.js", + "dist/nodes/Segment/Segment.node.js", + "dist/nodes/SurveyMonkey/SurveyMonkeyTrigger.node.js", + "dist/nodes/Telegram/Telegram.node.js", + "dist/nodes/Telegram/TelegramTrigger.node.js", + "dist/nodes/Todoist/Todoist.node.js", + "dist/nodes/Toggl/TogglTrigger.node.js", + "dist/nodes/Trello/Trello.node.js", + "dist/nodes/Trello/TrelloTrigger.node.js", + "dist/nodes/Twilio/Twilio.node.js", + "dist/nodes/Twitter/Twitter.node.js", + "dist/nodes/Typeform/TypeformTrigger.node.js", + "dist/nodes/Uplead/Uplead.node.js", + "dist/nodes/Vero/Vero.node.js", + "dist/nodes/Webflow/WebflowTrigger.node.js", + "dist/nodes/Webhook.node.js", + "dist/nodes/Wordpress/Wordpress.node.js", + "dist/nodes/WooCommerce/WooCommerce.node.js", + "dist/nodes/WooCommerce/WooCommerceTrigger.node.js", + "dist/nodes/WriteBinaryFile.node.js", + "dist/nodes/Xml.node.js", + "dist/nodes/Zendesk/Zendesk.node.js", + "dist/nodes/Zendesk/ZendeskTrigger.node.js", + "dist/nodes/Zoho/ZohoCrm.node.js", + "dist/nodes/Zulip/Zulip.node.js" + ] + }, + "devDependencies": { + "@types/aws4": "^1.5.1", + "@types/basic-auth": "^1.1.2", + "@types/cheerio": "^0.22.15", + "@types/cron": "^1.6.1", + "@types/eventsource": "^1.1.2", + "@types/express": "^4.16.1", + "@types/formidable": "^1.0.31", + "@types/gm": "^1.18.2", + "@types/imap-simple": "^4.2.0", + "@types/jest": "^24.0.18", + "@types/lodash.set": "^4.3.6", + "@types/moment-timezone": "^0.5.12", + "@types/mongodb": "^3.5.4", + "@types/node": "^10.10.1", + "@types/nodemailer": "^6.4.0", + "@types/redis": "^2.8.11", + "@types/request-promise-native": "~1.0.15", + "@types/uuid": "^3.4.6", + "@types/xml2js": "^0.4.3", + "gulp": "^4.0.0", + "jest": "^24.9.0", + "n8n-workflow": "~0.31.0", + "ts-jest": "^24.0.2", + "tslint": "^5.17.0", + "typescript": "~3.7.4" + }, + "dependencies": { + "aws4": "^1.8.0", + "basic-auth": "^2.0.1", + "change-case": "^4.1.1", + "cheerio": "^1.0.0-rc.3", + "cron": "^1.7.2", + "eventsource": "^1.0.7", + "formidable": "^1.2.1", + "glob-promise": "^3.4.0", + "gm": "^1.23.1", + "googleapis": "~50.0.0", + "imap-simple": "^4.3.0", + "jsonwebtoken": "^8.5.1", + "lodash.get": "^4.4.2", + "lodash.set": "^4.3.2", + "lodash.unset": "^4.5.2", + "moment": "2.24.0", + "moment-timezone": "^0.5.28", + "mongodb": "^3.5.5", + "mysql2": "^2.0.1", + "n8n-core": "~0.34.0", + "nodemailer": "^6.4.6", + "pdf-parse": "^1.1.1", + "pg-promise": "^9.0.3", + "redis": "^2.8.0", + "request": "^2.88.2", + "rhea": "^1.0.11", + "rss-parser": "^3.7.0", + "uuid": "^3.4.0", + "vm2": "^3.6.10", + "xlsx": "^0.14.3", + "xml2js": "^0.4.22" + }, + "jest": { + "transform": { + "^.+\\.tsx?$": "ts-jest" + }, + "testURL": "http://localhost/", + "testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$", + "testPathIgnorePatterns": [ + "/dist/", + "/node_modules/" + ], + "moduleFileExtensions": [ + "ts", + "tsx", + "js", + "json" + ] + } }