From 0b481794159f04df013b8a19770ff2f2b76b84ea Mon Sep 17 00:00:00 2001 From: SamTV12345 <40429738+samtv12345@users.noreply.github.com> Date: Sun, 14 Jan 2024 11:43:56 +0100 Subject: [PATCH] Added changes from other branch --- src/node/handler/PadMessageHandler.js | 79 +++--- src/node/hooks/express/socketio.js | 77 +++-- src/package-lock.json | 387 ++++++++++++++++++-------- src/package.json | 5 +- src/static/js/collab_client.js | 3 +- src/static/js/pad.js | 2 +- src/static/js/socketio.js | 2 +- src/static/js/timeslider.js | 2 +- src/templates/pad.html | 25 +- src/tests/backend/specs/socketio.js | 2 +- 10 files changed, 398 insertions(+), 186 deletions(-) diff --git a/src/node/handler/PadMessageHandler.js b/src/node/handler/PadMessageHandler.js index 2cfdcfc1a..b5c069230 100644 --- a/src/node/handler/PadMessageHandler.js +++ b/src/node/handler/PadMessageHandler.js @@ -39,7 +39,7 @@ const stats = require('../stats'); const assert = require('assert').strict; const {RateLimiterMemory} = require('rate-limiter-flexible'); const webaccess = require('../hooks/express/webaccess'); -const { checkValidRev } = require('../utils/checkValidRev'); +const {checkValidRev} = require('../utils/checkValidRev'); let rateLimiter; let socketio = null; @@ -83,7 +83,7 @@ exports.socketio = () => { const sessioninfos = {}; exports.sessioninfos = sessioninfos; -stats.gauge('totalUsers', () => socketio ? Object.keys(socketio.sockets.sockets).length : 0); +stats.gauge('totalUsers', () => socketio.sockets.size); stats.gauge('activePads', () => { const padIds = new Set(); for (const {padId} of Object.values(sessioninfos)) { @@ -155,13 +155,13 @@ exports.handleConnect = (socket) => { * Kicks all sessions from a pad */ exports.kickSessionsFromPad = (padID) => { - if (typeof socketio.sockets.clients !== 'function') return; + if (typeof socketio.sockets !== 'object') return; // skip if there is nobody on this pad if (_getRoomSockets(padID).length === 0) return; // disconnect everyone from this pad - socketio.sockets.in(padID).json.send({disconnect: 'deleted'}); + socketio.in(padID).emit('message', {disconnect: 'deleted'}); }; /** @@ -177,13 +177,13 @@ exports.handleDisconnect = async (socket) => { const {session: {user} = {}} = socket.client.request; /* eslint-disable prefer-template -- it doesn't support breaking across multiple lines */ accessLogger.info('[LEAVE]' + - ` pad:${session.padId}` + - ` socket:${socket.id}` + - ` IP:${settings.disableIPlogging ? 'ANONYMOUS' : socket.request.ip}` + - ` authorID:${session.author}` + - (user && user.username ? ` username:${user.username}` : '')); + ` pad:${session.padId}` + + ` socket:${socket.id}` + + ` IP:${settings.disableIPlogging ? 'ANONYMOUS' : socket.request.ip}` + + ` authorID:${session.author}` + + (user && user.username ? ` username:${user.username}` : '')); /* eslint-enable prefer-template */ - socket.broadcast.to(session.padId).json.send({ + socket.broadcast.to(session.padId).emit('message', { type: 'COLLABROOM', data: { type: 'USER_LEAVE', @@ -216,8 +216,8 @@ exports.handleMessage = async (socket, message) => { messageLogger.warn(`Rate limited IP ${socket.request.ip}. To reduce the amount of rate ` + 'limiting that happens edit the rateLimit values in settings.json'); stats.meter('rateLimited').mark(); - socket.json.send({disconnect: 'rateLimited'}); - throw err; + socket.emit('message', {disconnect: 'rateLimited'}); + return; } } @@ -267,11 +267,12 @@ exports.handleMessage = async (socket, message) => { const {accessStatus, authorID} = await securityManager.checkAccess(auth.padID, auth.sessionID, auth.token, user); if (accessStatus !== 'grant') { - socket.json.send({accessStatus}); + // Access denied. Send the reason to the user. + socket.emit('message', {accessStatus}); throw new Error('access denied'); } if (thisSession.author != null && thisSession.author !== authorID) { - socket.json.send({disconnect: 'rejected'}); + socket.emit('message', {disconnect: 'rejected'}); throw new Error([ 'Author ID changed mid-session. Bad or missing token or sessionID?', `socket:${socket.id}`, @@ -393,10 +394,10 @@ exports.handleCustomObjectMessage = (msg, sessionID) => { if (msg.data.type === 'CUSTOM') { if (sessionID) { // a sessionID is targeted: directly to this sessionID - socketio.sockets.socket(sessionID).json.send(msg); + socketio.to(sessionID).emit('message', msg); } else { // broadcast to all clients on this pad - socketio.sockets.in(msg.data.payload.padId).json.send(msg); + socketio.to(msg.data.payload.padId).emit('message', msg); } } }; @@ -416,7 +417,7 @@ exports.handleCustomMessage = (padID, msgString) => { time, }, }; - socketio.sockets.in(padID).json.send(msg); + socketio.in(padID).emit('message', msg); }; /** @@ -453,7 +454,7 @@ exports.sendChatMessageToPadClients = async (mt, puId, text = null, padId = null // authorManager.getAuthorName() to resolve before saving the message to the database. const promise = pad.appendChatMessage(message); message.displayName = await authorManager.getAuthorName(message.authorId); - socketio.sockets.in(padId).json.send({ + socketio.sockets.in(padId).emit('message', { type: 'COLLABROOM', data: {type: 'CHAT_MESSAGE', message}, }); @@ -483,7 +484,7 @@ const handleGetChatMessages = async (socket, {data: {start, end}}) => { }; // send the messages back to the client - socket.json.send(infoMsg); + socket.emit('message', infoMsg); }; /** @@ -500,7 +501,7 @@ const handleSuggestUserName = (socket, message) => { _getRoomSockets(padId).forEach((socket) => { const session = sessioninfos[socket.id]; if (session && session.author === unnamedId) { - socket.json.send(message); + socket.emit('message', message); } }); }; @@ -539,7 +540,7 @@ const handleUserInfoUpdate = async (socket, {data: {userInfo: {name, colorId}}}) }; // Send the other clients on the pad the update message - socket.broadcast.to(padId).json.send(infoMsg); + socket.to(padId).emit('message', infoMsg); // Block until the authorManager has stored the new attributes. await p; @@ -654,12 +655,12 @@ const handleUserChanges = async (socket, message) => { // The client assumes that ACCEPT_COMMIT and NEW_CHANGES messages arrive in order. Make sure we // have already sent any previous ACCEPT_COMMIT and NEW_CHANGES messages. assert.equal(thisSession.rev, r); - socket.json.send({type: 'COLLABROOM', data: {type: 'ACCEPT_COMMIT', newRev}}); + socket.emit('message', {type: 'COLLABROOM', data: {type: 'ACCEPT_COMMIT', newRev}}); thisSession.rev = newRev; if (newRev !== r) thisSession.time = await pad.getRevisionDate(newRev); await exports.updatePadClients(pad); } catch (err) { - socket.json.send({disconnect: 'badChangeset'}); + socket.emit('message', {disconnect: 'badChangeset'}); stats.meter('failedChangesets').mark(); messageLogger.warn(`Failed to apply USER_CHANGES from author ${thisSession.author} ` + `(socket ${socket.id}) on pad ${thisSession.padId}: ${err.stack || err}`); @@ -716,7 +717,7 @@ exports.updatePadClients = async (pad) => { }, }; try { - socket.json.send(msg); + socket.emit('message', msg); } catch (err) { messageLogger.error(`Failed to notify user of new revision: ${err.stack || err}`); return; @@ -833,7 +834,7 @@ const handleClientReady = async (socket, message) => { // fix user's counter, works on page refresh or if user closes browser window and then rejoins sessioninfos[otherSocket.id] = {}; otherSocket.leave(sessionInfo.padId); - otherSocket.json.send({disconnect: 'userdup'}); + otherSocket.emit('message', {disconnect: 'userdup'}); } } @@ -899,7 +900,7 @@ const handleClientReady = async (socket, message) => { apool: forWire.pool, author: changesets[r].author, currentTime: changesets[r].timestamp}}; - socket.json.send(wireMsg); + socket.emit('message', wireMsg); } if (startNum === endNum) { @@ -907,7 +908,7 @@ const handleClientReady = async (socket, message) => { data: {type: 'CLIENT_RECONNECT', noChanges: true, newRev: pad.getHeadRevisionNumber()}}; - socket.json.send(Msg); + socket.emit('message', Msg); } } else { // This is a normal first connect @@ -921,7 +922,7 @@ const handleClientReady = async (socket, message) => { atext.attribs = attribsForWire.translated; } catch (e) { messageLogger.error(e.stack || e); - socket.json.send({disconnect: 'corruptPad'}); // pull the brakes + socket.emit('message', {disconnect: 'corruptPad'}); // pull the brakes throw new Error('corrupt pad'); } @@ -1005,14 +1006,14 @@ const handleClientReady = async (socket, message) => { socket.join(sessionInfo.padId); // Send the clientVars to the Client - socket.json.send({type: 'CLIENT_VARS', data: clientVars}); + socket.emit('message', {type: 'CLIENT_VARS', data: clientVars}); // Save the current revision in sessioninfos, should be the same as in clientVars sessionInfo.rev = pad.getHeadRevisionNumber(); } // Notify other users about this new user. - socket.broadcast.to(sessionInfo.padId).json.send({ + socket.broadcast.to(sessionInfo.padId).emit('message', { type: 'COLLABROOM', data: { type: 'USER_NEWINFO', @@ -1062,7 +1063,7 @@ const handleClientReady = async (socket, message) => { }, }; - socket.json.send(msg); + socket.emit('message', msg); })); await hooks.aCallAll('userJoin', { @@ -1088,11 +1089,10 @@ const handleChangesetRequest = async (socket, {data: {granularity, start, reques const {padId, author: authorId} = sessioninfos[socket.id]; const pad = await padManager.getPad(padId, null, authorId); const headRev = pad.getHeadRevisionNumber(); - if (start > headRev) - start = headRev; + if (start > headRev) start = headRev; const data = await getChangesetInfo(pad, start, end, granularity); data.requestID = requestID; - socket.json.send({type: 'CHANGESET_REQ', data}); + socket.emit('message', {type: 'CHANGESET_REQ', data}); }; /** @@ -1235,14 +1235,9 @@ const composePadChangesets = async (pad, startNum, endNum) => { }; const _getRoomSockets = (padID) => { - const ns = socketio.sockets; // Default namespace. - const adapter = ns.adapter; - // We could call adapter.clients(), but that method is unnecessarily asynchronous. Replicate what - // it does here, but synchronously to avoid a race condition. This code will have to change when - // we update to socket.io v3. - const room = adapter.rooms[padID]; - if (!room) return []; - return Object.keys(room.sockets).map((id) => ns.connected[id]).filter((s) => s); + if (!socketio.in(padID).engine.clientsCount === 0) return []; + const data = Object.keys(socketio.in(padID).engine.clients).map((socketId) => socketio.in(padID).engine.clients[socketId]); + return data; }; /** diff --git a/src/node/hooks/express/socketio.js b/src/node/hooks/express/socketio.js index 978ea9bac..8c921e61d 100644 --- a/src/node/hooks/express/socketio.js +++ b/src/node/hooks/express/socketio.js @@ -5,7 +5,7 @@ const express = require('../express'); const log4js = require('log4js'); const proxyaddr = require('proxy-addr'); const settings = require('../../utils/Settings'); -const socketio = require('socket.io'); +const {Server} = require('socket.io'); const socketIORouter = require('../../handler/SocketIORouter'); const hooks = require('../../../static/js/pluginfw/hooks'); const padMessageHandler = require('../../handler/PadMessageHandler'); @@ -51,35 +51,64 @@ exports.expressCreateServer = (hookName, args, cb) => { // there shouldn't be a browser that isn't compatible to all // transports in this list at once // e.g. XHR is disabled in IE by default, so in IE it should use jsonp-polling - io = new socketio.Server({ - transports: settings.socketTransportProtocols - }).listen(args.server, { - /* - * Do not set the "io" cookie. - * - * The "io" cookie is created by socket.io, and its purpose is to offer an - * handle to perform load balancing with session stickiness when the library - * falls back to long polling or below. - * - * In Etherpad's case, if an operator needs to load balance, he can use the - * "express_sid" cookie, and thus "io" is of no use. - * - * Moreover, socket.io API does not offer a way of setting the "secure" flag - * on it, and thus is a liability. - * - * Let's simply nuke "io". - * - * references: - * https://socket.io/docs/using-multiple-nodes/#Sticky-load-balancing - * https://github.com/socketio/socket.io/issues/2276#issuecomment-147184662 (not totally true, actually, see above) - */ + // io = socketio({ + // transports: settings.socketTransportProtocols, + // }).listen(args.server, { + // /* + // * Do not set the "io" cookie. + // * + // * The "io" cookie is created by socket.io, and its purpose is to offer an + // * handle to perform load balancing with session stickiness when the library + // * falls back to long polling or below. + // * + // * In Etherpad's case, if an operator needs to load balance, he can use the + // * "express_sid" cookie, and thus "io" is of no use. + // * + // * Moreover, socket.io API does not offer a way of setting the "secure" flag + // * on it, and thus is a liability. + // * + // * Let's simply nuke "io". + // * + // * references: + // * https://socket.io/docs/using-multiple-nodes/#Sticky-load-balancing + // * https://github.com/socketio/socket.io/issues/2276#issuecomment-147184662 (not totally true, actually, see above) + // */ + // cookie: false, + // maxHttpBufferSize: settings.socketIo.maxHttpBufferSize, + // }); + + const io = new Server(args.server, { + // * Do not set the "io" cookie. + // * + // * The "io" cookie is created by socket.io, and its purpose is to offer an + // * handle to perform load balancing with session stickiness when the library + // * falls back to long polling or below. + // * + // * In Etherpad's case, if an operator needs to load balance, he can use the + // * "express_sid" cookie, and thus "io" is of no use. + // * + // * Moreover, socket.io API does not offer a way of setting the "secure" flag + // * on it, and thus is a liability. + // * + // * Let's simply nuke "io". + // * + // * references: + // * https://socket.io/docs/using-multiple-nodes/#Sticky-load-balancing + // * cookie: false, + // transports: settings.socketTransportProtocols, maxHttpBufferSize: settings.socketIo.maxHttpBufferSize, }); - io.on('connect', (socket) => { + io.on('connection', (socket) => { sockets.add(socket); socketsEvents.emit('updated'); + + // https://socket.io/docs/v3/faq/index.html + const session = socket.request.session; + session.connections++; + session.save(); + socket.on('disconnect', () => { sockets.delete(socket); socketsEvents.emit('updated'); diff --git a/src/package-lock.json b/src/package-lock.json index 4c6eaf800..f063ab375 100644 --- a/src/package-lock.json +++ b/src/package-lock.json @@ -271,6 +271,24 @@ "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==", "dev": true }, + "@types/component-emitter": { + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/@types/component-emitter/-/component-emitter-1.2.14.tgz", + "integrity": "sha512-lmPil1g82wwWg/qHSxMWkSKyJGQOK+ejXeMAAWyxNtVUD0/Ycj2maL63RAqpxVfdtvTfZkRnqzB0A9ft59y69g==" + }, + "@types/cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==" + }, + "@types/cors": { + "version": "2.8.17", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz", + "integrity": "sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==", + "requires": { + "@types/node": "*" + } + }, "@types/hast": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.1.tgz", @@ -311,6 +329,14 @@ "@types/unist": "*" } }, + "@types/node": { + "version": "20.11.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.0.tgz", + "integrity": "sha512-o9bjXmDNcF7GbM4CNQpmi+TutCgap/K3w1JyKgxAjqx41zp9qlIAVFi0IhCNsJcXolEqLWhbFbEeL0PvYm4pcQ==", + "requires": { + "undici-types": "~5.26.4" + } + }, "@types/semver": { "version": "7.5.3", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.3.tgz", @@ -535,7 +561,8 @@ "after": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", - "integrity": "sha512-QbJ0NTQ/I9DI3uSJA4cbexiwQeRAfjPScqIbSjUDd9TOrcg6pTkdgziesOqxBMBzit8vFCTwrP27t13vFOORRA==" + "integrity": "sha512-QbJ0NTQ/I9DI3uSJA4cbexiwQeRAfjPScqIbSjUDd9TOrcg6pTkdgziesOqxBMBzit8vFCTwrP27t13vFOORRA==", + "dev": true }, "agent-base": { "version": "7.1.0", @@ -702,7 +729,8 @@ "arraybuffer.slice": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", - "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==" + "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==", + "dev": true }, "asap": { "version": "2.0.6", @@ -787,7 +815,8 @@ "blob": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz", - "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==" + "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==", + "dev": true }, "body-parser": { "version": "1.20.1", @@ -974,7 +1003,8 @@ "component-bind": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", - "integrity": "sha512-WZveuKPeKAG9qY+FkYDeADzdHyTYdIboXS59ixDeRJL5ZhxpqUnxSOwop4FQjMsiYm3/Or8cegVbpAHNA7pHxw==" + "integrity": "sha512-WZveuKPeKAG9qY+FkYDeADzdHyTYdIboXS59ixDeRJL5ZhxpqUnxSOwop4FQjMsiYm3/Or8cegVbpAHNA7pHxw==", + "dev": true }, "component-emitter": { "version": "1.3.0", @@ -984,7 +1014,8 @@ "component-inherit": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", - "integrity": "sha512-w+LhYREhatpVqTESyGFg3NlP6Iu0kEKUHETY9GoZP/pQyW4mHFZuFWRUCIqVPZ36ueVLtoOEZaAqbCF2RDndaA==" + "integrity": "sha512-w+LhYREhatpVqTESyGFg3NlP6Iu0kEKUHETY9GoZP/pQyW4mHFZuFWRUCIqVPZ36ueVLtoOEZaAqbCF2RDndaA==", + "dev": true }, "concat-map": { "version": "0.0.1", @@ -1034,6 +1065,15 @@ "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", "dev": true }, + "cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "requires": { + "object-assign": "^4", + "vary": "^1" + } + }, "cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -1213,30 +1253,31 @@ "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==" }, "engine.io": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.6.1.tgz", - "integrity": "sha512-dfs8EVg/i7QjFsXxn7cCRQ+Wai1G1TlEvHhdYEi80fxn5R1vZ2K661O6v/rezj1FP234SZ14r9CmJke99iYDGg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-4.1.2.tgz", + "integrity": "sha512-t5z6zjXuVLhXDMiFJPYsPOWEER8B0tIsD3ETgw19S1yg9zryvUfY3Vhtk3Gf4sihw/bQGIqQ//gjvVlu+Ca0bQ==", "requires": { "accepts": "~1.3.4", "base64id": "2.0.0", "cookie": "~0.4.1", - "debug": "~4.1.0", - "engine.io-parser": "~2.2.0", + "cors": "~2.8.5", + "debug": "~4.3.1", + "engine.io-parser": "~4.0.0", "ws": "~7.4.2" }, "dependencies": { "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "requires": { - "ms": "^2.1.1" + "ms": "2.1.2" } }, "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "ws": { "version": "7.4.6", @@ -1246,16 +1287,15 @@ } }, "engine.io-client": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.5.3.tgz", - "integrity": "sha512-qsgyc/CEhJ6cgMUwxRRtOndGVhIu5hpL5tR4umSpmX/MvkFoIxUTM7oFMDQumHNzlNLwSVy6qhstFPoWTf7dOw==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-4.1.4.tgz", + "integrity": "sha512-843fqAdKeUMFqKi1sSjnR11tJ4wi8sIefu6+JC1OzkkJBmjtc/gM/rZ53tJfu5Iae/3gApm5veoS+v+gtT0+Fg==", "requires": { + "base64-arraybuffer": "0.1.4", "component-emitter": "~1.3.0", - "component-inherit": "0.0.3", - "debug": "~3.1.0", - "engine.io-parser": "~2.2.0", + "debug": "~4.3.1", + "engine.io-parser": "~4.0.1", "has-cors": "1.1.0", - "indexof": "0.0.1", "parseqs": "0.0.6", "parseuri": "0.0.6", "ws": "~7.4.2", @@ -1264,13 +1304,18 @@ }, "dependencies": { "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "requires": { - "ms": "2.0.0" + "ms": "2.1.2" } }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, "ws": { "version": "7.4.6", "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", @@ -1279,15 +1324,11 @@ } }, "engine.io-parser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.2.1.tgz", - "integrity": "sha512-x+dN/fBH8Ro8TFwJ+rkB2AmuVw9Yu2mockR/p3W8f8YtExwFgDvBDi0GWyb4ZLkpahtDGZgtr3zLovanJghPqg==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-4.0.3.tgz", + "integrity": "sha512-xEAAY0msNnESNPc00e19y5heTPX4y/TJ36gr8t1voOaNmTojP9b3oK3BbJLFufW2XFPQaaijpFewm2g2Um3uqA==", "requires": { - "after": "0.8.2", - "arraybuffer.slice": "~0.0.7", - "base64-arraybuffer": "0.1.4", - "blob": "0.0.5", - "has-binary2": "~1.0.2" + "base64-arraybuffer": "0.1.4" } }, "enhanced-resolve": { @@ -1834,6 +1875,55 @@ "ms": "2.1.2" } }, + "engine.io-client": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.5.3.tgz", + "integrity": "sha512-qsgyc/CEhJ6cgMUwxRRtOndGVhIu5hpL5tR4umSpmX/MvkFoIxUTM7oFMDQumHNzlNLwSVy6qhstFPoWTf7dOw==", + "dev": true, + "requires": { + "component-emitter": "~1.3.0", + "component-inherit": "0.0.3", + "debug": "~3.1.0", + "engine.io-parser": "~2.2.0", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "parseqs": "0.0.6", + "parseuri": "0.0.6", + "ws": "~7.4.2", + "xmlhttprequest-ssl": "~1.6.2", + "yeast": "0.1.2" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + } + } + }, + "engine.io-parser": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.2.1.tgz", + "integrity": "sha512-x+dN/fBH8Ro8TFwJ+rkB2AmuVw9Yu2mockR/p3W8f8YtExwFgDvBDi0GWyb4ZLkpahtDGZgtr3zLovanJghPqg==", + "dev": true, + "requires": { + "after": "0.8.2", + "arraybuffer.slice": "~0.0.7", + "base64-arraybuffer": "0.1.4", + "blob": "0.0.5", + "has-binary2": "~1.0.2" + } + }, "formidable": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/formidable/-/formidable-2.1.2.tgz", @@ -1846,6 +1936,12 @@ "qs": "^6.11.0" } }, + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha512-c2cu3UxbI+b6kR3fy0nRnAhodsvR9dx7U5+znCOzdj6IfP3upFURTr0Xl5BlQZNKZjEtxrmVyfSdeE3O57smoQ==", + "dev": true + }, "mime": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", @@ -1869,6 +1965,70 @@ "util-deprecate": "^1.0.1" } }, + "socket.io-client": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.5.0.tgz", + "integrity": "sha512-lOO9clmdgssDykiOmVQQitwBAF3I6mYcQAo7hQ7AM6Ny5X7fp8hIJ3HcQs3Rjz4SoggoxA1OgrQyY8EgTbcPYw==", + "dev": true, + "requires": { + "backo2": "1.0.2", + "component-bind": "1.0.0", + "component-emitter": "~1.3.0", + "debug": "~3.1.0", + "engine.io-client": "~3.5.0", + "has-binary2": "~1.0.2", + "indexof": "0.0.1", + "parseqs": "0.0.6", + "parseuri": "0.0.6", + "socket.io-parser": "~3.3.0", + "to-array": "0.1.4" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + } + } + }, + "socket.io-parser": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.3.tgz", + "integrity": "sha512-qOg87q1PMWWTeO01768Yh9ogn7chB9zkKtQnya41Y355S0UmpXgpcrFwAgjYJxu9BdKug5r5e9YtVSeWhKBUZg==", + "dev": true, + "requires": { + "component-emitter": "~1.3.0", + "debug": "~3.1.0", + "isarray": "2.0.1" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + } + } + }, "string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -1896,6 +2056,18 @@ "readable-stream": "^3.6.0", "semver": "^7.3.7" } + }, + "ws": { + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", + "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", + "dev": true + }, + "xmlhttprequest-ssl": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.6.3.tgz", + "integrity": "sha512-3XfeQE/wNkvrIktn2Kf0869fC0BN6UpydVasGIeSm2B1Llihf7/0UfZM+eCkOw3P7bP4+qPgqhm7ZoxuJtFU0Q==", + "dev": true } } }, @@ -2357,6 +2529,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz", "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==", + "dev": true, "requires": { "isarray": "2.0.1" }, @@ -2364,7 +2537,8 @@ "isarray": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", - "integrity": "sha512-c2cu3UxbI+b6kR3fy0nRnAhodsvR9dx7U5+znCOzdj6IfP3upFURTr0Xl5BlQZNKZjEtxrmVyfSdeE3O57smoQ==" + "integrity": "sha512-c2cu3UxbI+b6kR3fy0nRnAhodsvR9dx7U5+znCOzdj6IfP3upFURTr0Xl5BlQZNKZjEtxrmVyfSdeE3O57smoQ==", + "dev": true } } }, @@ -2655,7 +2829,8 @@ "indexof": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", - "integrity": "sha512-i0G7hLJ1z0DE8dsqJa2rycj9dBmNKgXBvotXtZYXakU9oivfB9Uj2ZBC27qqef2U58/ZLwalxa1X/RDCdkHtVg==" + "integrity": "sha512-i0G7hLJ1z0DE8dsqJa2rycj9dBmNKgXBvotXtZYXakU9oivfB9Uj2ZBC27qqef2U58/ZLwalxa1X/RDCdkHtVg==", + "dev": true }, "inflight": { "version": "1.0.6", @@ -6729,6 +6904,11 @@ } } }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" + }, "object-inspect": { "version": "1.12.3", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", @@ -7451,113 +7631,92 @@ "dev": true }, "socket.io": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.5.0.tgz", - "integrity": "sha512-gGunfS0od3VpwDBpGwVkzSZx6Aqo9uOcf1afJj2cKnKFAoyl16fvhpsUhmUFd4Ldbvl5JvRQed6eQw6oQp6n8w==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-3.1.2.tgz", + "integrity": "sha512-JubKZnTQ4Z8G4IZWtaAZSiRP3I/inpy8c/Bsx2jrwGrTbKeVU5xd6qkKMHpChYeM3dWZSO0QACiGK+obhBNwYw==", "requires": { - "debug": "~4.1.0", - "engine.io": "~3.6.0", - "has-binary2": "~1.0.2", - "socket.io-adapter": "~1.1.0", - "socket.io-client": "2.5.0", - "socket.io-parser": "~3.4.0" + "@types/cookie": "^0.4.0", + "@types/cors": "^2.8.8", + "@types/node": ">=10.0.0", + "accepts": "~1.3.4", + "base64id": "~2.0.0", + "debug": "~4.3.1", + "engine.io": "~4.1.0", + "socket.io-adapter": "~2.1.0", + "socket.io-parser": "~4.0.3" }, "dependencies": { "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "requires": { - "ms": "^2.1.1" + "ms": "2.1.2" } }, "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" } } }, "socket.io-adapter": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.2.tgz", - "integrity": "sha512-WzZRUj1kUjrTIrUKpZLEzFZ1OLj5FwLlAFQs9kuZJzJi5DKdU7FsWc36SNmA8iDOtwBQyT8FkrriRM8vXLYz8g==" + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.1.0.tgz", + "integrity": "sha512-+vDov/aTsLjViYTwS9fPy5pEtTkrbEKsw2M+oVSoFGw6OD1IpvlV1VPhUzNbofCQ8oyMbdYJqDtGdmHQK6TdPg==" }, "socket.io-client": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.5.0.tgz", - "integrity": "sha512-lOO9clmdgssDykiOmVQQitwBAF3I6mYcQAo7hQ7AM6Ny5X7fp8hIJ3HcQs3Rjz4SoggoxA1OgrQyY8EgTbcPYw==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-3.1.3.tgz", + "integrity": "sha512-4sIGOGOmCg3AOgGi7EEr6ZkTZRkrXwub70bBB/F0JSkMOUFpA77WsL87o34DffQQ31PkbMUIadGOk+3tx1KGbw==", "requires": { - "backo2": "1.0.2", - "component-bind": "1.0.0", + "@types/component-emitter": "^1.2.10", + "backo2": "~1.0.2", "component-emitter": "~1.3.0", - "debug": "~3.1.0", - "engine.io-client": "~3.5.0", - "has-binary2": "~1.0.2", - "indexof": "0.0.1", - "parseqs": "0.0.6", + "debug": "~4.3.1", + "engine.io-client": "~4.1.0", "parseuri": "0.0.6", - "socket.io-parser": "~3.3.0", - "to-array": "0.1.4" + "socket.io-parser": "~4.0.4" }, "dependencies": { "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "requires": { - "ms": "2.0.0" + "ms": "2.1.2" } }, - "isarray": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", - "integrity": "sha512-c2cu3UxbI+b6kR3fy0nRnAhodsvR9dx7U5+znCOzdj6IfP3upFURTr0Xl5BlQZNKZjEtxrmVyfSdeE3O57smoQ==" - }, - "socket.io-parser": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.3.tgz", - "integrity": "sha512-qOg87q1PMWWTeO01768Yh9ogn7chB9zkKtQnya41Y355S0UmpXgpcrFwAgjYJxu9BdKug5r5e9YtVSeWhKBUZg==", - "requires": { - "component-emitter": "~1.3.0", - "debug": "~3.1.0", - "isarray": "2.0.1" - } + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" } } }, "socket.io-parser": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.4.3.tgz", - "integrity": "sha512-1rE4dZN3kCI/E5wixd393hmbqa78vVpkKmnEJhLeWoS/C5hbFYAbcSfnWoaVH43u9ToUVtzKjguxEZq+1XZfCQ==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.0.5.tgz", + "integrity": "sha512-sNjbT9dX63nqUFIOv95tTVm6elyIU4RvB1m8dOeZt+IgWwcWklFDOdmGcfo3zSiRsnR/3pJkjY5lfoGqEe4Eig==", "requires": { - "component-emitter": "1.2.1", - "debug": "~4.1.0", - "isarray": "2.0.1" + "@types/component-emitter": "^1.2.10", + "component-emitter": "~1.3.0", + "debug": "~4.3.1" }, "dependencies": { - "component-emitter": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", - "integrity": "sha512-jPatnhd33viNplKjqXKRkGU345p263OIWzDL2wH3LGIGp5Kojo+uXizHmOADRvhGFFTnJqX3jBAKP6vvmSDKcA==" - }, "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "requires": { - "ms": "^2.1.1" + "ms": "2.1.2" } }, - "isarray": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", - "integrity": "sha512-c2cu3UxbI+b6kR3fy0nRnAhodsvR9dx7U5+znCOzdj6IfP3upFURTr0Xl5BlQZNKZjEtxrmVyfSdeE3O57smoQ==" - }, "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" } } }, @@ -7878,7 +8037,8 @@ "to-array": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", - "integrity": "sha512-LhVdShQD/4Mk4zXNroIQZJC+Ap3zgLcDuwEdcmLv9CCO73NWockQDwyUnW/m8VX/EElfL6FcYx7EeutN4HJA6A==" + "integrity": "sha512-LhVdShQD/4Mk4zXNroIQZJC+Ap3zgLcDuwEdcmLv9CCO73NWockQDwyUnW/m8VX/EElfL6FcYx7EeutN4HJA6A==", + "dev": true }, "to-regex-range": { "version": "5.0.1", @@ -8070,6 +8230,11 @@ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz", "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==" }, + "undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + }, "unified": { "version": "11.0.3", "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.3.tgz", diff --git a/src/package.json b/src/package.json index b602a2c52..21553d78b 100644 --- a/src/package.json +++ b/src/package.json @@ -62,7 +62,8 @@ "resolve": "1.22.8", "security": "1.0.0", "semver": "^7.5.4", - "socket.io": "^4.7.0", + "socket.io": "^3.1.2", + "socket.io-client": "^3.1.2", "superagent": "^8.1.2", "terser": "^5.26.0", "threads": "^1.7.0", @@ -102,7 +103,7 @@ }, "scripts": { "lint": "eslint .", - "test": "mocha --timeout 120000 --recursive tests/backend/specs ../node_modules/ep_*/static/tests/backend/specs", + "test": "mocha --timeout 12000000 --recursive tests/backend/specs ../node_modules/ep_*/static/tests/backend/specs", "test-container": "mocha --timeout 5000 tests/container/specs/api" }, "version": "1.9.6", diff --git a/src/static/js/collab_client.js b/src/static/js/collab_client.js index 11a3a3dc6..386c47c0c 100644 --- a/src/static/js/collab_client.js +++ b/src/static/js/collab_client.js @@ -156,10 +156,11 @@ const getCollabClient = (ace2editor, serverVars, initialUserInfo, options, _pad) }; const sendMessage = (msg) => { - getSocket().json.send( + getSocket().emit("message", { type: 'COLLABROOM', component: 'pad', + padId: clientVars.padId, data: msg, }); }; diff --git a/src/static/js/pad.js b/src/static/js/pad.js index 802f1d476..df409372a 100644 --- a/src/static/js/pad.js +++ b/src/static/js/pad.js @@ -207,7 +207,7 @@ const sendClientReady = (isReconnect) => { msg.reconnect = true; } - socket.json.send(msg); + socket.emit("message", msg); }; const handshake = async () => { diff --git a/src/static/js/socketio.js b/src/static/js/socketio.js index 17cce08ec..bf9cfd5d5 100644 --- a/src/static/js/socketio.js +++ b/src/static/js/socketio.js @@ -19,7 +19,7 @@ const connect = (etherpadBaseUrl, namespace = '/', options = {}) => { const baseUrl = new URL(etherpadBaseUrl, window.location); const socketioUrl = new URL('socket.io', baseUrl); const namespaceUrl = new URL(namespace, new URL('/', baseUrl)); - return new io.Socket(namespaceUrl.href, Object.assign({path: socketioUrl.pathname}, options)); + return io(namespaceUrl.href, Object.assign({path: socketioUrl.pathname}, options)); }; if (typeof exports === 'object') { diff --git a/src/static/js/timeslider.js b/src/static/js/timeslider.js index 8c5993145..0fe4a6227 100644 --- a/src/static/js/timeslider.js +++ b/src/static/js/timeslider.js @@ -95,7 +95,7 @@ const init = () => { // sends a message over the socket const sendSocketMsg = (type, data) => { - socket.json.send({ + socket.emit("message",{ component: 'pad', // FIXME: Remove this stupidity! type, data, diff --git a/src/templates/pad.html b/src/templates/pad.html index 54e1897d9..f52fa5e85 100644 --- a/src/templates/pad.html +++ b/src/templates/pad.html @@ -169,7 +169,7 @@

About

Powered by - Etherpad + Etherpad-lite <% if (settings.exposeVersion) { %>(commit <%=settings.getGitCommit()%>)<% } %> @@ -442,7 +442,28 @@ <% e.begin_block("scripts"); %> - + + + + diff --git a/src/tests/backend/specs/socketio.js b/src/tests/backend/specs/socketio.js index 15f561774..024602b80 100644 --- a/src/tests/backend/specs/socketio.js +++ b/src/tests/backend/specs/socketio.js @@ -24,7 +24,7 @@ describe(__filename, function () { }; let socket; - before(async function () { agent = await common.init(); }); + before(async function () {agent = await common.init(); }); beforeEach(async function () { backups.hooks = {}; for (const hookName of ['preAuthorize', 'authenticate', 'authorize']) {