XMPP: how to request server for presence status of a user's contacts? - xmpp

We have a site and we developed a chat system for it using strophe.js library and ejabberd XMPP server. We use session attachment that was initiated with PHP (using an in-house library). What we do is get the RID and SID from the PHP script, then use strophe's session attachment. The said RID and SID is stored on a cookie and the RID value on the cookie is updated every update of the RID on strophe.js.
This works fine, after logging in we receive the presence status of each of our contacts. The problem with this is, when you go to another page on the site, and attach using the said RID (we use the incremented value produced by strophe) and SID, the server wouldn't send presence information of your contacts anymore as opposed to when you logged in. This caused our contacts area to appear all invisible even though they are online. They would only appear online if you (or your contact) log out on the chat, then log in again (since you will receive a presence update from the XMPP server).
I have written a workaround where the presence status of your contacts is saved on a cookie (all online contacts will have their JIDs saved on the cookie) when a presence is received from the server. This is checked every page load, if the cookie is set, it will be read, and all JIDs on the cookie will be marked as online. This is working fine but there might be some better ways to solve this, using XMPP's default behaviors.

XMPP servers send presence probes to all your contacts on your behalf when you send your own initial presence to the server. From then on, you will only receive presence status changes from your contacts.
If you lose the presence state of your contacts, you will need to send your own presence probes to re-establish that state. However, this is probably not something you want to do a lot, and passing around the presence state is probably preferred in most cases.
You could try passing the state via XMPP. For example, you could use Private XML Storage (XEP-0049), Pubsub (XEP-0060), or PEP (XEP-0163).
Another option instead of cookies for passing it client side is to use an HTML5 SharedWorker object to hold the state.

I shudder to think of the scale properties associated with storing all of the presence you just received from the server back to the server in private storage. Private storage almost always is backed to long-term storage rather than stored in memory, so you're going to grind your server's disk to dust.
If you want to store more state in the browser, and insulate yourself from browser version, and you're already using jQuery, then jStore is pretty sweet.

Related

REST APIs: How to ensure atomicity?

I am developing a small REST API. As I got into analyzing all the possible failure scenarios, which I have to handle to create a reliable and stable system, I went into thinking about how to make my APIs atomic.
If we take a simple case of creating a contact through the POST API.
The server gets the POST request for the new contact.
Creates the contact in the DB.
Creates a response to send back to the client.
The server crashes before sending the response.
The client gets a timeout error (or connection refused?)
The client is bound to think that the contact creation has failed, though, in fact, the contact was in the DB.
Is this a rare case we can ignore? How do big companies deal with such an issue?
To handle this, you should make your write APIs idempotent i.e. If the same operation is executed multiple times, the result should be same as the operation was done only once.
To achieve this in your current example, you need to be able to identify a contact uniquely based on some parameter, say emailAddress. So, if the createContact is called again with the same emailAddress, check in the DB if a contact already exists with the emailAddress. If so, return the existing contact. Else, create a new contact with the emailAddress and return it.
Hope this helps.
If the request times out, the client should not make any assumption about whether it failed or succeeded.
If it is just a user making a request from a web form, then the timeout should just be exposed to the user, and they can hit the back button and check whether the operation succeeded or not, and if not they submit the request again. (This is fine as long as you always keep a consistent state. If your operation has multiple steps and fails mid way, you need to roll back.)
However if reliable messaging is important to your application you will have to use a library or build your own reliable messaging layer. This could work by having the client assign a unique ID to every request, and having another request that lets you check the result of that request ID later. Then you can do automated retries but only where necessary.

User status message for iOS chat app

I am developing an iPhone chat application using robbiehanson/XMPPFramework and I am using OpenFire on the server side. I want to implement the user status feature on my app like the whatsapp status concept.
How can I achieve this, is there any default support on the openfire server for storing the user status messages ?
Thanks in advance
I am not sure what you call 'user status'. You can add information about the presence of the user in presence packets. This is purely transient information and is generally not stored in XMPP server.
You can also decide to publish status information in a more persistent way using Personal Eventing Protocol (PEP). The last status is generally stored by server to be resend / retrieved at a later time.
Reference: http://xmpp.org/extensions/xep-0163.html

iphone app - preventing spam

I've developed an app that allows users to upload some photos and share them on Facebook/Dropbox/Twitter etc. Recently it went live in the app store.
However, I'm having a problem now: a bot is creating accounts and uploading many photos on my server. I've temporarily disabled the app, but now I'm looking for an efficient way to prevent this bot from doing this.
The bot's ip address is changing very often so it's impossible to block the ip. He creates accounts with a very realistic name and email address so it's hard to find out which users are real and which are created by the bot.
I was thinking of using a captcha, but I'm not sure if my app will be rejected by Apple if I implement this. I'm preferably looking for a way so I can prevent him from doing his work and so I don't have to resend the app to Apple again.
Could anyone give me some advice on what I could possibly do?
Thanks!
This is how I solved a similar problem:
I implemented a token-generator, which generates a one-time token for every single data transfer with the server, so even one for login-data, sending a file etc. This token is generated by a secret algorithm and can be verified server side, since you know how you generate one.
After one token is used, put it in a temporary list for the next X minutes/hours/days (depending on how many data transfers your server can handle). When a user tries to send data with a used token (i.e. the token matches one in the "banned" list), you can be sure that someone's trying to spam you -> mark the account as "spammer" and decide what you wish to do.
The algorithm must produce a different token each time (the best way would be a one-way hash), but you have to assure specific "properties", with which you can proof its authenticity.
So one very simple example:
Your algorithm in the client is generating a number between 1000000000000000000000 and 99999999999999999999999, this number is then multiplied with 12456564 and incremented by 20349.
The server becomes a specific command and data, and the generated token. Now it checks, whether (number - 20349)%12456564 is 0. If it's 0, it was likely generated by your "secret" algorithm.
It's a very basic example but you get the idea…

How does Litmus track their email analytics?

So, 'Litmus', a web app for testing emails and webpages across browsers and email clients, has a proprietary method that they claim is able to track not just opens, clicks, browsers, etc (standard with an embedded image and pass-through link tracking.)
What's unique is they claim that they are able to track what actions the end user took, how long the end user read it for, and if they deleted or forwarded the email. They claim they do this without JavaScript, and purely using embedded images. They claim that the method works across most major email clients.
What could they be doing to track this? Obviously, if they're doing it with third party applications that they don't control, whatever they are doing should be replicable.
I'm thinking that they realized that when an email client forwards or deletes an email, it 'opens' the email in a different way then normal, creating a unique user string on the server log of some kind? I'm grasping at strings, though.
http://litmusapp.com/email-analytics
Details here http://litmusapp.com/help/analytics/how-it-works
EDIT: It also looks like they track Prints. Maybe they do this by tracking calls to the 'print' css?
It's all done with good ol' image bugs. Breaking down how they find out...
Which client was used: Check the user-agent
Whether an email was forwarded: Done by attaching image bugs to divs that are loaded only when the message is forwarded.
Whether an email was printed: bug attached to print stylesheet
How long it takes to read an email: A connection that's kept open, as pointed out by Forrest (this is also how Facebook tracks(ed?) whether or not you are online on chat).
Whether an email was deleted: Check If a message was read for a short period of time or not opened. In fact, they group "glanced" and "deleted" together.
Of course none of this will work if email clients disable images in emails.
EDIT: Here's another question on this:
The OP actually has their tracking code, and this answer here explains how it works.
One way I can think of doing that is having an embedded image that loads from a script on a server. The script would not return anything or maybe send data really slowly to keep the connection open. Once the email is deleted the connection would be closed. This way they could know how long the email was open. Maybe they just assume if it's open for less than 10 seconds it was deleted?
Another way is tracking the referrer - this would give a lot of data on what a webmail client is doing, but I doubt it would be useful with a desktop client.
They know when the email is opened (it's when the image is called from their http server).
They also know what the user do and when since they can easily replace all links with their own tracking URLs redirecting to the original link.
There is nothing exceptional here. They are just a bit more advanced than their compatitors. There is no magic.
I have only one doubt: how they track delete. Technically, there is no way to know what happened to the message after it was read.
I suspect that a "deleted" mail is a mail that is never opened.

Which users are currently connected to an Openfire Jabber server?

I have got an Openfire Jabber server with in excess of 75,000 users listed. Of those, 150 or more can be online at any one time.
Is there anywhere that I can collect the JIDs (usernames) of the currently logged in users? I have full database access to the underlying data, but the server does not appear to write the current status back to the DB. Because of the number of users, rosters are not being used.
A very useful set of data being returned would be from a simple (password protected) webpage with one JID per line, optionally with the login time, and maybe also the last time that account performed an action [like send a message]. The latter two are not as essential, but would be useful if the data is available, as well as any other information that was available regarding the user session.
dont know if this will help but I ran into it looking for similar functionality. As defined in XEP-0045 http://xmpp.org/extensions/xep-0045.html#disco-roominfo :
An implementation MAY return a list of existing occupants if that information is publicly
available, or return no list at all if this information is kept private. Implementations
and deployments are advised to turn off such information sharing by default.
So you would need to ensure it works as advertised on Openfire (all xmpp servers ive come across have a bug or two in them), and I imagine you would need to code some logic to get the results.
Good luck.
Not a perfect answer, but the query you want is probably embedded in the session-summary.jsp page. I got to it on a locally hosted server at http://localhost:9090/session-summary.jsp. What I don't know is if that is then stored in the database where it is query-able, or if it is stored internally to the client. The latter is more likely.
The data that page displays is Name, Resource, Status, Presence, Priority, Client IP, and Close Connection.