1 | 'use strict';
|
2 |
|
3 |
|
4 | for (var i = 0; i < process.argv.length; i++) {
|
5 | var DEV = process.env.NODE_ENV === 'development' || process.argv[i] === "debug" || DEV;
|
6 | }
|
7 |
|
8 | if (DEV) {
|
9 | process.env["DEBUG"] = 'connect:*';
|
10 | }
|
11 | var fs = require('fs');
|
12 | var https = require('https');
|
13 | var SwaggerTools = require('swagger-tools');
|
14 | var hotp = require('otplib');
|
15 | generateSecretIfNecessary();
|
16 | var secretKey = require('./secretKey.js');
|
17 | var storage = require('node-persist');
|
18 | storage.initSync();
|
19 | var hotpcount = storage.getItem('hotpcount') || 0;
|
20 |
|
21 |
|
22 | var config = {
|
23 | appRoot: __dirname
|
24 | };
|
25 |
|
26 | var swaggerDoc = require('./api/swagger/swagger.json');
|
27 |
|
28 | var app = require('connect')();
|
29 |
|
30 | SwaggerTools.initializeMiddleware(swaggerDoc, function (middleware) {
|
31 |
|
32 |
|
33 | if (DEV) {
|
34 | app.use(check_signatures);
|
35 | }
|
36 |
|
37 |
|
38 | app.use(setJSONFormat);
|
39 |
|
40 |
|
41 | app.use(middleware.swaggerMetadata());
|
42 |
|
43 | app.use(middleware.swaggerValidator());
|
44 | app.use(catchValidationErrors);
|
45 | app.use(middleware.swaggerRouter({
|
46 | controllers: './api/controllers',
|
47 | useStubs: false
|
48 | }));
|
49 |
|
50 |
|
51 | var key = DEV ? fs.readFileSync('./ssl/snakeoil.key') : fs.readFileSync('./ssl/key.key');
|
52 | var cert = DEV ? fs.readFileSync('./ssl/snakeoil.cert') : fs.readFileSync('./ssl/cert.cert');
|
53 |
|
54 | https.createServer({ key: key, cert: cert }, app).listen(443, function () {
|
55 | console.log('Listening on port ' + 443);
|
56 | });
|
57 |
|
58 | });
|
59 |
|
60 | function check_signatures(req, res, next) {
|
61 | var count = parseInt(req.headers['x-hotp-count']);
|
62 | if ('x-hotp' in req.headers && 'x-hotp-count' in req.headers && hotpcount <= count && hotp.check(req.headers['x-hotp'], secretKey, count)) {
|
63 | hotpcount = count + 1; storage.setItem('hotpcount', hotpcount);
|
64 | next();
|
65 | } else {
|
66 | res.writeHead(403, { "Content-Type": "application/json" });
|
67 | res.end('{"error":"Unauthorized access. HOTP signature invalid. You must go through the syndication server."}');
|
68 | }
|
69 | }
|
70 |
|
71 | function setJSONFormat(req, res, next) {
|
72 | res.setHeader('content-type', 'application/json');
|
73 | next();
|
74 | }
|
75 |
|
76 | function catchValidationErrors(err, req, res, next) {
|
77 | if ('failedValidation' in err && err.failedValidation) {
|
78 | res.statusCode = 400;
|
79 | res.end('{"error":"The request failed validation of its parameters and format. Check to make sure it conforms to the swagger spec for this api."}');
|
80 | }
|
81 | }
|
82 |
|
83 | function generateSecretIfNecessary() {
|
84 | try {
|
85 | console.log("Looking for secret key...");
|
86 |
|
87 | try {
|
88 | var stats = fs.statSync("secretKey.js");
|
89 | if (stats.isFile()) {
|
90 | console.log("Secret key found!");
|
91 | }
|
92 | } catch(e) {
|
93 | var pass = hotp.authenticator.generateSecret();
|
94 | console.log("Generating secret key!");
|
95 | fs.writeFileSync("secretKey.js","module.exports = '"+pass+"';");
|
96 | console.log("New secret key written!");
|
97 | }
|
98 | } catch(err) {
|
99 | console.log("Secret Key could not be found/written: " + err);
|
100 | process.exit(11);
|
101 | }
|
102 | } |
\ | No newline at end of file |