| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Name | Name | Last commit date | ||
|---|---|---|---|---|
A Manifest V3 browser extension that brings Solid sign-in to the browser itself. It injects a window.solid API into every page (a DPoP-authenticated fetch, the user's webId, login/logout/setClientId) and pins a top-right account menu whose icon is the signed-in WebID's avatar. The UI is built with @jeswr/solid-elements so it is visually consistent with Pod Manager and the rest of the @jeswr Solid app suite.
Scope: this repo is the extension CORE — auth, window.solid, and the account popup. Access management (an access-request JS API, consent/data-type UI, queued requests) is a separate, design-first track and is intentionally not implemented here; only a clearly-marked, feature-detectable seam is left (see below).
Four contexts, with the access token held in exactly one of them (the service worker):
Page (MAIN world) Content script (ISOLATED) Service worker (background)
window.solid ⇄ content-script.ts ⇄ service-worker.ts
inject.ts postMessage chrome.runtime ├─ auth-flow.ts (auth-code + PKCE + DPoP)
(no credential) (trust boundary: (sole token ├─ core/authenticated-fetch.ts (the boundary)
stamps real origin) holder) ├─ core/dpop.ts (RFC 9449 proofs, Web Crypto)
├─ core/origin-policy.ts (fail-closed gate)
Popup = the account UI (@jeswr/solid-elements) ⇄ chrome.runtime ├─ session-store.ts (chrome.storage)
└─ action-icon.ts (avatar toolbar icon)
Because solid.fetch is callable from any page, the worker must never hand a foreign origin the user's token. core/origin-policy.ts + core/authenticated-fetch.ts enforce, fail-closed:
These invariants are pinned by an adversarial unit suite (test/), including a WebID/origin-mismatch test that genuinely fails without the guard.
interface SolidExtension {
readonly webId: string | null;
fetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response>;
setClientId(clientId: string): void; // declare this origin's Client ID Document
login(webId: string): Promise<void>;
logout(): Promise<void>;
requestAccess?(request: unknown): Promise<never>; // SEAM — not implemented (see below)
}The chrome.action icon is rendered (off-DOM, OffscreenCanvas) to the signed-in WebID's avatar — the profile photo (circular crop) or coloured initials — with a green status badge. The popup is the account UI: @jeswr/solid-elements' jeswr-account-menu + jeswr-theme-toggle, a recent-accounts affordance, a pod shortcut, a "restoring" state, and a first-run pin nudge (extensions can't self-pin). Light/dark themes the popup chrome and the web components in lockstep via the app-shell OKLCH tokens.
For users who want the account UI to stay open as they browse (vs the ephemeral popup), the extension also ships an MV3 side panel (sidepanel/sidepanel.html). It renders the identical signed-in/signed-out surface as the popup — the SAME @jeswr/solid-elements components driven by the SAME token-free MessageBridgeLoginController seam — via the shared mountAccountSurface() (src/popup/account-surface.ts), so there is exactly one copy of the view-switching + auth-bridge logic. The popup is unchanged. Open it by right-clicking the toolbar icon → "Open Solid side panel" (a left-click still opens the quick popup; Chrome ignores open-on-action-click while a default_popup is set, so both surfaces coexist via the context-menu entry).
Offline of arbitrary third-party pods is out of scope (it is a fork-only concern for this extension — a generic offline layer for any pod is the @jeswr/solid-offline SW track, not this one). The extension does no forced caching of third-party pod data; the worker's in-memory session/nonce caches are best-effort accelerators only.
The access-request JS API, the consent / data-type UI, and queued-request handling are a separate, design-first track and are deliberately excluded from this core. The only thing left here is a non-breaking seam: window.solid.requestAccess? is declared (so it is feature-detectable) but throws "not implemented". Do not wire access management onto this stub without the access-management design — adding the real method later is non-breaking.
npm install # @jeswr deps are pinned git+https (keyless npm ci); ignore-scripts=true
npm run build # webpack -> dist/Then in Chrome:
npm run gate # lint (biome) + typecheck (tsc) + test (vitest) + build (webpack)
npm run lint # biome over src test e2e scripts
npm run typecheck # tsc --noEmit
npm test # vitest — the security-critical core (51 cases), no server needed
npm run build # webpack bundle to dist/
npm run test:e2e # build + Playwright against a LOCAL Community Solid ServerThe unit suite stubs fetch / chrome.* and needs no server. The Playwright e2e suite boots a local Community Solid Server (e2e/setup) and a local test site — never the live deploy — and drives the real extension in headed Chromium.
MIT © Jesse Wright
| Back | FazBrowse Home | New Git URL |