sync: what the on-device round found

Everything here came from running the account flow against a real
Nextcloud rather than from reading the code.

Discovery
- A typed bare origin now gets the RFC 6764 well-known probe. It was
  returned as the only candidate, so `https://cloud.example.com` — what
  people actually type — was PROPFIND'd against the web UI, answered 405,
  and a working Nextcloud reported as "not a CalDAV server".
- A same-host HTTPS→HTTP redirect is put back on TLS instead of refused
  (`dav` change 7). A Nextcloud behind a TLS-terminating proxy without
  `overwriteprotocol` builds every redirect with http://, including the
  /.well-known/caldav hop discovery depends on. Cross-host still throws.
- Outcomes carry a `Cause` the UI translates, not the server's own words.
  "HTTP 405 Method Not Allowed" told someone entering an address nothing,
  in a language they may not read, from outside strings.xml.
- An IPv6 origin keeps its brackets: `HttpUrl.host` returns "fd00::1", so
  the rebuilt origin did not parse and a homelab address came back as
  "not an address".

Login Flow v2
- The poll response's scheme is coerced, never refused. Nextcloud returns
  the app password exactly once, so throwing there burned a live
  credential and left it dangling in the user's device list. The host
  mismatch already worked this way; the scheme now matches it.

Accounts
- The accounts screen observes Room and the sign-in state instead of
  taking a snapshot, so a sync landing — or a 401 stopping an account —
  reaches a screen that is already open.
- A per-account detail screen, and provider identity (`CalDavProvider`)
  shared with the quirk table so one list drives both the icon and the
  warning.
- The password field masks: floret-kit's `InlineTextField` gained a
  visual transformation, since `KeyboardType.Password` only tells the IME
  to drop suggestions.
This commit is contained in:
2026-09-07 18:41:45 +02:00
parent 28b2423ad9
commit b4a7fcb46e
31 changed files with 1455 additions and 280 deletions
+22 -4
View File
@@ -309,15 +309,33 @@
<string name="accounts_empty_body">Add a CalDAV account and Agendula keeps your task lists in step with it — Nextcloud, Radicale, Baïkal and anything else that speaks the protocol.</string>
<string name="accounts_add">Add an account</string>
<string name="accounts_remove">Remove account</string>
<string name="accounts_remove_confirm_title">Remove %1$s?</string>
<string name="accounts_remove_confirm_body">Its task lists stay on this device and stop syncing. Nothing is deleted from the server.</string>
<string name="accounts_remove_confirm_action">Remove</string>
<string name="accounts_remove_body">%1$s stops syncing with this device. Nothing is deleted from the server.</string>
<string name="accounts_remove_keep">Remove, keep the tasks</string>
<string name="accounts_remove_keep_body">Its lists stay on this device as device-only lists.</string>
<string name="accounts_remove_wipe">Remove and delete the tasks</string>
<string name="accounts_remove_wipe_body">Also deletes this account\u2019s lists and tasks from this device.</string>
<string name="accounts_never_synced">Never synced</string>
<string name="accounts_last_sync">Last sync</string>
<string name="accounts_generic_provider">CalDAV account</string>
<string name="accounts_sync_failed">Last sync didn\u2019t finish</string>
<string name="accounts_sync_now">Sync now</string>
<string name="add_account_browser_failed_title">Sign-in didn\u2019t finish</string>
<string name="add_account_step_of">Step %1$d of %2$d</string>
<string name="add_account_server_title">Where are your tasks?</string>
<string name="add_account_server_body">Enter the address of your CalDAV server, or the email address you use with it.</string>
<string name="add_account_credentials_title">Sign in</string>
<string name="add_account_credentials_body">Use an app password if your provider offers one \u2014 it can be revoked without changing your account password.</string>
<string name="add_account_lists_body">Pick the task lists to keep in sync. You can change this later.</string>
<string name="add_account_error_not_an_address">That doesn\u2019t look like a web address. Try something like cloud.example.com.</string>
<string name="add_account_error_not_dav">That address answered, but it isn\u2019t a CalDAV server. If you pasted the website, try the server address your provider gives for calendars.</string>
<string name="add_account_error_no_calendar">That server doesn\u2019t offer calendars. Check the address with your provider.</string>
<string name="add_account_error_unreachable">Couldn\u2019t reach that server. Check the address and your connection.</string>
<string name="add_account_error_insecure">That address is unencrypted. Agendula only sends your password over https.</string>
<string name="add_account_error_no_calendars">Signed in, but this account has no task lists.</string>
<string name="add_account_error_server">The server ran into a problem. Try again in a moment.</string>
<string name="accounts_needs_sign_in">Sign in again to keep syncing</string>
<string name="accounts_sign_in_again">Sign in again</string>
<string name="accounts_remove_delete_local">Also delete this account\u2019s tasks from this device</string>
<string name="accounts_summary">%1$s \u00b7 %2$s</string>
<string name="sync_notification_channel">Syncing</string>
<string name="sync_notification_title">Syncing tasks</string>