simpleSMTP User Auth - node.js

I'm trying to build a SMTP server with nodejs and stuck at user authentication. How can I create a function to auth the user with user: foo and pass: bar ?
var simplesmtp = require("simplesmtp"),
fs = require("fs");
var options = {
requireAuthentication: true,
debug: true
};
var smtp = simplesmtp.createServer(options);
smtp.listen(9845);
smtp.on("authorizeUser", function (connection, username, password, callback) {
callback(new Error("Auth fail!"), true);
});
smtp.on("startData", function(connection){
console.log("Message from:", connection.from);
console.log("Message to:", connection.to);
connection.saveStream = fs.createWriteStream("message.txt");
});
smtp.on("data", function(connection, chunk){
connection.saveStream.write(chunk);
});
smtp.on("dataReady", function(connection, callback){
connection.saveStream.end();
console.log("Incoming message saved to message.txt");
callback(null, "ABC1"); // ABC1 is the queue id to be advertised to the client
//callback(new Error("Rejected as spam!")); // reported back to the client
});

Did you try something like this?
smtp.on("authorizeUser", function (connection, username, password, callback) {
if (username == "foo" && password == "bar") {
callback(null, true);
} else {
callback(new Error("Auth fail!"), false);
}
});

Related

how to handle synchronous databse query in node.js

I am new to node.js, and I am starting with login and signUp implementation, and I have just found that my database Query of MySQL failed to execute in sequence. So what I do is to find does username match exisiting usernames in database, and invitation codes, if there exist, I will send my JSON file with property true, otherwise false, but I have just found, the json file is sent before the database query is finished, so that even if user name matched, the response property is still set to false. I tried async and sync but I still have trouble understanding and fixing my error, can someone please help me on fix or a better alternative implementation in this case? Thank you!!
Here is my code:
// build up connection to db
const con = mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'pwd',
database: 'test'
});
// async function search
async function dbFind(db, dbName, attribute, value) {
let users;
try{
console.log(`11111111111111`)
const users = await db.promise().query(`SELECT EMAIL_ADRESS FROM ${dbName} WHERE ${attribute} = ?`, [value]);
// console.log(`users: ${users}`)
if (users) {
return users;
} else {
return null;
}
} catch (err){
console.log(err)
}
}
// parse the json file from front-end and save it in variable data
app.post('/API/user/registration', function(req,res){
con.connect((err) => {
if(err){
console.log(err);
return;
}
console.log('Connection established');
});
var username = req.body.username;
var password = req.body.password;
var invicode = req.body.invitation_code;
var name = req.body.name;
console.log('reqeust ' + req.body)
// variable initialization
var invitationCodeMatched = false;
var role = 'student';
const uid = uuid.v4();
var verifyToken = uuid.v1()
var flag = true;
// // check if the username have already been registered isRegistered
if (dbFind.sync(con, 'login_Authentication', 'EMAIL_ADRESS', username) != null){
flag = false
} else {
flag = true
}
console.log(`1 ${flag}`)
// check invitation code to see if a user qualify for a TA:
if (dbFind(con, 'invitation_code', 'INVITATION_CODE', invicode) != null){
role = 'TA';
invitationCodeMatched = true
}
console.log(`3 ${invitationCodeMatched}`)
// otherwisr: insert it into te database:
const uLoginAuth = {
USER_ID: uid,
EMAIL_ADRESS: username,
PSWORD:password,
VERIFIED: false,
VERIFYCODE: verifyToken
};
const uInfo = {
USER_ID: uid,
NME: name,
USER_ROLE: role,
EMAIL_ADRESS: username
};
if(flag){
con.query('INSERT INTO login_authentication SET ?', uLoginAuth, (err, res) => {
if(err) throw err;
console.log('Last insert ID:', res.insertId);
});
con.query('INSERT INTO user_info SET ?', uInfo, (err, res) => {
if(err) throw err;
console.log('Last insert ID:', res.insertId);
});
}
con.query('SELECT * FROM user_info', (err,rows) => {
if(err) throw err;
console.log('Data received from Db:');
console.log(rows);
});
con.end((err) => {
// The connection is terminated gracefully
// Ensures all remaining queries are executed
// Then sends a quit packet to the MySQL server.
});
//send json file to the front end
console.log(`2 ${flag}`)
let judge = {
isRegistered: flag,
invitationCodeMatched: invitationCodeMatched
};
res.json(judge);
//If the user has not yet verified:
lib.sendConfirmationEmail(name, username, verifyToken)
});
app.listen(3000)
The output while hearing from request is:
1 false
2 false
and there is no output of 11111111 inside async dbFind function, there is a database match in this scenario, but what it returns is :
{
"isRegistered": false,
"invitationCodeMatched": false
}
which is the default value that is initailized before.

NodeJs login form with SQL Server user auth

I am having an issue with authenticating users using a SQL Server database. I have established the connection with the database and can pull user from the database. However when trying to query the database for authentication I get an "unhandledpromise - connection is closed" error.
app.js file:
var sql = require("mssql");
var express = require("express");
var session = require("express-session");
var bodyParser = require("body-parser");
var path = require("path");
var dbconfig = {
server: "Server",
database: "Test",
user: "########",
password: "####################",
port: 1433,
options : {
encrypt: false
}
};
var app = express();
app.use(session({
secret: 'Secret',
resave: true,
saveUninitalized: true
}));
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(bodyParser.json());
app.get('/', function(request, response) {
response.sendFile(path.join(__dirname + '/login.html'));
});
app.post('/auth', function(request, response) {
var username = request.body.username;
var password = request.body.password;
var conn = new sql.ConnectionPool(dbconfig);
var req = new sql.Request(conn);
if (username && password) {
conn.connect();
req.query('Select * from Admin where username = ? and password = ?', [username, password], function(error, results, fields) {
if (results.length > 0) {
request.session.loggedin = true;
resquest.session.username = username;
response.redirect('/home');
} else {
response.send('Username and/or Password not found');
}
conn.close();
response.end();
});
} else{
response.send('Please enter Username and Password');
}
});
app.get('/home', function(request, response){
if(request.session.loggedin){
response.send('Welcome back,' + request.session.username + '!');
}else{
response.send('Please sign');
}
response.end();
});
app.listen(3000);
function getEMP() {
var conn = new sql.ConnectionPool(dbconfig);
var req = new sql.Request(conn);
conn.connect(function(err) {
if (err) {
console.log(err);
return;
}
req.query("Select * from Admin", function(err, recordset) {
if (err) {
console.log(err)
} else {
console.log(recordset)
}
conn.close();
});
});
}
getEMP();
The getEMP function returns all of the admins from the database as expected. This is why I am positive the connection is working. This function was used for testing connection.
Error
UnhandledPromiseRejectionWarning: ConnectionError: Connection is closed.
at Request._query (///nodeconSQL/node_modules/mssql/lib/base/request.js:447:37)
at Request._query (///nodeconSQL/node_modules/mssql/lib/tedious/request.js:346:11)
at shared.Promise (///nodeconSQL/node_modules/mssql/lib/base/request.js:413:12)
at new Promise ()
at Request.query (///nodeconSQL/node_modules/mssql/lib/base/request.js:412:12)
at /home/devops-01/nodeconSQL/app.js:43:13
at Layer.handle [as handle_request] (///nodeconSQL/node_modules/express/lib/router/layer.js:95:5)
at next (///nodeconSQL/node_modules/express/lib/router/route.js:137:13)
at Route.dispatch (///nodeconSQL/node_modules/express/lib/router/route.js:112:3)
at Layer.handle [as handle_request] (///nodeconSQL/node_modules/express/lib/router/layer.js:95:5)
Your function getEMP() uses the callback from conn.connect() in order to wait until the connection is established before trying to execute the query.
The function that tries to login executes the query immediately after attempting to open the connection, however since the connection takes some time to be established, this is why you get the error that your connection is not open.
Put your login query inside the conn.connect(function(err){ /* login code */ }) construct like it is in your getEMP() function. You will then need to make sure that you can access the request and response objects in the callback function, for example by using .bind() on your callback function to put the request and response objects into the this object. Another option is to use closure functions to get data to the callbacks.
Example using closures:
app.post('/auth', function(request, response) {
var username = request.body.username;
var password = request.body.password;
if (username && password) {
var conn = new sql.ConnectionPool(dbconfig);
conn.connect((function(){
var thisConn = conn;
var req = new sql.Request(thisConn);
return function(){ //connect callback
req.query('Select * from Admin where username = ? and password = ?', [username, password],
(function(){
var req = request;
var resp = response;
var conn = thisConn;
return function(error, results, fields) { // query callback
if (results.length > 0) {
req.session.loggedin = true;
req.session.username = username;
resp.redirect('/home');
} else {
response.send('Username and/or Password not found');
}
conn.close();
resp.end();
};
})());
};
})());
} else {
response.send('Please enter Username and Password');
}
});
Example using bind:
...
// Inside your /auth route
// make an object with the data our callback needs, to use with .bind()
var callbackData = {"conn": conn, "request": request, "response": response};
var connectCallback = function(err){
if (err) {
console.log(err);
return;
}
req.query('Select * from Admin where username = ? and password = ?',
[username, password], function(error, results, fields) {
// 2nd level of callback, query callback
if (results.length > 0) {
this.request.session.loggedin = true;
this.resquest.session.username = username;
this.response.redirect('/home');
} else {
this.response.send('Username and/or Password not found');
}
this.conn.close();
this.response.end();
}.bind(this)); // pass our 'this' object through to the next level
}.bind(callbackData);
conn.connect(connectCallback);
...

Express authentication handling does not function

I am building a demo authentication system using express in combination with sqlite 3. Authentication functions the way it should, but the client does not react to any of the responses such as:
res.send('welcome to website');
or
res.redirect(login.html);
or
res.redirect('http://google.com');
How can I properly handle a login after it is approved?
Server side:
app.get('/login/username/:userN/password/:passW', function (req, res) {
var username = req.params.userN,
password = req.params.passW;
console.log('initiating login');
db.get('SELECT * FROM users WHERE username=?', [username], (err, row) => {
if (row == undefined){
console.log('login fail (user doesnt exist)')
}
else if (row.password == password) {
res.redirect('http://google.com');
console.log('user: ' + username + ' logged in');
}
else {
console.log('login fail (wrong password)');
}
})
});
Clientside:
function get(url) {
xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", "http://localhost:3000/" + url, true);
xmlhttp.send();
};
$('#login').click(function server() {
var username = document.getElementById('user').value;
var password = document.getElementById('pass').value;
var url = 'login/username/' + username + '/password/' + password;
get(url);
});

Using socket.io in modules and routes Express

I am having some issues using socket.io is modules. I have changed the way I do it quite drastically, however everything seems to be working, except being able to send userdata back to my socket connection:
Here is my io.js file: /config/io
/*jshint esversion: 6*/
var io = require('socket.io')();
const moment = require('moment');
// Socket stuff
io.on('connection', function (socket) {
socket.on('login', function (userdata) {
socket.handshake.session.userdata = userdata;
socket.handshake.session.save();
console.log(socket.handshake.session.userdata);
});
// Server Time
var interval = setInterval(function () {
var momentNow = moment();
var data = momentNow.format('LT');
socket.emit('time', data);
}, 60000);
// Chat - Needs work
socket.on('chat', function (msg) {
console.log(msg);
var username = 'Message'; //socket.handshake.session.userdata.username;
var message = '[' + moment().format('LT') + '] ' + username + ': ' + msg;
io.emit('message', message, username);
});
socket.on('disconnect', function () {
if (socket.handshake.session.userdata) {
delete socket.handshake.session.userdata;
socket.handshake.session.save();
}
console.log('user disconnected');
});
});
module.exports = io;
Here is where I'm trying to emit the data /config/passport: (please note that userdata does indeed contain the right information!)
/*jshint esversion: 6 */
const LocalStrategy = require('passport-local').Strategy;
const db = require('../config/db');
const bcrypt = require('bcryptjs');
var io = require('./io');
module.exports = function(passport) {
// Local Strategy login
passport.use(new LocalStrategy(function(username, password, done) {
// Match Username
let sql = 'SELECT * FROM users WHERE username = ?';
db.query(sql, [username], function(err, rows) {
if (err)
return done(err);
if (!rows.length) {
return done(null, false, {
type: 'loginMessage',
message: 'Wrong Login',
});
}
// Match Password
bcrypt.compare(password, rows[0].password, function(err, isMatch) {
if (err)
return done(err);
if (isMatch) {
var userdata = rows[0];
io.emit('login', userdata); // HERE IS WHERE I TRY TO EMIT IT
// console.log(rows[0]);
return done(null, rows[0]);
} else {
return done(null, false, {
type: 'loginMessage',
message: 'Wrong Login',
});
}
});
});
}));
Now here is my main app file: (leaving out a bunch of stuff)
var io = require('./config/io');
// Init App
const app = express();
// Init http server
const server = http.createServer(app);
// Attach IO
io.attach(server);
// Listen
server.listen(8080, function () {
console.log('Server listening on port 8080...');
});
Now, everything seems to be working fine, except being able to emit the data. Now I tried logging it client side as well (just in case it was emitting on client-side and not server-side) but it is not doing that as well.
Okay, so here is an actual working answer. It s a work-around, and I completely abandoned trying to do it from the passport login handler itself. But here is how I did it:
IO code:
var session = socket.handshake.session;
socket.on('login', function () {
if (socket.handshake.session.passport === undefined) {
var destination = '/';
socket.emit('not logged', destination);
} else {
console.log('user logged in');
var userId = session.passport.user;
var sql = 'SELECT * FROM users WHERE id = ?';
var query = db.query(sql, userId, function (err, rows) {
session.userdata = rows[0];
session.save();
var dataObj = session.userdata;
socket.emit('sart up', dataObj);
});
}
});
And jQuery:
// Connection Successful
socket.on('connect', function () {
connected = true;
socket.emit('login');
});
socket.on('disconnect', function () {
connected = false;
});
socket.on('not logged', function (destination) {
window.location.href = destination;
});
socket.on('start up', function (dataObj) {
});
I'm not a huge fan of having to do it this way, I would have liked to handle everything sever-sided, but for now this is working, and will use until I figure out how to do it the way I'd like to.

how to create login api using odoo-node?

I simply want to create api for login . no signup is there, username and password is already there in database.
simply want to get username and password from front end and , i have to check with existing database, whether username and password matching, then i have to send some success message or token, what ever it be.
font end side is angularjs. and in angularjs im using
$http.post("/api address",usedata).success(data,success){}
like that but i have no idea how to do it in backend side. anyone please help.....
what i have tried with oddo is given below.
var express = require('express');
var app = express();
var fs = require("fs");
var Odoo = require('node-odoo');
var odoo = new Odoo({
host: '192.168.1.121',
port: 8091,
database: 'oaveg_demo',
username: 'dkashyap#oaveg.com',
password: 'abcd#1234'
});
app.get('/api/userdetails',function(req, res) {
odoo.connect(function(err) {
if (err) {
return console.log(err);
}
odoo.get('res.users', 14, function(err, partner) {
if (err) {
return console.log(err);
}
var userData = {};
userData.name = partner.display_name;
userData.email = partner.email;
userData.id = partner.id;
userData.password = partner.password;
console.log('PARTNER GET====> ', userData);
});
var params = [['login','=','aritha#oaveg.com'],['password' , '=' , '']];
odoo.search('res.users', params, function(err, partner) {
if (err) {
return console.log(err);
}
console.log('PARTNER SEARCH===> ', partner);
})
});
});
app.listen(3001);

Resources