Prove cookie injection lands, rather than assuming it

setCookie is fire-and-forget, so the import's count was what WebKit was
handed, not what it kept. A probe from inside the page reads back the
other end: pairing against Arc gave `names=tz,cids,frontend_lang` for
aputure.odoo.com, and `tz` exists only in Arc's store — so the import
demonstrably landed.

The sites still ask for sign-in. That is the far end refusing the
session, not a broken import, and the two are now distinguishable
instead of being guessed at.
This commit is contained in:
2026-09-01 12:21:41 +02:00
parent ff4a0c6bc4
commit f057268103
5 changed files with 70 additions and 3 deletions
+36 -3
View File
@@ -453,11 +453,9 @@ pub fn notification_status(app: AppHandle) -> String {
Err(e) => format!("failed: {e}"),
};
let app_state = app.state::<AppState>();
let diag = app_state.diag.lock().unwrap().clone();
let last = app_state.last_notification.lock().unwrap().clone();
let page = if diag.is_empty() { "not run yet".into() } else { diag };
let from_page = if last.is_empty() { "none yet".into() } else { last };
format!("permission: {state} · direct: {raised} · page: {page} · from page: {from_page}")
format!("permission: {state} · direct: {raised} · from page: {from_page}")
}
/// Asks macOS for notification permission, once, at startup.
@@ -503,6 +501,41 @@ pub fn test_notification(app_id: String, app: AppHandle) -> Result<(), String> {
.map_err(|e| e.to_string())
}
/// Asks the page which cookies it can actually see.
///
/// `setCookie` is fire-and-forget, so the import's count is what was handed to
/// WebKit, not what WebKit kept. This reads the other end. HttpOnly cookies are
/// invisible to script by design, so the answer is a floor, not a total — but a
/// zero here means the injection never landed at all.
#[tauri::command]
pub fn probe_cookies(app_id: String, app: AppHandle) -> Result<(), String> {
let wv = app
.get_webview(&webviews::label_for(&app_id))
.ok_or_else(|| format!("{app_id} has no webview"))?;
wv.eval(
r#"(function () {
var names = document.cookie
? document.cookie.split(';').map(function (c) { return c.split('=')[0].trim(); })
: [];
if (window.__workAppSend) {
window.__workAppSend('diag', {
host: location.hostname,
visible: String(names.length),
names: names.slice(0, 12).join(',')
});
}
})();"#,
)
.map_err(|e| e.to_string())
}
/// What the last cookie probe saw.
#[tauri::command]
pub fn cookie_probe(app: AppHandle) -> String {
let diag = app.state::<AppState>().diag.lock().unwrap().clone();
if diag.is_empty() { "no answer from the page".into() } else { diag }
}
// ------------------------------------------------------- browser pairing
#[tauri::command]