1
var express = require('express')
2
, bodyParser = require('body-parser')
4
var Registry = require('./lib/registry')
5
, Inbox = require('./lib/inbox')
6
, Notifier = require('./lib/notifier')
8
function wire(db, cfg) {
9
var reg, inbox, notifier, app
11
// control whether not to have persistent inboxes
12
var no_inbox = cfg.no_inbox
16
reg = new Registry(db)
22
var push_url = process.env.PUSH_URL || cfg.push_url
23
notifier = new Notifier(push_url, cfg)
24
notifier.on('unknownToken', function(nick, token) {
25
reg.removeToken(nick, token, function() {},
27
app.emit('mongoError', err)
30
notifier.on('pushError', function(err, resp, body) {
31
app.emit('pushError', err, resp, body)
34
function unavailable(resp, err) {
35
app.emit('mongoError', err)
36
var ctype = resp.get('Content-Type')
37
if (ctype&&ctype.substr(0,10) == 'text/plain') {
38
resp.send(503, "db is hopefully only momentarily :(\n")
40
resp.json(503, {error: "unavailable"})
44
app.get("/_check", function(req, resp) {
45
db.command({ping: 1}, function(err, res) {
49
unavailable(resp, err)
54
app.use(bodyParser.json())
55
app.use('/play-notify-form', bodyParser.urlencoded({extended: false}))
56
app.use(function(err, req, resp, next) {
57
resp.json(err.status, {error: "invalid", message: err.message})
60
app.get("/", function(req, resp) {
61
if (!cfg.play_notify_form) {
62
resp.sendfile(__dirname + '/index.html')
64
resp.sendfile(__dirname + '/notify-form.html')
68
// NB: simplified, minimal identity and auth piggybacking on push tokens
71
POST /register let's register a pair nick, token taking a JSON obj:
72
{ "nick": string, "token": token-string }
74
app.post("/register", function(req, resp) {
75
if(typeof(req.body.token) != "string" ||
76
typeof(req.body.nick) != "string" ||
77
req.body.token == "" || req.body.nick == "") {
78
resp.json(400, {"error": "invalid"})
81
reg.insertToken(req.body.nick, req.body.token, function() {
84
resp.json(400, {"error": "dup"})
86
unavailable(resp, err)
90
function checkToken(nick, token, okCb, resp) {
92
resp.json(401, {error: "unauthorized"})
94
reg.findToken(nick, function(nickToken) {
95
if (nickToken == token) {
100
}, bad, function(err) {
101
unavailable(resp, err)
107
ephemeral is true: message not put in the inbox, _ephemeral flag added
109
ephemeral is false: message put in inbox, with added unix _timestamp and
113
function doNotify(ephemeral, nick, data, okCb, unknownNickCb, resp) {
114
function notify(token, data) {
115
notifier.notify(nick, token, data)
118
reg.findToken(nick, function(token) {
119
if (ephemeral||no_inbox) {
120
data._ephemeral = Date.now()
123
inbox.pushMessage(token, data, function(msg) {
126
unavailable(resp, err)
129
}, function() { // not found
132
unavailable(resp, err)
137
POST /message let's send a message to nick taking a JSON obj:
138
{ "nick": string, "data": data, "from_nick": string, "from_token": string}
140
app.post("/message", function(req, resp) {
141
if (!req.body.data||!req.body.nick||!req.body.from_token||!req.body.from_nick) {
142
resp.json(400, {"error": "invalid"})
145
checkToken(req.body.from_nick, req.body.from_token, function() {
146
var data = req.body.data
147
data._from = req.body.from_nick
148
doNotify(false, req.body.nick, data, function() {
149
resp.json({ok: true})
150
}, function() { // not found
151
resp.json(400, {"error": "unknown-nick"})
156
if (!no_inbox) { // /drain supported only if no_inbox false
158
POST /drain let's get pending messages for nick+token:
159
it removes messages older than timestamp and return newer ones
160
{ "nick": string, "token": string, "timestamp": unix-timestamp }
162
app.post("/drain", function(req, resp) {
163
if(!req.body.token||!req.body.nick||
164
typeof(req.body.timestamp) != "number") {
165
resp.json(400, {"error": "invalid"})
168
checkToken(req.body.nick, req.body.token, function() {
169
inbox.drain(req.body.token, req.body.timestamp, function(msgs) {
170
resp.json(200, {ok: true, msgs: msgs})
172
unavailable(resp, err)
179
Form /play-notify-form
180
messages sent through the form are ephemeral, just transmitted through PN,
181
without being pushed into the inbox
183
if (cfg.play_notify_form) {
184
app.post("/play-notify-form", function(req, resp) {
185
resp.type('text/plain')
186
if (!req.body.data||!req.body.nick) {
187
resp.send(400, "invalid/empty fields\n")
192
data = JSON.parse(req.body.data)
194
resp.send(400, "data is not JSON\n")
197
doNotify(true, req.body.nick, data, function() {
198
resp.send(200, 'OK\n')
199
}, function() { // not found
200
resp.send(400, "unknown nick\n")
207
app.set('_inbox', inbox)
208
app.set('_notifier', notifier)