Skip to content

feat(extension): browser extension core for Chrome and Firefox#418

Open
oxr463 wants to merge 6 commits into
mainfrom
feature/browser-extensions
Open

feat(extension): browser extension core for Chrome and Firefox#418
oxr463 wants to merge 6 commits into
mainfrom
feature/browser-extensions

Conversation

@oxr463

@oxr463 oxr463 commented May 25, 2026

Copy link
Copy Markdown
Collaborator

Issue number: resolves #417


Checklist

  • Code Formatter (run prettier/spotlessApply)
  • Code has unit tests? (If no explain in other_information)
  • Builds on localhost
  • Builds/Runs in docker compose

What is the current behavior?

There is no browser extension. Users must navigate to the FindFirst web app, manually enter a URL and title, and select tags to save a bookmark — interrupting their browsing flow.

The repository contained only a non-functional Firefox Manifest V2 stub and an empty Chrome directory.

What is the new behavior?

  • One-click save — popup lets users save the current tab's URL and title to FindFirst without leaving the page
  • Tag support — autocomplete from existing tags; create new tags inline during save
  • Context menu — right-click any page or link to save it directly
  • Options page — configure FindFirst server base URL and view connection status; supports any self-hosted instance
  • Auth flow — sign in from within the extension; JWT (accessToken) returned in the sign-in response body and stored in browser.storage.local; sent as Authorization: Bearer on all API calls; session persists across popup close/open for the lifetime of the JWT
  • Dual-browser support — single shared TypeScript source tree (src/) builds separate Chrome MV3 (dist/chrome/) and Firefox MV3 (dist/firefox/) artifacts via esbuild
  • 28 unit tests — covering the API client, storage helpers, tag logic, and URL validation (Vitest)

Server-side changes (this PR)

  • CORSchrome-extension://* and moz-extension://* added to allowed origin patterns so the extension can make cross-origin requests
  • Bearer token authjwtAuthenticationConverter wired into oauth2ResourceServer so Bearer token requests produce UserAuthenticationToken directly, making UserContext.getUserId() work for extension API calls
  • Sign-in responseaccessToken (JWT) added to TokenRefreshResponse body alongside refreshToken; the extension reads this from the response since the httpOnly cookie set for web clients is not accessible from extension origins
  • Docker — server image built from source in docker-compose.yml for local development iteration

Does this introduce a breaking change?

  • Yes
  • No

Other information

Firefox manifest: Firefox MV3 uses background.scripts (array) rather than background.service_worker. The extension build produces browser-specific manifests from manifests/manifest.firefox.json and manifests/manifest.chrome.json.

Docker Compose: The extension is a static build artifact loaded directly into the browser — it does not run as a container.

Screenshot 2026-05-24 at 7 04 39 PM Screenshot 2026-05-24 at 7 05 49 PM Screenshot 2026-05-24 at 7 07 06 PM Screenshot 2026-05-24 at 7 07 31 PM Screenshot 2026-05-24 at 7 12 10 PM Screenshot 2026-05-24 at 7 13 12 PM

- Add chrome-extension:// and moz-extension:// to CORS allowed origin
  patterns so the extension can make credentialed requests
- Fix UserContext.getUserId() to handle JwtAuthenticationToken (set by
  oauth2ResourceServer for Bearer token requests) in addition to the
  existing UserAuthenticationToken (set by the cookie filter); the hard
  cast was causing a ClassCastException and 500 on all extension API calls
@oxr463 oxr463 requested a review from R-Sandor May 25, 2026 01:10
@oxr463 oxr463 self-assigned this May 25, 2026
@oxr463 oxr463 added the enhancement New feature or request label May 25, 2026
- Mock next/font/google in vitestSetup to fix Libre_Baskerville not-a-function error in app.test.tsx
- Always render brand logo in Navbar (remove isMobile conditional that hid it on desktop); drop unused isMobile state and resize effect
- Update default avatar test to assert SVG icon presence instead of stale img/src expectation
Comment thread server/src/main/java/dev/findfirst/security/userauth/context/UserContext.java Outdated
Comment thread frontend/components/Navbar/Navbar.tsx Outdated

@R-Sandor R-Sandor left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

While the sign-in seems to work for firefox, there is an issue with the auth. The bear token filter doesn't succeed when attempting to add a bookmark.

On Firefox Linux the application also doesn't persist the token (maybe?) as each time the extension is opened it requires reauthentication.

Ideally the extension should be able to maintain login in for the life of the JWT.
Please test on your end.

@R-Sandor R-Sandor force-pushed the feature/browser-extensions branch from 34e0791 to ffb1aef Compare June 10, 2026 10:02
oxr463 added 2 commits June 13, 2026 16:46
- Add jwtAuthenticationConverter inline in securityFilterChain so
  Bearer token requests produce UserAuthenticationToken directly;
  avoids registering a Converter bean that breaks Spring MVC startup
- Remove JwtAuthenticationToken fallback from UserContext since the
  converter now handles Bearer token auth uniformly
- Add accessToken to TokenRefreshResponse so the extension can read
  the JWT from the sign-in response body (httpOnly cookie is not
  accessible from moz-extension:// origin)
- Build server image from source in docker-compose for local dev
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Browser extension for one-click bookmarking from Chrome and Firefox

2 participants