feature: authentuication
This commit is contained in:
		@@ -1,7 +1,13 @@
 | 
			
		||||
const moment = require('moment');
 | 
			
		||||
const bcrypt = require('bcryptjs');
 | 
			
		||||
const crypto = require("crypto");
 | 
			
		||||
 | 
			
		||||
const { insertSessions, insertSessionTracks } = require("../db/mongo/mongoSessions");
 | 
			
		||||
const { createUserMongo, getUserMongo } = require('../db/mongo/mongoUsers');
 | 
			
		||||
const { getHistoricalSessions, getIvaoSessionTracks } = require("../requests/ivao/session");
 | 
			
		||||
 | 
			
		||||
const saltRounds = 10;
 | 
			
		||||
 | 
			
		||||
async function initSessionsData(opts) {
 | 
			
		||||
  const { callsign, userId, from, clear = false } = opts;
 | 
			
		||||
  let to = opts.to;
 | 
			
		||||
@@ -45,6 +51,39 @@ async function pause(millis) {
 | 
			
		||||
  await new Promise((resolve) => setTimeout(resolve, millis));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function getHashedPassword(password) {
 | 
			
		||||
  const salt = bcrypt.genSaltSync(saltRounds);
 | 
			
		||||
  return bcrypt.hashSync(password, salt);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function createUser(request) {
 | 
			
		||||
  try {
 | 
			
		||||
    const { username, password, roles, firstname, lastname, vid } = request.body;
 | 
			
		||||
    const hash = getHashedPassword(password);
 | 
			
		||||
    const id = crypto.randomBytes(16).toString("hex");
 | 
			
		||||
    return await createUserMongo({ id, username, hash, roles, firstname, lastname, vid });
 | 
			
		||||
  } catch (err) {
 | 
			
		||||
    console.log('err :>> ', err);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function authenticate(username, password) {
 | 
			
		||||
  try {
 | 
			
		||||
    const user = await getUserMongo(username);
 | 
			
		||||
    if (bcrypt.compareSync(password, user.hash)) {
 | 
			
		||||
      delete user.hash;
 | 
			
		||||
      return user;
 | 
			
		||||
    }
 | 
			
		||||
    return undefined;
 | 
			
		||||
  } catch (err) {
 | 
			
		||||
    console.log('err :>> ', err);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
module.exports = {
 | 
			
		||||
  initSessionsData,
 | 
			
		||||
  createUser,
 | 
			
		||||
  authenticate,
 | 
			
		||||
  getHashedPassword,
 | 
			
		||||
}
 | 
			
		||||
@@ -19,18 +19,23 @@ const getMongoDatabase = (client, db) => {
 | 
			
		||||
  return client.db(DB);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const mongoExecute = async(fn, dbName = MONGO_DB) => {
 | 
			
		||||
  let conn;
 | 
			
		||||
const mongoExecute = async function(fn, opts) {
 | 
			
		||||
  const { dbName, colName } = { dbName: MONGO_DB, ...opts };
 | 
			
		||||
  let connection;
 | 
			
		||||
  try {
 | 
			
		||||
    conn = await getMongoConnection();
 | 
			
		||||
    const db = conn.db(dbName);
 | 
			
		||||
    const result = await fn(db, conn);
 | 
			
		||||
    return result;
 | 
			
		||||
    connection = await getMongoConnection();
 | 
			
		||||
    const database = connection.db(dbName);
 | 
			
		||||
    if (colName) {
 | 
			
		||||
      const collection = database.collection(colName);
 | 
			
		||||
      return await fn({ collection, database, connection });
 | 
			
		||||
    }
 | 
			
		||||
    return await fn({ database, connection });
 | 
			
		||||
  } catch (err) {
 | 
			
		||||
    console.log('err :>> ', err);
 | 
			
		||||
    console.log('MOMGODB ERROR:', err.message);
 | 
			
		||||
  } finally {
 | 
			
		||||
    if (conn) {
 | 
			
		||||
      await conn.close();
 | 
			
		||||
    if (connection) {
 | 
			
		||||
      await connection.close();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,8 @@
 | 
			
		||||
const { mongoExecute } = require("./mongoDBPool");
 | 
			
		||||
 | 
			
		||||
async function insertSessions(sessions, clear) {
 | 
			
		||||
  return mongoExecute(async(db) => {
 | 
			
		||||
    const sessionsCollection = db.collection('sessions');
 | 
			
		||||
  return await mongoExecute(async({ database }) => {
 | 
			
		||||
    const sessionsCollection = database.collection('sessions');
 | 
			
		||||
 | 
			
		||||
    if (clear) {
 | 
			
		||||
      sessionsCollection.deleteMany({});
 | 
			
		||||
@@ -16,16 +16,16 @@ async function insertSessions(sessions, clear) {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
async function insertOneSessionTracks(sessionTracks) {
 | 
			
		||||
  return mongoExecute(async(db) => {
 | 
			
		||||
    const sessionsCollection = db.collection('sessionTracks');
 | 
			
		||||
  return await mongoExecute(async({ database }) => {
 | 
			
		||||
    const sessionsCollection = database.collection('sessionTracks');
 | 
			
		||||
 | 
			
		||||
    await sessionsCollection.insertOne(sessionTracks);
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function insertSessionTracks(sessionTracks, clear) {
 | 
			
		||||
  return mongoExecute(async(db) => {
 | 
			
		||||
    const sessionsCollection = db.collection('sessionTracks');
 | 
			
		||||
  return await mongoExecute(async({ database }) => {
 | 
			
		||||
    const sessionsCollection = database.collection('sessionTracks');
 | 
			
		||||
 | 
			
		||||
    if (clear) {
 | 
			
		||||
      sessionsCollection.deleteMany({});
 | 
			
		||||
@@ -36,8 +36,8 @@ async function insertSessionTracks(sessionTracks, clear) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function getSessions(start, end) {
 | 
			
		||||
  return mongoExecute(async(db) => {
 | 
			
		||||
    const sessionsCollection = db.collection('sessions');
 | 
			
		||||
  return await mongoExecute(async({ database }) => {
 | 
			
		||||
    const sessionsCollection = database.collection('sessions');
 | 
			
		||||
    const startDate = start + 'T00:00:00.000Z';
 | 
			
		||||
    const endDate = end + 'T23:59:59.999Z';
 | 
			
		||||
    const result = await sessionsCollection.aggregate([{
 | 
			
		||||
@@ -71,9 +71,9 @@ async function getSessions(start, end) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function getSessionTracks(sessionId) {
 | 
			
		||||
  return mongoExecute(
 | 
			
		||||
    async(db) => {
 | 
			
		||||
      const tracksCollection = db.collection('sessionTracks');
 | 
			
		||||
  return await mongoExecute(
 | 
			
		||||
    async({ database }) => {
 | 
			
		||||
      const tracksCollection = database.collection('sessionTracks');
 | 
			
		||||
      const tracks = await tracksCollection.findOne({ sessionId });
 | 
			
		||||
      return tracks;
 | 
			
		||||
    }
 | 
			
		||||
@@ -81,8 +81,8 @@ async function getSessionTracks(sessionId) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function updateSessionTracks(tracks) {
 | 
			
		||||
  return mongoExecute(async(db) => {
 | 
			
		||||
    const tracksCollection = db.collection('sessionTracks');
 | 
			
		||||
  return await mongoExecute(async({ database }) => {
 | 
			
		||||
    const tracksCollection = database.collection('sessionTracks');
 | 
			
		||||
    await tracksCollection.updateOne({ _id: tracks._id }, { $set: { calculatedTime: tracks.calculatedTime } });
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										29
									
								
								app/db/mongo/mongoUsers.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								app/db/mongo/mongoUsers.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,29 @@
 | 
			
		||||
const { mongoExecute } = require('./mongoDBPool');
 | 
			
		||||
 | 
			
		||||
async function createUserMongo({ id, username, hash, roles = [], firstname, lastname, vid }) {
 | 
			
		||||
  return await mongoExecute(async({ database }) => {
 | 
			
		||||
    const usersCol = database.collection('users');
 | 
			
		||||
    const createdOn = new Date();
 | 
			
		||||
    await usersCol.insertOne({
 | 
			
		||||
      id,
 | 
			
		||||
      username,
 | 
			
		||||
      hash,
 | 
			
		||||
      createdOn,
 | 
			
		||||
      roles,
 | 
			
		||||
      firstname,
 | 
			
		||||
      lastname,
 | 
			
		||||
      vid
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function getUserMongo(username) {
 | 
			
		||||
  return await mongoExecute(async({ collection }) => {
 | 
			
		||||
    return await collection.findOne({ username });
 | 
			
		||||
  }, { colName: 'users' })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports = {
 | 
			
		||||
  createUserMongo,
 | 
			
		||||
  getUserMongo,
 | 
			
		||||
};
 | 
			
		||||
@@ -1,7 +1,35 @@
 | 
			
		||||
const express = require('express');
 | 
			
		||||
const { initSessionsData } = require('../controllers/adminController');
 | 
			
		||||
const passport = require('passport')
 | 
			
		||||
const LocalStrategy = require('passport-local');
 | 
			
		||||
const { initSessionsData, createUser, authenticate } = require('../controllers/adminController');
 | 
			
		||||
const router = express.Router();
 | 
			
		||||
 | 
			
		||||
passport.use(new LocalStrategy(async function verify(username, password, cb) {
 | 
			
		||||
  try {
 | 
			
		||||
    const user = await authenticate(username, password);
 | 
			
		||||
    delete user._id;
 | 
			
		||||
 | 
			
		||||
    if (user) {
 | 
			
		||||
      return cb(null, user);
 | 
			
		||||
    }
 | 
			
		||||
    return cb(null, false, { message: 'Incorrect username or password.' });
 | 
			
		||||
  } catch (err) {
 | 
			
		||||
    return cb(null, false, { message: 'Incorrect username or password.' });
 | 
			
		||||
  }
 | 
			
		||||
}));
 | 
			
		||||
 | 
			
		||||
passport.serializeUser(function(user, cb) {
 | 
			
		||||
  process.nextTick(function() {
 | 
			
		||||
    const { id, username, roles, firstname, lastname, vid } = user;
 | 
			
		||||
    cb(null, { id, username, roles, firstname, lastname, vid });
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
passport.deserializeUser(function(user, cb) {
 | 
			
		||||
  process.nextTick(function() {
 | 
			
		||||
    return cb(null, user);
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
router.get('/init-sessions', async(req, res) => {
 | 
			
		||||
@@ -13,4 +41,31 @@ router.get('/init-sessions', async(req, res) => {
 | 
			
		||||
  }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
router.post('/user/create', async(req, res) => {
 | 
			
		||||
  await createUser(req);
 | 
			
		||||
  res.status(201);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
router.post('/user/authenticate',
 | 
			
		||||
  passport.authenticate('local'),
 | 
			
		||||
  function(req, res) {
 | 
			
		||||
    console.log('req.user :>> ', req.isAuthenticated(), req.user);
 | 
			
		||||
    res.json(req.user);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
router.get('/user/alive',
 | 
			
		||||
  function(req, res) {
 | 
			
		||||
    console.log('req.user :>> ', req.isAuthenticated());
 | 
			
		||||
    res.status(200).json(req.user);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
router.get('/user/logout', function(req, res, next) {
 | 
			
		||||
  req.logout(function(err) {
 | 
			
		||||
    if (err) { return next(err); }
 | 
			
		||||
    req.session.destroy();
 | 
			
		||||
    res.status(200).send();
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
module.exports = router;
 | 
			
		||||
@@ -43,7 +43,6 @@ router.get('/sessions/all/now', async(req, res) => {
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
router.get('/flightplans/latest', async(req, res) => {
 | 
			
		||||
  console.log('object :>> ', '/flightplans/latest');
 | 
			
		||||
  try {
 | 
			
		||||
    const data = await getLatestsFlightPlans();
 | 
			
		||||
    res.status(200).json(data);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user