sns-payload-validator
v2.1.0
Published
Node.js library that validates an AWS SNS payload of an HTTP/S POST or Lambda.
Downloads
21,331
Maintainers
Readme
AWS SNS Payload Validator
Node.js library that validates an AWS SNS payload of an HTTP/S POST or Lambda. The payload / error is then sent to either a Promise, or a callback if one is provided. Downloaded certificates can be cached.
Status and Testing
Check the status of a message signed with SignatureVersion
1, or check the status of a message signed with SignatureVersion
2. This module is tested daily at 12:00 UTC on a live AWS account using SNS via the code found in the sns-tester repository.
Please note: While SignatureVersion
1 is the default, on 2022-09-19 AWS announced the ability to set topics with SignatureVersion
2. Starting with version 1.1.0
of this module, SignatureVersion
1 and 2 are supported.
Installing
Using npm:
$ npm install sns-payload-validator
Using yarn:
$ yarn add sns-payload-validator
Getting started
The AWS SNS Payload Validator validates that the payload is from AWS SNS by validating the Type
, SignatureVersion
, SigningCertURL
and Signature
. For more on this process please see Verifying the signatures of Amazon SNS messages. A Validator
object must be first be instantiated. The payload is the passed to the objects validate
method. When instantiating, the cache options can be set. In HTTP/S there are three ways to validate the message:
async/await with try/catch
const Validator = require('sns-payload-validator');
const validator = new Validator();
try {
const validPayload = await validator.validate(payloadFromRequest)
// validPayload has been validated and its signature checked
}
catch (err) {
// payloadFromRequest could not be validated
}
Promise Chaining
const Validator = require('sns-payload-validator');
const validator = new Validator();
validator.validate(payloadFromRequest)
.then((validPayload) => {
// validPayload has been validated and its signature checked
})
.catch((err) => {
// payloadFromRequest could not be validated
});
Callbacks
const Validator = require('sns-payload-validator');
const validator = new Validator();
validator.validate(payloadFromRequest, (err, validPayload) => {
if (err) {
// payloadFromRequest could not be validated
return;
}
// validPayload has been validated and its signature checked
});
TypeScript
TypeScript is also supported by using:
import * as Validator from 'sns-payload-validator';
If you want to use the SnsPayload
interface, you can import it using:
import { SnsPayload } from 'sns-payload-validator/interfaces';
The Payload
AWS SNS sends HTTP/S POSTS with the Content-Type of text/plain
. Therefore, if there is a need to manipulate the payload before sending it to the AWS SNS Payload Validator, JSON.parse()
must be used. AWS SNS Payload Validator accepts the payload as a valid JSON string
or a JavaScript Object
. The return value is parsed into a JavaScript Object
, so it is recommended to do any manipulation on the return value.
Cache Options
The Validator
object can be instantiated with the following cache options:
useCache
:boolean
- Iftrue
, the validator will cache the certificates it downloads from Amazon SNS using lru-cache. Default:true
.maxCerts
:number
- The maximum number of certificates to cache. Must be positive integer. Default:1000
. If the number of certificates exceeds this value, the least recently used certificate will be removed from the cache.
const Validator = require('sns-payload-validator');
const validator = new Validator({ useCache: true, maxCerts: 100 });
Custom Request Agent
If a custom request agent is needed, it can be passed to the Validator
object, which will be used when making requests to download the certificate. This is useful if you are behind a proxy. By default the Validator
object uses the https
module.
const Validator = require('sns-payload-validator');
const validator = new Validator({ requestAgent: new ExternalProxyLib({ proxy: 'http://localhost:3000' }) });
Examples with Types
Not to be confused with TypeScript, AWS SNS Messages start with a Type
field. The Type
is one of three values: Notification
, SubscriptionConfirmation
or UnsubscribeConfirmation
.
Subscribe / Unsubscribe
If the endpoint should automaticaly subscribe when the a SubscriptionConfirmation
is sent. OR if the endpoint should resubscribe if a UnsubscribeConfirmation
is sent, the SubscribeURL
can be used:
const Validator = require('sns-payload-validator');
const Https = require('https')
const validator = new Validator();
try {
const validPayload = await validator.validate(payloadFromRequest)
if (validPayload.Type === 'SubscriptionConfirmation' || validPayload.Type === 'UnsubscribeConfirmation') {
Https.get(validPayload.SubscribeURL, (res) => {
// The route has been confirmed
return;
});
}
return;
}
catch (err) {
console.log(err);
}
Notifications
To act on a message published, a Notification
is sent and the Message
can be used:
const Validator = require('sns-payload-validator');
const validator = new Validator();
try {
const validPayload = await validator.validate(payloadFromRequest)
if (validPayload.Type === 'Notification') {
console.log('Here is the message:', validPayload.Message);
return;
}
return;
}
catch (err) {
console.log(err);
}
Lambda
Validating the payload of the Lambda is similar:
const Validator = require('sns-payload-validator');
const validator = new Validator();
exports.handler = async (event) => {
const validPayload = await validator.validate(event.Records[0].Sns);
console.log('Here is the message:', validPayload.Message);
return;
}
Put the await
inside a try/catch
block if the Lambda should not error if validation fails.
A few notes on Lambda:
- The payload is JavaScript
Object
. - The keys of
SigningCertURL
andUnsubscribeURL
areSigningCertUrl
andUnsubscribeUrl
respectivley. - If a subject is not specified on publish the key of
Subject
isnull
as opposed to absent.
Conclusion
See the Amazon Simple Notification Service Developer Guide for more Documentation on AWS SNS.