Bladeren bron

fix(socket.io -> WS): cleaned up code, some bug fixes

Signed-off-by: Jonathan <theflametrooper@gmail.com>
Jonathan 3 jaren geleden
bovenliggende
commit
289165d5a7
41 gewijzigde bestanden met toevoegingen van 396 en 991 verwijderingen
  1. 1 1
      README.md
  2. 2 2
      backend/index.js
  3. 6 6
      backend/logic/actions/activities.js
  4. 3 3
      backend/logic/actions/apis.js
  5. 11 10
      backend/logic/actions/news.js
  6. 35 35
      backend/logic/actions/playlists.js
  7. 6 6
      backend/logic/actions/punishments.js
  8. 10 10
      backend/logic/actions/queueSongs.js
  9. 8 8
      backend/logic/actions/reports.js
  10. 18 18
      backend/logic/actions/songs.js
  11. 29 29
      backend/logic/actions/stations.js
  12. 43 43
      backend/logic/actions/users.js
  13. 8 8
      backend/logic/activities.js
  14. 13 13
      backend/logic/stations.js
  15. 5 5
      backend/logic/tasks.js
  16. 4 6
      backend/logic/utils.js
  17. 104 117
      backend/logic/ws.js
  18. 0 552
      backend/package-lock.json
  19. 0 1
      backend/package.json
  20. 0 1
      frontend/dist/index.tpl.html
  21. 0 5
      frontend/dist/vendor/socket.io.2.2.0.js
  22. 3 3
      frontend/src/App.vue
  23. 1 1
      frontend/src/api/admin/index.js
  24. 5 5
      frontend/src/api/admin/reports.js
  25. 5 5
      frontend/src/api/auth.js
  26. 8 8
      frontend/src/main.js
  27. 2 2
      frontend/src/pages/Admin/tabs/NewStatistics.vue
  28. 2 2
      frontend/src/pages/Admin/tabs/News.vue
  29. 2 2
      frontend/src/pages/Admin/tabs/Playlists.vue
  30. 2 2
      frontend/src/pages/Admin/tabs/Punishments.vue
  31. 2 2
      frontend/src/pages/Admin/tabs/QueueSongs.vue
  32. 2 2
      frontend/src/pages/Admin/tabs/Reports.vue
  33. 2 2
      frontend/src/pages/Admin/tabs/Songs.vue
  34. 2 2
      frontend/src/pages/Admin/tabs/Stations.vue
  35. 2 2
      frontend/src/pages/Admin/tabs/Statistics.vue
  36. 2 2
      frontend/src/pages/Admin/tabs/Users.vue
  37. 2 2
      frontend/src/pages/Home.vue
  38. 1 1
      frontend/src/pages/Settings/tabs/Profile.vue
  39. 2 5
      frontend/src/pages/Station/index.vue
  40. 2 2
      frontend/src/store/modules/user.js
  41. 41 60
      frontend/src/ws.js

+ 1 - 1
README.md

@@ -2,7 +2,7 @@
 
 Based off of the original [Musare](https://github.com/Musare/MusareMeteor), which utilized Meteor.
 
-MusareNode now uses NodeJS, Express, SocketIO and VueJS - among other technologies. We have also implemented the ability to host Musare in [Docker Containers](https://www.docker.com/).
+MusareNode now uses NodeJS, Express, VueJS and websockets - among other technologies. We have also implemented the ability to host Musare in [Docker Containers](https://www.docker.com/).
 
 The master branch is available at [musare.com](https://musare.com)
 You can also find the staging branch at [musare.dev](https://musare.dev)

+ 2 - 2
backend/index.js

@@ -196,7 +196,7 @@ if (config.debug && config.debug.traceUnhandledPromises === true) {
 // moduleManager.addModule("mail");
 // moduleManager.addModule("api");
 // moduleManager.addModule("app");
-// moduleManager.addModule("io");
+// moduleManager.addModule("ws");
 // moduleManager.addModule("logger");
 // moduleManager.addModule("notifications");
 // moduleManager.addModule("activities");
@@ -381,7 +381,7 @@ if (!config.get("migration")) {
 	moduleManager.addModule("activities");
 	moduleManager.addModule("api");
 	moduleManager.addModule("app");
-	moduleManager.addModule("io");
+	moduleManager.addModule("ws");
 	moduleManager.addModule("notifications");
 	moduleManager.addModule("playlists");
 	moduleManager.addModule("punishments");

+ 6 - 6
backend/logic/actions/activities.js

@@ -6,17 +6,17 @@ import moduleManager from "../../index";
 
 const DBModule = moduleManager.modules.db;
 const CacheModule = moduleManager.modules.cache;
-const IOModule = moduleManager.modules.io;
+const WSModule = moduleManager.modules.ws;
 const UtilsModule = moduleManager.modules.utils;
 
 CacheModule.runJob("SUB", {
 	channel: "activity.removeAllForUser",
 	cb: userId => {
-		IOModule.runJob("SOCKETS_FROM_USER", { userId }, this).then(sockets =>
+		WSModule.runJob("SOCKETS_FROM_USER", { userId }, this).then(sockets =>
 			sockets.forEach(socket => socket.dispatch("event:activity.removeAllForUser"))
 		);
 
-		IOModule.runJob("EMIT_TO_ROOM", {
+		WSModule.runJob("EMIT_TO_ROOM", {
 			room: `profile-${userId}-activities`,
 			args: ["event:activity.removeAllForUser"]
 		});
@@ -26,11 +26,11 @@ CacheModule.runJob("SUB", {
 CacheModule.runJob("SUB", {
 	channel: "activity.hide",
 	cb: res => {
-		IOModule.runJob("SOCKETS_FROM_USER", { userId: res.userId }, this).then(sockets =>
+		WSModule.runJob("SOCKETS_FROM_USER", { userId: res.userId }, this).then(sockets =>
 			sockets.forEach(socket => socket.dispatch("event:activity.hide", res.activityId))
 		);
 
-		IOModule.runJob("EMIT_TO_ROOM", {
+		WSModule.runJob("EMIT_TO_ROOM", {
 			room: `profile-${res.userId}-activities`,
 			args: ["event:activity.hide", res.activityId]
 		});
@@ -41,7 +41,7 @@ export default {
 	/**
 	 * Returns how many activities there are for a user
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {string} userId - the id of the user in question
 	 * @param {Function} cb - callback
 	 */

+ 3 - 3
backend/logic/actions/apis.js

@@ -7,7 +7,7 @@ import { isAdminRequired } from "./hooks";
 import moduleManager from "../../index";
 
 const UtilsModule = moduleManager.modules.utils;
-const IOModule = moduleManager.modules.io;
+const WSModule = moduleManager.modules.ws;
 const YouTubeModule = moduleManager.modules.youtube;
 
 export default {
@@ -122,7 +122,7 @@ export default {
 	 */
 	joinRoom(session, page, cb) {
 		if (page === "home" || page.startsWith("profile-")) {
-			IOModule.runJob("SOCKET_JOIN_ROOM", {
+			WSModule.runJob("SOCKET_JOIN_ROOM", {
 				socketId: session.socketId,
 				room: page
 			})
@@ -152,7 +152,7 @@ export default {
 			page === "statistics" ||
 			page === "punishments"
 		) {
-			IOModule.runJob("SOCKET_JOIN_ROOM", {
+			WSModule.runJob("SOCKET_JOIN_ROOM", {
 				socketId: session.socketId,
 				room: `admin.${page}`
 			});

+ 11 - 10
backend/logic/actions/news.js

@@ -6,13 +6,13 @@ import moduleManager from "../../index";
 
 const DBModule = moduleManager.modules.db;
 const UtilsModule = moduleManager.modules.utils;
-const IOModule = moduleManager.modules.io;
+const WSModule = moduleManager.modules.ws;
 const CacheModule = moduleManager.modules.cache;
 
 CacheModule.runJob("SUB", {
 	channel: "news.create",
 	cb: news => {
-		IOModule.runJob("EMIT_TO_ROOM", {
+		WSModule.runJob("EMIT_TO_ROOM", {
 			room: "admin.news",
 			args: ["event:admin.news.created", news]
 		});
@@ -22,7 +22,7 @@ CacheModule.runJob("SUB", {
 CacheModule.runJob("SUB", {
 	channel: "news.remove",
 	cb: news => {
-		IOModule.runJob("EMIT_TO_ROOM", {
+		WSModule.runJob("EMIT_TO_ROOM", {
 			room: "admin.news",
 			args: ["event:admin.news.removed", news]
 		});
@@ -32,7 +32,7 @@ CacheModule.runJob("SUB", {
 CacheModule.runJob("SUB", {
 	channel: "news.update",
 	cb: news => {
-		IOModule.runJob("EMIT_TO_ROOM", {
+		WSModule.runJob("EMIT_TO_ROOM", {
 			room: "admin.news",
 			args: ["event:admin.news.updated", news]
 		});
@@ -43,7 +43,7 @@ export default {
 	/**
 	 * Gets all news items
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {Function} cb - gets called with the result
 	 */
 	async index(session, cb) {
@@ -69,7 +69,7 @@ export default {
 	/**
 	 * Gets a news item by id
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {string} newsId - the news id
 	 * @param {Function} cb - gets called with the result
 	 */
@@ -95,7 +95,7 @@ export default {
 	/**
 	 * Creates a news item
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {object} data - the object of the news data
 	 * @param {Function} cb - gets called with the result
 	 */
@@ -128,7 +128,7 @@ export default {
 	/**
 	 * Gets the latest news item
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {Function} cb - gets called with the result
 	 */
 	async newest(session, cb) {
@@ -145,6 +145,7 @@ export default {
 					this.log("ERROR", "NEWS_NEWEST", `Getting the latest news failed. "${err}"`);
 					return cb({ status: "failure", message: err });
 				}
+
 				this.log("SUCCESS", "NEWS_NEWEST", `Successfully got the latest news.`, false);
 				return cb({ status: "success", data: news });
 			}
@@ -154,7 +155,7 @@ export default {
 	/**
 	 * Removes a news item
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {object} news - the news object
 	 * @param {Function} cb - gets called with the result
 	 */
@@ -184,7 +185,7 @@ export default {
 	/**
 	 * Removes a news item
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {string} _id - the news id
 	 * @param {object} news - the news object
 	 * @param {Function} cb - gets called with the result

+ 35 - 35
backend/logic/actions/playlists.js

@@ -6,7 +6,7 @@ import moduleManager from "../../index";
 
 const DBModule = moduleManager.modules.db;
 const UtilsModule = moduleManager.modules.utils;
-const IOModule = moduleManager.modules.io;
+const WSModule = moduleManager.modules.ws;
 const SongsModule = moduleManager.modules.songs;
 const CacheModule = moduleManager.modules.cache;
 const PlaylistsModule = moduleManager.modules.playlists;
@@ -16,12 +16,12 @@ const ActivitiesModule = moduleManager.modules.activities;
 CacheModule.runJob("SUB", {
 	channel: "playlist.create",
 	cb: playlist => {
-		IOModule.runJob("SOCKETS_FROM_USER", { userId: playlist.createdBy }, this).then(sockets => {
+		WSModule.runJob("SOCKETS_FROM_USER", { userId: playlist.createdBy }, this).then(sockets => {
 			sockets.forEach(socket => socket.dispatch("event:playlist.create", playlist));
 		});
 
 		if (playlist.privacy === "public")
-			IOModule.runJob("EMIT_TO_ROOM", {
+			WSModule.runJob("EMIT_TO_ROOM", {
 				room: `profile-${playlist.createdBy}-playlists`,
 				args: ["event:playlist.create", playlist]
 			});
@@ -31,13 +31,13 @@ CacheModule.runJob("SUB", {
 CacheModule.runJob("SUB", {
 	channel: "playlist.delete",
 	cb: res => {
-		IOModule.runJob("SOCKETS_FROM_USER", { userId: res.userId }, this).then(sockets => {
+		WSModule.runJob("SOCKETS_FROM_USER", { userId: res.userId }, this).then(sockets => {
 			sockets.forEach(socket => {
 				socket.dispatch("event:playlist.delete", res.playlistId);
 			});
 		});
 
-		IOModule.runJob("EMIT_TO_ROOM", {
+		WSModule.runJob("EMIT_TO_ROOM", {
 			room: `profile-${res.userId}-playlists`,
 			args: ["event:playlist.delete", res.playlistId]
 		});
@@ -47,7 +47,7 @@ CacheModule.runJob("SUB", {
 CacheModule.runJob("SUB", {
 	channel: "playlist.repositionSongs",
 	cb: res => {
-		IOModule.runJob("SOCKETS_FROM_USER", { userId: res.userId }, this).then(sockets =>
+		WSModule.runJob("SOCKETS_FROM_USER", { userId: res.userId }, this).then(sockets =>
 			sockets.forEach(socket =>
 				socket.dispatch("event:playlist.repositionSongs", {
 					playlistId: res.playlistId,
@@ -61,7 +61,7 @@ CacheModule.runJob("SUB", {
 CacheModule.runJob("SUB", {
 	channel: "playlist.addSong",
 	cb: res => {
-		IOModule.runJob("SOCKETS_FROM_USER", { userId: res.userId }, this).then(sockets => {
+		WSModule.runJob("SOCKETS_FROM_USER", { userId: res.userId }, this).then(sockets => {
 			sockets.forEach(socket => {
 				socket.dispatch("event:playlist.addSong", {
 					playlistId: res.playlistId,
@@ -71,7 +71,7 @@ CacheModule.runJob("SUB", {
 		});
 
 		if (res.privacy === "public")
-			IOModule.runJob("EMIT_TO_ROOM", {
+			WSModule.runJob("EMIT_TO_ROOM", {
 				room: `profile-${res.userId}-playlists`,
 				args: [
 					"event:playlist.addSong",
@@ -87,7 +87,7 @@ CacheModule.runJob("SUB", {
 CacheModule.runJob("SUB", {
 	channel: "playlist.removeSong",
 	cb: res => {
-		IOModule.runJob("SOCKETS_FROM_USER", { userId: res.userId }, this).then(sockets => {
+		WSModule.runJob("SOCKETS_FROM_USER", { userId: res.userId }, this).then(sockets => {
 			sockets.forEach(socket => {
 				socket.dispatch("event:playlist.removeSong", {
 					playlistId: res.playlistId,
@@ -97,7 +97,7 @@ CacheModule.runJob("SUB", {
 		});
 
 		if (res.privacy === "public")
-			IOModule.runJob("EMIT_TO_ROOM", {
+			WSModule.runJob("EMIT_TO_ROOM", {
 				room: `profile-${res.userId}-playlists`,
 				args: [
 					"event:playlist.removeSong",
@@ -113,7 +113,7 @@ CacheModule.runJob("SUB", {
 CacheModule.runJob("SUB", {
 	channel: "playlist.updateDisplayName",
 	cb: res => {
-		IOModule.runJob("SOCKETS_FROM_USER", { userId: res.userId }, this).then(sockets => {
+		WSModule.runJob("SOCKETS_FROM_USER", { userId: res.userId }, this).then(sockets => {
 			sockets.forEach(socket => {
 				socket.dispatch("event:playlist.updateDisplayName", {
 					playlistId: res.playlistId,
@@ -123,7 +123,7 @@ CacheModule.runJob("SUB", {
 		});
 
 		if (res.privacy === "public")
-			IOModule.runJob("EMIT_TO_ROOM", {
+			WSModule.runJob("EMIT_TO_ROOM", {
 				room: `profile-${res.userId}-playlists`,
 				args: [
 					"event:playlist.updateDisplayName",
@@ -139,7 +139,7 @@ CacheModule.runJob("SUB", {
 CacheModule.runJob("SUB", {
 	channel: "playlist.updatePrivacy",
 	cb: res => {
-		IOModule.runJob("SOCKETS_FROM_USER", { userId: res.userId }, this).then(sockets => {
+		WSModule.runJob("SOCKETS_FROM_USER", { userId: res.userId }, this).then(sockets => {
 			sockets.forEach(socket => {
 				socket.dispatch("event:playlist.updatePrivacy", {
 					playlist: res.playlist
@@ -148,12 +148,12 @@ CacheModule.runJob("SUB", {
 		});
 
 		if (res.playlist.privacy === "public")
-			return IOModule.runJob("EMIT_TO_ROOM", {
+			return WSModule.runJob("EMIT_TO_ROOM", {
 				room: `profile-${res.userId}-playlists`,
 				args: ["event:playlist.create", res.playlist]
 			});
 
-		return IOModule.runJob("EMIT_TO_ROOM", {
+		return WSModule.runJob("EMIT_TO_ROOM", {
 			room: `profile-${res.userId}-playlists`,
 			args: ["event:playlist.delete", res.playlist._id]
 		});
@@ -164,7 +164,7 @@ export default {
 	/**
 	 * Gets all playlists
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {Function} cb - gets called with the result
 	 */
 	index: isAdminRequired(async function index(session, cb) {
@@ -191,7 +191,7 @@ export default {
 	/**
 	 * Gets the first song from a private playlist
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {string} playlistId - the id of the playlist we are getting the first song from
 	 * @param {Function} cb - gets called with the result
 	 */
@@ -235,7 +235,7 @@ export default {
 	/**
 	 * Gets a list of all the playlists for a specific user
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {string} userId - the user id in question
 	 * @param {Function} cb - gets called with the result
 	 */
@@ -308,7 +308,7 @@ export default {
 	/**
 	 * Gets all playlists for the user requesting it
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {boolean} showNonModifiablePlaylists - whether or not to show non modifiable playlists e.g. liked songs
 	 * @param {Function} cb - gets called with the result
 	 */
@@ -371,7 +371,7 @@ export default {
 	/**
 	 * Creates a new private playlist
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {object} data - the data for the new private playlist
 	 * @param {Function} cb - gets called with the result
 	 */
@@ -461,7 +461,7 @@ export default {
 	/**
 	 * Gets a playlist from id
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {string} playlistId - the id of the playlist we are getting
 	 * @param {Function} cb - gets called with the result
 	 */
@@ -510,7 +510,7 @@ export default {
 	/**
 	 * Obtains basic metadata of a playlist in order to format an activity
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {string} playlistId - the playlist id
 	 * @param {Function} cb - callback
 	 */
@@ -554,7 +554,7 @@ export default {
 	/**
 	 * Updates a private playlist
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {string} playlistId - the id of the playlist we are updating
 	 * @param {object} playlist - the new private playlist object
 	 * @param {Function} cb - gets called with the result
@@ -614,7 +614,7 @@ export default {
 	/**
 	 * Shuffles songs in a private playlist
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {string} playlistId - the id of the playlist we are updating
 	 * @param {Function} cb - gets called with the result
 	 */
@@ -675,7 +675,7 @@ export default {
 	/**
 	 * Changes the order of song(s) in a private playlist
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {string} playlistId - the id of the playlist we are targeting
 	 * @param {Array} songsBeingChanged - the songs to be repositioned, each element contains "songId" and "position" properties
 	 * @param {Function} cb - gets called with the result
@@ -751,7 +751,7 @@ export default {
 	/**
 	 * Moves a song to the bottom of the list in a private playlist
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {string} playlistId - the id of the playlist we are moving the song to the bottom from
 	 * @param {string} songId - the id of the song we are moving to the bottom of the list
 	 * @param {Function} cb - gets called with the result
@@ -791,7 +791,7 @@ export default {
 					});
 
 					// update position property on songs that need to be changed
-					return IOModule.runJob(
+					return WSModule.runJob(
 						"RUN_ACTION2",
 						{
 							session,
@@ -836,7 +836,7 @@ export default {
 	/**
 	 * Adds a song to a private playlist
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {boolean} isSet - is the song part of a set of songs to be added
 	 * @param {string} songId - the id of the song we are trying to add
 	 * @param {string} playlistId - the id of the playlist we are adding the song to
@@ -955,7 +955,7 @@ export default {
 	/**
 	 * Adds a set of songs to a private playlist
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {string} url - the url of the the YouTube playlist
 	 * @param {string} playlistId - the id of the playlist we are adding the set of songs to
 	 * @param {boolean} musicOnly - whether to only add music to the playlist
@@ -994,7 +994,7 @@ export default {
 						songIds,
 						1,
 						(songId, next) => {
-							IOModule.runJob(
+							WSModule.runJob(
 								"RUN_ACTION2",
 								{
 									session,
@@ -1078,7 +1078,7 @@ export default {
 	/**
 	 * Removes a song from a private playlist
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {string} songId - the id of the song we are removing from the private playlist
 	 * @param {string} playlistId - the id of the playlist we are removing the song from
 	 * @param {Function} cb - gets called with the result
@@ -1124,7 +1124,7 @@ export default {
 					});
 
 					// update position property on songs that need to be changed
-					return IOModule.runJob(
+					return WSModule.runJob(
 						"RUN_ACTION2",
 						{
 							session,
@@ -1223,7 +1223,7 @@ export default {
 	/**
 	 * Updates the displayName of a private playlist
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {string} playlistId - the id of the playlist we are updating the displayName for
 	 * @param {Function} cb - gets called with the result
 	 */
@@ -1305,7 +1305,7 @@ export default {
 	/**
 	 * Removes a private playlist
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {string} playlistId - the id of the playlist we are moving the song to the top from
 	 * @param {Function} cb - gets called with the result
 	 */
@@ -1430,7 +1430,7 @@ export default {
 	/**
 	 * Updates the privacy of a private playlist
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {string} playlistId - the id of the playlist we are updating the privacy for
 	 * @param {string} privacy - what the new privacy of the playlist should be e.g. public
 	 * @param {Function} cb - gets called with the result

+ 6 - 6
backend/logic/actions/punishments.js

@@ -6,19 +6,19 @@ import moduleManager from "../../index";
 
 const DBModule = moduleManager.modules.db;
 const UtilsModule = moduleManager.modules.utils;
-const IOModule = moduleManager.modules.io;
+const WSModule = moduleManager.modules.ws;
 const CacheModule = moduleManager.modules.cache;
 const PunishmentsModule = moduleManager.modules.punishments;
 
 CacheModule.runJob("SUB", {
 	channel: "ip.ban",
 	cb: data => {
-		IOModule.runJob("EMIT_TO_ROOM", {
+		WSModule.runJob("EMIT_TO_ROOM", {
 			room: "admin.punishments",
 			args: ["event:admin.punishment.added", data.punishment]
 		});
 
-		IOModule.runJob("SOCKETS_FROM_IP", { ip: data.ip }, this).then(sockets => {
+		WSModule.runJob("SOCKETS_FROM_IP", { ip: data.ip }, this).then(sockets => {
 			sockets.forEach(socket => {
 				socket.disconnect(true);
 			});
@@ -30,7 +30,7 @@ export default {
 	/**
 	 * Gets all punishments
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {Function} cb - gets called with the result
 	 */
 	index: isAdminRequired(async function index(session, cb) {
@@ -62,7 +62,7 @@ export default {
 	/**
 	 * Gets a punishment by id
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {string} punishmentId - the punishment id
 	 * @param {Function} cb - gets called with the result
 	 */
@@ -99,7 +99,7 @@ export default {
 	/**
 	 * Bans an IP address
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {string} value - the ip address that is going to be banned
 	 * @param {string} reason - the reason for the ban
 	 * @param {string} expiresAt - the time the ban expires

+ 10 - 10
backend/logic/actions/queueSongs.js

@@ -8,7 +8,7 @@ import moduleManager from "../../index";
 
 const DBModule = moduleManager.modules.db;
 const UtilsModule = moduleManager.modules.utils;
-const IOModule = moduleManager.modules.io;
+const WSModule = moduleManager.modules.ws;
 const YouTubeModule = moduleManager.modules.youtube;
 const CacheModule = moduleManager.modules.cache;
 
@@ -19,7 +19,7 @@ CacheModule.runJob("SUB", {
 			modelName: "queueSong"
 		});
 		queueSongModel.findOne({ _id: songId }, (err, song) => {
-			IOModule.runJob("EMIT_TO_ROOM", {
+			WSModule.runJob("EMIT_TO_ROOM", {
 				room: "admin.queue",
 				args: ["event:admin.queueSong.added", song]
 			});
@@ -30,7 +30,7 @@ CacheModule.runJob("SUB", {
 CacheModule.runJob("SUB", {
 	channel: "queue.removedSong",
 	cb: songId => {
-		IOModule.runJob("EMIT_TO_ROOM", {
+		WSModule.runJob("EMIT_TO_ROOM", {
 			room: "admin.queue",
 			args: ["event:admin.queueSong.removed", songId]
 		});
@@ -44,7 +44,7 @@ CacheModule.runJob("SUB", {
 			modelName: "queueSong"
 		});
 		queueSongModel.findOne({ _id: songId }, (err, song) => {
-			IOModule.runJob("EMIT_TO_ROOM", {
+			WSModule.runJob("EMIT_TO_ROOM", {
 				room: "admin.queue",
 				args: ["event:admin.queueSong.updated", song]
 			});
@@ -125,7 +125,7 @@ export default {
 	/**
 	 * Gets a song from the Musare song id
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {string} songId - the Musare song id
 	 * @param {Function} cb
 	 */
@@ -159,7 +159,7 @@ export default {
 	/**
 	 * Updates a queuesong
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {string} songId - the id of the queuesong that gets updated
 	 * @param {object} updatedSong - the object of the updated queueSong
 	 * @param {Function} cb - gets called with the result
@@ -221,7 +221,7 @@ export default {
 	/**
 	 * Removes a queuesong
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {string} songId - the id of the queuesong that gets removed
 	 * @param {Function} cb - gets called with the result
 	 */
@@ -269,7 +269,7 @@ export default {
 	/**
 	 * Creates a queuesong
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {string} songId - the id of the song that gets added
 	 * @param {Function} cb - gets called with the result
 	 */
@@ -361,7 +361,7 @@ export default {
 	/**
 	 * Adds a set of songs to the queue
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {string} url - the url of the the YouTube playlist
 	 * @param {boolean} musicOnly - whether to only get music from the playlist
 	 * @param {Function} cb - gets called with the result
@@ -395,7 +395,7 @@ export default {
 						songIds,
 						1,
 						(songId, next) => {
-							IOModule.runJob(
+							WSModule.runJob(
 								"RUN_ACTION2",
 								{
 									session,

+ 8 - 8
backend/logic/actions/reports.js

@@ -6,7 +6,7 @@ import moduleManager from "../../index";
 
 const DBModule = moduleManager.modules.db;
 const UtilsModule = moduleManager.modules.utils;
-const IOModule = moduleManager.modules.io;
+const WSModule = moduleManager.modules.ws;
 const SongsModule = moduleManager.modules.songs;
 const CacheModule = moduleManager.modules.cache;
 const ActivitiesModule = moduleManager.modules.activities;
@@ -37,7 +37,7 @@ const reportableIssues = [
 CacheModule.runJob("SUB", {
 	channel: "report.resolve",
 	cb: reportId => {
-		IOModule.runJob("EMIT_TO_ROOM", {
+		WSModule.runJob("EMIT_TO_ROOM", {
 			room: "admin.reports",
 			args: ["event:admin.report.resolved", reportId]
 		});
@@ -47,7 +47,7 @@ CacheModule.runJob("SUB", {
 CacheModule.runJob("SUB", {
 	channel: "report.create",
 	cb: report => {
-		IOModule.runJob("EMIT_TO_ROOM", {
+		WSModule.runJob("EMIT_TO_ROOM", {
 			room: "admin.reports",
 			args: ["event:admin.report.created", report]
 		});
@@ -58,7 +58,7 @@ export default {
 	/**
 	 * Gets all reports
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {Function} cb - gets called with the result
 	 */
 	index: isAdminRequired(async function index(session, cb) {
@@ -90,7 +90,7 @@ export default {
 	/**
 	 * Gets a specific report
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {string} reportId - the id of the report to return
 	 * @param {Function} cb - gets called with the result
 	 */
@@ -123,7 +123,7 @@ export default {
 	/**
 	 * Gets all reports for a songId (_id)
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {string} songId - the id of the song to index reports for
 	 * @param {Function} cb - gets called with the result
 	 */
@@ -167,7 +167,7 @@ export default {
 	/**
 	 * Resolves a report
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {string} reportId - the id of the report that is getting resolved
 	 * @param {Function} cb - gets called with the result
 	 */
@@ -220,7 +220,7 @@ export default {
 	/**
 	 * Creates a new report
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {object} data - the object of the report data
 	 * @param {Function} cb - gets called with the result
 	 */

+ 18 - 18
backend/logic/actions/songs.js

@@ -6,7 +6,7 @@ import moduleManager from "../../index";
 
 const DBModule = moduleManager.modules.db;
 const UtilsModule = moduleManager.modules.utils;
-const IOModule = moduleManager.modules.io;
+const WSModule = moduleManager.modules.ws;
 const CacheModule = moduleManager.modules.cache;
 const SongsModule = moduleManager.modules.songs;
 const ActivitiesModule = moduleManager.modules.activities;
@@ -15,7 +15,7 @@ const PlaylistsModule = moduleManager.modules.playlists;
 CacheModule.runJob("SUB", {
 	channel: "song.removed",
 	cb: songId => {
-		IOModule.runJob("EMIT_TO_ROOM", {
+		WSModule.runJob("EMIT_TO_ROOM", {
 			room: "admin.songs",
 			args: ["event:admin.song.removed", songId]
 		});
@@ -27,7 +27,7 @@ CacheModule.runJob("SUB", {
 	cb: async songId => {
 		const songModel = await DBModule.runJob("GET_MODEL", { modelName: "song" });
 		songModel.findOne({ _id: songId }, (err, song) => {
-			IOModule.runJob("EMIT_TO_ROOM", {
+			WSModule.runJob("EMIT_TO_ROOM", {
 				room: "admin.songs",
 				args: ["event:admin.song.added", song]
 			});
@@ -40,7 +40,7 @@ CacheModule.runJob("SUB", {
 	cb: async songId => {
 		const songModel = await DBModule.runJob("GET_MODEL", { modelName: "song" });
 		songModel.findOne({ _id: songId }, (err, song) => {
-			IOModule.runJob("EMIT_TO_ROOM", {
+			WSModule.runJob("EMIT_TO_ROOM", {
 				room: "admin.songs",
 				args: ["event:admin.song.updated", song]
 			});
@@ -51,7 +51,7 @@ CacheModule.runJob("SUB", {
 CacheModule.runJob("SUB", {
 	channel: "song.like",
 	cb: data => {
-		IOModule.runJob("EMIT_TO_ROOM", {
+		WSModule.runJob("EMIT_TO_ROOM", {
 			room: `song.${data.songId}`,
 			args: [
 				"event:song.like",
@@ -62,7 +62,7 @@ CacheModule.runJob("SUB", {
 				}
 			]
 		});
-		IOModule.runJob("SOCKETS_FROM_USER", { userId: data.userId }).then(sockets => {
+		WSModule.runJob("SOCKETS_FROM_USER", { userId: data.userId }).then(sockets => {
 			sockets.forEach(socket => {
 				socket.dispatch("event:song.newRatings", {
 					songId: data.songId,
@@ -77,7 +77,7 @@ CacheModule.runJob("SUB", {
 CacheModule.runJob("SUB", {
 	channel: "song.dislike",
 	cb: data => {
-		IOModule.runJob("EMIT_TO_ROOM", {
+		WSModule.runJob("EMIT_TO_ROOM", {
 			room: `song.${data.songId}`,
 			args: [
 				"event:song.dislike",
@@ -88,7 +88,7 @@ CacheModule.runJob("SUB", {
 				}
 			]
 		});
-		IOModule.runJob("SOCKETS_FROM_USER", { userId: data.userId }).then(sockets => {
+		WSModule.runJob("SOCKETS_FROM_USER", { userId: data.userId }).then(sockets => {
 			sockets.forEach(socket => {
 				socket.dispatch("event:song.newRatings", {
 					songId: data.songId,
@@ -103,7 +103,7 @@ CacheModule.runJob("SUB", {
 CacheModule.runJob("SUB", {
 	channel: "song.unlike",
 	cb: data => {
-		IOModule.runJob("EMIT_TO_ROOM", {
+		WSModule.runJob("EMIT_TO_ROOM", {
 			room: `song.${data.songId}`,
 			args: [
 				"event:song.unlike",
@@ -114,7 +114,7 @@ CacheModule.runJob("SUB", {
 				}
 			]
 		});
-		IOModule.runJob("SOCKETS_FROM_USER", { userId: data.userId }).then(sockets => {
+		WSModule.runJob("SOCKETS_FROM_USER", { userId: data.userId }).then(sockets => {
 			sockets.forEach(socket => {
 				socket.dispatch("event:song.newRatings", {
 					songId: data.songId,
@@ -129,7 +129,7 @@ CacheModule.runJob("SUB", {
 CacheModule.runJob("SUB", {
 	channel: "song.undislike",
 	cb: data => {
-		IOModule.runJob("EMIT_TO_ROOM", {
+		WSModule.runJob("EMIT_TO_ROOM", {
 			room: `song.${data.songId}`,
 			args: [
 				"event:song.undislike",
@@ -140,7 +140,7 @@ CacheModule.runJob("SUB", {
 				}
 			]
 		});
-		IOModule.runJob("SOCKETS_FROM_USER", { userId: data.userId }).then(sockets => {
+		WSModule.runJob("SOCKETS_FROM_USER", { userId: data.userId }).then(sockets => {
 			sockets.forEach(socket => {
 				socket.dispatch("event:song.newRatings", {
 					songId: data.songId,
@@ -156,7 +156,7 @@ export default {
 	/**
 	 * Returns the length of the songs list
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param cb
 	 */
 	length: isAdminRequired(async function length(session, cb) {
@@ -182,7 +182,7 @@ export default {
 	/**
 	 * Gets a set of songs
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param set - the set number to return
 	 * @param cb
 	 */
@@ -213,7 +213,7 @@ export default {
 	/**
 	 * Gets a song from the YouTube song id
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {string} songId - the YouTube song id
 	 * @param {Function} cb
 	 */
@@ -245,7 +245,7 @@ export default {
 	/**
 	 * Gets a song from the Musare song id
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {string} songId - the Musare song id
 	 * @param {Function} cb
 	 */
@@ -277,7 +277,7 @@ export default {
 	/**
 	 * Obtains basic metadata of a song in order to format an activity
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {string} songId - the song id
 	 * @param {Function} cb - callback
 	 */
@@ -333,7 +333,7 @@ export default {
 	/**
 	 * Updates a song
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {string} songId - the song id
 	 * @param {object} song - the updated song object
 	 * @param {Function} cb

+ 29 - 29
backend/logic/actions/stations.js

@@ -6,7 +6,7 @@ import moduleManager from "../../index";
 
 const DBModule = moduleManager.modules.db;
 const UtilsModule = moduleManager.modules.utils;
-const IOModule = moduleManager.modules.io;
+const WSModule = moduleManager.modules.ws;
 const SongsModule = moduleManager.modules.songs;
 const CacheModule = moduleManager.modules.cache;
 const NotificationsModule = moduleManager.modules.notifications;
@@ -17,7 +17,7 @@ const YouTubeModule = moduleManager.modules.youtube;
 CacheModule.runJob("SUB", {
 	channel: "station.updateUsers",
 	cb: ({ stationId, usersPerStation }) => {
-		IOModule.runJob("EMIT_TO_ROOM", {
+		WSModule.runJob("EMIT_TO_ROOM", {
 			room: `station.${stationId}`,
 			args: ["event:users.updated", usersPerStation]
 		});
@@ -29,19 +29,19 @@ CacheModule.runJob("SUB", {
 	cb: ({ stationId, usersPerStationCount }) => {
 		const count = usersPerStationCount || 0;
 
-		IOModule.runJob("EMIT_TO_ROOM", {
+		WSModule.runJob("EMIT_TO_ROOM", {
 			room: `station.${stationId}`,
 			args: ["event:userCount.updated", count]
 		});
 
 		StationsModule.runJob("GET_STATION", { stationId }).then(async station => {
 			if (station.privacy === "public")
-				IOModule.runJob("EMIT_TO_ROOM", {
+				WSModule.runJob("EMIT_TO_ROOM", {
 					room: "home",
 					args: ["event:userCount.updated", stationId, count]
 				});
 			else {
-				const sockets = await IOModule.runJob("GET_SOCKETS_FOR_ROOM", {
+				const sockets = await WSModule.runJob("GET_SOCKETS_FOR_ROOM", {
 					room: "home"
 				});
 
@@ -75,7 +75,7 @@ CacheModule.runJob("SUB", {
 CacheModule.runJob("SUB", {
 	channel: "station.updateTheme",
 	cb: data => {
-		IOModule.runJob("EMIT_TO_ROOM", {
+		WSModule.runJob("EMIT_TO_ROOM", {
 			room: `station.${data.stationId}`,
 			args: ["event:theme.updated", data.theme]
 		});
@@ -85,7 +85,7 @@ CacheModule.runJob("SUB", {
 CacheModule.runJob("SUB", {
 	channel: "station.queueLockToggled",
 	cb: data => {
-		IOModule.runJob("EMIT_TO_ROOM", {
+		WSModule.runJob("EMIT_TO_ROOM", {
 			room: `station.${data.stationId}`,
 			args: ["event:queueLockToggled", data.locked]
 		});
@@ -95,7 +95,7 @@ CacheModule.runJob("SUB", {
 CacheModule.runJob("SUB", {
 	channel: "station.updatePartyMode",
 	cb: data => {
-		IOModule.runJob("EMIT_TO_ROOM", {
+		WSModule.runJob("EMIT_TO_ROOM", {
 			room: `station.${data.stationId}`,
 			args: ["event:partyMode.updated", data.partyMode]
 		});
@@ -105,7 +105,7 @@ CacheModule.runJob("SUB", {
 CacheModule.runJob("SUB", {
 	channel: "privatePlaylist.selected",
 	cb: data => {
-		IOModule.runJob("EMIT_TO_ROOM", {
+		WSModule.runJob("EMIT_TO_ROOM", {
 			room: `station.${data.stationId}`,
 			args: ["event:privatePlaylist.selected", data.playlistId]
 		});
@@ -115,7 +115,7 @@ CacheModule.runJob("SUB", {
 CacheModule.runJob("SUB", {
 	channel: "privatePlaylist.deselected",
 	cb: data => {
-		IOModule.runJob("EMIT_TO_ROOM", {
+		WSModule.runJob("EMIT_TO_ROOM", {
 			room: `station.${data.stationId}`,
 			args: ["event:privatePlaylist.deselected"]
 		});
@@ -126,7 +126,7 @@ CacheModule.runJob("SUB", {
 	channel: "station.pause",
 	cb: stationId => {
 		StationsModule.runJob("GET_STATION", { stationId }).then(station => {
-			IOModule.runJob("EMIT_TO_ROOM", {
+			WSModule.runJob("EMIT_TO_ROOM", {
 				room: `station.${stationId}`,
 				args: ["event:stations.pause", { pausedAt: station.pausedAt }]
 			});
@@ -148,7 +148,7 @@ CacheModule.runJob("SUB", {
 	channel: "station.resume",
 	cb: stationId => {
 		StationsModule.runJob("GET_STATION", { stationId }).then(station => {
-			IOModule.runJob("EMIT_TO_ROOM", {
+			WSModule.runJob("EMIT_TO_ROOM", {
 				room: `station.${stationId}`,
 				args: ["event:stations.resume", { timePaused: station.timePaused }]
 			});
@@ -177,7 +177,7 @@ CacheModule.runJob("SUB", {
 				if (station.privacy === "public") {
 					// Station became public
 
-					IOModule.runJob("EMIT_TO_ROOM", {
+					WSModule.runJob("EMIT_TO_ROOM", {
 						room: "home",
 						args: ["event:stations.created", station]
 					});
@@ -229,7 +229,7 @@ CacheModule.runJob("SUB", {
 			})
 		);
 
-		IOModule.runJob("EMIT_TO_ROOM", {
+		WSModule.runJob("EMIT_TO_ROOM", {
 			room: `station.${stationId}`,
 			args: ["event:station.updateName", { stationId, name }]
 		});
@@ -253,7 +253,7 @@ CacheModule.runJob("SUB", {
 			})
 		);
 
-		IOModule.runJob("EMIT_TO_ROOM", {
+		WSModule.runJob("EMIT_TO_ROOM", {
 			room: `station.${stationId}`,
 			args: ["event:station.updateDisplayName", { stationId, displayName }]
 		});
@@ -277,7 +277,7 @@ CacheModule.runJob("SUB", {
 			})
 		);
 
-		IOModule.runJob("EMIT_TO_ROOM", {
+		WSModule.runJob("EMIT_TO_ROOM", {
 			room: `station.${stationId}`,
 			args: ["event:station.updateDescription", { stationId, description }]
 		});
@@ -289,7 +289,7 @@ CacheModule.runJob("SUB", {
 	cb: response => {
 		const { stationId } = response;
 		StationsModule.runJob("GET_STATION", { stationId }).then(station => {
-			IOModule.runJob("EMIT_TO_ROOM", {
+			WSModule.runJob("EMIT_TO_ROOM", {
 				room: `station.${stationId}`,
 				args: ["event:station.themeUpdated", station.theme]
 			});
@@ -310,7 +310,7 @@ CacheModule.runJob("SUB", {
 	channel: "station.queueUpdate",
 	cb: stationId => {
 		StationsModule.runJob("GET_STATION", { stationId }).then(station => {
-			IOModule.runJob("EMIT_TO_ROOM", {
+			WSModule.runJob("EMIT_TO_ROOM", {
 				room: `station.${stationId}`,
 				args: ["event:queue.update", station.queue]
 			});
@@ -321,7 +321,7 @@ CacheModule.runJob("SUB", {
 CacheModule.runJob("SUB", {
 	channel: "station.voteSkipSong",
 	cb: stationId => {
-		IOModule.runJob("EMIT_TO_ROOM", {
+		WSModule.runJob("EMIT_TO_ROOM", {
 			room: `station.${stationId}`,
 			args: ["event:song.voteSkipSong"]
 		});
@@ -331,16 +331,16 @@ CacheModule.runJob("SUB", {
 CacheModule.runJob("SUB", {
 	channel: "station.remove",
 	cb: stationId => {
-		IOModule.runJob("EMIT_TO_ROOM", {
+		WSModule.runJob("EMIT_TO_ROOM", {
 			room: `station.${stationId}`,
 			args: ["event:stations.remove"]
 		});
 		console.log(111, "REMOVED");
-		IOModule.runJob("EMIT_TO_ROOM", {
+		WSModule.runJob("EMIT_TO_ROOM", {
 			room: `home`,
 			args: ["event:station.removed", { stationId }]
 		});
-		IOModule.runJob("EMIT_TO_ROOM", {
+		WSModule.runJob("EMIT_TO_ROOM", {
 			room: "admin.stations",
 			args: ["event:admin.station.removed", stationId]
 		});
@@ -355,18 +355,18 @@ CacheModule.runJob("SUB", {
 		StationsModule.runJob("INITIALIZE_STATION", { stationId }).then(async response => {
 			const { station } = response;
 			station.userCount = StationsModule.usersPerStationCount[stationId] || 0;
-			IOModule.runJob("EMIT_TO_ROOM", {
+			WSModule.runJob("EMIT_TO_ROOM", {
 				room: "admin.stations",
 				args: ["event:admin.station.added", station]
 			});
 			// TODO If community, check if on whitelist
 			if (station.privacy === "public")
-				IOModule.runJob("EMIT_TO_ROOM", {
+				WSModule.runJob("EMIT_TO_ROOM", {
 					room: "home",
 					args: ["event:stations.created", station]
 				});
 			else {
-				const sockets = await IOModule.runJob("GET_SOCKETS_FOR_ROOM", {
+				const sockets = await WSModule.runJob("GET_SOCKETS_FOR_ROOM", {
 					room: "home"
 				});
 				Object.keys(sockets).forEach(socketKey => {
@@ -722,7 +722,7 @@ export default {
 				},
 
 				(station, next) => {
-					IOModule.runJob("SOCKET_JOIN_ROOM", {
+					WSModule.runJob("SOCKET_JOIN_ROOM", {
 						socketId: session.socketId,
 						room: `station.${station._id}`
 					});
@@ -761,7 +761,7 @@ export default {
 
 					if (!data.currentSong || !data.currentSong.title) return next(null, data);
 
-					IOModule.runJob("SOCKET_JOIN_SONG_ROOM", {
+					WSModule.runJob("SOCKET_JOIN_SONG_ROOM", {
 						socketId: session.socketId,
 						room: `song.${data.currentSong.songId}`
 					});
@@ -1026,7 +1026,7 @@ export default {
 
 				(station, next) => {
 					skipVotes = station.currentSong.skipVotes.length;
-					IOModule.runJob("GET_SOCKETS_FOR_ROOM", { room: `station.${stationId}` }, this)
+					WSModule.runJob("GET_SOCKETS_FOR_ROOM", { room: `station.${stationId}` }, this)
 						.then(sockets => next(null, sockets))
 						.catch(next);
 				},
@@ -1129,7 +1129,7 @@ export default {
 
 				this.log("SUCCESS", "STATIONS_LEAVE", `Left station "${stationId}" successfully.`);
 
-				IOModule.runJob("SOCKET_LEAVE_ROOMS", { socketId: session });
+				WSModule.runJob("SOCKET_LEAVE_ROOMS", { socketId: session });
 
 				delete StationsModule.userList[session.socketId];
 

+ 43 - 43
backend/logic/actions/users.js

@@ -11,7 +11,7 @@ import moduleManager from "../../index";
 
 const DBModule = moduleManager.modules.db;
 const UtilsModule = moduleManager.modules.utils;
-const IOModule = moduleManager.modules.io;
+const WSModule = moduleManager.modules.ws;
 const CacheModule = moduleManager.modules.cache;
 const MailModule = moduleManager.modules.mail;
 const PunishmentsModule = moduleManager.modules.punishments;
@@ -21,7 +21,7 @@ const PlaylistsModule = moduleManager.modules.playlists;
 CacheModule.runJob("SUB", {
 	channel: "user.updatePreferences",
 	cb: res => {
-		IOModule.runJob("SOCKETS_FROM_USER", { userId: res.userId }, this).then(sockets => {
+		WSModule.runJob("SOCKETS_FROM_USER", { userId: res.userId }, this).then(sockets => {
 			sockets.forEach(socket => {
 				socket.dispatch("keep.event:user.preferences.changed", res.preferences);
 			});
@@ -32,13 +32,13 @@ CacheModule.runJob("SUB", {
 CacheModule.runJob("SUB", {
 	channel: "user.updateOrderOfPlaylists",
 	cb: res => {
-		IOModule.runJob("SOCKETS_FROM_USER", { userId: res.userId }, this).then(sockets => {
+		WSModule.runJob("SOCKETS_FROM_USER", { userId: res.userId }, this).then(sockets => {
 			sockets.forEach(socket => {
 				socket.dispatch("event:user.orderOfPlaylists.changed", res.orderOfPlaylists);
 			});
 		});
 
-		IOModule.runJob("EMIT_TO_ROOM", {
+		WSModule.runJob("EMIT_TO_ROOM", {
 			room: `profile-${res.userId}-playlists`,
 			args: ["event:user.orderOfPlaylists.changed", res.orderOfPlaylists]
 		});
@@ -48,7 +48,7 @@ CacheModule.runJob("SUB", {
 CacheModule.runJob("SUB", {
 	channel: "user.updateUsername",
 	cb: user => {
-		IOModule.runJob("SOCKETS_FROM_USER", { userId: user._id }).then(sockets => {
+		WSModule.runJob("SOCKETS_FROM_USER", { userId: user._id }).then(sockets => {
 			sockets.forEach(socket => {
 				socket.dispatch("event:user.username.changed", user.username);
 			});
@@ -59,7 +59,7 @@ CacheModule.runJob("SUB", {
 CacheModule.runJob("SUB", {
 	channel: "user.removeSessions",
 	cb: userId => {
-		IOModule.runJob("SOCKETS_FROM_USER_WITHOUT_CACHE", { userId }).then(sockets => {
+		WSModule.runJob("SOCKETS_FROM_USER_WITHOUT_CACHE", { userId }).then(sockets => {
 			sockets.forEach(socket => {
 				socket.dispatch("keep.event:user.session.removed");
 			});
@@ -70,7 +70,7 @@ CacheModule.runJob("SUB", {
 CacheModule.runJob("SUB", {
 	channel: "user.linkPassword",
 	cb: userId => {
-		IOModule.runJob("SOCKETS_FROM_USER", { userId }).then(sockets => {
+		WSModule.runJob("SOCKETS_FROM_USER", { userId }).then(sockets => {
 			sockets.forEach(socket => {
 				socket.dispatch("event:user.linkPassword");
 			});
@@ -81,7 +81,7 @@ CacheModule.runJob("SUB", {
 CacheModule.runJob("SUB", {
 	channel: "user.unlinkPassword",
 	cb: userId => {
-		IOModule.runJob("SOCKETS_FROM_USER", { userId }).then(sockets => {
+		WSModule.runJob("SOCKETS_FROM_USER", { userId }).then(sockets => {
 			sockets.forEach(socket => {
 				socket.dispatch("event:user.unlinkPassword");
 			});
@@ -92,7 +92,7 @@ CacheModule.runJob("SUB", {
 CacheModule.runJob("SUB", {
 	channel: "user.linkGithub",
 	cb: userId => {
-		IOModule.runJob("SOCKETS_FROM_USER", { userId }).then(sockets => {
+		WSModule.runJob("SOCKETS_FROM_USER", { userId }).then(sockets => {
 			sockets.forEach(socket => {
 				socket.dispatch("event:user.linkGithub");
 			});
@@ -103,7 +103,7 @@ CacheModule.runJob("SUB", {
 CacheModule.runJob("SUB", {
 	channel: "user.unlinkGithub",
 	cb: userId => {
-		IOModule.runJob("SOCKETS_FROM_USER", { userId }).then(sockets => {
+		WSModule.runJob("SOCKETS_FROM_USER", { userId }).then(sockets => {
 			sockets.forEach(socket => {
 				socket.dispatch("event:user.unlinkGithub");
 			});
@@ -114,7 +114,7 @@ CacheModule.runJob("SUB", {
 CacheModule.runJob("SUB", {
 	channel: "user.ban",
 	cb: data => {
-		IOModule.runJob("SOCKETS_FROM_USER", { userId: data.userId }).then(sockets => {
+		WSModule.runJob("SOCKETS_FROM_USER", { userId: data.userId }).then(sockets => {
 			sockets.forEach(socket => {
 				socket.dispatch("keep.event:banned", data.punishment);
 				socket.disconnect(true);
@@ -126,7 +126,7 @@ CacheModule.runJob("SUB", {
 CacheModule.runJob("SUB", {
 	channel: "user.favoritedStation",
 	cb: data => {
-		IOModule.runJob("SOCKETS_FROM_USER", { userId: data.userId }).then(sockets => {
+		WSModule.runJob("SOCKETS_FROM_USER", { userId: data.userId }).then(sockets => {
 			sockets.forEach(socket => {
 				socket.dispatch("event:user.favoritedStation", data.stationId);
 			});
@@ -137,7 +137,7 @@ CacheModule.runJob("SUB", {
 CacheModule.runJob("SUB", {
 	channel: "user.unfavoritedStation",
 	cb: data => {
-		IOModule.runJob("SOCKETS_FROM_USER", { userId: data.userId }).then(sockets => {
+		WSModule.runJob("SOCKETS_FROM_USER", { userId: data.userId }).then(sockets => {
 			sockets.forEach(socket => {
 				socket.dispatch("event:user.unfavoritedStation", data.stationId);
 			});
@@ -149,7 +149,7 @@ export default {
 	/**
 	 * Lists all Users
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {Function} cb - gets called with the result
 	 */
 	index: isAdminRequired(async function index(session, cb) {
@@ -199,7 +199,7 @@ export default {
 	/**
 	 * Removes all data held on a user, including their ability to login
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {Function} cb - gets called with the result
 	 */
 	remove: isLoginRequired(async function remove(session, cb) {
@@ -256,7 +256,7 @@ export default {
 	/**
 	 * Logs user in
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {string} identifier - the email of the user
 	 * @param {string} password - the plaintext of the user
 	 * @param {Function} cb - gets called with the result
@@ -340,7 +340,7 @@ export default {
 	/**
 	 * Registers a new user
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {string} username - the username for the new user
 	 * @param {string} email - the email for the new user
 	 * @param {string} password - the plaintext password for the new user
@@ -563,7 +563,7 @@ export default {
 	/**
 	 * Logs out a user
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {Function} cb - gets called with the result
 	 */
 	logout(session, cb) {
@@ -605,7 +605,7 @@ export default {
 	/**
 	 * Removes all sessions for a user
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {string} userId - the id of the user we are trying to delete the sessions of
 	 * @param {Function} cb - gets called with the result
 	 */
@@ -689,7 +689,7 @@ export default {
 	/**
 	 * Updates the order of a user's playlists
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {Array} orderOfPlaylists - array of playlist ids (with a specific order)
 	 * @param {Function} cb - gets called with the result
 	 */
@@ -745,7 +745,7 @@ export default {
 	/**
 	 * Updates a user's preferences
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {object} preferences - object containing preferences
 	 * @param {boolean} preferences.nightmode - whether or not the user is using the night mode theme
 	 * @param {boolean} preferences.autoSkipDisliked - whether to automatically skip disliked songs
@@ -832,7 +832,7 @@ export default {
 	/**
 	 * Retrieves a user's preferences
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {Function} cb - gets called with the result
 	 */
 	getPreferences: isLoginRequired(async function updatePreferences(session, cb) {
@@ -875,7 +875,7 @@ export default {
 	/**
 	 * Gets user object from username (only a few properties)
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {string} username - the username of the user we are trying to find
 	 * @param {Function} cb - gets called with the result
 	 */
@@ -924,7 +924,7 @@ export default {
 	/**
 	 * Gets a username from an userId
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {string} userId - the userId of the person we are trying to get the username from
 	 * @param {Function} cb - gets called with the result
 	 */
@@ -969,7 +969,7 @@ export default {
 	/**
 	 * Gets a user from a userId
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {string} userId - the userId of the person we are trying to get the username from
 	 * @param {Function} cb - gets called with the result
 	 */
@@ -1024,7 +1024,7 @@ export default {
 	/**
 	 * Gets user info from session
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {Function} cb - gets called with the result
 	 */
 	async findBySession(session, cb) {
@@ -1092,7 +1092,7 @@ export default {
 	/**
 	 * Updates a user's username
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {string} updatingUserId - the updating user's id
 	 * @param {string} newUsername - the new username
 	 * @param {Function} cb - gets called with the result
@@ -1176,7 +1176,7 @@ export default {
 	/**
 	 * Updates a user's email
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {string} updatingUserId - the updating user's id
 	 * @param {string} newEmail - the new email
 	 * @param {Function} cb - gets called with the result
@@ -1280,7 +1280,7 @@ export default {
 	/**
 	 * Updates a user's name
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {string} updatingUserId - the updating user's id
 	 * @param {string} newBio - the new name
 	 * @param {Function} cb - gets called with the result
@@ -1346,7 +1346,7 @@ export default {
 	/**
 	 * Updates a user's location
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {string} updatingUserId - the updating user's id
 	 * @param {string} newLocation - the new location
 	 * @param {Function} cb - gets called with the result
@@ -1418,7 +1418,7 @@ export default {
 	/**
 	 * Updates a user's bio
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {string} updatingUserId - the updating user's id
 	 * @param {string} newBio - the new bio
 	 * @param {Function} cb - gets called with the result
@@ -1478,7 +1478,7 @@ export default {
 	/**
 	 * Updates the type of a user's avatar
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {string} updatingUserId - the updating user's id
 	 * @param {string} newType - the new type
 	 * @param {Function} cb - gets called with the result
@@ -1542,7 +1542,7 @@ export default {
 	/**
 	 * Updates a user's role
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {string} updatingUserId - the updating user's id
 	 * @param {string} newRole - the new role
 	 * @param {Function} cb - gets called with the result
@@ -1601,7 +1601,7 @@ export default {
 	/**
 	 * Updates a user's password
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {string} previousPassword - the previous password
 	 * @param {string} newPassword - the new password
 	 * @param {Function} cb - gets called with the result
@@ -1678,7 +1678,7 @@ export default {
 	/**
 	 * Requests a password for a session
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {string} email - the email of the user that requests a password reset
 	 * @param {Function} cb - gets called with the result
 	 */
@@ -1756,7 +1756,7 @@ export default {
 	/**
 	 * Verifies a password code
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {string} code - the password code
 	 * @param {Function} cb - gets called with the result
 	 */
@@ -1800,7 +1800,7 @@ export default {
 	/**
 	 * Adds a password to a user with a code
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {string} code - the password code
 	 * @param {string} newPassword - the new password code
 	 * @param {Function} cb - gets called with the result
@@ -1880,7 +1880,7 @@ export default {
 	/**
 	 * Unlinks password from user
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {Function} cb - gets called with the result
 	 */
 	unlinkPassword: isLoginRequired(async function unlinkPassword(session, cb) {
@@ -1927,7 +1927,7 @@ export default {
 	/**
 	 * Unlinks GitHub from user
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {Function} cb - gets called with the result
 	 */
 	unlinkGitHub: isLoginRequired(async function unlinkGitHub(session, cb) {
@@ -1974,7 +1974,7 @@ export default {
 	/**
 	 * Requests a password reset for an email
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {string} email - the email of the user that requests a password reset
 	 * @param {Function} cb - gets called with the result
 	 */
@@ -2053,7 +2053,7 @@ export default {
 	/**
 	 * Verifies a reset code
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {string} code - the password reset code
 	 * @param {Function} cb - gets called with the result
 	 */
@@ -2092,7 +2092,7 @@ export default {
 	/**
 	 * Changes a user's password with a reset code
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {string} code - the password reset code
 	 * @param {string} newPassword - the new password reset code
 	 * @param {Function} cb - gets called with the result
@@ -2165,7 +2165,7 @@ export default {
 	/**
 	 * Bans a user by userId
 	 *
-	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {object} session - the session object automatically added by the websocket
 	 * @param {string} value - the user id that is going to be banned
 	 * @param {string} reason - the reason for the ban
 	 * @param {string} expiresAt - the time the ban expires

+ 8 - 8
backend/logic/activities.js

@@ -6,7 +6,7 @@ let ActivitiesModule;
 let DBModule;
 let CacheModule;
 let UtilsModule;
-let IOModule;
+let WSModule;
 let PlaylistsModule;
 
 class _ActivitiesModule extends CoreClass {
@@ -27,7 +27,7 @@ class _ActivitiesModule extends CoreClass {
 			DBModule = this.moduleManager.modules.db;
 			CacheModule = this.moduleManager.modules.cache;
 			UtilsModule = this.moduleManager.modules.utils;
-			IOModule = this.moduleManager.modules.io;
+			WSModule = this.moduleManager.modules.ws;
 			PlaylistsModule = this.moduleManager.modules.playlists;
 
 			resolve();
@@ -72,7 +72,7 @@ class _ActivitiesModule extends CoreClass {
 					},
 
 					(activity, next) => {
-						IOModule.runJob("SOCKETS_FROM_USER", { userId: activity.userId }, this)
+						WSModule.runJob("SOCKETS_FROM_USER", { userId: activity.userId }, this)
 							.then(sockets => {
 								sockets.forEach(socket => socket.dispatch("event:activity.create", activity));
 								next(null, activity);
@@ -81,7 +81,7 @@ class _ActivitiesModule extends CoreClass {
 					},
 
 					(activity, next) => {
-						IOModule.runJob("EMIT_TO_ROOM", {
+						WSModule.runJob("EMIT_TO_ROOM", {
 							room: `profile-${activity.userId}-activities`,
 							args: ["event:activity.create", activity]
 						});
@@ -225,13 +225,13 @@ class _ActivitiesModule extends CoreClass {
 						activities.forEach(activity => {
 							activityModel.updateOne({ _id: activity._id }, { $set: { hidden: true } }).catch(next);
 
-							IOModule.runJob("SOCKETS_FROM_USER", { userId: payload.userId }, this)
+							WSModule.runJob("SOCKETS_FROM_USER", { userId: payload.userId }, this)
 								.then(sockets =>
 									sockets.forEach(socket => socket.dispatch("event:activity.hide", activity._id))
 								)
 								.catch(next);
 
-							IOModule.runJob("EMIT_TO_ROOM", {
+							WSModule.runJob("EMIT_TO_ROOM", {
 								room: `profile-${payload.userId}-activities`,
 								args: ["event:activity.hide", activity._id]
 							});
@@ -330,13 +330,13 @@ class _ActivitiesModule extends CoreClass {
 						activities.forEach(activity => {
 							activityModel.updateOne({ _id: activity._id }, { $set: { hidden: true } }).catch(next);
 
-							IOModule.runJob("SOCKETS_FROM_USER", { userId: payload.userId }, this)
+							WSModule.runJob("SOCKETS_FROM_USER", { userId: payload.userId }, this)
 								.then(sockets =>
 									sockets.forEach(socket => socket.dispatch("event:activity.hide", activity._id))
 								)
 								.catch(next);
 
-							IOModule.runJob("EMIT_TO_ROOM", {
+							WSModule.runJob("EMIT_TO_ROOM", {
 								room: `profile-${payload.userId}-activities`,
 								args: ["event:activity.hide", activity._id]
 							});

+ 13 - 13
backend/logic/stations.js

@@ -6,7 +6,7 @@ let StationsModule;
 let CacheModule;
 let DBModule;
 let UtilsModule;
-let IOModule;
+let WSModule;
 let SongsModule;
 let NotificationsModule;
 
@@ -27,7 +27,7 @@ class _StationsModule extends CoreClass {
 		CacheModule = this.moduleManager.modules.cache;
 		DBModule = this.moduleManager.modules.db;
 		UtilsModule = this.moduleManager.modules.utils;
-		IOModule = this.moduleManager.modules.io;
+		WSModule = this.moduleManager.modules.ws;
 		SongsModule = this.moduleManager.modules.songs;
 		NotificationsModule = this.moduleManager.modules.notifications;
 
@@ -83,7 +83,7 @@ class _StationsModule extends CoreClass {
 					key: stationId
 				}).then(playlistObj => {
 					if (playlistObj) {
-						IOModule.runJob("EMIT_TO_ROOM", {
+						WSModule.runJob("EMIT_TO_ROOM", {
 							room: `station.${stationId}`,
 							args: ["event:newOfficialPlaylist", playlistObj.songs]
 						});
@@ -905,7 +905,7 @@ class _StationsModule extends CoreClass {
 						}
 						// TODO Pub/Sub this
 
-						IOModule.runJob("EMIT_TO_ROOM", {
+						WSModule.runJob("EMIT_TO_ROOM", {
 							room: `station.${station._id}`,
 							args: [
 								"event:songs.next",
@@ -921,17 +921,17 @@ class _StationsModule extends CoreClass {
 							.catch();
 
 						if (station.privacy === "public") {
-							IOModule.runJob("EMIT_TO_ROOM", {
+							WSModule.runJob("EMIT_TO_ROOM", {
 								room: "home",
 								args: ["event:station.nextSong", station._id, station.currentSong]
 							})
 								.then()
 								.catch();
 						} else {
-							const sockets = await IOModule.runJob("GET_SOCKETS_FOR_ROOM", { room: "home" }, this);
+							const sockets = await WSModule.runJob("GET_SOCKETS_FOR_ROOM", { room: "home" }, this);
 
 							sockets.forEach(async socketId => {
-								const socket = await IOModule.runJob("SOCKET_FROM_SOCKET_ID", { socketId }, this);
+								const socket = await WSModule.runJob("SOCKET_FROM_SOCKET_ID", { socketId }, this);
 								const { session } = socket;
 
 								if (session.sessionId) {
@@ -980,8 +980,8 @@ class _StationsModule extends CoreClass {
 						}
 
 						if (station.currentSong !== null && station.currentSong.songId !== undefined) {
-							IOModule.runJob("SOCKETS_JOIN_SONG_ROOM", {
-								sockets: await IOModule.runJob(
+							WSModule.runJob("SOCKETS_JOIN_SONG_ROOM", {
+								sockets: await WSModule.runJob(
 									"GET_SOCKETS_FOR_ROOM",
 									{ room: `station.${station._id}` },
 									this
@@ -996,8 +996,8 @@ class _StationsModule extends CoreClass {
 								});
 							}
 						} else {
-							IOModule.runJob("SOCKETS_LEAVE_SONG_ROOMS", {
-								sockets: await IOModule.runJob(
+							WSModule.runJob("SOCKETS_LEAVE_SONG_ROOMS", {
+								sockets: await WSModule.runJob(
 									"GET_SOCKETS_FOR_ROOM",
 									{ room: `station.${station._id}` },
 									this
@@ -1117,12 +1117,12 @@ class _StationsModule extends CoreClass {
 	 *
 	 * @param {object} payload - the payload object
 	 * @param {object} payload.station - the station object
-	 * @param {string} payload.room - the socket.io room to get the sockets from
+	 * @param {string} payload.room - the websockets room to get the sockets from
 	 * @returns {Promise} - returns a promise (resolve, reject)
 	 */
 	GET_SOCKETS_THAT_CAN_KNOW_ABOUT_STATION(payload) {
 		return new Promise((resolve, reject) => {
-			IOModule.runJob("GET_SOCKETS_FOR_ROOM", { room: payload.room }, this)
+			WSModule.runJob("GET_SOCKETS_FOR_ROOM", { room: payload.room }, this)
 				.then(socketsObject => {
 					const sockets = Object.keys(socketsObject).map(socketKey => socketsObject[socketKey]);
 					let socketsThatCan = [];

+ 5 - 5
backend/logic/tasks.js

@@ -12,7 +12,7 @@ let TasksModule;
 let CacheModule;
 let StationsModule;
 let UtilsModule;
-let IOModule;
+let WSModule;
 let DBModule;
 
 class _TasksModule extends CoreClass {
@@ -37,7 +37,7 @@ class _TasksModule extends CoreClass {
 			CacheModule = this.moduleManager.modules.cache;
 			StationsModule = this.moduleManager.modules.stations;
 			UtilsModule = this.moduleManager.modules.utils;
-			IOModule = this.moduleManager.modules.io;
+			WSModule = this.moduleManager.modules.ws;
 			DBModule = this.moduleManager.modules.db;
 
 			// this.createTask("testTask", testTask, 5000, true);
@@ -245,7 +245,7 @@ class _TasksModule extends CoreClass {
 									}).finally(() => next2());
 								}
 								if (Date.now() - session.refreshDate > 60 * 60 * 24 * 30 * 1000) {
-									return IOModule.runJob("SOCKETS_FROM_SESSION_ID", {
+									return WSModule.runJob("SOCKETS_FROM_SESSION_ID", {
 										sessionId: session.sessionId
 									}).then(response => {
 										if (response.sockets.length > 0) {
@@ -360,9 +360,9 @@ class _TasksModule extends CoreClass {
 			async.each(
 				Object.keys(StationsModule.userList),
 				(socketId, next) => {
-					IOModule.runJob("SOCKET_FROM_SOCKET_ID", { socketId }).then(async socket => {
+					WSModule.runJob("SOCKET_FROM_SOCKET_ID", { socketId }).then(async socket => {
 						const stationId = StationsModule.userList[socketId];
-						const room = await IOModule.runJob("GET_SOCKETS_FOR_ROOM", { room: `station.${stationId}` });
+						const room = await WSModule.runJob("GET_SOCKETS_FOR_ROOM", { room: `station.${stationId}` });
 
 						if (!socket || room.includes(socketId)) {
 							if (stationsCountUpdated.indexOf(stationId) === -1) stationsCountUpdated.push(stationId);

+ 4 - 6
backend/logic/utils.js

@@ -2,7 +2,7 @@ import crypto from "crypto";
 import CoreClass from "../core";
 
 let UtilsModule;
-let IOModule;
+let WSModule;
 
 class _UtilsModule extends CoreClass {
 	// eslint-disable-next-line require-jsdoc
@@ -19,7 +19,7 @@ class _UtilsModule extends CoreClass {
 	 */
 	initialize() {
 		return new Promise(resolve => {
-			IOModule = this.moduleManager.modules.io;
+			WSModule = this.moduleManager.modules.ws;
 
 			resolve();
 		});
@@ -151,10 +151,8 @@ class _UtilsModule extends CoreClass {
 	 * @returns {Promise} - returns promise (reject, resolve)
 	 */
 	async GET_SOCKET_FROM_ID(payload) {
-		// socketId
-		const io = await IOModule.runJob("IO", {}, this);
-
-		return new Promise(resolve => resolve(io.sockets.sockets[payload.socketId]));
+		const ws = await WSModule.runJob("WS", {}, this);
+		return new Promise(resolve => resolve(ws.sockets.sockets[payload.socketId]));
 	}
 
 	/**

+ 104 - 117
backend/logic/io.js → backend/logic/ws.js

@@ -9,23 +9,23 @@ import { EventEmitter } from "events";
 
 import CoreClass from "../core";
 
-let IOModule;
+let WSModule;
 let AppModule;
 let CacheModule;
 let UtilsModule;
 let DBModule;
 let PunishmentsModule;
 
-class _IOModule extends CoreClass {
+class _WSModule extends CoreClass {
 	// eslint-disable-next-line require-jsdoc
 	constructor() {
-		super("io");
+		super("ws");
 
-		IOModule = this;
+		WSModule = this;
 	}
 
 	/**
-	 * Initialises the io module
+	 * Initialises the ws module
 	 *
 	 * @returns {Promise} - returns promise (reject, resolve)
 	 */
@@ -58,8 +58,6 @@ class _IOModule extends CoreClass {
 		return new Promise(resolve => {
 			this.setStage(3);
 
-			this.setStage(4);
-
 			this._io.on("connection", async (socket, req) => {
 				socket.dispatch = (...args) => socket.send(JSON.stringify(args));
 
@@ -67,26 +65,24 @@ class _IOModule extends CoreClass {
 				socket.actions.setMaxListeners(0);
 				socket.listen = (target, cb) => socket.actions.addListener(target, args => cb(args));
 
-				IOModule.runJob("HANDLE_IO_USE", { socket, req }).then(socket =>
-					IOModule.runJob("HANDLE_IO_CONNECTION", { socket })
+				WSModule.runJob("HANDLE_WS_USE", { socket, req }).then(socket =>
+					WSModule.runJob("HANDLE_WS_CONNECTION", { socket })
 				);
 			});
 
-			this.setStage(5);
+			this.setStage(4);
 
 			return resolve();
 		});
 	}
 
 	/**
-	 * Returns the socket io variable
+	 * Returns the websockets variable
 	 *
 	 * @returns {Promise} - returns a promise (resolve, reject)
 	 */
-	IO() {
-		return new Promise(resolve => {
-			resolve(IOModule._io);
-		});
+	WS() {
+		return new Promise(resolve => resolve(WSModule._io));
 	}
 
 	/**
@@ -98,13 +94,12 @@ class _IOModule extends CoreClass {
 	 */
 	async SOCKET_FROM_SOCKET_ID(payload) {
 		return new Promise((resolve, reject) => {
-			const { clients } = IOModule._io;
+			const { clients } = WSModule._io;
 
-			if (clients) {
+			if (clients)
 				return clients.forEach(socket => {
 					if (socket.session.socketId === payload.socketId) resolve(socket);
 				});
-			}
 
 			return reject();
 		});
@@ -119,7 +114,7 @@ class _IOModule extends CoreClass {
 	 */
 	async SOCKETS_FROM_SESSION_ID(payload) {
 		return new Promise(resolve => {
-			const { clients } = IOModule._io;
+			const { clients } = WSModule._io;
 			const sockets = [];
 
 			if (clients) {
@@ -150,7 +145,7 @@ class _IOModule extends CoreClass {
 			const sockets = [];
 
 			return async.eachLimit(
-				IOModule._io.clients,
+				WSModule._io.clients,
 				1,
 				(socket, next) => {
 					const { sessionId } = socket.session;
@@ -183,7 +178,7 @@ class _IOModule extends CoreClass {
 	 */
 	async SOCKETS_FROM_IP(payload) {
 		return new Promise(resolve => {
-			const { clients } = IOModule._io;
+			const { clients } = WSModule._io;
 
 			const sockets = [];
 
@@ -213,7 +208,7 @@ class _IOModule extends CoreClass {
 	 */
 	async SOCKETS_FROM_USER_WITHOUT_CACHE(payload) {
 		return new Promise(resolve => {
-			const { clients } = IOModule._io;
+			const { clients } = WSModule._io;
 			const sockets = [];
 
 			if (clients) {
@@ -242,8 +237,8 @@ class _IOModule extends CoreClass {
 	async SOCKET_LEAVE_ROOMS(payload) {
 		return new Promise(resolve => {
 			// filter out rooms that the user is in
-			Object.keys(IOModule.rooms).forEach(room => {
-				IOModule.rooms[room] = IOModule.rooms[room].filter(participant => participant !== payload.socketId);
+			Object.keys(WSModule.rooms).forEach(room => {
+				WSModule.rooms[room] = WSModule.rooms[room].filter(participant => participant !== payload.socketId);
 			});
 
 			return resolve();
@@ -262,12 +257,12 @@ class _IOModule extends CoreClass {
 		const { room, socketId } = payload;
 
 		// leave all other rooms
-		await IOModule.runJob("SOCKET_LEAVE_ROOMS", { socketId }, this);
+		await WSModule.runJob("SOCKET_LEAVE_ROOMS", { socketId }, this);
 
 		return new Promise(resolve => {
 			// create room if it doesn't exist, and add socketId to array
-			if (IOModule.rooms[room]) IOModule.rooms[room].push(socketId);
-			else IOModule.rooms[room] = [socketId];
+			if (WSModule.rooms[room]) WSModule.rooms[room].push(socketId);
+			else WSModule.rooms[room] = [socketId];
 
 			return resolve();
 		});
@@ -283,9 +278,11 @@ class _IOModule extends CoreClass {
 	 */
 	async EMIT_TO_ROOM(payload) {
 		return new Promise(resolve => {
-			if (IOModule.rooms[payload.room])
-				return IOModule.rooms[payload.room].forEach(async socketId => {
-					const socket = await IOModule.runJob("SOCKET_FROM_SOCKET_ID", { socketId }, this);
+			// if the room exists
+			if (WSModule.rooms[payload.room])
+				return WSModule.rooms[payload.room].forEach(async socketId => {
+					// get every socketId (and thus every socket) in the room, and dispatch to each
+					const socket = await WSModule.runJob("SOCKET_FROM_SOCKET_ID", { socketId }, this);
 					socket.dispatch(...payload.args);
 				});
 
@@ -305,12 +302,12 @@ class _IOModule extends CoreClass {
 		const { room, socketId } = payload;
 
 		// leave any other song rooms the user is in
-		await IOModule.runJob("SOCKETS_LEAVE_SONG_ROOMS", { sockets: [socketId] }, this);
+		await WSModule.runJob("SOCKETS_LEAVE_SONG_ROOMS", { sockets: [socketId] }, this);
 
 		return new Promise(resolve => {
 			// join the room
-			if (IOModule.rooms[room]) IOModule.rooms[room].push(socketId);
-			else IOModule.rooms[room] = [socketId];
+			if (WSModule.rooms[room]) WSModule.rooms[room].push(socketId);
+			else WSModule.rooms[room] = [socketId];
 
 			return resolve();
 		});
@@ -326,7 +323,7 @@ class _IOModule extends CoreClass {
 	 */
 	SOCKETS_JOIN_SONG_ROOM(payload) {
 		return new Promise(resolve => {
-			payload.sockets.forEach(socketId => IOModule.runJob("SOCKET_JOIN_SONG_ROOM", { socketId }, this));
+			payload.sockets.forEach(socketId => WSModule.runJob("SOCKET_JOIN_SONG_ROOM", { socketId }, this));
 			return resolve();
 		});
 	}
@@ -341,11 +338,11 @@ class _IOModule extends CoreClass {
 	SOCKETS_LEAVE_SONG_ROOMS(payload) {
 		return new Promise(resolve => {
 			payload.sockets.forEach(async socketId => {
-				const rooms = await IOModule.runJob("GET_ROOMS_FOR_SOCKET", { socketId }, this);
+				const rooms = await WSModule.runJob("GET_ROOMS_FOR_SOCKET", { socketId }, this);
 
 				rooms.forEach(room => {
 					if (room.indexOf("song.") !== -1)
-						IOModule.rooms[room] = IOModule.rooms[room].filter(
+						WSModule.rooms[room] = WSModule.rooms[room].filter(
 							participant => participant !== payload.socketId
 						);
 				});
@@ -364,7 +361,7 @@ class _IOModule extends CoreClass {
 	 */
 	async GET_SOCKETS_FOR_ROOM(payload) {
 		return new Promise(resolve => {
-			if (IOModule.rooms[payload.room]) return resolve(IOModule.rooms[payload.room]);
+			if (WSModule.rooms[payload.room]) return resolve(WSModule.rooms[payload.room]);
 			return resolve([]);
 		});
 	}
@@ -380,8 +377,8 @@ class _IOModule extends CoreClass {
 		return new Promise(resolve => {
 			const rooms = [];
 
-			Object.keys(IOModule.rooms).forEach(room => {
-				if (IOModule.rooms[room].includes(payload.socketId)) rooms.push(room);
+			Object.keys(WSModule.rooms).forEach(room => {
+				if (WSModule.rooms[room].includes(payload.socketId)) rooms.push(room);
 			});
 
 			return resolve(rooms);
@@ -389,20 +386,17 @@ class _IOModule extends CoreClass {
 	}
 
 	/**
-	 * Handles io.use
+	 * Handles use of websockets
 	 *
 	 * @param {object} payload - object that contains the payload
 	 * @returns {Promise} - returns promise (reject, resolve)
 	 */
-	async HANDLE_IO_USE(payload) {
-		console.log("io use");
-
+	async HANDLE_WS_USE(payload) {
 		return new Promise(resolve => {
 			const { socket, req } = payload;
+			let SID = "";
 
-			let SID;
-
-			socket.ip = req.headers["x-forwarded-for"] || "0.0.0.0";
+			socket.ip = req.headers["x-forwarded-for"] || "0..0.0";
 
 			return async.waterfall(
 				[
@@ -410,7 +404,7 @@ class _IOModule extends CoreClass {
 						if (!req.headers.cookie) return next("No cookie exists yet.");
 						return UtilsModule.runJob("PARSE_COOKIES", { cookieString: req.headers.cookie }, this).then(
 							res => {
-								SID = res[IOModule.SIDname];
+								SID = res[WSModule.SIDname];
 								next(null);
 							}
 						);
@@ -421,6 +415,7 @@ class _IOModule extends CoreClass {
 						return next();
 					},
 
+					// see if session exists for cookie
 					next => {
 						CacheModule.runJob("HGET", { table: "sessions", key: SID }, this)
 							.then(session => next(null, session))
@@ -465,16 +460,13 @@ class _IOModule extends CoreClass {
 
 								next();
 							})
-							.catch(() => {
-								next();
-							});
+							.catch(() => next());
 					}
 				],
 				() => {
 					if (!socket.session) socket.session = { socketId: req.headers["sec-websocket-key"] };
 					else socket.session.socketId = req.headers["sec-websocket-key"];
 
-					// cb();
 					resolve(socket);
 				}
 			);
@@ -482,24 +474,22 @@ class _IOModule extends CoreClass {
 	}
 
 	/**
-	 * Handles io.connection
+	 * Handles a websocket connection
 	 *
 	 * @param {object} payload - object that contains the payload
+	 * @param {object} payload.socket - socket itself
 	 * @returns {Promise} - returns promise (reject, resolve)
 	 */
-	async HANDLE_IO_CONNECTION(payload) {
-		console.log("handle io connection");
-
+	async HANDLE_WS_CONNECTION(payload) {
 		return new Promise(resolve => {
 			const { socket } = payload;
 
 			let sessionInfo = "";
-
 			if (socket.session.sessionId) sessionInfo = ` UserID: ${socket.session.userId}.`;
 
 			// if session is banned
 			if (socket.banishment && socket.banishment.banned) {
-				IOModule.log(
+				WSModule.log(
 					"INFO",
 					"IO_BANNED_CONNECTION",
 					`A user tried to connect, but is currently banned. IP: ${socket.ip}.${sessionInfo}`
@@ -507,43 +497,24 @@ class _IOModule extends CoreClass {
 
 				socket.dispatch("keep.event:banned", socket.banishment.ban);
 
-				return socket.disconnect(true); // doesn't work - need to fix
+				return socket.close(); // close socket connection
 			}
 
-			IOModule.log("INFO", "IO_CONNECTION", `User connected. IP: ${socket.ip}.${sessionInfo}`);
+			WSModule.log("INFO", "IO_CONNECTION", `User connected. IP: ${socket.ip}.${sessionInfo}`);
 
 			// catch when the socket has been disconnected
 			socket.on("close", async () => {
 				if (socket.session.sessionId) sessionInfo = ` UserID: ${socket.session.userId}.`;
-				IOModule.log("INFO", "IO_DISCONNECTION", `User disconnected. IP: ${socket.ip}.${sessionInfo}`);
+				WSModule.log("INFO", "IO_DISCONNECTION", `User disconnected. IP: ${socket.ip}.${sessionInfo}`);
 
-				await IOModule.runJob("SOCKET_LEAVE_ROOMS", { socketId: socket.session.socketId });
+				// leave all rooms when a socket connection is closed (to prevent rooms object building up)
+				await WSModule.runJob("SOCKET_LEAVE_ROOMS", { socketId: socket.session.socketId });
 			});
 
-			// socket.use((data, next) => {
-			// 	if (data.length === 0) return next(new Error("Not enough arguments specified."));
-			// 	if (typeof data[0] !== "string") return next(new Error("First argument must be a string."));
-
-			// 	const namespaceAction = data[0];
-			// 	if (
-			// 		!namespaceAction ||
-			// 		namespaceAction.indexOf(".") === -1 ||
-			// 		namespaceAction.indexOf(".") !== namespaceAction.lastIndexOf(".")
-			// 	)
-			// 		return next(new Error("Invalid first argument"));
-			// 	const namespace = data[0].split(".")[0];
-			// 	const action = data[0].split(".")[1];
-
-			// 	if (!namespace) return next(new Error("Invalid namespace."));
-			// 	if (!action) return next(new Error("Invalid action."));
-			// 	if (!IOModule.actions[namespace]) return next(new Error("Namespace not found."));
-			// 	if (!IOModule.actions[namespace][action]) return next(new Error("Action not found."));
-
-			// 	return next();
-			// });
-
-			// catch errors on the socket (internal to socket.io)
-			socket.onerror = console.error; // need to update
+			// catch errors on the socket
+			socket.onerror = error => {
+				console.error("SOCKET ERROR: ", error);
+			};
 
 			if (socket.session.sessionId) {
 				CacheModule.runJob("HGET", {
@@ -552,12 +523,13 @@ class _IOModule extends CoreClass {
 				})
 					.then(session => {
 						if (session && session.userId) {
-							IOModule.userModel.findOne({ _id: session.userId }, (err, user) => {
+							WSModule.userModel.findOne({ _id: session.userId }, (err, user) => {
 								if (err || !user) return socket.dispatch("ready", false);
 
 								let role = "";
 								let username = "";
 								let userId = "";
+
 								if (user) {
 									role = user.role;
 									username = user.username;
@@ -568,35 +540,50 @@ class _IOModule extends CoreClass {
 							});
 						} else socket.dispatch("ready", false);
 					})
-					.catch(() => {
-						socket.dispatch("ready", false);
-					});
+					.catch(() => socket.dispatch("ready", false));
 			} else socket.dispatch("ready", false);
 
-			// have the socket listen for each action
-			Object.keys(IOModule.actions).forEach(namespace => {
-				Object.keys(IOModule.actions[namespace]).forEach(action => {
-					// the full name of the action
-					const name = `${namespace}.${action}`;
+			socket.onmessage = message => {
+				const data = JSON.parse(message.data);
 
-					socket.onmessage = message => {
-						const data = JSON.parse(message.data);
+				if (data.length === 0) return socket.dispatch("ERROR", "Not enough arguments specified.");
+				if (typeof data[0] !== "string") return socket.dispatch("ERROR", "First argument must be a string.");
 
-						if (data[data.length - 1].callbackRef) {
-							const { callbackRef } = data[data.length - 1];
-							data.pop();
-							return socket.actions.emit(data.shift(0), [
-								...data,
-								res => socket.dispatch("callbackRef", callbackRef, res)
-							]);
-						}
+				const namespaceAction = data[0];
+				if (
+					!namespaceAction ||
+					namespaceAction.indexOf(".") === -1 ||
+					namespaceAction.indexOf(".") !== namespaceAction.lastIndexOf(".")
+				)
+					return socket.dispatch("ERROR", "Invalid first argument");
+
+				const namespace = data[0].split(".")[0];
+				const action = data[0].split(".")[1];
+
+				if (!namespace) return socket.dispatch("ERROR", "Invalid namespace.");
+				if (!action) return socket.dispatch("ERROR", "Invalid action.");
+				if (!WSModule.actions[namespace]) return socket.dispatch("ERROR", "Namespace not found.");
+				if (!WSModule.actions[namespace][action]) return socket.dispatch("ERROR", "Action not found.");
 
-						return socket.actions.emit(data.shift(0), data);
-					};
+				if (data[data.length - 1].CB_REF) {
+					const { CB_REF } = data[data.length - 1];
+					data.pop();
+
+					return socket.actions.emit(data.shift(0), [...data, res => socket.dispatch("CB_REF", CB_REF, res)]);
+				}
+
+				return socket.actions.emit(data.shift(0), data);
+			};
+
+			// have the socket listen for each action
+			Object.keys(WSModule.actions).forEach(namespace => {
+				Object.keys(WSModule.actions[namespace]).forEach(action => {
+					// the full name of the action
+					const name = `${namespace}.${action}`;
 
 					// listen for this action to be called
 					socket.listen(name, async args =>
-						IOModule.runJob("RUN_ACTION", { socket, namespace, action, args })
+						WSModule.runJob("RUN_ACTION", { socket, namespace, action, args })
 					);
 				});
 			});
@@ -622,11 +609,11 @@ class _IOModule extends CoreClass {
 
 			if (typeof cb !== "function")
 				cb = () => {
-					IOModule.log("INFO", "IO_MODULE", `There was no callback provided for ${name}.`);
+					WSModule.log("INFO", "IO_MODULE", `There was no callback provided for ${name}.`);
 				};
 			else args.pop();
 
-			IOModule.log("INFO", "IO_ACTION", `A user executed an action. Action: ${namespace}.${action}.`);
+			WSModule.log("INFO", "IO_ACTION", `A user executed an action. Action: ${namespace}.${action}.`);
 
 			// load the session from the cache
 			new Promise(resolve => {
@@ -651,9 +638,9 @@ class _IOModule extends CoreClass {
 				else resolve();
 			})
 				.then(() => {
-					// call the job that calls the action, passing it the session, and the arguments socket.io passed us
+					// call the job that calls the action, passing it the session, and the arguments the websocket passed us
 
-					IOModule.runJob("RUN_ACTION2", { session: socket.session, namespace, action, args }, this)
+					WSModule.runJob("RUN_ACTION2", { session: socket.session, namespace, action, args }, this)
 						.then(response => {
 							cb(response);
 							resolve();
@@ -667,7 +654,7 @@ class _IOModule extends CoreClass {
 
 							reject(err);
 
-							IOModule.log(
+							WSModule.log(
 								"ERROR",
 								"IO_ACTION_ERROR",
 								`Some type of exception occurred in the action ${namespace}.${action}. Error message: ${err.message}`
@@ -689,12 +676,12 @@ class _IOModule extends CoreClass {
 			const { session, namespace, action, args } = payload;
 
 			try {
-				// call the the action, passing it the session, and the arguments socket.io passed us
-				IOModule.actions[namespace][action].apply(
+				// call the the action, passing it the session, and the arguments the websocket passed us
+				WSModule.actions[namespace][action].apply(
 					this,
 					[session].concat(args).concat([
 						result => {
-							IOModule.log(
+							WSModule.log(
 								"INFO",
 								"RUN_ACTION2",
 								`Response to action. Action: ${namespace}.${action}. Response status: ${result.status}`
@@ -706,7 +693,7 @@ class _IOModule extends CoreClass {
 			} catch (err) {
 				reject(err);
 
-				IOModule.log(
+				WSModule.log(
 					"ERROR",
 					"IO_ACTION_ERROR",
 					`Some type of exception occurred in the action ${namespace}.${action}. Error message: ${err.message}`
@@ -716,4 +703,4 @@ class _IOModule extends CoreClass {
 	}
 }
 
-export default new _IOModule();
+export default new _WSModule();

+ 0 - 552
backend/package-lock.json

@@ -24,7 +24,6 @@
         "oauth": "^0.9.15",
         "redis": "^2.8.0",
         "sha256": "^0.2.0",
-        "socket.io": "2.4.1",
         "underscore": "^1.10.2",
         "ws": "^7.4.3"
       },
@@ -232,11 +231,6 @@
       "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==",
       "dev": true
     },
-    "node_modules/after": {
-      "version": "0.8.2",
-      "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz",
-      "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8="
-    },
     "node_modules/ajv": {
       "version": "6.12.6",
       "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
@@ -336,11 +330,6 @@
         "node": ">= 0.4"
       }
     },
-    "node_modules/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=="
-    },
     "node_modules/astral-regex": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz",
@@ -363,32 +352,11 @@
         "follow-redirects": "^1.10.0"
       }
     },
-    "node_modules/backo2": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz",
-      "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc="
-    },
     "node_modules/balanced-match": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
       "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
     },
-    "node_modules/base64-arraybuffer": {
-      "version": "0.1.4",
-      "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz",
-      "integrity": "sha1-mBjHngWbE1X5fgQooBfIOOkLqBI=",
-      "engines": {
-        "node": ">= 0.6.0"
-      }
-    },
-    "node_modules/base64id": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz",
-      "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==",
-      "engines": {
-        "node": "^4.5.0 || >= 5.9"
-      }
-    },
     "node_modules/bcrypt": {
       "version": "5.0.0",
       "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.0.0.tgz",
@@ -411,11 +379,6 @@
         "safe-buffer": "^5.1.1"
       }
     },
-    "node_modules/blob": {
-      "version": "0.0.5",
-      "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz",
-      "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig=="
-    },
     "node_modules/bluebird": {
       "version": "3.7.2",
       "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
@@ -551,21 +514,6 @@
         "node": ">= 6.0.0"
       }
     },
-    "node_modules/component-bind": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz",
-      "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E="
-    },
-    "node_modules/component-emitter": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz",
-      "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg=="
-    },
-    "node_modules/component-inherit": {
-      "version": "0.0.3",
-      "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz",
-      "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM="
-    },
     "node_modules/concat-map": {
       "version": "0.0.1",
       "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@@ -631,14 +579,6 @@
       "resolved": "https://registry.npmjs.org/convert-string/-/convert-string-0.1.0.tgz",
       "integrity": "sha1-ec5BqbsNA7z3LNxqjzxW+7xkQQo="
     },
-    "node_modules/cookie": {
-      "version": "0.4.1",
-      "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz",
-      "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==",
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
     "node_modules/cookie-parser": {
       "version": "1.4.5",
       "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.5.tgz",
@@ -802,73 +742,6 @@
         "node": ">= 0.8"
       }
     },
-    "node_modules/engine.io": {
-      "version": "3.5.0",
-      "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.5.0.tgz",
-      "integrity": "sha512-21HlvPUKaitDGE4GXNtQ7PLP0Sz4aWLddMPw2VTyFz1FVZqu/kZsJUO8WNpKuE/OCL7nkfRaOui2ZCJloGznGA==",
-      "dependencies": {
-        "accepts": "~1.3.4",
-        "base64id": "2.0.0",
-        "cookie": "~0.4.1",
-        "debug": "~4.1.0",
-        "engine.io-parser": "~2.2.0",
-        "ws": "~7.4.2"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/engine.io-client": {
-      "version": "3.5.0",
-      "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.5.0.tgz",
-      "integrity": "sha512-12wPRfMrugVw/DNyJk34GQ5vIVArEcVMXWugQGGuw2XxUSztFNmJggZmv8IZlLyEdnpO1QB9LkcjeWewO2vxtA==",
-      "dependencies": {
-        "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.5.4",
-        "yeast": "0.1.2"
-      }
-    },
-    "node_modules/engine.io-client/node_modules/debug": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
-      "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
-      "dependencies": {
-        "ms": "2.0.0"
-      }
-    },
-    "node_modules/engine.io-client/node_modules/ms": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
-    },
-    "node_modules/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==",
-      "dependencies": {
-        "after": "0.8.2",
-        "arraybuffer.slice": "~0.0.7",
-        "base64-arraybuffer": "0.1.4",
-        "blob": "0.0.5",
-        "has-binary2": "~1.0.2"
-      }
-    },
-    "node_modules/engine.io/node_modules/debug": {
-      "version": "4.1.1",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
-      "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
-      "dependencies": {
-        "ms": "^2.1.1"
-      }
-    },
     "node_modules/enquirer": {
       "version": "2.3.6",
       "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz",
@@ -1782,24 +1655,6 @@
         "node": ">= 0.4.0"
       }
     },
-    "node_modules/has-binary2": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz",
-      "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==",
-      "dependencies": {
-        "isarray": "2.0.1"
-      }
-    },
-    "node_modules/has-binary2/node_modules/isarray": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz",
-      "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4="
-    },
-    "node_modules/has-cors": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz",
-      "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk="
-    },
     "node_modules/has-flag": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
@@ -1921,11 +1776,6 @@
         "node": ">=0.8.19"
       }
     },
-    "node_modules/indexof": {
-      "version": "0.0.1",
-      "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz",
-      "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10="
-    },
     "node_modules/inflight": {
       "version": "1.0.6",
       "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
@@ -2719,16 +2569,6 @@
         "node": ">=0.10.0"
       }
     },
-    "node_modules/parseqs": {
-      "version": "0.0.6",
-      "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.6.tgz",
-      "integrity": "sha512-jeAGzMDbfSHHA091hr0r31eYfTig+29g3GKKE/PPbEQ65X0lmMwlEoqmhzu0iztID5uJpZsFlUPDP8ThPL7M8w=="
-    },
-    "node_modules/parseuri": {
-      "version": "0.0.6",
-      "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.6.tgz",
-      "integrity": "sha512-AUjen8sAkGgao7UyCX6Ahv0gIK2fABKmYjvP4xmy5JaKvcbTRueIqIPHLAfq30xJddqSE033IOMUSOMCcK3Sow=="
-    },
     "node_modules/parseurl": {
       "version": "1.3.3",
       "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
@@ -3206,106 +3046,6 @@
       "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz",
       "integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E="
     },
-    "node_modules/socket.io": {
-      "version": "2.4.1",
-      "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.4.1.tgz",
-      "integrity": "sha512-Si18v0mMXGAqLqCVpTxBa8MGqriHGQh8ccEOhmsmNS3thNCGBwO8WGrwMibANsWtQQ5NStdZwHqZR3naJVFc3w==",
-      "dependencies": {
-        "debug": "~4.1.0",
-        "engine.io": "~3.5.0",
-        "has-binary2": "~1.0.2",
-        "socket.io-adapter": "~1.1.0",
-        "socket.io-client": "2.4.0",
-        "socket.io-parser": "~3.4.0"
-      }
-    },
-    "node_modules/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=="
-    },
-    "node_modules/socket.io-client": {
-      "version": "2.4.0",
-      "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.4.0.tgz",
-      "integrity": "sha512-M6xhnKQHuuZd4Ba9vltCLT9oa+YvTsP8j9NcEiLElfIg8KeYPyhWOes6x4t+LTAC8enQbE/995AdTem2uNyKKQ==",
-      "dependencies": {
-        "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"
-      }
-    },
-    "node_modules/socket.io-client/node_modules/debug": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
-      "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
-      "dependencies": {
-        "ms": "2.0.0"
-      }
-    },
-    "node_modules/socket.io-client/node_modules/isarray": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz",
-      "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4="
-    },
-    "node_modules/socket.io-client/node_modules/ms": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
-    },
-    "node_modules/socket.io-client/node_modules/socket.io-parser": {
-      "version": "3.3.2",
-      "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.2.tgz",
-      "integrity": "sha512-FJvDBuOALxdCI9qwRrO/Rfp9yfndRtc1jSgVgV8FDraihmSP/MLGD5PEuJrNfjALvcQ+vMDM/33AWOYP/JSjDg==",
-      "dependencies": {
-        "component-emitter": "~1.3.0",
-        "debug": "~3.1.0",
-        "isarray": "2.0.1"
-      }
-    },
-    "node_modules/socket.io-parser": {
-      "version": "3.4.1",
-      "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.4.1.tgz",
-      "integrity": "sha512-11hMgzL+WCLWf1uFtHSNvliI++tcRUWdoeYuwIl+Axvwy9z2gQM+7nJyN3STj1tLj5JyIUH8/gpDGxzAlDdi0A==",
-      "dependencies": {
-        "component-emitter": "1.2.1",
-        "debug": "~4.1.0",
-        "isarray": "2.0.1"
-      }
-    },
-    "node_modules/socket.io-parser/node_modules/component-emitter": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
-      "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY="
-    },
-    "node_modules/socket.io-parser/node_modules/debug": {
-      "version": "4.1.1",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
-      "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
-      "dependencies": {
-        "ms": "^2.1.1"
-      }
-    },
-    "node_modules/socket.io-parser/node_modules/isarray": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz",
-      "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4="
-    },
-    "node_modules/socket.io/node_modules/debug": {
-      "version": "4.1.1",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
-      "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
-      "dependencies": {
-        "ms": "^2.1.1"
-      }
-    },
     "node_modules/sparse-bitfield": {
       "version": "3.0.3",
       "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz",
@@ -3553,11 +3293,6 @@
       "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
       "dev": true
     },
-    "node_modules/to-array": {
-      "version": "0.1.4",
-      "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz",
-      "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA="
-    },
     "node_modules/toidentifier": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
@@ -3742,23 +3477,10 @@
         }
       }
     },
-    "node_modules/xmlhttprequest-ssl": {
-      "version": "1.5.5",
-      "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz",
-      "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4=",
-      "engines": {
-        "node": ">=0.4.0"
-      }
-    },
     "node_modules/yallist": {
       "version": "3.1.1",
       "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
       "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="
-    },
-    "node_modules/yeast": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz",
-      "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk="
     }
   },
   "dependencies": {
@@ -3929,11 +3651,6 @@
       "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==",
       "dev": true
     },
-    "after": {
-      "version": "0.8.2",
-      "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz",
-      "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8="
-    },
     "ajv": {
       "version": "6.12.6",
       "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
@@ -4018,11 +3735,6 @@
         "es-abstract": "^1.18.0-next.1"
       }
     },
-    "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=="
-    },
     "astral-regex": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz",
@@ -4042,26 +3754,11 @@
         "follow-redirects": "^1.10.0"
       }
     },
-    "backo2": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz",
-      "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc="
-    },
     "balanced-match": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
       "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
     },
-    "base64-arraybuffer": {
-      "version": "0.1.4",
-      "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz",
-      "integrity": "sha1-mBjHngWbE1X5fgQooBfIOOkLqBI="
-    },
-    "base64id": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz",
-      "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog=="
-    },
     "bcrypt": {
       "version": "5.0.0",
       "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.0.0.tgz",
@@ -4080,11 +3777,6 @@
         "safe-buffer": "^5.1.1"
       }
     },
-    "blob": {
-      "version": "0.0.5",
-      "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz",
-      "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig=="
-    },
     "bluebird": {
       "version": "3.7.2",
       "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
@@ -4198,21 +3890,6 @@
       "integrity": "sha512-GKNxVA7/iuTnAqGADlTWX4tkhzxZKXp5fLJqKTlQLHkE65XDUKutZ3BHaJC5IGcper2tT3QRD1xr4o3jNpgXXg==",
       "dev": true
     },
-    "component-bind": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz",
-      "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E="
-    },
-    "component-emitter": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz",
-      "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg=="
-    },
-    "component-inherit": {
-      "version": "0.0.3",
-      "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz",
-      "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM="
-    },
     "concat-map": {
       "version": "0.0.1",
       "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@@ -4266,11 +3943,6 @@
       "resolved": "https://registry.npmjs.org/convert-string/-/convert-string-0.1.0.tgz",
       "integrity": "sha1-ec5BqbsNA7z3LNxqjzxW+7xkQQo="
     },
-    "cookie": {
-      "version": "0.4.1",
-      "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz",
-      "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA=="
-    },
     "cookie-parser": {
       "version": "1.4.5",
       "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.5.tgz",
@@ -4400,74 +4072,6 @@
       "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
       "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
     },
-    "engine.io": {
-      "version": "3.5.0",
-      "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.5.0.tgz",
-      "integrity": "sha512-21HlvPUKaitDGE4GXNtQ7PLP0Sz4aWLddMPw2VTyFz1FVZqu/kZsJUO8WNpKuE/OCL7nkfRaOui2ZCJloGznGA==",
-      "requires": {
-        "accepts": "~1.3.4",
-        "base64id": "2.0.0",
-        "cookie": "~0.4.1",
-        "debug": "~4.1.0",
-        "engine.io-parser": "~2.2.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==",
-          "requires": {
-            "ms": "^2.1.1"
-          }
-        }
-      }
-    },
-    "engine.io-client": {
-      "version": "3.5.0",
-      "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.5.0.tgz",
-      "integrity": "sha512-12wPRfMrugVw/DNyJk34GQ5vIVArEcVMXWugQGGuw2XxUSztFNmJggZmv8IZlLyEdnpO1QB9LkcjeWewO2vxtA==",
-      "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.5.4",
-        "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==",
-          "requires": {
-            "ms": "2.0.0"
-          }
-        },
-        "ms": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
-        }
-      }
-    },
-    "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==",
-      "requires": {
-        "after": "0.8.2",
-        "arraybuffer.slice": "~0.0.7",
-        "base64-arraybuffer": "0.1.4",
-        "blob": "0.0.5",
-        "has-binary2": "~1.0.2"
-      }
-    },
     "enquirer": {
       "version": "2.3.6",
       "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz",
@@ -5226,26 +4830,6 @@
         "function-bind": "^1.1.1"
       }
     },
-    "has-binary2": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz",
-      "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==",
-      "requires": {
-        "isarray": "2.0.1"
-      },
-      "dependencies": {
-        "isarray": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz",
-          "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4="
-        }
-      }
-    },
-    "has-cors": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz",
-      "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk="
-    },
     "has-flag": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
@@ -5344,11 +4928,6 @@
       "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
       "dev": true
     },
-    "indexof": {
-      "version": "0.0.1",
-      "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz",
-      "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10="
-    },
     "inflight": {
       "version": "1.0.6",
       "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
@@ -5981,16 +5560,6 @@
         "error-ex": "^1.2.0"
       }
     },
-    "parseqs": {
-      "version": "0.0.6",
-      "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.6.tgz",
-      "integrity": "sha512-jeAGzMDbfSHHA091hr0r31eYfTig+29g3GKKE/PPbEQ65X0lmMwlEoqmhzu0iztID5uJpZsFlUPDP8ThPL7M8w=="
-    },
-    "parseuri": {
-      "version": "0.0.6",
-      "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.6.tgz",
-      "integrity": "sha512-AUjen8sAkGgao7UyCX6Ahv0gIK2fABKmYjvP4xmy5JaKvcbTRueIqIPHLAfq30xJddqSE033IOMUSOMCcK3Sow=="
-    },
     "parseurl": {
       "version": "1.3.3",
       "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
@@ -6375,112 +5944,6 @@
       "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz",
       "integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E="
     },
-    "socket.io": {
-      "version": "2.4.1",
-      "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.4.1.tgz",
-      "integrity": "sha512-Si18v0mMXGAqLqCVpTxBa8MGqriHGQh8ccEOhmsmNS3thNCGBwO8WGrwMibANsWtQQ5NStdZwHqZR3naJVFc3w==",
-      "requires": {
-        "debug": "~4.1.0",
-        "engine.io": "~3.5.0",
-        "has-binary2": "~1.0.2",
-        "socket.io-adapter": "~1.1.0",
-        "socket.io-client": "2.4.0",
-        "socket.io-parser": "~3.4.0"
-      },
-      "dependencies": {
-        "debug": {
-          "version": "4.1.1",
-          "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
-          "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
-          "requires": {
-            "ms": "^2.1.1"
-          }
-        }
-      }
-    },
-    "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=="
-    },
-    "socket.io-client": {
-      "version": "2.4.0",
-      "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.4.0.tgz",
-      "integrity": "sha512-M6xhnKQHuuZd4Ba9vltCLT9oa+YvTsP8j9NcEiLElfIg8KeYPyhWOes6x4t+LTAC8enQbE/995AdTem2uNyKKQ==",
-      "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==",
-          "requires": {
-            "ms": "2.0.0"
-          }
-        },
-        "isarray": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz",
-          "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4="
-        },
-        "ms": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
-        },
-        "socket.io-parser": {
-          "version": "3.3.2",
-          "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.2.tgz",
-          "integrity": "sha512-FJvDBuOALxdCI9qwRrO/Rfp9yfndRtc1jSgVgV8FDraihmSP/MLGD5PEuJrNfjALvcQ+vMDM/33AWOYP/JSjDg==",
-          "requires": {
-            "component-emitter": "~1.3.0",
-            "debug": "~3.1.0",
-            "isarray": "2.0.1"
-          }
-        }
-      }
-    },
-    "socket.io-parser": {
-      "version": "3.4.1",
-      "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.4.1.tgz",
-      "integrity": "sha512-11hMgzL+WCLWf1uFtHSNvliI++tcRUWdoeYuwIl+Axvwy9z2gQM+7nJyN3STj1tLj5JyIUH8/gpDGxzAlDdi0A==",
-      "requires": {
-        "component-emitter": "1.2.1",
-        "debug": "~4.1.0",
-        "isarray": "2.0.1"
-      },
-      "dependencies": {
-        "component-emitter": {
-          "version": "1.2.1",
-          "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
-          "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY="
-        },
-        "debug": {
-          "version": "4.1.1",
-          "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
-          "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
-          "requires": {
-            "ms": "^2.1.1"
-          }
-        },
-        "isarray": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz",
-          "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4="
-        }
-      }
-    },
     "sparse-bitfield": {
       "version": "3.0.3",
       "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz",
@@ -6690,11 +6153,6 @@
       "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
       "dev": true
     },
-    "to-array": {
-      "version": "0.1.4",
-      "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz",
-      "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA="
-    },
     "toidentifier": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
@@ -6831,20 +6289,10 @@
       "integrity": "sha512-hr6vCR76GsossIRsr8OLR9acVVm1jyfEWvhbNjtgPOrfvAlKzvyeg/P6r8RuDjRyrcQoPQT7K0DGEPc7Ae6jzA==",
       "requires": {}
     },
-    "xmlhttprequest-ssl": {
-      "version": "1.5.5",
-      "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz",
-      "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4="
-    },
     "yallist": {
       "version": "3.1.1",
       "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
       "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="
-    },
-    "yeast": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz",
-      "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk="
     }
   }
 }

+ 0 - 1
backend/package.json

@@ -30,7 +30,6 @@
     "oauth": "^0.9.15",
     "redis": "^2.8.0",
     "sha256": "^0.2.0",
-    "socket.io": "2.4.1",
     "underscore": "^1.10.2",
     "ws": "^7.4.3"
   },

+ 0 - 1
frontend/dist/index.tpl.html

@@ -36,7 +36,6 @@
 	<link rel='stylesheet' href='/index.css'>
 	<script src='https://www.youtube.com/iframe_api'></script>
 	<script type='text/javascript' src='/vendor/can-autoplay.min.js'></script>
-	<script src="/vendor/socket.io.2.2.0.js"></script>
 	<script type='text/javascript' src='/vendor/lofig.1.3.3.min.js'></script>
 </head>
 <body>

File diff suppressed because it is too large
+ 0 - 5
frontend/dist/vendor/socket.io.2.2.0.js


+ 3 - 3
frontend/src/App.vue

@@ -18,7 +18,7 @@ import Banned from "./pages/Banned.vue";
 import WhatIsNew from "./components/modals/WhatIsNew.vue";
 import LoginModal from "./components/modals/Login.vue";
 import RegisterModal from "./components/modals/Register.vue";
-import io from "./io";
+import ws from "./ws";
 import keyboardShortcuts from "./keyboardShortcuts";
 
 export default {
@@ -112,11 +112,11 @@ export default {
 			localStorage.removeItem("github_redirect");
 		}
 
-		io.onConnect(true, () => {
+		ws.onConnect(true, () => {
 			this.socketConnected = true;
 		});
 
-		io.onDisconnect(true, () => {
+		ws.onDisconnect(true, () => {
 			this.socketConnected = false;
 		});
 

+ 1 - 1
frontend/src/api/admin/index.js

@@ -2,7 +2,7 @@
 
 import reports from "./reports";
 
-// when Vuex needs to interact with socket.io
+// when Vuex needs to interact with websockets
 
 export default {
 	reports

+ 5 - 5
frontend/src/api/admin/reports.js

@@ -1,17 +1,17 @@
 /* eslint-disable import/no-cycle */
 
 import Toast from "toasters";
-import io from "../../io";
+import ws from "../../ws";
 
 export default {
 	resolve(reportId) {
-		return new Promise((resolve, reject) => {
-			io.socket.dispatch("reports.resolve", reportId, res => {
+		return new Promise((resolve, reject) =>
+			ws.socket.dispatch("reports.resolve", reportId, res => {
 				new Toast({ content: res.message, timeout: 3000 });
 				if (res.status === "success")
 					return resolve({ status: "success" });
 				return reject(new Error(res.message));
-			});
-		});
+			})
+		);
 	}
 };

+ 5 - 5
frontend/src/api/auth.js

@@ -1,16 +1,16 @@
 /* eslint-disable import/no-cycle */
 
 import Toast from "toasters";
-import io from "../io";
+import ws from "../ws";
 
-// when Vuex needs to interact with socket.io
+// when Vuex needs to interact with websockets
 
 export default {
 	register(user) {
 		return new Promise((resolve, reject) => {
 			const { username, email, password, recaptchaToken } = user;
 
-			io.socket.dispatch(
+			ws.socket.dispatch(
 				"users.register",
 				username,
 				email,
@@ -52,7 +52,7 @@ export default {
 		return new Promise((resolve, reject) => {
 			const { email, password } = user;
 
-			io.socket.dispatch("users.login", email, password, res => {
+			ws.socket.dispatch("users.login", email, password, res => {
 				console.log(123, res);
 				if (res.status === "success") {
 					return lofig.get("cookie").then(cookie => {
@@ -77,7 +77,7 @@ export default {
 	},
 	logout() {
 		return new Promise((resolve, reject) => {
-			io.socket.dispatch("users.logout", res => {
+			ws.socket.dispatch("users.logout", res => {
 				if (res.status === "success") {
 					return lofig.get("cookie").then(cookie => {
 						document.cookie = `${cookie.SIDname}=;expires=Thu, 01 Jan 1970 00:00:01 GMT;`;

+ 8 - 8
frontend/src/main.js

@@ -4,7 +4,7 @@ import VueRouter from "vue-router";
 import store from "./store";
 
 import App from "./App.vue";
-import io from "./io";
+import ws from "./ws";
 
 const REQUIRED_CONFIG_VERSION = 1;
 
@@ -138,9 +138,9 @@ const router = new VueRouter({
 });
 
 // const { serverDomain } = config;
-io.init({ url: "ws://localhost:8080/ws" });
+ws.init({ url: "ws://localhost:8080/ws" });
 
-io.socket.on("ready", (loggedIn, role, username, userId) =>
+ws.socket.on("ready", (loggedIn, role, username, userId) =>
 	store.dispatch("user/auth/authData", {
 		loggedIn,
 		role,
@@ -149,15 +149,15 @@ io.socket.on("ready", (loggedIn, role, username, userId) =>
 	})
 );
 
-io.socket.on("keep.event:banned", ban =>
+ws.socket.on("keep.event:banned", ban =>
 	store.dispatch("user/auth/banUser", ban)
 );
 
-io.socket.on("event:user.username.changed", username =>
+ws.socket.on("event:user.username.changed", username =>
 	store.dispatch("user/auth/updateUsername", username)
 );
 
-io.socket.on("keep.event:user.preferences.changed", preferences => {
+ws.socket.on("keep.event:user.preferences.changed", preferences => {
 	store.dispatch(
 		"user/preferences/changeAutoSkipDisliked",
 		preferences.autoSkipDisliked
@@ -189,9 +189,9 @@ router.beforeEach((to, from, next) => {
 		window.stationInterval = 0;
 	}
 
-	if (window.socket) io.removeAllListeners();
+	if (window.socket) ws.removeAllListeners();
 
-	io.clear();
+	ws.clear();
 
 	if (to.meta.loginRequired || to.meta.adminRequired) {
 		const gotData = () => {

+ 2 - 2
frontend/src/pages/Admin/tabs/NewStatistics.vue

@@ -193,7 +193,7 @@
 <script>
 import { mapGetters } from "vuex";
 
-import io from "../../../io";
+import ws from "../../../ws";
 
 export default {
 	components: {},
@@ -208,7 +208,7 @@ export default {
 	}),
 	mounted() {
 		if (this.socket.readyState === 1) this.init();
-		io.onConnect(() => this.init());
+		ws.onConnect(() => this.init());
 	},
 	methods: {
 		init() {

+ 2 - 2
frontend/src/pages/Admin/tabs/News.vue

@@ -218,7 +218,7 @@
 import { mapActions, mapState, mapGetters } from "vuex";
 
 import Toast from "toasters";
-import io from "../../../io";
+import ws from "../../../ws";
 
 import EditNews from "../../../components/modals/EditNews.vue";
 
@@ -264,7 +264,7 @@ export default {
 		);
 
 		if (this.socket.readyState === 1) this.init();
-		io.onConnect(() => this.init());
+		ws.onConnect(() => this.init());
 	},
 	methods: {
 		createNews() {

+ 2 - 2
frontend/src/pages/Admin/tabs/Playlists.vue

@@ -62,7 +62,7 @@ import { mapState, mapActions, mapGetters } from "vuex";
 // import EditPlaylist from "../../../components/modals/EditPlaylist/index.vue";
 import UserIdToUsername from "../../../components/common/UserIdToUsername.vue";
 
-import io from "../../../io";
+import ws from "../../../ws";
 import utils from "../../../../js/utils";
 
 export default {
@@ -84,7 +84,7 @@ export default {
 	},
 	mounted() {
 		if (this.socket.readyState === 1) this.init();
-		io.onConnect(() => this.init());
+		ws.onConnect(() => this.init());
 	},
 	methods: {
 		// edit(playlist) {

+ 2 - 2
frontend/src/pages/Admin/tabs/Punishments.vue

@@ -98,7 +98,7 @@ import { mapState, mapGetters, mapActions } from "vuex";
 import Toast from "toasters";
 
 import ViewPunishment from "../../../components/modals/ViewPunishment.vue";
-import io from "../../../io";
+import ws from "../../../ws";
 
 export default {
 	components: { ViewPunishment },
@@ -125,7 +125,7 @@ export default {
 	},
 	mounted() {
 		if (this.socket.readyState === 1) this.init();
-		io.onConnect(() => this.init());
+		ws.onConnect(() => this.init());
 
 		this.socket.on("event:admin.punishment.added", punishment =>
 			this.punishments.push(punishment)

+ 2 - 2
frontend/src/pages/Admin/tabs/QueueSongs.vue

@@ -188,7 +188,7 @@ import FloatingBox from "../../../components/ui/FloatingBox.vue";
 
 import ScrollAndFetchHandler from "../../../mixins/ScrollAndFetchHandler.vue";
 
-import io from "../../../io";
+import ws from "../../../ws";
 
 export default {
 	components: { EditSong, UserIdToUsername, FloatingBox },
@@ -243,7 +243,7 @@ export default {
 		});
 
 		if (this.socket.readyState === 1) this.init();
-		io.onConnect(() => this.init());
+		ws.onConnect(() => this.init());
 	},
 	methods: {
 		edit(song) {

+ 2 - 2
frontend/src/pages/Admin/tabs/Reports.vue

@@ -71,7 +71,7 @@ import { mapState, mapActions, mapGetters } from "vuex";
 import { formatDistance } from "date-fns";
 
 import Toast from "toasters";
-import io from "../../../io";
+import ws from "../../../ws";
 
 import ViewReport from "../../../components/modals/ViewReport.vue";
 import UserIdToUsername from "../../../components/common/UserIdToUsername.vue";
@@ -94,7 +94,7 @@ export default {
 	},
 	mounted() {
 		if (this.socket.readyState === 1) this.init();
-		io.onConnect(() => this.init());
+		ws.onConnect(() => this.init());
 
 		this.socket.dispatch("reports.index", res => {
 			this.reports = res.data;

+ 2 - 2
frontend/src/pages/Admin/tabs/Songs.vue

@@ -211,7 +211,7 @@ import FloatingBox from "../../../components/ui/FloatingBox.vue";
 
 import ScrollAndFetchHandler from "../../../mixins/ScrollAndFetchHandler.vue";
 
-import io from "../../../io";
+import ws from "../../../ws";
 
 export default {
 	components: { EditSong, UserIdToUsername, FloatingBox },
@@ -321,7 +321,7 @@ export default {
 		);
 
 		if (this.socket.readyState === 1) this.init();
-		io.onConnect(() => this.init());
+		ws.onConnect(() => this.init());
 
 		if (this.$route.query.songId) {
 			this.socket.dispatch(

+ 2 - 2
frontend/src/pages/Admin/tabs/Stations.vue

@@ -187,7 +187,7 @@
 import { mapState, mapActions, mapGetters } from "vuex";
 
 import Toast from "toasters";
-import io from "../../../io";
+import ws from "../../../ws";
 
 import EditStation from "../../../components/modals/EditStation.vue";
 import UserIdToUsername from "../../../components/common/UserIdToUsername.vue";
@@ -216,7 +216,7 @@ export default {
 	},
 	mounted() {
 		if (this.socket.readyState === 1) this.init();
-		io.onConnect(() => this.init());
+		ws.onConnect(() => this.init());
 
 		this.socket.on("event:admin.station.added", station =>
 			this.stationAdded(station)

+ 2 - 2
frontend/src/pages/Admin/tabs/Statistics.vue

@@ -106,7 +106,7 @@ import { mapGetters } from "vuex";
 import { Line } from "chart.js";
 import "chartjs-adapter-date-fns";
 
-import io from "../../../io";
+import ws from "../../../ws";
 
 export default {
 	components: {},
@@ -268,7 +268,7 @@ export default {
 		});
 
 		if (this.socket.readyState === 1) this.init();
-		io.onConnect(() => this.init());
+		ws.onConnect(() => this.init());
 	},
 	methods: {
 		init() {

+ 2 - 2
frontend/src/pages/Admin/tabs/Users.vue

@@ -70,7 +70,7 @@ import { mapState, mapActions, mapGetters } from "vuex";
 
 import EditUser from "../../../components/modals/EditUser.vue";
 import ProfilePicture from "../../../components/ui/ProfilePicture.vue";
-import io from "../../../io";
+import ws from "../../../ws";
 
 export default {
 	components: { EditUser, ProfilePicture },
@@ -90,7 +90,7 @@ export default {
 	},
 	mounted() {
 		if (this.socket.readyState === 1) this.init();
-		io.onConnect(() => this.init());
+		ws.onConnect(() => this.init());
 	},
 	methods: {
 		edit(user) {

+ 2 - 2
frontend/src/pages/Home.vue

@@ -445,7 +445,7 @@ import MainFooter from "../components/layout/MainFooter.vue";
 import CreateCommunityStation from "../components/modals/CreateCommunityStation.vue";
 import UserIdToUsername from "../components/common/UserIdToUsername.vue";
 
-import io from "../io";
+import ws from "../ws";
 
 export default {
 	components: {
@@ -500,7 +500,7 @@ export default {
 		this.siteName = await lofig.get("siteSettings.siteName");
 
 		if (this.socket.readyState === 1) this.init();
-		io.onConnect(() => this.init());
+		ws.onConnect(() => this.init());
 
 		this.socket.on("event:stations.created", res => {
 			const station = res;

+ 1 - 1
frontend/src/pages/Settings/tabs/Profile.vue

@@ -64,7 +64,7 @@
 				v-model="modifiedUser.bio"
 			/>
 			<span v-if="modifiedUser.bio" class="character-counter"
-				>{{ modifiedUser.bio.length }}/200</span
+				>{{ modifiedUser.bws.length }}/200</span
 			>
 		</p>
 

+ 2 - 5
frontend/src/pages/Station/index.vue

@@ -507,7 +507,7 @@ import Z404 from "../404.vue";
 import FloatingBox from "../../components/ui/FloatingBox.vue";
 import AddToPlaylistDropdown from "../../components/ui/AddToPlaylistDropdown.vue";
 
-import io from "../../io";
+import ws from "../../ws";
 import keyboardShortcuts from "../../keyboardShortcuts";
 import utils from "../../../js/utils";
 
@@ -599,10 +599,7 @@ export default {
 		window.stationInterval = 0;
 
 		if (this.socket.readyState === 1) this.join();
-		io.onConnect(() => {
-			console.log("station page connect", this.socket.readyState);
-			this.join();
-		});
+		ws.onConnect(() => this.join());
 
 		this.socket.dispatch(
 			"stations.existsByName",

+ 2 - 2
frontend/src/store/modules/user.js

@@ -2,7 +2,7 @@
 /* eslint-disable import/no-cycle */
 
 import auth from "../../api/auth";
-import io from "../../io";
+import ws from "../../ws";
 import validation from "../../validation";
 
 const state = {};
@@ -117,7 +117,7 @@ const modules = {
 					if (typeof state.userIdMap[`Z${userId}`] !== "string") {
 						if (state.userIdRequested[`Z${userId}`] !== true) {
 							commit("requestingUserId", userId);
-							io.socket.dispatch(
+							ws.socket.dispatch(
 								"users.getUsernameFromId",
 								userId,
 								res => {

+ 41 - 60
frontend/src/io.js → frontend/src/ws.js

@@ -3,55 +3,47 @@ import Toast from "toasters";
 // eslint-disable-next-line import/no-cycle
 import store from "./store";
 
-const callbacks = {
-	general: {
-		temp: [],
-		persist: []
-	},
-	onConnect: {
-		temp: [],
-		persist: []
-	},
-	onDisconnect: {
-		temp: [],
-		persist: []
-	}
+const onConnect = {
+	temp: [],
+	persist: []
 };
 
-const whenConnected = [];
+const onDisconnect = {
+	temp: [],
+	persist: []
+};
 
-const callbackss = {};
-let callbackRef = 0;
+// references for when a dispatch event is ready to callback from server to client
+const CB_REFS = {};
+let CB_REF = 0;
 
 export default {
 	socket: null,
 	dispatcher: null,
 
 	onConnect(...args) {
-		if (args[0] === true) callbacks.onConnect.persist.push(args[1]);
-		else callbacks.onConnect.temp.push(args[0]);
+		if (args[0] === true) onConnect.persist.push(args[1]);
+		else onConnect.temp.push(args[0]);
 	},
 
 	onDisconnect(...args) {
-		if (args[0] === true) callbacks.onDisconnect.persist.push(args[1]);
-		else callbacks.onDisconnect.temp.push(args[0]);
+		if (args[0] === true) onDisconnect.persist.push(args[1]);
+		else onDisconnect.temp.push(args[0]);
 	},
 
 	clear: () => {
-		Object.keys(callbacks).forEach(type => {
-			callbacks[type].temp = [];
-		});
+		onConnect.temp = [];
+		onDisconnect.temp = [];
 	},
 
-	removeAllListeners() {
-		Object.keys(callbackss).forEach(id => {
+	removeAllListeners: () =>
+		Object.keys(CB_REFS).forEach(id => {
 			if (
 				id.indexOf("$event:") !== -1 &&
 				id.indexOf("$event:keep.") === -1
 			)
-				delete callbackss[id];
-		});
-	},
+				delete CB_REFS[id];
+		}),
 
 	init() {
 		class ListenerHandler extends EventTarget {
@@ -71,17 +63,16 @@ export default {
 
 				const stack = this.listeners[type];
 
-				for (let i = 0, l = stack.length; i < l; i += 1)
-					if (stack[i] === cb) stack.splice(i, 1);
+				stack.forEach((element, index) => {
+					if (element === cb) stack.splice(index, 1);
+				});
 			}
 
 			dispatchEvent(event) {
 				if (!(event.type in this.listeners)) return true; // event type doesn't exist
 
 				const stack = this.listeners[event.type].slice();
-
-				for (let i = 0, l = stack.length; i < l; i += 1)
-					stack[i].call(this, event);
+				stack.forEach(element => element.call(this, event));
 
 				return !event.defaultPrevented;
 			}
@@ -100,18 +91,16 @@ export default {
 			}
 
 			dispatch(...args) {
-				callbackRef += 1;
+				CB_REF += 1;
 
 				if (this.readyState !== 1)
-					return callbacks.onConnect.temp.push(() =>
-						this.dispatch(...args)
-					);
+					return onConnect.temp.push(() => this.dispatch(...args));
 
 				const cb = args[args.length - 1];
-				if (typeof cb === "function") callbackss[callbackRef] = cb;
+				if (typeof cb === "function") CB_REFS[CB_REF] = cb;
 
 				return this.send(
-					JSON.stringify([...args.slice(0, -1), { callbackRef }])
+					JSON.stringify([...args.slice(0, -1), { CB_REF }])
 				);
 			}
 		}
@@ -120,30 +109,24 @@ export default {
 		store.dispatch("websockets/createSocket", this.socket);
 
 		this.socket.onopen = () => {
-			callbacks.onConnect.temp.forEach(cb => cb());
-			callbacks.onConnect.persist.forEach(cb => cb());
-
 			console.log("IO: SOCKET CONNECTED");
 
-			whenConnected.forEach(func => func());
-
-			callbacks.general.temp.forEach(cb => cb(this.socket));
-			callbacks.general.persist.forEach(cb => cb(this.socket));
-
-			callbacks.general.temp = [];
-			callbacks.general.persist = [];
+			onConnect.temp.forEach(cb => cb());
+			onConnect.persist.forEach(cb => cb());
 		};
 
 		this.socket.onmessage = message => {
 			const data = JSON.parse(message.data);
 			const name = data.shift(0);
 
-			if (name === "callbackRef") {
-				const callbackRef = data.shift(0);
-				callbackss[callbackRef](...data);
-				return delete callbackss[callbackRef];
+			if (name === "CB_REF") {
+				const CB_REF = data.shift(0);
+				CB_REFS[CB_REF](...data);
+				return delete CB_REFS[CB_REF];
 			}
 
+			if (name === "ERROR") console.log("WS: SOCKET ERROR:", data[0]);
+
 			return this.socket.dispatcher.dispatchEvent(
 				new CustomEvent(name, {
 					detail: data
@@ -152,19 +135,17 @@ export default {
 		};
 
 		this.socket.onclose = () => {
-			console.log("IO: SOCKET DISCONNECTED");
+			console.log("WS: SOCKET DISCONNECTED");
 
-			callbacks.onDisconnect.temp.forEach(cb => cb());
-			callbacks.onDisconnect.persist.forEach(cb => cb());
+			onDisconnect.temp.forEach(cb => cb());
+			onDisconnect.persist.forEach(cb => cb());
 
 			// try to reconnect every 1000ms
-			setTimeout(() => {
-				this.init();
-			}, 1000);
+			setTimeout(() => this.init(), 1000);
 		};
 
 		this.socket.onerror = err => {
-			console.log("IO: SOCKET ERROR", err);
+			console.log("WS: SOCKET ERROR", err);
 
 			new Toast({
 				content: "Cannot perform this action at this time.",

Some files were not shown because too many files changed in this diff