PromucFlow_constructor/app/client/packages/rts/src/controllers/socket.ts
Ilia d6f249b42d
chore: add blank line eslint rule (#36369)
## Description
Added ESLint rule to force blank lines between statements. 


Fixes #`Issue Number`  
_or_  
Fixes `Issue URL`
> [!WARNING]  
> _If no issue exists, please create an issue first, and check with the
maintainers if the issue is valid._

## Automation

/ok-to-test tags="@tag.All"

### 🔍 Cypress test results
<!-- This is an auto-generated comment: Cypress test results  -->
> [!CAUTION]
> 🔴 🔴 🔴 Some tests have failed.
> Workflow run:
<https://github.com/appsmithorg/appsmith/actions/runs/10924926728>
> Commit: 34f57714a1575ee04e94e03cbcaf95e57a96c86c
> <a
href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=10924926728&attempt=1&selectiontype=test&testsstatus=failed&specsstatus=fail"
target="_blank">Cypress dashboard</a>.
> Tags: @tag.All
> Spec: 
> The following are new failures, please fix them before merging the PR:
<ol>
> <li>cypress/e2e/Regression/ClientSide/Anvil/AnvilModal_spec.ts
>
<li>cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilButtonWidgetSnapshot_spec.ts
>
<li>cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilCheckboxGroupWidgetSnapshot_spec.ts
>
<li>cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilCurrencyInputWidgetSnapshot_spec.ts
>
<li>cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilIconButtonWidgetSnapshot_spec.ts
>
<li>cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilInlineButtonWidgetSnapshot_spec.ts
>
<li>cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilInputWidgetSnapshot_spec.ts
>
<li>cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilParagraphWidgetSnapshot_spec.ts
>
<li>cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilPhoneInputWidgetSnapshot_spec.ts
>
<li>cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilStatsWidgetSnapshot_spec.ts
>
<li>cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilSwitchGroupWidgetSnapshot_spec.ts
>
<li>cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilSwitchWidgetSnapshot_spec.ts
>
<li>cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilTableWidgetSnapshot_spec.ts
>
<li>cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilToolbarButtonWidgetSnapshot_spec.ts
>
<li>cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilZoneSectionWidgetSnapshot_spec.ts</ol>
> <a
href="https://internal.appsmith.com/app/cypress-dashboard/identified-flaky-tests-65890b3c81d7400d08fa9ee3?branch=master"
target="_blank">List of identified flaky tests</a>.
> <hr>Wed, 18 Sep 2024 16:33:36 UTC
<!-- end of auto-generated comment: Cypress test results  -->


## Communication
Should the DevRel and Marketing teams inform users about this change?
- [ ] Yes
- [ ] No

---------

Co-authored-by: Valera Melnikov <valera@appsmith.com>
2024-09-18 19:35:28 +03:00

137 lines
3.7 KiB
TypeScript

import type { Server, Socket } from "socket.io";
import { tryAuth } from "@middlewares/socket-auth";
import {
START_EDIT_EVENT_NAME,
LEAVE_EDIT_EVENT_NAME,
MOUSE_POINTER_EVENT_NAME,
PAGE_EDIT_NAMESPACE,
PAGE_ROOM_PREFIX,
EDITORS_EVENT_NAME,
} from "@constants/socket";
import type { Policy, MousePointerEvent } from "@utils/models";
import { AppUser, CurrentEditorsEvent } from "@utils/models";
function subscribeToEditEvents(socket: Socket, appRoomPrefix: string) {
socket.on(START_EDIT_EVENT_NAME, (resourceId) => {
if (socket.data.email) {
// user is authenticated, join the room now
joinEditRoom(socket, resourceId, appRoomPrefix);
} else {
// user not authenticated yet, save the resource id and room prefix to join later after auth
socket.data.pendingRoomId = resourceId;
socket.data.pendingRoomPrefix = appRoomPrefix;
}
});
socket.on(LEAVE_EDIT_EVENT_NAME, (resourceId) => {
const roomName = appRoomPrefix + resourceId;
socket.leave(roomName); // remove this socket from room
});
}
async function onAppSocketConnected(socket: Socket) {
const isAuthenticated = await tryAuthAndJoinPendingRoom(socket);
if (isAuthenticated) {
socket.join("email:" + socket.data.email);
}
}
async function onPageSocketConnected(socket: Socket, socketIo: Server) {
const isAuthenticated = await tryAuthAndJoinPendingRoom(socket);
if (isAuthenticated) {
socket.on(MOUSE_POINTER_EVENT_NAME, (event: MousePointerEvent) => {
event.user = new AppUser(socket.data.name, socket.data.email);
event.socketId = socket.id;
socketIo
.of(PAGE_EDIT_NAMESPACE)
.to(PAGE_ROOM_PREFIX + event.pageId)
.emit(MOUSE_POINTER_EVENT_NAME, event);
});
}
}
async function tryAuthAndJoinPendingRoom(socket: Socket) {
const isAuthenticated = await tryAuth(socket);
if (socket.data.pendingRoomId) {
// an appId or pageId is pending for this socket, join now
joinEditRoom(
socket,
socket.data.pendingRoomId,
socket.data.pendingRoomPrefix,
);
}
return isAuthenticated;
}
function joinEditRoom(socket: Socket, roomId: string, roomPrefix: string) {
// remove this socket from any other rooms with roomPrefix
if (socket.rooms) {
socket.rooms.forEach((roomName) => {
if (roomName.startsWith(roomPrefix)) {
socket.leave(roomName);
}
});
}
// add this socket to room with application id
const roomName = roomPrefix + roomId;
socket.join(roomName);
}
function findPolicyEmails(policies: Policy[], permission: string): string[] {
const emails: string[] = [];
for (const policy of policies) {
if (policy.permission === permission) {
for (const email of policy.users) {
emails.push(email);
}
break;
}
}
return emails;
}
function sendCurrentUsers(socketIo, roomName: string, roomPrefix: string) {
if (roomName.startsWith(roomPrefix)) {
socketIo
.in(roomName)
.fetchSockets()
.then((sockets) => {
const onlineUsernames = new Set<string>();
const onlineUsers = new Array<AppUser>();
if (sockets) {
sockets.forEach((s) => {
if (!onlineUsernames.has(s.data.email)) {
onlineUsers.push(new AppUser(s.data.name, s.data.email));
}
onlineUsernames.add(s.data.email);
});
}
const resourceId = roomName.replace(roomPrefix, ""); // get resourceId from room name by removing the prefix
const response = new CurrentEditorsEvent(resourceId, onlineUsers);
socketIo.to(roomName).emit(EDITORS_EVENT_NAME, response);
});
}
}
export {
subscribeToEditEvents,
onAppSocketConnected,
onPageSocketConnected,
sendCurrentUsers,
findPolicyEmails,
};