Android sharing sends the opened device token, not the sealed one
CI & Build / Python lint (push) Successful in 2s
CI & Build / Build now, or wait for Android? (push) Successful in 3s
Android / Build, or is the channel already serving this? (push) Successful in 3s
Desktop (Tauri) / Build, or is the channel already serving this? (push) Successful in 2s
CI & Build / Python tests (push) Successful in 12s
CI & Build / Web typecheck and unit tests (push) Successful in 13s
Android / Core and FFI clippy and tests (push) Successful in 34s
CI & Build / integration (push) Successful in 1m39s
CI & Build / Build & push image (push) Skipped
Desktop (Tauri) / Web tests, clippy, Rust tests and rustfmt (push) Successful in 1m58s
Desktop (Tauri) / Windows installer (cross-compiled) (push) Successful in 3m5s
Desktop (Tauri) / Tauri desktop (Linux) (push) Successful in 4m11s
Desktop (Tauri) / Update manifest (push) Successful in 4s
Android / Kotlin + Rust (APK) (push) Successful in 9m17s
Android / Build the server image (push) Successful in 1s

Android has stored its device token sealed ("sealed:…") since 8592b83, and
core's sharing calls read the token from the store themselves. The ffi opened
it in credentials() and then threw the result away, so every Share-sheet
request went out as `Bearer sealed:…` and the server refused it.

The sharing functions now take the server address and token from the caller.
The ffi passes what credentials() opened; the desktop, which stores its token
plain, reads it through sharing::stored_link. A new ffi test serves one request
on a loopback port and checks the bearer token that arrives (#5381).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-08 14:05:10 -04:00
co-authored by Claude Opus 5.5
parent 39b1ebae96
commit be4897276c
3 changed files with 128 additions and 27 deletions
+8 -4
View File
@@ -194,12 +194,14 @@ pub fn sync_has_pending(db: State<'_, Db>) -> Result<bool, String> {
#[tauri::command]
pub async fn shares_directory(db: State<'_, Db>) -> Result<Directory, String> {
sharing::directory(&db).await
let (url, token) = sharing::stored_link(&db)?;
sharing::directory(&url, &token).await
}
#[tauri::command]
pub async fn shares_list(note_id: String, db: State<'_, Db>) -> Result<Vec<NoteShare>, String> {
sharing::list(&db, &note_id).await
let (url, token) = sharing::stored_link(&db)?;
sharing::list(&db, &url, &token, &note_id).await
}
/// Share with a person (`user_id`) or a group (`group_id`, #5177): exactly one.
@@ -216,7 +218,8 @@ pub async fn shares_share(
(None, Some(id)) => ShareTarget::Group(id),
_ => return Err("Choose someone or a group to share with.".to_string()),
};
sharing::share(&db, &note_id, &target, &permission).await
let (url, token) = sharing::stored_link(&db)?;
sharing::share(&db, &url, &token, &note_id, &target, &permission).await
}
#[tauri::command]
@@ -225,5 +228,6 @@ pub async fn shares_unshare(
share_id: String,
db: State<'_, Db>,
) -> Result<Vec<NoteShare>, String> {
sharing::unshare(&db, &note_id, &share_id).await
let (url, token) = sharing::stored_link(&db)?;
sharing::unshare(&db, &url, &token, &note_id, &share_id).await
}