From de0558b8a86aa599ad0605d01ffc4a09a1fbcb86 Mon Sep 17 00:00:00 2001 From: Menkveld Date: Wed, 1 Mar 2023 22:53:27 +0100 Subject: [PATCH 01/19] Admins set to a limited duration --- server/modules/AuthService.js | 5 ++- server/modules/DataBase.js | 6 ++-- server/modules/Middlewares.js | 2 +- server/modules/api_endpoints/ProtubeApi.js | 32 +++---------------- .../modules/socket_endpoints/RemoteSocket.js | 10 +++--- 5 files changed, 16 insertions(+), 39 deletions(-) diff --git a/server/modules/AuthService.js b/server/modules/AuthService.js index 847de67..05e0c0a 100644 --- a/server/modules/AuthService.js +++ b/server/modules/AuthService.js @@ -14,7 +14,6 @@ passport.use( tokenURL: tokenURL, clientID: process.env.OAUTH_CLIENT_ID, clientSecret: process.env.OAUTH_CLIENT_SECRET, - //callbackURL: "http://localhost:3000/api/auth/example/callback" }, async function (accessToken, refreshToken, profile, done) { let response = await fetch( @@ -30,13 +29,13 @@ passport.use( await User.upsert({ id: userData.id, name: userData.name, - admin: +userData.admin, + admin_until: +userData.admin_until, refresh_token: refreshToken, access_token: accessToken, }); return done(null, { id: userData.id, - admin: userData.admin, + admin_until: userData.admin_until, name: userData.name, }); } diff --git a/server/modules/DataBase.js b/server/modules/DataBase.js index c4bf435..c3c8c2e 100644 --- a/server/modules/DataBase.js +++ b/server/modules/DataBase.js @@ -38,11 +38,11 @@ this.sequelize class User extends Model { isAdmin() { - return this.admin; + return this.admin_until > getCurrentUnix(); } hasValidRemote() { - return this.admin || this.valid_remote_until > getCurrentUnix(); + return this.isAdmin() || this.valid_remote_until > getCurrentUnix(); } setValidRemote() { @@ -73,7 +73,7 @@ User.init( primaryKey: true, }, name: DataTypes.TEXT, - admin: DataTypes.BOOLEAN, + admin_until: DataTypes.INTEGER, valid_remote_until: { type: DataTypes.INTEGER, defaultValue: 0, diff --git a/server/modules/Middlewares.js b/server/modules/Middlewares.js index 3e181f3..1aff37f 100644 --- a/server/modules/Middlewares.js +++ b/server/modules/Middlewares.js @@ -33,7 +33,7 @@ exports.socketCheckAuthenticated = (socket, next) => { exports.socketCheckAdminAuthenticated = (socket, next) => { if (socket.request.isAuthenticated()) { - if (socket.request.user.admin) return next(); + if (socket.request.user.isAdmin()) return next(); else return next(new Error("forbidden")); } // accept localhost connections also to be admin (local client) diff --git a/server/modules/api_endpoints/ProtubeApi.js b/server/modules/api_endpoints/ProtubeApi.js index 592db72..43e1944 100644 --- a/server/modules/api_endpoints/ProtubeApi.js +++ b/server/modules/api_endpoints/ProtubeApi.js @@ -15,46 +15,24 @@ this.protubeApi.post("/updateadmin", async function (req, res) { `Attempt from ${req.hostname} to update the admin status of a user` ); // Check if the required data is present and parse it - if (!req.body?.user_id || !req.body?.admin) { + if (!req.body?.user_id || !req.body?.admin_until) { logger.apiInfo("Request had incomplete body"); return res.send({ success: enums.FAIL, message: "Incomplete body" }); } const userID = parseInt(req.body.user_id); - const isAdmin = parseInt(req.body.admin) === 1; + const adminUntil = parseInt(req.body.admin); // finding and updating the users admin status in the database const user = await User.findByPk(userID); - if (!user) { logger.apiInfo("User is not found!"); return res.send({ success: enums.FAIL, message: "User not found!" }); } - user.admin = isAdmin; - await user.save(); - logger.apiInfo(`User ${userID}'s new admin status: ${isAdmin}`); - - if (isAdmin) return res.send({ success: enums.SUCCESS }); - - // disconnecting admin screen and remote sockets if present - const sockets = await io.of("/socket/remote/admin").fetchSockets(); - const screenSockets = await io.of("/socket/screen/admin").fetchSockets(); - - for (const sock of sockets) { - await sock.request.user.reload(); - if (sock.request.user.id === userID) { - logger.apiInfo(`Disconnected admin remote socket`); - sock.disconnect(true); - } - } - for (const sock of screenSockets) { - await sock.request.user.reload(); - if (sock.request.user.id === userID) { - logger.apiInfo(`Disconnected admin screen socket`); - sock.disconnect(true); - } - } + user.admin_until = adminUntil; + await user.save(); + logger.apiInfo(`User ${userID}'s is admin until: ${adminUntil}`); return res.send({ success: enums.SUCCESS }); }); diff --git a/server/modules/socket_endpoints/RemoteSocket.js b/server/modules/socket_endpoints/RemoteSocket.js index 2dca179..5da40bc 100644 --- a/server/modules/socket_endpoints/RemoteSocket.js +++ b/server/modules/socket_endpoints/RemoteSocket.js @@ -19,7 +19,7 @@ endpoint.on("connection", (socket) => { const result = await youtube.search( request.query, request.continuationToken, - socket.request.user.admin, + socket.request.user.isAdmin(), queueManager.getQueue() ); callback(result); @@ -33,7 +33,7 @@ endpoint.on("connection", (socket) => { try { const videos = await youtube.getVideosInPlaylist( playlistId, - socket.request.user.admin + socket.request.user.isAdmin() ); videos.forEach((video) => (video.user = formatUser(socket))); callback(queueManager.addAllFair(videos)); @@ -44,7 +44,7 @@ endpoint.on("connection", (socket) => { socket.on("fetch-then-add-video", async (videoId, callback) => { try { - const video = await youtube.getVideo(videoId, socket.request.user.admin); + const video = await youtube.getVideo(videoId, socket.request.user.isAdmin()); video.user = formatUser(socket); callback({ success: queueManager.addFair(video) }); @@ -62,7 +62,7 @@ endpoint.on("connection", (socket) => { success: queueManager.removeVideos( videoIDs, socket.request.session.passport.user.id, - socket.request.user.admin + socket.request.user.isAdmin() ), }); } catch (e) { @@ -82,7 +82,7 @@ function formatUser(socket) { return { name: socket.request.user.name, id: socket.request.user.id, - admin: socket.request.user.admin, + admin: socket.request.user.isAdmin(), }; } From 2e474218abe92f8e3e26da3c56a8e84bffac794b Mon Sep 17 00:00:00 2001 From: Menkveld Date: Thu, 9 Mar 2023 10:10:09 +0100 Subject: [PATCH 02/19] Optional overlay --- client/src/components/MasterControls.vue | 22 +++++++++ .../src/components/ScreenSettingsButton.vue | 46 +++++++++++++++++++ deployment.yml | 41 +++++++++++++++++ enums.json | 6 +++ server/modules/ScreenSettings.js | 34 ++++++++++++++ .../modules/socket_endpoints/AdminRemote.js | 14 ++++++ .../modules/socket_endpoints/ScreenSocket.js | 4 ++ 7 files changed, 167 insertions(+) create mode 100644 client/src/components/ScreenSettingsButton.vue create mode 100644 deployment.yml create mode 100644 server/modules/ScreenSettings.js diff --git a/client/src/components/MasterControls.vue b/client/src/components/MasterControls.vue index 8582fef..90d1d08 100644 --- a/client/src/components/MasterControls.vue +++ b/client/src/components/MasterControls.vue @@ -77,6 +77,7 @@ +
-
-
+
+
Volume - {{ playerSettings.volume }} @@ -24,14 +24,32 @@ min="0" max="100" :value="playerSettings.volume" /> -
- -
-
- - ProTube - -
+ + +
+ + + + +
+
+
+ +
+ + -
- - Radio - -
-
- -
- - - - - - + +
-
-
- -
-
+
-
diff --git a/client/src/components/ScreenSettingsButton.vue b/client/src/components/ScreenSettingsButton.vue index a3dfcb2..19e125a 100644 --- a/client/src/components/ScreenSettingsButton.vue +++ b/client/src/components/ScreenSettingsButton.vue @@ -1,6 +1,10 @@ @@ -20,6 +24,8 @@ const currentScreenSetting = computed(() => { return "Queue only"; case enums.SCREEN_SETTINGS.SHOW_PHOTOS: return "Photos only"; + case enums.SCREEN_SETTINGS.SHOW_NOQUEUE: + return "No queue"; case enums.SCREEN_SETTINGS.SHOW_NOTHING: default: return "Nothing"; diff --git a/client/src/main.js b/client/src/main.js index bfbd357..a9381ec 100644 --- a/client/src/main.js +++ b/client/src/main.js @@ -23,6 +23,8 @@ import { faTrash, faQuestionCircle, faCaretDown, + faRadio, + faTv } from "@fortawesome/free-solid-svg-icons"; library.add( @@ -44,7 +46,9 @@ library.add( faSearch, faTrash, faCaretDown, - faQuestionCircle + faQuestionCircle, + faRadio, + faTv ); import "./assets/tailwind.css"; From 83cad2af604bc2106cf359a88c5cf42da3d1bd18 Mon Sep 17 00:00:00 2001 From: Menkveld Date: Mon, 8 May 2023 11:51:52 +0200 Subject: [PATCH 05/19] added phpmyadmin --- server/docker-compose.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/server/docker-compose.yml b/server/docker-compose.yml index 24cc4be..3283b32 100644 --- a/server/docker-compose.yml +++ b/server/docker-compose.yml @@ -12,3 +12,14 @@ services: MYSQL_ALLOW_EMPTY_PASSWORD: "yes" ports: - "${DATABASE_PORT}:3306" + + phpmyadmin: + container_name: "${DOCKER_CONTAINER_NAME}-pma" + image: phpmyadmin + ports: + - '3002:80' + environment: + - 'PMA_HOST=mysql' + - 'PMA_USER=${DATABASE_USER}' + - 'PMA_PASSWORD=${DATABASE_PASSWORD}' + - 'PMA_PORT=3002' \ No newline at end of file From a7dd2b4af2ee6d1113ea47b19e54cd20b7eea005 Mon Sep 17 00:00:00 2001 From: Menkveld Date: Mon, 8 May 2023 12:13:25 +0200 Subject: [PATCH 06/19] Componentized slider --- client/src/components/MasterControls.vue | 97 ++++++++++++------------ client/src/components/ToggleSlider.vue | 30 ++++++++ 2 files changed, 77 insertions(+), 50 deletions(-) create mode 100644 client/src/components/ToggleSlider.vue diff --git a/client/src/components/MasterControls.vue b/client/src/components/MasterControls.vue index ac524cb..234cf36 100644 --- a/client/src/components/MasterControls.vue +++ b/client/src/components/MasterControls.vue @@ -44,44 +44,26 @@
- -
+ + + + + +
@@ -92,16 +74,19 @@ import { ref, onBeforeMount, onBeforeUnmount, defineEmits } from "vue"; import { useRouter } from "vue-router"; import enums from "@/js/Enums"; import ContentField from "../layout/ContentField.vue"; -import ScreenSettingsButton from "./ScreenSettingsButton.vue"; +import ToggleSlider from "./ToggleSlider.vue"; const emit = defineEmits(["display-toast"]); const user = ref({}); -const screenSetting = ref(enums.SCREEN_SETTINGS.SHOW_DEFAULT); const playerSettings = ref({ volume: 75, playerMode: enums.MODES.IDLE, playerType: enums.TYPES.VIDEO, + screenSetting: { + 'showQueue': true, + 'showPhotos': true + } }); const router = useRouter(); @@ -132,9 +117,9 @@ socket.on("update-admin-panel", (newSettings) => { playerSettings.value = newSettings; }); -socket.on("new-screen-setting", (newSetting) => { - screenSetting.value = newSetting; -}); +// socket.on("new-screen-setting", (newSetting) => { +// screenSetting.value = newSetting; +// }); function displayToast(toast) { emit("display-toast", toast); @@ -187,17 +172,29 @@ async function toggleRadioProtube() { }); } -async function nextScreenSetting() { - const data = await new Promise((resolve) => { - socket.emit("set-screen-setting", callback => { - resolve(callback); - }); - }); - displayToast({ - status: data.status ?? enums.STATUS.SUCCESS, - message: data.message ?? `Successfully changed screen setting!`, - }); -} +// async function togglePhotosOverlay() { +// const data = await new Promise((resolve) => { +// socket.emit("toggle-photos-visibility", callback => { +// resolve(callback); +// }); +// }); +// displayToast({ +// status: data.status ?? enums.STATUS.SUCCESS, +// message: data.message ?? `Successfully changed the photos visibility setting!`, +// }); +// } + +// async function toggleQueueOverlay() { +// const data = await new Promise((resolve) => { +// socket.emit("toggle-queue-visibility", callback => { +// resolve(callback); +// }); +// }); +// displayToast({ +// status: data.status ?? enums.STATUS.SUCCESS, +// message: data.message ?? `Successfully changed the queue visibility setting!`, +// }); +// } async function skipVideo() { const data = await new Promise((resolve) => { diff --git a/client/src/components/ToggleSlider.vue b/client/src/components/ToggleSlider.vue new file mode 100644 index 0000000..78d0233 --- /dev/null +++ b/client/src/components/ToggleSlider.vue @@ -0,0 +1,30 @@ + + + \ No newline at end of file From 146572a12525b5a8ba4fec3220125156042f57f5 Mon Sep 17 00:00:00 2001 From: Menkveld Date: Mon, 8 May 2023 12:33:02 +0200 Subject: [PATCH 07/19] switch to toggles --- client/src/components/CurrentQueue.vue | 1 - client/src/components/MasterControls.vue | 84 ++++++++++++------- client/src/components/PhotosOverlay.vue | 3 +- client/src/main.js | 10 ++- client/src/views/ProtubeScreen.vue | 37 ++------ enums.json | 7 -- server/modules/ScreenSettings.js | 26 ++++-- .../modules/socket_endpoints/AdminRemote.js | 19 ++++- .../modules/socket_endpoints/ScreenSocket.js | 2 +- 9 files changed, 110 insertions(+), 79 deletions(-) diff --git a/client/src/components/CurrentQueue.vue b/client/src/components/CurrentQueue.vue index 4d14ce2..153358a 100644 --- a/client/src/components/CurrentQueue.vue +++ b/client/src/components/CurrentQueue.vue @@ -128,7 +128,6 @@ const userHasItemsInQueue = computed(() => { const videosOfUser = queue.value.filter((video) => { return video.user.id === props.userID; }); - console.log(videosOfUser); return videosOfUser.length > 0; }); diff --git a/client/src/components/MasterControls.vue b/client/src/components/MasterControls.vue index 234cf36..375f103 100644 --- a/client/src/components/MasterControls.vue +++ b/client/src/components/MasterControls.vue @@ -43,7 +43,7 @@
-
+
+ + + + + + + +