Commit 4ec802020cf8bf47c4f4783a51eaca9230c8586b

Authored by Adhidarma Hadiwinoto
1 parent aa77cc76e0
Exists in master

verbose sorting

Showing 1 changed file with 6 additions and 2 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 var products = req.body.newValue.split(','); 90 var products = req.body.newValue.split(',');
91 products = aaa.sortProductsArray(products); 91 var sortedProducts = products = aaa.sortProductsArray(products);
92 req.body.newValue = products.join(','); 92 req.body.newValue = sortedProducts.join(',');
93 console.log('Unsorted products:');
94 console.log(products);
95 console.log('Sorted products:');
96 console.log(sortedProducts);
93 } 97 }
94 98
95 if (config[req.body.scope][req.body.keyword] != req.body.newValue.trim()) { 99 if (config[req.body.scope][req.body.keyword] != req.body.newValue.trim()) {
96 config[req.body.scope][req.body.keyword] = req.body.newValue.trim(); 100 config[req.body.scope][req.body.keyword] = req.body.newValue.trim();
97 matrix.config_dirty = 1; 101 matrix.config_dirty = 1;
98 } 102 }
99 103
100 res.redirect('/config'); 104 res.redirect('/config');
101 } 105 }
102 106
103 function submitConfigAdd(req, res) { 107 function submitConfigAdd(req, res) {
104 108
105 if (!req.body.newKeyword.trim()) { 109 if (!req.body.newKeyword.trim()) {
106 res.redirect('/config'); 110 res.redirect('/config');
107 return; 111 return;
108 } 112 }
109 113
110 if (config[req.body.scope] === undefined) { 114 if (config[req.body.scope] === undefined) {
111 config[req.body.scope] = {}; 115 config[req.body.scope] = {};
112 } 116 }
113 117
114 config[req.body.scope][req.body.newKeyword.trim()] = req.body.newValue.trim(); 118 config[req.body.scope][req.body.newKeyword.trim()] = req.body.newValue.trim();
115 matrix.config_dirty = 1; 119 matrix.config_dirty = 1;
116 120
117 res.redirect('/config#config.' + req.body.scope + '.' + req.body.newKeyword); 121 res.redirect('/config#config.' + req.body.scope + '.' + req.body.newKeyword);
118 } 122 }
119 123
120 function submitConfigDelete(req, res) { 124 function submitConfigDelete(req, res) {
121 125
122 matrix.config_dirty = 1; 126 matrix.config_dirty = 1;
123 delete config[req.scope][req.keyword]; 127 delete config[req.scope][req.keyword];
124 128
125 res.redirect('/config'); 129 res.redirect('/config');
126 } 130 }
127 131
128 function submitConfigSave(req, res) { 132 function submitConfigSave(req, res) {
129 fsextra.copy('config.ini', 'config.ini.backup_' + strftime('%F_%H%M%S', new Date()), function(err) { 133 fsextra.copy('config.ini', 'config.ini.backup_' + strftime('%F_%H%M%S', new Date()), function(err) {
130 fs.writeFileSync('./config.ini', ini.stringify(config)); 134 fs.writeFileSync('./config.ini', ini.stringify(config));
131 matrix.config_dirty = 0; 135 matrix.config_dirty = 0;
132 res.redirect('/config'); 136 res.redirect('/config');
133 }); 137 });
134 } 138 }
135 139
136 function renderLoginPage(req, res) { 140 function renderLoginPage(req, res) {
137 res.render('signin.html', {title: 'Signin'}); 141 res.render('signin.html', {title: 'Signin'});
138 } 142 }
139 143
140 function renderConfigAskDelete(req, res) { 144 function renderConfigAskDelete(req, res) {
141 res.render('config.ask.delete.html', { 145 res.render('config.ask.delete.html', {
142 gateway_name: config.globals.gateway_name, 146 gateway_name: config.globals.gateway_name,
143 title: 'Konfirmasi Penghapusan', 147 title: 'Konfirmasi Penghapusan',
144 scope: req.scope, 148 scope: req.scope,
145 keyword: req.keyword, 149 keyword: req.keyword,
146 value: config[req.scope][req.keyword], 150 value: config[req.scope][req.keyword],
147 }); 151 });
148 } 152 }
149 153
150 function renderDashboardIndex(req, res) { 154 function renderDashboardIndex(req, res) {
151 var template = "dashboard.index.html"; 155 var template = "dashboard.index.html";
152 156
153 var os_info = { 157 var os_info = {
154 uptime: os.uptime(), 158 uptime: os.uptime(),
155 loadavg: os.loadavg(), 159 loadavg: os.loadavg(),
156 hostname: os.hostname(), 160 hostname: os.hostname(),
157 type: os.type(), 161 type: os.type(),
158 platform: os.platform(), 162 platform: os.platform(),
159 arch: os.arch(), 163 arch: os.arch(),
160 release: os.release(), 164 release: os.release(),
161 totalmem: os.totalmem(), 165 totalmem: os.totalmem(),
162 } 166 }
163 167
164 res.render(template, { 168 res.render(template, {
165 gateway_name: config.globals.gateway_name, 169 gateway_name: config.globals.gateway_name,
166 title: 'Dashboard', 170 title: 'Dashboard',
167 matrix: JSON.stringify(matrix, null, 2), 171 matrix: JSON.stringify(matrix, null, 2),
168 config: JSON.stringify(config, null, 2), 172 config: JSON.stringify(config, null, 2),
169 nodejs_versions: JSON.stringify(process.versions, null, 2), 173 nodejs_versions: JSON.stringify(process.versions, null, 2),
170 pendings: JSON.stringify(aaa.getPendingList(), null, 2), 174 pendings: JSON.stringify(aaa.getPendingList(), null, 2),
171 memory_usage: JSON.stringify(process.memoryUsage(), null, 2), 175 memory_usage: JSON.stringify(process.memoryUsage(), null, 2),
172 uptime: process.uptime(), 176 uptime: process.uptime(),
173 os_info: JSON.stringify(os_info, null, 2), 177 os_info: JSON.stringify(os_info, null, 2),
174 net_ifaces: JSON.stringify(os.networkInterfaces(), null, 2), 178 net_ifaces: JSON.stringify(os.networkInterfaces(), null, 2),
175 }); 179 });
176 } 180 }
177 181
178 function isNoTemplateCache() { 182 function isNoTemplateCache() {
179 var retval = false; 183 var retval = false;
180 try { 184 try {
181 retval = config.expresso.no_template_cache.toUpperCase() == 'YES'; 185 retval = config.expresso.no_template_cache.toUpperCase() == 'YES';
182 } 186 }
183 catch(err) { 187 catch(err) {
184 return retval; 188 return retval;
185 } 189 }
186 190
187 return retval; 191 return retval;
188 } 192 }
189 193
190 function createServer() { 194 function createServer() {
191 if (!config.expresso || !config.expresso.listen_port) { 195 if (!config.expresso || !config.expresso.listen_port) {
192 console.log('Not starting expresso admin UI'); 196 console.log('Not starting expresso admin UI');
193 return; 197 return;
194 } 198 }
195 199
196 nunjucks.configure(view_path, { 200 nunjucks.configure(view_path, {
197 autoescape: true, 201 autoescape: true,
198 noCache: isNoTemplateCache(), 202 noCache: isNoTemplateCache(),
199 express: app 203 express: app
200 }); 204 });
201 205
202 app.use(express.static(__dirname + '/public')); 206 app.use(express.static(__dirname + '/public'));
203 app.use(require('cookie-parser')()); 207 app.use(require('cookie-parser')());
204 app.use(require('body-parser').urlencoded({ extended: true })); 208 app.use(require('body-parser').urlencoded({ extended: true }));
205 app.use(require('express-session')({ secret: 'keyboard cat', resave: false, saveUninitialized: false })); 209 app.use(require('express-session')({ secret: 'keyboard cat', resave: false, saveUninitialized: false }));
206 app.use(passport.initialize()); 210 app.use(passport.initialize());
207 app.use(passport.session()); 211 app.use(passport.session());
208 212
209 passport.use(new LocalStrategy( 213 passport.use(new LocalStrategy(
210 function(username, password, done) { 214 function(username, password, done) {
211 215
212 if (username == 'admin' && matchedPasswordAndHash(password, config.expresso.password)) { 216 if (username == 'admin' && matchedPasswordAndHash(password, config.expresso.password)) {
213 var user = { 217 var user = {
214 username: username, 218 username: username,
215 last_login: Date.now() / 1000 | 0 219 last_login: Date.now() / 1000 | 0
216 } 220 }
217 221
218 return done(null, user); 222 return done(null, user);
219 } 223 }
220 224
221 return done(null, false, { message: 'Incorrect password.' }); 225 return done(null, false, { message: 'Incorrect password.' });
222 } 226 }
223 )); 227 ));
224 228
225 passport.serializeUser(function(user, done) { 229 passport.serializeUser(function(user, done) {
226 done(null, user.username); 230 done(null, user.username);
227 }); 231 });
228 232
229 passport.deserializeUser(function(username, done) { 233 passport.deserializeUser(function(username, done) {
230 var user = { 234 var user = {
231 username: username 235 username: username
232 }; 236 };
233 done(null, user); 237 done(null, user);
234 }); 238 });
235 239
236 app.get('/', loggedIn, function(req, res) { res.redirect('/dashboard'); }); 240 app.get('/', loggedIn, function(req, res) { res.redirect('/dashboard'); });
237 app.get('/config', loggedIn, renderConfigIndex); 241 app.get('/config', loggedIn, renderConfigIndex);
238 app.get('/login', renderLoginPage); 242 app.get('/login', renderLoginPage);
239 app.post('/login', passport.authenticate('local', { successRedirect: '/dashboard', failureRedirect: '/login' })); 243 app.post('/login', passport.authenticate('local', { successRedirect: '/dashboard', failureRedirect: '/login' }));
240 app.get('/logout', function(req, res){ 244 app.get('/logout', function(req, res){
241 req.logout(); 245 req.logout();
242 res.redirect('/login'); 246 res.redirect('/login');
243 }); 247 });
244 248
245 app.param('scope', function(req, res, next, value) { 249 app.param('scope', function(req, res, next, value) {
246 req.scope = value; 250 req.scope = value;
247 next(); 251 next();
248 }); 252 });
249 253
250 app.param('keyword', function(req, res, next, value) { 254 app.param('keyword', function(req, res, next, value) {
251 req.keyword = value; 255 req.keyword = value;
252 next(); 256 next();
253 }); 257 });
254 258
255 app.get('/config/edit/:scope/:keyword', loggedIn, renderConfigEdit); 259 app.get('/config/edit/:scope/:keyword', loggedIn, renderConfigEdit);
256 app.post('/config/edit/:scope/:keyword', loggedIn, submitConfigEdit); 260 app.post('/config/edit/:scope/:keyword', loggedIn, submitConfigEdit);
257 261
258 app.get('/config/ask-delete/:scope/:keyword', loggedIn, renderConfigAskDelete); 262 app.get('/config/ask-delete/:scope/:keyword', loggedIn, renderConfigAskDelete);
259 app.get('/config/delete/:scope/:keyword', loggedIn, submitConfigDelete); 263 app.get('/config/delete/:scope/:keyword', loggedIn, submitConfigDelete);
260 264
261 app.get('/config/add/:scope', loggedIn, renderConfigAdd); 265 app.get('/config/add/:scope', loggedIn, renderConfigAdd);
262 app.post('/config/add/:scope', loggedIn, submitConfigAdd); 266 app.post('/config/add/:scope', loggedIn, submitConfigAdd);
263 267
264 app.get('/config/save', loggedIn, submitConfigSave); 268 app.get('/config/save', loggedIn, submitConfigSave);
265 269
266 app.get('/dashboard', loggedIn, renderDashboardIndex); 270 app.get('/dashboard', loggedIn, renderDashboardIndex);
267 271
268 var server = app.listen(config.expresso.listen_port, function () { 272 var server = app.listen(config.expresso.listen_port, function () {
269 var host = server.address().address; 273 var host = server.address().address;
270 var port = server.address().port; 274 var port = server.address().port;
271 275
272 console.log('Expresso admin UI listening at http://%s:%s', host, port); 276 console.log('Expresso admin UI listening at http://%s:%s', host, port);
273 }); 277 });
274 } 278 }
275 279
276 function sanitizeMatrix(matrix) { 280 function sanitizeMatrix(matrix) {
277 if (matrix === undefined) { 281 if (matrix === undefined) {
278 matrix = {}; 282 matrix = {};
279 } 283 }
280 if (matrix.config_dirty === undefined) { 284 if (matrix.config_dirty === undefined) {
281 matrix.config_dirty = 0; 285 matrix.config_dirty = 0;
282 } 286 }
283 } 287 }
284 288
285 function start(options) { 289 function start(options) {
286 if (options['config']) { 290 if (options['config']) {
287 config = options['config']; 291 config = options['config'];
288 } 292 }
289 293
290 if (options['matrix']) { 294 if (options['matrix']) {
291 matrix = options['matrix']; 295 matrix = options['matrix'];
292 } 296 }
293 sanitizeMatrix(matrix); 297 sanitizeMatrix(matrix);
294 298
295 if (options['aaa']) { 299 if (options['aaa']) {
296 aaa = options['aaa']; 300 aaa = options['aaa'];
297 } 301 }
298 302
299 if (options['expresso_views']) { 303 if (options['expresso_views']) {
300 view_path = options['expresso_views']; 304 view_path = options['expresso_views'];
301 } 305 }
302 306
303 createServer(); 307 createServer();
304 } 308 }
305 309
306 exports.start = start; 310 exports.start = start;
307 311