-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathindex.js
122 lines (114 loc) · 4.06 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
var EventEmitter = require('events');
var express = require('express');
var jwt = require('jsonwebtoken');
var methods = require('./methods');
var methodUtils = require('./methodUtils');
exports.appId = null;
exports.appSecret = null;
var events = new EventEmitter();
// standalone function to verify event tokens
events.verifyToken = function (token, userId) {
var payload = null;
try {
payload = jwt.verify(token, exports.appSecret, {
algorithms: ['HS256']
});
} catch (e) {
console.warn('Got error while verifying token: ' + e);
}
if (payload) {
if (!(payload.appId && payload.appId === exports.appId)) {
return null;
}
if (userId && !(payload.userId && payload.userId === userId)) {
return null;
}
}
return payload;
};
// express middleware to verify event tokens
// works for events sent to event listener, and widget/browser URLs
events.tokenVerifier = function (req, res, next) {
// if res.locals.eventTokenPayload exists, we've already run the
// token verifier, no need to run it again
if (!res.locals.eventTokenPayload) {
var token = req.get('x-flock-event-token') || req.query.flockEventToken;
if (token) {
// if userId is given, include it for verification
var userId = null;
if (req.is('application/json') && req.body) {
userId = req.body.userId;
} else if (req.query.flockEvent) {
try {
var event = JSON.parse(req.query.flockEvent);
userId = event.userId;
} catch (e) {
//console.warn('Couldn't parse flockEvent query param');
}
}
var payload = events.verifyToken(token, userId);
if (!payload) {
console.warn('Invalid event token', token);
res.sendStatus(403);
return;
}
res.locals.eventTokenPayload = payload;
}
}
next();
};
// express middleware that listens for events sent to the event listener URL
// use events.on() to listen for events in your application
events.listener = express.Router();
events.listener.use(require('body-parser').json());
events.listener.use(events.tokenVerifier);
events.responseTimeout = 60 * 1000;
events.listener.use(function (req, res, next) {
console.log('received request: ', req.method, req.url, req.headers);
console.log('received event: %j', req.body);
var event = req.body;
var responded = false;
var timeoutID = null;
events.listeners(event.name).forEach(function (listener) {
try {
listener(event, function (error, body) {
if (responded) {
console.warn('(%s) Only one listener can respond to an event', event.name);
return;
}
responded = true;
if (timeoutID) {
clearTimeout(timeoutID);
}
if (error) {
var statusCode = error.statusCode || 400;
res.status(statusCode).send({ error: error.name,
description: error.message });
} else if (body && typeof body === 'object' || typeof body === 'string') {
res.send(body);
} else {
res.send({});
}
});
} catch (e) {
console.warn('(%s) Got an error in event listener', event.name, e);
}
});
// respond to an event after events.responseTimeout if none of the
// listeners do by then
if (!responded) {
timeoutID = setTimeout(function () {
res.send({});
}, events.responseTimeout);
}
});
Object.defineProperty(exports, 'baseUrl', {
set: function(value) {
methodUtils.baseUrl = value;
},
get: function() {
return methodUtils.baseUrl;
}
});
exports.events = events;
Object.assign(exports, methods, methodUtils);