Server Side JS SDK fails to flag user - getstream-io

I have a webhook that runs on message save and message update. I do some basic bad word filtering. I can update the message to filter out bad words. However, when I attempt to flag the message, I get an error. Has anyone seen anything like this? How have you worked around it?
The code:
client.flagMessage(message.id).then(r => console.log('flagged message', r))
I have verified that client works as I am able to update the message with client in the same Promise.all() call.
The error:
Flag failed with error: "either user or user_id must be provided when using server side auth."
Version:
"stream-chat": "^1.7.4"
The docs:
https://getstream.io/chat/docs_rest/#flag
https://github.com/GetStream/stream-chat-js/blob/master/src/client.js#L1227
It seems very similar to this closed issue:
https://github.com/GetStream/stream-chat-js/issues/113

This might not be a proper answer but definitely is a resolution for your problem.
If setUser is called on the client then server will be able to get the flagging user from the JWT (client side auth) but in server side auth, there is no user passed to server so you get the expected error message.
You check REST docs and as seen, server supports it where JS client lacks this server side support. This a missing feature bug from JS client. It's reported to be extended as soon as possible.

Related

RangeError [ERR_HTTP_INVALID_STATUS_CODE]: Invalid status code: undefined Forge App

I am building a 3-legged OAuth Forge application using Visual Studio Code and Node.js. Once I start debugging, the server is listening on http://localhost:3000, but after signing in, I am getting this error message and cannot see Forge Viewer. What is the reason?
Error screenshot
The error you're seeing is most likely a "side effect" of another issue in your code. It looks like the server code is failing for some reason, and when the server tries to send back the generic error response to the client, it does not know what status code to include in the response.
Consider stepping through the authentication code in your Node.js server to narrow down the actual code that's causing the issue.

socket.io client doesn't set sid in requests

I'm trying to build a nodejs script to communicate with a socket.io server.
const io = require('socket.io-client');
const socket = io('http://192.168.144.249');
socket.on('connect', () => {
console.log('connected');
})
Using wireshark to follow traffic I can see the following:
So the browser sends me a sid, both in the response body and in the cookie.
Unfortunately, my following requests do not include this sid and I received a 400 Bad Request error:
When I try to build the same client from a browser windows I can see that this cookie is indeed set, both as cookie and as a query parameter:
I don't want to use a browser, I want to use a standalone node script. As far as I understood the parsing of the response and the inclusion of the session id should be done automatically by the socket.io-client. Am I wrong? If so, how can I intercept this event so that I can send the sid with following requests?
Am I supposed to first do a simple http request to the server, get the sid from there and then add it to the socket.io client when creating it using custom cookies or custom query parameters?
I can also see that the node standalone script is using engine.io version 4 (EIO=4 in the GET requests), while the browser is doing it with engine.io version 3, but the respose received seems to be exactly the same so I don't really think this is what is preventing my script from automatically completing the handshake with the server.
Well, I was wrong. It was indeed a protocol mismatch problem.
I was able to make my script working using socket.io-client#1.0.2. Install it with:
npm install socket.io-client#1.0.2

Why might a nodeJS API work locally but fail in production?

An API method I've been using without problems on localhost:3000/userinfo suddenly gives an "Empty Reply From Server" when I upload that same code to my web server and send a POST request to myserver.com:3000/userinfo.
Even more strange is that if the JSON returned by user info does not contain an array of objects, there is no error locally or remotely.
I don't know how much detail will be useful, and how much will just clutter this question. This one is especially strange so I'd like to approach it very generally. In other words, I don't think I'm missing a semi colon this time because the API function works perfectly when run on a local server.
So without a whole lot of detail, the only thing I can suggest here is make sure your ports are correct. You said 4200 locally but its 3000 on your server? The error you're getting also suggests ( I'm assuming cURL? ) that it couldn't connect at all to your server, which furthers my hypothesis.
Alternatively, there could be an error in your API and its "crashing" without logging anything, which would also cause an empty reply error.
Be sure to capture unhandled exceptions using process events to log out errors!
https://nodejs.org/dist/latest-v10.x/docs/api/process.html#process_process_events
process.on('uncaughtException', function (error) {
console.error("GOT UNCAUGHT EXECPTION!", error)
process.exit(1);
})

FCM XMPP: no 'success' response

I am using nodejs to implement a server application with XMPP. I am following the guide to authorize an XMPP connection. My problem is exactly when I expect a
<success xmlns="urn:ietf:params:xml:ns:xmpp-sasl"/>
when I send the server key, a SASL PLAIN authentication. It is made this way
const key = Buffer('\x00' + senderId + '#gcm.googleapis.com\x00' + serverKey).toString('base64');
const message = `<auth mechanism="PLAIN"
xmlns="urn:ietf:params:xml:ns:xmpp-sasl">${key}</auth>`;
Where senderID is that number that is in "Cloud Messaging" tag and
serverKey is one of the server keys from the "Cloud Messaging" tag. There are two server keys types: one is the "normal" and the other one is inherited; I've used both types without success.
I don't really know what I am doing wrong, or what I am missing.
The first two steps of the connection, the 'hello' and the list of mechanisms response from FCM are done. However, after this, FCM closes the connection. I suspect is related with this problem.
I would appreciate a help. Thanks.
I've contacted with the Firebase support team and they have solved my problem (thanks a lot).
The thing, with nodejs, is you have to avoid to implement the event 'end' on the socket because this seems to force to close the socket, and use the same socket. Another thing is to avoid set up the socket encoding. You can convert the buffer with another encoding though.
With all this I can mark this question as solved.

JWT Authorization Over Socket.io Connection

The fact that I haven't found an existing answer for this makes me think I'm asking the wrong question. Please feel free to (gently or otherwise) push me onto a better path if necessary.
We use a dedicated auth server, the purpose of which is to (1) given login credentials, return a JWT with a near-term exp or (2) given a JWT, according to a set of rules, issue a new JWT. A refresh, essentially.
That all works ace, until it's hacked. But for now, it's ace.
When it comes to socket.io connections to non-auth servers, however, we're shooting more than a bit from the hip. I wonder if somebody would be so kind as to evaluate this process. (I'm happy to post more code; you tell me if it's relevant).
1) initial socket.io connection results in a challenge:
this.socket.emit('authenticate'); // the challenge
this.authTimeout = setTimeout(() => {
this.socket.disconnect('unauthorized', errors);
}, TIME_TO_AUTHENTICATE); // the response kills this!
this.socket.on('authenticate', token => {
clearTimeout(this.authTimeout);
this._authenticate(token)
})
2) subsequent messages must contain a "payload" message in the form:
payload = {token: 'foo', message: 'bar'}, which token would be accepted if valid or returned if invalid.
In addition, the resource server sends its own periodic heartbeat, which must be acknowledged by heartbeat {token}.
My question, thus is: this seems too easy; am I cutting corners somewhere? Could you defeat this feeble fortification?
Just to be clear, we're looking to roll our own module here. I'm happy to look at anything existing; just haven't found anything I could begin to convince the bosses is fully baked for our needs.
Many thanks in advance.
I cannot fully analyse the method or ensure it doesn't have flaws, however I'd like to point out some things that came up to mind:
Apart from disconnecting the user in case of timeout on authentication challenge, you must ensure that the server does not send any non-public message to this user until after the authorization challenge is actually fulfilled successfully. Otherwise, there is a period until timeout where the user could receive a message without being authenticated.
I assume that you are also disconnecting the socket if token is invalid (or someway preventing non-public message to be sent).
This article is about authenticating socket.io communications using JWT. It is from 2014 so it might be a little bit out of date but I think that the core concept is still valid.
Associated with the article, there is a tool built specifically to authenticate socket.io connections using jwt. Even if you don't want to use it, you might want to explore its code looking for "inspiration". You can find it here: socketio-jwt.
You can see that this tool is able to use two different approaches:
An approach pretty similar to yours:
from socketio-jwt/blob/master/lib/index.js
if(options.required){
var auth_timeout = setTimeout(function () {
socket.disconnect('unauthorized');
}, options.timeout || 5000);
}
socket.on('authenticate', function (data) {
// ...
// Token validation
// Emit "authenticated" event if token is valid, the server can use
// this event as a point to send messages, once token is valid
});
A "One roundtrip" approach that basically uses query strings during handshake. And whose main drawback is that the token is exposed in the URL, so it might be logged, or getting exposed.

Resources