-
Notifications
You must be signed in to change notification settings - Fork 7
/
server.js
303 lines (279 loc) · 10.3 KB
/
server.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
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
var
// load config from file
bodyParser = require('body-parser'),
config = require('./local_modules/config'),
express = require('express'),
fs = require('fs'),
helmet = require('helmet'),
Mailgun = require('mailgun-js');
SmidManger = require('./local_modules/smid-manager.js').SmidManger,
OcridOAuthUtil = require('./local_modules/orcid-oauth-util.js').OcridOAuthUtil;
var smidManger = new SmidManger(config.MONGO_CONNECTION_STRING);
var mailgunPriv = Mailgun({apiKey: config.MAILGUN_PRIV_API_KEY, domain: config.MAILGUN_DOMAIN});
var mailgunPub = Mailgun({apiKey: config.MAILGUN_PUB_API_KEY, domain: config.MAILGUN_DOMAIN});
var ooau = new OcridOAuthUtil(
config.CLIENT_ID,
config.CLIENT_SECRET,
config.ORCID_URL);
// Init express
var app = express();
var path = require('path');
var distDir = __dirname + "/dist/";
var index_file = distDir + "index.html"
var PAGE_404 = distDir + "assets/404.html"
var PAGE_500 = distDir + "assets/500.html"
app.use(express.static(distDir));
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(bodyParser.json());
//app.use(helmet());
app.set('json spaces', 2);
app.set('json replacer', null);
app.listen(config.PORT_HTTP, function() {
console.log('listening on port: ' + config.PORT_HTTP)
})
// Custom console for orcid logging
var orcidOutput = fs.createWriteStream('./orcidout.log');
var orcidErrorOutput = fs.createWriteStream('./orciderr.log');
var orcidLogger = new console.Console(orcidOutput, orcidErrorOutput);
//Endpoints
var CONFIG = '/config';
var CREATE_SMID_AUTHORIZE = '/create-smid-authorize';
var CREATE_SMID_EMAIL = '/create-smid-email';
var CONFIG = '/config';
var CREATE_SMID_URI = '/create-smid-redirect';
var COLLECTION_DETAILS = '/:publicKey/details';
var COLLECTION_DETAILS_DOWNLOAD = '/:publicKey/details/download';
var COLLECTION_DETAILS_FORM = '/:publicKey/details/:privateKey/details/form';
var EMAIL_SMID = '/email-smid';
var ADD_ID_AUTHORIZE = '/add-id-authorize/:publicKey';
var ADD_ID_REDIRECT = '/add-id-redirect';
var ADD_ID_SUCCESS = '/:publicKey/orcid/:orcid';
var ADD_ID_ERROR = '/:publicKey/add-id-error';
var COLLECTION_EDIT = '/:publicKey/edit/:privateKey';
var COLLECTION_SHARE = '/:publicKey';
function rmTab(str) {
if (str !== undefined && str != null)
return str.replace(/\t/g, '');
return str;
}
function dateToStr(date) {
return date.toISOString();
}
function smidToTxt(doc) {
if (doc === undefined || doc == null) return null;
var csv = `${rmTab(doc.form.title)}\n`;
csv += `Created by ${doc.owner.name} (${doc.owner.fullOrcidId})\n`;
csv += `\n`;
csv += `Collected iDs as of ${dateToStr(new Date())}\n`;
csv += `Date Collected \tORCID \tFull ORCID iD \tCollected Name\n`;
doc.authenticated_orcids.forEach(function(row) {
csv += `${dateToStr(row.dateRecorded)}\t${row.orcid}\t${row.fullOrcidId}\t${rmTab(row.name)}\n`;
})
return csv;
}
app.get(CONFIG, function(req, res) {
return res.status(200).json({
'ORCID_URL': config.ORCID_URL
});
});
app.get(CONFIG, function(req, res) {
return res.status(200).json({
'ORCID_URL': config.ORCID_URL
});
});
//Create new id collection
app.get(CREATE_SMID_URI, function(req, res) { // Redeem code URL
var state = req.query.state;
if (req.query.error == 'access_denied') {
// User denied access
console.log("error: " + req.query.error);
res.json(req.query);
} else if (req.query.code === undefined) {
res.json(req.query);
} else {
// exchange code
// function to render page after making request
var exchangingCallback = function(err, token) {
if (err != null)
res.sendFile(PAGE_500);
else { // No errors! we have a token :-)
var date = new Date();
//Log ORCID info to file
orcidLogger.log(date, token.name, token.orcid, req.query.state);
console.log("creating smid for " + token.orcid);
var orcidRecord = smidManger.createOrcidRecord(token.orcid, ooau.fullOrcid(token.orcid), token.name);
smidManger.addOwnerOrcidRecord(orcidRecord, req.query.state, function(err, doc) {
if (err) res.send(err)
else {
var collection = JSON.parse(JSON.stringify(doc, null, 2));
var private_key = collection.private_key;
var public_key = collection.public_key;
res.redirect('/' + public_key + '/edit/' + private_key);
}
});
}
};
ooau.exchangeCode(req.query.code, exchangingCallback);
}
});
//Get collection details
app.get(COLLECTION_DETAILS, function(req, res) {
smidManger.getDetails(req.params.publicKey, function(err, doc) {
if (err)
res.send(err)
else if (doc === undefined || doc == null)
res.sendFile(PAGE_404);
else
res.status(200).json(doc);
});
});
//Get collection details
app.get(COLLECTION_DETAILS_DOWNLOAD, function(req, res) {
smidManger.getDetails(req.params.publicKey, function(err, doc) {
if (err)
res.send(err)
else if (doc === undefined || doc == null)
res.sendFile(PAGE_404);
else {
try {
var txt = smidToTxt(doc);
res.set({
"Content-Disposition": `attachment; filename="${doc.form.title}_tab_separated.txt"`
});
res.status(200).send(txt);
} catch (e) {
res.sendFile(PAGE_500);
}
}
});
});
//Update collection details form fields
app.put(COLLECTION_DETAILS_FORM, function(req, res) {
var data = req.body;
smidManger.updateForm(req.params.privateKey, data.form, function(err, doc) {
if (err) res.status(400).json({'error':err})
else {
res.status(200).json(doc);
}
});
});
// create and email smid
app.post(EMAIL_SMID, function(req, res) {
var data = req.body;
mailgunPub.validate(data.email, function (error, body) {
if(body && body.is_valid) {
console.log("email is valid");
smidManger.createSmid(function(err, doc) {
var mailData = {
from: 'No Reply <[email protected]>',
to: data.email,
subject: 'Share My iD links',
text: `Thanks for creating an ORCID iD collection.\n`
+ `\n`
+ `\n`
+ `Administration Link\n`
+ `Use this link to edit collection details: \n`
+ `${config.HOST}/${doc.public_key}/edit/${doc.private_key}\n`
+ `\n`
+ `\n`
+ `Share Link\n`
+ `Share this link with anyone whose iD you want to collect, and visit this link to view/download iDs you have collected:`
+ `${config.HOST}/${doc.public_key}`
+ `\n`
+ `\n`
+ `For more information, see our KnowledgeBase at ${config.SUPPORT_URL} and in case of problems, please contact our Community Team at [email protected].`
+ `\n`
+ `\n`
+ `Thanks,\n`
+ `The ORCID Team`
};
console.log("Email to: " + data.to);
console.log("Email to: " + data.subject);
console.log("Email body: " + mailData.text);
var create_smid_authorization_uri = ooau.getAuthUrl(config.HOST + CREATE_SMID_URI, doc.private_key);
mailgunPriv.messages().send(mailData, function (error, body) {
if (error != null) {
console.log("mailgun error:");
console.log(error);
if (body != null && body.message != null && body.message.includes("Great job"))
res.status(200).json({'email': data.email, 'redirect': create_smid_authorization_uri }); // using test credentials
else
res.status(400).json({'error':error, 'body': body});
} else {
console.log("mailgun body:");
console.log(body);
res.status(200).json({'email': data.email, 'redirect': create_smid_authorization_uri });
}
});
});
} else {
console.log(error);
res.status(400).json({'error':"Email failed to pass validation", 'body': body});
}
});
});
//Add iD oauth sign into ORCID
app.get(ADD_ID_AUTHORIZE, function(req, res) {
var add_id_authorization_uri = ooau.getAuthUrl(config.HOST + ADD_ID_REDIRECT, req.params.publicKey);
res.redirect(add_id_authorization_uri);
});
//Add id to collection
app.get(ADD_ID_REDIRECT, function(req, res) { // Redeem code URL
var state = req.query.state;
if (req.query.error == 'access_denied') {
// User denied access
console.log("error: " + req.query.error);
res.redirect( /* make ADD_ID_ERROR url */ '/' + state + "/add-id-error");
} else {
// exchange code
// function to render page after making request
var exchangingCallback = function(error, token) {
if (error != null)
res.sendFile(PAGE_500);
else { // No errors! we have a token :-)
var date = new Date();
//Log ORCID info to file
orcidLogger.log(date, token.name, token.orcid, req.query.state);
//state maps to smid public key
console.log("Got user id: " + token.orcid);
var orcidRecord = smidManger.createOrcidRecord(token.orcid, ooau.fullOrcid(token.orcid), token.name);
smidManger.addOrcidRecord(orcidRecord, req.query.state, function(err, doc) {
if (err) res.send(err)
else {
//res.redirect('/' + req.query.state);
res.redirect( /* make ADD_ID_SUCCESS url */ '/' + state + '/orcid/' + token.orcid);
}
});
}
};
ooau.exchangeCode(req.query.code, exchangingCallback);
}
});
app.get([COLLECTION_EDIT], function(req, res) { // Index page
smidManger.exist(req.params.publicKey, req.params.privateKey, function(err, boolA) {
if (boolA == true) {
smidManger.hasOwner(req.params.publicKey, req.params.privateKey, function(err, boolB) {
if (boolB == true) {
res.status(200).sendFile(index_file);
} else {
res.redirect(ooau.getAuthUrl(config.HOST + CREATE_SMID_URI, req.params.privateKey));
}
});
} else {
res.sendFile(PAGE_404);
}
});
});
app.get([CREATE_SMID_EMAIL, '/'], function(req, res) { // Index page
res.status(200).sendFile(index_file);
});
app.get([COLLECTION_SHARE, ADD_ID_SUCCESS, ADD_ID_ERROR], function(req, res) { // Index page
smidManger.detailsExist(req.params.publicKey, function(err, bool) {
if (bool == true)
res.status(200).sendFile(index_file);
else
res.sendFile(PAGE_404);
});
});