Using continue as button for facebook login - javascript

I am building a React Native app, I previously implemented Facebook login using login Manager
export const onLogin = () => {
return (dispatch) => {
console.log('inside login');
dispatch({ type: ON_LOGIN });
LoginManager.logInWithReadPermissions(['public_profile',
'email']).then((res) => {
console.log(res);
MakeGraphRequest(dispatch);
},
(error) => {
console.log(error);
LoginFail(dispatch, error);
});
};
};
function MakeGraphRequest(dispatch) {
const responseInfoCallback = (error: ?Object, result: ?Object) => {
if (error) {
console.log(error);
LoginFail(dispatch, error);
} else {
axios({
method: 'post',
url: 'url',
data: {
first_name: result.first_name,
last_name: result.last_name,
profile_photo: result.picture.data.url,
email: result.email,
spend_history: []
}
}).then((res) => {
if (res.data.userid) {
const userid = res.data.userid;
LoginSuccessForUnregisteredUser(dispatch, result, userid);
} else {
LoginSuccess(dispatch, result);
}
});
}
};
const infoRequest = new GraphRequest(
'/me',
{
parameters: {
fields: {
string: 'email, first_name, last_name, picture.type(large), birthday'
}
}
},
responseInfoCallback
);
new GraphRequestManager().addRequest(infoRequest).start();
}
Also I've used Login Button and Expo Facebook login but I could not find a way to implement this kind of a login.
Should I use Login Manager or Login Button. The Facebook docs are valid for web only. Is there a way to integrate this in my RN(react native) project?

You already have the user data in the response. So you can just start your screen (like in the picture) and ask if the user really wants to sign in with this account. Only after that, call your LoginSuccess events. If the user doesn't want to login just dispose the result data.
.then((res) => {
if (res.data.userid) {
const userid = res.data.userid;
// add screen logic here
// LoginSuccessForUnregisteredUser(dispatch, result, userid);
} else {
// add screen logic here
// LoginSuccess(dispatch, result);
}
});
Same would go with the Facebook Login Button or AuthSession.
Using AsyncStorage to save/fetch the state and get wether he goes or goes not to the "continue as" screen.
try {
await AsyncStorage.setItem('#MySuperStore:key', 'I like to save it.');
} catch (error) {
// Error saving data
}
try {
const value = await AsyncStorage.getItem('#MySuperStore:key');
if (value !== null){
// We have data!!
// show "continue as" screen
console.log(value);
}
} catch (error) {
// Error retrieving data
}

Related

How to make a post request by SERVER not by user

Node.js CODE
exports.user = async (req, res) => {
try {
const { wallet } = req.body;
if (!wallet) {
res.status(400).json({ error: "Not logged in" });
return;
} else {
user = User.findone(wallet);
// if user is not found then create a new user and mark as loggged In
if (!user) {
User.create({
user: wallet,
});
}
// if user found then create a session token and mark as logged
in
res.send({
user: wallet,
});
}
} catch (error) {
console.log(`ERROR::`, error);
}
};
REACTJs CODE
// post call/update
const axiosCall = async () => {
// core login will give a unique username by fulling a transcation
// core.login i dont have any control
const userAccount = await core.login();
try {
const res = await Axios.post(`${API}/user`, userAccount, dataToken);
setData({
...data,
error: "",
success: res.data.message,
});
} catch (error) {
setData({
...data,
error: error.response.data.error,
});
}
};
Now here the problem occurs when some one could modify userAccount in the front-end or someone could send a body with wallet: anything to my route localhost:3000/api/user
There is no option for me to check if some actually used core.login(); to get the wallet address.
So is there any solution?
I was thinking to allow only my server IP or localhost to hit the route localhost:3000/api/user and is that even possible?
Also there is another issue anyone could modify userAccount in front-end.

Set State inside axios post method

I have axios post method to check username and password when they available I want to set a state as true but always get the state as false.
My code is:
const [validated, setValidated] = useState(false);
const login = () => {
Axios.post('http://124.43.17.60:4000/loginnew', {
username: email,
password: password
}).then((response) => {
// let data = response.data
console.log("my web response all", response)
console.log("my web response", response.data[0])
try {
if (response.data[0].role) {
let role = response.data[0].role
setValidated(true)
console.log(validated)
if (role == "admin") {
history.push('/admin')
} else {
history.push('/member')
}
}
} catch (err) {
alert.error("wrong credentials");
}
});
}
Can anyone tell me what um doing wrong and please help me to solve this problem
In React, modifying the state is an asynchronous action. Meaning that this piece of code won't give your expected results:
setValidated(true)
console.log(validated) // Won't be updated to true
If you want to achieve something specifically on true, you have 2 options
1. useEffect
useEffect(() => { if (validated) { ...do something... } }, [validated])
2. setState callback
setValidated((oldValidated) => {
const newValidated = !oldValidated;
console.log(newValidated) // true if oldValidated was false
// do something with newValidated === true
return newValidated; // Make sure to return the new value, otherwise state won't update at all.
})
You cannot view the "updated" state inside you login function as setValidated is an asynchronous process, which mean the code will not wait for the data to get back and still use the old value. Read this post for more explanation
If you want to view the "updated" value of validated you need to create a useEffect like so
useEffect(() => {
console.log(validated)
})
useEffect(() => {
Axios.post('http://124.43.17.60:4000/loginnew', {
username: email,
password: password
}).then((response) => {
// let data = response.data
console.log("my web response all", response)
console.log("my web response", response.data[0])
try {
if (response.data[0].role) {
let role = response.data[0].role
setValidated(true)
console.log(validated)
if (role == "admin") {
history.push('/admin')
} else {
history.push('/member')
}
}
} catch (err) {
alert.error("wrong credentials");
}
});
}, []);

ClientSide Notification for failed Login

I have a node.js project where I can fill a login form which will be send to my server.js as url params. If the sent data can be verified as registered, the client will be logged in. My Problem is now how do notificate the client when it didn't work?
My login.html contains a div which will be shown if it's triggered by my login.js file. But how do I activate the trigger, can I send url params to client and change the site's behaviour?
server.js
app.get("/signUp/:username/:password", (req, res) => {
auth.signUp({
username: req.params.username,
password: req.params.password
}, (result) => {
if (result) {
res.redirect("../../index.html");
} else {
res.redirect("../../index.html");
// res.send("Login failed");
}
})
})
app.get("/signIn/:username/:password", (req, res) => {
auth.signIn({
username: req.params.username,
password: req.params.password
}, (result) => {
if (result) {
res.redirect("../../index.html");
} else {
res.send("Login failed");
}
})
})
login.js Client-Side
signIn = () => {
let user = document.getElementById('signDiv-username').value;
let pass = document.getElementById('signDiv-password').value;
hideErrorLog();
window.location.replace("/signIn/" + user + "/" + pass);
}
signUp = () => {
let user = document.getElementById('signDiv-username').value;
let pass = document.getElementById('signDiv-password').value;
hideErrorLog();
window.location.replace("/signUp/" + user + "/" + pass);
}
hideErrorLog = () => {
let errorLog = document.getElementById("error-log");
errorLog.style.display = "none";
errorLog.innerText = "";
}
showErrorLog = (signUp) => {
let errorLog = document.getElementById("error-log");
errorLog.style.display = "block";
if (signUp) {
errorLog.innerText = "Benutzername existiert bereits!";
} else {
errorLog.innerText = "Benutzername/Passwort falsch!";
}
}
I see that you have been calling SignUp and SignIn APIs by using window.location.replace() and you are just replacing username and password as a part of the url which is not the way to make API calls AFAIK. And also never pass sensitive data like username and password in the URL, send them as part of body of the request.
You need to make use of fetch() and call showErrorLog() inside the catch() which means there's error in the API call.
Sample fetch code
fetch('http://example.com/movies.json')
.then(function(response) {
// Add some code here
})
.then(function(myJson) {
// call showErrorLog() here
});

Get data when login by facebook?

I have this function to log in by facebook method in firebase with React Native :
async handleFacebookButton() {
const navigation = this.props.navigation;
const { type, token } = await Facebook.logInWithReadPermissionsAsync(FACEBOOK_APP_ID, {
permissions: ['public_profile', 'email']
});
if (type === 'success') {
const credential = firebase.auth.FacebookAuthProvider.credential(token);
navigation.navigate("Profile");
auth.signInWithCredential(credential).catch(error => {
this.setState({ errorMessage: error.message });
alert('please check your email or password');
});
}
}
And I need to get the user data when login, like username, phone, email.
how can I get the data?
You need a .then() in your auth.signInWithCredential(). Then you'd have something like:
auth.signInWithCredential().then(user => {
// user is the signed in user, for which you can get details
})

Twitter authentication with passport.js

This is a real niche question regarding Twitter OAuth with passport.js ()
I have a controller which updates the user's avatar using their Twitter "avatar":
const signInViaTwitter = (twitterProfile) => {
return new Promise((resolve, reject) => {
console.log(twitterProfile);
// find if user exist on in
User.findOne({ username: twitterProfile.username }, (error, user) => {
if (error) { console.log(error); reject(error); }
else {
// user existed on db
if (user) {
// update the user with latest git profile info
user.name = twitterProfile.displayName;
user.username = twitterProfile.username;
user.avatarUrl = twitterProfile.photos.value;
user.email = '';
// save the info and resolve the user doc
user.save((error) => {
if (error) { console.log(error); reject(error); }
else { resolve(user); }
});
}
// user doesn't exists on db
else {
// check if it is the first user (Adam/Eve) :-p
// assign him/her as the admin
User.count({}, (err, count) => {
console.log('usercount: ' + count);
let assignAdmin = false;
if (count === 0) assignAdmin = true;
// create a new user
const newUser = new User({
name: twitterProfile.displayName,
username: twitterProfile.username,
avatarUrl: twitterProfile.photos.value,
email: '',
role: assignAdmin ? 'admin' : 'user',
});
// save the user and resolve the user doc
newUser.save((error) => {
if (error) { console.log(error); reject(error); }
else { resolve(newUser); }
});
});
}
}
});
});
};
The authentication of the user works - but for some reason, the avatar won't show...here is the following console output:
Refused to load the image 'https://api.twitter.com/favicon.ico'
because it violates the following Content Security Policy directive:
"img-src https://abs.twimg.com https://*.twimg.com
https://pbs.twimg.com data:".
Does anyone know what this means? I'm thinking it's probably due to being in development mode - that is, http://localhost:8080/ ... and it won't accept https?? Or won't pass it back?
UPDATE: ^I think the above error is unrelated to the image not being display...
A little look at the html source gives:
<img class="styles__userAvatar___2x2U9" src="{unknown}" alt="Wind Up Lord Vexxos Avatar">
So it's obviously passing in an unknown variable for the src - rather than the user's display avatar...
So, for me it looks like the offending line is:
user.avatarUrl = twitterProfile.photos.value;
What should I be setting this to?
Just a thought, isn't twitterProfile.photos an array? probably you should try accessing twitterProfile.photos[0].value

Categories