diff --git a/manifest.json b/manifest.json index 2633fa5..4fb9142 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "name": "docs-in-tickets", "vendor": "vtexhelp", - "version": "1.0.0", + "version": "1.0.3", "title": "Docs in Tickets", "description": "Process information about documentation links sent in support tickets.", "categories": [], diff --git a/node/clients/zendesk.ts b/node/clients/zendesk.ts index ac40d44..daba282 100644 --- a/node/clients/zendesk.ts +++ b/node/clients/zendesk.ts @@ -2,9 +2,15 @@ import { ExternalClient, IOContext, InstanceOptions } from '@vtex/api' -const username = 'xxxxxxxxxxxxxxxxxxxxxxxx' -const token = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx' +const username = 'xxxxxxxxxxxxxxxxx' +const token = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' const authValue = btoa(`${username}/token:${token}`) + +// Below are sandbox auth variables, just to facilitate debugging. Note that the format is different. +// const username = 'xxxxxxxxxxxxxxxxx' +// const token = 'xxxxxxxxxxxxxxxxx' +// const authValue = btoa(`${username}:${token}`) + const requestHeaders = { 'Content-Type': 'application/json', 'Authorization': `Basic ${authValue}`, diff --git a/node/middlewares/processTicket.ts b/node/middlewares/processTicket.ts index ae39219..6dda19a 100644 --- a/node/middlewares/processTicket.ts +++ b/node/middlewares/processTicket.ts @@ -1,6 +1,5 @@ // The processMessage function gets the ticket message from the context and formats its content to be saved in a database later. -import bodyParser from 'co-body' import { or } from 'ramda' import type { MessageData } from '../clients/redshift' @@ -27,7 +26,8 @@ export async function processTicket( ) { console.info('Running processTicket') - const requestBody = await bodyParser(ctx.req) + const requestBody = ctx.state.body + console.info(requestBody) const zendeskTicket = requestBody.ticketId const zendesk = ctx.clients.zendesk @@ -99,8 +99,7 @@ export async function processTicket( allCommentsWithUrls.push(messageData) - const redshiftResponse = await redshift.saveMessage(messageData) - console.log('redshift >>> '+JSON.stringify(redshiftResponse)) + await redshift.saveMessage(messageData) } } diff --git a/node/middlewares/verifyZendeskSignature.ts b/node/middlewares/verifyZendeskSignature.ts index f31c537..47589d9 100644 --- a/node/middlewares/verifyZendeskSignature.ts +++ b/node/middlewares/verifyZendeskSignature.ts @@ -3,7 +3,8 @@ import bodyParser from 'co-body' import * as crypto from 'crypto' -const ZENDESK_SECRET_KEY = "xxxxxxxxxxxxxxxxxxxxxxx" +const ZENDESK_SECRET_KEY_PRODUCTION = "xxxxxxxxxxxxxxxxx" +const ZENDESK_SECRET_KEY_SANDBOX = "xxxxxxxxxxxxxxxxxx" const SIGNING_SECRET_ALGORITHM = "sha256" export async function verifyZendeskSignature ( @@ -13,38 +14,49 @@ export async function verifyZendeskSignature ( console.info('Running verifyZendeskSignature') // Determining whether the signature is compatible with the expected, according to the secret key provided by zendesk. This key is exclusive to this webhook. - function isValidSignature(signature: string, body: string, timestamp: string): boolean { + function isValidSignature(signature: string, body: object, timestamp: string, key: string): boolean { console.info('Running isValidSignature') - let hmac = crypto.createHmac(SIGNING_SECRET_ALGORITHM, ZENDESK_SECRET_KEY) + let hmac = crypto.createHmac(SIGNING_SECRET_ALGORITHM, key) let sig = hmac.update(timestamp + body).digest('base64') const comparison = Buffer.compare( Buffer.from(signature, 'base64'), Buffer.from(sig.toString(), 'base64') ) - return ( - comparison === 0 - ) + return (comparison === 0) } if (ctx.request.headers['x-zendesk-webhook-signature'] !== undefined) { const requestBody = await bodyParser(ctx.req, { returnRawBody: true }) + ctx.state.body = requestBody.parsed + console.info(ctx.state.body) const requestSignature: string = ctx.request.headers["x-zendesk-webhook-signature"] as string const requestSignatureTimestamp: string = ctx.request.headers["x-zendesk-webhook-signature-timestamp"] as string - if (isValidSignature(requestSignature, requestBody.raw, requestSignatureTimestamp)) { + if (isValidSignature(requestSignature, requestBody.raw, requestSignatureTimestamp, ZENDESK_SECRET_KEY_PRODUCTION)) { - console.info('Zendesk signature verified successfully.') + console.info('Zendesk production signature verified successfully.') await next() } else { + + if (isValidSignature(requestSignature, requestBody.raw, requestSignatureTimestamp, ZENDESK_SECRET_KEY_SANDBOX)) { + + console.info('Zendesk sandbox signature verified successfully.') + await next() + + } else { + ctx.status = 400 ctx.response.body = { message: 'Zendesk signature not valid.' } console.info('Zendesk signature not valid.') return + + } + } } else { ctx.status = 400