when receiving a message from pubnub, there is no information on the sender. how to know if it's a message from visitorA or visitorB ? there are examples on the web where the sender sends his name with the message, but how to know he isn't spoofing someone else's identity ?
here is an example of a chat interface :
<html>
<body>
<form id="message_form">
<input id="message_input" type="text"/>
</form>
<div id="chat"></div>
<script src="http://cdn.pubnub.com/pubnub-3.7.1.min.js"></script>
<script>
var pubnub = PUBNUB.init({
publish_key: 'demo',
subscribe_key: 'demo'
});
pubnub.subscribe({
channel: 'chat',
message: function(message){
var div = document.createElement("div");
div.textContent = message;
var chat = document.getElementById("chat");
chat.appendChild(div);
}
});
var form = document.getElementById("message_form");
form.onsubmit = function(e) {
var input = document.getElementById("message_input");
pubnub.publish({
channel: 'chat',
message: input.value
});
input.value = '';
e.preventDefault();
};
</script>
</body>
</html>
Chat User Identification
You can identify the sender by creating a Unique ID as well as a Name attached to the message payload of the chat conversation. This is similar to IRC strategies but a bit more simplistic.
var user_id = PUBNUB.uuid();
var user_name = name.value;
var user_message = input.vaule;
Here is a full example which includes the HTML elements for UserName input. Notice also that I added a safe_text() method to prevent XSS attacks.
<form id="message_form">
Name: <input id="name_input" value="John" type="text"/><br>
Message: <input id="message_input" value="Hi" type="text"/><br>
<input type="submit" value="send">
</form>
<div id="chat"></div>
<script src="http://cdn.pubnub.com/pubnub-dev.js"></script>
<script>
var userid = PUBNUB.uuid();
var pubnub = PUBNUB({
publish_key : 'demo',
subscribe_key : 'demo',
uuid : userid
});
function safe_text(text) {
return (''+text).replace( /[<>]/g, '' );
}
pubnub.subscribe({
channel: 'chat',
message: function(message){
var div = document.createElement("div");
div.textContent =
safe_text(message.name) + ": " +
safe_text(message.text);
var chat = document.getElementById("chat");
chat.appendChild(div);
}
});
var form = document.getElementById("message_form");
form.onsubmit = function(e) {
var input = document.getElementById("message_input");
var name = document.getElementById("name_input");
pubnub.publish({
channel: 'chat',
message: { name : name.value, text : input.value, userid :userid }
});
input.value = '';
e.preventDefault();
};
</script>
While this demonstration provides you with a quick and easy getting started app, you will want to add more enhanced chat security and chat authentication systems.
For additional resources for building chat applications check out Build Real-time Chat Apps in 10 Lines of Code guide and also Building A Basic Chat Application.
Chat Access Control Layer ACL
You will need to add Security ACL Access Control Layer. With PubNub Access Manager (PAM) you can control who has access by granting users permission with access tokens.
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
// Grant Chat Access to Secured Conversations
// All server-side data is stored according to defined security policies.
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
var pubnub = PUBNUB({
publish_key: "PUBLISH_KEY",
subscribe_key: "SUBSCRIBE_KEY",
secret_key: "SECRET_KEY"
})
pubnub.grant({
channel : "CHANNEL",
callback : receiver,
error : receiver,
ttl : 60, // Minutes
read : true,
write : true,
auth_key : "AUTH_KEY"
});
It is recommended to run this level of ACL code on Trusted Systems such as your own data center servers.
Sending/Receiving Secure Encrypted Messages
PubNub client libraries offer built-in Advanced Encryption Standard (AES) 256-bit encryption. To use message encryption, simply use cipher_key at initialization.
To enable Transport Layer Encryption with TLS and the ssl flag.
Then publish/subscribe as usual.
var pubnub = PUBNUB({
subscribe_key: 'sub-c-f762fb78-...',
publish_key: 'pub-c-156a6d5f-...',
ssl: true,
cipher_key: 'my_cipherkey'
});
Message Verification for Identity of Sender
Attaching user's information to each message is efficient and provides a very powerful level of flexibility within your application. However malicious users may attempt to spoof the identity of users and therefor impersonate other users. In the sample app we have shown that it is easy to impersonate anyone by changing your name in the "message_form" field. This is the same situation you encounter with email and SMTP where arbitrary email header impersonations are possible unless you provide a way to verify the identity of the sender. There is a solution! 😄
Digital Signatures are fingerprints with embedded secure cryptographic hashes of key components of the message payload optionally including a salt (sometimes a timestamp) and then signing/encrypting with an asymmetric secret key which is used to verify the identity of the sender. This process is used to block spoofers and impersonations.
A digital signature is a mathematical scheme for demonstrating the authenticity of a digital message or document.
Message Verification for Chat Applications
Start by assuming that only the chat users have been granted access and they can publish and subscribe to chat channels using grant and revoke techniques available in your PubNub Access Manager implementation.
The challenge here is that in a group chat room, your chat users have been granted auth_tokens yet they still can impersonate other chat users on the channel.
The goal here is to verify two things when a client receives a message.
Identity of sender.
Integrity of message.
Using asymmetric cryptography, you can provide a layer of validation and security to your users' messages by creating a digital signature. A valid digital signature gives a recipient reason to believe that the message was created by a known sender, that the sender cannot deny having sent the message (authentication and non-repudiation), and that the message was not altered in transit (integrity). Digital signatures are commonly used for financial transactions and message oriented communication such as email and chat and in other cases where it is important to detect forgery or tampering.
You will start by issuing each of your chat users' a set of keys, server generated, with a public-key (asymmetric) algorithm such as ECC/RSA via your server after user login. I recommend ECC as the key size is much smaller than RSA with comparable cryptographic strength. Each chat user in a chatroom is notified of other chat users' public key via a secured read only side-channel. Your users must only receive the Public Key from a public READ-ONLY channel controlled by your server's trusted and secure environment. Your server will be able to write each user's Public Key to this READ-ONLY channel. Your users will read from this channel.
Your user's can receive each other's Public Keys via a PubNub History call before joining the chat room. They should also open a subscription to the same channel to get public key of new chat users joining the chatroom.
The users' Private Key must not be exposed to anyone but the verified owner. This can be done upon email/password sign-on and you can send the private key to the verified user as soon as they log-in.
Sending a Chat Message with Attached Digital Signature
{ userId: 123456,
profilePic: "http://www.chats.com/user1234.jpg",
message: "Hello World",
signature: "tnnArxj06cWHq44gCs1OSKk/jLY" }
You will create the signature by concatenation of the following base string (userId+profilePic+message). Next you need to calculate a message digest using SHA1(signature_base_string) or SHA256(signature_base_string). Now you can use this cryptographically generated hash to sign with the users' private key using an ECC/RSA asymmetric algorithm.
Now attach this digital signature to chat message as shown in the example above and on to the final phase of Chatroom Message Verification.
Chatroom Message Verification
While subscribed to the chatroom channel you will receive user sent chat message with an attached digital signature. You will use this signature to verify the chat message's authenticity. If the message was an attempted spoof you will drop the message altogether.
// Digitally Signed Chat Message
{ userId: 123456,
profilePic: "http://www.chats.com/user1234.jpg",
message: "Hello World",
signature: "tnnArxj06cWHq44gCs1OSKk/jLY" }
To verify the signature you will create the signature by concatenation of the following base string (userId+profilePic+message). Next you need to calculate a message digest using SHA1(signature_base_string) or SHA256(signature_base_string). Now using the chat users' public key you already have for userId 123456 you can Verify/Decrypt digital signature to get original message digest you just generated which was also created by the sender.
Compare current message digest and original message digest. If they are the same then the message is authentic and you have successfully verified the sender's message using Message Verification via digital signing. If the digests do not match, it's a phony message and you may disregard the impersonator.
Creating a PKI Public Key Infrastructure using PubNub
You'll need a way to securely transmit public keys via a read-only PKI. PubNub provides to you a way for exposing a secure read-only PKI list for your chat users. Important to note that PKI requires asymmetric key algorithm like ECC or RSA. Also we are using these crypto algorithms for creating digital signatures rather than encrypting the data. This means we will be able to identify and verify the sender by successfully decrypting the signature using the public key and verifying the salted signed string matches.
Public Key is used as the Decryption Key and Verify Key.
Private Key is used as the Encryption Key and Signing Key.
It is important to note that you should only print the username retrieved from the Public Key Trusted Source and not from the message content. The message content is only used for signing and verifying Identity. If an Identity is changed it must be relayed via the PKI using PubNub’s Broadcast mechanism and Storage and Playback for Secure Authorization.
Access tokens, Identity Name/Photo and Asymmetric Keys must only be generated from trusted execution environments on your servers and relayed over PubNub's Authorized Read-only PKI data channels.
In the most recent PubNub SDKs (v4), the publisher UUID is now included in subscribe response.
{
actualChannel: null,
channel: "my_channel_1",
message: "Hello World!",
publisher: "pn-58e1a647-3e8a-4c7f-bfa4-e007ea4b2073",
subscribedChannel: "my_channel_1",
subscription: null,
timetoken: "14966804541029440"
}
Related
I am using directline with webchat.
window.WebChat.renderWebChat(
{
directLine: window.WebChat.createDirectLine({
secret: '<my secret key>',
}),
//customizing web chat styles.
styleOptions: styleOptions
},
document.getElementById('webchat')
);
This my javascript that initiates the webchat with the secret key. Is there anyway that I can receive the conversationId back in the javascript after initializing the webchat as above?
This is easily achieved by utilizing the method demonstrated in the 04.api/a.welcome-event sample. Upon Web Chat connecting, an event is sent to the bot indicating this. When the event is received by the bot the bot sends a return activity. The return activity, by design, includes the conversationID.
In short, here is the code you can reference. Taken from the sample, this sends the users location based on the browser's properties.
From Web Chat:
https://github.com/microsoft/BotFramework-WebChat/tree/master/samples/04.api/a.welcome-event
From the bot:
if (context.activity.name === 'webchat/join') {
await context.sendActivity(
`Got \`webchat/join\` event, your language is \`${(context.activity.value || {}).language}\``
);
}
I execute this code to push notifications to mobile device using FCM library
public string PushFCMNotification(string deviceId, string message)
{
string SERVER_API_KEY = "xxxxxxxxxxxxxxxxxxxxxxx";
var SENDER_ID = "xxxxxxxxx";
var value = message;
WebRequest tRequest;
tRequest = WebRequest.Create("https://fcm.googleapis.com/fcm/send");
tRequest.Method = "post";
tRequest.ContentType = "application/json";
tRequest.Headers.Add(string.Format("Authorization: key={0}", SERVER_API_KEY));
tRequest.Headers.Add(string.Format("Sender: id={0}", SENDER_ID));
var data = new
{
to = deviceId,
notification = new
{
body = "This is the message",
title = "This is the title",
icon = "myicon"
}
};
var serializer = new JavaScriptSerializer();
var json = serializer.Serialize(data);
Byte[] byteArray = Encoding.UTF8.GetBytes(json);
tRequest.ContentLength = byteArray.Length;
Stream dataStream = tRequest.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
WebResponse tResponse = tRequest.GetResponse();
dataStream = tResponse.GetResponseStream();
StreamReader tReader = new StreamReader(dataStream);
String sResponseFromServer = tReader.ReadToEnd();
tReader.Close();
dataStream.Close();
tResponse.Close();
return sResponseFromServer;
}
now, how to send message to multi device,
assume that string deviceId parameter replaced with List devicesIDs.
can you help
Update: For v1, it seems that registration_ids is no longer supported. It is strongly suggested that topics be used instead. Only the parameters shown in the documentation are supported for v1.
Simply use the registration_ids parameter instead of to in your payload. Depending also on your use case, you may use either Topic Messaging or Device Group Messaging.
Topic Messaging
Firebase Cloud Messaging (FCM) topic messaging allows you to send a message to multiple devices that have opted in to a particular topic. Based on the publish/subscribe model, topic messaging supports unlimited subscriptions for each app. You compose topic messages as needed, and Firebase handles message routing and delivering the message reliably to the right devices.
For example, users of a local weather forecasting app could opt in to a "severe weather alerts" topic and receive notifications of storms threatening specified areas. Users of a sports app could subscribe to automatic updates in live game scores for their favorite teams. Developers can choose any topic name that matches the regular expression: "/topics/[a-zA-Z0-9-_.~%]+".
Device Group Messaging
With device group messaging, app servers can send a single message to multiple instances of an app running on devices belonging to a group. Typically, "group" refers a set of different devices that belong to a single user. All devices in a group share a common notification key, which is the token that FCM uses to fan out messages to all devices in the group.
Device group messaging makes it possible for every app instance in a group to reflect the latest messaging state. In addition to sending messages downstream to a notification key, you can enable devices to send upstream messages to a device group. You can use device group messaging with either the XMPP or HTTP connection server. The limit on data payload is 2KB when sending to iOS devices, and 4KB for other platforms.
The maximum number of members allowed for a notification_key is 20.
For more details, you can check out the Sending to Multiple Devices in FCM docs.
You should create a Topic and let users subscribe to that topic.
That way, when you send an FCM message, every user subscribed gets it, except you actually want to keep record of their Id's for special purposes.
FirebaseMessaging.getInstance().subscribeToTopic("news");
See this link: https://firebase.google.com/docs/cloud-messaging/android/topic-messaging
https://fcm.googleapis.com/fcm/send
Content-Type:application/json
Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA
{
"to": "/topics/news",
"data": {
"message": "This is a Firebase Cloud Messaging Topic Message!",
}
}
Please follow these steps.
public String addNotificationKey(
String senderId, String userEmail, String registrationId, String idToken)
throws IOException, JSONException {
URL url = new URL("https://android.googleapis.com/gcm/googlenotification");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setDoOutput(true);
// HTTP request header
con.setRequestProperty("project_id", senderId);
con.setRequestProperty("Content-Type", "application/json");
con.setRequestProperty("Accept", "application/json");
con.setRequestMethod("POST");
con.connect();
// HTTP request
JSONObject data = new JSONObject();
data.put("operation", "add");
data.put("notification_key_name", userEmail);
data.put("registration_ids", new JSONArray(Arrays.asList(registrationId)));
data.put("id_token", idToken);
OutputStream os = con.getOutputStream();
os.write(data.toString().getBytes("UTF-8"));
os.close();
// Read the response into a string
InputStream is = con.getInputStream();
String responseString = new Scanner(is, "UTF-8").useDelimiter("\\A").next();
is.close();
// Parse the JSON string and return the notification key
JSONObject response = new JSONObject(responseString);
return response.getString("notification_key");
}
I hope the above code will help you to send push on multiple devices.
For more detail please refer this link https://firebase.google.com/docs/cloud-messaging/android/device-group
***Note : Please must read the about creating/removing group by the above link.
A word of caution mentioned in FCM DOcument which is as follows,
Caution: Any apps that use device group messaging must continue to use the legacy API for the management of device groups (creating, updating, etc.). The HTTP v1 can send messages to device groups, but does not support management.
https://firebase.google.com/docs/cloud-messaging/migrate-v1
Also the Admin SDK's uses a Batch HttpPostrequest to make it easy for consumers, so if you want Device Group messaging you could still uses the New V1 FCM API, but using FCM Admin SDK.
Here is the code from Admin SDK which does this job for you.
Class Name: FirebaseMessagingClientImpl
for (Message message : messages) {
// Using a separate request factory without authorization is faster for large batches.
// A simple performance test showed a 400-500ms speed up for batches of 1000 messages.
HttpRequest request = childRequestFactory.buildPostRequest(
sendUrl,
new JsonHttpContent(jsonFactory, message.wrapForTransport(dryRun)));
request.setParser(jsonParser);
setCommonFcmHeaders(request.getHeaders());
batch.queue(
request, MessagingServiceResponse.class, MessagingServiceErrorResponse.class, callback);
}
Is it possible to send a message to a specific Skype Account using nodejs?
Example: I'm trying to send a message to a specific Skype account (Person 2) if my bot does not have the answer. Then, catch again the answer to resend to the first user (Person 1).
I'm using NodeJs v8.12, and BotBuilder v4
Thanks
If you have the bot's conversationId of the skype account, then you can send a proactive message. Conversation Id is found in session.message.address.conversation.id in nodeJs app.
When someone interacts with the bot say for the first time, you can save the session.message.address object (in string form) in your database.
const addressString = JSON.stringify(session.message.address)
// now save addressString to the database
Later you can retrieve this object (and convert it back to json) to send proavtive message.
const address = JSON.parse(addressString);
private sendProactiveMessage(message, address) {
const msg = new BotBuilder.Message().address(address);
msg.text(message);
this.bot.send(msg);
}
I'm a bit confused on the presence-channels in Pusher's platform, as I'm building a chat application from scratch. Now, I know some of you guys have seen tons of "realtime chat app" topics around, but, I'm looking for a peer-to-peer chat and not the site-wide global thingy. More like a facebook chat, where you can go one-to-one.
Now, I've seen an example in PubNub's demos (named Babel) but, that thing is far from what I'm looking for because I've checked the requests in the console and even if it's not shown, the sent messages between other users are shown in my network request logs too because it's being filtered in JS and not server-side and thats not something I want for sure.
So, coming back to the subject,
I'm aware of the channel / private-channel / presence channel functionality, and I decided to do this:
When opening the app, every user subcribes to his private-user_id channel ( creates, if it doesn't exist already ).
At the same time ( while opening the app ) user1 subscribes to a presence-global channel where others keep track if friends are online.
When others want to send him a message, e.g. user2 to user1, he subscribes to private-1 thereafter javascript will process the events.
Now, I know something's wrong with this because.. if user3 would send a message to user1 he'd subscribe to private-user1 so I guess he'll see the events that user2 is triggering when sending messages to user1 too, right ? Or did I get this wrong ?
I've read in their docs that presence channel is actually a private channel extension, so I'm thinking now.. why using private channels anymore, and then, how can I notify all my friends I'm online.
But then, something else comes up in their docs , telling me that channels provide two important things (among others), from which, first is a way of filtering data and second is a way of controlling access.
How am I supposed to "filter data" since there's no link in their docs, or better, what do you have in mind for a one-to-one chat. I'm sorry if I got all their docs wrong, I had a look on their sample applications but none of them are using the one-to-one technique which I'm looking for.
I am new to Pusher and socket connections etc, but I've learned how to authenticate, how to create , detect and process the events in the channel, and I can create a simple global chat with online members, but, when it comes to private-channels I'm quite confused on how to create separate channels for two users.
Thanks in advance !
The purpose of private channels is to restrict who can subscribe to that channel. So, you can either:
Use it to ensure only a users friends can subscribe to updates
Use it for notifications only for that user
In one-to-one chat I'd suggest you choose the latter (No.2).
With this in mind I'd set out achieving one-to-one chat as follows:
The Forum
When users join the chat application they all subscribe to two channels:
private-notifications-<user_id> where user_id is their unique user ID e.g. leggetter in my case. This channel is utilised for user-specific notifications.
presence-forum for all users in that forum. The question called this presence-global.
This is achieved as follows:
var notifications = pusher.subscribe( 'private-notifications-user_one' );
var forum = pusher.subscribe( 'presence-forum' );
Upon subscription to each channel the channel authentication process will take place.
Within the forum you could have a general public chat on the presence-forum/presence-global presence channel by sending and receiving messages.
Starting one-to-one chat
When one user (user_one) wants to have a private chat with another user (user_two) you obviously need something in the UI to trigger this. Say user_one clicks on something next to user_two that indicates they want a one-to-one chat. When this happens a request should be made to the server (the authority) to indicate that user_one wants to initiate the private chat with user_two†.
Note: †if you chose a channel naming convention for one-to-one chat the private channel authentication could actually be used as the private one-to-one chat initiation
When the server receives this request it can generate a unique private channel name for this one-to-one chat. A really simple way of doing this is by concatenating the user IDs e.g. private-chat-<initiating_user>-<receiving_user> (there are other considerations e.g. maybe you want to ensure the channel name is always the same between the two users). In our simple scenario the channel name would be private-chat-user_one-user_two.
The server can then trigger a one-to-one-chat-request event on the private notification channel for each user delivering the one-to-one private chat channel name in the payload.
// Trigger event on both user channels with one call
var channels = [ 'private-notifications-user_one', 'private-notifications-user_two' ];
// Additional event data could also be sent
// e.g. more info on the initiating user
var eventData = {
'channel_name': 'private-chat-user_one-user_two',
'initiated_by': 'user_one'
'chat_with' : 'user_two'
};
pusher.trigger( channels, 'one-to-one-chat-request', eventData );
When user_one receives the one-to-one-chat-request they will subscribe to the eventData.channel_name channel and the auth process will take place for that channel.
// A lookup of private chats
// where the key is the user ID of the current user is chatting with
var privateChats = {};
notifications.bind( 'one-to-one-chat-request', function( data ) {
// MY_USER_ID would need to be stored somewhere
// and in this case the value would be 'user_one'.
// expectingChatWith should make sure user_one is waiting for
// a private chat response with the given user
if( data.initiated_by === MY_USER_ID &&
expectingChatWith( data.chat_with ) ) {
startPrivateChat( data.chat_with, data.channel_name );
}
} );
function startPrivateChat( withUserId, channelName ) {
privateChats[ withUserId ] = pusher.subscribe( channelName );
}
When user_two receives the one-to-one-chat-request the user will need to be notified about the request and either accept or decline it. If the user accepts then the client-side code simply subscribes to the channel. If the user declines then a request should be sent to the server and an event triggered on private-notifications-user_one telling them their one-to-one chat request was declined. This will allow user_one to unsubscribe from the private chat channel.
var privateChats = {};
notifications.bind( 'one-to-one-chat-request', function( data ) {
if( ... ) { ... }
// has somebody request to chat with this user?
else if( data.chatWith === MY_USER_ID ) {
// Prompt the user
// Note: more user info required
displayChatPrompt( data );
}
} );
// callback when the user accepts the chat request
function accepted( chatUserId, channelName ) {
startPrivateChat( chatUserId, channelName );
}
// the user doesn't want to chat
function declined( chatUserId ) {
// send info to the server indicating declined request
}
Private one-to-one chat success
With both user_one and user_two subscribed to private-chat-user_one-user_two they can trigger events on the channel and participate in their private one-to-one chat.
I'm now learning some new technologies (such as node.js, socket.io, redis etc.) and making some simple test applications to see how it can work.
My question is about security on a client-side javascript code: for example, i have a chat-server on node.js+express and when a user connects to this chat, server should assign his registred username (authorisation through oldschool php+mysql is used) to his socket. The question is, can user modify his client-side script and connect to chat under different users' names?
Some code is given below:
(server-side part of assigning username, which is just getting the username from client-side call)
// when the client emits 'adduser', this listens and executes
socket.on('adduser', function(username){
// store the username in the socket session for this client
socket.username = username;
// store the room name in the socket session for this client
socket.room = 'General';
// add the client's username to the global list
usernames[username] = username;
// send client to room 1
socket.join('General');
// echo to client they've connected
socket.emit('updatechat', 'SERVER', 'you have connected to General');
// echo to room 1 that a person has connected to their room
socket.broadcast.to('General').emit('updatechat', 'SERVER', username + ' has connected to this room');
socket.emit('updaterooms', rooms, 'General');
});
(client-side part of sending username to server, it looks like 'var username = "User";' for a particular user)
Yii::$app->view->registerJs('var username = "'.$user->identity->username.'";', yii\web\View::POS_HEAD);
(connect function)
chat.on('connect', function(){
// call the server-side function 'adduser' and send one parameter (value of prompt)
chat.emit('adduser', username);
});
SO the question is: can user change (for example, through chrome development tools) his username in line 'var username ...' and connect to chat under the different name?
P.S. this particular situation is just an example, obviously, changed nicknames in chat are not more than a simple joke, but similar situations can appear in other projects...
Supposing your variables are protected in closures and that it's not trivial to change them by typing username='root' in the console, a user could simply replace the whole code.
Everything that happens client side is totally out of your control.
The good news is that they are solutions not involving a duplicate authentication. Supposing you already authenticate the user in your express application, you can get the session and the user from that.
See how I do it in my chat server :
var sessionSockets = new SessionSockets(io, sessionStore, cookieParser);
sessionSockets.on('connection', function (err, socket, session) {
function die(err){
console.log('ERR', err);
socket.emit('error', err.toString());
socket.disconnect();
}
if (! (session && session.passport && session.passport.user && session.room)) return die ('invalid session');
var userId = session.passport.user;
if (!userId) return die('no authenticated user in session');
... handling socket for authenticated user
});
Basically, it uses the session.socket.io module to propagate the session from the standard http requests (authenticated using passport) to the socket.io connection. And everything that isn't supposed to be provided by the user is taken from the session/db/server.