I am new to node.js and want to send private message to my facebook friends. I used facebook-chat
but above framework is not supported.
Please give me sample code or example for the same.
I use facebook-chat-api module:
var login = require("facebook-chat-api");
login({
email: "your#mail.com",
password: "password"
}, function callback(err, api) {
if (err) return console.error(err);
var userId = "12345";
var msg = {
body: "Hey! That's Node.js!"
};
api.sendMessage(msg, userID);
});
Example above didn't work with (string) user nicknames - only with user ids.
Related
I'm trying to authenticate users locally with Passport.js while not keeping session and using my own JWTokens.
I was following this tutorial:
Learn using JWT with Passport authentication
While also reading Passport.js documentation. I don't know what went wrong, but passport doesn't seem to notice that some functions are indeed functions.
I've got a Load function to select a User from the DB(mongo) given certain criteria(a user might logIn with e-mail or phone number).
load: function(options, cb) {
options.select = options.select || 'email phone';
return this.findOne(options.criteria)
.select(options.select)
.exec(cb);
}
I'm calling passport.authenticate in my routes:
// Controllers //
const Users = require('../../app/controllers/users');
...
...
app.post('/api/login', passport.authenticate('local', { failureRedirect: '/api/login' }), Users.login);
And here's my local strategy:
const mongoose = require('mongoose');
const User = mongoose.model('User');
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
passport.use(new LocalStrategy(
{
usernameField: 'email',
phoneField: 'phone',
passwordField: 'password',
session: false
},
function(email, phone, password) {//cb == callback
const options = {
criteria: { email: email, phone: phone },
select: 'name username email hashed_password salt'
};
User.load(options, function(err, user) {
if (err || !user){
return res.status(400).json({
type: 'failure',
message: "User creation failed",
data: [err]
});
};
if (!user.authenticate(password)) {
return res.status(400).json({
type: 'failure',
message: "User creation failed",
data: [err]
});
};
req.login(user, {session: false}, (err) => {
if (err) {
res.send(err);
}
// generate a signed son web token with the contents of user object and return it in the response
const token = jwt.sign(user.id, 'your_jwt_secret');
return res.json({user, token});
});
});
}
));
I'm getting the following error:
TypeError: res.status is not a function
Before trying to get stuff back from passport with responde. I was trying to do it with cb(callback), as done in the tutorial, but I keep getting the same error.
Thanks in advance for any help!
There are a few issues with how you are implementing Passport's local strategy that are causing problems.
You are trying to use two fields as the username when Passport's local startegy only accepts one. (see: http://www.passportjs.org/packages/passport-local/)
function(username, password, done){}
If you want to use both as a username, you might want to consider creating your own custom strategy. This is going to be a little more in-depth, but you can start learning on the Passport Github page (https://github.com/jaredhanson/passport-strategy)
The second issue is that you are trying to get Passport to send a response in the local strategy which is not what it is intended to do. Instead, you should be passing the errors and return values to Passport's done() function, which will process them accordingly.
Here is an example of what your local strategy should look like:
passport.use(
new LocalStrategy(async (email, phone, password, done) => {
const options = {
criteria: { email, phone },
select: 'name username email hashed_password salt',
};
try {
const user = await User.load(options);
/**
* If null is returned meaning there was no user found, send the done call
* with the false flag. This tells passport to redirect to the failure URL.
*/
if (!user) {
return done(null, false);
}
/**
* If the user's password is incorrect, also return the done function with the false
* flag. This tells passport to redirect to the failure URL.
*/
if (!user.authenticate(password)) {
return done(null, false);
}
/**
* If a user is found and their password is verified, send the user object to
* the done function. This will tell Passport to call the next middelware attaching
* the user object.
*/
return done(null, user);
} catch (err) {
/**
* If there is an error with the DB call, return generic message
* for security purposes.
*/
return done('There was an internal server error.');
}
})
);
and an example of what your load function should look like:
load: options => {
return new Promise(async (resolve, reject) => {
options.select = options.select || 'email phone';
try {
const user = await this.findOne(options.criteria)
.select(options.select)
.exec();
resolve(user);
} catch (err) {
reject(err);
}
});
};
As a general best practice, I changed your callbacks to the newer method of promises (https://developers.google.com/web/fundamentals/primers/promises).
This should work in the way you are intending to use Passport.
I am trying to login user using either username or email i.e user can enter either email or password and should be able to log in. However, so far I am able to use one of them.
Here is the code tried so far.
authenticate: function (req, res) {
var username = req.body.username;
var email = req.body.email;
users.findOne({
or: [
{username: username},
{email: email}
]
}).exec(function(err, user) {
console.log(user);
if (err) {
return res.json({err});
} else if (!user) {
var err = new Error('User not found.');
err.status = 401;
return res.json({err});
} else {
require('bcrypt').compare(req.body.password, user.password, function(err, result) {
if(result === true) {
return res.json({user});
} else {
return res.json({err});
}
});
}
});
}
Though sails waterline is not as powerful as direct access to any one db, it can do what you want here and much more. The docs give some good examples of what's possible.
I don't know exactly how you are passing in the username or email to your request object, but something like this should work:
authenticate: function(req, res) {
var username = req.param('username'); // or however you get this
var email = req.param('email'); // or however you get this
Users.findOne({
or: [{username: username}, {email: email}]
}).exec(function(err, user) {
// handle the error, or make use of found user...
});
}
You can also handle the case where user hands you an input that could be either a username or email...
var identifier = req.param('identifier'); // could be a username or an email
And then modify your or array to:
or: [{username: identifer}, {email: identifier}]
if you use the action 2 style, you can do
```
var identifier = inputs.identifier;
var userRecord = await User.findOne({
or : [{username: identifier}, {email: identifier}]
});
I am trying to add a REST API to my Meteor application using Restivus
I putted the following code in server folder of my Meteor application. Currently, I am trying to get the URL parameters.
var Api = new Restivus({
useDefaultAuth: true,
prettyJson: true
});
Api.addRoute('login/:id/:password', {authRequired: true}, {
get:{
action: function(){
var id = this.queryParams.id;
var password = this.queryParams.password;
return {
id: id,
password: password
}
}
}
});
I got this response
{
"status": "error"
"message": "API endpoint does not exist"
}
to my request:
http://localhost:3000/api/login?id=BGrZbGtKZZQYr9jDR&password=myPassword
the way you wrote the url login/:id/:password means it is expecting the url to be
http://localhost:3000/api/login/BGrZbGtKZZQYr9jDR/myPassword
However in your code, you are looking at the queryParams not urlParams:
var id = this.queryParams.id;
var password = this.queryParams.password;
You should choose one or the other:
use the code:
var id = this.urlParams.id;
var password = this.urlParams.password;
with the /login/:id/:password URL,
or use the route with just /login and pass the params as query params to use as you described:
http://localhost:3000/api/login?id=BGrZbGtKZZQYr9jDR&password=myPassword
var Api = new Restivus({
useDefaultAuth: true,
prettyJson: true
});
Api.addRoute('login', {authRequired: true}, {
get:{
action: function(){
var id = this.queryParams.id;
var password = this.queryParams.password;
return {
id: id,
password: password
}
}
}
});
I am having a problem with waterlock-local-auth. Basically I've been playing around with waterlock all day trying to figure out how to create a new user (with hashed password and all), and also how to authenticate the user from a form on a server side sails.js view. But have been completely unsuccessful. Below is the code in my LoginController that my login form is posting to. Any help will be greatly appreciated. Thanks!
module.exports = {
login: function(req, res) {
var isAuthenticated = function(){...} <-- Authenticated by waterlocks
if(isAuthenticated) {
res.view('home');
}
else {
res.view('login', {errorMessage: "Invalid username or password"});
}
}
};
Ok, so basically I went with the solution posted here (Sails.js Waterlock /auth/register causes error 500). ;0)
module.exports = require('waterlock').waterlocked({
// Endpoint for registering new users. Taken from: https://stackoverflow.com/questions/29944905/sails-js-waterlock-auth-register-causes-error-500/29949255#29949255
register: function (req, res) {
var params = req.params.all(),
def = waterlock.Auth.definition,
criteria = {},
scopeKey = def.email !== undefined ? 'email' : 'username'; // Determines if the credentials are using username or emailaddess.
var attr = { password: params.password }
attr[scopeKey] = params[scopeKey];
criteria[scopeKey] = attr[scopeKey];
waterlock.engine.findAuth(criteria, function (err, user) {
if (user)
return res.badRequest("User already exists");
else
waterlock.engine.findOrCreateAuth(criteria, attr, function (err, user) {
if (err)
return res.badRequest(err);
delete user.password;
return res.ok(user);
});
});
}
});
I am trying to implement a facebook connection in sails using passport. Therefore, I've created a passport.js file in my services folder, the code is given below. It looks like the login is done successfully, however the user serialization doesn't seem to work as the console.log that I put in it never appears in the console and I cannot access the user id trhough req.user once the user is supposed to be logged in. Did anyone managed to get passport working with sails?
var passport = require('passport')
, FacebookStrategy = require('passport-facebook').Strategy,
bcrypt = require('bcrypt');
// helper functions
function findById(id, fn) {
User.findOne(id).done( function(err, user){
if (err){
return fn(null, null);
}else{
return fn(null, user);
}
});
}
function findByUsername(u, fn) {
User.findOne({
username: u
}).done(function(err, user) {
// Error handling
if (err) {
return fn(null, null);
// The User was found successfully!
}else{
return fn(null, user);
}
});
}
// Passport session setup.
// To support persistent login sessions, Passport needs to be able to
// serialize users into and deserialize users out of the session. Typically,
// this will be as simple as storing the user ID when serializing, and finding
// the user by ID when deserializing.
passport.serializeUser(function(user, done) {
console.log("utilisateur serilizé!");
done(null, user.uid);
});
passport.deserializeUser(function(id, done) {
//console.log("coucou");
findById(id, function (err, user) {
done(err, user);
});
});
// Use the LocalStrategy within Passport.
// Strategies in passport require a `verify` function, which accept
// credentials (in this case, a username and password), and invoke a callback
// with a user object.
// using https://gist.github.com/theangryangel/5060446
// as an example
passport.use(new FacebookStrategy({
clientID: 'XXX',
clientSecret: 'XXX',
callbackURL: "http://localhost:1337/callback"
},
function(accessToken, refreshToken, profile, done) {
User.findOne({uid: profile.id}, function(err, user) {
if (err) { return done(err); }
if (user) {
//console.log('momo');
User.update({uid : user.uid},{token : accessToken},function(){done(null, user);});
} else {
console.log(profile);
var user_data = {
token : accessToken
, provider: profile.provider
, alias: profile.username
, uid: profile.id
, created: new Date().getTime()
, name: {
first: profile.name.givenName
, last: profile.name.familyName
}
, alerts: {
email: true
, mobile: false
, features: true
}
};
console.log(user_data);
User.create(user_data).done(function(err, user) {
console.log(err);
if(err) { console.log("err");throw err; }
done(null, user);
});
}
});
}
));
While I do not have a direct answer for you, this was extremely useful to when getting it to work with GitHub OAuth: https://github.com/stefanbuck/sails-social-auth-example/blob/master/config/middleware.js
This is an entire, recent, Sails.js application implementing passport so it might be of use to you to side-by-side the two in the debugger and find out what is going on.
Check out this easy and full implementation for sails.js with passport.js supporting both Email, Twitter and Facebook.
https://github.com/bmustata/sails-auth-super-template