Facebook API Nodejs - node.js

I'm trying post a message as admin of a facebook page, but my code keeps posting as my personal account to the "wall" of the page, not as the page itself.
When authorizing my application I ask for the right permissionscopes, and accept them. Although, when I check my permissions with /{USER-ID}/permissions, it says that I've denied the application to manage my pages. Any ideas why?
Here's my code for posting:
var parameters = {};
parameters.message = "Hello world, this is dog.";
parameters.access_token = req.session.access_token;
FB.api('{PAGE-ID}/feed', 'post', parameters, function (result) {
if (!result) {
return res.send(500, 'error');
} else if (result.error) {
if (result.error.type == 'OAuthException') {
result.redirectUri = FB.getLoginUrl({ scope: 'publish_actions,manage_pages,publish_pages', state: encodeURIComponent(JSON.stringify(parameters)) });
}
console.log(result);
return res.send(500, result);
}
res.send(result);
});
And yes, of course I use my page id instead of the placeholder in my code above.
*Update: It seems like the permissions aren't even asked for when authorizing the application. I added the email scope to the list and it appears when I re-authorize the application.
Could this have anything to do with my application not beeing approved?
"Submit for Login Review
Some of the permissions below have not been approved for use by Facebook.
Submit for review now or read more."

Related

Protect the API from being displayed on the browser and programs such as postman

I want to protect the api of the current user, I am starting to learn Node.js but I know that I can get the request information so I wrote this code in which I try to prevent sensitive data from appearing if someone takes the API link and puts it on the browser or postman.
My question: is this method correct to use?.
(sorry for the poor english)
module.exports.current_user_get = (req, res) => {
// If the API is opened by browser or postman
if (req.rawHeaders.indexOf("User-Agent") > -1) {
return res.json({ msg: "Not allowed" });
}
// return user data
};

How to choose user or page in facebook API call

I want to be able to post on a Facebook page using the graph API but I am unable to as it gives me this error.
{ message: '(#200) If posting to a group, requires app being
installed in the group, and \\n' +
' either publish_to_groups permission with user token, or both pages_read_engagement \\n' +
' and pages_manage_posts permission with page token; If posting to a page, \\n' +
' requires both pages_read_engagement and pages_manage_posts as an admin with \\n' +
' sufficient administrative permission',
type: 'OAuthException',
code: 200,
fbtrace_id: 'ABHLK9ZxMynsgBhcPI3Q0DL'
}
I am using the following API call for my request
const apiurl = `/${pagename}/feed`;
FB.api(apiurl, 'post', { message: req.body.fpost }, (response) => {
if (!response || response.error) {
console.log(!response ? 'error occurred' : response.error);
return;
}
res.render('facebook');
});
Can anyone help with what I am missing and how can I choose between use and page like we can choose in the Graph API Explorer as seen below. I have my page PrudentSays as the under User or Page. How can I choose the same with the API request? I have chosen all the proper permissions for posting as mentioned in the error.
Graph API Explorer Example

Stripe login link URL does not work

I am following the project at stripe-connect-rocketrides, and running it on my own NodeJS server to try to learn how to integrate Stripe payments. I've setup pretty much everything,
but am now running into an issue where the login link doesn't work.
To start, I have a Stripe Account ID that I have created for the user who logged in and stored in the database. Now, when I try to log the user in to the Stripe Dashboard, I know that I need to use the Create Login Link API to fetch a URL from Stripe that I can redirect users to. The URL I get is: https://connect.stripe.com/express/somehash
The problem is, when I redirect users to https://connect.stripe.com/express/somehash, this is the response I get:
{
"error": {
"code": "unexpected_api_error",
"message": "An unexpected error occurred",
"type": "api_error"
}
}
This is code in the project that redirects the users to that page:
router.get('/transfers', pilotRequired, async (req, res) => {
const pilot = req.user;
// Make sure the logged-in pilot had completed the Stripe onboarding.
if (!pilot.stripeAccountId) {
return res.redirect('/pilots/signup');
}
try {
// Generate a unique login link for the associated Stripe account.
const loginLink = await
stripe.accounts.createLoginLink(pilot.stripeAccountId);
return res.redirect(loginLink.url);
} catch (err) {
console.log('Failed to create a Stripe login link.');
return res.redirect('/pilots/signup');
}
});
I wonder if this is because the URL expired. But I always get the API error from Stripe as soon as I receive the URL. Any help would be greatly appreciated

Cloud Functions for Firebase - action on email verified

Im trying to create a Cloud Function trigger that will execute after email has been verified.
In the Cloud Functions samples I could only find examples on triggers for onCreate and onDelete.
Within the documentation I found something about creating custom action handlers but I don't actually want to replace the standard email verification dialog they have by default, I just want to change the property of a "user" after the email is verified.
Does anyone have any experience with this, and is this even possible? Or is my only option to create my custom verification view/dialog webpage?
I faced this problem and took me a long time to figure it out how to solve so I hope this could help anyone that could get stuck into this too:
1 -> I created a function that was triggered with onCreate() for a new user
exports.sendConfirmationEmail = functions.auth.user()
.onCreate((user) => {
const actionCodeSettings = {
url: 'https://appNextURL.com/',
handleCodeInApp: false//ensure that the link will open into browser
};
return admin.auth().generateEmailVerificationLink(user.email, actionCodeSettings)
.then(async (link) => {
await db.collection('users').doc(user.uid).set({
verificationLink: link,
emailVerified: false
}, {merge: true});
return sendCustomVerificationEmail(user.email, user.displayName, link);
})
.catch((err) => {
console.error("Error:", err);
return Promise.reject(err);
});
});
The generateEmailVErificationLink() will generate the link based on the link we will save on step 3.
The function sendCustomVerificationEmail() is just an internal function that overcomes the standard email firebase send
2 -> Then I created a function that will receive a manual http trigger with the data that would be generated automatically by firebase when sending an automatic email
exports.verifyEmail = functions.https.onRequest((req, res) => {
const {mode, oobCode, apiKey, continueUrl, lang} = req.query;
const link = "https://us-central1-projectId.cloudfunctions.net/verifyEmail/?mode=" + encodeURIComponent(mode) + "&oobCode=" + encodeURIComponent(oobCode) + "&apiKey=" + encodeURIComponent(apiKey) + "&continueUrl=" + encodeURIComponent(continueUrl) + "&lang=" + encodeURIComponent(lang);
return db.collection("users")
.where("verificationLink", "==", link)
.get()
.then(function (querySnapshot) {
querySnapshot.forEach(function (user) {
const userData: UserData = user.data();
console.log("email verified: ", userData.userId);
return admin.auth().updateUser(userData.userId, {
emailVerified: true
}).then(function (userRecord) {
return db.collection('users').doc(userData.userId).set({emailVerified: true}, {merge: true});
});
});
return res.sendStatus(200).end();
}).catch(function (err) {
console.log("error:", err);
return res.sendStatus(403).end();
});
});
As I saved the link in the onCreate() I can now query that link to get who is the user that I am authenticating
3 -> the third step is to change the link in to Firebase Authentication template to the link generated into the 2nd step:
Navigate to Authentication>Templates:
Click on edit icon> Click on customize action URL:
Navigation
Paste the link generated into the step 2 and save:
Save link
Now every link generated automatically will go trought that function you created on step 2 and you will be able to handle the actions you want to happen.
I hope I could be clear.
you could still check for the verification status (at least) on Android with interface UserInfo method isEmailVerified(); eg. in order to send another verification email upon successful login, in case the current user has not yet verified the email address - and show the login screen again. one could as well HTTP trigger a cloud function or update values in the Firebase directly, through the client library. this might also apply to other platform clients, where one can check for the verification status.
this would not be exactly the event when the email just had been verified, but upon each single login attempt one knows the verification status and this value might be merely relevant on the client-side.
Create a publish button so your users trigger your cloud function
Instead of firing the cloud function immediately upon auth.emailVerified, I'm giving my users a 'Publish Profile' button which fires an http cloud function (passing in user.uid). This function looks up the user auth using the passed in user.uid
if user.uid && auth.emailVerified
write auth.emailVerified to each user.post
By default, post document "post.emailVerified" fields start out false, and cannot be written to except via adminFirestore in a cloud function.

Appcelerator ACS.Users.login API Getting error code 400 with message: 'Invalid request sent.'

I am trying to store some data on Custom Object of Appcelerator ACS. So there will be a service to do that. Each time it require authentication to create a new object
But I am sometime getting below error while login with ACS. But it not occuring always. It only if I call service multiple time.
error i am getting is:
{
success: false,
error: true,
code: 400,
message: "Invalid request sent."
}
Code used to login :
ACS.Users.login(userData, function(data){
if(data.success) {
console.log("----------Successful to login.---------------");
console.log(data);
res.send(data);
res.end();
} else {
console.log("------------------login failed---------------");
console.log(data);
res.send(data);
res.end();
}
},req, res);
Can some one can help me to understand how to re-use session id from node.ACS web service app (Not web app)?
How I can keep session / check session validity before pushing something to custom object? Has anyone faced similar issue?
Thanks
Peter
Since you are passing in the req and res parameters into ACS.Users.login, the session is saved in the _session_id cookie:
http://docs.appcelerator.com/cloud/latest/#!/guide/node_acs
When you make subsequent calls to ACS, you pass in the req and res parameters and it will check for this session token.
A session can become invalid after timeout or logout. To check whether a session is still good, one way is to check against this REST API endpoint (GET):
https://api.cloud.appcelerator.com/v1/users/show/me.json?key=(YOUR ACS KEY)&_session_id=(SESSION ID OF THE USER)
Also, for some reason acs-node v0.9.3 appears to be returning the same session ID, even for different users. Some side-effects I've seen include (1) the wrong user attempting to make a change to an object, and (2) objects created by one user are actually owned by the last person who logged in. Making sure acs-node is at v0.9.2 avoids this issue.
Now that node-acs has been shut down, everyone is obliged to move to the new arrowdb node sdk.
To solve the issue above about not authenticating the User, before every ArrowDB call, make sure to pass the session_id of the user like so:
// Connect Node.ACS to existing ACS
var ArrowDB = require('arrowdb'),
arrowDBApp = new ArrowDB('XXYYZZZ', { // ArrowDB Key
apiEntryPoint: 'https://api.cloud.appcelerator.com',
autoSessionManagement: false, // handle session_id yourself
prettyJson: true,
responseJsonDepth: 3
});
// == Creates the ACS_Event for a logged in User on ArrowDB ==
function createACSEvent(uniqueId, params) {
arrowDBApp.sessionCookieString = params.session_id; //<-- THIS IS IT!
arrowDBApp.eventsCreate({
name: 'someEvent',
start_time: params.start_time,
custom_fields: params,
}, function(err, result) {
if (err) {
logger.info( 'ERROR ACS_Event created '+ err);
} else {
logger.info( 'Success Creating ACSEvent ' + JSON.stringify(result));
}
});
}

Resources