Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions example/jokeChatServer.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const Bot = require('../build');
const express = require('express');
const bodyParser = require('body-parser')
const Promise = require('bluebird');
const helmet = require('helmet');

const JOKE = "Did you know photons had mass? I didn't even know they were Catholic.";
const RiddleImageUrl ="http://tinyurl.com/he9tsph";
Expand Down Expand Up @@ -164,6 +165,7 @@ function makeServer() {
});

const app = express();
app.use(helmet());

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
Expand Down
13 changes: 11 additions & 2 deletions src/FBLocalChatRoutes.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import invariant from 'invariant';
import fs from 'fs';
import dot from 'dot';
import path from 'path';
import rateLimit from 'express-rate-limit'; // Import rate limiting middleware
import sanitizeHtml from 'sanitize-html'; // Import a library to sanitize HTML

const FBLocalChatRoutes = (router: Router, Bot: Object): Router => {
router.get('/localChat/getMessages', (req, res) => {
Expand Down Expand Up @@ -102,7 +104,13 @@ const FBLocalChatRoutes = (router: Router, Bot: Object): Router => {
res.sendStatus(200);
});

router.get('/localChat/*', (req, res) => {
// Apply rate limiting to the endpoint
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100 // limit each IP to 100 requests per windowMs
});

router.get('/localChat/*', limiter, (req, res) => {
const dir = path.join(path.dirname(__filename), '..', 'localChatWeb');
var filePath = req.url.replace('/localChat', '');
if (filePath !== '/') {
Expand All @@ -119,7 +127,8 @@ const FBLocalChatRoutes = (router: Router, Bot: Object): Router => {
return;
}
var tempFn = dot.template(data);
res.send(tempFn({baseURL}));
// Sanitize the input to prevent XSS
res.send(tempFn({baseURL: sanitizeHtml(baseURL)}));
});
});

Expand Down
62 changes: 34 additions & 28 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,9 @@ class Bot extends EventEmitter {
});

router.post('/', (req, res) => {
this.handleMessage(req.body);
if (typeof req.body === 'object' && req.body !== null) {
this.handleMessage(req.body);
}
res.sendStatus(200);
});

Expand Down Expand Up @@ -108,34 +110,38 @@ class Bot extends EventEmitter {
return;
}

data.entry.forEach((entry) => {
entry.messaging.forEach((event) => {
// handle messages
if (event.message) {
// Since a message containing a quick_reply can also contain text
// and attachment, check for quick_reply first
if (event.message.quick_reply) {
this.emit('quick_reply', event);
return;
}
if (event.message.text) {
this.emit('text', event);
} else if (event.message.attachments) {
this.emit('attachments', event);
}
}

// handle postback
if (event.postback && event.postback.payload) {
this.emit('postback', event);
if (Array.isArray(data.entry)) {
data.entry.forEach((entry) => {
if (entry.messaging && Array.isArray(entry.messaging)) {
entry.messaging.forEach((event) => {
// handle messages
if (event.message) {
// Since a message containing a quick_reply can also contain text
// and attachment, check for quick_reply first
if (event.message.quick_reply) {
this.emit('quick_reply', event);
return;
}
if (event.message.text) {
this.emit('text', event);
} else if (event.message.attachments) {
this.emit('attachments', event);
}
}

// handle postback
if (event.postback && event.postback.payload) {
this.emit('postback', event);
}
// Handle authentication
if (event.optin && event.optin.ref) {
this.emit('optin', event);
}
// TODO: handle message delivery
});
}
// Handle authentication
if (event.optin && event.optin.ref) {
this.emit('optin', event);
}
// TODO: handle message delivery
})
});
});
}
}

/**
Expand Down