munafio / chatify

Laravel's #1 one-to-one chatting system package, helps you add a complete real-time chatting system to your new/existing Laravel application with only one command.
https://chatify.munafio.com
MIT License
2.24k stars 479 forks source link

API Usage - Simple HTML + JS page. #306

Closed Tech-Dex closed 1 year ago

Tech-Dex commented 1 year ago

Hello. I am trying to use the APIs in order to be able to use any client side ( react, react-native, jquery, etc ). I've done the setup for chatify, edit the middleware to use auth:sanctum. I am able to get a response from /chat/auth like this

{"auth":"xxxxxx","channel_data":"{\"user_id\":381,\"user_info\":{\"name\":null}}"}

Yes, I know that name=null, I have username in users table instead of user, that is not the problem. I've edited the vendor manually to use username at a point.

The code for html+js

<!DOCTYPE html>
<head>
    <title>Pusher Test</title>
    <script src="https://js.pusher.com/8.2.0/pusher.min.js"></script>
    <script>

      // Enable pusher logging - don't include this in production
      Pusher.logToConsole = true;

      var pusher = new Pusher("xxxxxxxx", {
        cluster: 'us2',
        forceTLS: true,
        channelAuthorization: {
          endpoint: "http://localhost:8000/chatify/api/chat/auth",
          transport: "ajax",
          params: {
            'socket_id': '123.456',
            'channel_name': 'private-chatify'
          },
          headers: {
            'Authorization': 'Bearer 5|4VOLwQsCeGZVm05plDYmNmhAAKOmpB4yGs4kw0j7',
          },
        }
      });

      var channel = pusher.subscribe('private-chatify.1');
      channel.bind('my-event', function (data) {
        alert(JSON.stringify(data));
      });
    </script>
</head>
<body>
<h1>Pusher Test</h1>
<p>
    Try publishing an event to channel <code>my-channel</code>
    with event name <code>my-event</code>.
</p>
</body>

The pusher library does an API requests and returns 200, with the response presented before. My error:

Pusher :  : ["Event recd",{"event":"pusher:error","data":{"code":null,"message":"Invalid signature: Expected HMAC SHA256 hex digest of 54879.19617339:private-chatify:{\"user_id\":381,\"user_info\":{\"name\":null}}, but got dcd0f6b661505d6a0a90f2cc1026b637db499ef9aafef9b31ffa7145fa465025"}}]
munafio commented 1 year ago

@Tech-Dex please check the following:

Tech-Dex commented 1 year ago

key, secret, app_id and cluster are properly set via env so no issues on that side. I've manually checked those values.

        'pusher' => [
            'driver' => 'pusher',
            'key' => env('PUSHER_APP_KEY'),
            'secret' => env('PUSHER_APP_SECRET'),
            'app_id' => env('PUSHER_APP_ID'),
            'options' => [
                'cluster' => env('PUSHER_APP_CLUSTER'),
                'useTLS' => true,
            ],
        ],

Ensure the Data Being Sent is Correct - From what I've read in their documentation content-type html/text + "auth":"","channel_data:{} is the right format.

I am unable to find any typos

No middleware used. The response is coming as expected : Content-Type: text/html; charset=UTF-8 ; I know that the dev tools shows it as json, but the headers are text/html image

This is on local, so no timestamp issue. That number seems to be a socket_id that is not like the one that I've sent in my request ( from initial message 'socket_id': '123.456',. That's what I have in Pusher Error Logs interface:

image

image

Tech-Dex commented 1 year ago

Hello updates for this one. It seems like Pusher JS was the problem. It is not really well documented so I'll leave here my solution, maybe someone will be happy to find that. You have to use the customHandler in order to be able to do that validation from a client side like React/Vue/Flutter/RN.

        async function fetchAuth(socketId, channelName) {
            try {
                const myHeaders = new Headers();
                myHeaders.append("Accept", "application/json");
                myHeaders.append("Content-Type", "application/json");
                myHeaders.append("Authorization", "Bearer my-token-from-login-here");

                const raw = JSON.stringify({
                    "socket_id": socketId,
                    "channel_name": channelName
                });

                const requestOptions = {
                    method: 'POST',
                    headers: myHeaders,
                    body: raw,
                    redirect: 'follow'
                };

                const response = await fetch("http://localhost:8000/chatify/api/chat/auth", requestOptions);
                const result = await response.json();

                return result
            } catch (error) {
                console.error('error', error);
            }
        }

        const pusher = new Pusher("fff37687037ad4a26501", {
            cluster: 'us2',
            forceTLS: true,
            channelAuthorization: {
                customHandler : async ({socketId, channelName}, callback) => {
                    const data = await fetchAuth(socketId, channelName);
                    callback(null, {
                        "auth": data["auth"],
                        "channel_data": data["channel_data"]
                    })
                },
            }
        });