passport.js authenticate popup window using sails.js - node.js

i need a help in passport.js authentication.
passort.js authentiction working fine.
but i dont know how can i create authentication login in popup window.
all the authentication process functions in backend.
please help me.
'linkedin': function(req, res) {
passport.authenticate('linkedin', {failureRedirect: '/login', scope: ['r_basicprofile', 'r_emailaddress']},
function(err, user) {
req.logIn(user, function(err) {
if (err) {
// console.log(err);
res.view('500');
return;
}
req.session.user = user;
return res.redirect('/user');
});
})(req, res);
},
'facebook': function(req, res) {
passport.authenticate('facebook', {failureRedirect: '/login', scope: ['email','publish_stream'],display:'popup' },
function(err, user) {
req.logIn(user, function(err) {
if (err) {
throw err;
res.view('500');
return;
}
req.session.user = user;
if (p) {
//write the post project function
}
return res.redirect('/user');
});
})(req, res);
},
this is my login page
<form action ="/auth/linkedin" method = "POST" class="columns small-12 iconized" >
<input type="hidden" value="test messge" name="title">
<button type="submit" class="icon-linkedin">Linkedin</button>
</form>
please help how can i resize the window .

One solution is jquery.lightbox_me.js found here http://www.freshdesignweb.com/demo/index.php?p=1379320109
Just follow the steps:
1) download the source code, and copy the .js file to assets/js, and copy the .css file to assets/style
2) change your html code to
<button id="loginBtn" class="btn btn-success btn-med">Login</button>
<form id="loginForm" action ="/auth/linkedin" method = "POST" class="columns small-12 iconized" display: none; >
<input type="text" value="test messge" name="title">
<button type="submit" class="icon-linkedin">Linkedin</button>
</form>
<script>
$('#loginBtn').click(function(e) {
$('#loginForm').lightbox_me({
centered: true,
onLoad: function() {
$('#loginForm').find('input:first').focus()
}
});
e.preventDefault();
});
</script>
3) This should do the trick. However eventually it will best if you keep your js scripts out of the html/ejs files, so things are more tidy.
Since Sails comes with ejs-locals, I would put the content within the tags in a separate file and make a call to <% block ... %> instead. Check this page for more info:
Sails.js - How to inject a js file to a specific route?

Related

Cant Save to MongoDB database and using handlebars

this is my post request to save to mongdb database
router.post("/create", async (req, res) => {
const createJottings = new Jottings({
title: req.body.title,
jottings: req.body.jottings
});
try {
await createJottings.save();
res.json(createJottings);
} catch (err) {
res.json({ message: err });
}
});
it works fine on postman but now i am trying to render it using handlebars to the client. this is the form for the client side using handlebars
<div class="card card-body">
<h3>
Edit Jottings/Idea
</h3>
<form action="/jottings/create" method="get">
<div class="form-group">
<label for="title">
Title
</label>
<input type="text" name="title" class="form-control" required />
</div>
<div class="form-group">
<label for="title">
Jottings
</label>
<textarea name="Description" class="form-control" required></textarea>
</div>
<button type="submit" class="btn btn-primary">
Submit
</button>
</form>
</div>
the form actually loads but when i press submit it doesnt save to mongodb server
{{#each getJottings}}
<div class="card card-body mb-2">
<h4>
{{title}}
</h4>
<p>
{{jottings}}
</p>
<a href="/jottings/edit/{{id}}" class="btn btn-dark btn-block">
Edit
</a>
</div>
{{else}}
<p>
No Ideas and Jottings listed
</p>
{{/each}}
code that outlists saved data in the database if i create it using postman it works but with the form it doesnt.
overview of my jottings route
// Require Mongoose
const router = require("express").Router();
// Setup Models for Jotting
const Jottings = require("../models/jottings.model");
// Setting Endpoints For Routes
// Get All Jottings
router.get("/", async (req, res) => {
try {
const getJottings = await Jottings.find({}).sort({ date: "desc" });
res.render("jottings/index", {
getJottings: getJottings
});
} catch (err) {
res.json({ message: err });
}
});
// Getting routes to set form
router.get("/add", (req, res) => {
res.render("jottings/add");
});
// Get Specific Jottings
router.get("/:id", async (req, res) => {
try {
// Requesting for request paremeter given to ever document created in mongoDB
const id = req.params.id;
await Jottings.findById(id, (err, jottings) => {
if (!id) {
res.json({ message: err });
} else {
res.json(jottings);
}
});
} catch (err) {
res.json({ message: err });
}
});
// Post to create New Jottings for form
router.post("/create", async (req, res) => {
const createJottings = new Jottings({
title: req.body.title,
jottings: req.body.jottings
});
try {
await createJottings.save();
res.json(createJottings);
} catch (err) {
res.json({ message: err });
}
});
router.get("/edit/:id", async (req, res) => {
try {
// Requesting for request paremeter given to ever document created in mongoDB
const id = req.params.id;
const editJottings = await Jottings.findOne({ _id: id });
res.render("jottings/edit", {
editJottings: editJottings
});
} catch (err) {
res.json({ message: err });
}
});
// Patch to Edit Jottings for form
router.patch("/edit/:id", async (req, res) => {
try {
// Requesting for request paremeter given to ever document created in mongoDB
const id = req.params.id;
const editJottings = await Jottings.updateOne(
{ _id: id },
{ $set: { jottings: req.body.jottings } }
);
res.render("jottings/edit", {
editJottings: editJottings
});
} catch (err) {
res.json({ message: err });
}
});
// Delete to delete Jottings for form
router.delete("/delete/:id", async (req, res) => {
try {
// Requesting for request paremeter given to ever document created in mongoDB
const id = req.params.id;
const deleteJottings = await Jottings.deleteOne({ _id: id });
res.json(deleteJottings);
} catch (err) {
res.json({ message: err });
}
});
// Exporting router
module.exports = router;
i would like the details to be saved to the database when i click the submit button and also redirect me to a list of my saved details.
You form uses method GET while you defined router.post to handle form submission.

app.post won't work, expressJS

I want to integrate a button on my website that will open a port, recieve some data, update a database and then render the home page. Basically I need that botton to execute the code between the app.post's curly brackets.
That works fine when I click the button for first time but then, after rendering, I have to restart the server to do that again.
app.post('/test', isLoggedIn, (req, res) => {
port.on('data', function (data) {
sirDeAfisat+=data.toString('ascii');
if(checker.sfarsitSir(data)==true) {
if(checker.sirOk(sirDeAfisat)==true){
fs.appendFile("./log/date.txt",sirDeAfisat,(err)=>{
if(err) console.log(err.message);
});
const child=fork('./parser_ok.js');
child.send(`${sirDeAfisat}`);
child.on('message',(answ)=>{
console.log(`Sunt portul, am primit de la parser : ${answ}`)
child.kill('SIGINT');
});
}else{
fs.appendFile('./log/erori.txt',new Date().toISOString(),function (err){
if(err) console.log(err.message);
});
fs.appendFile('./log/erori.txt',"SIR !OK",sirDeAfisat,(err)=>{
if(err) console.log(err.message);
});
}
sirDeAfisat='';
port.close();
res.send(201);
return;
}
});
port.on('readable',() =>{
port.read();
});
});
isLoggedIn:
function isLoggedIn (req, res, next) {
if (req.isAuthenticated()) {
return next();
}
res.redirect('/');
}
and this is test.ejs
<!-- form -->
<form action="/test" method="post">
<input type="submit" class="btn btn-dark btn-lg">
</form>

Nodejs Passport authentication & local strategy not work through API Call

This is solved. Actually, the problem is with postman not on Passport code
I have a login system which is implemented through Nodejs Passport. For Login I use Handlebars for creating the UI and send the form data from frontend to backend.
These is my login Handlebars File
<form id="userloginform" method="post" action="/user/login">
<div class="form-group">
<label>Username</label>
<input type="text" name="username" class="form-control" placeholder="Username or Email">
</div>
<div class="form-group">
<label>Password</label>
<input type="password" name="password" class="form-control" placeholder="Password">
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
and on User.js file I have a code of authentication i.e like this
//Login Handler
passport.use('local-user', new LocalStrategy(
function(username, password, done) {
User.getUserByUsername(username, function(err, user){
if(err) {
console.log('error')
logger.log('error', 'Error Generates on User.getUserByUsername Query on users.js file');
throw err;
}
if(!user){
return done(null, false, {message: 'Unknown User'});
}
User.comparePassword(password, user.password, function(err, isMatch){
if(err) {
logger.log('error', 'Error Generates on User.comparePassword Query on users.js file');
throw err;
}
if(isMatch){
return done(null, user);
}else{
return done(null, false, {message: 'Invalid Credential, please check carefully...!'})
}
});
});
}
));
//Login Authentication
router.post('/login',
passport.authenticate('local-user', {
failureRedirect: '/user/login',
badRequestMessage: 'Field cannot be blank.!!', //missing credentials
failureFlash: true
}),
function(req, res) {
console.log('hello');
req.flash('success_msg', 'Welcome ' + req.user.name);
req.flash('custom_msg', token);
//res.redirect('/success?username='+req.user.username);
res.redirect('/user/dashboard');
});
All these things are working pefectly.
Now when I call it through postman and pass two parameters i.e username and password then it does nothing. Simply failure redirect.
I have done this through proper nodejs with form submitted pattern. Now I want to be done through API from different Server.
Anyone have any idea then let me know. Any help is really appreciated.

Post file and data in same request to node server

I have a form in HTML with two inputs - 1 text and 1 file.
<form method="post" action="http://localhost:3000/users">
<input type="text" name="username" />
<input type="file" name="file" />
<button type="submit">Submit</button>
</form>
Now I am posting it to a node server-
router.post('/users', function(req, res, next){
req.pipe(req.busboy);
req.busboy.on('file', function(fieldname, file, filename){
var fstream=fs.createWriteStream('./uploads/'+filename);
file.pipe(fstream);
fstream.on('close', function(){
var user = User({
username: req.body.username,
});
user.save(function(err){
if(err)
res.json({error: err});
else
res.redirect('/');
});
});
});
});
But I am only able to get either username or file (when I use enctype="multipart/form-data" in HTML form.) at a time.
Is there any way to save both in a single request. If yes then how ?
Any help is appreciated.
Thanks.
You're only listening for file fields. If you want to be notified about non-file fields, then you need to also add a 'field' event listener:
req.busboy.on('field', function(key, val, keyTrunc, valTrunc) {
console.log(key, val);
});

bcrypt.compareSync is always returning false

I verified that in my db I am saving the username and hash of the password. I am able to retrieve the name from the db, however when I check the password it always returns false. Not sure what is wrong.
Here is my HTML
<div ng-controller="userController">
<div class=user>
<form name="login_form">
<h2 class>Login</h2>
<h3 class = "login_page">UserName</h3>
<input ng-model="user" type="text" ng-minlength="1" required>
<h3 class = "login_page">Password</h3>
<input ng-model="password" type="password" name="password" ng-minlength="4" required>
<input type="submit" value="Login" ng-click="login()" >
<div ng-if ="login_form.$submitted" ng-messages="login_form.password.$error" style="color:maroon" role="alert">
<div ng-message="minlength">Your field is too short</div>
</div>
<p ng-if="error">Username or login is incorrect</p>
</form>
</div>
<div class=user>
<form name = "register_form">
<h2 class>Register</h2>
<h3 class = "login_page">UserName</h3>
<input ng-model="reg.name" type="text" required>
<h3 class = "login_page">Password</h3>
<input ng-model="reg.password" type="password">
<input type="submit" value="Register" ng-click="register()" required >
<div ng-if ="login_form.$submitted" ng-messages="login_form.password.$error" style="color:maroon" role="alert">
<div ng-message="minlength">Your field is too short</div>
</div>
<p ng-if="duplicate">That user name is taken, please choose another</p>
<p ng-if="correct">Registration Succesfull</p>
</form>
</div>
</div>
Here is my controller on the server side
var mongoose = require('mongoose'),
Todo = mongoose.model('Todo');
Login = mongoose.model('Login');
var bcrypt = require('bcrypt');
var name = ""
module.exports = (function(){
return {
save_name:function(req, res){
req.session.user = req.body.user
Login.findOne({name: req.body.user},
function(err, user) {
if(user){
console.log(user.password);
console.log( bcrypt.compareSync(req.body.password, user.password));
res.json({'error': false});
}else {
res.json({'error': true});
}
})
}, //end of save name method
register:function(req, res){
bcrypt.hashSync(req.body.password, bcrypt.genSaltSync(8));
login = new Login({
name:req.body.user,
password: bcrypt.genSaltSync(8)
})
login.save(function(err){
if(err){
res.json({'error': true});
} else {
res.json({'sucess': true})
}
})
} // end of register user function
}
})();
You're saving a generated salt as the password instead of the actual hash itself. Also, explicitly calling genSalt*() is unnecessary. Lastly, you really should use the async functions instead, to avoid unnecessarily blocking the event loop. So with all of this in mind, you may end up with something like:
module.exports = {
save_name: function(req, res) {
req.session.user = req.body.user;
Login.findOne({ name: req.body.user },
function(err, user) {
if (err)
return res.json({ error: true });
bcrypt.compare(req.body.password,
user.password,
function(err, valid) {
res.json({ error: !!(err || !valid) });
});
});
}, // end of save name method
register: function(req, res) {
bcrypt.hash(req.body.password, 8, function(err, hash) {
if (err)
return res.json({ error: true });
login = new Login({
name: req.body.user,
password: hash
})
login.save(function(err) {
res.json({ error: !!err });
})
});
} // end of register user function
};
Despite other answers, if it is still not resolving your issue. Try by applying the toString() when passing the password upon login like this.
req.body.password.toString();
The immediate cause of your bug is in register you should be using bcrypt.hashSync(myPlaintextPassword, saltRounds) instead of genSaltSync. Fixing that should make things "work".
However, you need to recode all this to use the async bcrypt APIs or your application will respond very poorly under load (like crippled and unusable, not just "slow"). General rule: no sync calls in a node.js server.

Resources