diff --git a/spec/http-error-spec.coffee b/spec/http-error-spec.coffee deleted file mode 100644 index a77800d..0000000 --- a/spec/http-error-spec.coffee +++ /dev/null @@ -1,22 +0,0 @@ -assert = require('chai').assert -HttpError = require('../src/http-error') - - -describe 'HttpError', -> - - it 'should capture stack trace', -> - fxn = -> - throw new HttpError(500, {}, '') - try - fxn() - assert.fail() - catch e - stack = e.stack.split('\n') - assert.equal stack[0], 'HttpError: integration terminated early' - assert.match stack[1], /at fxn.*spec\/http\-error\-spec\.coffee\:/ - - it 'should have name', -> - assert.equal new HttpError(500, {}, '').name, 'HttpError' - - it 'should be an instance of HttpError', -> - assert new HttpError() instanceof HttpError diff --git a/spec/strip-metadata-spec.coffee b/spec/strip-metadata-spec.coffee deleted file mode 100644 index 82e3223..0000000 --- a/spec/strip-metadata-spec.coffee +++ /dev/null @@ -1,97 +0,0 @@ -assert = require('chai').assert -types = require('leadconduit-types') -strip = require('../src/strip-metadata') - -describe 'Strip metadata', -> - - beforeEach () -> - @vars = - submission: - timestamp: '2019-02-27T08:02:53.669Z' - account: - id: 'account123' - name: 'Lead Garden, Inc.' - sso_id: 'sso123' - flow: - id: 'flow123' - name: 'Sales Leads' - random: 24 - source: - id: 'source123' - name: 'Contact Form' - to: 'delivery@example.com' - cc: 'customer@example.com' - lead: - id: 'lead123' - email: types.email.parse('dee@leadgarden.com') - first_name: 'Dee' - last_name: 'Daniels' - phone_1: types.phone.parse('512-555-1212') - trustedform_cert_url: types.url.parse('https://cert.trustedform.com/cert123') - suppression_list: - query_item: - key: 'dee@leadgarden.com' - found: types.boolean.parse(false) - reason: null - outcome: 'success' - duration: types.number.parse(0.0123) - specified_lists: ['sales_leads'] - add_item: - reason: null - outcome: 'success' - accepted: types.number.parse(1) - rejected: types.number.parse(0) - duration: types.number.parse(0.0456) - anura: - outcome: 'success' - billable: types.number.parse(1) - is_suspect: types.boolean.parse(false) - leadconduit_classic: - id: 'classic123' - - - it 'should strip basic metadata', -> - expected = - email: 'dee@leadgarden.com' - first_name: 'Dee' - last_name: 'Daniels' - phone_1: '5125551212' - trustedform_cert_url: 'https://cert.trustedform.com/cert123' - to: 'delivery@example.com' - cc: 'customer@example.com' - suppression_list: - query_item: - key: 'dee@leadgarden.com' - found: false - duration: 0.0123 - specified_lists: ['sales_leads'] - add_item: - accepted: 1 - rejected: 0 - duration: 0.0456 - anura: - is_suspect: false - leadconduit_classic: - id: 'classic123' - - assert.deepEqual(strip(@vars), expected) - - - it 'should strip basic metadata plus additional fields', -> - expected = - email: 'dee@leadgarden.com' - first_name: 'Dee' - last_name: 'Daniels' - phone_1: '5125551212' - trustedform_cert_url: 'https://cert.trustedform.com/cert123' - to: 'delivery@example.com' - suppression_list: - add_item: - accepted: 1 - rejected: 0 - anura: - is_suspect: false - leadconduit_classic: - id: 'classic123' - - assert.deepEqual(strip(@vars, [new RegExp('query_item.*'), new RegExp('.*.duration'), 'cc']), expected) diff --git a/spec/test-types-parse-spec.coffee b/spec/test-types-parse-spec.coffee deleted file mode 100644 index 8dda4fd..0000000 --- a/spec/test-types-parse-spec.coffee +++ /dev/null @@ -1,24 +0,0 @@ -assert = require('chai').assert -parser = require('../src/test/types').parser - - -describe 'Test types parse', -> - - it 'should parse number to string', -> - parse = parser([ name: 'foo', type: 'string' ]) - assert.deepEqual parse(foo: 5), foo: '5' - - it 'should parse to typed value', -> - parse = parser([ name: 'foo', type: 'number' ]) - parsed = parse(foo: '5') - assert.equal parsed.foo.valueOf(), 5 - assert.equal parsed.foo.raw, '5' - assert.isTrue parsed.foo.valid - - it 'should do nothing if request variable is missing a type', -> - parse = parser([ name: 'foo' ]) - assert.deepEqual parse(foo: 5), foo: 5 - - it 'should do nothing if request variable is missing', -> - parse = parser([]) - assert.deepEqual parse(foo: 5), foo: 5 diff --git a/spec/util-spec.coffee b/spec/util-spec.coffee deleted file mode 100644 index 389cb8b..0000000 --- a/spec/util-spec.coffee +++ /dev/null @@ -1,109 +0,0 @@ -assert = require('chai').assert -utils = require('../src/util') - -describe 'Utility functions', -> - - describe 'parseFullname', -> - - it 'should parse a standard name', -> - parsed = utils.parseFullname("John Smith") - assert.equal parsed.first_name, "John" - assert.equal parsed.last_name, "Smith" - - it 'should parse a name with an apostrophe', -> - parsed = utils.parseFullname("Sean O'Reilly") - assert.equal parsed.first_name, "Sean" - assert.equal parsed.last_name, "O'Reilly" - - it 'should parse a name with a space', -> - parsed = utils.parseFullname("Juliana de Luna") - assert.equal parsed.first_name, "Juliana" - assert.equal parsed.last_name, "de Luna" - - it 'should parse a name with a bunch of other stuff', -> - parsed = utils.parseFullname("Mr. Charles P. Wooten, III") - assert.equal parsed.salutation, "Mr." - assert.equal parsed.first_name, "Charles" - assert.equal parsed.middle_name, "P." - assert.equal parsed.last_name, "Wooten" - assert.equal parsed.suffix, "III" - - describe 'validateRequest', -> - - it 'should not error if all required data is correct', -> - invokeRequest = -> - utils.validateRequest({method: 'POST', headers: {'Content-Type': 'application/json'}}, ['application/json']) - try - invokeRequest() - catch err - finally - assert.isUndefined err - - it 'should error if method is not POST', -> - invokeRequest = -> - utils.validateRequest({method: 'GET', headers: {'Content-Type': 'application/json'}}, ['application/json']) - try - invokeRequest() - catch err - assert.equal err.status, 415 - assert.equal err.body, 'The GET method is not allowed' - finally - assert.isDefined err - - it 'should require a Content-Type header', -> - invokeRequest = -> - utils.validateRequest({method: 'POST', headers: {}}, ['application/json']) - try - invokeRequest() - catch err - assert.equal err.status, 415 - assert.equal err.body, 'Content-Type header is required' - finally - assert.isDefined err - - it 'should require the correct Content-Type header', -> - invokeRequest = -> - utils.validateRequest({method: 'POST', headers: {'Content-Type': 'application/x-www-form-urlencoded'}}, ['application/json']) - try - invokeRequest() - catch err - assert.equal err.status, 415 - assert.equal err.body, 'MIME type in Content-Type header is not supported. Use only application/json' - finally - assert.isDefined err - - it 'should support allowing multiple Content-Types', -> - invokeRequest = (contentType) -> - utils.validateRequest({method: 'POST', headers: {'Content-Type': contentType}}, ['application/json', 'application/xml']) - try - invokeRequest('application/json') - invokeRequest('application/xml') - catch err - finally - assert.isUndefined err - - it 'should support allowing multiple methods', -> - invokeRequest = (method) -> - utils.validateRequest({method: method, headers: {'Content-Type': 'text/json'}}, ['text/json'], ['GET', 'POST']) - try - invokeRequest('GET') - invokeRequest('POST') - catch err - finally - assert.isUndefined err - - - describe 'calculateTimeout', -> - - it 'returns the correct remaining timeout', -> - timeout = -1 - start = new Date(new Date().getTime() - 2000) # 2s ago - timeout = utils.calculateTimeout(start, 4000) # 4s timeout - assert.closeTo timeout, 2000, 500 # .5s of wiggle-room - - - it 'returns minimum of zero', -> - timeout = -1 - start = new Date(new Date().getTime() - 2000) # 2s ago - timeout = utils.calculateTimeout(start, 1000) # 1s timeout - assert.equal timeout, 1 diff --git a/src/http-error.coffee b/src/http-error.coffee deleted file mode 100644 index 551d8b2..0000000 --- a/src/http-error.coffee +++ /dev/null @@ -1,20 +0,0 @@ -class HttpError extends Error - constructor: (@status, @headers, @body) -> - @message = 'integration terminated early' - @name = 'HttpError' - Error.captureStackTrace @, arguments.callee - super - - -module.exports = HttpError -#HttpError = (status, headers, body) -> - - -# Error.call(@) -# Error.captureStackTrace(@, arguments.callee) -# @status = status -# @headers = headers -# @body = body -# @name = 'HttpError' -# -#HttpError.prototype.__proto__ = Error.prototype; \ No newline at end of file diff --git a/src/index.coffee b/src/index.coffee deleted file mode 100644 index c61e866..0000000 --- a/src/index.coffee +++ /dev/null @@ -1,3 +0,0 @@ -require('@activeprospect/indexer')(__dirname, module) - -module.exports.HttpError = module.exports['http-error'] diff --git a/src/strip-metadata.coffee b/src/strip-metadata.coffee deleted file mode 100644 index 3e6585a..0000000 --- a/src/strip-metadata.coffee +++ /dev/null @@ -1,34 +0,0 @@ -_ = require('lodash') -flat = require('flat') - -excludePatterns = [ - /^timestamp$/ - /^timeout_seconds$/ - /^random$/ - /^flow\./ - /^source\./ - /^account\./ - /^lead\.id/ - /^recipient\./ - /^submission\./ - /\.outcome$/ - /\.reason$/ - /\.billable$/ -] - -# given the `vars` "snowball", this will strip all the data that a user -# wouldn't want delivered as a "lead". used, for example, by email-delivery -module.exports = (vars, additionalExcludes = []) -> - - for exclude in additionalExcludes - # \b = word-boundary, so, e.g., "cc" doesn't exclude "accept" - excludePatterns.push(if _.isRegExp(exclude) then exclude else RegExp("\\b#{exclude}\\b")) - - stripped = {} - flatVars = flat.flatten(vars) - for key of flatVars - if !excludePatterns.some((val) => key.match(val)) - # replace attribute, moving "lead." fields up a level - _.set stripped, key.replace(/^lead\./, ''), flatVars[key]?.valueOf() - - stripped diff --git a/src/test/index.coffee b/src/test/index.coffee deleted file mode 100644 index ef5c681..0000000 --- a/src/test/index.coffee +++ /dev/null @@ -1 +0,0 @@ -require('@activeprospect/indexer')(__dirname, module) diff --git a/src/test/types.coffee b/src/test/types.coffee deleted file mode 100644 index 5fc2f11..0000000 --- a/src/test/types.coffee +++ /dev/null @@ -1,19 +0,0 @@ -types = require('leadconduit-types') -flat = require('flat') - - -module.exports.parser = (requestVars=[]) -> - typeLookup = {} - - for requestVar in requestVars - typeLookup[requestVar.name] = types[requestVar.type] - - (vars) -> - parsed = {} - for name, value of flat.flatten(vars, safe: true) - parse = typeLookup[name]?.parse - if parse? and value? - parsed[name] = parse(value) - else - parsed[name] = value - flat.unflatten(parsed) diff --git a/src/util.coffee b/src/util.coffee deleted file mode 100644 index baa7f9f..0000000 --- a/src/util.coffee +++ /dev/null @@ -1,55 +0,0 @@ -humanname = require 'humanname' -mimeparse = require 'mimeparse' -HttpError = require './http-error' -stripMetadata = require './strip-metadata' - -selectMimeType = (contentType, supportedTypes) -> - return unless contentType? - mimeparse.bestMatch(supportedTypes, contentType) - -module.exports = - - # given a string containing a person's full name, return a two-element array containing firstName and lastName - parseFullname: (fullname) -> - parsed = humanname.parse(fullname) - - salutation: parsed.salutation - first_name: parsed.firstName - middle_name: parsed.initials - last_name: parsed.lastName - suffix: parsed.suffix - - - validateRequest: (req, mimeTypes, methods) -> - - #ensure supported method - method = req.method?.toLowerCase() - supportedMethods = methods or ['POST'] - supportedMethods = supportedMethods.map (val) -> val.toLowerCase() - unless supportedMethods.indexOf(method) > -1 - throw new HttpError(415, { 'Content-Type': 'text/plain', Allow: 'POST' }, "The #{method.toUpperCase()} method is not allowed") - - #ensure a content-type header - contentType = req.headers['Content-Type'] - unless contentType - throw new HttpError(415, { 'Content-Type': 'text/plain' }, 'Content-Type header is required') - - #ensure a valid mime type - unless mimeTypes.indexOf(selectMimeType(req.headers['Content-Type'], mimeTypes)) > -1 - throw new HttpError(415, {'Content-Type': 'text/plain'}, "MIME type in Content-Type header is not supported. Use only #{mimeTypes.join ', '}") - - - # given a starting timestamp and the total timeout (in ms), return the remaining timeout (in ms) - calculateTimeout: (startTimestamp, timeoutMs) -> - elapsedMs = new Date().getTime() - startTimestamp - remaining = timeoutMs - elapsedMs - return 1 if remaining <= 0 # the `request` library treats a timeout value of '0' as no timeout - remaining - - stripMetadata: stripMetadata - - getBaseUrl: (env = process.env.NODE_ENV) -> - switch env - when 'staging' then 'https://next.staging.leadconduit.com' - when 'development' then "http://leadconduit.localhost" - else 'https://next.leadconduit.com'