Skip to content

Commit

Permalink
Add webhookKey support (parse-community#1920)
Browse files Browse the repository at this point in the history
  • Loading branch information
TylerBrock committed May 26, 2016
1 parent 0850c18 commit 2561987
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 8 deletions.
59 changes: 55 additions & 4 deletions spec/ParseHooks.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ app.listen(12345);

describe('Hooks', () => {

it("should have some hooks registered", (done) => {
it("should have no hooks registered", (done) => {
Parse.Hooks.getFunctions().then((res) => {
expect(res.constructor).toBe(Array.prototype.constructor);
done();
Expand All @@ -27,7 +27,7 @@ describe('Hooks', () => {
});
});

it("should have some triggers registered", (done) => {
it("should have no triggers registered", (done) => {
Parse.Hooks.getTriggers().then( (res) => {
expect(res.constructor).toBe(Array.prototype.constructor);
done();
Expand Down Expand Up @@ -291,15 +291,15 @@ describe('Hooks', () => {
console.error(err);
fail("Should not fail calling a function");
done();
})
});
});

it("should run the function on the test server", (done) => {

app.post("/SomeFunctionError", function(req, res) {
res.json({error: {code: 1337, error: "hacking that one!"}});
});
// The function is delete as the DB is dropped between calls
// The function is deleted as the DB is dropped between calls
Parse.Hooks.createFunction("SOME_TEST_FUNCTION", hookServerURL+"/SomeFunctionError").then(function(){
return Parse.Cloud.run("SOME_TEST_FUNCTION")
}, (err) => {
Expand All @@ -317,6 +317,57 @@ describe('Hooks', () => {
});
});

it("should provide X-Parse-Webhook-Key when defined", (done) => {
app.post("/ExpectingKey", function(req, res) {
if (req.get('X-Parse-Webhook-Key') === 'hook') {
res.json({success: "correct key provided"});
} else {
res.json({error: "incorrect key provided"});
}
});

Parse.Hooks.createFunction("SOME_TEST_FUNCTION", hookServerURL+"/ExpectingKey").then(function(){
return Parse.Cloud.run("SOME_TEST_FUNCTION")
}, (err) => {
console.error(err);
fail("Should not fail creating a function");
done();
}).then(function(res){
expect(res).toBe("correct key provided");
done();
}, (err) => {
console.error(err);
fail("Should not fail calling a function");
done();
});
});

it("should not pass X-Parse-Webhook-Key if not provided", (done) => {
setServerConfiguration(Object.assign({}, defaultConfiguration, { webhookKey: undefined }));
app.post("/ExpectingKeyAlso", function(req, res) {
if (req.get('X-Parse-Webhook-Key') === 'hook') {
res.json({success: "correct key provided"});
} else {
res.json({error: "incorrect key provided"});
}
});

Parse.Hooks.createFunction("SOME_TEST_FUNCTION", hookServerURL+"/ExpectingKeyAlso").then(function(){
return Parse.Cloud.run("SOME_TEST_FUNCTION")
}, (err) => {
console.error(err);
fail("Should not fail creating a function");
done();
}).then(function(res){
fail("Should not succeed calling that function");
done();
}, (err) => {
expect(err.code).toBe(141);
expect(err.message).toEqual("incorrect key provided");
done();
});
});


it("should run the beforeSave hook on the test server", (done) => {
var triggerCount = 0;
Expand Down
1 change: 1 addition & 0 deletions spec/helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ var defaultConfiguration = {
dotNetKey: 'windows',
clientKey: 'client',
restAPIKey: 'rest',
webhookKey: 'hook',
masterKey: 'test',
collectionPrefix: 'test_',
fileKey: 'test',
Expand Down
14 changes: 11 additions & 3 deletions src/Controllers/HooksController.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import * as DatabaseAdapter from "../DatabaseAdapter";
import * as triggers from "../triggers";
import * as Parse from "parse/node";
import * as request from "request";
import { logger } from '../logger';

const DefaultHooksCollectionName = "_Hooks";

Expand All @@ -12,9 +13,10 @@ export class HooksController {
_collectionPrefix:string;
_collection;

constructor(applicationId:string, collectionPrefix:string = '') {
constructor(applicationId:string, collectionPrefix:string = '', webhookKey) {
this._applicationId = applicationId;
this._collectionPrefix = collectionPrefix;
this._webhookKey = webhookKey;
this.database = DatabaseAdapter.getDatabaseConnection(this._applicationId, this._collectionPrefix).WithoutValidation();
}

Expand Down Expand Up @@ -79,7 +81,7 @@ export class HooksController {
}

addHookToTriggers(hook) {
var wrappedFunction = wrapToHTTPRequest(hook);
var wrappedFunction = wrapToHTTPRequest(hook, this._webhookKey);
wrappedFunction.url = hook.url;
if (hook.className) {
triggers.addTrigger(hook.triggerName, hook.className, wrappedFunction, this._applicationId)
Expand Down Expand Up @@ -153,7 +155,7 @@ export class HooksController {
};
}

function wrapToHTTPRequest(hook) {
function wrapToHTTPRequest(hook, key) {
return (req, res) => {
let jsonBody = {};
for (var i in req) {
Expand All @@ -174,6 +176,12 @@ function wrapToHTTPRequest(hook) {
body: JSON.stringify(jsonBody)
};

if (key) {
jsonRequest.headers['X-Parse-Webhook-Key'] = key;
} else {
logger.warn('Making outgoing webhook request without webhookKey being set!');
}

request.post(hook.url, jsonRequest, function (err, httpResponse, body) {
var result;
if (body) {
Expand Down
4 changes: 3 additions & 1 deletion src/ParseServer.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ class ParseServer {
javascriptKey,
dotNetKey,
restAPIKey,
webhookKey,
fileKey = 'invalid-file-key',
facebookAppIds = [],
enableAnonymousUsers = true,
Expand Down Expand Up @@ -166,7 +167,7 @@ class ParseServer {
const filesController = new FilesController(filesControllerAdapter, appId);
const pushController = new PushController(pushControllerAdapter, appId);
const loggerController = new LoggerController(loggerControllerAdapter, appId);
const hooksController = new HooksController(appId, collectionPrefix);
const hooksController = new HooksController(appId, collectionPrefix, webhookKey);
const userController = new UserController(emailControllerAdapter, appId, { verifyUserEmails });
const liveQueryController = new LiveQueryController(liveQuery);
const cacheController = new CacheController(cacheControllerAdapter, appId);
Expand All @@ -179,6 +180,7 @@ class ParseServer {
javascriptKey: javascriptKey,
dotNetKey: dotNetKey,
restAPIKey: restAPIKey,
webhookKey: webhookKey,
fileKey: fileKey,
facebookAppIds: facebookAppIds,
cacheController: cacheController,
Expand Down

0 comments on commit 2561987

Please sign in to comment.