The viewer-side `obfuscate-email` helper used by `anonymize-member` when
building share-link bundles called `clojure.string/split` on the raw
email input and then on the extracted domain. Two failure modes:
1. When the stored email had no `@` (legacy data, LDAP-sourced UIDs, direct
DB inserts, or fixtures that bypassed `::sm/email`), destructuring
left `domain` bound to `nil` and the follow-up `(str/split nil "." 2)`
raised `NullPointerException`. Because `obfuscate-email` runs inside
`get-view-only-bundle`, the exception aborted the whole RPC response
for share-link viewers, not just the field.
2. When the stored email used a single-label domain (`alice@localhost`),
`(str/split "localhost" "." 2)` returned `["localhost"]`; destructuring
bound `rest` to `nil` and the final `(str name "@****." rest)` produced
a dangling-dot output `"****@****."` (nil coerces to empty in `str`).
Guard both split calls with `(or x "")` so the chain is nil-safe, and
emit the trailing `.<tld>` segment only when `rest` is present. Add three
`deftest` groups covering the happy path, dotless domains, and malformed
inputs (nil / empty / no-`@`), plus a CHANGES.md entry under the 2.17.0
Unreleased bugs-fixed section.
Signed-off-by: Andrey Antukh <niwi@niwi.nz>
Co-authored-by: Andrey Antukh <niwi@niwi.nz>