Skip to content

Commit

Permalink
Made websocket presence code more DRY
Browse files Browse the repository at this point in the history
  • Loading branch information
miguel-lansdorf committed Apr 25, 2023
1 parent d782ad4 commit 533df29
Showing 1 changed file with 58 additions and 70 deletions.
128 changes: 58 additions & 70 deletions api/src/utils/websocket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ enum CLIENT_CHANNELS {
DASHBOARD_CONTENT_END_EDIT = 'DASHBOARD_CONTENT_END_EDIT',
}

type SOCKET_AUTH = { auth_id: string; auth_name: string; auth_type: 'NO_AUTH' | 'ACCOUNT' | 'APIKEY' };
type PRESENCE = Map<string, Record<string, { name: string; connections: Set<string> }>>;
const dashboardEditPresence: PRESENCE = new Map();
const dashboardContentEditPresence: PRESENCE = new Map();

let socket: Server;

export function initWebsocket(server: http.Server, origin: string[]) {
Expand All @@ -37,22 +42,26 @@ export function initWebsocket(server: http.Server, origin: string[]) {
let authenticated = false;
if (!AUTH_ENABLED) {
authenticated = true;
socket.handshake.auth.auth = { id: '0', name: 'NO_AUTH', type: 'NO_AUTH' };
socket.handshake.auth.auth = { auth_id: '0', auth_name: 'NO_AUTH', auth_type: 'NO_AUTH' } as SOCKET_AUTH;
}

if (!authenticated) {
const account = await AccountService.getByToken(socket.handshake.auth.account);
if (account) {
authenticated = true;
socket.handshake.auth.auth = { id: account.id, name: account.name, type: 'ACCOUNT' };
socket.handshake.auth.auth = {
auth_id: account.id,
auth_name: account.name,
auth_type: 'ACCOUNT',
} as SOCKET_AUTH;
}
}

if (!authenticated) {
const apiKey = await ApiService.verifyApiKey(socket.handshake.auth.apikey, {});
if (apiKey) {
authenticated = true;
socket.handshake.auth.auth = { id: apiKey.id, name: apiKey.name, type: 'APIKEY' };
socket.handshake.auth.auth = { auth_id: apiKey.id, auth_name: apiKey.name, auth_type: 'APIKEY' } as SOCKET_AUTH;
}
}

Expand All @@ -74,18 +83,25 @@ export function initWebsocket(server: http.Server, origin: string[]) {

client.on('disconnect', () => {
logger.info(`user disconnected from websocket with id: ${client.id}`);
removeDashboardEditPresence(
client.handshake.auth.auth.id,
client.handshake.auth.auth.type,
client.handshake.auth.auth.name,
const dashboardEditInfos = removePresence(
dashboardEditPresence,
client.handshake.auth.auth as SOCKET_AUTH,
client.id,
);
removeDashboardContentEditPresence(
client.handshake.auth.auth.id,
client.handshake.auth.auth.type,
client.handshake.auth.auth.name,
const dashboardContentEditInfos = removePresence(
dashboardContentEditPresence,
client.handshake.auth.auth as SOCKET_AUTH,
client.id,
);
for (const data of dashboardEditInfos) {
socketEmit(channelBuilder(SERVER_CHANNELS.DASHBOARD_EDIT_PRESENCE, [data.id]), parsePresence(data.info));
}
for (const data of dashboardContentEditInfos) {
socketEmit(
channelBuilder(SERVER_CHANNELS.DASHBOARD_CONTENT_EDIT_PRESENCE, [data.id]),
parsePresence(data.info),
);
}
});

client.on(CLIENT_CHANNELS.DASHBOARD_GET_EDIT_PRESENCE, (data: { id: string }) => {
Expand All @@ -94,25 +110,25 @@ export function initWebsocket(server: http.Server, origin: string[]) {
});

client.on(CLIENT_CHANNELS.DASHBOARD_START_EDIT, (data: { id: string }) => {
updateDashboardEditPresence(
const { id, info } = updatePresence(
dashboardEditPresence,
data.id,
client.handshake.auth.auth.id,
client.handshake.auth.auth.type,
client.handshake.auth.auth.name,
client.handshake.auth.auth as SOCKET_AUTH,
client.id,
'ADD',
);
socketEmit(channelBuilder(SERVER_CHANNELS.DASHBOARD_EDIT_PRESENCE, [id]), parsePresence(info));
});

client.on(CLIENT_CHANNELS.DASHBOARD_END_EDIT, (data: { id: string }) => {
updateDashboardEditPresence(
const { id, info } = updatePresence(
dashboardEditPresence,
data.id,
client.handshake.auth.auth.id,
client.handshake.auth.auth.type,
client.handshake.auth.auth.name,
client.handshake.auth.auth as SOCKET_AUTH,
client.id,
'REMOVE',
);
socketEmit(channelBuilder(SERVER_CHANNELS.DASHBOARD_EDIT_PRESENCE, [id]), parsePresence(info));
});

client.on(CLIENT_CHANNELS.DASHBOARD_CONTENT_GET_EDIT_PRESENCE, (data: { id: string }) => {
Expand All @@ -121,25 +137,25 @@ export function initWebsocket(server: http.Server, origin: string[]) {
});

client.on(CLIENT_CHANNELS.DASHBOARD_CONTENT_START_EDIT, (data: { id: string }) => {
updateDashboardContentEditPresence(
const { id, info } = updatePresence(
dashboardContentEditPresence,
data.id,
client.handshake.auth.auth.id,
client.handshake.auth.auth.type,
client.handshake.auth.auth.name,
client.handshake.auth.auth as SOCKET_AUTH,
client.id,
'ADD',
);
socketEmit(channelBuilder(SERVER_CHANNELS.DASHBOARD_CONTENT_EDIT_PRESENCE, [id]), parsePresence(info));
});

client.on(CLIENT_CHANNELS.DASHBOARD_CONTENT_END_EDIT, (data: { id: string }) => {
updateDashboardContentEditPresence(
const { id, info } = updatePresence(
dashboardContentEditPresence,
data.id,
client.handshake.auth.auth.id,
client.handshake.auth.auth.type,
client.handshake.auth.auth.name,
client.handshake.auth.auth as SOCKET_AUTH,
client.id,
'REMOVE',
);
socketEmit(channelBuilder(SERVER_CHANNELS.DASHBOARD_CONTENT_EDIT_PRESENCE, [id]), parsePresence(info));
});
});
}
Expand All @@ -166,16 +182,14 @@ function parsePresence(presence: Record<string, { name: string; connections: Set
return result;
}

const dashboardEditPresence = new Map<string, Record<string, { name: string; connections: Set<string> }>>();
function updateDashboardEditPresence(
function updatePresence(
presence: PRESENCE,
id: string,
auth_id: string,
auth_type: string,
auth_name: string,
{ auth_id, auth_type, auth_name }: SOCKET_AUTH,
client_id: string,
type: 'ADD' | 'REMOVE',
) {
const info = dashboardEditPresence.get(id) ?? {};
): { id: string; info: Record<string, { name: string; connections: Set<string> }> } {
const info = presence.get(id) ?? {};
const authKey = getPresenceAuthKey(auth_id, auth_type);
if (type === 'ADD') {
info[authKey] = info[authKey] ?? { name: auth_name, connections: new Set() };
Expand All @@ -188,44 +202,18 @@ function updateDashboardEditPresence(
}
}
}
dashboardEditPresence.set(id, info);
socketEmit(channelBuilder(SERVER_CHANNELS.DASHBOARD_EDIT_PRESENCE, [id]), parsePresence(info));
presence.set(id, info);
return { id, info };
}

const dashboardContentEditPresence = new Map<string, Record<string, { name: string; connections: Set<string> }>>();
function updateDashboardContentEditPresence(
id: string,
auth_id: string,
auth_type: string,
auth_name: string,
function removePresence(
presence: PRESENCE,
{ auth_id, auth_type, auth_name }: SOCKET_AUTH,
client_id: string,
type: 'ADD' | 'REMOVE',
) {
const info = dashboardContentEditPresence.get(id) ?? {};
const authKey = getPresenceAuthKey(auth_id, auth_type);
if (type === 'ADD') {
info[authKey] = info[authKey] ?? { name: auth_name, connections: new Set() };
info[authKey].connections.add(client_id);
} else {
if (info[authKey]) {
info[authKey].connections.delete(client_id);
if (info[authKey].connections.size === 0) {
delete info[authKey];
}
}
}
dashboardContentEditPresence.set(id, info);
socketEmit(channelBuilder(SERVER_CHANNELS.DASHBOARD_CONTENT_EDIT_PRESENCE, [id]), parsePresence(info));
}

function removeDashboardEditPresence(auth_id: string, auth_type: string, auth_name: string, client_id: string) {
for (const [id, _info] of dashboardEditPresence) {
updateDashboardEditPresence(id, auth_id, auth_type, auth_name, client_id, 'REMOVE');
}
}

function removeDashboardContentEditPresence(auth_id: string, auth_type: string, auth_name: string, client_id: string) {
for (const [id, _info] of dashboardContentEditPresence) {
updateDashboardContentEditPresence(id, auth_id, auth_type, auth_name, client_id, 'REMOVE');
): { id: string; info: Record<string, { name: string; connections: Set<string> }> }[] {
const infos: { id: string; info: Record<string, { name: string; connections: Set<string> }> }[] = [];
for (const [id, _info] of presence) {
infos.push(updatePresence(presence, id, { auth_id, auth_type, auth_name }, client_id, 'REMOVE'));
}
return infos;
}

0 comments on commit 533df29

Please sign in to comment.