Match an LDIF re-import on the entry's dn #274

Closed
opened 2026-09-04 14:51:02 +00:00 by jcoffey-dev · 0 comments
Owner

Closes the half of #223 that was left undone when it was closed. Reported again by the submitter's colleague at LINET: duplicate checking landed for vCard and never for LDIF, so re-importing an address book still leaves a second copy of everything.

It was left open because I wanted the matching key decided rather than guessed. The decision had already been made on #174 — an attribute that can change is fine, because it will not have changed between two imports minutes apart — and I closed the issue without acting on it.

What it does

  • uidFromDn derives a namespaced, stable uid from an entry's distinguished name (urn:x-ihasmail:ldif:…), normalised for the case and spacing two exports of one directory differ in. The namespace is what keeps it from being read as a UID a vCard author meant.
  • A card the target book already holds under that uid is updated, not duplicated — merged as the vCard import merges: properties the file carries win, properties it does not mention are left alone. Skipping would mean a corrected export corrects nothing, which is the whole reason anyone re-imports.
  • The toast reports created and updated apart, which is the pair that was asked for.
  • An entry with no usable dn gets an identity of its own and duplicates on re-import, as everything did before.

Three things worth knowing

Matching is per address book. Two customer directories that each hold a cn=John Smith stay two people as long as they are filed separately; imported into one book they merge. That is the one way this can be wrong, and separate books are the escape hatch.

The look-alike count stays and now means something narrower — entries dn matching could not catch: one whose dn moved between exports, and anything imported before there was a dn to match on. Still counted, never merged, because name-plus-email is a guess wrong in both directions.

A file with two entries under one dn is malformed, since a directory cannot hold that, and now becomes one card rather than two sharing an identity.

Tests

New ldif-dedupe.test.ts covers update-not-duplicate, the merge, that the card is not refiled into the import target, per-book scoping, case and spacing, and created/updated reported apart. uidFromDn has unit tests next to the parser. Existing LDIF suites updated where they asserted the old "invents a UID" behaviour. 1034 web tests, 142 server tests, typecheck clean.

Merged 2026-09-04 as coffey-labs/ihasmail@4d23cef511

Rebuilt from: git history, session transcript.

Closes the half of #223 that was left undone when it was closed. Reported again by the submitter's colleague at LINET: duplicate checking landed for vCard and never for LDIF, so re-importing an address book still leaves a second copy of everything. It was left open because I wanted the matching key decided rather than guessed. The decision had already been made on [#174](https://github.com/Coffey-Labs/ihasmail/issues/174#issuecomment-5507056538) — an attribute that *can* change is fine, because it will not have changed between two imports minutes apart — and I closed the issue without acting on it. ## What it does - `uidFromDn` derives a namespaced, stable uid from an entry's distinguished name (`urn:x-ihasmail:ldif:…`), normalised for the case and spacing two exports of one directory differ in. The namespace is what keeps it from being read as a UID a vCard author meant. - A card the target book already holds under that uid is **updated, not duplicated** — merged as the vCard import merges: properties the file carries win, properties it does not mention are left alone. Skipping would mean a corrected export corrects nothing, which is the whole reason anyone re-imports. - The toast reports **created and updated** apart, which is the pair that was asked for. - An entry with no usable `dn` gets an identity of its own and duplicates on re-import, as everything did before. ## Three things worth knowing **Matching is per address book.** Two customer directories that each hold a `cn=John Smith` stay two people as long as they are filed separately; imported into one book they merge. That is the one way this can be wrong, and separate books are the escape hatch. **The look-alike count stays and now means something narrower** — entries `dn` matching could not catch: one whose `dn` moved between exports, and anything imported before there was a `dn` to match on. Still counted, never merged, because name-plus-email is a guess wrong in both directions. **A file with two entries under one `dn`** is malformed, since a directory cannot hold that, and now becomes one card rather than two sharing an identity. ## Tests New `ldif-dedupe.test.ts` covers update-not-duplicate, the merge, that the card is not refiled into the import target, per-book scoping, case and spacing, and created/updated reported apart. `uidFromDn` has unit tests next to the parser. Existing LDIF suites updated where they asserted the old "invents a UID" behaviour. 1034 web tests, 142 server tests, typecheck clean. **Merged** 2026-09-04 as coffey-labs/ihasmail@4d23cef5112c <sub>Rebuilt from: git history, session transcript.</sub>
This repo is archived. You cannot comment on issues.