UNPKG

6.54 kBJavaScriptView Raw
1/* jshint node: true */
2"use strict";
3
4/**
5 * get session secret from db
6 * acl: check if req route is allowed as express middelware
7 * decrypt token an put rights object in req
8 */
9
10
11var jwt = require('jsonwebtoken'),
12 NodeCache = require("node-cache"),
13 myCache = new NodeCache({
14 stdTTL: 1000,
15 checkperiod: 250
16 }),
17 os = require('os'),
18 config = require("rf-config"),
19 log = require("rf-log"),
20 db = require("rf-load").require("db").db,
21 app = require("rf-load").require("http").app;
22
23
24
25// get internal ip addresses for allowing internal requests
26var interfaces = os.networkInterfaces();
27var internal_ip_addresses = [];
28for (var k in interfaces) {
29 for (var k2 in interfaces[k]) {
30 var address = interfaces[k][k2];
31 internal_ip_addresses.push(address.address.replace("::ffff:", ""));
32 }
33}
34
35
36module.exports.start = function(options, startNextModule) {
37
38 //get session secret from db
39 db.global.settings.findOne({
40 name: "sessionSecret"
41 }, function(err, doc) {
42 var sessionSecret;
43 if (doc && doc.settings && doc.settings.value) {
44 sessionSecret = doc.settings.value;
45 } else {
46 // no secret => create one and put it in db (avalibale for other apps)
47 log.info("Couldn't load session secret, creating a new one");
48 sessionSecret = require('crypto').randomBytes(64).toString('hex');
49
50 db.global.mongooseConnection.collection("settings").insert({
51 name: "sessionSecret",
52 settings: {
53 value: sessionSecret
54 }
55 });
56 }
57 config.sessionSecret = sessionSecret; // login function als needs it
58 startACL(sessionSecret);
59 });
60
61
62 function startACL(sessionSecret) {
63
64
65 // process the token
66 app.use(function(req, res, next) {
67
68 // check for token
69 var token = req.body.token || req.query.token || req.headers['x-access-token'];
70
71 if (token) {
72 try {
73 getSession(token, res, function(session) {
74 // make data accessible afterwards
75 req._session = session;
76 req._token = token;
77 // req._decoded = jwt.verify(token, sessionSecret, {
78 // ignoreExpiration: true
79 // });
80 next();
81 });
82 } catch (err) {
83 error();
84 }
85
86 // no token
87 } else {
88 next();
89 }
90
91 function error () {
92 res.status(403).send('AuthenticateFailed');
93 }
94
95
96 function getSession(token, res, next) {
97
98 // session with key "token" in cach?
99 myCache.get(token, function(err, session) {
100
101 if (err) {
102 log.error("node-cache ", err);
103 } else {
104 // not in cache => get from db and put in cache
105 if (session === undefined || session === null) {
106 db.user.sessions.findOne({
107 "token": token
108 })
109 .populate({
110 path: 'user',
111 populate: {
112 path: 'account'
113 }
114 })
115 .exec(function(err, doc) {
116
117 if (doc) {
118 session = doc;
119 myCache.set(token, session, function(err, success) {
120 if (err) {
121 log.error("node-cache ", err);
122 } else {
123 //console.log("session from db", session);
124 next(session);
125 }
126 });
127
128 // no session found in db
129 } else {
130 error();
131 }
132
133 });
134
135 // return session from cache
136 } else {
137 // console.log("session in cache", session);
138 next(session);
139 }
140 }
141 });
142
143 }
144 });
145
146
147 // check if rout allowed
148 app.use(function(req, res, next) {
149
150 //Do not protect internal requests
151 var ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
152 ip = ip.replace("::ffff:", "");
153
154 // console.log(req._session);
155
156 if (internal_ip_addresses.indexOf(ip) < 0) {
157
158 if (!config.acl) {
159 log.warning("No acls found in config! Nothing is protected!");
160 next();
161 } else {
162 for (var c in config.acl) {
163
164 if (req.url.match(new RegExp(c, 'g'))) {
165
166 //protected
167 if (config.acl[c] !== false) {
168
169
170 //req._session
171 // req._token
172
173 // TODO
174 //Check for roles for this route
175 // if (decoded.roles.indexOf(config.acl[c]) < 0) {
176 // return res.status(403).json({
177 // success: false,
178 // message: 'Wrong permissions.'
179 // }, 403);
180 // }
181
182 // everything good
183 next();
184 } else { // no token => error
185
186 next();
187
188 // return res.status(403).json({
189 // success: false,
190 // message: 'No token provided.'
191 // }, 403);
192 }
193
194 //unprotected
195 } else {
196 next();
197 }
198 }
199 }
200 // internal
201 }else {
202 next();
203 }
204
205 });
206
207
208 // provide the login url (no acl here)
209 app.post('/basic-config', function(req, res) {
210 var loginUrls = config.global.apps.login.urls;
211 var basicInfo = {
212 app: config.app,
213 loginUrl: loginUrls.main + loginUrls.login,
214 loginMainUrl: loginUrls.main,
215 };
216 res.status(200).send(basicInfo).end();
217 });
218
219
220 log.success("Session started");
221 startNextModule();
222
223 }
224
225
226
227
228};