Webhook Subscription for AzureAd groups and Users not working - azure-active-directory

I have created a webhook subscription for Users and Groups by making a POST call to https://graph.microsoft.com/v1.0/subscriptions with the following as payload:
{
"changeType": "updated,deleted",
"notificationUrl": "https://a0317384.ngrok.io",
"resource": "groups",
"expirationDateTime": "2019-06-25T19:23:45.9356913Z",
"clientState": "<redacted>"
}
A Subscription is successfully getting created and I am returning verification token from my endpoint. I can also see it in the list of Subscriptions by making GET call on above URL.
When I am making some changes in Groups, like changing displayName or adding Members to the Group, I am not seeing notifications in real-time. Sometimes I am getting notifications in a bulk and other times the notifications do not arrive at all.
I have tried multiple times to delete and re-create the Subscription, but I still see the same behavior.
Can anyone tell why is it happening?

Notifications can be batched for performance optimizations and the delay to deliver notifications can vary based on service load and other factors.
While debugging you should also make sure there's no blocking conditions set by the IDE (like a break point for instance) that might block other incoming requests.
Lastly, it's pretty rare, but service outages can happen, in that case the best thing to do it to contact support.

Related

Microsoft Graph API subscription triggers same email with different IDs

I have a weird hard-to-replicate issue with Graph API and Outlook subscription endpoints. A user is authorised in my app and subscription is created for me/messages with change type created.
Everything works fine in 99% of the cases, but once in a while the endpoint is triggered several times with the same email. There is no changes to the email or any other part of the request, except ID, even timestamp. I have no idea how to replicate it consistently and/or fix an issue. Is there any scenario where Graph API would send the same message twice with slightly different IDs? It looks like they are sequentially generated IDs too, as they differ by 1-3 characters in the very end.

How to limit fraud, abuse and/or spam of public APIs without reCpatcha?

We provide an external JS-script to our partners, that they include in their e-commerce website. Basically, they call a function whenever a purchased has been made so we can record conversions of purchases referred by us and also change the state of the purchased item (items are set as purchased).
However, because our script is executed on the client side (for the sake of making the implementation simple for our partners), they can be used by an attacker to spam the platform with unreal requests. Enforcing a private key policy for every request to ensure they're legitimate requests is useless because they'll be exposed to the public anyway.
I don't think that ReCaptcha or invisible captcha would be an option, since the request has to be made as quick as possible and we use a pixel image to send the request. So, we were wondering how do services like Google Analytics, Google AdSense etc. detect and prevent spam requests or requests that are not coming from a real user.
We do understand that because the implementation is client-side only, there's no 100% prevention. We just hope that we could make it difficult enough that it doesn't worth the time and effort of an attacker.
So, what are possible solutions to ensure request made to the API are a result of an actual action made by a real user?

How to detect expired user session in a react app?

I am developing a REST API based on Node / Express and a frontend for it based on React / Redux. Users can login (which gives them access to additional functionality) but they can use basic functionality also without logging in.
When a user logs in, the client makes an HTTP call with the credentials, the server creates a session and returns a user object (user_id and some other data) as well as a session cookie. The React app saves the user object in its Redux state. In subsequent HTTP calls, the user is authenticated through the cookie.
When rendering the user interface, the React app determines whether it is logged in or not by checking for a user object in its state. This is used to grey out some buttons which are only available to logged in users, or to hide the login link when the user is already logged in.
The problem
It could occur that the session expires, or that the user logs out in a different browser tab. The React app has no way of knowing this and thinks it is still logged in (i.e. app state mismatches reality), leading to wrong UI display.
What pattern to solve this?
Put a hook on all Ajax calls to check for 401 and update the
state?
Return session state in HTTP headers (and then?)
A Comet pattern for the server to notify the client that it has been logged out? (not a REST API anymore then)
Additional calls before actual API calls to make sure user is still logged in? (seems wasteful)
And how to deal with this once the client detects it is no longer logged in during an ongoing operation? I'd prefer to handle this in one place rather than all functions making API calls...
I'd be thankful for some best practice!
There are two straightforward ways to deal with this issue in a React application that I can think of. Both inspired by a colleague of mine few days ago.
Use SSE (server-side-events) technology to PUSH notifications. As you correctly pointed out, this makes your API less pure. This approach should be quite an acceptable sacrifice where flawless UX is required AND/OR your server might need to push other notifications to the app.
Establish a short term timer somewhere in your client app (e.g.: setTimeout(...)) that makes periodic calls to a "ping" API endpoint that will return current user/session information. This approach will impact UX for the duration of timeout, often negligible, and is commonly known as polling.
Hope this helps!
As an alternative to the naive polling, you can make it a little smarter by adding an endpoint that lets you know in how many seconds timeout is set to occur for the session at that point in time.
Then ping just before that time (instead of at a certain poll-rate) and update accordingly.
Logging out in another tab would return with an invalid token so would be picked up, too, but not as quickly if this is your main concern.
For this you could use broadcasting to let the other tabs know immediately (or use sessionStorage's change event to simulate a broadcast on unsupported browsers).
Otherwise the best way would be to implement a ServiceWorker; these can handle all requests for your app to the server. It's a centralised piece of code separate from your app that can broadcast to all tabs that a session is lost the moment it sees that one of its requests was rejected, and you can efficiently naively poll from this one place (instead of in each individual tab's runtime).
Since I am using token from the API Server that is valid for a specific period of time. So in addition to setting token in session storage I was thinking of setting up another session storage variable that stores the timestamp at which the token was generated. Then, in my js code I plan to add the validity period (say, 3600 seconds) and check if the token is still valid or not. If it is valid then the user session is valid else it is invalid.

Synchronizing Clients with Gmail

What is Synchronizing client with gmail ? Can anybody give a detailed explanation, because i want to have a better understanding over this concept.
For example, if your client keeps any local cache of the Gmail mailbox data like the Message.Id and labels, or headers, or the entire email. Then in order to update your client you're synchronizing it with Gmail--pulling new updates down to your client. In cases of clients designed for offline use, then synchronizing may also mean pushing local updates back up to the server (e.g. label updates made by client while "offline" that get applied at some later point). That's the general definition of synchronizing.
For the Gmail API specific case, Gmail has a backend mailbox-wide history Id. Any change that affects that account in any way gets a history identifier and most (but not all) history changes affect the state of email messages. Like adding a new message, changing the labels on a message, or deleting a message. Clients of the Gmail API can poll the history Id and find out what's changed since the last time they synchronized and pull down updates to maintain their sync.

Listening to changes in sling's users and groups

I want to be notified of changes to users or groups in sling's userManager as they happen. For example, when a new group is created, I need to create a new node with the same name under /content. When a new user is created, I want to give them write-permissions for /content/foo. And similar tearDown steps when objects are deleted.
I tried registering a EventHandler (org.osgi.service.event.EventHandler), with event.topics set to "*" (all topics), but this captured only resource changes and not userManager changes because users and groups are synthetic resources (I think)
I tried using a org.apache.sling.api.request.SlingRequestListener, but the SlingRequestEvent did not come with any info that would help me distinguish the request (or I didn't know how). Also, I am not sure if this is can even be used for callbacks that need to be called AFTER the request is processed.
I have used Filters for a different issue and I tried applying them for this purpose too. But they have their limitations - My filter is called BEFORE the request, so it's not possible to know if the request will result in SUCCESS before deciding to take action.
Any suggestions on how to listen and respond to changes in sling's user and group models?
In https://issues.apache.org/jira/browse/SLING-977 Ian Boston suggests using a SlingPostProcessor service to be informed of calls to the user management's POST servlets.
I haven't tried it myself, and if you do it you might anyway miss changes that are done via Sling's user management APIs - but that might be good enough depending on your use case.
Apart from that I don't think there's currently a surefire way of being notified of such changes. To implement that in Sling we'd need to wrap the org.apache.jackrabbit.api.security.user.* objects (Group, User, UserManager) to send events when they're changed. Certainly doable but would require changes to that Sling bundle.

Resources