GithubHelp home page GithubHelp logo

aws-js-sns-message-validator's Introduction

Amazon SNS Message Validator for JavaScript

@awsforjs on Twitter Build Status Apache 2 License

The Amazon SNS Message Validator for Node.js library allows you to validate that incoming HTTP(S) POST messages are valid Amazon SNS notifications. This library is standalone and does not depend on the AWS SDK for JavaScript.

Installation

The npm module's name is sns-validator. Install with npm or yarn:

npm i sns-validator

or

yarn add sns-validator

Basic Usage

To validate a message, you can instantiate a MessageValidator object and pass an SNS message and a callback to its validate method. The message should be the result of calling JSON.parse on the body of the HTTP(S) message sent by SNS to your endpoint. The callback should take two arguments, the first being an error and the second being the successfully validated SNS message.

The message validator checks the SigningCertURL, SignatureVersion, and Signature to make sure they are valid and consistent with the message data.

var MessageValidator = require('sns-validator'),
    validator = new MessageValidator();

validator.validate(message, function (err, message) {
    if (err) {
        // Your message could not be validated.
        return;
    }

    // message has been validated and its signature checked.
});

Installation

The SNS Message Validator relies on the Node crypto module and is only designed to work on a server, not in a browser. The validation performed is only necessary when subscribing HTTP(S)

About Amazon SNS

Amazon Simple Notification Service (Amazon SNS) is a fast, fully-managed, push messaging service. Amazon SNS can deliver messages to email, mobile devices (i.e., SMS; iOS, Android and FireOS push notifications), Amazon SQS queues,and — of course — HTTP/HTTPS endpoints.

With Amazon SNS, you can setup topics to publish custom messages to subscribed endpoints. However, SNS messages are used by many of the other AWS services to communicate information asynchronously about your AWS resources. Some examples include:

  • Configuring Amazon Glacier to notify you when a retrieval job is complete.
  • Configuring AWS CloudTrail to notify you when a new log file has been written.
  • Configuring Amazon Elastic Transcoder to notify you when a transcoding job changes status (e.g., from "Progressing" to "Complete")

Though you can certainly subscribe your email address to receive SNS messages from service events like these, your inbox would fill up rather quickly. There is great power, however, in being able to subscribe an HTTP/HTTPS endpoint to receive the messages. This allows you to program webhooks for your applications to easily respond to various events.

Handling Messages

Confirming a Subscription to a Topic

In order to handle a SubscriptionConfirmation message, you must use the SubscribeURL value in the incoming message:

var https = require('https'),
    MessageValidator = require('sns-validator'),
    validator = new MessageValidator();

validator.validate(message, function (err, message) {
    if (err) {
        console.error(err);
        return;
    }

    if (message['Type'] === 'SubscriptionConfirmation') {
        https.get(message['SubscribeURL'], function (res) {
          // You have confirmed your endpoint subscription
        });
    }
});

If an incoming message includes multibyte characters and its encoding is utf8, set the encoding to validator.

var MessageValidator = require('sns-validator'),
    validator = new MessageValidator();
validator.encoding = 'utf8';

Receiving a Notification

To receive a notification, use the same code as the preceding example, but check for the Notification message type.

if (message['Type'] === 'Notification') {
    // Do whatever you want with the message body and data.
    console.log(message['MessageId'] + ': ' + message['Message']);
}

The message body will be a string, and will hold whatever data was published to the SNS topic.

Unsubscribing

Unsubscribing looks the same as subscribing, except the message type will be UnsubscribeConfirmation.

if (message['Type'] === 'UnsubscribeConfirmation') {
    // Unsubscribed in error? You can resubscribe by visiting the endpoint
    // provided as the message's SubscribeURL field.
    https.get(message['SubscribeURL'], function (res) {
        // You have re-subscribed your endpoint.
    });
}

aws-js-sns-message-validator's People

Contributors

albertovasquez avatar dancrumb avatar hyandell avatar jeskew avatar mokemokechicken avatar parkerram avatar sethtippetts avatar trivikr avatar yurko-fedoriv avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

aws-js-sns-message-validator's Issues

Error: Message missing required keys.

I'm trying to use this library with AWS Lambda to validate an incoming SNS message, but I keep running into the following error message.

Error: Message missing required keys.

After some more investigation, I've noticied a very subtle difference. When logging what the SNS message looks like as it triggers the lambda and in AWS Lambda's SNS sample json event files, the SNS message looks like this (unimportant pieces snipped out)

{
      "Sns": {
        ...,
        "SigningCertUrl": "EXAMPLE",
        ...,
        "UnsubscribeUrl": "EXAMPLE",
        ...
}

While as documented here, http://docs.aws.amazon.com/sns/latest/dg/json-formats.html as well as the test cases you provide for this library, the json structure is the following.

{
      "Sns": {
        ...,
        "SigningCertURL": "EXAMPLE",
        ...,
        "UnsubscribeURL": "EXAMPLE",
        ...
}

Notice the subtle capitalization of the 'r' and the 'l' (Url and the URL). I'm not sure if this is a bug in the library itself or if AWS's documentation needs to be updated?

❤️

Sending a little love to the team that put this together! Was sweating having to wire up this validation myself and then a quick search found this.

Thanks for doing this! Works perfect.

ReferenceError: email is not defined

Hi,
Thanks for providing such great package 👍
Currently I have problem while validating SNS Notification using sns-validator it's always come with error message:
ReferenceError: email is not defined

I put the whole body (in JSON) as message parameter, see below
{ Type: 'Notification', MessageId: 'xxxxxx-ada8-50ea-b2fd-xxxxxxxx', TopicArn: 'arn:aws:sns:us-west-1:6999999999:SOmeTopiCARn', Message: '{"notificationType":"Bounce","bounce":{"bounceType":"Permanent","bounceSubType":"General","bouncedRecipients":[{"emailAddress":"[email protected]","action":"failed","status":"5.3.0","diagnosticCode":"smtp; 554 delivery error: dd This user doesn\'t have a yahoo.com account ([email protected]) [0] - mta1429.mail.ne1.yahoo.com"}],"timestamp":"2017-07-26T04:29:58.373Z","feedbackId":"213213123131-qweqweqw-qweqwe-4d9a-a7b1-weeqewqe-000000","remoteMtaIp":"xx.xxx.xxx.xx","reportingMTA":"dsn; werwrwr34.smtp-out.us-west-2.amazonses.com"},"mail":{"timestamp":"2017-07-26T04:29:55.000Z","source":"[email protected]","sourceArn":"arn:aws:ses:us-west-2:6999999999:identity/[email protected]","sourceIp":"203.xx.xxx.xxx","sendingAccountId":"6999999999","messageId":"sadad33-ddd-ddd-3433-dddd-adasdadsasd-4455454545","destination":["[email protected]"]}}', Timestamp: '2017-07-26T04:29:58.432Z', SignatureVersion: '1', Signature: 'sOmeSgn4tur3+NL6xs1DrG8basdwewfWECFCdaseQQWWaasdZt57ScO18SoWhatGithuLoch7bMfpfW2vRN0w2f+kP/M', SigningCertURL: 'https://sns.us-west-1.amazonaws.com/sns-asdadadasdasdadadasd.pem', UnsubscribeURL: 'https://sns.us-west-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-west-2:6999999999:SOmeTopiCARn:sdadsadad-e271-453a-8666-asdsadsdsada' }
Please let me know if I have done something incorrect, or maybe there is an issue about this.

Thanks
Rio

Error: the message signature is invalid

I'm getting "Error: the message signature is invalid" when I run this. I've used console.log to confirm several of the required components (certificate, signature) as well as confirm logical mechanics (missing keys, cert URL inaccessible). Everything seems to be checking out, yet it's coming back each time indicating invalid.

I've also tried access the message object at various places, from index.js and from the dependent node packages, to ensure everything is being passed around and everything looks good. I'm parsing the initial message string into a parsed JS object, and passing that to the MessageValidator constructor.

Any thoughts would be great. I'm using the latest version, 0.3.4.

For reference, a snapshot of the base project index.js which is attempting to kick this off, just in case I've done something wrong here.

image

The message signature is invalid.

Hello,

Thanks for the work carried out!

I keep having the following error message: "The message signature is invalid."

I added a console.log before the verifier.verify method call to display the certificate and the signature. Both look correct.

Any suggestions on how to debug this?

Regards,
Jean

When provided callback to validate() throws an error that callback is being called again.

Message validator has the issue of calling the provided callback twice. It can cause error where it is assumed that function will be called once. For example:

var v = new MessageValidator('someurl');

function middleware(req, res, next) {
   v.validate(validMessage, function(err, message) {
       console.count('called');
       if (err) { 
          return next(new Error('Validation error:' + err.message )); 
       }
       // some code
       throw new Error('inside callback');
   });
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.