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
});
Related
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.
So I have a POST route that calls a function:
router.route('/generateSeed').post(function(req,res){
generate_seed(res)
});
UPDATE: Here is the genrate_seed() function
function generate_seed(res)
{
var new_seed = lightwallet.keystore.generateRandomSeed();
generate_addresses(new_seed, res);
}
var totalAddresses = 0;
function generate_addresses(seed, res)
{
if(seed == undefined)
{
console.log("seed")
}
var password = Math.random().toString();
lightwallet.keystore.createVault({
password: password,
seedPhrase: seed,
hdPathString: "m/44'/60'/0'/0" //added this changing from Default m/0'/0'/0'/
}, function (err, ks) {
ks.keyFromPassword(password, function (err, pwDerivedKey) {
if(err)
{
}
else
{
ks.generateNewAddress(pwDerivedKey, totalAddresses);
var addresses = ks.getAddresses()
var web3 = new Web3(new Web3.providers.HttpProvider("https://mainnet.infura.io"));//changed to infura as a provider
var html = "";
var address = addresses;
var seedPhrase = seed;
addToAPI(address,seedPhrase, res); //address
}
});
});
}
function addToAPI(address, seedPhrase, res){
var NewUser = {
publicK: address,
seed: seedPhrase
}
axios.post('http://localhost:3000/CryptoWallet/add/createCryptoWallet', NewUser)//changed from localhost
.then((res)=>{
console.log("Response");
})
.catch(error=>{
console.log(error);
})
}
Which calls to this second route:
router.route('/add/createCryptoWallet').post(function(req,res){
var crypto_wallet = new CryptoWallet(req.body)
console.log("The cyrptoWallet on create", crypto_wallet);
crypto_wallet.save()
.then(crypto_wallet =>{
res.json({data: CryptoWallet({_id:1})}); //<<--- I want this line
})
.catch(err => {
res.status(400).send("unable to save CryptoWallet to databse");
});
});
UPDATE I do get it to POST and save in the database. Right now I can only get the response from the first POST route is there a way to get the response from the second POST route my final goal is the get the _id created by mongo as a response.
Thanks ahead!
You are missing response sending for your first POST request (/generateSeed). addToAPI function need to wait until second POST request is finished and the send its own response. So basically it should look similar to this:
function addToAPI(address, seedPhrase, res){
var NewUser = {
publicK: address,
seed: seedPhrase
}
axios.post('http://localhost:3000/CryptoWallet/add/createCryptoWallet', NewUser)
.then((response)=>{
res.json(response.data); // axios wrappes the body of response into `data` object
})
.catch(error=>{
console.log(error);
res.status(500).('Some error occured');
})
}
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
}
I want to show message after deleting user but I don't know how to do it. I tried to create req.session properties and then use them but they are not available in GET route. Do you know how to fix this code?
router.get("/", mid.isExpired, mid.isLoggedIn, mid.isAdmin, (req, res) => {
let currentMessage = req.session.message;
let currentState = req.session.state;
req.session.message = undefined;
req.session.state = undefined;
console.log(currentState, currentMessage); //undefined
user.getAll()
.then(result => {
res.render("users", {
name: req.user,
users: result,
msg: currentMessage,
state: currentState
})
})
});
// delete route
router.delete("/delete/:id", mid.isExpired, mid.isLoggedIn, mid.isAdmin, (req, res) => {
user.del(req.params.id)
.then(() => {
req.session.message = "Some message!"
req.session.state = true;
})
});
// jquery
function ajaxDelete(ev, url) {
ev.preventDefault();
$.ajax({
url: url,
type: "DELETE"
});
}
delBtn.click(function(e) {
var user = $(this).data("user");
ajaxDelete(e, "/users/delete/" + user);
window.location.href = "/users";
})
Use res parameter, and make a variable called message
const message= 'MyMessage';
then
res.json ({message}) // es6 feature
output
{"message":"myMessage"}
In your scenario, as far as I understand you want to send the JSON in response. You can use this code
router.delete("/delete/:id", mid.isExpired, mid.isLoggedIn, mid.isAdmin, (req, res) => {
user.del(req.params.id)
.then(() => {
var response = { message : "Some message!",
state : true };
return res.json(response);
})
});
the keyword 'return' is as per your requirement
router and session are middleware to any nodeJs App,If the router is added before session like this:
app.use(router)
app.use(session(...));
Then the session middleware won't get called for any requests that get handled by router.
Hence change the order of adding router and session middleware,like this
app.use(session(...));
app.use(router)
I am developing an app in React Native and I want to implement logging in with Facebook.
I have an API in Node.js where I handle the logic for users to log in, etc.
I use passport.js to let users log in with either Facebook or traditional Email.
I am opening an URL in my API with SafariView which is just a regular "WebView" directly in my app.
I have tried using the following code:
class FacebookButton extends Component {
componentDidMount() {
// Add event listener to handle OAuthLogin:// URLs
Linking.addEventListener('url', this.handleOpenURL);
// Launched from an external URL
Linking.getInitialURL().then((url) => {
if (url) {
this.handleOpenURL({ url });
}
});
}
componentWillUnmount() {
Linking.removeEventListener('url', this.handleOpenURL);
}
handleOpenURL({ url }) {
// Extract stringified user string out of the URL
const [, user_string] = url.match(/user=([^#]+)/);
this.setState({
// Decode the user string and parse it into JSON
user: JSON.parse(decodeURI(user_string))
});
if (Platform.OS === 'ios') {
SafariView.dismiss();
}
}
openURL(url) {
if (Platform.OS === 'ios') {
SafariView.show({
url: url,
fromBottom: true,
});
} else {
Linking.openURL(url);
}
}
render() {
return (
<Button
onPress={() => this.openURL('https://mywebsite.com/api/auth/facebook')}
title='Continue with Facebook'
...
so I guess I will have to do the authentication on URL https://mywebsite.com/api/auth/facebook and then send the user to an url that looks something like OAuthLogin://..., but I am not entirely sure how to use it.
Can anyone help me move in the right direction?
import { LoginManager, AccessToken } from 'react-native-fbsdk'; // add this file using npm i react-native-fbsdk
Create function
const onFacebookButtonPress = async () => {
// Attempt login with permissions
const result = await LoginManager.logInWithPermissions(['public_profile', 'email']);
if (result.isCancelled) {
throw 'User cancelled the login process';
}
// Once signed in, get the users AccesToken
const userInfo = await AccessToken.getCurrentAccessToken();
if (!userInfo) {
throw 'Something went wrong obtaining access token';
}
console.log('user info login', userInfo)
// Create a Firebase credential with the AccessToken
const facebookCredential = auth.FacebookAuthProvider.credential(userInfo.accessToken);
setGoogleToken(userInfo.accessToken)
// Sign-in the user with the credential
return auth().signInWithCredential(facebookCredential)
.then(() => {
//Once the user creation has happened successfully, we can add the currentUser into firestore
//with the appropriate details.
console.log('current User ####', auth().currentUser);
var name = auth().currentUser.displayName
var mSplit = name.split(' ');
console.log("mSplit ",mSplit);
let mUserDataFacebook = {
user_registration_email: auth().currentUser.email,
user_registration_first_name: mSplit[0],
user_registration_last_name: mSplit[1],
registration_type: 'facebook',
user_registration_role: "Transporter",
token: userInfo.accessToken,
user_image : auth().currentUser.photoURL,
};
console.log('mUserDataFacebook',mUserDataFacebook)
LoginWithGoogleFacebook(mUserDataFacebook) /// Call here your API
firestore().collection('users').doc(auth().currentUser.uid) //// here you can add facebook login details to your firebase authentication.
.set({
fname: mSplit[0],
lname: mSplit[1],
email: auth().currentUser.email,
createdAt: firestore.Timestamp.fromDate(new Date()),
userImg: auth().currentUser.photoURL,
})
//ensure we catch any errors at this stage to advise us if something does go wrong
.catch(error => {
console.log('Something went wrong with added user to firestore: ', error);
})
})
}
Call this function on button press onFacebookButtonPress()
For android need to setup and add facebook id in
android/app/src/main/res/values/strings.xml file
add these two lines.
YOUR_FACEBOOK_ID
fbYOUR_FACEBOOK_ID //Don't remove fb in this string value
/////////////add this code in AndroidMainfest.xml file
//////////This code add in MainApplication.java file
import com.facebook.FacebookSdk;
import com.facebook.appevents.AppEventsLogger;
/////////add code build.gradle file
implementation 'com.facebook.android:facebook-android-sdk:[5,6)'