From 364ac2564863abba422cfe3e4121cf801f07acf2 Mon Sep 17 00:00:00 2001 From: Yashasvi Bajpai <33063622+yashasvibajpai@users.noreply.github.com> Date: Thu, 9 Jan 2025 12:59:08 +0530 Subject: [PATCH] fix: add email validation in HS --- package-lock.json | 9 ++ package.json | 1 + src/v0/destinations/hs/HSTransform-v2.js | 6 ++ .../destinations/hs/processor/data.ts | 82 +++++++++++++++++++ 4 files changed, 98 insertions(+) diff --git a/package-lock.json b/package-lock.json index 99efc2e7fd..c34bc606e4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -75,6 +75,7 @@ "unset-value": "^2.0.1", "uuid": "^9.0.1", "valid-url": "^1.0.9", + "validator": "^13.12.0", "zod": "^3.22.4" }, "devDependencies": { @@ -21970,6 +21971,14 @@ "spdx-expression-parse": "^3.0.0" } }, + "node_modules/validator": { + "version": "13.12.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.12.0.tgz", + "integrity": "sha512-c1Q0mCiPlgdTVVVIJIrBuxNicYE+t/7oKeI9MWLj3fh/uq2Pxh/3eeWbVZ4OcGW1TUf53At0njHw5SMdA3tmMg==", + "engines": { + "node": ">= 0.10" + } + }, "node_modules/vary": { "version": "1.1.2", "license": "MIT", diff --git a/package.json b/package.json index 7f713bdd5d..cf72ab26de 100644 --- a/package.json +++ b/package.json @@ -120,6 +120,7 @@ "unset-value": "^2.0.1", "uuid": "^9.0.1", "valid-url": "^1.0.9", + "validator": "^13.12.0", "zod": "^3.22.4" }, "devDependencies": { diff --git a/src/v0/destinations/hs/HSTransform-v2.js b/src/v0/destinations/hs/HSTransform-v2.js index 3dd9f87ea4..894b3d291a 100644 --- a/src/v0/destinations/hs/HSTransform-v2.js +++ b/src/v0/destinations/hs/HSTransform-v2.js @@ -5,6 +5,7 @@ const { ConfigurationError, InstrumentationError, } = require('@rudderstack/integrations-lib'); +const validator = require('validator'); const { MappedToDestinationKey, GENERIC_TRUE_VALUES } = require('../../../constants'); const { defaultPostRequestConfig, @@ -72,6 +73,11 @@ const addHsAuthentication = (response, Config) => { const processIdentify = async ({ message, destination, metadata }, propertyMap) => { const { Config } = destination; let traits = getFieldValueFromMessage(message, 'traits'); + // since hubspot does not allow imvalid emails, we need to + // validate the email before sending it to hubspot + if (traits?.email && !validator.isEmail(traits.email)) { + throw new InstrumentationError(`Email ${traits.email} is invalid`); + } const mappedToDestination = get(message, MappedToDestinationKey); const operation = get(message, 'context.hubspotOperation'); const externalIdObj = getDestinationExternalIDObjectForRetl(message, 'HS'); diff --git a/test/integrations/destinations/hs/processor/data.ts b/test/integrations/destinations/hs/processor/data.ts index f503ae92ac..b36db8504b 100644 --- a/test/integrations/destinations/hs/processor/data.ts +++ b/test/integrations/destinations/hs/processor/data.ts @@ -5425,4 +5425,86 @@ export const data = [ }, }, }, + { + name: 'hs', + description: + '[HS] (New API v3) - throw error if invalid email is provided in traits for identify call', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + description: + '[HS] (New API v3) - throw error if invalid email is provided in traits for identify call', + message: { + channel: 'web', + context: { + traits: { + email: 'incorrect-email', + firstname: 'Test Hubspot', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + }, + type: 'identify', + messageId: 'e8585d9a-7137-4223-b295-68ab1b17dad7', + originalTimestamp: '2025-01-01T09:35:31.289Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + properties: '', + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + authorizationType: 'newPrivateAppApi', + hubID: '', + apiKey: '', + accessToken: 'dummy-access-token', + apiVersion: 'newApi', + lookupField: 'lookupField', + eventFilteringOption: 'disable', + blacklistedEvents: [ + { + eventName: '', + }, + ], + whitelistedEvents: [ + { + eventName: '', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'Email incorrect-email is invalid', + statTags: { + destType: 'HS', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, ];