How can I solve alert reference errors in Javascript? - javascript

I got this error
"type error alert is not a function ".
So I created an alert function but got this error
reference error alert is not defined
when I try to execute its function
function alertMessage(messageObject) {
alert(messageObject);
return true;
}
app.post("/login", function(req, res) {
const username = req.body.username;
const password = req.body.password
User.findOne({
email: username
},
function(err, foundUser) {
if (foundUser) {
if (foundUser.password !== password) {
alertMessage("Password Is Incorrect");
} else {
if (foundUser) {
if (foundUser.password === password) {
res.render("compose");
}
}
};
};
});
});

From app.post, I'm guessing this is code running in Node.js via Express.js. Node.js doesn't have an alert function, that's something browsers provide. In app.post you're replying to a response from the browser. If there's a login error, you need to send a reply to the post saying there's a login error. It looks like your code is expecting to present a page in response to the post (rather than being called via ajax), so you'd render a page saying the login failed. (You might consider using ajax instead, so the page doesn't have to refresh in this case, but that's beside the point.)

Related

Adding Email Authentication to a Login Service that uses React and Firebase

I currently have a file for authentication called AuthContext.js and a seperate file called Login.js for my login page. Firebase is only imported into the AuthContext file and it currently works, the method appears as follows
function signup(email, password) {
return auth.createUserWithEmailAndPassword(email, password);
}
And the method is called in the Login file inside of an async function.
async function handleSubmit(e) {
e.preventDefault();
if (passwordRef.current.value !== passwordConfirmRef.current.value) {
return setError("Passwords do not match");
}
try {
setError("");
setLoading(true);
await signup(emailRef.current.value, passwordRef.current.value);
navigate("/");
} catch (err) {
setError("Failed to create an account");
}
setLoading(false);
}
I am now attempting to integrate email authentication into the function. I would like to get it to where, if an account remains unverified for a elongated duration then it will delete the account, but I think that Is likely in the Firebase settings.
I found this article on geeksforgeeks that suggested calling the method in the following manner:
const signup = ()=>{
   auth.createUserWithEmailAndPassword(email , password)
   .then((userCredential)=>{
       // send verification mail.
     userCredential.user.sendEmailVerification();
     auth.signOut();
     alert("Email sent");
   })
   .catch(alert);
}
However, when I attempted to return this function in the form
function signup(email, password) {
return auth.createUserWithEmailAndPassword(email, password).then(
(userCredentials) => {
userCredentials.user.sendEmailVerification();
auth.signOut();
auth.alert("Please verify your email address before logging in.");
}
);
}
It does not work properly, and I get error messages every time I try to sign up a new account. How do I properly implement this to where the promise returns properly and displays the correct message? Is there a way for me to link them to the /login page with an alert already on it that says "Please verify your email address before logging in."? Thanks in advance for any help!

feathersjs: How do I pass un-opinionated errors back to client

Seems like error messages are wrapped in text. Say in a model validation I just want to send "exists" to the client if a record already exists.
One the server maybe I do something like:
validate: {
isEmail: true,
isUnique: function (email, done) {
console.log("checking to see if %s exists", email);
user.findOne({ where: { email: email }})
.then(function (user) {
done(new Error("exists"));
},function(err) {
console.error(err);
done(new Error('ERROR: see server log for details'));
}
);
}
}
On the client maybe I do:
feathers.service('users').create({
email: email,
password: password
})
.then(function() {
console.log("created");
})
.catch(function(error){
console.error('Error Creating User!');
console.log(error);
});
The error printed to console is:
"Error: Validation error: exists"
How to I just send the word "exists" without the extra text? Really I'd like to send back a custom object, but I can't seem to find any examples of doing this. The closest I've seen is this: https://docs.feathersjs.com/middleware/error-handling.html#featherserror-api
But I haven't figured out how to make something like this work in the validator.
Feathers does not change any error messages so the Validation error: prefix is probably added by Mongoose.
If you want to change the message or send an entirely new error object, as of feathers-hooks v1.6.0 you can use error hooks:
const errors = require('feathers-errors');
app.service('myservice').hooks({
error(hook) {
const { error } = hook;
if(error.message.indexOf('Validation error:') !== -1) {
hook.error = new errors.BadRequest('Something is wrong');
}
}
});
You can read more about error and application hooks here

Parse Server / JS SDK, error 206 when saving a user object

I am having trouble using the Parse Server JS SDK to edit and save a user.
I am signing in, logging in and retrieving the user just fine, I can call without exception user.set and add/edit any field I want, but when I try to save, even when using the masterKey, I get Error 206: Can t modify user <id>.
I also have tried to use save to direcly set the fields, same result.
A interesting thing is that in the DB, the User's Schema get updated with the new fields and types.
Here is my update function:
function login(user, callback) {
let username = user.email,
password = user.password;
Parse.User.logIn(username, password).then(
(user) => {
if(!user) {
callback('No user found');
} else {
callback(null, user);
}
},
(error) => {
callback(error.message, null);
}
);
}
function update(user, callback) {
login(user, (error, user) => {
if(error) {
callback('Can t find user');
} else {
console.log('save');
console.log('Session token: ' + user.getSessionToken());
console.log('Master key: ' + Parse.masterKey);
user.set('user', 'set');
user.save({key: 'test'}, {useMasterKey: true}).then(
(test) => {
console.log('OK - ' + test);
callback();
}, (err) => {
console.log('ERR - ' + require('util').inspect(err));
callback(error.message);
}
);
}
});
}
And a exemple of the error:
update
save
Session token: r:c29b35a48d144f146838638f6cbed091
Master key: <my master key>
ERR- ParseError { code: 206, message: 'cannot modify user NPubttVAYv' }
How can I save correctly my edited user?
I had the exact same problem when using Parse Server with migrated data from an existing app.
The app was created before March 2015 when the new Enhanced Sessions was introduced. The app was still using legacy session tokens and the migration to the new revocable sessions system was never made. Parse Server requires revocable sessions tokens and will fail when encountering legacy session tokens.
In the app settings panel, the Require revocable sessions setting was not enabled before the migration and users sessions were not migrated to the new system when switching to Parse Server. The result when trying to edit a user was a 400 Bad Request with the message cannot modify user xxxxx (Code: 206).
To fix the issue, I followed the Session Migration Tutorial provided by Parse which explain how to upgrade from legacy session tokens to revocable sessions. Multiple methods are described depending on your needs like enableRevocableSession() to enable these sessions on a mobile app, if you're only having a web app, you can enforce that any API requests with a legacy session token to return an invalid session token error, etc.
You should also check if you're handling invalid session token error correctly during the migration to prompt the user to login again and therefore obtain a new session token.
I had the same error and neither useMasterKey nor sessionToken worked for me either. :(
Here's my code:
console.log("### attempt 1 sessionToken: " + request.user.getSessionToken());
var p1 = plan.save();
var p2 = request.user.save(null, {sessionToken: request.user.getSessionToken()});
return Parse.Promise.when([p1, p2]).then(function(savedPlan) {
...
}
I see the matching session token in log output:
2016-08-21T00:19:03.318662+00:00 app[web.1]: ### attempt 1 sessionToken: r:506deaeecf8a0299c9a4678ccac47126
my user object has the correct ACL values:
"ACL":{"*":{"read":true},"PC7AuAVDLY":{"read":true,"write":true}}
I also see a bunch of beforeSave and afterSave logs with user being "undefined". not sure whether that's related.
beforeSave triggered for _User for user undefined:
I'm running latest parser-server version 2.2.18 on Heroku (tried it on AWS and results are the same)
function login(logInfo, callback) {
let username = logInfo.email,
password = logInfo.password;
Parse.User.logIn(username, password).then(
(user) => {
if(!user) {
callback('No user found');
} else {
callback(null, user);
}
},
(error) => {
callback(error.message, null);
}
);
}
function update(userInfo, data, callback) {
login(userInfo, (error, user) => {
if(error) {
callback('Can t find user');
} else {
getUpdatedData(user.get('data'), data, (error, updateData) => {
if(error) {
callback(error);
} else {
user.save({data: updateData}, /*{useMasterKey: true}*/ {sessionToken: user.get("sessionToken")}).then(
(test) => {
callback();
}, (err) => {
callback(error.message);
}
);
}
});
}
});
}
For some reason, retrying to use sessionToken worked.
This is not how asynchronous functions work in JavaScript. When createUser returns, the user has not yet been created. Calling user.save kicks off the save process, but it isn't finished until the success or error callback has been executed. You should have createUser take another callback as an argument, and call it from the user.save success callback.
Also, you can't create a user with save. You need to use Parse.User.signUp.
The function returns long before success or error is called.

Getting [object, Object] instead of whole user data. What does that mean?

I am getting the [object,Object ] in my server terminal instead of whole user data . I do not know what does that mean... I think I did all perfectly but still unable to get the whole data. I specified of sailjs server.
How to get whole user data instead of [object,Object]?
module.exports = {
/**
* Check the provided email address and password, and if they
* match a real user in the database, sign in to Medool.
*/
login: function (req, res) {
// Try to look up user using the provided email address
User.findOne({
email: req.param('email')
}, function foundUser(err, user) {
if (err)
return res.negotiate(err);
if (!user)
return res.notFound();
// Compare password attempt from the form params to the encrypted password
// from the database (`user.password`)
require('machinepack-passwords').checkPassword({
passwordAttempt: req.param('password'),
encryptedPassword: user.encryptedPassword
}).exec({
error: function (err) {
return res.negotiate(err);
},
/*
If the password from the form params doesn't checkout w/ the encrypted
password from the database...
*/
incorrect: function () {
return res.notFound();
},
success: function () {
// Store user id in the user session
console.log("User form the login check" +user)
req.session.me = user.helpsterId;
console.log(req.session.me);
// All done- let the client know that everything worked.
return res.ok();
}
});
});
}
};
Output when lifted server is [object, Object]in console
Try it,
console.log(user);
console.log(JSON.stringify(user));
console.log("User form the login check" +user);
and write the result for us.

How to validate if its a login page using webdriverio

I am using Javascript, webdriverio (v2.1.2) to perform some data extraction from an internal site. The internal site is SSO enabled, so if I have been authenticated on another application, I need not login for this application (common in enterprise intranet applications).
I plan to achieve the below,
Create a client with required capabilities
Pass the required URL
For fun : Print the title of the page
Check if an element exist on the page. If yes, then it's a login page. If not, then it's not login page
login = function (username, password) {
if (!browserClientUtil) {
throw "Unable to load browserClientUtil.js";
}
browserClientUtil
.createClient()
.url(_Url)
.title(function (err, res) {
console.log('Title is: ' + res.value);
}) .isExisting('input#login_button.login_button', function (err, isExisting) {
browserClientUtil.getCurrentClient()
.setValue('input#USER.input', username)
.setValue('input#PASSWORD.input', password)
//.saveScreenshot('ultimatixLoginDetails.png')
.click('input#login_button.login_button')
.pause(100);
handlePostLogin();
});
};
Is this the best way to do? I tried to separate the code for verifying login page in a separate function, it didn't work as everything in webdriver happens as part of callback and I am not sure if I am doing it in a right way.
How do I return from a callback, that will in-turn be the final value returned by that function?
login = function (username, password) {
if (!browserClientUtil) {
throw "Unable to load browserClientUtil.js";
}
browserClientUtil
.createClient()
.url(_Url)
.title(function (err, res) {
console.log('Title is: ' + res.value);
});
if(isThisLoginPage()){
browserClientUtil.getCurrentClient()
.setValue('input#USER.input', username)
.setValue('input#PASSWORD.input', password)
//.saveScreenshot('ultimatixLoginDetails.png')
.click('input#login_button.login_button')
.pause(100);
handlePostLogin();
}
};
isThisLoginPage = function() {
var client = browserClientUtil.getCurrentClient();
if(!client) {
throw "Unable to get reference for current client, hence cannot validate if this is login page.";
}
client.isExisting('input#login_button.login_button', function (err, isExisting) {
if(isExisting) {
return true;
}
});
return false;
};
You can create your own workflow by creating own commands that wrap other ones. For example you can make an own command to login:
browserClientUtil.addCommand("login", function(url, user, pw, cb) {
this.url(url)
.setValue('#username', user)
.setValue('#password', pw)
.submitForm('#loginForm')
.call(cb);
});
This allows you to hide "complex" asynchronous webdriver actions behind a simple function. It is easy to create an powerful toolchain. At the end your test script looks like:
browserClientUtil
.login("http://example.com/login", "john.doe", "testpass")
.getTitle(function(err, title) {
console.log(title);
})
// ...
Cheers

Categories