Skip to content

Live Folders: support GitHub Enterprise instances#13044

Open
gcsecsey wants to merge 5 commits intozen-browser:devfrom
gcsecsey:feat/github-enterprise-live-folders
Open

Live Folders: support GitHub Enterprise instances#13044
gcsecsey wants to merge 5 commits intozen-browser:devfrom
gcsecsey:feat/github-enterprise-live-folders

Conversation

@gcsecsey
Copy link
Copy Markdown

@gcsecsey gcsecsey commented Apr 1, 2026

Related issues

Fixes #12768

Proposed Changes

The GitHub Live Folder provider currently hardcodes https://github.com as its only source, preventing users with GitHub Enterprise (GHE) instances from using the feature.

This PR adds full GitHub Enterprise support with two authentication strategies:

1. Configurable GitHub host per folder

  • Each GitHub live folder targets a configurable instance (defaults to github.com)
  • First folder creation skips the prompt for a frictionless default experience; subsequent folders prompt for the host URL
  • "Instance: hostname" context menu option allows changing the host after creation
  • Folder label includes the hostname for non-github.com instances (e.g., "Pull Requests (github.corp.com)")

2. Personal Access Token (PAT) authentication for GHE

  • For GHE instances, cookie-based auth won't work, so PAT authentication is supported via the GitHub REST API (/search/issues)
  • Tokens are stored securely in Firefox's Login Manager (encrypted, supports Primary Password) — never in the JSON state file
  • "Set Access Token…" / "Remove Access Token" context menu options for token management
  • Clicking the error triangle on a GHE folder opens the PAT creation page with pre-selected repo scope
  • Token expiry is handled gracefully: 401/403 clears the stored token and shows an actionable error
  • When a PAT is available, fetching switches from HTML scraping to the REST API (more reliable and future-proof)

3. Security hardening

  • HTTPS-only for host URLs (HTTP rejected to prevent cleartext PAT transmission)
  • _hasToken runtime flag excluded from state file serialization
  • Stored PAT cleaned up from Login Manager when folder is deleted (if no other folder shares the host)
  • API queries parallelized with Promise.all for better performance

4. Broader auth error detection

  • Any non-2xx HTTP response treated as auth failure (not just 404)
  • GHE instances without a PAT skip HTML scraping entirely and show the auth error directly
  • Empty API results (authenticated but no matching items) no longer incorrectly treated as auth failures

Files changed

File Purpose
providers/GithubAuth.sys.mjs New — Secure PAT storage CRUD via Firefox Login Manager
providers/GithubLiveFolder.sys.mjs Host state, REST API fetch path, PAT UI options, GHE-specific error handling
ZenLiveFolder.sys.mjs Added headers parameter to base fetch() method
ZenLiveFoldersManager.sys.mjs Conditional host prompt, PAT cleanup on folder delete
moz.build Register new GithubAuth.sys.mjs module
zen-live-folders.ftl Localization strings for instance prompt, PAT options, error messages
browser_github_live_folder.js Tests for custom host, GHE auth flow, error detection

Testing Instructions

  1. Default github.com flow — Create a GitHub PR live folder via right-click sidebar → Create Live Folder → Pull Requests. Should work as before with no prompt (defaults to github.com).
  2. Add a GHE instance — Create a second PR folder. Enter your GHE URL in the prompt (e.g., https://github.corp.com). The PAT creation page should open on your GHE instance.
  3. Set the PAT — Right-click the GHE folder → Live Folder Options → "Set Access Token…" → paste the token. PRs should appear after refresh.
  4. Verify error triangle — For a GHE folder without a PAT, the triangle should appear. Clicking it opens the PAT creation page (no prompt window).
  5. Change instance — Right-click → Live Folder Options → "Instance: hostname" → enter a different URL.
  6. Delete folder — Delete the GHE folder. Verify the PAT is cleaned up (check about:logins).
  7. Run testsnpm run test live-folders

gcsecsey added 4 commits April 1, 2026 15:22
Allow each GitHub live folder to target a configurable GitHub instance
instead of hardcoding github.com. Users are prompted for the instance
URL when creating a folder, and can change it later via the context
menu "Instance" option.

- Add `host` to GitHub provider state (defaults to github.com)
- Derive fetch URL and login redirect from the configured host
- Add `promptForHost()` static method (follows RSS pattern)
- Add "Instance: hostname" option in Live Folder context menu
- Broaden auth error detection (any non-2xx + empty results)
- Add localization strings for instance prompt and validation
- Update tests for custom host support

Related to zen-browser#12768
- Add GithubAuth.sys.mjs: secure PAT storage via Firefox Login Manager
  (tokens stored with unique httpRealm, never in JSON state file)
- Add REST API fetch path: when a PAT is available, use GitHub's
  /search/issues API instead of HTML scraping (more reliable for GHE)
- Add headers support to base fetch() method via channel.setRequestHeader
- Add "Set/Remove Access Token" context menu options
- Open PAT creation page with pre-selected scopes when configuring GHE
- Skip host prompt for first GitHub folder (defaults to github.com)
- Handle token expiry: clear stored token on 401/403, prompt for new one
- Add comprehensive tests for custom host, auth detection, and state defaults
- Triangle click always opens PAT creation page (no prompt window)
- GHE instances without PAT skip HTML scraping, show auth error directly
- Empty API results no longer treated as auth failure (valid empty search)
- Register GithubAuth.sys.mjs in moz.build
- Remove debug logging
Security:
- Exclude _hasToken from serialize() to prevent state file leakage
- Only allow HTTPS for GitHub host URLs (reject HTTP)
- Clean up stored PAT when folder is deleted (if no other folder shares host)

Performance:
- Parallelize API queries with Promise.all (saves 400-1000ms per cycle)

Correctness:
- Use || instead of ?? for host default (prevents empty string breaking URL)
- Fix broken GHE tests (GHE early-returns before fetch, so test fetch assertions)
- Remove dead hasToken() method from GithubTokenManager
@gcsecsey gcsecsey changed the title feat: GitHub Enterprise instance support for Live Folders Live Folders: support GitHub Enterprise instances Apr 1, 2026
@gcsecsey gcsecsey marked this pull request as ready for review April 1, 2026 20:49
@gcsecsey gcsecsey requested a review from mr-cheffy as a code owner April 1, 2026 20:49
@dosubot dosubot bot added size:XL This PR changes 500-999 lines, ignoring generated files. Feature labels Apr 1, 2026
- Extract `get #isGitHubEnterprise` getter (replaces 3 inline checks)
- Extract `get #hasAnyFilterEnabled` getter (eliminates duplication
  between fetchItems and fetchItemsViaApi)
- Use Promise.allSettled for API queries (preserves partial results
  when one query fails instead of losing all results)
- Sync _hasToken on 401/403 token removal
@mr-cheffy
Copy link
Copy Markdown
Member

Not too sure about this, it certainly seems to add quite the level of complexity from the user's side...

@mirai-toto
Copy link
Copy Markdown

mirai-toto commented Apr 2, 2026

Not too sure about this, it certainly seems to add quite the level of complexity from the user's side...

What makes you think that? Is it the concept or the usage? I think if this feature is greenlit, we could have settings on a Live Folder when right-clicking it, where we could set a token or URL.

Or is it the customization of Live Folders that feels too advanced?

@gcsecsey
Copy link
Copy Markdown
Author

gcsecsey commented Apr 2, 2026

@mr-cheffy thanks for the feedback. Yes, I was experimenting with using only cookie-based auth to make the UX just as simple as for github.com, but GHE instances are typically behind SSO/SAML, so the cookie-based approach is not reliable.

This requires us to manage the entry and storage of the PAT in some way, I'm not sure if the current approach is the best UX. This is how the current flow looks like:

  1. User creates a second GitHub live folder, and gets prompted for the host URL
CleanShot 2026-04-02 at 09 41 23@2x 2. Clicking the error triangle opens the GHE's "Create new token" page with pre-selected scopes CleanShot 2026-04-02 at 09 42 48@2x 3. User then right-clicks the folder → "Set Access Token…" to paste the token CleanShot 2026-04-02 at 09 46 54@2x CleanShot 2026-04-02 at 09 47 00@2x 4. Once the PAT is set, the user can remove it by right-clicking the folder → "Remove Access Token" then set a new one CleanShot 2026-04-02 at 09 53 34@2x

Could you advise how we can make this flow easier to use?

@mr-cheffy
Copy link
Copy Markdown
Member

mr-cheffy commented Apr 2, 2026

Or is it the customization of Live Folders that feels too advanced?

Yes, I feel like part of the magic behind live folders is that everything feels seeming-less... Give me some time to think about this, maybe there's a nicer solution

}

if (!hasAnyFilterEnabled) {
// GHE instances require a PAT — HTML scraping won't work without cookies
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We are sending cookies though?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Not at the moment, I started working on this by testing my own use-case (SAML). However, GHE support these 4 auth methods, and for instances using the built in auth, the same flow should work that already works with github.com.

I'll update the PR to try to use cookies first, and only fall back to requiring a PAT if that approach fails. Unfortunately, AFAIK there's no way to detect the auth method from the client side.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Feature size:XL This PR changes 500-999 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants