From 2ac1c30112cd39a6b00ba0b0603ec3e72185c8ff Mon Sep 17 00:00:00 2001 From: William Mantly Date: Sun, 26 Jul 2026 22:38:48 -0400 Subject: [PATCH] Fix sshPublicKey ObjectClassViolationError and blank OAuth parent dropdown - User.update/addSSHkey now ensure the ldapPublicKey objectClass is present before writing sshPublicKey, so accounts predating that objectClass (e.g. the bootstrap admin) no longer 500 on PUT /api/user/:uid. - populateHostDropdown in directory.ejs was missing an `oauth` branch, leaving the parent-Service picker blank when adding an OAuth Integration. - Bump to 1.5.1. Co-Authored-By: Claude Sonnet 5 --- CHANGELOG.md | 6 ++++++ nodejs/models/user_ldap.js | 26 ++++++++++++++++++++++++++ nodejs/package.json | 2 +- nodejs/views/directory.ejs | 2 ++ 4 files changed, 35 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b066dd9..7beb113 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project are documented here. Format loosely follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); versions correspond to git tags (`vX.Y.Z`) and `nodejs/package.json`'s `version`. +## [1.5.1] - 2026-07-27 + +### Fixed +- **`PUT /api/user/:uid` 500'd with `ObjectClassViolationError` (LDAP `0x41`) when setting `sshPublicKey`** on any account created before the `ldapPublicKey` auxiliary objectClass was added to new-user creation (e.g. the bootstrap `admin` account). `User.update`'s `sshPublicKey` handling and `User.addSSHkey` (`nodejs/models/user_ldap.js`) now add the `ldapPublicKey` objectClass first (ignoring `TypeOrValueExistsError` if already present), the same pattern already used for `dateOfBirth`/`theta42Person`. +- **OAuth Integration parent dropdown was blank.** `populateHostDropdown` in `nodejs/views/directory.ejs` only built options for `kind === 'host'` and `kind === 'service'` — there was no branch for `kind === 'oauth'`, so choosing "OAuth Integration" in the Directory's add-resource modal left the parent-Service picker empty except the placeholder. Added the missing branch. + ## [1.5.0] - 2026-07-26 ### Changed diff --git a/nodejs/models/user_ldap.js b/nodejs/models/user_ldap.js index dd82393..e7afd01 100644 --- a/nodejs/models/user_ldap.js +++ b/nodejs/models/user_ldap.js @@ -473,6 +473,19 @@ User.update = async function(data){ } if(data.sshPublicKey){ + // Ensure the auxiliary objectClass is present before setting the attribute + // -- accounts created before ldapPublicKey was added to addPosixAccount's + // objectclass list (e.g. the bootstrap admin) won't have it yet. + try { + await client.modify(this.dn, [ + new Change({ + operation: 'add', + modification: new Attribute({ type: 'objectClass', values: ['ldapPublicKey'] }), + }), + ]); + } catch(e) { + if(e.name !== 'TypeOrValueExistsError') throw e; + } await client.modify(this.dn, [ new Change({ operation: 'replace', @@ -784,6 +797,19 @@ User.addSSHkey = async function(data) { let result; try { await withClient(async (client) => { + // Ensure the auxiliary objectClass is present before setting the attribute + // -- accounts created before ldapPublicKey was added to addPosixAccount's + // objectclass list (e.g. the bootstrap admin) won't have it yet. + try { + await client.modify(user.dn, [ + new Change({ + operation: 'add', + modification: new Attribute({ type: 'objectClass', values: ['ldapPublicKey'] }), + }), + ]); + } catch(e) { + if (e.name !== 'TypeOrValueExistsError') throw e; + } await client.modify(user.dn, [ new Change({ operation: 'add', diff --git a/nodejs/package.json b/nodejs/package.json index ae51b96..19a80c4 100755 --- a/nodejs/package.json +++ b/nodejs/package.json @@ -1,6 +1,6 @@ { "name": "t42-sso-manager", - "version": "1.5.0", + "version": "1.5.1", "description": "A very simple LDAP management and SSO system", "author": [ { diff --git a/nodejs/views/directory.ejs b/nodejs/views/directory.ejs index 955cef6..465f9db 100644 --- a/nodejs/views/directory.ejs +++ b/nodejs/views/directory.ejs @@ -572,6 +572,8 @@ $target.append($('