├── .gitignore ├── .jshintrc ├── History.md ├── Makefile ├── Procfile ├── README.md ├── config ├── development.config.js ├── index.js └── production.config.js ├── index.js ├── package.json └── server ├── index.js └── middlewares ├── check-access-token.js ├── cors.js ├── index.js ├── ssl.js └── validate-event.js /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | *.log 4 | .env 5 | 6 | config/development.config*.js -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "predef": [ 3 | "angular", 4 | "after", 5 | "afterEach", 6 | "before", 7 | "beforeEach", 8 | "chai", 9 | "describe", 10 | "expect", 11 | "iit", 12 | "it", 13 | "runs", 14 | "sinon", 15 | "spyOn", 16 | "waits", 17 | "waitsFor", 18 | "xit", 19 | "xdescribe", 20 | "define", 21 | "module", 22 | "exports", 23 | "require", 24 | "window", 25 | "process", 26 | "console", 27 | "twttr", 28 | "FB", 29 | "__dirname", 30 | "Buffer" 31 | ], 32 | 33 | "asi" : false, 34 | "bitwise" : true, 35 | "boss" : false, 36 | "browser" : true, 37 | "curly" : true, 38 | "debug": false, 39 | "devel": false, 40 | "eqeqeq": true, 41 | "evil": false, 42 | "expr": true, 43 | "forin": false, 44 | "immed": true, 45 | "latedef" : false, 46 | "laxbreak": false, 47 | "multistr": true, 48 | "newcap": true, 49 | "noarg": true, 50 | "noempty": false, 51 | "nonew": true, 52 | "onevar": false, 53 | "plusplus": false, 54 | "regexp": false, 55 | "strict": false, 56 | "globalstrict": true, 57 | "sub": false, 58 | "trailing" : true, 59 | "undef": true, 60 | "unused": "vars" 61 | } -------------------------------------------------------------------------------- /History.md: -------------------------------------------------------------------------------- 1 | 2 | 1.0.0 / 2015-11-13 3 | ================== 4 | 5 | * Update Dependency democracyos-notifier to DemocracyOS/notifier 6 | * Replace master branch contents with the contents of 1.0.0 7 | 8 | 1.0.0rc / 2015-08-25 9 | ==================== 10 | 11 | * add nodemailer 12 | * fix ssl redirection, only when protocol is http 13 | * log forwarding header for debugging 14 | * fix debug scope of ssl middleware 15 | * fix typo 16 | * [config] - Add organizationEmail config parameter 17 | * [config] - Add organizationName config parameter 18 | * Update repositories, contact and description in package.json 19 | * Update status codes for error responses (40x) 20 | * Remove 'engines' declaration from package.json 21 | * Update Procfile 22 | * Remove unncesary directories and files. Rewrite config module. 23 | * Rewrite notifier-server to use democracyos-notifier 24 | * Start rewriting notifier-server 25 | * Update version compatibility warning 26 | * Bump to 0.3.1 27 | * Fix RESET_PASSWORD_URL on templates Closes #37 28 | * Release 0.3.0 29 | * [topic] - Rename law to topic. Closes #35 30 | * [topic-published] - Update feed to new forum and topic format #35 31 | * [topic-commented] - Update feed to new forum and topic format #35 32 | * [topic-voted] - Update feed to new forum and topic format #35 33 | * Release 0.2.1 34 | * [feed] - Add feededAt attribute on model 35 | 36 | 0.3.1 / 2015-06-11 37 | ================== 38 | 39 | * Fix RESET_PASSWORD_URL on templates #37 40 | 41 | 0.3.0 / 2015-06-02 42 | ================== 43 | 44 | * Rename law to topic. Closes #35 45 | * Update feed to new forum and topic format #35 46 | 47 | 0.2.1 / 2015-03-25 48 | ================== 49 | 50 | * Add feededAt attribute on feed model 51 | 52 | 0.2.0 / 2015-03-19 53 | ================== 54 | 55 | * Add HTTP->HTTPS redirection for heroku 56 | 57 | 0.1.11 / 2015-03-12 58 | ================== 59 | 60 | * Update some translations 61 | 62 | 0.1.10 / 2015-03-11 63 | ================== 64 | 65 | * add 'deploymentId' on 'law-published' feeds 66 | 67 | 0.1.9 / 2015-03-06 68 | ================== 69 | 70 | * [update-feed] - Fix getting instance url from action 71 | 72 | 0.1.8 / 2015-03-06 73 | ================== 74 | 75 | * [law-commented] - Add a new feed story when 'law-commented' is received 76 | * [law-voted] - Add a new feed story when 'law-voted' is received 77 | 78 | 0.1.7 / 2015-02-26 79 | ================== 80 | 81 | * Add saving new feed for new published law 82 | 83 | 0.1.6 / 2015-01-28 84 | ================== 85 | 86 | * Add russian translation 87 | 88 | 0.1.5 / 2015-01-22 89 | ================== 90 | 91 | * Update configuration default aliases from user->citizens to user->users 92 | 93 | 0.1.4 / 2015-01-17 94 | ================== 95 | 96 | * Add Galician translation 97 | * Add Ukrainian transolation 98 | * added uk.json support 99 | * Remove non-user database access for 'law-published' event. Closes #22 100 | * Change MONGO_CONNECTION to MONGO_URL. Closes #23 101 | * Add app port to '/' response JSON 102 | 103 | 0.1.3 / 2014-12-07 104 | ================== 105 | 106 | * Add German, Dutch and Portuguese translations 107 | * Remove 'DemocracyOS' from mail subjects 108 | * Fix existing translations 109 | * Add PORT variable to config 110 | 111 | 0.1.2 / 2014-12-04 112 | ================== 113 | 114 | * remove unneeded data from argument-replies flow #9 115 | * update codebase to version 0.1.0 of likeastore/notifier 116 | 117 | 0.1.1 / 2014-12-01 118 | ================== 119 | 120 | * Add support for notifying 'law-published' and fix 'reply-comment'. Closes #17 121 | * Update texts for 'reply-argument' event and template 122 | * Notify user on reply argument only if he has enabled it in their notifications preferences #7 123 | * Add reply-argument notification 124 | * Add 'resend-validation-email' handler, as it's the same as the 'signup' one 125 | * Refactor app.js and make event handling logic self-contained 126 | * Add basic app.js 127 | * Update README.md with description on collection name aliasing 128 | * Add debug dep and update makefile 129 | * Add support for aliasing db collection names 130 | * Add flexibility for 'name' property definition in users 131 | * Fetch port optionally from config file 132 | * Fix mail template not escaping HTML 133 | * Update welcome-email subject and tempalte 134 | * Update welcome-email template and translations 135 | * Add translations engine 136 | * Fix template vars usage to be uncoupled from mandrill 137 | * Fix welcome flow 138 | * Add basic templates 139 | * Add dev settings to `.gitignore` 140 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # DemocracyOS Makefile 3 | # 4 | 5 | BABEL="./node_modules/.bin/babel-node" 6 | 7 | ifndef DEBUG 8 | DEBUG="democracyos:notifier-server*" 9 | endif 10 | 11 | ifndef NODE_ENV 12 | NODE_ENV="development" 13 | endif 14 | 15 | run: packages 16 | @echo "Starting application..." 17 | @NODE_PATH=. DEBUG=$(DEBUG) $(BABEL) index.js 18 | 19 | packages: 20 | @echo "Installing dependencies..." 21 | @npm install 22 | @echo "Done.\n" 23 | 24 | clean: 25 | @echo "Removing dependencies, components and built assets." 26 | @rm -rf node_modules components public 27 | @echo "Done.\n" 28 | 29 | 30 | .PHONY: clean -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: npm start -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Notifier 2 | 3 | HTTP API that receives the event and turning that event into corresponding notification. 4 | 5 | ## Note about 1.0.0 branch 6 | 7 | This version of `notifier` is intended to be used **only** with DemocracyOS ~1.0.0 8 | 9 | ## API 10 | 11 | The entry point of application responsible for initializing the `notifier`. 12 | 13 | ```js 14 | var notifier = require('./source/notifier'); 15 | 16 | notifier.start(5050); 17 | ``` 18 | 19 | To initialize the `notifier` you should create 3 entities - `actions`, `resolvers` and `executors`. 20 | 21 | ### Receiving event 22 | 23 | `notifier` exposes `.receive()` call to initialize particular action. The action `callback` is called then `server` receives event with defined type. 24 | 25 | ```js 26 | notifier.receive('user-registered', function (event, actions, callback) { 27 | actions.create('send-welcome-email', {user: event.user}, callback); 28 | }); 29 | ``` 30 | 31 | You can define as many actions as you need for same event. 32 | 33 | ```js 34 | notifier.receive('user-payment-recieved', function (event, actions, callback) { 35 | actions.create('send-invoice-email', {user: event.user, payment: event.amount}, callback); 36 | }); 37 | 38 | notifier.receive('user-payment-recieved', function (event, actions, callback) { 39 | actions.create('notify-developers-sms', {user: event.user}, callback); 40 | }); 41 | ``` 42 | 43 | ### Resolving action 44 | 45 | To resolve an action, `notifier` should define resolved. Usually resolve calls database or other service for additional data. 46 | 47 | ```js 48 | notifier.resolve('user-registered', function (action, actions, callback) { 49 | db.user.findOne({email: action.email}, function (err, user) { 50 | if (err) { 51 | return callback(err); 52 | } 53 | 54 | var data = { 55 | email: user.email, 56 | firstName: user.firstName, 57 | secondName: user.secondName, 58 | registered: user.registered 59 | }; 60 | 61 | actions.resolved(action, data, callback); 62 | }); 63 | }); 64 | ``` 65 | 66 | Note, there should be only one resolve function for action, otherwise the exception is thrown. 67 | 68 | ### Skipping action 69 | 70 | For any reason, action could be skipped, means that it could be resolved but will not be executed. 71 | 72 | ```js 73 | notifier.resolve('user-registered', function (action, actions, callback) { 74 | db.user.findOne({email: action.email}, function (err, user) { 75 | if (err) { 76 | return callback(err); 77 | } 78 | 79 | if (user.email === 'test@example.com') { 80 | return actions.skipped(action, callback); 81 | } 82 | 83 | actions.resolved(action, {data: 123}, callback); 84 | }); 85 | }); 86 | ``` 87 | 88 | 89 | ### Executing action 90 | 91 | Once action got resolve, it's ready to be executed. 92 | 93 | ```js 94 | notifier.execute('user-registered', function (action, transport, callback) { 95 | var vars = [ 96 | {name: 'FIRST_NAME', content: action.data.firstName} 97 | {name: 'SECOND_NAME', content: action.data.secondName} 98 | {name: 'REGISTERED_DATE', content: action.data.registered} 99 | ]; 100 | 101 | transport.mandrill('/messages/send-template', { 102 | template_name: 'welcome-email', 103 | template_content: [], 104 | 105 | message: { 106 | to: [{email: user.email}], 107 | global_merge_vars: vars 108 | } 109 | }, callback); 110 | }); 111 | ``` 112 | 113 | ### Events aggregation 114 | 115 | TDB. 116 | 117 | ## Transports 118 | 119 | Each `.execute()` function callback receives `transport` object, which exposes intialized transports clients libraries. 120 | 121 | Supported now: 122 | * [Mandrill](https://github.com/jimrubenstein/node-mandrill) 123 | * [Twilio](https://github.com/twilio/twilio-node) 124 | * [Android push notification](https://github.com/ToothlessGear/node-gcm) 125 | * [iOS push notification](https://github.com/argon/node-apn) 126 | 127 | Will be added soon: 128 | * [Mailgun](https://github.com/jimrubenstein/node-mandrill) 129 | 130 | If you want to extend transport support: 131 | 132 | 1. Fork this repo 133 | 2. Update [transport.js](/source/transport.js) 134 | 3. Update [config/*.js](/config/development.js) files with new transport section. 135 | 4. Send PR. 136 | 137 | 138 | 139 | If you want to use `notifier` with an existing DB, you'll probably want keep your schema going. Since `notifier` can't know your DB collection names beforehand, you can manually specify aliases for them. Just add an `aliases` object under the `db` object in your `config` files. 140 | 141 | ```js 142 | 143 | db: { 144 | connection: /*...your db connection string...*/, 145 | aliases: { 146 | user: "players", 147 | } 148 | } 149 | ``` 150 | 151 | This will make `db.user` actually end up using the `players` collection when querying the DB. 152 | 153 | ## REST Hooks 154 | 155 | When `notifier` completed `execution` and you want to notify external service about it, use [REST hooks](http://resthooks.org/). 156 | Let's say we want to notify external service that push notification failed for some reason, for that purpose we use 157 | `notifier.sendHook(event,data)` 158 | 159 | ```js 160 | transport.android.push({ message: message, regIds: regIds, retries: 1}, function (err, result) { 161 | if (err || result.failure === 1) { 162 | var data = { 163 | clientId: a.data.clientId, 164 | message: message, 165 | status: result.success 166 | }; 167 | 168 | notifier.sendHook('notify.sms', data); 169 | } 170 | 171 | return callback(err, result); 172 | }); 173 | ``` 174 | Note, that you have to setup config with hook configuration, namely: 175 | 176 | ```js 177 | hook: { 178 | url: 'http://localhost:5000/api/notify/', 179 | token: 'fake-hook-token' 180 | }, 181 | ``` 182 | where `url` is url of your external system that you'd like to notify and `token` is simply authentication mechanism to be able to talk to our external system. 183 | 184 | 185 | ## How to use? 186 | 187 | Clone repo, 188 | 189 | ```bash 190 | $ git clone git@github.com:likeastore/notifier.git 191 | ``` 192 | 193 | Create `app.js` file, 194 | 195 | ```js 196 | var notifier = require('./source/notifier'); 197 | 198 | // initialize actions, resolvers and executors 199 | notifier 200 | .receive('incoming-event', function () { /* ... */ }) 201 | .resolve('created-action', function () { /* ... */ }) 202 | .execute('created-action', function () { /* ... */ }); 203 | 204 | // start the server 205 | notifier.start(process.env.PORT); 206 | ``` 207 | 208 | Update `development.config.js` and `production.config.js` configuration. For now, configuration requires connection string to MongoDB, accessToken (shared secret) to access service, mandrill and logentries tokens. 209 | 210 | Commit the changes and deploy (heroku, dokku, aws). 211 | 212 | ```bash 213 | $ git push master heroku 214 | ``` 215 | 216 | Check the server deployed fine, 217 | 218 | ```bash 219 | $ curl http://notifier.likeastore.com/ 220 | {"app":"notifier","env":"production","version":"0.0.5","apiUrl":"/api"}% 221 | ``` 222 | 223 | Send first notification, 224 | 225 | ```bash 226 | $ echo '{"event": "incoming-event"}' | curl -H "Content-Type:application/json" -d @- http://notifier.likeastore.com/api/events?access_token=ACCESS_TOKEN 227 | ``` 228 | 229 | ## Getting started 230 | 231 | Check the following code for guidance. 232 | 233 | * [example/server.js](example/server.js) with ready to use `notifier` server. 234 | * [production](https://github.com/likeastore/notifier/tree/production) version of notifier used by Likeastore 235 | 236 | ## Used by 237 | 238 | * [Likeastore](https://likeastore.com) 239 | * [DemocracyOS](http://democracyos.org) 240 | * [Tapreserve](http://tapreserve.com) 241 | 242 | (if you are one of the user, please send a PR to extend the list) 243 | 244 | # License (MIT) 245 | 246 | Copyright (c) 2014, Likeastore.com info@likeastore.com 247 | 248 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 249 | 250 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 251 | 252 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 253 | -------------------------------------------------------------------------------- /config/development.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | locale: 'en', 3 | port: 9001, 4 | mongoUrl: 'mongodb://localhost/DemocracyOS-dev', 5 | accessToken: '123', 6 | organizationName: 'The DemocracyOS Team', 7 | organizationEmail: 'noreply@democracyos.org', 8 | mailer: { 9 | service: '', 10 | auth: { 11 | user: '', 12 | pass: '' 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /config/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Constants definition 3 | */ 4 | 5 | const env = process.env.NODE_ENV || 'development'; 6 | 7 | module.exports = require(`./${env}.config.js`); 8 | -------------------------------------------------------------------------------- /config/production.config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Constants definition 3 | */ 4 | 5 | const env = process.env 6 | 7 | export default { 8 | locale: env.LOCALE, 9 | port: env.PORT, 10 | mongoUrl: env.MONGO_URL, 11 | accessToken: env.ACCESS_TOKEN, 12 | organizationName: env.ORGANIZATION_NAME, 13 | organizationEmail: env.ORGANIZATION_EMAIL, 14 | mailer: { 15 | service: env.MAILER_SERVICE, 16 | auth: { 17 | user: env.MAILER_AUTH_USER, 18 | pass: env.MAILER_AUTH_PASS 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Module Dependencies 3 | */ 4 | 5 | import app from './server' 6 | import config from './config' 7 | import debug from 'debug' 8 | 9 | /** 10 | * Constants definition 11 | */ 12 | 13 | const log = debug('democracyos:notifier-server') 14 | const port = config.port || 9001 15 | 16 | app.listen(port, () => { 17 | log(`App started at port ${port}`) 18 | }) 19 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "notifier-server", 3 | "version": "1.0.0", 4 | "description": "Service for sending notifications to users.", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "NODE_PATH=. DEBUG=democracyos:notifier-server* babel-node index.js" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git://github.com/DemocracyOS/notifier-server.git" 12 | }, 13 | "author": "Democracia en Red ", 14 | "license": "MIT", 15 | "bugs": { 16 | "url": "https://github.com/DemocracyOS/notifier-server/issues" 17 | }, 18 | "homepage": "https://github.com/DemocracyOS/notifier", 19 | "dependencies": { 20 | "apn": "^1.6.0", 21 | "babel": "^5.8.21", 22 | "body-parser": "^1.13.3", 23 | "cookie-parser": "^1.3.5", 24 | "debug": "^0.7.4", 25 | "democracyos-notifier": "DemocracyOS/notifier", 26 | "express": "^4.13.3", 27 | "method-override": "^2.3.5", 28 | "moment": "~2.6.0", 29 | "node-gcm": "^0.9.12", 30 | "node-logentries": "~0.1.4", 31 | "request": "~2.21.0", 32 | "underscore": "^1.7.0" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /server/index.js: -------------------------------------------------------------------------------- 1 | import { cors, ssl, checkAccessToken, validateEvent } from 'server/middlewares' 2 | import bodyParser from 'body-parser' 3 | import config from 'config' 4 | import cookieParser from 'cookie-parser' 5 | import debug from 'debug' 6 | import methodOverride from 'method-override' 7 | import express from 'express' 8 | import pack from 'package' 9 | import notifier from 'democracyos-notifier' 10 | 11 | /** 12 | * Constants definition 13 | */ 14 | 15 | const app = express() 16 | const log = debug('democracyos:notifier-server:app') 17 | 18 | /** 19 | * Bind middlewares 20 | */ 21 | 22 | app.use(ssl) 23 | app.use(bodyParser.json()) 24 | app.use(bodyParser.urlencoded({ extended: true })) 25 | app.use(cookieParser()) 26 | app.use(cors) 27 | app.use(methodOverride()) 28 | 29 | app.get('/', function (req, res) { 30 | res.json({app: pack.name, env: process.env.NODE_ENV, port: config.port, version: pack.version, apiUrl: '/api'}) 31 | }) 32 | 33 | app.post('/api/events', checkAccessToken, validateEvent, (req, res) => { 34 | const { event } = req.body 35 | 36 | notifier.notify(req.body, (err) => { 37 | if (err) { 38 | log('Error when sending notification for event %s: %j', event, err); 39 | return res.status(500).send(err); 40 | } 41 | 42 | log(`Success on ${event}`); 43 | res.sendStatus(201) 44 | }) 45 | }) 46 | 47 | const opts = { 48 | mongoUrl: config.mongoUrl, 49 | organizationName: config.organizationName, 50 | organizationEmail: config.organizationEmail, 51 | mandrillToken: config.mandrillToken, 52 | mailer: config.mailer 53 | } 54 | 55 | const httpListen = app.listen 56 | app.listen = function listen(port, callback) { 57 | log('About to start embedded notifier notifier with options: %j', opts) 58 | 59 | notifier(opts, function (err) { 60 | if (err) return log('Unexpected error while starting embedded notifications service: %s', err) 61 | 62 | log('Embedded notifications service started') 63 | httpListen.call(app, port, callback) 64 | }) 65 | } 66 | 67 | export default app 68 | -------------------------------------------------------------------------------- /server/middlewares/check-access-token.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Module Dependencies 3 | */ 4 | 5 | import config from 'config' 6 | 7 | 8 | export default function checkAccessToken(req, res, next) { 9 | var accessToken = req.query.access_token; 10 | 11 | if (!accessToken) { 12 | return res.send(400, {message: 'access_token is missing'}); 13 | } 14 | 15 | if (accessToken !== config.accessToken) { 16 | return res.send(403, {message: 'access_token is wrong'}); 17 | } 18 | 19 | next(); 20 | } -------------------------------------------------------------------------------- /server/middlewares/cors.js: -------------------------------------------------------------------------------- 1 | /** 2 | * CORS express middleware 3 | */ 4 | 5 | export default function cors(req, res, next) { 6 | res.header('Access-Control-Allow-Origin', '*') 7 | res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE') 8 | res.header('Access-Control-Allow-Headers', 'X-Requested-With, X-Access-Token, X-Revision, Content-Type') 9 | 10 | next() 11 | } 12 | -------------------------------------------------------------------------------- /server/middlewares/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Module Dependencies 3 | */ 4 | 5 | import cors from './cors' 6 | import ssl from './ssl' 7 | import checkAccessToken from './check-access-token' 8 | import validateEvent from './validate-event' 9 | 10 | export default { ssl, cors, checkAccessToken, validateEvent } -------------------------------------------------------------------------------- /server/middlewares/ssl.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Module Dependencies 3 | */ 4 | 5 | import debug from 'debug' 6 | 7 | /** 8 | * Constants definition 9 | */ 10 | 11 | const log = debug('democracyos:notifier-server:ssl') 12 | const env = process.env.NODE_ENV 13 | const prod = env === 'production' 14 | 15 | /** 16 | * Force load with https on parameter environments (defaults to production) 17 | * https://devcenter.heroku.com/articles/http-routing#heroku-headers 18 | * 19 | * Orignal function from https://github.com/paulomcnally/node-heroku-ssl-redirect 20 | * 21 | * WARNING: only use in a heroku (or other reverse-proxy) environments 22 | */ 23 | 24 | //TODO: replace this with `ssl` module from `DemocracyOS/app` 25 | 26 | export default function herokuSslRedirect(req, res, next) { 27 | const https = req.headers['x-forwarded-proto'] === 'https' 28 | if (!prod || https) return next() 29 | 30 | const redirectionUrl = `https://${req.host}${req.originalUrl}` 31 | log(`About to force redirection to ${redirectionUrl}`) 32 | res.redirect(redirectionUrl) 33 | } 34 | -------------------------------------------------------------------------------- /server/middlewares/validate-event.js: -------------------------------------------------------------------------------- 1 | /** 2 | * TODO: Validate event 3 | */ 4 | 5 | export default function validateEvent(req, res, next) { 6 | next(); 7 | } --------------------------------------------------------------------------------