From 3aa442b580fff73c6a3f5d9f5930d073e782ee09 Mon Sep 17 00:00:00 2001 From: Shubhashish-Chakraborty Date: Wed, 22 Apr 2026 18:33:33 +0530 Subject: [PATCH 1/3] add auth guards and conditional rendering btn for virtual classroom --- public/classroom_poc.html | 18 ++++++++++++++++++ public/index.html | 11 ++++++++--- public/js/layout.js | 15 +++++++++++++++ 3 files changed, 41 insertions(+), 3 deletions(-) diff --git a/public/classroom_poc.html b/public/classroom_poc.html index 704967d..03a7076 100644 --- a/public/classroom_poc.html +++ b/public/classroom_poc.html @@ -235,6 +235,19 @@

const desksContainer = document.getElementById('desksContainer'); const toastContainer = document.getElementById('toastContainer'); + // Authentication utils + function getAuth() { + return { + token: localStorage.getItem('edu_token'), + user: JSON.parse(localStorage.getItem('edu_user') || 'null') + }; + } + + function isAuthenticated() { + const { token, user } = getAuth(); + return token && user; + } + // COORDINATE HELPERS // Positions are stored and transmitted as NORMALIZED values (0.0 – 1.0) // representing a fraction of the canvas width/height. @@ -414,6 +427,11 @@

// Join / Leave function joinClassroom() { + if (!isAuthenticated()) { + alert('You must be signed in to join the virtual classroom.'); + window.location.href = '/login.html'; + return; + } intentionalDisconnect = false; reconnectAttempts = 0; isSeated = false; diff --git a/public/index.html b/public/index.html index 9be30f3..56c11a7 100644 --- a/public/index.html +++ b/public/index.html @@ -153,9 +153,14 @@

Global Virtual Classroom

21 learners inside - - Join Lobby Classroom - +
+ + Join Lobby Classroom + + +
diff --git a/public/js/layout.js b/public/js/layout.js index e016c9c..3fc03e2 100644 --- a/public/js/layout.js +++ b/public/js/layout.js @@ -178,4 +178,19 @@ document.addEventListener('DOMContentLoaded', async () => { await inject('site-navbar', '/partials/navbar.html', updateAuthSection); await inject('site-footer', '/partials/footer.html'); updateDarkModeIcon(); +}); + +// conditional rendering for the join lobby classroom btn +document.addEventListener('DOMContentLoaded', function() { + const loggedInEl = document.getElementById('join-logged-in'); + const notLoggedInEl = document.getElementById('join-not-logged-in'); + const token = localStorage.getItem('edu_token'); + const user = JSON.parse(localStorage.getItem('edu_user') || 'null'); + if (token && user) { + loggedInEl.style.display = 'flex'; + notLoggedInEl.style.display = 'none'; + } else { + loggedInEl.style.display = 'none'; + notLoggedInEl.style.display = 'flex'; + } }); \ No newline at end of file From 5e95ef2d31a2c8d7102361dcf493569384047847 Mon Sep 17 00:00:00 2001 From: Shubhashish-Chakraborty Date: Thu, 23 Apr 2026 00:01:34 +0530 Subject: [PATCH 2/3] enhancements --- public/classroom_poc.html | 8 +++++-- public/index.html | 4 ++-- public/js/layout.js | 19 +++++++--------- public/login.html | 46 +++++++++++++++++++++++++++++++++++++-- 4 files changed, 60 insertions(+), 17 deletions(-) diff --git a/public/classroom_poc.html b/public/classroom_poc.html index 03a7076..edf0300 100644 --- a/public/classroom_poc.html +++ b/public/classroom_poc.html @@ -428,8 +428,12 @@

// Join / Leave function joinClassroom() { if (!isAuthenticated()) { - alert('You must be signed in to join the virtual classroom.'); - window.location.href = '/login.html'; + showToast('Please sign in to join the virtual classroom.', 'warning'); + // Preserve the user's intended destination so login.html can send + // them back here after authentication. + const returnTo = window.location.pathname + window.location.search; + sessionStorage.setItem('post_login_redirect', returnTo); + setTimeout(() => { window.location.href = '/login.html'; }, 800); return; } intentionalDisconnect = false; diff --git a/public/index.html b/public/index.html index 56c11a7..15fc516 100644 --- a/public/index.html +++ b/public/index.html @@ -154,10 +154,10 @@

Global Virtual Classroom

21 learners inside diff --git a/public/js/layout.js b/public/js/layout.js index 3fc03e2..182ffbe 100644 --- a/public/js/layout.js +++ b/public/js/layout.js @@ -180,17 +180,14 @@ document.addEventListener('DOMContentLoaded', async () => { updateDarkModeIcon(); }); -// conditional rendering for the join lobby classroom btn -document.addEventListener('DOMContentLoaded', function() { +// Conditional rendering for the "Join Lobby Classroom" button. +// These elements only exist on the homepage, so we guard against nulls. +document.addEventListener('DOMContentLoaded', () => { const loggedInEl = document.getElementById('join-logged-in'); const notLoggedInEl = document.getElementById('join-not-logged-in'); - const token = localStorage.getItem('edu_token'); - const user = JSON.parse(localStorage.getItem('edu_user') || 'null'); - if (token && user) { - loggedInEl.style.display = 'flex'; - notLoggedInEl.style.display = 'none'; - } else { - loggedInEl.style.display = 'none'; - notLoggedInEl.style.display = 'flex'; - } + if (!loggedInEl || !notLoggedInEl) return; + + const authed = isAuthenticated(); + loggedInEl.style.display = authed ? 'flex' : 'none'; + notLoggedInEl.style.display = authed ? 'none' : 'flex'; }); \ No newline at end of file diff --git a/public/login.html b/public/login.html index 336beeb..3d6bd7b 100644 --- a/public/login.html +++ b/public/login.html @@ -256,11 +256,32 @@

Create your : 'border-transparent text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-300'); } -// Store authentication data +// Store authentication data and handle post-login flow function storeAuth(data) { localStorage.setItem('edu_token', data.token); localStorage.setItem('edu_user', JSON.stringify(data.user)); - window.location.href = '/dashboard.html'; + + // Show success toast + showToast('Redirecting...'); + + // Wait a few seconds then redirect + setTimeout(() => { + handlePostLoginRedirect(); + }, 500); +} + +// Show success toast message +function showToast(msg) { + const toast = document.createElement('div'); + toast.className = 'fixed top-4 right-4 bg-green-50 dark:bg-green-900/30 border border-green-200 dark:border-green-800 rounded-lg p-4 text-green-700 dark:text-green-300 text-sm flex items-start gap-2 animate-pulse shadow-lg z-50'; + toast.innerHTML = ` + + ${msg} + `; + document.body.appendChild(toast); + setTimeout(() => { + toast.remove(); + }, 3000); } // Show error message @@ -274,12 +295,33 @@

Create your }, 5000); } +// Handle redirect after successful login +function handlePostLoginRedirect() { + // Check if there's a stored redirect URL + const redirectUrl = sessionStorage.getItem('post_login_redirect'); + + if (redirectUrl) { + // Clear it so it doesn't trigger again + sessionStorage.removeItem('post_login_redirect'); + // Redirect to the original destination + window.location.href = redirectUrl; + } else { + // Default redirect + window.location.href = '/dashboard.html'; + } +} + // Handle tab parameter in URL const params = new URLSearchParams(location.search); if (params.get('tab') === 'register') { switchTab('register'); } +// Handle next parameter for post-login redirect +if (params.get('next')) { + sessionStorage.setItem('post_login_redirect', decodeURIComponent(params.get('next'))); +} + // Login form submission document.getElementById('form-login').addEventListener('submit', async e => { e.preventDefault(); From e3375cc5d0b32258d0b01c35ba2a7eb276b22098 Mon Sep 17 00:00:00 2001 From: Shubhashish-Chakraborty Date: Thu, 23 Apr 2026 00:17:21 +0530 Subject: [PATCH 3/3] fixes --- public/login.html | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/public/login.html b/public/login.html index 3d6bd7b..cd7ad04 100644 --- a/public/login.html +++ b/public/login.html @@ -274,10 +274,11 @@

Create your function showToast(msg) { const toast = document.createElement('div'); toast.className = 'fixed top-4 right-4 bg-green-50 dark:bg-green-900/30 border border-green-200 dark:border-green-800 rounded-lg p-4 text-green-700 dark:text-green-300 text-sm flex items-start gap-2 animate-pulse shadow-lg z-50'; - toast.innerHTML = ` - - ${msg} - `; + const icon = document.createElement('i'); + icon.className = 'fas fa-check-circle mt-0.5 flex-shrink-0'; + const span = document.createElement('span'); + span.textContent = msg; + toast.append(icon, span); document.body.appendChild(toast); setTimeout(() => { toast.remove(); @@ -297,18 +298,11 @@

Create your // Handle redirect after successful login function handlePostLoginRedirect() { - // Check if there's a stored redirect URL const redirectUrl = sessionStorage.getItem('post_login_redirect'); - - if (redirectUrl) { - // Clear it so it doesn't trigger again - sessionStorage.removeItem('post_login_redirect'); - // Redirect to the original destination - window.location.href = redirectUrl; - } else { - // Default redirect - window.location.href = '/dashboard.html'; - } + sessionStorage.removeItem('post_login_redirect'); + // Only honor same-origin, path-only redirects to prevent open-redirect abuse. + const safe = redirectUrl && /^\/(?!\/)/.test(redirectUrl); + window.location.href = safe ? redirectUrl : '/dashboard.html'; } // Handle tab parameter in URL @@ -317,9 +311,11 @@

Create your switchTab('register'); } -// Handle next parameter for post-login redirect -if (params.get('next')) { - sessionStorage.setItem('post_login_redirect', decodeURIComponent(params.get('next'))); +// Handle next parameter for post-login redirect. +// URLSearchParams.get() already performs percent-decoding — no need to decode again. +const nextParam = params.get('next'); +if (nextParam) { + sessionStorage.setItem('post_login_redirect', nextParam); } // Login form submission