scimgateway 4.2.9 → 4.2.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1169,6 +1169,12 @@ MIT © [Jarle Elshaug](https://www.elshaug.xyz)
1169
1169
 
1170
1170
  ## Change log
1171
1171
 
1172
+ ### v4.2.10
1173
+
1174
+ [Fixed]
1175
+
1176
+ - plugin-ldap broken after dependencies bump of ldapjs (from 2.x.x to 3.x.x) in version 4.2.7
1177
+
1172
1178
  ### v4.2.9
1173
1179
 
1174
1180
  [Fixed]
@@ -110,15 +110,11 @@ if (config.useSID_id && config.map.group) {
110
110
  }
111
111
  if (config.map.user.userPrincipalName && config.map.user.userPrincipalName.mapDomain) { // support mapping different inbound/outbound upn domain names
112
112
  if (config.map.user.userPrincipalName.mapDomain.inbound && config.map.user.userPrincipalName.mapDomain.outbound) {
113
- let inbound = config.map.user.userPrincipalName.mapDomain.inbound
114
- let outbound = config.map.user.userPrincipalName.mapDomain.outbound
115
- inbound = inbound.startsWith('@') ? inbound : '@' + inbound
116
- outbound = outbound.startsWith('@') ? outbound : '@' + outbound
117
- config.upnMapDomain = {
118
- inbound: inbound, // "test.onmicrosoft.com
119
- outbound: outbound // "my-company.com"
120
- }
121
- }
113
+ const inbound = config.map.user.userPrincipalName.mapDomain.inbound
114
+ const outbound = config.map.user.userPrincipalName.mapDomain.outbound
115
+ config.map.user.userPrincipalName.mapDomain.inbound = inbound.startsWith('@') ? inbound : '@' + inbound // "@my-company.com"
116
+ config.map.user.userPrincipalName.mapDomain.outbound = outbound.startsWith('@') ? outbound : '@' + outbound // "@test.onmicrosoft.com
117
+ } else delete config.map.user.userPrincipalName.mapDomain
122
118
  }
123
119
 
124
120
  // =================================================
@@ -1034,13 +1030,12 @@ const doRequest = async (baseEntity, method, base, ldapOptions, ctx) => {
1034
1030
  let client = null
1035
1031
 
1036
1032
  const options = scimgateway.copyObj(ldapOptions)
1037
- if (config.upnMapDomain) {
1038
- for (const key in options) {
1039
- if ((typeof options[key] === 'string') && options[key].includes(config.upnMapDomain.inbound)) {
1040
- const old = options[key]
1041
- options[key] = options[key].replace(config.upnMapDomain.inbound, config.upnMapDomain.outbound)
1042
- scimgateway.logger.debug(`${pluginName}[${baseEntity}] inbound upnMapDomain ${old} => ${options[key]}`)
1043
- }
1033
+ // support having different upn-domain on IdP and target
1034
+ if (options.modification && options.modification.userPrincipalName && config.map.user.userPrincipalName && config.map.user.userPrincipalName.mapDomain) {
1035
+ if (options.modification.userPrincipalName.endsWith(config.map.user.userPrincipalName.mapDomain.outbound)) {
1036
+ const old = options.modification.userPrincipalName
1037
+ options.modification.userPrincipalName = options.modification.userPrincipalName.replace(config.map.user.userPrincipalName.mapDomain.outbound, config.map.user.userPrincipalName.mapDomain.inbound)
1038
+ scimgateway.logger.debug(`${pluginName}[${baseEntity}] inbound upnMapDomain ${old} => ${options.modification.userPrincipalName}`)
1044
1039
  }
1045
1040
  }
1046
1041
 
@@ -1055,37 +1050,45 @@ const doRequest = async (baseEntity, method, base, ldapOptions, ctx) => {
1055
1050
  if (err) {
1056
1051
  return reject(err)
1057
1052
  }
1053
+
1058
1054
  search.on('searchEntry', (entry) => {
1059
- if (entry.attributes) {
1060
- entry.attributes.find((el, i) => {
1061
- if (['objectSid', 'objectGUID'].includes(el.type)) { // assume Active Directory - can't use default utf-8 when attribute value is hex
1062
- const b = Buffer.from(el.buffers[0], 'hex')
1063
- if (el.type === 'objectSid') {
1064
- const sidStr = convertSidToString(b) // using string: S-1-5-21-2657077294-4200173015-2627628055-1255
1065
- if (!sidStr) throw new Error(`doRequest() error: failed to convert SID ${b.toString('hex')} to string}`)
1066
- entry.attributes[i]._vals = [sidStr]
1067
- } else {
1068
- entry.attributes[i]._vals = [b.toString('base64')] // using base64: nitWLrhokUqKl1DywiavXg==
1069
- }
1070
- } else if (el.type === 'userPrincipalName' && config.upnMapDomain) {
1071
- const val = Buffer.from(el.buffers[0], 'hex').toString('utf8')
1072
- const old = val
1073
- entry.attributes[i]._vals = [val.replace(config.upnMapDomain.outbound, config.upnMapDomain.inbound)]
1074
- scimgateway.logger.debug(`${pluginName}[${baseEntity}] outbound upnMapDomain ${old} => ${entry.attributes[i]._vals}`)
1075
- }
1076
- return undefined
1077
- })
1055
+ if (!entry.pojo || !entry.pojo.attributes) return
1056
+ const obj = { dn: entry.pojo.objectName }
1057
+ entry.pojo.attributes.map((el) => {
1058
+ if (el.values.length > 1) obj[el.type] = el.values
1059
+ else obj[el.type] = el.values[0]
1060
+ return null
1061
+ })
1062
+ // objectSid/objectGUID - assume Active Directory - can't use default utf-8 when attribute value is hex
1063
+ if (obj.objectSid) {
1064
+ const b = Buffer.from(obj.objectSid, 'utf-8')
1065
+ const sidStr = convertSidToString(b) // using string: S-1-5-21-2657077294-4200173015-2627628055-1255
1066
+ if (!sidStr) throw new Error(`doRequest() error: failed to convert SID ${b.toString('hex')} to string}`)
1067
+ obj.objectSid = sidStr
1068
+ }
1069
+ if (obj.objectGUID) {
1070
+ const b = Buffer.from(obj.objectGUID, 'utf-8')
1071
+ obj.objectGUID = b.toString('base64') // using base64: nitWLrhokUqKl1DywiavXg==
1072
+ }
1073
+ if (obj.userPrincipalName && config.map.user.userPrincipalName && config.map.user.userPrincipalName.mapDomain) {
1074
+ if (obj.userPrincipalName.endsWith(config.map.user.userPrincipalName.mapDomain.inbound)) {
1075
+ const old = obj.userPrincipalName
1076
+ obj.userPrincipalName = obj.userPrincipalName.replace(config.map.user.userPrincipalName.mapDomain.inbound, config.map.user.userPrincipalName.mapDomain.outbound)
1077
+ scimgateway.logger.debug(`${pluginName}[${baseEntity}] outbound upnMapDomain ${old} => ${obj.userPrincipalName}`)
1078
+ }
1078
1079
  }
1079
- results.push(entry.object)
1080
+ results.push(obj)
1080
1081
  })
1081
1082
 
1082
1083
  search.on('page', (entry, cb) => {
1083
1084
  // if (cb) cb() // pagePause = true gives callback
1084
1085
  })
1086
+
1085
1087
  search.on('error', (err) => {
1086
1088
  if (err.message.includes('LdapErr: DSID-0C0909F2') || err.message.includes('NO_OBJECT')) return resolve([]) // object not found when using base <SID=...> or <GUID=...> ref. objectSid/objectGUID
1087
1089
  reject(err)
1088
1090
  })
1091
+
1089
1092
  search.on('end', (_) => { resolve(results) })
1090
1093
  })
1091
1094
  })
@@ -1094,7 +1097,22 @@ const doRequest = async (baseEntity, method, base, ldapOptions, ctx) => {
1094
1097
  case 'modify':
1095
1098
  result = await new Promise((resolve, reject) => {
1096
1099
  const dn = base
1097
- client.modify(dn, options, (err) => {
1100
+ const changes = []
1101
+ for (const key in options.modification) {
1102
+ const mod = {}
1103
+ mod.type = key
1104
+ if (Array.isArray(options.modification[key])) mod.values = options.modification[key]
1105
+ else {
1106
+ if (typeof options.modification[key] === 'string') mod.values = [options.modification[key]]
1107
+ else mod.values = [options.modification[key].toString()]
1108
+ }
1109
+ const change = new ldap.Change({
1110
+ operation: options.operation || 'replace',
1111
+ modification: mod // { type: "givenName", values: ["Joe"] }
1112
+ })
1113
+ changes.push(change)
1114
+ }
1115
+ client.modify(dn, changes, (err) => {
1098
1116
  if (err) {
1099
1117
  if (options.operation && options.operation === 'add' && options.modification && options.modification.member) {
1100
1118
  if (err.message.includes('ENTRY_EXISTS')) return resolve() // add already existing group to user
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "scimgateway",
3
- "version": "4.2.9",
3
+ "version": "4.2.10",
4
4
  "description": "Using SCIM protocol as a gateway for user provisioning to other endpoints",
5
5
  "author": "Jarle Elshaug <jarle.elshaug@gmail.com> (https://elshaug.xyz)",
6
6
  "homepage": "https://elshaug.xyz",