-
Notifications
You must be signed in to change notification settings - Fork 0
/
app.js
161 lines (145 loc) · 4.28 KB
/
app.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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
var cfenv = require('cfenv'),
path = require('path'),
appEnv = cfenv.getAppEnv(),
async = require('async'),
express = require('express'),
bodyParser = require('body-parser'),s
CryptoJS = require("crypto-js"),
slack = require('./lib/slack.js'),
router = express.Router();
cloudant = null,
teamsdb = null,
tokensdb = null,
notificationsdb = null,
uuid = require('uuid'),
appurl = (appEnv.app.application_uris)?appEnv.app.application_uris[0]:"localhost:"+appEnv.port,
thekey = 'bj0uSrR1WZtxIZ6thpMX',
dbName = 'advocated2';
var encrypt = function(str, key) {
return CryptoJS.AES.encrypt(str, key).toString();
};
var decrypt = function(str, key) {
var bytes = CryptoJS.AES.decrypt(str, key);
return bytes.toString(CryptoJS.enc.Utf8);
};
var createUser = function(q, team, callback) {
envoy.auth.getUser(q.user_id, function (err, data) {
if (err) {
var meta = {
user_name: q.user_name,
team_id: team._id,
team_name: team.name
};
console.log("created new user", q.user_id, meta);
var password = uuid.v4();
meta.password = encrypt(password, thekey);
envoy.auth.newUser(q.user_id, password, meta, function (err, data) {
envoy.auth.getUser(q.user_id, function(err, data) {
callback(err, data);
});
})
} else {
console.log("User already exists", data);
callback(err, data);
}
});
}
router.post('/slack', bodyParser.urlencoded({ extended: false }), function(req, res) {
var q = req.body;
if (q.team_id) {
console.log("Incoming slack request for team_id", q.team_id);
teamsdb.get(q.team_id, function (err, team) {
if (err) {
res.status(403).send("Team not found");
} else {
// if the incoming token matches the team token
if (team.slack.token === q.token) {
createUser(q, team, function(err, data) {
data._id = uuid.v4();
data.ts = new Date().getTime() + 1000*60*60;
delete data._rev;
tokensdb.insert(data, function (err, data) {
res.send("Thanks for advocating. Please visit this URL to enter the details <https://" + appurl + "/#token.html?token=" + data.id + ">");
});
});
} else {
res.status(403).send("Invalid token");
}
}
});
} else {
res.send(403);
}
});
// exchange
router.get('/api/token/:token', function(req, res) {
tokensdb.get(req.params.token, function(err, data) {
if (err) {
res.send({ok: false});
} else {
tokensdb.destroy(data._id, data._rev);
if (data.ts > new Date().getTime()) {
data.meta.password = decrypt(data.meta.password, thekey);
res.send(data);
} else {
res.send({ok: false, msg: 'out of date'});
}
}
});
});
// setup envoy with our static files
var opts = {
databaseName: dbName,
port: appEnv.port,
logFormat: 'dev',
production: true,
static: path.join(__dirname, './public'),
router: router
};
// queue to deal with outgoing Slack requests
var q = async.queue(function(payload, done) {
envoy.db.get(payload, function(err, data) {
if (err) {
return done();
}
var url = process.env.SLACK_WEBHOOK_URL;
notificationsdb.get(payload, function(err, d) {
if (err) {
slack.post(url, data, done);
notificationsdb.insert({_id: payload, done:true});
} else {
done();
}
});
});
},1);
// run envoy
var envoy = require('cloudant-envoy')(opts);
envoy.events.on('listening', function() {
// create databases
cloudant = envoy.cloudant;
cloudant.db.create('teams');
cloudant.db.create('tokens');
cloudant.db.create('notifications');
// use the databases
teamsdb = cloudant.db.use('teams');
tokensdb = cloudant.db.use('tokens');
notificationsdb = cloudant.db.use('notifications');
console.log('[OK] Server is up');
// listen for changes on the Envoy datbase
var feed = envoy.db.follow({since: 'now'});
feed.on('change', function(change) {
var isnew = false;
for (var i in change.changes) {
// if this is the first time we've seen this doc
if (change.changes[i].rev.match(/^1/)) {
isnew = true;
break;
}
}
if (isnew) {
q.push(change.id);
}
});
feed.follow();
});