Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
126 changes: 126 additions & 0 deletions controllers/authentication.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
/*==========================
* Subscriptions
*
* @description: Managing the client subscription to be notified about a given topic
* @author: Government of Canada; @duboisp
* @version: 1.0
===========================*/

const axios = require('axios');

const NotifyClient = require('notifications-node-client').NotifyClient; // https://docs.notifications.service.gov.uk/node.html#node-js-client-documentation

const entities = require("entities");

const dbConn = module.parent.exports.dbConn;
const ObjectId = require('mongodb').ObjectId;

var options = {
apiVersion: 'v1', // default
endpoint: 'http://127.0.0.1:8200' // default
//token: '1234' // optional client token; can be fetched after valid initialization of the server
};

// get new instance of the client
//const vault = require("node-vault");

const processEnv = process.env,
_devLog = !!!processEnv.prodNoLog,
_keySalt = processEnv.keySalt || "salt",
_validHosts = JSON.parse(processEnv.validHosts || '["localhost:8080"]'),
_errorPage = processEnv.errorPage || "https://canada.ca",
_successJSO = processEnv.successJSO || { statusCode: 200, ok: 1 },
_cErrorsJSO = processEnv.cErrorsJSO || { statusCode: 400, bad: 1, msg: "Bad request" },
_sErrorsJSO = processEnv.sErrorsJSO || { statusCode: 500, err: 1 },
_notifyEndPoint = processEnv.notifyEndPoint || "https://api.notification.alpha.canada.ca",
_confirmBaseURL = processEnv.confirmBaseURL || "https://apps.canada.ca/x-notify/subs/confirm/",
_nbMinutesBF = processEnv.notSendBefore || 25, // Default of 25 minutes.
_bypassSubscode = processEnv.subscode,
_topicCacheLimit = processEnv.topicCacheLimit || 50,
_notifyCacheLimit = processEnv.notifyCacheLimit || 40,
_flushAccessCode = processEnv.flushAccessCode,
_flushAccessCode2 = processEnv.flushAccessCode2,
_notifyUsTimeLimit = processEnv.notifyUsTimeLimit || 180000,
_subsLinkSuffix = processEnv.subsLinkSuffix || "853e0212b92a127";

let notifyCached = [],
notifyCachedIndexes = [],
topicCached = [],
topicCachedIndexes = [],
fakeSubsIncrement = 0,
_notifyUsNotBeforeTimeLimit = 0;



/*
// init vault server
vault.init({ secret_shares: 1, secret_threshold: 1 })
.then( (result) => {
var keys = result.keys;
// set token for all following requests
vault.token = result.root_token;
// unseal vault server
console.log("result.root_token : " + result.root_token);
return vault.unseal({ secret_shares: 1, key: keys[0] })
})
.catch(console.error);


vault.write('secret/hello', { value: 'world', lease: '1s' })
.then( () => vault.read('secret/hello'))
.then( () => vault.delete('secret/hello'))
.catch(console.error);
*/

//
// Get key
//
// @return; a JSON containing valid key
//
exports.getKey = ( req, res, next ) => {

generateAuthenticationKey().then(data => {
res.json({data})
})
};



//
// Get Authentication Token key from Vault
//
// @return; a JSON containing valid key
//
generateAuthenticationKey = () => {



/*return axios.get("http://127.0.0.1:8200/v1/secret?help=1",
{ headers: {'X-Vault-Token': 'root'}}
)
.then((response) => {
console.log(response.data);
//console.log(response.status);
return response.data
}, (error) => {
console.log(error);
});
*/
/// http://localhost:8200/v1/sys/seal-status
// https://dog.ceo/api/breeds/list/all
// http://172.18.0.1:8200/v1/sys/seal-status
return axios.get("http://ec2-100-26-121-207.compute-1.amazonaws.com:8200/v1/sys/seal-status",
{ headers: {'Content-Type': 'application/json'}}
)
.then((response) => {
console.log(response.data);
//console.log(response.status);
return response.data
}, (error) => {
console.log(error);
});


}


236 changes: 236 additions & 0 deletions controllers/users.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,236 @@
/**
* Module dependencies.
*/
const express = require('express'); // HTTP server
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const cors = require('cors'); // CORS
const crypto = require('crypto');

const userNameSecretKeyCollection = module.parent.exports.userNameSecretKeyCollection;

const userNamePasswordCollection = module.parent.exports.userNamePasswordCollection;

userNameSecretKeyCollection.createIndex( { "userName": 1 }, { unique: true } );

/**
* Create Express server.
*/
const usersRouter = express();


// Generate the secret key
let keyMap = new Map()
const NO_USER = "noUser";
var username;

usersRouter.get('/getSecretKey', (req, res) => {
const secretKey = crypto.randomBytes(64).toString('base64').replace(/\//g,'_').replace(/\+/g,'-');
console.log(secretKey);
// first loading to get secret key, there is no way to get to know the user info
keyMap.set(NO_USER, secretKey);


userNameSecretKeyCollection.replaceOne(
{ userName: NO_USER },
{ userName: NO_USER, secretKey: secretKey },
{ upsert : true}
).then( () => {
console.log("1 document inserted on api /test/getSecretKey ");
}).catch( ( e ) => {
console.log( "err while generate secretKey on api /test/getSecretKey" );
console.log( e );
});

res.json({ secretKey: secretKey })
})



// Get all the username Password
usersRouter.get('/getAllUserNamePassword', (req, res) => {

userNamePasswordCollection.find({}).toArray(function(err, result) {
if (err) throw err;
console.log(result);
res.sendStatus(200);
});
}
);


// Register
usersRouter.post('/register', (req, res) => {
var { username, password } = req.body;
console.log(username + " as username and password " + password);
let errors = [];

userNamePasswordCollection.findOne({ username: username }).then(user => {
if (user) {
errors.push({ msg: 'UserName already exists' });
console.log("UserName already exists");
res.status(200).send("UserName already exists");
} else {
bcrypt.genSalt(10, (err, salt) => {
bcrypt.hash(password, salt, (err, hash) => {
if (err) throw err;
password = hash;
userNamePasswordCollection.insertOne({username: username, password: password})
.then(user => {
console.log("You are now registered and can log in");
//res.redirect('/users/login');
res.sendStatus(200);
})
.catch(err => {
console.log(err);
res.sendStatus(500);
});
});
});
}
});
}
);


// Generate the key and persist in hashmap
usersRouter.post('/login', verifyToken, (req, res) => {
// Authenticate User
//res.status(500).send('The email is not registered');
//console.log( req.headers );
//console.log( req.body );

username = req.body.username;
const password = req.body.password;
console.log("username is " + username + " and password is " + password);
var secretKey;

// Match user
userNamePasswordCollection.findOne({
username: username
}).then(user => {
if (!user) {
console.log("That email is not registered");
res.status(500).send('The email is not registered');
} else {
// Match password
bcrypt.compare(password, user.password, (err, isMatch) => {
if (err) throw err;
if (isMatch) {
console.log("Password is matched and user can login");
secretKey = crypto.randomBytes(64).toString('base64').replace(/\//g,'_').replace(/\+/g,'-');
console.log(secretKey);
keyMap.set(username, secretKey);

userNameSecretKeyCollection.replaceOne(
{ userName: username },
{ userName: username, secretKey: secretKey },
{ upsert: true }
).then( () => {
console.log("1 document inserted on api /test/login");
res.json({ secretKey: secretKey });
}).catch( ( e ) => {
console.log( "err while generate secretKey on api /test/login" );
console.log( e );
});
} else {
console.log("Password incorrect");
}
});
}
});


})


// List mailing for the user
usersRouter.get( '/mailing/create/:topicId', cors( { "origin": "*" } ),
verifyToken, ( req, res ) => {
const user = req.user;
res.json( {
id: "uid-33",
created: "2020-06-16",
updated: "2020-06-16",
title: "Mailing Title",
user
} );

});

// Logout
usersRouter.get('/logout', (req, res) => {
req.logout();
// delete the user related document in the collection
console.log("logout username : " + username)
var myquery = { username: username };
userNameSecretKeyCollection.deleteOne(myquery, function(err, obj) {
if (err) throw err;
console.log("1 document deleted" + obj);
});

res.sendStatus(200);

});

// Authenticate the JWT and verify that if it is tampered or not
// FORMATE OF TOKEN
// Authorization : Bearer <accessToken>
// Verify Token
function verifyToken(req, res, next) {
// check if the secretKey is generated by server
// check if the request include jws in http header authroization
const authHeader = req.headers['authorization']
const token = authHeader && authHeader.split(' ')[1]
if (token == null) return res.sendStatus(401)
console.log("incoming token payload : " + token);

let secretKey ='';
if (req.body.secretKey){
secretKey = req.body.secretKey;
jwt.verify(token, secretKey, (err, decoded) => {
console.log(err)
if (err) return res.sendStatus(403)
console.log("decoded payload : " + decoded.name);
console.log("decoded payload : " + decoded.sub);
console.log("decoded payload : " + decoded.iat);
req.user = decoded
next()
})
} else {
let payload = token.split('.')[1];
let buff = new Buffer(payload, 'base64');
let payLoadJson = JSON.parse(buff.toString('ascii'));
let userNameFromPayload = payLoadJson.name;
secretKey = keyMap.get(userNameFromPayload);


userNameSecretKeyCollection.find({}).toArray(function(err, result) {
if (err) throw err;
console.log(result);
});

userNameSecretKeyCollection.findOne(
{ userName: userNameFromPayload }
).then((documentRecord) => {
console.log("userName in payload in verify : " + documentRecord.userName);
console.log("secretKey in mongoDb : " + documentRecord.secretKey);
jwt.verify(token, documentRecord.secretKey, (err, decoded) => {
console.log(err)
if (err) return res.sendStatus(403)
console.log("decoded payload : " + decoded.name);
console.log("decoded payload : " + decoded.sub);
console.log("decoded payload : " + decoded.iat);
req.user = decoded
next()
})
}).catch( (e) => {
console.log( "look up document by useName in verify" );
console.log( e );
});
}

}

module.exports = usersRouter;

Loading