Skip to content

Commit 2561987

Browse files
committed
Add webhookKey support (#1920)
1 parent 0850c18 commit 2561987

File tree

4 files changed

+70
-8
lines changed

4 files changed

+70
-8
lines changed

spec/ParseHooks.spec.js

Lines changed: 55 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ app.listen(12345);
1717

1818
describe('Hooks', () => {
1919

20-
it("should have some hooks registered", (done) => {
20+
it("should have no hooks registered", (done) => {
2121
Parse.Hooks.getFunctions().then((res) => {
2222
expect(res.constructor).toBe(Array.prototype.constructor);
2323
done();
@@ -27,7 +27,7 @@ describe('Hooks', () => {
2727
});
2828
});
2929

30-
it("should have some triggers registered", (done) => {
30+
it("should have no triggers registered", (done) => {
3131
Parse.Hooks.getTriggers().then( (res) => {
3232
expect(res.constructor).toBe(Array.prototype.constructor);
3333
done();
@@ -291,15 +291,15 @@ describe('Hooks', () => {
291291
console.error(err);
292292
fail("Should not fail calling a function");
293293
done();
294-
})
294+
});
295295
});
296296

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

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

320+
it("should provide X-Parse-Webhook-Key when defined", (done) => {
321+
app.post("/ExpectingKey", function(req, res) {
322+
if (req.get('X-Parse-Webhook-Key') === 'hook') {
323+
res.json({success: "correct key provided"});
324+
} else {
325+
res.json({error: "incorrect key provided"});
326+
}
327+
});
328+
329+
Parse.Hooks.createFunction("SOME_TEST_FUNCTION", hookServerURL+"/ExpectingKey").then(function(){
330+
return Parse.Cloud.run("SOME_TEST_FUNCTION")
331+
}, (err) => {
332+
console.error(err);
333+
fail("Should not fail creating a function");
334+
done();
335+
}).then(function(res){
336+
expect(res).toBe("correct key provided");
337+
done();
338+
}, (err) => {
339+
console.error(err);
340+
fail("Should not fail calling a function");
341+
done();
342+
});
343+
});
344+
345+
it("should not pass X-Parse-Webhook-Key if not provided", (done) => {
346+
setServerConfiguration(Object.assign({}, defaultConfiguration, { webhookKey: undefined }));
347+
app.post("/ExpectingKeyAlso", function(req, res) {
348+
if (req.get('X-Parse-Webhook-Key') === 'hook') {
349+
res.json({success: "correct key provided"});
350+
} else {
351+
res.json({error: "incorrect key provided"});
352+
}
353+
});
354+
355+
Parse.Hooks.createFunction("SOME_TEST_FUNCTION", hookServerURL+"/ExpectingKeyAlso").then(function(){
356+
return Parse.Cloud.run("SOME_TEST_FUNCTION")
357+
}, (err) => {
358+
console.error(err);
359+
fail("Should not fail creating a function");
360+
done();
361+
}).then(function(res){
362+
fail("Should not succeed calling that function");
363+
done();
364+
}, (err) => {
365+
expect(err.code).toBe(141);
366+
expect(err.message).toEqual("incorrect key provided");
367+
done();
368+
});
369+
});
370+
320371

321372
it("should run the beforeSave hook on the test server", (done) => {
322373
var triggerCount = 0;

spec/helper.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ var defaultConfiguration = {
2323
dotNetKey: 'windows',
2424
clientKey: 'client',
2525
restAPIKey: 'rest',
26+
webhookKey: 'hook',
2627
masterKey: 'test',
2728
collectionPrefix: 'test_',
2829
fileKey: 'test',

src/Controllers/HooksController.js

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import * as DatabaseAdapter from "../DatabaseAdapter";
44
import * as triggers from "../triggers";
55
import * as Parse from "parse/node";
66
import * as request from "request";
7+
import { logger } from '../logger';
78

89
const DefaultHooksCollectionName = "_Hooks";
910

@@ -12,9 +13,10 @@ export class HooksController {
1213
_collectionPrefix:string;
1314
_collection;
1415

15-
constructor(applicationId:string, collectionPrefix:string = '') {
16+
constructor(applicationId:string, collectionPrefix:string = '', webhookKey) {
1617
this._applicationId = applicationId;
1718
this._collectionPrefix = collectionPrefix;
19+
this._webhookKey = webhookKey;
1820
this.database = DatabaseAdapter.getDatabaseConnection(this._applicationId, this._collectionPrefix).WithoutValidation();
1921
}
2022

@@ -79,7 +81,7 @@ export class HooksController {
7981
}
8082

8183
addHookToTriggers(hook) {
82-
var wrappedFunction = wrapToHTTPRequest(hook);
84+
var wrappedFunction = wrapToHTTPRequest(hook, this._webhookKey);
8385
wrappedFunction.url = hook.url;
8486
if (hook.className) {
8587
triggers.addTrigger(hook.triggerName, hook.className, wrappedFunction, this._applicationId)
@@ -153,7 +155,7 @@ export class HooksController {
153155
};
154156
}
155157

156-
function wrapToHTTPRequest(hook) {
158+
function wrapToHTTPRequest(hook, key) {
157159
return (req, res) => {
158160
let jsonBody = {};
159161
for (var i in req) {
@@ -174,6 +176,12 @@ function wrapToHTTPRequest(hook) {
174176
body: JSON.stringify(jsonBody)
175177
};
176178

179+
if (key) {
180+
jsonRequest.headers['X-Parse-Webhook-Key'] = key;
181+
} else {
182+
logger.warn('Making outgoing webhook request without webhookKey being set!');
183+
}
184+
177185
request.post(hook.url, jsonRequest, function (err, httpResponse, body) {
178186
var result;
179187
if (body) {

src/ParseServer.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ class ParseServer {
9898
javascriptKey,
9999
dotNetKey,
100100
restAPIKey,
101+
webhookKey,
101102
fileKey = 'invalid-file-key',
102103
facebookAppIds = [],
103104
enableAnonymousUsers = true,
@@ -166,7 +167,7 @@ class ParseServer {
166167
const filesController = new FilesController(filesControllerAdapter, appId);
167168
const pushController = new PushController(pushControllerAdapter, appId);
168169
const loggerController = new LoggerController(loggerControllerAdapter, appId);
169-
const hooksController = new HooksController(appId, collectionPrefix);
170+
const hooksController = new HooksController(appId, collectionPrefix, webhookKey);
170171
const userController = new UserController(emailControllerAdapter, appId, { verifyUserEmails });
171172
const liveQueryController = new LiveQueryController(liveQuery);
172173
const cacheController = new CacheController(cacheControllerAdapter, appId);
@@ -179,6 +180,7 @@ class ParseServer {
179180
javascriptKey: javascriptKey,
180181
dotNetKey: dotNetKey,
181182
restAPIKey: restAPIKey,
183+
webhookKey: webhookKey,
182184
fileKey: fileKey,
183185
facebookAppIds: facebookAppIds,
184186
cacheController: cacheController,

0 commit comments

Comments
 (0)