Skip to content

The peer lobby stays on "Checking account..." when an invite link is opened with site data blocked #626

Closed

Description

@sidney-Hung

Problem

web/peer-lobby.js names the sessionStorage global in five places (lines 29, 187, 253, 262 and 266 at fcae4d8). Where site data is blocked, touching that global throws. #603 fixed the same failure in the lobby and left these five references behind per-line eslint-disable-next-line no-restricted-globals directives, because a mechanical conversion does not fix this page; the maintainer asked for a separate issue in the review of #603.

Current behavior

Reproduced on fcae4d8 in Chromium:

  1. With the CodeTrial origin added to Chrome's "Not allowed to save data on your device" list (chrome://settings/content/siteData), open /peer-lobby#invite=test. The page stays on "Checking account...", and the console shows Uncaught SecurityError: Failed to read the 'sessionStorage' property from 'Window': Access is denied for this document. The address bar still carries #invite=test: the history.replaceState that should drop it, two lines after the sessionStorage.setItem at line 29, never runs.
Image

 

  1. With site data allowed, the same link moves on: the invite leaves the address bar and the signed-out page goes to /api/login?next=peer-join (on this local server, without GitHub sign-in configured, that answers a JSON error, which is outside this issue).

Cause

Line 29 runs at module scope: when the URL carries an invite, the page stores the token in sessionStorage and then removes it from the URL. With the global throwing, the module stops there and init() never runs. Lines 187 and 253 run in init() outside any try, so a page that gets past module scope still fails there.

Converting the references to storageArea("sessionStorage") would pass the lint rule but still fail: .setItem and .getItem on the null it returns throw too. The token has to survive the trip to /api/login?next=peer-join and back (line 188), and sessionStorage is the only place the page keeps it.

Desired outcome

With site data blocked, the peer lobby never hangs or shows a raw exception, and it tells the candidate why peer interviews cannot start there.

Open question

Signing in needs the session cookie, which the same block refuses, so a candidate under a full block cannot join a peer interview whatever happens to the token. Is it enough to detect the block (as the lobby does with tabStorageBlocked) and show a site-data message like the lobby's, without trying to keep the token? Or should the token stay in the URL until the join succeeds, for a browser that blocks storage but not cookies?

Acceptance criteria

  • Opening an invite link with sessionStorage unreachable shows a reason instead of "Checking account...", and a test covers it.
  • The five eslint-disable-next-line directives in web/peer-lobby.js are gone; reportUnusedDisableDirectives makes each fix remove its own.

Related

#600 and #603 (the same failure in the lobby).

I found this while working on #603 and am not taking it myself; it is open for anyone to pick up.

Activity

  1. dges5202 commented on Nov 8, 2026

    @dges5202
    Contributor

    Hi @sidney-Hung — thanks for filing this and leaving it open. I'd like to take it if that works for you.

    Plan

    Mirror the lobby fix from #603 on the peer-lobby path:

    1. Detect that sessionStorage is unreachable (same idea as the lobby's tabStorageBlocked / safe probe), before any module-scope sessionStorage touch so init() can still run.
    2. When blocked, stop hanging on "Checking account…": show a clear site-data / peer-interview message (aligned with the lobby wording), and do not leave a raw SecurityError in the console from those five sites.
    3. Remove all five eslint-disable-next-line no-restricted-globals directives in web/peer-lobby.js as each call site is converted; keep reportUnusedDisableDirectives happy.
    4. Add a browser test that opens an invite link with storage unreachable and asserts the reason UI (not the stuck checking state).

    Open question (my take)

    I'd go with detect the block and show a site-data message, without trying to preserve the invite token across login when storage is blocked.

    Reason: a full site-data block also refuses the session cookie, so peer join cannot complete anyway. Keeping the token in the URL until join succeeds adds edge cases (reload / share / history) for a path that still cannot sign in. If maintainers prefer a URL-held token for a hypothetical "storage blocked, cookies allowed" browser, I'm happy to adjust after feedback.

    Scope

    • web/peer-lobby.js (+ shared helper reuse from the lobby fix if one already exists)
    • browser coverage for the blocked-storage invite path
    • no change to happy-path invite → login → join when storage works

    Please assign this to me if the plan looks right, or tell me what you'd change before I open a PR.

  2. sidney-Hung commented on Nov 8, 2026

    @sidney-Hung
    ContributorAuthor

    @jserv I opened this as a follow-up and noted I am not taking it myself, and @dges5202 offered to work on it above. Could you assign it to them instead?

  3. jserv commented on Nov 8, 2026

    @jserv
    Contributor

    @dges5202 The plan matches. Detect the block and show the site-data reason; do not try to keep the invite token. A full block refuses the session cookie too, so there is no join to protect, and a browser that blocks storage but allows cookies is its own issue if one turns up.

    Run the probe before anything touches sessionStorage at module scope, use storageArea("sessionStorage") from #603 (it answers null where the global throws), and remove the five eslint-disable-next-line directives as each site is converted. The test opens an invite link with storage unreachable and asserts the reason is shown instead of "Checking account...". Open the pull request with Closes #626.

  4. added 6 commits that reference this issue on Nov 8, 2026
    2b7bf19
    6f08a54
    bd22209
    1cd97d9
    927c953
    7efd9a4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions