New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@mapbox/cloudfriend

Package Overview
Dependencies
Maintainers
14
Versions
92
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@mapbox/cloudfriend - npm Package Compare versions

Comparing version 2.7.0 to 2.8.0

test/fixtures/shortcuts/hookshot-github-secret-ref.json

5

changelog.md

@@ -0,1 +1,6 @@

# v2.8.0
- Allows Hookshot callers to bring their own webhook secret. This is used for
signature-verification in the `.Github()` case.
# v2.7.0

@@ -2,0 +7,0 @@

@@ -351,2 +351,6 @@ <!-- Generated by documentation.js. Update this documentation by updating the source code. -->

least $context.requestId. [See AWS documentation for details][89].
- `WebhookSecret` **([String][31] \| [Object][30])?** A secret string to be used to verify
payload signatures that are delivered to the endpoint. This is optional. If
not specified, a string will be autogenerated for you. Implementation of
signature verification is up to the caller.

@@ -403,2 +407,7 @@ ### Properties

to a CloudWatch LogGroup named `API-Gateway-Execution-Logs_{rest-api-id}/hookshot`
- `WebhookSecret` **([String][31] \| [Object][30])?** A secret string to be used to verify
payload signatures that are delivered to the endpoint. This is optional. If
not specified, a string will be autogenerated for you. You should provide this
value to Github, and signature verification will be performed prior to your
Lambda function being invoked to respond to the event.

@@ -405,0 +414,0 @@ ### Properties

85

lib/shortcuts/hookshot.js

@@ -55,2 +55,6 @@ 'use strict';

* least $context.requestId. [See AWS documentation for details](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-apigateway-stage-accesslogsetting.html#cfn-apigateway-stage-accesslogsetting-format).
* @param {String|Object} [WebhookSecret] A secret string to be used to verify
* payload signatures that are delivered to the endpoint. This is optional. If
* not specified, a string will be autogenerated for you. Implementation of
* signature verification is up to the caller.
*

@@ -84,3 +88,4 @@ * @example

DataTraceEnabled = false,
MetricsEnabled = false
MetricsEnabled = false,
WebhookSecret
} = options;

@@ -104,11 +109,5 @@

this.PassthroughTo = PassthroughTo;
this.WebhookSecret = options.WebhookSecret;
const Resources = {
[`${Prefix}Secret`]: {
Type: 'AWS::ApiGateway::ApiKey',
Properties: {
Enabled: false
}
},
[`${Prefix}Api`]: {

@@ -189,2 +188,9 @@ Type: 'AWS::ApiGateway::RestApi',

if (!WebhookSecret) Resources[`${Prefix}Secret`] = {
Type: 'AWS::ApiGateway::ApiKey',
Properties: {
Enabled: false
}
};
if (AccessLogFormat) {

@@ -234,3 +240,3 @@ Resources[`${Prefix}AccessLogs`] = {

Description: 'A secret key to give Github to use when signing webhook requests',
Value: { Ref: `${Prefix}Secret` }
Value: WebhookSecret ? WebhookSecret : { Ref: `${Prefix}Secret` }
}

@@ -328,2 +334,7 @@ };

* to a CloudWatch LogGroup named `API-Gateway-Execution-Logs_{rest-api-id}/hookshot`
* @param {String|Object} [WebhookSecret] A secret string to be used to verify
* payload signatures that are delivered to the endpoint. This is optional. If
* not specified, a string will be autogenerated for you. You should provide this
* value to Github, and signature verification will be performed prior to your
* Lambda function being invoked to respond to the event.
*

@@ -355,2 +366,3 @@ * @example

}
method() {

@@ -412,33 +424,38 @@ return {

return {
'Fn::Sub': redent(`
'use strict';
'Fn::Sub': [
redent(`
'use strict';
const crypto = require('crypto');
const AWS = require('aws-sdk');
const lambda = new AWS.Lambda();
const secret = '\${${this.Prefix}Secret}';
const crypto = require('crypto');
const AWS = require('aws-sdk');
const lambda = new AWS.Lambda();
const secret = '\${WebhookSecret}';
module.exports.lambda = (event, context, callback) => {
const body = event.body;
const hash = 'sha1=' + crypto
.createHmac('sha1', secret)
.update(new Buffer(JSON.stringify(body)))
.digest('hex');
module.exports.lambda = (event, context, callback) => {
const body = event.body;
const hash = 'sha1=' + crypto
.createHmac('sha1', secret)
.update(new Buffer(JSON.stringify(body)))
.digest('hex');
if (event.signature !== hash)
return callback('invalid: signature does not match');
if (event.signature !== hash)
return callback('invalid: signature does not match');
if (body.zen) return callback(null, 'ignored ping request');
if (body.zen) return callback(null, 'ignored ping request');
const lambdaParams = {
FunctionName: '\${${this.PassthroughTo}}',
Payload: JSON.stringify(event.body),
InvocationType: 'Event'
const lambdaParams = {
FunctionName: '\${${this.PassthroughTo}}',
Payload: JSON.stringify(event.body),
InvocationType: 'Event'
};
lambda.invoke(lambdaParams).promise()
.then(() => callback(null, 'success'))
.catch((err) => callback(err));
};
lambda.invoke(lambdaParams).promise()
.then(() => callback(null, 'success'))
.catch((err) => callback(err));
};
`).trim()
`).trim(),
{
WebhookSecret: this.WebhookSecret || { Ref: `${this.Prefix}Secret` }
}
]
};

@@ -445,0 +462,0 @@ }

2

package.json
{
"name": "@mapbox/cloudfriend",
"version": "2.7.0",
"version": "2.8.0",
"description": "Helper functions for assembling CloudFormation templates in JavaScript",

@@ -5,0 +5,0 @@ "main": "index.js",

@@ -8,8 +8,2 @@ {

"Resources": {
"PassSecret": {
"Type": "AWS::ApiGateway::ApiKey",
"Properties": {
"Enabled": false
}
},
"PassApi": {

@@ -28,3 +22,3 @@ "Type": "AWS::ApiGateway::RestApi",

"DeploymentId": {
"Ref": "PassDeployment60b3cb7b"
"Ref": "PassDeployment55cc8548"
},

@@ -48,3 +42,3 @@ "StageName": "hookshot",

},
"PassDeployment60b3cb7b": {
"PassDeployment55cc8548": {
"Type": "AWS::ApiGateway::Deployment",

@@ -144,2 +138,8 @@ "DependsOn": "PassMethod",

},
"PassSecret": {
"Type": "AWS::ApiGateway::ApiKey",
"Properties": {
"Enabled": false
}
},
"PassFunctionLogs": {

@@ -211,3 +211,10 @@ "Type": "AWS::Logs::LogGroup",

"ZipFile": {
"Fn::Sub": "'use strict';\n\nconst crypto = require('crypto');\nconst AWS = require('aws-sdk');\nconst lambda = new AWS.Lambda();\nconst secret = '${PassSecret}';\n\nmodule.exports.lambda = (event, context, callback) => {\n const body = event.body;\n const hash = 'sha1=' + crypto\n .createHmac('sha1', secret)\n .update(new Buffer(JSON.stringify(body)))\n .digest('hex');\n\n if (event.signature !== hash)\n return callback('invalid: signature does not match');\n\n if (body.zen) return callback(null, 'ignored ping request');\n\n const lambdaParams = {\n FunctionName: '${Destination}',\n Payload: JSON.stringify(event.body),\n InvocationType: 'Event'\n };\n\n lambda.invoke(lambdaParams).promise()\n .then(() => callback(null, 'success'))\n .catch((err) => callback(err));\n};"
"Fn::Sub": [
"'use strict';\n\nconst crypto = require('crypto');\nconst AWS = require('aws-sdk');\nconst lambda = new AWS.Lambda();\nconst secret = '${WebhookSecret}';\n\nmodule.exports.lambda = (event, context, callback) => {\n const body = event.body;\n const hash = 'sha1=' + crypto\n .createHmac('sha1', secret)\n .update(new Buffer(JSON.stringify(body)))\n .digest('hex');\n\n if (event.signature !== hash)\n return callback('invalid: signature does not match');\n\n if (body.zen) return callback(null, 'ignored ping request');\n\n const lambdaParams = {\n FunctionName: '${Destination}',\n Payload: JSON.stringify(event.body),\n InvocationType: 'Event'\n };\n\n lambda.invoke(lambdaParams).promise()\n .then(() => callback(null, 'success'))\n .catch((err) => callback(err));\n};",
{
"WebhookSecret": {
"Ref": "PassSecret"
}
}
]
}

@@ -214,0 +221,0 @@ },

@@ -18,3 +18,3 @@ 'use strict';

return cf.validate(path.join(__dirname, 'fixtures', 'shortcuts', filename))
.catch(() => assert.fail(`${filename} fixture fails validation`))
.catch((err) => assert.fail(`${filename} fixture fails validation: ${err.message}`))
.then(() => assert.pass(`${filename} fixture passed validation`));

@@ -523,3 +523,3 @@ });

const github = new cf.shortcuts.hookshot.Github({
let github = new cf.shortcuts.hookshot.Github({
Prefix: 'Pass',

@@ -529,3 +529,3 @@ PassthroughTo: 'Destination'

const template = cf.merge(github, to);
let template = cf.merge(github, to);
if (update) fixtures.update('hookshot-github', template);

@@ -538,3 +538,31 @@ assert.deepEqual(

github = new cf.shortcuts.hookshot.Github({
Prefix: 'Pass',
PassthroughTo: 'Destination',
WebhookSecret: 'abc123'
});
template = cf.merge(github, to);
if (update) fixtures.update('hookshot-github-secret-string', template);
assert.deepEqual(
normalizeDeployment(noUndefined(template)),
normalizeDeployment(fixtures.get('hookshot-github-secret-string')),
'expected resources generated when secret passed as string'
);
github = new cf.shortcuts.hookshot.Github({
Prefix: 'Pass',
PassthroughTo: 'Destination',
WebhookSecret: cf.ref('SomeParameter')
});
const Parameters = { SomeParameter: { Type: 'String' } };
template = cf.merge(github, to, { Parameters });
if (update) fixtures.update('hookshot-github-secret-ref', template);
assert.deepEqual(
normalizeDeployment(noUndefined(template)),
normalizeDeployment(fixtures.get('hookshot-github-secret-ref')),
'expected resources generated when secret passed as ref'
);
assert.end();
});
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc