Drop cookie import; click-through notifications; per-app zoom
The cookie import is gone. It worked mechanically - 43 cookies decrypted from Arc and verifiably visible to the page - but Google, Microsoft and Odoo all refused the imported sessions, because each binds a session to the browser that created it. Signing in once inside the app is simpler and actually works, so the whole path is deleted rather than kept as a feature that mostly fails. That takes rusqlite, aes, cbc, pbkdf2, hmac, sha1 and sha2 out of the build with it. Notifications are now raised through mac-notification-sys rather than Tauri's notification plugin, because the plugin cannot report that one was clicked. A click switches to the app that raised it and then runs the page's own click handler - the only thing that knows which message the notification was about. Zoom is per app, on a fixed ladder so Cmd+0 returns to exactly 100%. The shortcuts are menu-bar accelerators rather than a key listener, since the keystroke has to work while a remote page has focus. The hidden-element count is off the nav rows.
This commit is contained in:
@@ -21,7 +21,7 @@ Settled during brainstorming. Not open questions.
|
||||
|---|---|---|
|
||||
| Shell | Tauri 2.11 · React 19 · Vite 7 · Tailwind 4 · TypeScript | Matches FlightTube, the reference app on this machine |
|
||||
| App rendering | One child webview per app (`add_child`) | Iframes are impossible: Google, Microsoft and most SaaS send `X-Frame-Options: DENY` |
|
||||
| Sessions | Persistent per-app cookie jar, plus opt-in import from a paired browser | The jar is mandatory either way; the import only saves first logins |
|
||||
| Sessions | Persistent per-app cookie jar | You sign in once per tool and it sticks |
|
||||
| Link routing | Injected JS click interceptor; permissive `on_navigation` | A strict navigation filter breaks every OAuth redirect chain |
|
||||
| Tab memory | Every app is a live webview, hidden when inactive | Keeps scroll position, drafts and timers across switches |
|
||||
| Collapsed nav | ~52px icon rail | Still clickable when collapsed |
|
||||
@@ -32,9 +32,11 @@ Settled during brainstorming. Not open questions.
|
||||
|
||||
- **Multi-webview is `unstable` in Tauri.** The API can change between minor versions, so
|
||||
`tauri` is pinned to `=2.11.5`.
|
||||
- **Device-bound sessions defeat cookie import.** Google and Microsoft increasingly bind a
|
||||
session to the browser that created it. Imported cookies will sometimes be rejected and
|
||||
the tool asks for a real login once. The persistent jar keeps it from then on.
|
||||
- **Browser cookie import was built, measured, and removed.** It worked mechanically —
|
||||
43 cookies decrypted from Arc and verifiably visible to the page — but Google, Microsoft
|
||||
and Odoo all refused the imported sessions, because each binds a session to the browser
|
||||
that created it. Signing in once inside the app is both simpler and more reliable, so
|
||||
the whole import path was deleted rather than kept as a feature that mostly fails.
|
||||
- **Bounds sync trails layout by a frame.** A native webview is positioned from measurements
|
||||
the shell reports, so during a window resize it can lag. Every app in this class does.
|
||||
- **The Chrome user agent is a lie.** Sites that sniff deeply may behave oddly. It is on by
|
||||
@@ -137,30 +139,6 @@ for the top bar. Redirects, meta-refreshes and OAuth bounces are never blocked.
|
||||
`window.open` cannot escape into a stray window. A `_blank` link within the same app
|
||||
navigates that app's webview in place.
|
||||
|
||||
### Browser pairing
|
||||
|
||||
Settings lists the browsers actually installed. Pairing with a Chromium browser:
|
||||
|
||||
1. Copy the profile's `Cookies` SQLite file — Chrome holds a lock on the original — and
|
||||
read it with `rusqlite`.
|
||||
2. Read the `Chrome Safe Storage` key from the login Keychain, derive AES-128 with
|
||||
PBKDF2-HMAC-SHA1 (salt `saltysalt`, 1003 iterations), and decrypt the `v10` values.
|
||||
3. Keep only cookies whose domain matches a configured app's scope or the identity-provider
|
||||
list. Nothing else is read out of the browser.
|
||||
4. Inject them into `WKHTTPCookieStore`.
|
||||
|
||||
**Verified on the machine.** Pairing against Arc imported 43 cookies across 9 domains,
|
||||
and a probe from inside the page then read back `host=example.odoo.com
|
||||
names=tz,cids,frontend_lang visible=3` — `tz` existing only in Arc's store, which is what
|
||||
proves the import landed rather than merely being handed over. `setCookie` is
|
||||
fire-and-forget, so the import's own count could never have shown this.
|
||||
|
||||
The sites still presented sign-in pages. That is the documented limitation, not a broken
|
||||
import: the cookies are in the store and visible to the page, and the session is being
|
||||
refused at the far end. Settings keeps the probe as **Check cookies**, so the same
|
||||
question can be answered again without guessing.
|
||||
|
||||
Pairing is a button, not a background job. Cookies rotate; a silent task that periodically
|
||||
reaches into the Keychain is worse than one the user presses when something logs them out.
|
||||
|
||||
## UI
|
||||
@@ -201,8 +179,20 @@ Verified on the machine: `permission: Granted · direct: raised · page: api=fun
|
||||
was the reading that showed the native API existed and the shim had therefore never
|
||||
installed. The shim now replaces it unconditionally.
|
||||
|
||||
A click on the banner switches to the app that raised it and then runs the page's own
|
||||
click handler, which is the only thing that knows which message the notification was
|
||||
about. This is why notifications are raised through `mac-notification-sys` rather than
|
||||
Tauri's notification plugin: the plugin cannot report a click.
|
||||
|
||||
Service-worker push is **not** covered — only notifications a page raises while it is open.
|
||||
|
||||
## Zoom
|
||||
|
||||
Per app, on a fixed ladder so ⌘0 returns to exactly 100% rather than to whatever a
|
||||
repeated multiplier happened to leave behind. The shortcuts are menu-bar accelerators, not
|
||||
a key listener: the keystroke has to work while an app's own webview has focus, and that
|
||||
webview is a remote page this app deliberately cannot script for input.
|
||||
|
||||
## Hiding elements
|
||||
|
||||
Anything on a page can be right-clicked and hidden. The injected script owns a stylesheet
|
||||
|
||||
Reference in New Issue
Block a user