Changelogs

Release notes for every version of Dirdap.

v0.3.0Latest

Adds automatic update checks, schema-driven attribute and object-class editing, and a more consistent interface. It also makes binary writes and DIT tree expansion reliable, verifies update downloads, and recovers saved connections from a backup.

Added

  • Automatic update checks. The app checks the latest GitLab release at startup and every hour. The first time a newer release is found, it opens the update dialog with the release notes; a badge in the header keeps that version reachable after the dialog is closed. Choosing Update now downloads the installer for the current platform, verifies its SHA-256 checksum, replaces the app and restarts it.
  • Add Attribute guided by the schema. The picker offers only the attributes the entry can still gain — MUST and MAY attributes from its object classes, with aliases collapsed and excluding the RDN, read-only, password, password-history and already-present single-valued attributes. The value editor follows the attribute type: TRUE/FALSE, a calendar using the schema’s timestamp format, a multi-line address field, or a file picker for binary, image and certificate values. When the server schema is unavailable, the dialog falls back to free-text entry.
  • Add Object Class. The editor can add the auxiliary object classes declared by the server schema — the only kind an existing entry can gain — and leaves out the classes the entry already carries. Without a schema, the field falls back to free text.
  • Clear the Activity Log. A clear action in the Activity Log header empties the log.
  • Empty panels explain themselves. A panel with nothing to show displays a centred icon and message instead of an empty list.

Changed

  • One panel header. Connections, DIT, Activity Log and Search share the same title-bar height and padding; the Search form sits below its title, and the actions keep the same spacing across panels.
  • Consistent controls. Buttons, icon buttons, inputs and selects now have consistent sizing, focus and hover behaviour.
  • Native platform font. The app no longer bundles Inter; it uses the platform’s UI font, so no webfont is served and text matches the system.
  • Attribute edits wait for the server. Attribute additions and removals appear only after the server accepts the write; a refusal leaves the entry unchanged and shows the server’s message. New attributes are inserted in alphabetical order.
  • Escape closes overlays. Escape now closes dialogs, selects and menus.
  • Windows support removed. Windows is no longer supported or packaged; Linux and macOS remain supported.

Fixed

  • Binary attribute writes. Removing userCertificate or another binary-transfer attribute no longer fails with LDAP code 17: ;binary is sent only for the syntaxes that require it, on every write, including deletes, and base64 values are decoded to their bytes.
  • A DIT node with children stays expandable. A node whose children are already in memory keeps its arrow even when the schema hint calls it a leaf and a later child fetch fails, so its rows stay reachable.
  • Corrupt connections are recovered. If the connections file is corrupt, the app reads the owner-only .bak file instead of losing the saved connections.
  • The Linux AppImage has the correct icon. Cross-built AppImages now embed the application icon.
  • More stable layout. Line heights and the heights of form fields are now fixed and the monospace font is consistent, so the layout no longer depends on how the rendering engine rounds line heights or measures the monospace font. Labels, panels and buttons no longer shift by 1–2 px or truncate text differently. Attribute values line up with their icons and timestamps with the calendar icon; password dots are unchanged. Small character-width differences remain, visible only when text is close to being cut off.

Security

  • Verified updates. The installer’s SHA-256 checksum is verified before an update is applied, and an update without a published checksum is not offered.
  • TLS verification is visible. The connection form warns when certificate verification is disabled, and a live TLS connection with it off carries a persistent TLS off badge.
  • Safe release notes. The update dialog renders release notes with a minimal Markdown renderer that escapes raw HTML and keeps unsafe links as plain text.

Performance

  • Add Attribute stays local. The picker is computed from the entry’s object classes and the schema already in memory, with no extra LDAP round-trip.

Previous versions

▸v0.2.3

Makes the entry editor safer and more readable: multi-line values edit in full, removals ask for confirmation, timestamps are edited with a calendar, and narrow windows stay readable. Writes respect the server’s schema again.

Added

  • A calendar for timestamps. Timestamp attributes (createTimestamp, modifyTimestamp, pwdLastSet and the other FILETIME values) are no longer edited as raw strings: the editor opens a date/time picker, shows the value in its human form, and writes it back in the attribute’s own format — GeneralizedTime or FILETIME. The special FILETIME sentinels (never expires, must change password, never logged on) are offered as their own action, instead of being typed by hand.
  • Confirmation before removal. Removing a value or a whole attribute asks for confirmation and shows the value being removed. The entry DN is no longer a row among the attributes: it is shown in the editor’s header, where it cannot be mistaken for a removable value.

Changed

  • Multi-line values edit in full. Editing a value used to cut it at the first line; the editor now keeps the value’s lines exactly as displayed, so long values can be read and changed in full.
  • The entry stays readable on narrow windows. When the window is narrow, an attribute’s name and its badges stay on their own line and the values move below them, instead of squeezing every column.
  • pwdHistory shows change dates. A password history value is recognized by its record shape and shown as the date of the change — not as an opaque binary value — whether or not the server’s schema classifies it as bytes.
  • Dropdowns centre the selected option when they open, so the current value stays visible even in a long list.
  • The interface ships its own font. Text now renders with Inter instead of the installed system font, so the app looks the same on every platform and nothing wraps or truncates differently from one machine to another.

Fixed

  • Modifies no longer carry read-only operational attributes. An edit could include an attribute the schema marks NO-USER-MODIFICATION, and the server refused the whole operation (result code 19); such attributes are now never written.
  • The last required value is protected. The editor no longer offers removing the last value of an attribute the entry’s object classes require: the server refuses it (result code 65) and the value belongs to the entry’s identity.
  • A refused change reloads the entry in order. When the server rejects an edit, the restored attribute returns to its alphabetical position instead of reappearing at the bottom of the list.
▸v0.2.2

Rewrites LDIF parsing and DN comparison, hardens the connection lifecycle, adds password management for Active Directory, and narrows the desktop package’s permissions.

Added

  • Passwords on Active Directory. Changing a password now works on AD, which keeps it in a different attribute (unicodePwd) that is only writable over a secure channel; the dialog adapts to the server, offering the hash algorithm on OpenLDAP and warning about TLS on AD.
  • Attribute kinds from the schema. GUIDs, addresses, UUIDs, X.509 certificates, booleans and timestamps are now shown in their own form — a GUID as a GUID, a boolean as true or false — instead of as the raw string.
  • Image thumbnails. Attributes that hold an image (jpegPhoto, thumbnailPhoto) show a preview that opens full size, rather than base64.
  • Operational attributes. Reads now request the operational attributes as well (* plus +), so pwdHistory and other operational values are visible; a read-only attribute is marked from its NO-USER-MODIFICATION flag.
  • A warning banner in the edit form when the connection is open: only its name can be changed then, because the running session keeps using the saved configuration.

Changed

  • LDIF import and export conform to RFC 2849. The parser is a tokenizer rather than a line loop, so folded lines, comments, :< URL values and moddn/modrdn are handled correctly. An import is now all-or-nothing (a file with one error applies nothing) and reports the outcome per record; export base64-encodes non-SAFE values and folds at 76 columns, staying re-importable.
  • An edit is written as soon as it is made, one write at a time, instead of waiting for a 600 ms quiet period. There is no pending window left to drop, so moving to another entry right after an edit no longer loses it, and a write that finishes after the panel moved on no longer touches it.
  • DNs are compared and keyed in their RFC 4514 normalized form, so two DNs that denote the same entry but are written differently — extra spaces, escape style, or the order of a multi-valued RDN — are treated as the same.
  • Clicking a connection that is already open makes it active instead of reconnecting it, so it no longer flashes “connecting” for nothing.
  • userPassword is no longer treated as binary on a stock OpenLDAP server, so the password attribute is shown and edited as text.
  • Binary values read more clearly and the attribute name and value columns line up.

Fixed

  • A failed reconnect keeps your session. Reconnecting used to drop the old client before binding the new one, so a wrong password or a server briefly down left you disconnected; the new client is now bound first and the old one replaced only on success.
  • Closing the app closes its sessions with an unbind, instead of leaving the server to reap them.
  • A session whose credentials were refused is ended, instead of staying shown as connected while every operation fails.
  • Two connects at once can no longer open two sockets, and a double click no longer starts a second one.
  • Deleting an entry no longer lets it reappear: a fetch that was already in flight when the entry was deleted is no longer reused or injected.
  • The connection list and a search index can no longer be left stale by an aborted build or a deletion that arrives while a fetch is running.
  • The connection import works in the desktop app: the file picker now hands the chosen file to an input that is part of the document.
  • Search This Branch always starts. The search panel applied a branch search requested from the tree only when the selection happened to change; it now reacts to the request itself, so the search runs even with the selection still.
  • The tree refreshes and reveals when another panel asks. An import, a rename or a search result now updates the tree at once, instead of waiting for an unrelated render.

Security

  • The desktop package asks for fewer permissions: the local HTTP server and the LDAP connections, the connections file, and the environment variables that pick its directory — not the whole -A.
▸v0.2.1

Fixes a fault that made wide searches return a fraction of their entries while reporting success. Also fixes losing your edits when a save is refused, losing them again when the server had dropped an idle connection, and an auto-save that could send values you had already changed.

Fixed

  • Searches no longer report success on an incomplete result. Wide searches had been failing on the packaged app since 0.2.0, where the symptom was a crash; the release mitigated it by capping pages at 850 entries, which held often enough to ship but left the cause unidentified. That cause has now been measured. The message parser in ldapts, the LDAP library, calls itself once per message that arrives in the same TCP read, so the stack depth was set by how the network happened to deliver the response rather than by anything the app requested, and the packaged app runs on QuickJS, whose stack holds an order of magnitude fewer of those calls than the V8 engine the dev server uses. Past the limit the overflow was swallowed and the entries already parsed were returned as if complete, which is the more damaging form of the same fault: a crash is at least visible. Incoming data is now reassembled into one message per read before the parser sees it, so the depth is fixed at one call regardless of how the response arrives. The measurements, and the two explanations they ruled out, are written up in FRAMING.md.
  • A refused save no longer discards your work. When the directory rejected an attribute, the value stayed in the local entry and every later save resubmitted it and failed again, even for an unrelated edit. If the edit included the entry’s name, the rename committed while the rest did not, leaving the app pointing at a DN the directory no longer knew.
  • An idle connection repairs itself. After a period of inactivity the app still showed itself connected while the server had closed the connection: the next operation failed, the session was torn down, and the current selection and any unsaved edit went with it. The connection is now checked before use and rebound when needed, without asking for credentials again.
  • Auto-save cannot send values you have already changed. A pending save is cancelled when the entry changes, when the connection goes away, before a delete and after a refusal, and two saves can no longer overlap.
  • Write errors name the operation and the result code instead of the hex suffix the library appends.
  • Group ranges in the tree are bracketed ([1...250]), so a range no longer reads as an entry named after it.

Changed

  • Pages of a search or a branch enumeration carry 1500 entries instead of 850. The 850 cap was a mitigation, not a setting: it kept the parser under its limit often enough to work, on the working assumption that the page size governed the recursion depth. Measurement showed it does not — what governs the depth is how many messages share one TCP read, which no page size controls. With the cause addressed, the page size only trades round trips against the memory one page holds. Enumerating 21 000 entries takes 14 pages instead of 25; the cost of parsing each entry is unchanged.
▸v0.2.0

Makes large directories usable: branches and search results with tens of thousands of entries are paged instead of fetched whole, and attributes are rendered from the server schema, so timestamps are readable and read-only attributes are marked. Side panels collapse and resize. Fixes binary value corruption on save and several LDIF parsing errors.

Added

  • The connection form can look up the available base DNs from the server’s Root DSE, instead of requiring them to be typed in.
  • Side panels can be collapsed and resized by dragging; dragging past the minimum width collapses the panel, and double clicking the resize grip restores the default width.
  • Large branches of the tree are shown as position ranges (1...250) and only the open range is fetched.
  • A branch with more children than the index holds is now marked as capped, with a tooltip naming the limit, and its context menu offers Search This Branch to reach the rest through the search panel.
  • Non-editable attributes carry a read-only hint.
  • Timestamp attributes (GeneralizedTime and Active Directory FILETIME) are formatted for humans.

Changed

  • How an attribute is displayed and whether it can be edited now comes from the server subschema rather than a built-in list, so the app follows the directory’s own definitions.
  • Search results are paged through a sorted index built once per query: showing ten matches no longer fetches all of them. Indexing runs on a second connection, so a search never stalls the tree.
  • Error messages describe the LDAP result code instead of showing its hex value (No such object (code 32) in place of Code: 0x20).
  • Long attribute names are revealed on hover, and the name column is wider.
  • Scrollbars follow the platform’s overlay style.

Fixed

  • Values the directory returns as raw bytes are written back unchanged. Saving an entry with a binary attribute previously corrupted it.
  • LDIF import read a folded dn: line as its last segment only, and merged consecutive modify records into the first.
  • Two paged operations on the same connection made the server reject one of them with unwillingToPerform (0x35).
  • Pressing Next twice in the search results skipped a page, and paging or exporting after editing a search field applied the new criteria to the old result set.
  • Context menu actions could act on the wrong node when the menu had been reopened elsewhere.
  • The LDIF export log reported the size of the index rather than the number of entries exported.
  • Loading spinners wobbled instead of turning in place in the desktop app.
  • Long attribute values wrap instead of scrolling the pane sideways, the remove cross no longer reflows the value next to it, and attribute names and read-only values can be selected.
▸v0.1.1

Adds StartTLS connections, decouples saving a connection from testing it, and closes modals only on explicit actions. Fixes the desktop window close and size.

Added

  • StartTLS protocol for connections, alongside LDAP and LDAPS.

Changed

  • A connection can now be saved without a successful test, so a profile can be stored with incomplete credentials and completed later.
  • Modals no longer close when clicking outside; they close only via their close button or the Escape key.

Fixed

  • Closing the application window now terminates the process.
  • The application window now opens at a fixed size (1200×800).
▸v0.1.0

Initial release of Dirdap, a desktop app to browse, search and edit LDAP directories locally. Available for Linux, macOS and Windows.

Added

  • Create, test and manage LDAP and LDAPS connection profiles, with export and import.
  • Browse the directory information tree, with a per-entry context menu (copy, paste, delete, LDIF export/import).
  • Read, add, modify and delete entries and attributes, with inline editing and auto-save.
  • Scoped search (base, one level, subtree) with paginated results and LDIF export.
  • Import and export LDIF, plus a standalone LDIF editor.
  • Verify and change user passwords, hashed with RFC 2307.
  • Activity log for every operation.

Security

  • Binds to localhost only, with CSRF protection and hardened response headers.
  • LDIF export warns that connection passwords are exported in plain text.