Jquery Terminal register & login - javascript

I have question, i want user register then login but here it's error anyone can help me ? i saw the documentation . here is link of the documentation jquery termi[jquery terminal]1nal
here is my script:
if (command == 'register') {
term.push(function(command, term) {
term.pause();
$.ajax({
url: "register.php",
type: "post",
data: {data_register : command },
success: function (msg) {
term.echo(yellow('Data Saved Successfully !'));
term.resume();
},
error: function(jqXHR, textStatus, errorThrown) {
term.resume();
}
});
},
{
prompt: " > "
});
} else if (command == 'login'){
login: function(user, password, callback) {
if (user == 'demo' && password == 'secret') {
callback('SECRET TOKEN');
} else {
callback(null);
}
}
}
this line's error :
else if (command == 'login'){
login: function(user, password, callback) {
if (user == 'demo' && password == 'secret') {
callback('SECRET TOKEN');
} else {
callback(null);
}
}
}
Thank you

You have invalid JavaScript you have label and function declaration, which should be put in an object like this:
var x = {
login: function() {
}
};
which should be part of object in second argument which is options object.
.terminal(function(command) {
if (command === 'register') {
}
}, {
login: function(...) {
...
}
});
and for your exact problem on having login command, that login you in, you need to invoke login method like this:
} else if (command == 'login'){
term.login(function(user, password, callback) {
// to get the token you should send user and password to the server
if (user == 'demo' && password == 'secret') {
callback('SECRET TOKEN');
} else {
callback(null);
}
});
} else if (term.token()) {
// here are commands that will only work after user login
// but you need to know that user may add token in developer tools
// so you should use additional check if token is valid by sending token
// to the server, or if you're invoking command on the server then just
// send the token and validate it there
} else {
term.error('invalid command');
}

Related

How to fix "Error: Can't set headers after they are sent" in Express

I have recently been developing a MERN application and I have recently came into the trouble that express is saying that I am setting headers after they are sent.
I am using mongo db and trying to update a user profile.
I have tried to comment out my res.send points to find the issue but I have failed to do so.
Here is my post method for updating the user profile:
app.post("/api/account/update", (req, res) => {
const { body } = req;
// Validating and Checking Email
if (body.email) {
var email = body.email;
email = email.toLowerCase();
email = email.trim();
body.email = email;
User.find(
{
email: body.email
},
(err, previousUsers) => {
if (previousUsers.length > 0) {
return res.send({
success: false,
message:
"Error: There is already another account with that email address"
});
} else {
}
}
);
}
// Validating Names Function
function checkName(name) {
var alphaExp = /^[a-zA-Z]+$/;
if (!name.match(alphaExp)) {
return res.send({
success: false,
message: "Error: Names cannot contain special characters or numbers"
});
}
}
checkName(body.firstName);
checkName(body.lastName);
// Making sure that all fields cannot be empty
if (!body.email && !body.firstName && !body.lastName) {
return res.send({
success: false,
message: "Error: You cannot submit nothing"
});
}
// Getting User ID from the current session
UserSession.findById(body.tokenID, function(err, userData) {
// Finding User ID using the current users session token
if (userData.isDeleted) {
return res.send({
success: false,
message:
"Error: Session token is no longer valid, please login to recieve a new one"
});
}
// Deleting the token ID from the body object as user table entry doesnt store tokens
delete body.tokenID;
// Finding the user profile and updating fields that are present
User.findByIdAndUpdate(userData.userId, body, function(err, userInfo) {
if (!err) {
return res.send({
success: true,
message: "Success: User was updated successfully"
});
}
});
});
});
This is the call that I am doing to the backend of the site:
onUpdateProfile: function(fieldsObj) {
return new Promise(function(resolve, reject) {
// Get Session Token
const obj = getFromStorage("the_main_app");
// Defining what fields are getting updated
fieldsObj.tokenID = obj.token;
// Post request to backend
fetch("/api/account/update", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(fieldsObj)
})
.then(res => {
console.log("Verify Token - Res");
return res.json();
})
.then(json => {
console.log("Verify Token JSON", json);
if (json.success) {
window.location.href = `/manage-account?success=${json.success}`;
} else {
window.location.href = `/manage-account?success=${json.success}`;
}
});
});
}
Here is my error message that I am getting:
Error: Can't set headers after they are sent.
at validateHeader (_http_outgoing.js:491:11)
at ServerResponse.setHeader (_http_outgoing.js:498:3)
at ServerResponse.header (C:\Users\kieran.corkin\Desktop\Projects\Mern Template Final\mern-cra-and-server\server\node_modules\express\lib\response.js:767:10)
at ServerResponse.send (C:\Users\kieran.corkin\Desktop\Projects\Mern Template Final\mern-cra-and-server\server\node_modules\express\lib\response.js:170:12)
at ServerResponse.json (C:\Users\kieran.corkin\Desktop\Projects\Mern Template Final\mern-cra-and-server\server\node_modules\express\lib\response.js:267:15)
at ServerResponse.send (C:\Users\kieran.corkin\Desktop\Projects\Mern Template Final\mern-cra-and-server\server\node_modules\express\lib\response.js:158:21)
at C:\Users\kieran.corkin\Desktop\Projects\Mern Template Final\mern-cra-and-server\server\routes\api\account.js:270:22
at C:\Users\kieran.corkin\Desktop\Projects\Mern Template Final\mern-cra-and-server\server\node_modules\mongoose\lib\model.js:4641:16
at process.nextTick (C:\Users\kieran.corkin\Desktop\Projects\Mern Template Final\mern-cra-and-server\server\node_modules\mongoose\lib\query.js:2624:28)
at _combinedTickCallback (internal/process/next_tick.js:131:7)
at process._tickCallback (internal/process/next_tick.js:180:9)
[nodemon] app crashed - waiting for file changes before starting...
Can anyone help me with this?
EDIT
I have changed my code, this seems to now work however I feel like its a little messy when put together. Any refactoring tips?
Code:
app.post("/api/account/update", (req, res) => {
// Preform checks on data that is passed through
const { body } = req;
var messages = {
ExistedUser:
"Error: There is already another account with that email address",
NameFormat: "Error: Names cannot contain special characters or numbers",
BlankInputs: "Error: You cannot submit nothing",
accountLoggedOut:
"Error: Session token is no longer valid, please login to recieve a new one",
successfullyUpdated: "Success: User was updated successfully"
};
var usersFound;
if (body.email) {
var email = body.email;
email = email.toLowerCase();
email = email.trim();
body.email = email;
User.find(
{
email: body.email
},
(err, UserCount) => {
usersFound = UserCount;
}
);
}
function capitalize(text) {
return text.replace(/\b\w/g, function(m) {
return m.toUpperCase();
});
}
if (body.firstName) {
body.firstName = capitalize(body.firstName);
}
if (body.lastName) {
body.lastName = capitalize(body.lastName);
}
//Making sure that all fields cannot be empty
if (!body.email && !body.firstName && !body.lastName) {
return res.send({
success: false,
message: messages.BlankInputs
});
}
// Getting User ID from the current session
UserSession.findById(body.tokenID, function(err, userData) {
// Finding User ID using the current users session token
if (userData.isDeleted) {
return res.end({
success: false,
message: messages.accountLoggedOut
});
}
if (userData) {
// Deleting the token ID from the body object as user table entry doesnt store tokens
delete body.tokenID;
// Finding the user profile and updating fields that are present
User.findByIdAndUpdate(userData.userId, body, function(err, userInfo) {
if (userInfo) {
if (!usersFound.length > 0) {
return res.send({
success: true,
message: messages.successfullyUpdated
});
} else {
return res.send({
success: false,
message: messages.ExistedUser
});
}
}
});
}
});
});
You're calling res.send() twice. res.send() ends the process. You ought to refactor such that you call res.write() and only call res.send() when you're done.
This StackOverflow link describes the difference in more detail. What is the difference between res.send and res.write in express?
I believe this is happening, as you're trying to send a response after the first / initial response has already been sent to the browser. For example:
checkName(body.firstName);
checkName(body.lastName);
Running this function twice is going to try and yield 2 different "response" messages.
The product of a single route, should ultimately be a single response.
Thanks for all your help on this issue.
Here is my final code that allowed it to work.
I have also tried to "refactor" it too. Let me know if you'd do something else.
app.post("/api/account/update", (req, res) => {
const { body } = req;
console.log(body, "Logged body");
// Defining objects to be used at the end of request
var updateUserInfo = {
userInfo: {},
sessionToken: body.tokenID
};
var hasErrors = {
errors: {}
};
// Checking that there is at least one value to update
if (!body.email && !body.firstName && !body.lastName) {
var blankError = {
success: false,
message: "Error: You cannot change your details to nothing"
};
hasErrors.errors = { ...hasErrors.errors, ...blankError };
} else {
console.log("Normal Body", body);
clean(body);
console.log("Cleaned Body", body);
updateUserInfo.userInfo = body;
delete updateUserInfo.userInfo.tokenID;
}
// Function to check if object is empty
function isEmpty(obj) {
if (Object.keys(obj).length === 0) {
return true;
} else {
return false;
}
}
// Function to remove objects from body if blank
function clean(obj) {
for (var propName in obj) {
if (obj[propName] === "" || obj[propName] === null) {
delete obj[propName];
}
}
}
// Checking and Formatting Names Given
function capitalize(text) {
return text.replace(/\b\w/g, function(m) {
return m.toUpperCase();
});
}
if (body.firstName) {
body.firstName = capitalize(body.firstName);
}
if (body.lastName) {
body.lastName = capitalize(body.lastName);
}
// Checking and formatting email
if (body.email) {
body.email = body.email.toLowerCase();
body.email = body.email.trim();
// Checking for email in database
User.find({ email: body.email }, (err, EmailsFound) => {
if (EmailsFound.length > 0) {
var EmailsFoundErr = {
success: false,
message: "There is already an account with that email address"
};
hasErrors.errors = { ...hasErrors.errors, ...EmailsFoundErr };
}
});
}
// Getting User Session Token
UserSession.findById(updateUserInfo.sessionToken, function(err, userData) {
// Finding User ID using the current users session token
if (userData.isDeleted) {
var userDeletedError = {
success: false,
message:
"Your account is currently logged out, you must login to change account details"
};
hasErrors.errors = { ...hasErrors.errors, ...userDeletedError };
} else {
// Finding the user profile and updating fields that are present
User.findByIdAndUpdate(
userData.userId,
updateUserInfo.userInfo,
function(err, userInfo) {
// userInfo varable contains user db entry
if (err) {
var updateUserError = {
success: false,
message: "Error: Server Error"
};
hasErrors.errors = {
...hasErrors.errors,
...updateUserError
};
}
if (isEmpty(hasErrors.errors)) {
res.send({
success: true,
message: "Success: You have updated your profile!"
});
} else {
res.send({
success: false,
message: hasErrors.errors
});
}
}
);
}
});
});

How to delay a function until another one executes in JavaScript?

I am trying to write a simple registration function. I keep getting tripped up while trying to verify whether or not a user email already exists. I think that my issue has something to do with asynchronicity. My intent is to hide the registration div and show the profile div once a 201 resonse is received from the server. However, I believe my alert keeps coming up before the response is received. How can I get the code to freeze until after my handlePost is finished? I have tried it in the following ways:
1
registerButton.onclick = function(){
var encodedBody = getRegistrationData();
//if encodedbody then handlepost and show profile etc
if (encodedBody) {
var response = handlePost(encodedBody, 'user');
if (response == '201') {
hideRegistration();
showProfile();
showLoginNav();
showLogin();
// clearFields() need to create this
} else {
alert("Invalid password or email")
console.log('hmm')
}
} else {
alert("Invalid password or email")
}
};
2
registerButton.onclick = function() {
var a = function(callBack){
var encodedBody = getRegistrationData()
var response = handlePost(encodedBody, 'user')
callBack(response)
}
var b = function(response) {
if (response == '201') {
hideRegistration();
showProfile();
showLoginNav();
showLogin();
} else {
alert("Invalid password or email")
}
}
a(b)
}
3
registerButton.onclick = function() {
var encodedBody = getRegistrationData()
if (encodedBody) {
handlePost(encodedBody, 'user').then(function(response) {
if (response == '201') {
hideRegistration();
showProfile();
showLoginNav();
showLogin();
} else {
alert("Invalid password or email")
}
})
} else {
alert("Invalid password or email")
}
};
The following functions are used within the above:
function getRegistrationData() {
var newUserEmail = document.querySelector("#newUserEmail");
var newUserPassword = document.querySelector("#newUserPassword");
var newUserPasswordVerify = document.querySelector('#newUserPasswordVerify');
flag = []
//verify passwords match
if (newUserPassword.value != newUserPasswordVerify.value) {
flag = false
return flag
} else {
flag = true
}
//if user does not exist and passwords match return encoded body
if (flag == true) {
var encodedBody = 'email='+encodeURIComponent(newUserEmail.value)+'&'+'encryptedPassword='+encodeURIComponent(newUserPassword.value)
return encodedBody
}
};
function handlePost(encodedBody, flag) {
if (flag =='user') {
fetch('http://localhost:8080/users', {
body: encodedBody,
method: 'POST',
headers: {
'Content-Type': 'text/plain',
}
})
.then(function(response) {
console.log(response.status)
return response.status
// clearRegistrationFields();
// function to get user profile data
})
}
};
Thanks in advance
Chris
Your handlPost is asynchronous, so you should return a promise if you want to wait for the results:
function handlePost(encodedBody, flag) {
return new Promise(function(resolve, reject) {
if (flag =='user') {
fetch('http://localhost:8080/users', {
body: encodedBody,
method: 'POST',
headers: {
'Content-Type': 'text/plain',
}
})
.then(function(response) {
console.log(response.status)
resolve(response.status)
// clearRegistrationFields();
// function to get user profile data
})
}
});
}
Now your snippet 3 will work, and the response object will be the 'response.status' resolved in the handlePost promise.
Note: you should also handle the promise failure. I'll leave you to work that out.

Post a message as a page using JAVASCRIPT

I had successfully post a message to my own Facebook page but it was posted as a visitor(I want post as a page). I'm not sure where i missed and also i confused to the page access token.
$('#btn-fb').click(function () {
getPageAccess(function (page_id){
postToFB(page_id,'sien');
});
//postStatus();
});
function getPageAccess(callback) {
FB.login(function (response) {
// handle the response
if (response.authResponse) {
FB.api('/' + page_id + '', {fields: 'access_token'}, function (response) {
if (response && !response.error) {
callback(page_id);
}
});
}
}, {scope: 'manage_pages,publish_pages'});
}
function postToFB(page_id, message) {
FB.api(
"/" + page_id + "/feed",
"post",
{
"message": message
},
function (response) {
if (response && !response.error) {
/* handle the result */
}
else {
}
}
);
}
You need to use a Page Token to post as Page, right now you are using a User Token. You are asking for the Page Token (fields parameter), but you never use it and you donĀ“t add it as callback parameter:
{
'message': message,
'access_token': pageToken
}

Accounts.sendVerificationEmail Issue in Meteor

I Need to send VerificationEmail using Meteor.I did the code but It didn't send VerificationEmail and also got error on server side.Error is : Can't find user.I didn't have any idea about this.so Please see the below code & suggest me how to do.
JS Code:
if (Meteor.isClient)
{
Template.main.events
({
'submit #register-form' : function (e,t)
{
console.log("You pressed the button Register ");
e.preventDefault();
var username = t.find('#username').value
, name = t.find('#name').value
, email = t.find('#email1').value
, password = t.find('#pwd1').value;
console.log("password="+password);
var isValidPassword = function(val, field)
{
if (val.length >= 6) {
return true;
} else {
Session.set('displayMessage', 'Error & Too short.')
return false;
}
}
if (isValidPassword(password))
{
console.log(" *** isValidPassword *** ");
Accounts.createUser({email: email, password : password,username : username }, function(err)
{
if (err)
{
console.log(err);
}
else
{
console.log("Register Successfully");
Meteor.call('sendEmail',
'*****#gmail.com',
'****.com',
'Hello from Meteor!',
'This is a test of Email.send.');
}
});
}
else
{
console.log("*** Error ***");
}
}
});
}
if (Meteor.isServer)
{
Meteor.startup(function ()
{
// code to run on server at startup
});
//Meteor methods
Meteor.methods
({
sendEmail: function (to, from, subject, text)
{
Accounts.config({sendVerificationEmail: true, forbidClientAccountCreation: false});
process.env.MAIL_URL = 'smtp://****#gmail.com:*pwd*#smtp.gmail.com:587';
this.unblock();
Accounts.sendVerificationEmail(to);
}
});
}
Did you send the email to an email address? When you use to in Accounts.sendVerificationEmail(to);
it must be the _id of the user you want to send the confirmation email to, not their email address.

How can I tell when a JavaScript asynchronous function ends?

I am trying to determine through some flag when this asynchronous function ends.
This is how I call my function:
// Calling the function in a loop
for (var i=0,l=myIds.length; i<l; ++i) {
install(pageId, myIds[i], apps_num[''+myIds[i]], <?php echo $this->comid ?>, '<?php echo $this->site_url; ?>');
}
And this is my function:
install: function(pageId, appId, app_num, com_id, siteurl) {
FB.getLoginStatus(function(response) {
// Checking if connected to Facebook
if (response.status === 'connected') {
var uid = response.authResponse.userID;
console.log(response.authResponse);
var userAccessToken = response.authResponse.accessToken;
// Get page access token
FB.api('/'+pageId+'?fields=access_token='+userAccessToken, function(response) {
var pageAccessToken = response.access_token;
// Get information if user got this application
FB.api('/'+pageId+'/tabs/'+appId+'?access_token='+pageAccessToken,
function(data) {
if (data.data.length < 1) {
console.log("Not installed, Installing...");
// Install the application
var params = {};
params['app_id'] = appId;
FB.api('/'+pageId+'/tabs?access_token='+pageAccessToken, 'post', params, function(response) {
if (!response || response.error) {
console.log("Error Installing!");
}
else {
console.log("Installed :)");
}
});
}
else {
console.log("Already installed.");
}
});
});
}
else
if (response.status === 'not_authorized') {
console.log("the user is logged in to Facebook, but not connected to the app.");
}
else {
console.log("the user isn't even logged in to Facebook.");
}
});
}
How can I solve this issue? I tried to use static variables, but I wasn't able to call them inside the asynchronous function..
The usual thing is to have any code that needs to know the outcome of an asynchronous call pass a function reference into the call, which the function then calls when it's done (a "callback").
So in your case, you'd add a callback parameter to your install function:
install: function(pageId, appId, app_num, com_id, siteurl, callback)
// here ------------^
...and then call it when appropriate from the callbacks you're passing into FB.getLoginStatus and/or FB.api, e.g. something like this:
install: function(pageId, appId, app_num, com_id, siteurl, callback) {
FB.getLoginStatus(function(response) {
// checking if connected to facebook
if (response.status === 'connected') {
var uid = response.authResponse.userID;
console.log(response.authResponse);
var userAccessToken = response.authResponse.accessToken;
// get page access token
FB.api('/'+pageId+'?fields=access_token='+userAccessToken, function(response) {
var pageAccessToken = response.access_token;
// get information if user got this app
FB.api('/'+pageId+'/tabs/'+appId+'?access_token='+pageAccessToken,
function(data) {
if (data.data.length < 1) {
console.log("Not installed, Installing...");
// install the app
var params = {};
params['app_id'] = appId;
FB.api('/'+pageId+'/tabs?access_token='+pageAccessToken, 'post', params, function(response) {
if (!response || response.error) {
callback(false, "Error installing");
console.log("Error Installing!");
} else {
callback(true, "Installed");
console.log("Installed :)");
}
});
}
else {
callback(false, "Already installed.");
console.log("Already installed.");
}
});
});
} else if (response.status === 'not_authorized') {
callback(false, "Logged in but not connected.");
console.log("the user is logged in to Facebook, but not connected to the app.");
} else {
callback(false, "Not logged in.");
console.log("the user isn't even logged in to Facebook.");
}
});
}
There I've given the callback function two arguments: A boolean saying whether the installation was performed, and a status message.
First, you add an extra param to your function, that will receive a function object
install: function(pageId, appId, app_num, com_id, siteurl, callbackFunction) {
Then, inside the function install, after
console.log("Installed :)");
you add
callbackFunction();
This way, when you call the install function:
for (var i=0,l=myIds.length; i<l; ++i) {
install(pageId, myIds[i], apps_num[''+myIds[i]], <?php echo $this->comid ?>, '<?php echo $this->site_url; ?>', function(){
//do whatever you want;
});
}
jQuery does it by letting the user determine how a function should react when a function is finished. This means, putting a function as a parameter. This is called a callback
function install(pageId, appId, app_num, com_id, siteurl, pCallback) {
//Doing cool stuff.
//OK, I am finished.
pCallback(a, b, c)
}
function lefinish(a, b, c) {
alert(b);
}
// Calling install
install(pageId, appId, app_num, com_id, siteurl, lefinish)
As an added bonus, if you really need to know exactly what happened, you can put multiple functions in it, depending on the success of your first function
function install(pageId, appId, app_num, com_id, siteurl, pCallback) {
//Doing awesome stuff
if (response.status === 'connected') {
if (typeof(pCallback.onConnect) == 'function') {
pCallback.onConnect(a,b,c);
}
}
else
if (response.status === 'not_authorized') {
if (typeof(pCallback.onNoAuth) == 'function') {
pCallback.onNoAuth(a,b,c);
}
}
else {
if (typeof(pCallback.onNotLoggedIn) == 'function') {
pCallback.onNotLoggedIn(a,b,c);
}
}
}
function lefinish(a, b, c) {
alert(b);
}
// Calling install
install(pageId, appId, app_num, com_id, siteurl, {
'onConnect': function(a,b,c) {}, //Anonymous function
'onNoAuth': lefinish //A predefined function
// does not produce an error if onNotLoggedIn is not defined because of typeof().
})

Categories

Resources