Skip to content

fix(files): accept a typed email address as a share recipient - #499

Merged
veryCrunchy merged 5 commits into
mainfrom
fix/share-email-recipient
Oct 9, 2026
Merged

veryCrunchy merged 5 commits into
mainfrom
fix/share-email-recipient

Conversation

@veryCrunchy

@veryCrunchy veryCrunchy commented Oct 8, 2026 •

Copy link
Copy Markdown
Member

Outcome

Advances #420.

A typed, valid email address can now be confirmed as an email share recipient by pressing Enter or tapping it, even when the server's sharee search does not return it. In the reported build the server's matching result appeared as a plain row with no selection affordance, and the recipient was only set if that row was clicked, so Create share stayed disabled with "A share recipient is required." main already auto-selects the address when the server returns it as an exact email match (1e518cf). This PR covers the remaining cases: a failed or still-running search, a server result limit, or an exact match found by another route.

  • New FileShareEmailAddress.kt: validateFileShareEmailAddress() returns a typed Valid or Invalid(reason). Quoted names, IP or bracket domains, and domains without a dot are rejected; letters outside ASCII are accepted.
  • The picker shows a "Typed address" row whenever the address is valid and the server has not returned the same address, including while a search is running or after it failed. Invalid addresses get a specific message.
  • If the server's matching result would fall past the eight visible rows, it is promoted to the first row instead of the typed row, so exactly one row is shown for the address and the server's identity and display name are kept.
  • FileShareDialogUiState.recipient is now a typed FileShareRecipient? that records its origin (Server or Typed), and a recipient is only used when its target matches the selected share type, so a recipient picked for one share type can never be sent as another.
  • The local address rules apply only to typed addresses. Server-returned email recipients (for example single-label domains or quoted local parts) are sent for the server's own validation as before.
  • Creation still requires the server to advertise email sharing. Missing or unknown capabilities still block with the existing messages, and take priority over address messages.
  • A missing email recipient now says "Enter an email address or choose one from the search results."

Contract checked against Nextcloud server source: email shares are type 4 with shareWith set to the address, MailPlugin only returns the typed address as an exact match when nothing else matched and the result limit was not reached, and ShareAPIController::createShare does not require a prior sharee search.

Verification

  • Every check relevant to the changed scope passes, or each unrun check is listed below with a reason
  • bash tools/check-repository.sh passes
  • A new changes/unreleased/ fragment records the change
  • No credentials, private server data, machine-local paths, or generated output are included

Run on Windows with JDK 21:

  • Focused :ui:desktopTest for the 7 share-related test classes: 71 tests pass.
  • Full :ui:desktopTest: 3786 tests, 0 failures, 69 skipped.
  • :androidApp:testDebugUnitTest: 1167 tests, 0 failures.
  • bash tools/check-kotlin-architecture.sh, bash tools/test-text-hygiene.sh, node tools/changelog-fragments.mjs validate: pass.

New and updated tests: FileShareEmailAddressTest (valid addresses and 21 invalid cases), FileShareRecipientSelectionTest (+8: typed row while loading or after failure, hidden once the server returns the address, capability blocking, target mismatch, local rules applied only to typed addresses, and a match past the visible limit promoted to the first row), FileOperationsTest (exact type 4 request bodies, including unusual server-returned addresses, and messages), and FileShareRecipientPickerSceneTest (+3 desktop Compose tests for Enter and tap selection, a late search result not clearing the choice, and a ninth-place server match shown and selectable).

Compatibility and risk

  • Not tested against a live Nextcloud 34 server with sharebymail, and the dialog was not checked visually.
  • The Android IME Done action is only covered through the desktop Compose Enter test.
  • An address the client accepts but the server rejects is handled by the existing create-error path.
  • Pre-existing behavior, not changed here: after a share is created the search text stays, and a re-run search can auto-select the same server-confirmed address and re-enable Create share. The server's duplicate check should prevent a second email share, but this was not verified.

Visual changes

Adds a "Typed address" row and address-specific validation messages to the share recipient picker. Screenshots not yet captured.

- Offer a complete typed email address as an email share recipient that
  Enter or a tap confirms, so Create share no longer depends on the sharee
  search echoing the address back.
- Validate email recipients before the Share API request and explain
  incomplete or malformed addresses instead of a generic missing-recipient
  message.
- Keep the chosen recipient typed with its share target so a recipient
  chosen for one target can never become the shareWith value of another.
- Creation stays blocked unless the server advertises sharing by email.

Advances #420
@obiente-cloud
obiente-cloud Bot temporarily deployed to Obiente Preview / PR #499 / NC Native October 8, 2026 00:33 Destroyed
@obiente-cloud

obiente-cloud Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

Obiente preview

NC Native · a6ac1295d029 · Removed

View preview status

View in Obiente

Obiente updates this comment as the preview changes.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-08T17:38:07.987937Z 06283e2 New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7f984a3c15

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread ui/src/commonMain/kotlin/dev/obiente/nextcloudnative/app/FileOperations.kt Outdated
@obiente-cloud
obiente-cloud Bot temporarily deployed to Obiente Preview / PR #499 / NC Native October 8, 2026 00:39 Destroyed
- Record whether a share recipient was typed or returned by the sharee
  search, and apply the local email address grammar only to typed input.
  Sharee results such as single-label domains or quoted local parts are
  sent as returned and left to the Share API to validate.
- Always show the server result that matches the typed address as the
  leading choice, even when the server listed it after the visible result
  limit, so the address has exactly one choice.
- Target matching and email capability gating are unchanged.

Advances #420
@obiente-cloud
obiente-cloud Bot temporarily deployed to Obiente Preview / PR #499 / NC Native October 8, 2026 17:35 Destroyed
@obiente-cloud
obiente-cloud Bot temporarily deployed to Obiente Preview / PR #499 / NC Native October 8, 2026 17:40 Destroyed
@veryCrunchy
veryCrunchy merged commit 259d9e7 into main Oct 9, 2026
6 checks passed

This branch was successfully deployed

No deployments
Obiente Preview / PR #499 / NC Native — a6ac1295 Deployed Oct 8, 2026 by obiente-cloud[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant