Allow users to subscribe to community chat topics
Build and Push Docker Images / build-and-push (push) Successful in 1m28s
Build and Push Docker Images / build-and-push (push) Successful in 1m28s
This commit is contained in:
1 parent
68c7ae67f1
commit
baaae2b850
3 files changed
+41
-3
No files matched your search
@@ -19,7 +19,8 @@ Frontend / mobile clients
|
||||
│ Socket.IO (connection token + topic token)
|
||||
▼
|
||||
Socket broker ── rooms: user/{uuid}/notifications
|
||||
▲ event/{slug}/ticket_statistics
|
||||
▲ community/user/{uuid}
|
||||
│ event/{slug}/ticket_statistics
|
||||
│ POST /publish (API key)
|
||||
Laravel backend
|
||||
```
|
||||
@@ -74,7 +75,7 @@ const socket = io("https://bram-sockets.comedykit.be", {
|
||||
});
|
||||
```
|
||||
|
||||
A user may always subscribe to `user/{their-own-id}/notifications`. Any other topic requires a topic token whose `sub` matches the connection subject and whose `topic` matches the subscription exactly.
|
||||
A user may always subscribe to `user/{their-own-id}/notifications` and `community/user/{their-own-id}`. Any other topic requires a topic token whose `sub` matches the connection subject and whose `topic` matches the subscription exactly.
|
||||
|
||||
## WebSocket API
|
||||
|
||||
|
||||
@@ -172,7 +172,7 @@ function createBroker(env = process.env) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return /^(user\/[0-9a-fA-F-]{36}\/notifications|event\/[A-Za-z0-9_-]+\/ticket_statistics)$/.test(topic);
|
||||
return /^(user\/[0-9a-fA-F-]{36}\/notifications|community\/user\/[0-9a-fA-F-]{36}|event\/[A-Za-z0-9_-]+\/ticket_statistics)$/.test(topic);
|
||||
}
|
||||
|
||||
function normalizeSubscription(payload) {
|
||||
@@ -205,6 +205,12 @@ function createBroker(env = process.env) {
|
||||
return userTopic[1] === socket.data.auth.sub;
|
||||
}
|
||||
|
||||
const communityUserTopic = topic.match(/^community\/user\/([^/]+)$/);
|
||||
|
||||
if (communityUserTopic) {
|
||||
return communityUserTopic[1] === socket.data.auth.sub;
|
||||
}
|
||||
|
||||
const verifiedTopicToken = verifyToken(topicToken, 'topic');
|
||||
|
||||
if (!verifiedTopicToken) {
|
||||
|
||||
@@ -203,6 +203,37 @@ test('socket broker', async t => {
|
||||
socket.close();
|
||||
});
|
||||
|
||||
await t.test('a user can subscribe to their own community topic only', async () => {
|
||||
const userId = randomUuid();
|
||||
const otherUserId = randomUuid();
|
||||
const socket = connect({ token: connectToken(userId) });
|
||||
|
||||
await once(socket, 'connect');
|
||||
|
||||
socket.emit('subscribe', `community/user/${userId}`);
|
||||
const subscribed = await once(socket, 'subscribed');
|
||||
assert.equal(subscribed.topic, `community/user/${userId}`);
|
||||
|
||||
socket.emit('subscribe', `community/user/${otherUserId}`);
|
||||
const error = await once(socket, 'error');
|
||||
assert.equal(error.code, 'FORBIDDEN_TOPIC');
|
||||
|
||||
socket.close();
|
||||
});
|
||||
|
||||
await t.test('invalid community topics are rejected', async () => {
|
||||
const userId = randomUuid();
|
||||
const socket = connect({ token: connectToken(userId) });
|
||||
|
||||
await once(socket, 'connect');
|
||||
|
||||
socket.emit('subscribe', 'community/user/not-a-uuid');
|
||||
const error = await once(socket, 'error');
|
||||
assert.equal(error.code, 'INVALID_TOPIC');
|
||||
|
||||
socket.close();
|
||||
});
|
||||
|
||||
await t.test('event stats require a matching topic token', async () => {
|
||||
const userId = randomUuid();
|
||||
const eventTopic = 'event/test-event/ticket_statistics';
|
||||
|
||||
Reference in new issue
Block a user