experiments in a post-browser web
10
fork

Configure Feed

Select the types of activity you want to include in your feed.

docs: add research on bundled web extensions (uBlock, Proton Pass)

+213 -4
+209
notes/research-bundled-web-extensions.md
··· 1 + # Research: Bundled Web Extensions for Peek 2 + 3 + ## Executive Summary 4 + 5 + Bundling a small set of extensions (uBlock Origin, Proton Pass) with Peek for Electron is **technically feasible but requires careful architectural decisions**. The primary challenge is **API coverage limitations** and **licensing complexity**, particularly around the Manifest V2→V3 transition. 6 + 7 + **Key Recommendation**: Use electron-chrome-extensions for MV2 support (short term) or Polypane's fork for MV3, implement a hybrid approach with native ad-blocking fallback, and establish clear licensing disclosures for bundled extensions. 8 + 9 + --- 10 + 11 + ## 1. electron-chrome-extensions Analysis 12 + 13 + **Status**: Actively maintained as of 2025 14 + - **Repository**: [samuelmaddock/electron-browser-shell](https://github.com/samuelmaddock/electron-browser-shell) 15 + - **Alternative Fork**: [Polypane/electron-chrome-extensions](https://github.com/Polypane/electron-chrome-extensions) (provides MV3 support) 16 + 17 + **Capabilities**: 18 + - Loads unpacked Chrome extensions from filesystem 19 + - Supports customizable API behavior for tab/window management 20 + - Extensions run in isolated BrowserWindow processes 21 + - Tabs API supported with customizable callbacks 22 + 23 + **Critical Limitations**: 24 + - **Manifest V2 only** in samuelmaddock's version (MV3 blocked in Chromium for security) 25 + - **webRequest API conflict**: Using Electron's webRequest prevents chrome.webRequest listeners from firing 26 + - **No incognito/private session support** for extensions 27 + - **MV3 limitations**: webRequest is restricted to force-installed extensions only; uses limited declarativeNetRequest instead 28 + 29 + **Licensing**: MIT, but contact author for proprietary-use license 30 + 31 + --- 32 + 33 + ## 2. Bundling Approach 34 + 35 + **How to Bundle**: 36 + 1. Place extension code in app's resources directory (unpacked) 37 + 2. Load on startup: `session.extensions.loadExtension(extensionPath)` 38 + 3. Extensions not automatically remembered across restarts—must re-load on each start 39 + 4. Configuration: Only enable/disable per extension via settings 40 + 41 + **Build Integration**: 42 + - Copy unpacked extension directories into `app.asar` or unpacked resources folder 43 + - Load paths at startup via main process IPC 44 + - Settings stored in app datastore to track enable/disable state per extension 45 + 46 + **Note**: Electron does NOT natively support .crx files—only unpacked extensions work. 47 + 48 + --- 49 + 50 + ## 3. Extension-Specific Findings 51 + 52 + ### uBlock Origin (ad blocker) 53 + 54 + **License**: GPLv3 (open source) 55 + 56 + **APIs Required**: 57 + - **Critical**: chrome.webRequest (blocking version) - for network filtering 58 + - **Secondary**: chrome.tabs, chrome.storage, chrome.runtime 59 + 60 + **Manifest V3 Impact**: 61 + - **Broken in MV3**: webRequest blocking removed 62 + - Google provides only declarativeNetRequest (rule-based, ~30K rule limit) 63 + - Creator has stated MV3 makes full uBlock functionality "technically impossible" 64 + 65 + **Viability in Peek**: 66 + - ✅ Works in Electron with electron-chrome-extensions (uses MV2) 67 + - ⚠️ Risk: If uBlock migrates to MV3, declarativeNetRequest support needed 68 + 69 + ### Proton Pass (password manager) 70 + 71 + **License**: GPLv3 (open source codebase, proprietary service) 72 + 73 + **APIs Required**: 74 + - chrome.webRequest (non-blocking, for content injection) 75 + - chrome.tabs, chrome.storage, chrome.runtime 76 + 77 + **Manifest V3 Support**: 78 + - ✅ **Better positioned than uBlock** - non-blocking webRequest is supported 79 + - Simpler feature set (no blocking needed) 80 + 81 + **Viability in Peek**: 82 + - ✅ Works well with electron-chrome-extensions 83 + - ✅ MV3 compatible without major changes 84 + - ⚠️ Requires Proton account for full sync features 85 + 86 + --- 87 + 88 + ## 4. API Coverage Matrix 89 + 90 + | API | uBlock | Proton Pass | Electron Support | MV3 Status | 91 + |-----|--------|-------------|------------------|------------| 92 + | webRequest (blocking) | ✅ Critical | ❌ Not needed | ✅ Yes (conflicts) | ❌ Restricted | 93 + | webRequest (non-blocking) | ❌ Insufficient | ✅ Yes | ✅ Yes | ✅ Yes | 94 + | tabs | ✅ Yes | ✅ Yes | ✅ Customizable | ✅ Yes | 95 + | storage | ✅ Yes | ✅ Yes | ✅ Yes | ✅ Yes | 96 + | cookies | ✅ Optional | ❌ No | ✅ Yes | ✅ Yes | 97 + | declarativeNetRequest | ❌ (MV3 only) | ✅ Can use | ⚠️ Partial | ✅ Yes | 98 + 99 + --- 100 + 101 + ## 5. Alternative Approaches 102 + 103 + **Option A: Native Ad Blocking** - [@cliqz/adblocker-electron](https://www.npmjs.com/package/@cliqz/adblocker-electron) 104 + - Covers 99% of uBlock Origin + Easylist filters 105 + - No webRequest API conflicts 106 + - Simpler deployment, smaller attack surface 107 + 108 + **Option B: Hybrid Approach** (Recommended) 109 + - Use native ad blocker for core needs 110 + - Bundle Proton Pass as full extension (most compatible) 111 + 112 + **Option C: Built-in Equivalents** 113 + - Password manager: Built-in secure storage + autofill 114 + - Ad blocker: Native implementation via webRequest in main process 115 + 116 + --- 117 + 118 + ## 6. Licensing Considerations 119 + 120 + | Extension | License | Bundling OK? | Notes | 121 + |-----------|---------|--------------|-------| 122 + | uBlock Origin | GPLv3 | ✅ Yes | Must acknowledge GPL, include source | 123 + | Proton Pass | GPLv3 | ✅ Yes | Open source + proprietary service | 124 + 125 + **Disclosure Requirements**: 126 + - Display list of bundled extensions with versions in Settings 127 + - Link to source repositories 128 + - Disclose GPL licensing in app credits 129 + 130 + --- 131 + 132 + ## 7. Security Considerations 133 + 134 + **Risks**: 135 + - Extensions run in isolated BrowserWindow processes (good) 136 + - Each extension gets full webRequest access (risky) 137 + - No ability to restrict permissions per extension 138 + 139 + **Mitigations**: 140 + - ✅ Bundle only well-known, maintained projects 141 + - ✅ Validate extension code at build time (sign/hash) 142 + - ✅ Use Electron's sandbox: `sandbox: true` 143 + - ✅ Limit to utility functions (no main process access) 144 + - ⚠️ Monitor for security advisories 145 + 146 + --- 147 + 148 + ## 8. Implementation Phases 149 + 150 + ### Phase 1: Research & Setup (1-2 weeks) 151 + - [ ] Clone electron-chrome-extensions, test with sample extension 152 + - [ ] Evaluate Polypane fork for MV3 support readiness 153 + - [ ] Create extension bundling directory structure 154 + - [ ] Prototype loading via session.extensions.loadExtension() 155 + 156 + ### Phase 2: Proof of Concept (2-3 weeks) 157 + - [ ] Bundle & load Proton Pass (easiest, most compatible) 158 + - [ ] Implement enable/disable toggle in Settings UI 159 + - [ ] Test basic functionality (password saving/autofill) 160 + 161 + ### Phase 3: Ad Blocking (2-3 weeks) 162 + - [ ] Integrate @cliqz/adblocker-electron as native solution 163 + - [ ] OR address webRequest conflict for uBlock Origin 164 + - [ ] Measure performance impact 165 + 166 + ### Phase 4: Polish (1-2 weeks) 167 + - [ ] Per-extension settings UI (if extensions provide manifests) 168 + - [ ] Licensing/attribution UI in About dialog 169 + - [ ] Security review of bundled code 170 + 171 + --- 172 + 173 + ## 9. Risks & Mitigations 174 + 175 + | Risk | Impact | Mitigation | 176 + |------|--------|------------| 177 + | webRequest conflict | uBlock fails | Use @cliqz/adblocker native | 178 + | MV3 migration | uBlock breaks | Monitor; plan native fallback | 179 + | Memory/CPU impact | App bloat | Profile; lazy-load extensions | 180 + | Security vulnerability | RCE via extension | Sandbox; audit code | 181 + 182 + --- 183 + 184 + ## 10. Recommended Path Forward 185 + 186 + **Immediate (MVP)**: 187 + 1. Use [Polypane/electron-chrome-extensions](https://github.com/Polypane/electron-chrome-extensions) (MV3-ready) 188 + 2. Bundle **Proton Pass only** (best compatibility, no licensing issues) 189 + 3. Implement toggle in Settings UI 190 + 191 + **Short-term**: 192 + 4. Add **@cliqz/adblocker-electron** as native ad blocker (no webRequest conflicts) 193 + 5. Monitor uBlock Origin MV3 progress; defer until stable 194 + 195 + **Long-term**: 196 + 7. If uBlock MV3 becomes viable, bundle as opt-in 197 + 8. Consider extension update mechanism 198 + 199 + --- 200 + 201 + ## Resources 202 + 203 + - [samuelmaddock/electron-browser-shell](https://github.com/samuelmaddock/electron-browser-shell) 204 + - [Polypane/electron-chrome-extensions](https://github.com/Polypane/electron-chrome-extensions) 205 + - [Electron Extension Support](https://www.electronjs.org/docs/latest/api/extensions) 206 + - [uBlock Origin](https://github.com/gorhill/uBlock) 207 + - [Proton Pass](https://proton.me/pass) 208 + - [@cliqz/adblocker-electron](https://www.npmjs.com/package/@cliqz/adblocker-electron) 209 + - [Chrome MV3 Overview](https://developer.chrome.com/docs/extensions/develop/migrate/what-is-mv3)
+1 -1
schema/generated/sqlite-full.sql
··· 1 1 -- Generated by schema/codegen.js 2 2 -- Schema version: 1 3 - -- Generated: 2026-01-29T20:54:01.895Z 3 + -- Generated: 2026-01-30T08:06:39.915Z 4 4 -- DO NOT EDIT - regenerate with: yarn schema:codegen 5 5 6 6 -- Unified content storage - URLs, text notes, tagsets, and images
+1 -1
schema/generated/sqlite-sync.sql
··· 1 1 -- Generated by schema/codegen.js 2 2 -- Schema version: 1 3 - -- Generated: 2026-01-29T20:54:01.896Z 3 + -- Generated: 2026-01-30T08:06:39.916Z 4 4 -- DO NOT EDIT - regenerate with: yarn schema:codegen 5 5 6 6 -- Unified content storage - URLs, text notes, tagsets, and images
+1 -1
schema/generated/types.rs
··· 1 1 // Generated by schema/codegen.js 2 2 // Schema version: 1 3 - // Generated: 2026-01-29T20:54:01.896Z 3 + // Generated: 2026-01-30T08:06:39.916Z 4 4 // DO NOT EDIT - regenerate with: yarn schema:codegen 5 5 6 6 use serde::{Deserialize, Serialize};
+1 -1
schema/generated/types.ts
··· 1 1 /** 2 2 * Generated by schema/codegen.js 3 3 * Schema version: 1 4 - * Generated: 2026-01-29T20:54:01.896Z 4 + * Generated: 2026-01-30T08:06:39.916Z 5 5 * DO NOT EDIT - regenerate with: yarn schema:codegen 6 6 */ 7 7