mirror of
https://github.com/HeyPuter/puter.git
synced 2026-10-12 14:50:39 +00:00
refactor: carry the revocation on outer.* instead of outer.pubsub.*
Eviction runs through `io.in(room).disconnectSockets()`, which goes via the socket.io Redis adapter a cluster shares, so one node handling the event disconnects that user on every node in it. Fanning out to siblings had each of them repeat the same cluster-wide disconnect. The adapter's Redis is per-cluster, so peer clusters still need the hop -- `outer.*` reaches them and skips the sibling fan-out. The local `auth.sessions.revoked` goes with it: `outer.*` fires on the emitting node too, and nothing else subscribed.
This commit is contained in:
1 parent
155341ee6c
commit
8cf07db422
4 files changed
+16
-20
No files matched your search
@@ -706,10 +706,13 @@ export type EventMap = {
|
||||
* Sessions were revoked for a user. Anything holding one of them open — a
|
||||
* live socket, say — should drop it: `revoked_at` is otherwise only read on
|
||||
* the next handshake.
|
||||
*
|
||||
* `outer.*` rather than `outer.pubsub.*` on purpose: the eviction runs
|
||||
* through the socket.io Redis adapter a cluster shares, so one node
|
||||
* disconnecting covers every node in it — fanning out to siblings would
|
||||
* just have each of them repeat the same cluster-wide disconnect.
|
||||
*/
|
||||
'auth.sessions.revoked': { user_id: number; session_uids: string[] };
|
||||
/** The same revocation, carried to sibling nodes and peer clusters. */
|
||||
'outer.pubsub.auth.sessions.revoked': {
|
||||
'outer.auth.sessions.revoked': {
|
||||
user_id: number;
|
||||
session_uids: string[];
|
||||
};
|
||||
|
||||
@@ -732,13 +732,8 @@ export class AuthService extends PuterService {
|
||||
user_id: revoked.userId,
|
||||
session_uids: revoked.uuids,
|
||||
};
|
||||
this.clients.event?.emit('auth.sessions.revoked', payload, {});
|
||||
// Whoever holds the socket may not be whoever revoked the session.
|
||||
this.clients.event?.emit(
|
||||
'outer.pubsub.auth.sessions.revoked',
|
||||
payload,
|
||||
{},
|
||||
);
|
||||
this.clients.event?.emit('outer.auth.sessions.revoked', payload, {});
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -671,10 +671,10 @@ describe('SocketService (live socket.io)', () => {
|
||||
const socket = await connect({ auth_token: `Bearer ${evicted.token}` });
|
||||
expect(socket.connected).toBe(true);
|
||||
|
||||
// As the fan-out delivers it: the node holding this socket is not
|
||||
// As a peer cluster delivers it: the node holding this socket is not
|
||||
// the one that revoked the session.
|
||||
server.clients.event.emit(
|
||||
'outer.pubsub.auth.sessions.revoked',
|
||||
'outer.auth.sessions.revoked',
|
||||
{ user_id: row!.id, session_uids: ['whatever'] },
|
||||
{},
|
||||
);
|
||||
|
||||
@@ -834,19 +834,17 @@ export class SocketService extends PuterService {
|
||||
},
|
||||
);
|
||||
|
||||
// Both channels: the local one for the node that did the revoking,
|
||||
// the fanned-out one for every other node holding its sockets.
|
||||
for (const key of [
|
||||
'auth.sessions.revoked',
|
||||
'outer.pubsub.auth.sessions.revoked',
|
||||
] as const) {
|
||||
this.clients.event.on(key, (_key: string, data: unknown) => {
|
||||
// Fires on this node and carries to peer clusters; the adapter
|
||||
// reaches the rest of this one.
|
||||
this.clients.event.on(
|
||||
'outer.auth.sessions.revoked',
|
||||
(_key: string, data: unknown) => {
|
||||
const { user_id } = data as { user_id: number };
|
||||
this.#evictUserSockets(user_id).catch((err: unknown) => {
|
||||
console.error('[socket] session eviction failed', err);
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
this.clients.event.on(
|
||||
'auth.access-token.revoked',
|
||||
|
||||
Reference in new issue
Block a user