Skip to content

feat: implement auth guards and conditional rendering entry button for virtual classroom#51

Merged
A1L13N merged 3 commits intoalphaonelabs:mainfrom
Shubhashish-Chakraborty:virtualclassroom-authenhancement
Apr 23, 2026
Merged

feat: implement auth guards and conditional rendering entry button for virtual classroom#51
A1L13N merged 3 commits intoalphaonelabs:mainfrom
Shubhashish-Chakraborty:virtualclassroom-authenhancement

Conversation

@Shubhashish-Chakraborty
Copy link
Copy Markdown
Contributor

@Shubhashish-Chakraborty Shubhashish-Chakraborty commented Apr 22, 2026

Description

This PR introduces necessary authentication guards and UX improvements for the Virtual Classroom entry points to prevent unauthorized access and console errors.

  • Conditional UI (Homepage): Conditionally rendering the Join Lobby Classroom button. Unauthenticated users will now see a prompt to login instead of redirecting to the classroom.

  • Classroom Auth Guard: Added validation logic to the frontend. If a user attempts to bypass the homepage and directly access the classroom URL without an active session, they are alerted and automatically redirected to the login page.

Logged In:
Screenshot 2026-04-22 at 6 37 12 PM

Logged Out:
Screenshot 2026-04-22 at 6 37 26 PM

alert:
Screenshot 2026-04-22 at 11 02 43 PM

Purpose

Implements client-side authentication guards and conditional UI for the Virtual Classroom entry flow to prevent unauthorized access and provide clearer UX for authenticated vs unauthenticated users.

Key Changes

  • public/classroom_poc.html
    • Added authentication helpers: getAuth() (reads edu_token and parses edu_user from localStorage) and isAuthenticated().
    • Updated joinClassroom() to enforce an auth guard: if not authenticated, show a warning toast, save current path+query to sessionStorage.post_login_redirect, and redirect to /login.html after ~800ms; aborts the join flow to avoid console errors and unauthorized access.
  • public/index.html
    • Replaced single "Join Lobby Classroom" anchor with a hidden dual-state container (#join-logged-in, #join-not-logged-in). Links point to the classroom autojoin and to login with a next parameter respectively.
  • public/js/layout.js
    • Added getAuth(), isAuthenticated(), and logout() utilities.
    • Added DOMContentLoaded logic that conditionally displays the appropriate homepage button: authenticated users see "Join Lobby Classroom"; unauthenticated users see "Login to Join Classroom".
    • updateAuthSection integration preserved for navbar/profile handling.
  • public/login.html
    • storeAuth(data) now shows a "Redirecting..." toast and defers navigation to handlePostLoginRedirect() (500ms delay) instead of immediately navigating to dashboard.
    • Added showToast(msg) UI helper and handlePostLoginRedirect() which reads sessionStorage.post_login_redirect (or falls back to /dashboard.html). Also stores a provided next query parameter into sessionStorage.post_login_redirect when present.

Impact

  • Functionality: Prevents unauthenticated direct access to the classroom page and aborts the join flow early to avoid runtime errors; preserves post-login redirect so users return to their intended classroom.
  • UX: Homepage shows context-appropriate CTAs (join vs login), login flow displays a toast and redirects back to the classroom when applicable, and unauthenticated join attempts display a warning notification before redirecting.
  • Backwards compatibility / APIs: No exported/public signature changes; changes are low-risk and limited to frontend client behavior.

Notes

  • Auth checks are client-side (localStorage-based); server-side enforcement is still recommended for security-sensitive endpoints.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 22, 2026

Warning

Rate limit exceeded

@Shubhashish-Chakraborty has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 44 minutes and 7 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 44 minutes and 7 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: alphaonelabs/coderabbit/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 19bebde6-dbce-4745-b55a-fca7c5d3feae

📥 Commits

Reviewing files that changed from the base of the PR and between 5e95ef2 and e3375cc.

📒 Files selected for processing (1)
  • public/login.html

Walkthrough

Client-side auth was added to the classroom join flow and UI. classroom_poc.html now exposes getAuth()/isAuthenticated() and blocks joinClassroom() when unauthenticated (shows toast, stores post-login redirect, redirects to /login.html). index.html, layout.js, and login.html update homepage links and post-login redirect/toast handling.

Changes

Cohort / File(s) Summary
Classroom auth & guard
public/classroom_poc.html
Added getAuth() and isAuthenticated() helpers that read edu_token and edu_user from localStorage. joinClassroom() now guards: if unauthenticated, shows a warning toast, stores current path+query as post_login_redirect in sessionStorage, delays 800ms, and redirects to /login.html; otherwise continues existing join flow.
Homepage join UI
public/index.html
Replaced single “Join Lobby Classroom” anchor with a div#classroom-join-container containing two hidden anchors: #join-logged-in (autojoin link) and #join-not-logged-in (login link with next=).
Homepage render logic
public/js/layout.js
Added DOMContentLoaded handler that toggles #join-logged-in / #join-not-logged-in visibility based on isAuthenticated() (reads localStorage) while leaving existing layout initialization intact.
Login & post-login flow
public/login.html
Modified storeAuth(data) to show a "Redirecting..." toast and call handlePostLoginRedirect() after 500ms instead of immediate dashboard redirect. Added showToast(msg) and handlePostLoginRedirect() to read/clear post_login_redirect from sessionStorage (and logic to store next= query to post_login_redirect).

Sequence Diagram(s)

sequenceDiagram
  participant User as User (Browser)
  participant Classroom as classroom_poc.html
  participant Storage as localStorage/sessionStorage
  participant Login as login.html

  User->>Classroom: Click "Join Classroom"
  Classroom->>Storage: call isAuthenticated() -> read edu_token, edu_user
  alt authenticated
    Classroom->>Classroom: proceed with joinClassroom() flow (connect, seating, websocket)
  else not authenticated
    Classroom->>Classroom: show warning toast
    Classroom->>Storage: set post_login_redirect = currentPath+query (sessionStorage)
    Classroom->>User: delay 800ms then redirect to /login.html
    User->>Login: visits login.html (with optional next=)
    Login->>Storage: on successful login store edu_token, edu_user (localStorage)
    Login->>Login: showToast("Redirecting...") and call handlePostLoginRedirect()
    Login->>Storage: read and clear post_login_redirect (sessionStorage)
    Login->>User: redirect to stored URL or /dashboard.html
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main changes: adding authentication guards to prevent unauthorized classroom access and conditionally rendering the entry button based on login state.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@public/classroom_poc.html`:
- Around line 238-249: The getAuth() and isAuthenticated() functions are
duplicated; extract them into a single shared module (e.g., create /js/auth.js)
that exports getAuth and isAuthenticated, update classroom_poc.html to load that
script instead of defining the functions, and remove the local definitions;
ensure the exported getAuth() returns the same token/user shape and the
consuming code still calls getAuth() and isAuthenticated() (function names:
getAuth, isAuthenticated) so both pages use the single source of truth.
- Around line 429-434: Replace the blocking alert in joinClassroom() with a
non-blocking UX: call the existing showToast() helper to display the "must be
signed in" message, store the intended classroom path (e.g.,
window.location.pathname + search or the roomId) into sessionStorage under a key
like "post_login_redirect", then set window.location.href = '/login.html';
update login.html's post-login flow to check
sessionStorage.getItem('post_login_redirect') and redirect there after
successful login (and clear the key). Ensure references: joinClassroom,
showToast, and the sessionStorage key "post_login_redirect".

In `@public/index.html`:
- Around line 156-163: The login flow and visibility suffer two issues: clicking
the "Login to Join Classroom" anchor (id="join-not-logged-in") sends users to
login.html which currently redirects to dashboard, losing the intended classroom
target, and the logged-in button (id="join-logged-in") can briefly flash for
logged-out users; fix by making the classroom link include a next query param
(e.g., ?next=<url-encoded-current-target>) or by storing the target in
sessionStorage before navigating so login.html can read and redirect to that
next value instead of dashboard, and change the initial markup/CSS to hide both
anchors (or the container) by default and let your existing DOMContentLoaded/js
visibility logic reveal only the correct element (referencing ids join-logged-in
and join-not-logged-in and the login redirect logic in login.html) so logged-out
users never see the wrong button briefly.

In `@public/js/layout.js`:
- Around line 183-195: The DOMContentLoaded handler that reads localStorage and
manipulates loggedInEl/notLoggedInEl can throw when those elements are absent;
instead, move this logic into the existing initializer (merge with the current
DOMContentLoaded handler) and use the isAuthenticated() helper rather than
re-reading localStorage, then guard element access by checking const loggedInEl
= document.getElementById('join-logged-in') and const notLoggedInEl =
document.getElementById('join-not-logged-in') for null before touching
.style.display so pages without the buttons won't error.
🪄 Autofix (Beta)

❌ Autofix failed (check again to retry)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: alphaonelabs/coderabbit/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: f3b95952-6a1e-441f-aea2-e38921760136

📥 Commits

Reviewing files that changed from the base of the PR and between c132da2 and 3aa442b.

📒 Files selected for processing (3)
  • public/classroom_poc.html
  • public/index.html
  • public/js/layout.js

Comment thread public/classroom_poc.html
Comment thread public/classroom_poc.html
Comment thread public/index.html
Comment thread public/js/layout.js Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@public/login.html`:
- Around line 320-323: The code double-decodes the next parameter by calling
decodeURIComponent on params.get('next'); update the post-login redirect logic
to store the raw params.get('next') value (no decodeURIComponent) into
sessionStorage under 'post_login_redirect' (i.e., change the
sessionStorage.setItem call to use params.get('next') directly) to avoid
malformed URI errors and preserve encoded percent literals.
- Around line 273-285: The showToast function is vulnerable to HTML injection
because it assigns the msg via innerHTML; update showToast to construct DOM
nodes safely instead of using innerHTML: create the wrapper div (toast) as
before, create an <i> element and set its className to "fas fa-check-circle
mt-0.5 flex-shrink-0", create a <span> for the message and set its textContent
to the msg argument (not innerHTML), append these children to toast, then append
toast to document.body and keep the existing timeout/remove logic; this ensures
msg is XSS-safe while preserving the toast styling and behavior.
- Around line 298-312: handlePostLoginRedirect currently redirects to whatever
is in sessionStorage['post_login_redirect'] allowing open-redirects; change it
to validate the stored value before navigating: when reading redirectUrl (from
sessionStorage.getItem('post_login_redirect')), construct a URL object with
location.origin as the base (new URL(redirectUrl, location.origin)) and only
allow the redirect if url.origin === location.origin and url.protocol is http:
or https: and url.pathname starts with '/'; also explicitly reject values
starting with '//' or 'javascript:' and fallback to the default
'/dashboard.html' if validation fails, then remove the stored item and perform
the safe navigation in handlePostLoginRedirect.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: alphaonelabs/coderabbit/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 15d376a3-6142-4104-801e-6bba2daf69e4

📥 Commits

Reviewing files that changed from the base of the PR and between 3aa442b and 5e95ef2.

📒 Files selected for processing (4)
  • public/classroom_poc.html
  • public/index.html
  • public/js/layout.js
  • public/login.html

Comment thread public/login.html
Comment thread public/login.html
Comment on lines +298 to +312
// 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';
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Open-redirect risk via post_login_redirect.

handlePostLoginRedirect() navigates to whatever URL sits in sessionStorage['post_login_redirect'] without validating that it's same-origin. Combined with the ?next= handler at lines 321‑323, an attacker can craft https://yoursite/login.html?next=https%3A%2F%2Fevil.example%2Fphish — after a legitimate login, the user is silently bounced to evil.example, which is a classic phishing vector.

Recommend constraining to same-origin relative paths only:

🛡️ Suggested guard
 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';
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@public/login.html` around lines 298 - 312, handlePostLoginRedirect currently
redirects to whatever is in sessionStorage['post_login_redirect'] allowing
open-redirects; change it to validate the stored value before navigating: when
reading redirectUrl (from sessionStorage.getItem('post_login_redirect')),
construct a URL object with location.origin as the base (new URL(redirectUrl,
location.origin)) and only allow the redirect if url.origin === location.origin
and url.protocol is http: or https: and url.pathname starts with '/'; also
explicitly reject values starting with '//' or 'javascript:' and fallback to the
default '/dashboard.html' if validation fails, then remove the stored item and
perform the safe navigation in handlePostLoginRedirect.

Comment thread public/login.html Outdated
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 23, 2026

Note

Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it.

Autofix skipped. No unresolved CodeRabbit review comments with fix instructions found.

@A1L13N A1L13N merged commit 1cf4e2f into alphaonelabs:main Apr 23, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants