Commit 79e1f904b8e997c07021d0846d7ac5efef28c0c3

Authored by Adhidarma Hadiwinoto
1 parent dc387d6062
Exists in master

express session name support

Showing 1 changed file with 12 additions and 1 deletions Inline Diff

1 var express = require('express'); 1 var express = require('express');
2 var app = express(); 2 var app = express();
3 var nunjucks = require('nunjucks'); 3 var nunjucks = require('nunjucks');
4 var passport = require('passport'); 4 var passport = require('passport');
5 var LocalStrategy = require('passport-local').Strategy; 5 var LocalStrategy = require('passport-local').Strategy;
6 var crypto = require('crypto'); 6 var crypto = require('crypto');
7 //var sha256sum = crypto.createHash('sha256'); 7 //var sha256sum = crypto.createHash('sha256');
8 var fsextra = require('fs-extra'); 8 var fsextra = require('fs-extra');
9 var strftime = require('strftime'); 9 var strftime = require('strftime');
10 var fs = require('fs'); 10 var fs = require('fs');
11 var ini = require('ini'); 11 var ini = require('ini');
12 var os = require('os'); 12 var os = require('os');
13 13
14 var config; 14 var config;
15 var aaa; 15 var aaa;
16 var matrix; 16 var matrix;
17 var view_path = __dirname + '/views'; 17 var view_path = __dirname + '/views';
18 18
19 function loggedIn(req, res, next) { 19 function loggedIn(req, res, next) {
20 if (req.user) { 20 if (req.user) {
21 next(); 21 next();
22 } else { 22 } else {
23 res.redirect('/login'); 23 res.redirect('/login');
24 } 24 }
25 } 25 }
26 26
27 function matchedPasswordAndHash(password, hash) { 27 function matchedPasswordAndHash(password, hash) {
28 var sha256sum = crypto.createHash('sha256'); 28 var sha256sum = crypto.createHash('sha256');
29 sha256sum.update(password); 29 sha256sum.update(password);
30 return (hash == sha256sum.digest('hex')) 30 return (hash == sha256sum.digest('hex'))
31 } 31 }
32 32
33 function renderConfigIndex(req, res) { 33 function renderConfigIndex(req, res) {
34 34
35 masked = ['config.expresso.password']; 35 masked = ['config.expresso.password'];
36 36
37 res.render('config.index.html', { 37 res.render('config.index.html', {
38 gateway_name: config.globals.gateway_name, 38 gateway_name: config.globals.gateway_name,
39 title: 'CONFIG', configs: config, 39 title: 'CONFIG', configs: config,
40 config_dirty: matrix.config_dirty, 40 config_dirty: matrix.config_dirty,
41 isMask: function(scope, keyword) { 41 isMask: function(scope, keyword) {
42 return masked.indexOf('config.' + scope + '.' + keyword) >= 0; 42 return masked.indexOf('config.' + scope + '.' + keyword) >= 0;
43 }, 43 },
44 }); 44 });
45 } 45 }
46 46
47 function renderConfigEdit(req, res) { 47 function renderConfigEdit(req, res) {
48 var template = "config.edit.html"; 48 var template = "config.edit.html";
49 49
50 if (req.scope == 'expresso' && req.keyword == 'password') { 50 if (req.scope == 'expresso' && req.keyword == 'password') {
51 template = "config.edit.expresso.password.html"; 51 template = "config.edit.expresso.password.html";
52 } 52 }
53 53
54 res.render(template, { 54 res.render(template, {
55 gateway_name: config.globals.gateway_name, 55 gateway_name: config.globals.gateway_name,
56 title: 'Edit Konfigurasi', 56 title: 'Edit Konfigurasi',
57 scope: req.scope, 57 scope: req.scope,
58 keyword: req.keyword, 58 keyword: req.keyword,
59 old_value: config[req.scope][req.keyword] 59 old_value: config[req.scope][req.keyword]
60 }); 60 });
61 } 61 }
62 62
63 function renderConfigAdd(req, res){ 63 function renderConfigAdd(req, res){
64 64
65 var template = 'config.add.html'; 65 var template = 'config.add.html';
66 if (req.scope == 'products') { 66 if (req.scope == 'products') {
67 template = 'config.add.products.html'; 67 template = 'config.add.products.html';
68 } 68 }
69 69
70 res.render(template, { 70 res.render(template, {
71 gateway_name: config.globals.gateway_name, 71 gateway_name: config.globals.gateway_name,
72 title: 'Tambah Item Konfigurasi', 72 title: 'Tambah Item Konfigurasi',
73 scope: req.scope 73 scope: req.scope
74 }); 74 });
75 } 75 }
76 76
77 function submitConfigEdit(req, res) { 77 function submitConfigEdit(req, res) {
78 78
79 if (req.scope == 'expresso' && req.keyword == 'password') { 79 if (req.scope == 'expresso' && req.keyword == 'password') {
80 if (req.body.newValue != req.body.newValue2) { 80 if (req.body.newValue != req.body.newValue2) {
81 res.redirect('/config/edit/' + req.scope + '/' + req.keyword); 81 res.redirect('/config/edit/' + req.scope + '/' + req.keyword);
82 return; 82 return;
83 } 83 }
84 84
85 var sha256sum = crypto.createHash('sha256'); 85 var sha256sum = crypto.createHash('sha256');
86 sha256sum.update(req.body.newValue); 86 sha256sum.update(req.body.newValue);
87 req.body.newValue = sha256sum.digest('hex'); 87 req.body.newValue = sha256sum.digest('hex');
88 88
89 } else if (req.scope == 'globals' && req.keyword == 'products' && req.body.newValue.trim()) { 89 } else if (req.scope == 'globals' && req.keyword == 'products' && req.body.newValue.trim()) {
90 90
91 try { 91 try {
92 var unsortedString = req.body.newValue.toUpperCase().replace(/ /g, '').trim(); 92 var unsortedString = req.body.newValue.toUpperCase().replace(/ /g, '').trim();
93 var unsortedProducts = unsortedString.split(','); 93 var unsortedProducts = unsortedString.split(',');
94 var sortedProducts = aaa.sortProductsArray(unsortedProducts); 94 var sortedProducts = aaa.sortProductsArray(unsortedProducts);
95 req.body.newValue = sortedProducts.join(','); 95 req.body.newValue = sortedProducts.join(',');
96 } 96 }
97 catch(e) { 97 catch(e) {
98 console.log('Error sorting products'); 98 console.log('Error sorting products');
99 } 99 }
100 } 100 }
101 101
102 if (config[req.body.scope][req.body.keyword] != req.body.newValue.trim()) { 102 if (config[req.body.scope][req.body.keyword] != req.body.newValue.trim()) {
103 config[req.body.scope][req.body.keyword] = req.body.newValue.trim(); 103 config[req.body.scope][req.body.keyword] = req.body.newValue.trim();
104 matrix.config_dirty = 1; 104 matrix.config_dirty = 1;
105 } 105 }
106 106
107 res.redirect('/config'); 107 res.redirect('/config');
108 } 108 }
109 109
110 function submitConfigAdd(req, res) { 110 function submitConfigAdd(req, res) {
111 111
112 if (!req.body.newKeyword.trim()) { 112 if (!req.body.newKeyword.trim()) {
113 res.redirect('/config'); 113 res.redirect('/config');
114 return; 114 return;
115 } 115 }
116 116
117 if (config[req.body.scope] === undefined) { 117 if (config[req.body.scope] === undefined) {
118 config[req.body.scope] = {}; 118 config[req.body.scope] = {};
119 } 119 }
120 120
121 config[req.body.scope][req.body.newKeyword.trim()] = req.body.newValue.trim(); 121 config[req.body.scope][req.body.newKeyword.trim()] = req.body.newValue.trim();
122 matrix.config_dirty = 1; 122 matrix.config_dirty = 1;
123 123
124 res.redirect('/config#config.' + req.body.scope + '.' + req.body.newKeyword); 124 res.redirect('/config#config.' + req.body.scope + '.' + req.body.newKeyword);
125 } 125 }
126 126
127 function submitConfigDelete(req, res) { 127 function submitConfigDelete(req, res) {
128 128
129 matrix.config_dirty = 1; 129 matrix.config_dirty = 1;
130 delete config[req.scope][req.keyword]; 130 delete config[req.scope][req.keyword];
131 131
132 res.redirect('/config'); 132 res.redirect('/config');
133 } 133 }
134 134
135 function submitConfigSave(req, res) { 135 function submitConfigSave(req, res) {
136 fsextra.copy('config.ini', 'config.ini.backup_' + strftime('%F_%H%M%S', new Date()), function(err) { 136 fsextra.copy('config.ini', 'config.ini.backup_' + strftime('%F_%H%M%S', new Date()), function(err) {
137 fs.writeFileSync('./config.ini', ini.stringify(config)); 137 fs.writeFileSync('./config.ini', ini.stringify(config));
138 matrix.config_dirty = 0; 138 matrix.config_dirty = 0;
139 res.redirect('/config'); 139 res.redirect('/config');
140 }); 140 });
141 } 141 }
142 142
143 function renderLoginPage(req, res) { 143 function renderLoginPage(req, res) {
144 res.render('signin.html', {title: config.globals.gateway_name}); 144 res.render('signin.html', {title: config.globals.gateway_name});
145 } 145 }
146 146
147 function renderConfigAskDelete(req, res) { 147 function renderConfigAskDelete(req, res) {
148 res.render('config.ask.delete.html', { 148 res.render('config.ask.delete.html', {
149 gateway_name: config.globals.gateway_name, 149 gateway_name: config.globals.gateway_name,
150 title: 'Konfirmasi Penghapusan', 150 title: 'Konfirmasi Penghapusan',
151 scope: req.scope, 151 scope: req.scope,
152 keyword: req.keyword, 152 keyword: req.keyword,
153 value: config[req.scope][req.keyword], 153 value: config[req.scope][req.keyword],
154 }); 154 });
155 } 155 }
156 156
157 function renderDashboardIndex(req, res) { 157 function renderDashboardIndex(req, res) {
158 var template = "dashboard.index.html"; 158 var template = "dashboard.index.html";
159 159
160 var os_info = { 160 var os_info = {
161 uptime: os.uptime(), 161 uptime: os.uptime(),
162 loadavg: os.loadavg(), 162 loadavg: os.loadavg(),
163 hostname: os.hostname(), 163 hostname: os.hostname(),
164 type: os.type(), 164 type: os.type(),
165 platform: os.platform(), 165 platform: os.platform(),
166 arch: os.arch(), 166 arch: os.arch(),
167 release: os.release(), 167 release: os.release(),
168 totalmem: os.totalmem(), 168 totalmem: os.totalmem(),
169 } 169 }
170 170
171 res.render(template, { 171 res.render(template, {
172 gateway_name: config.globals.gateway_name, 172 gateway_name: config.globals.gateway_name,
173 title: 'Dashboard', 173 title: 'Dashboard',
174 matrix: JSON.stringify(matrix, null, 2), 174 matrix: JSON.stringify(matrix, null, 2),
175 config: JSON.stringify(config, null, 2), 175 config: JSON.stringify(config, null, 2),
176 nodejs_versions: JSON.stringify(process.versions, null, 2), 176 nodejs_versions: JSON.stringify(process.versions, null, 2),
177 pendings: JSON.stringify(aaa.getPendingList(), null, 2), 177 pendings: JSON.stringify(aaa.getPendingList(), null, 2),
178 memory_usage: JSON.stringify(process.memoryUsage(), null, 2), 178 memory_usage: JSON.stringify(process.memoryUsage(), null, 2),
179 uptime: process.uptime(), 179 uptime: process.uptime(),
180 os_info: JSON.stringify(os_info, null, 2), 180 os_info: JSON.stringify(os_info, null, 2),
181 net_ifaces: JSON.stringify(os.networkInterfaces(), null, 2), 181 net_ifaces: JSON.stringify(os.networkInterfaces(), null, 2),
182 }); 182 });
183 } 183 }
184 184
185 function isNoTemplateCache() { 185 function isNoTemplateCache() {
186 var retval = false; 186 var retval = false;
187 try { 187 try {
188 retval = config.expresso.no_template_cache.toUpperCase() == 'YES'; 188 retval = config.expresso.no_template_cache.toUpperCase() == 'YES';
189 } 189 }
190 catch(err) { 190 catch(err) {
191 return retval; 191 return retval;
192 } 192 }
193 193
194 return retval; 194 return retval;
195 } 195 }
196 196
197 function createServer() { 197 function createServer() {
198 if (!config.expresso || !config.expresso.listen_port) { 198 if (!config.expresso || !config.expresso.listen_port) {
199 console.log('Not starting expresso admin UI'); 199 console.log('Not starting expresso admin UI');
200 return; 200 return;
201 } 201 }
202 202
203 nunjucks.configure(view_path, { 203 nunjucks.configure(view_path, {
204 autoescape: true, 204 autoescape: true,
205 noCache: isNoTemplateCache(), 205 noCache: isNoTemplateCache(),
206 express: app 206 express: app
207 }); 207 });
208 208
209 app.use(express.static(__dirname + '/public')); 209 app.use(express.static(__dirname + '/public'));
210 app.use(require('cookie-parser')()); 210 app.use(require('cookie-parser')());
211 app.use(require('body-parser').urlencoded({ extended: true })); 211 app.use(require('body-parser').urlencoded({ extended: true }));
212 app.use(require('express-session')({ secret: 'keyboard cat', resave: false, saveUninitialized: false })); 212
213 var express_session_opts = {
214 secret: 'keyboard cat',
215 resave: false,
216 saveUninitialized: false
217 };
218
219 if (config.expresso && config.expresso.session_name) {
220 express_session_opts.name = config.expresso.session_name;
221 }
222
223 app.use(require('express-session')(express_session_opts));
213 app.use(passport.initialize()); 224 app.use(passport.initialize());
214 app.use(passport.session()); 225 app.use(passport.session());
215 226
216 passport.use(new LocalStrategy( 227 passport.use(new LocalStrategy(
217 function(username, password, done) { 228 function(username, password, done) {
218 229
219 if (username == 'admin' && matchedPasswordAndHash(password, config.expresso.password)) { 230 if (username == 'admin' && matchedPasswordAndHash(password, config.expresso.password)) {
220 var user = { 231 var user = {
221 username: username, 232 username: username,
222 last_login: Date.now() / 1000 | 0 233 last_login: Date.now() / 1000 | 0
223 } 234 }
224 235
225 return done(null, user); 236 return done(null, user);
226 } 237 }
227 238
228 return done(null, false, { message: 'Incorrect password.' }); 239 return done(null, false, { message: 'Incorrect password.' });
229 } 240 }
230 )); 241 ));
231 242
232 passport.serializeUser(function(user, done) { 243 passport.serializeUser(function(user, done) {
233 done(null, user.username); 244 done(null, user.username);
234 }); 245 });
235 246
236 passport.deserializeUser(function(username, done) { 247 passport.deserializeUser(function(username, done) {
237 var user = { 248 var user = {
238 username: username 249 username: username
239 }; 250 };
240 done(null, user); 251 done(null, user);
241 }); 252 });
242 253
243 app.get('/', loggedIn, function(req, res) { res.redirect('/dashboard'); }); 254 app.get('/', loggedIn, function(req, res) { res.redirect('/dashboard'); });
244 app.get('/config', loggedIn, renderConfigIndex); 255 app.get('/config', loggedIn, renderConfigIndex);
245 app.get('/login', renderLoginPage); 256 app.get('/login', renderLoginPage);
246 app.post('/login', passport.authenticate('local', { successRedirect: '/dashboard', failureRedirect: '/login' })); 257 app.post('/login', passport.authenticate('local', { successRedirect: '/dashboard', failureRedirect: '/login' }));
247 app.get('/logout', function(req, res){ 258 app.get('/logout', function(req, res){
248 req.logout(); 259 req.logout();
249 res.redirect('/login'); 260 res.redirect('/login');
250 }); 261 });
251 262
252 app.param('scope', function(req, res, next, value) { 263 app.param('scope', function(req, res, next, value) {
253 req.scope = value; 264 req.scope = value;
254 next(); 265 next();
255 }); 266 });
256 267
257 app.param('keyword', function(req, res, next, value) { 268 app.param('keyword', function(req, res, next, value) {
258 req.keyword = value; 269 req.keyword = value;
259 next(); 270 next();
260 }); 271 });
261 272
262 app.get('/config/edit/:scope/:keyword', loggedIn, renderConfigEdit); 273 app.get('/config/edit/:scope/:keyword', loggedIn, renderConfigEdit);
263 app.post('/config/edit/:scope/:keyword', loggedIn, submitConfigEdit); 274 app.post('/config/edit/:scope/:keyword', loggedIn, submitConfigEdit);
264 275
265 app.get('/config/ask-delete/:scope/:keyword', loggedIn, renderConfigAskDelete); 276 app.get('/config/ask-delete/:scope/:keyword', loggedIn, renderConfigAskDelete);
266 app.get('/config/delete/:scope/:keyword', loggedIn, submitConfigDelete); 277 app.get('/config/delete/:scope/:keyword', loggedIn, submitConfigDelete);
267 278
268 app.get('/config/add/:scope', loggedIn, renderConfigAdd); 279 app.get('/config/add/:scope', loggedIn, renderConfigAdd);
269 app.post('/config/add/:scope', loggedIn, submitConfigAdd); 280 app.post('/config/add/:scope', loggedIn, submitConfigAdd);
270 281
271 app.get('/config/save', loggedIn, submitConfigSave); 282 app.get('/config/save', loggedIn, submitConfigSave);
272 283
273 app.get('/dashboard', loggedIn, renderDashboardIndex); 284 app.get('/dashboard', loggedIn, renderDashboardIndex);
274 285
275 var server = app.listen(config.expresso.listen_port, function () { 286 var server = app.listen(config.expresso.listen_port, function () {
276 var host = server.address().address; 287 var host = server.address().address;
277 var port = server.address().port; 288 var port = server.address().port;
278 289
279 console.log('Expresso admin UI listening at http://%s:%s', host, port); 290 console.log('Expresso admin UI listening at http://%s:%s', host, port);
280 }); 291 });
281 } 292 }
282 293
283 function sanitizeMatrix(matrix) { 294 function sanitizeMatrix(matrix) {
284 if (matrix === undefined) { 295 if (matrix === undefined) {
285 matrix = {}; 296 matrix = {};
286 } 297 }
287 if (matrix.config_dirty === undefined) { 298 if (matrix.config_dirty === undefined) {
288 matrix.config_dirty = 0; 299 matrix.config_dirty = 0;
289 } 300 }
290 } 301 }
291 302
292 function start(options) { 303 function start(options) {
293 if (options['config']) { 304 if (options['config']) {
294 config = options['config']; 305 config = options['config'];
295 } 306 }
296 307
297 if (options['matrix']) { 308 if (options['matrix']) {
298 matrix = options['matrix']; 309 matrix = options['matrix'];
299 } 310 }
300 sanitizeMatrix(matrix); 311 sanitizeMatrix(matrix);
301 312
302 if (options['aaa']) { 313 if (options['aaa']) {
303 aaa = options['aaa']; 314 aaa = options['aaa'];
304 } 315 }
305 316
306 if (options['expresso_views']) { 317 if (options['expresso_views']) {
307 view_path = options['expresso_views']; 318 view_path = options['expresso_views'];
308 } 319 }
309 320
310 createServer(); 321 createServer();
311 } 322 }
312 323
313 exports.start = start; 324 exports.start = start;
314 325