const express = require('express'); const app = express(); const mongoose = require('mongoose'); const Schema = mongoose.Schema; const database = 'mongodb://' + process.env.mongousr + ':' + process.env.mongopwd + '@mongo:27017/test'; const today = new Date(); var counter = 0; const Prometheus = require('prom-client'); const fs = require('file-system'); const marked = require('marked'); const jwt = require('jsonwebtoken'); const bodyParser= require('body-parser'); const colors = require('colors'); const secret = 'wowmuchsecretveryhiddenwow'; // const morgan = require('morgan'); // use morgan to log requests to the console // app.use(morgan('dev')); // database connection (with retries) const options = { autoIndex: false, // Don't build indexes reconnectTries:30, // Retry up to 30 times reconnectInterval: 500, // Reconnect every 500ms poolSize: 10, // Maintain up to 10 socket connections // If not connected, return errors immediately rather than waiting for reconnect bufferMaxEntries: 0, useNewUrlParser: true } const connectWithRetry = () => { console.log('MongoDB connection with retry') mongoose.connect(database, options).then(()=>{ console.log('MongoDB is connected') }).catch(err=>{ console.log('MongoDB connection unsuccessful, retry after 5 seconds.') setTimeout(connectWithRetry, 5000) }) } const libCounter = new Prometheus.Counter({ name: 'lib_invocation_count', help: 'A simple counter for app access during runtime created with prometheus nodejs library' }); const libUptime = new Prometheus.Counter({ name: 'lib_upTime', help: 'uptime A counter of the application\'s uptime in seconds created with prometheus nodejs library.' }) console.log('mongousr: ', process.env.mongousr); console.log('mongopwd: ', process.env.mongopwd); // Prometheus Default Metrics collector const collectDefaultMetrics = Prometheus.collectDefaultMetrics; // Probe every 5th second. collectDefaultMetrics({ timeout: 5000 }); // new schema model object based on the structure of what I want to put on MongoDB collection var testSchema = new Schema({ thingies: { type: String } },{ collection: 'test' }); // new object that will hold the data using model structure made above var thingies = mongoose.model('thingieName', testSchema); // Default message for testing app.get('/', (req, res)=>{ res.json([{message:'yes, your nodejs app is really running'}]); counter++; // for prometheus invocation_count metric libCounter.inc(); // for prometheus lib_invocation_count metric console.log('Hello, I\'m inside endpoint \'/\''.green); }); // Test endpoint for md files rendering app.get('/test', function(req, res) { var path = '/app/README.md'; var file = fs.readFileSync(path, 'utf8'); res.send(marked(file.toString())); }); // Prometheus metrics endpoint - Library app.get('/metrics', function(req, res){ libUptime.inc(Math.floor(process.uptime())); res.set('Content-Type', Prometheus.register.contentType) res.end(Prometheus.register.metrics()) libUptime.reset(); }); // Prometheus metrics endpoint - Handmade app.get('/metrics2', function(req, res){ var now = new Date(); var passedTime = now - today; res.writeHead(200, {'Content-Type':'text/plain'}); res.write('# HELP uptime A counter of the application\'s uptime in millisenconds.' + '\n'); res.write('# TYPE uptime counter' + '\n'); res.write('uptime ' + passedTime + '\n'); res.write('# HELP invocation_count A simple counter for app access during runtime' + '\n'); res.write('# TYPE invocation_count counter'+ '\n'); res.write('invocation_count ' + counter + '\n'); res.end(); }) // JWT generation app.use(bodyParser.urlencoded({ extended: false })); app.post('/token', function(req, res) { const claims_power = { username: req.body.username, password: req.body.password, subject: 'power#1234', issuer: 'http://youcantrustme.io', scope: 'admin' }; const claims_user = { username: req.body.username, password: req.body.password, subject: 'normal_user', issuer: 'http://youcantrustme.io', scope: 'user' }; let token = ''; switch(req.body.username) { case 'user1': if (req.body.password === 'pass1') { token = jwt.sign(claims_user, secret); console.log('JWT Token: ' + token); console.log(jwt.decode(token)); // req.headers['access-token'] = token; res.redirect('http://localhost/yay.html'); } else { res.redirect('http://localhost/nay.html'); } break; case 'power': if (req.body.password === 'weak') { token = jwt.sign(claims_power, secret); console.log('JWT Token: ' + token); console.log(jwt.decode(token)); // req.headers['access-token'] = token; res.redirect('http://localhost/yay.html'); } else { res.redirect('http://localhost/nay.html'); } break; default: res.status(500).send('User not found'); } console.log('http headers below:') console.log(req.headers); }); // Restricted route // const restrictedRoutes = express.Router(); // app.use('/restricted', restrictedRoutes); // restrictedRoutes.use((req, res, next) => { // if (req.headers['access-token']) { // jwt.verify(req.headers['access-token'], secret), (err, decoded) => { // if (err) { // return res.json({ message: 'invalid token' }); // } else { // req.decoded = decoded; // next(); // } // } // } else { // res.status(500).send('no token found'); // } // }); // Restricted endpoint // restrictedRoutes.get('/restricted', (req, res) => { // res.json([{secret:'you can see this message if you have access'}]) // }); // Mongo query app.get('/info', function(req, res){ thingies.find({}).then(function (thingies) { res.json(thingies); }); }); // Mongo insert app.post('/info/add/:name', function(req, res){ var item = {thingies: req.params.name}; var data = new thingies(item); data.save(); res.send('thingie ' + req.params.name + ' added to database' + '\n'); }); connectWithRetry(); app.listen(3001, () => { console.log('Server running on port 3001'); console.log('process.env.PORT: ' + process.env.PORT); });