Skip to content

fix(protocol): register all custom scheme privileges in one call - #136

Merged
mrsibe merged 1 commit into
mainfrom
fix/privileged-scheme-single-registration
Sep 25, 2026
Merged

mrsibe merged 1 commit into
mainfrom
fix/privileged-scheme-single-registration

Conversation

@mrsibe

@mrsibe mrsibe commented Sep 25, 2026

Copy link
Copy Markdown
Owner

What does this PR do?

Fixes the PDF reader, which #131 broke. All custom scheme privileges are now declared by the protocol modules and submitted to Electron in a single registerSchemesAsPrivileged() call.

Why?

protocol.registerSchemesAsPrivileged() replaces the privilege table; it does not append. #131 added a second, separate call:

registerDocumentScheme()      // knownote-doc
registerPdfjsAssetScheme()    // knownote-asset  ← overwrites the table

so knownote-doc lost supportFetchAPI and the renderer's fetch() on it failed:

Fetch API cannot load knownote-doc://docs/doc_...: URL scheme "knownote-doc" is not supported.
Failed to open PDF TypeError: Failed to fetch. URL scheme "knownote-doc" is not supported.

Every PDF failed to open. protocol.handle itself keeps working in the main process without the privilege, which is why nothing else noticed.

The packaged smoke test stayed green because its knownote-doc:// check used the main process (net.fetch), which does not exercise the renderer-facing privilege. That gap is closed here too.

Fixes #135. Regression from #131.

What changed?

  • New src/main/protocol/privilegedSchemes.ts: holds declarations, performs the one registerSchemesAsPrivileged() call.
  • documentProtocol.ts / pdfjsAssetProtocol.ts: registerXScheme() → declareXScheme(), which only enqueues; no Electron call.
  • index.ts: declares both schemes, then calls applyPrivilegedSchemes() once, before the app is ready.
  • smokeTest.ts: a new renderer-side fetch of knownote-doc:// (hidden window, intentionally not destroyed — destroying the last window fires window-all-closed and this app closes the database on it).
  • test/privilegedSchemes.test.ts: asserts there is exactly one registerSchemesAsPrivileged() call site in src/ and that index.ts declares and submits both schemes.

How was this tested?

  • Reproduced the regression and the fix in headless Electron using the repo's real protocol modules:
    • two separate registerSchemesAsPrivileged() calls → knownote-doc:// returns ERR Failed to fetch;
    • one combined call → {"knownote-doc":"ok 15306","knownote-asset":"ok 553"}.
  • npm test — 283 pass, 0 fail (2 new).
  • npm run typecheck, npm run build — pass.
  • npm run build:unpack + smoke:packaged — 22/22 checks pass, including the new knownote-doc:// is fetchable from a renderer (scheme privileges registered).

Screenshots / recordings

Not applicable.

Checklist

  • I have reviewed my own changes.
  • npm run typecheck passes.
  • npm run build passes.
  • I have tested the affected user workflow.
  • I have not included unrelated changes.
  • I have updated documentation when necessary.

Desktop / build changes

  • npm run build:unpack passes.
  • npm run smoke:packaged passes.

`protocol.registerSchemesAsPrivileged()` replaces the whole privilege table
instead of appending to it. `registerDocumentScheme()` and
`registerPdfjsAssetScheme()` each called it once, so the second call silently
dropped `knownote-doc`'s `supportFetchAPI` privilege. The renderer's
`fetch('knownote-doc://docs/<id>')` then failed with

    Fetch API cannot load knownote-doc://docs/...: URL scheme "knownote-doc" is not supported

and every PDF failed to open. Introduced by #131.

Protocol modules now only declare their scheme
(`declareDocumentScheme()` / `declarePdfjsAssetScheme()`); the single call to
Electron lives in `privilegedSchemes.ts::applyPrivilegedSchemes()`, invoked once
from `index.ts` before the app is ready.

`smokeTest` gains a renderer-side fetch of `knownote-doc://`. The existing check
used the main process's `net.fetch`, which works even without the privilege -
that is why the packaged gate stayed green while the reader was broken. The
renderer check creates a hidden window and deliberately does not destroy it:
destroying the last window fires `window-all-closed`, and this app closes the
database on that event, which would abort the remaining checks.

Verification (Linux, Electron 39.8.10):
- headless Electron running the repo's real protocol modules: both
  `knownote-doc://` (15306 bytes) and `knownote-asset://` (553 bytes) fetch from a
  renderer. With two separate `registerSchemesAsPrivileged()` calls the same
  harness returns "ERR Failed to fetch" for `knownote-doc://` - the regression,
  reproduced.
- `npm test` 283 pass (2 new: one submission point, all declarations applied).
- `npm run typecheck`, `npm run build`.
- `npm run build:unpack` + `smoke:packaged` 22/22, including the new renderer
  check.
@github-actions github-actions Bot added the bug Something isn't working label Sep 25, 2026
@mrsibe
mrsibe merged commit 0df2b62 into main Sep 25, 2026
4 checks passed
@mrsibe
mrsibe deleted the fix/privileged-scheme-single-registration branch September 25, 2026 17:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] PDF reader broken: the pdfjs asset scheme registration dropped knownote-doc's privileges

1 participant