Meteor facebook id vs accounts id - javascript

I am making an application which uses both the accounts package and facebook's graph api. Specifically the friends api. The friends api returns all facebook friends that have used the application. The problem is that it returns facebook id's, and the accounts package generate application specific id's. This is problematic when i want to retrieve information from a collection containing a friends information, but stored with the application specific id. I have worked around this by storing both the fb id and the accounts id in the collection.
But i still can't update a user data based on their fb id, as update is only permitted using the application specific id. What i want, but not allowed:
UserData.update({fbId: friend.fbId},{$push: {some: data}});
The only solution i could think of is to get each user id first, like this:
var friendId = UserData.findOne({fbId: friend.fbId})._id;
This is obviously not a good solution as it needs one extra db call for every update.
Is there a way of setting the accounts id equal to the facebook id upon creation? Or do you have any other suggestions.

Extending on the comment above:
MoeRum: #Xinzz UserData is a custom collection. If try updating with fbId I get the
following error: Uncaught Error: Not permitted. Untrusted code may
only update documents by ID. [403]
That is because you're trying to update on the client-side. You can only update by ID on the client-side. What you're trying to do should not be a problem as long as you do it on the server.
From the Meteor docs (for more reference: http://docs.meteor.com/#/full/update):
The behavior of update differs depending on whether it is called by
trusted or untrusted code. Trusted code includes server code and
method code. Untrusted code includes client-side code such as event
handlers and a browser's JavaScript console.
Trusted code can modify multiple documents at once by setting multi to
true, and can use an arbitrary Mongo selector to find the documents to
modify. It bypasses any access control rules set up by allow and deny.
The number of affected documents will be returned from the update call
if you don't pass a callback.
Untrusted code can only modify a single document at once, specified by
its _id. The modification is allowed only after checking any
applicable allow and deny rules. The number of affected documents will
be returned to the callback. Untrusted code cannot perform upserts,
except in insecure mode.

Related

Firestore (javascript sdk) - Get only new data (not just adding)

Im using Firestore with web javascript sdk.
Assume following scheme:
User Doc -> Friends collection
I want to know when someone change/remove/add data to it.
so what I wrote is something like this:
friendsCollectionRef.onSnapshot(snapshot => {
snapshot.docChanges().forEach(change => {
onChange(change);
});
});
The problem is that whenever I refresh the page, it keeps calling the onChange with data that was updated in my last session..
Is there a way to get only NEW data and not retroactively?
I would like to avoid store "LastUpdate" field on everything.
This, of course, should not be done in client side because then I pay for network which im never going to use..
So storing a boolean isFirstCall in out of the question.
As explained in the doc, when you listen to multiple documents in a collection with the onSnapshot() method:
The first query snapshot contains added events for all existing
documents that match the query. This is because you're getting a set
of changes that bring your query snapshot current with the initial
state of the query.
So each time you refresh your page you are calling again the onSnapshot() method "from scratch" and therefore you get the first query snapshot with all the collection docs.
In other words, I think you will have to implement your "home-made" mechanism to only get the documents you want (probably a "LastUpdate" field...).
You may be interested by this SO answer which shows how to add a createdAt timestamp to a Firestore document via a Cloud Function. You could easily adapt it to record the last update. It would be more complicated if you want to detect the Documents that were deleted since the last fetch.

Display visitor_posts facebook graph api

I'm using visitor_post to display page visitor posts.
right now i can get created_time, message, and id in object.
is it possible to display also the user profile picture?
The from field holds the user id, and via Field Expansion syntax you can use that to request the picture property of that:
...?fields=from{picture.type(large)}
Be aware that you will need a page access token to make this request; with any other kind of token you won't get any user details for posts on pages any more.
That of course also means that you should only do this on the server side (which you should for caching purposes anyway), because a page access token should never be exposed in publicly available code such as client-side JavaScript.

NiFi: Which processor would I use to connect to a third party API requiring 3 credential elements?

The options for configuring the GetHTTP processor look like they would work for connecting to a third party API. I need to send the username (available), password (available) and a 3rd string value which represents the database name. When the response (json) comes back, it will contain a session identifier which I will later need for any other API (javascript) calls. There is a "new property" option for this processor which I thought I might be able to use for the database string, however, it appears to be looking for a specific type of property. The warning message I get states: 'database' validated against 'mydatabasename' is invalid because 'database' is not a supported property. Any advice? Also, once the response does return, how would I retain the session id from it for all the subsequent API calls?
GetHTTP accepts dynamic properties which will be passed as HTTP request headers to the server. I did not have any problem adding a dynamic property called database in NiFi 1.2.0, but I believe that is a relatively recent addition that might not be available in earlier versions. InvokeHTTP might be an alternative.
Reusing the session id requires parsing the session id out of the response and into a NiFi flowfile attribute. Depending on the type of content you get back, this is typically done with an ExtractText, EvaluateJsonPath, or a similar processor.
Subsequent GetHTTP or InvokeHTTP processors should be configured to have a dynamic property for the session id, with the value set to use NiFi expression language to use the flowfile attribute, like ${sessionid}.

Parse User Query Only Retrieves Current user

I'm trying to run a query that retrieves a specific set of users from the User table and presents them to a given logged in user, using the Parse JS SDK.
At first I was running a query like:
(new Parse.Query(Parse.Object.extends("_User"))).containedIn("objectId", [/* list of user ids */]).find(/* success & error blocks */);
but then I learned the more correct way was:
(new Parse.Query(Parse.User)).containedIn("objectId", [/* list of user ids */]).find(/* success & error blocks */);
But even with this, I would get back an empty list. I double-checked the db and made sure the ids I was passing were in there, and they were. Just for the hell of it I tried:
(new Parse.Query(Parse.User)).find(/* success & error blocks */);
And I got back the user object corresponding to the current user. So it seems my User queries are only able to access the current user. I also noticed that when I tried running an equivalent query from the Parse API Console, I got the same results! Is this some sort of global setting, or am I doing something wrong? Thanks!
I believe you have to use CloudCode due to User Security Settings in Parse. Try shifting this to a cloud code function and include
Parse.Cloud.useMasterKey()
prior to the cloudcode function. This is a security 'feature' of Parse to ensure people can't edit and access other user profiles and information.
See Parse security site here:
https://parse.com/docs/js/guide#security-object-level-access-control
and more on use and considerations of implementing useMasterKey() and its persistence.
https://parse.com/docs/js/guide#security-implementing-business-logic-in-cloud-code
I would recommend not condensing all these calls into one line for the sake of saving lines. It sacrifices readability. Although, it's technically not wrong, and the docs even say the calls return a query so you can chain calls, so to each their own.
I don't see anything wrong with your call, though. How are you accessing the retrieved objects? What is the list of objectIds that you are passing into containedIn? We need a bit more of your code here, I think.
edit - I would say I'm 80% sure, without more information, that this is an ACL / CLP issue. Go to the dashboard, hit the _User class, press Security, and see what the read/write settings are.
Looks like a CLP issue to me. Maybe Find permission on your User class is disabled. Go to your User class, tap on security, switch to advance and then check whether the Find permission is ticked off or not.

Javascript: How to show hide divs based on security role

I have been using JQuery and AngularJS. One requirement I had was to show/hide divs and other widgets based on the login user role. I implemented the solution as below:-
On page load, get role of logged in user and store as a global variable in javascript
Show complete page
Hide divs using simple if statements based on security role
Is this the best way? Isn't there some framework or library for this? Doesn't AngularJS have anything to help?
Btw I understand that server side security is a must in spite of controlling what widgets login user can see in browser.
You could look at something like Angular Schema Forms. This takes a JSON object and will render it out using templates as HTML.
Another approach would be to use a template for each widget and then check the role before retrieving the template. If the template isn't retrieved then your custom tags will remain empty and have no content.
if isAuthorized
get template
else
do nothing or remove the element (your call)
The benefit of the first is that your markup is generated from server side data and thus has the extra benefit of being more secure. The second will work as well however.
Do note that you can change ANYTHING in javascript including global variable and javascript code in client side, so your server CANNOT TRUST THE CLIENT.
It's fine if you want to show/hide div based on the global variable, but your server should NEVER use that global variable to determine user permission. And for the div's that are hidden, you should NOT populate them with data from DB, so even when client change the CSS, they can't see data that is not permitted. Not to mention they can always inspect the network to see what is inside the JSON returned.
Usually you don't need to store as global variable, though. If your user does proper authentication, you should verify his identity for every transaction (every ajax request) and return only relevant content. In Angular view you can do ng-if when data exists only.

Categories

Resources