@backstage/plugin-catalog-backend-module-ldap 0.12.9-next.1 → 0.12.9

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/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @backstage/plugin-catalog-backend-module-ldap
2
2
 
3
+ ## 0.12.9
4
+
5
+ ### Patch Changes
6
+
7
+ - 736d84e: Use locale-insensitive Unicode casing for consistent string handling across environments.
8
+ - Updated dependencies
9
+ - @backstage/plugin-catalog-common@1.2.0
10
+ - @backstage/catalog-model@1.10.1
11
+ - @backstage/config@1.3.9
12
+ - @backstage/backend-plugin-api@1.10.1
13
+ - @backstage/plugin-catalog-node@2.2.5
14
+
3
15
  ## 0.12.9-next.1
4
16
 
5
17
  ### Patch Changes
@@ -228,7 +228,7 @@ function ensureItems(target, key, values) {
228
228
  }
229
229
  function getValueFromMapWithInsensitiveKey(map, searchValue) {
230
230
  const result = map.get(searchValue);
231
- return result ? result : map.get(searchValue.toLocaleLowerCase("en-US"));
231
+ return result ? result : map.get(searchValue.toLowerCase());
232
232
  }
233
233
  function resolveRelations(groups, users, userMemberOf, groupMemberOf, groupMember) {
234
234
  const userMap = /* @__PURE__ */ new Map();
@@ -237,9 +237,7 @@ function resolveRelations(groups, users, userMemberOf, groupMemberOf, groupMembe
237
237
  userMap.set(catalogModel.stringifyEntityRef(user), user);
238
238
  userMap.set(user.metadata.annotations[constants.LDAP_DN_ANNOTATION], user);
239
239
  userMap.set(
240
- user.metadata.annotations[constants.LDAP_DN_ANNOTATION]?.toLocaleLowerCase(
241
- "en-US"
242
- ),
240
+ user.metadata.annotations[constants.LDAP_DN_ANNOTATION]?.toLowerCase(),
243
241
  user
244
242
  );
245
243
  userMap.set(user.metadata.annotations[constants.LDAP_RDN_ANNOTATION], user);
@@ -249,9 +247,7 @@ function resolveRelations(groups, users, userMemberOf, groupMemberOf, groupMembe
249
247
  groupMap.set(catalogModel.stringifyEntityRef(group), group);
250
248
  groupMap.set(group.metadata.annotations[constants.LDAP_DN_ANNOTATION], group);
251
249
  groupMap.set(
252
- group.metadata.annotations[constants.LDAP_DN_ANNOTATION]?.toLocaleLowerCase(
253
- "en-US"
254
- ),
250
+ group.metadata.annotations[constants.LDAP_DN_ANNOTATION]?.toLowerCase(),
255
251
  group
256
252
  );
257
253
  groupMap.set(group.metadata.annotations[constants.LDAP_RDN_ANNOTATION], group);
@@ -1 +1 @@
1
- {"version":3,"file":"read.cjs.js","sources":["../../src/ldap/read.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n GroupEntity,\n stringifyEntityRef,\n UserEntity,\n} from '@backstage/catalog-model';\nimport { Entry } from 'ldapts';\nimport lodashSet from 'lodash/set';\nimport cloneDeep from 'lodash/cloneDeep';\nimport { buildOrgHierarchy } from './org';\nimport { LdapClient } from './client';\nimport { GroupConfig, UserConfig, VendorConfig } from './config';\nimport {\n LDAP_DN_ANNOTATION,\n LDAP_RDN_ANNOTATION,\n LDAP_UUID_ANNOTATION,\n} from './constants';\nimport { LdapVendor } from './vendors';\nimport { GroupTransformer, UserTransformer } from './types';\nimport { mapStringAttr } from './util';\nimport { LoggerService } from '@backstage/backend-plugin-api';\nimport { InputError } from '@backstage/errors';\n\n/**\n * The default implementation of the transformation from an LDAP entry to a\n * User entity.\n *\n * @public\n */\nexport async function defaultUserTransformer(\n vendor: LdapVendor,\n config: UserConfig,\n entry: Entry,\n): Promise<UserEntity | undefined> {\n const { set, map } = config;\n\n const entity: UserEntity = {\n apiVersion: 'backstage.io/v1beta1',\n kind: 'User',\n metadata: {\n name: '',\n annotations: {},\n },\n spec: {\n profile: {},\n memberOf: [],\n },\n };\n\n if (set) {\n for (const [path, value] of Object.entries(set)) {\n lodashSet(entity, path, cloneDeep(value));\n }\n }\n\n mapStringAttr(entry, vendor, map.name, v => {\n entity.metadata.name = v;\n });\n\n if (!entity.metadata.name) {\n throw new InputError(\n `User syncing failed: missing '${map.name}' attribute, consider applying a user filter to skip processing users with incomplete data.`,\n );\n }\n\n mapStringAttr(entry, vendor, map.description, v => {\n entity.metadata.description = v;\n });\n mapStringAttr(entry, vendor, map.rdn, v => {\n entity.metadata.annotations![LDAP_RDN_ANNOTATION] = v;\n });\n mapStringAttr(entry, vendor, vendor.uuidAttributeName, v => {\n entity.metadata.annotations![LDAP_UUID_ANNOTATION] = v;\n });\n mapStringAttr(entry, vendor, vendor.dnAttributeName, v => {\n entity.metadata.annotations![LDAP_DN_ANNOTATION] = v;\n });\n mapStringAttr(entry, vendor, map.displayName, v => {\n entity.spec.profile!.displayName = v;\n });\n mapStringAttr(entry, vendor, map.email, v => {\n entity.spec.profile!.email = v;\n });\n mapStringAttr(entry, vendor, map.picture, v => {\n entity.spec.profile!.picture = v;\n });\n\n return entity;\n}\n\n/**\n * Reads users out of an LDAP provider.\n *\n * @param client - The LDAP client\n * @param config - The user data configuration\n * @param opts - Additional options\n */\nexport async function readLdapUsers(\n client: LdapClient,\n userConfig: UserConfig[],\n vendorConfig: VendorConfig | undefined,\n opts?: { transformer?: UserTransformer },\n): Promise<{\n users: UserEntity[]; // With all relations empty\n userMemberOf: Map<string, Set<string>>; // DN -> DN or UUID of groups\n}> {\n if (userConfig.length === 0) {\n return { users: [], userMemberOf: new Map() };\n }\n const entities: UserEntity[] = [];\n const userMemberOf: Map<string, Set<string>> = new Map();\n const vendorDefaults = await client.getVendor();\n const vendor: LdapVendor = {\n dnAttributeName:\n vendorConfig?.dnAttributeName ?? vendorDefaults.dnAttributeName,\n uuidAttributeName:\n vendorConfig?.uuidAttributeName ?? vendorDefaults.uuidAttributeName,\n decodeStringAttribute: vendorDefaults.decodeStringAttribute,\n };\n const transformer = opts?.transformer ?? defaultUserTransformer;\n\n for (const cfg of userConfig) {\n const { dn, options, map } = cfg;\n const searchResult = await client.search(dn, options);\n for (const entry of searchResult.searchEntries) {\n const entity = await transformer(vendor, cfg, entry);\n\n if (!entity) {\n continue;\n }\n\n mapReferencesAttr(entry, vendor, map.memberOf, (myDn, vs) => {\n ensureItems(userMemberOf, myDn, vs);\n });\n\n entities.push(entity);\n }\n }\n\n return { users: entities, userMemberOf };\n}\n\n/**\n * The default implementation of the transformation from an LDAP entry to a\n * Group entity.\n *\n * @public\n */\nexport async function defaultGroupTransformer(\n vendor: LdapVendor,\n config: GroupConfig,\n entry: Entry,\n): Promise<GroupEntity | undefined> {\n const { set, map } = config;\n const entity: GroupEntity = {\n apiVersion: 'backstage.io/v1beta1',\n kind: 'Group',\n metadata: {\n name: '',\n annotations: {},\n },\n spec: {\n type: 'unknown',\n profile: {},\n children: [],\n },\n };\n\n if (set) {\n for (const [path, value] of Object.entries(set)) {\n lodashSet(entity, path, cloneDeep(value));\n }\n }\n\n mapStringAttr(entry, vendor, map.name, v => {\n entity.metadata.name = v;\n });\n\n if (!entity.metadata.name) {\n throw new InputError(\n `Group syncing failed: missing '${map.name}' attribute, consider applying a group filter to skip processing groups with incomplete data.`,\n );\n }\n\n mapStringAttr(entry, vendor, map.description, v => {\n entity.metadata.description = v;\n });\n mapStringAttr(entry, vendor, map.rdn, v => {\n entity.metadata.annotations![LDAP_RDN_ANNOTATION] = v;\n });\n mapStringAttr(entry, vendor, vendor.uuidAttributeName, v => {\n entity.metadata.annotations![LDAP_UUID_ANNOTATION] = v;\n });\n mapStringAttr(entry, vendor, vendor.dnAttributeName, v => {\n entity.metadata.annotations![LDAP_DN_ANNOTATION] = v;\n });\n mapStringAttr(entry, vendor, map.type, v => {\n entity.spec.type = v;\n });\n mapStringAttr(entry, vendor, map.displayName, v => {\n entity.spec.profile!.displayName = v;\n });\n mapStringAttr(entry, vendor, map.email, v => {\n entity.spec.profile!.email = v;\n });\n mapStringAttr(entry, vendor, map.picture, v => {\n entity.spec.profile!.picture = v;\n });\n\n return entity;\n}\n\n/**\n * Reads groups out of an LDAP provider.\n *\n * @param client - The LDAP client\n * @param config - The group data configuration\n * @param opts - Additional options\n */\nexport async function readLdapGroups(\n client: LdapClient,\n groupConfig: GroupConfig[],\n vendorConfig: VendorConfig | undefined,\n opts?: {\n transformer?: GroupTransformer;\n },\n): Promise<{\n groups: GroupEntity[]; // With all relations empty\n groupMemberOf: Map<string, Set<string>>; // DN -> DN or UUID of groups\n groupMember: Map<string, Set<string>>; // DN -> DN or UUID of groups & users\n}> {\n if (groupConfig.length === 0) {\n return { groups: [], groupMemberOf: new Map(), groupMember: new Map() };\n }\n const groups: GroupEntity[] = [];\n const groupMemberOf: Map<string, Set<string>> = new Map();\n const groupMember: Map<string, Set<string>> = new Map();\n\n const vendorDefaults = await client.getVendor();\n const vendor: LdapVendor = {\n dnAttributeName:\n vendorConfig?.dnAttributeName ?? vendorDefaults.dnAttributeName,\n uuidAttributeName:\n vendorConfig?.uuidAttributeName ?? vendorDefaults.uuidAttributeName,\n decodeStringAttribute: vendorDefaults.decodeStringAttribute,\n };\n\n const transformer = opts?.transformer ?? defaultGroupTransformer;\n\n for (const cfg of groupConfig) {\n const { dn, map, options } = cfg;\n const searchResult = await client.search(dn, options);\n for (const entry of searchResult.searchEntries) {\n const entity = await transformer(vendor, cfg, entry);\n\n if (!entity) {\n continue;\n }\n\n mapReferencesAttr(entry, vendor, map.memberOf, (myDn, vs) => {\n ensureItems(groupMemberOf, myDn, vs);\n });\n\n mapReferencesAttr(entry, vendor, map.members, (myDn, vs) => {\n ensureItems(groupMember, myDn, vs);\n });\n\n groups.push(entity);\n }\n }\n\n return {\n groups,\n groupMemberOf,\n groupMember,\n };\n}\n\n/**\n * Reads users and groups out of an LDAP provider.\n *\n * @param client - The LDAP client\n * @param userConfig - The user data configuration\n * @param groupConfig - The group data configuration\n * @param options - Additional options\n *\n * @public\n */\nexport async function readLdapOrg(\n client: LdapClient,\n userConfig: UserConfig[],\n groupConfig: GroupConfig[],\n vendorConfig: VendorConfig | undefined,\n options: {\n groupTransformer?: GroupTransformer;\n userTransformer?: UserTransformer;\n logger: LoggerService;\n },\n): Promise<{\n users: UserEntity[];\n groups: GroupEntity[];\n}> {\n // Invokes the above \"raw\" read functions and stitches together the results\n // with all relations etc filled in.\n\n const { users, userMemberOf } = await readLdapUsers(\n client,\n userConfig,\n vendorConfig,\n {\n transformer: options?.userTransformer,\n },\n );\n const { groups, groupMemberOf, groupMember } = await readLdapGroups(\n client,\n groupConfig,\n vendorConfig,\n { transformer: options?.groupTransformer },\n );\n\n resolveRelations(groups, users, userMemberOf, groupMemberOf, groupMember);\n users.sort((a, b) => a.metadata.name.localeCompare(b.metadata.name));\n groups.sort((a, b) => a.metadata.name.localeCompare(b.metadata.name));\n\n return { users, groups };\n}\n\n//\n// Helpers\n//\n\n// Maps a multi-valued attribute of references to other objects, to a consumer\nfunction mapReferencesAttr(\n entry: Entry,\n vendor: LdapVendor,\n attributeName: string | undefined | null,\n setter: (sourceDn: string, targets: string[]) => void,\n) {\n if (attributeName) {\n const values = vendor.decodeStringAttribute(entry, attributeName);\n const dn = vendor.decodeStringAttribute(entry, vendor.dnAttributeName);\n if (values && dn && dn.length === 1) {\n setter(dn[0], values);\n }\n }\n}\n\n// Inserts a number of values in a key-values mapping\nfunction ensureItems(\n target: Map<string, Set<string>>,\n key: string,\n values: string[],\n) {\n if (key) {\n let set = target.get(key);\n if (!set) {\n set = new Set();\n target.set(key, set);\n }\n for (const value of values) {\n if (value) {\n set!.add(value);\n }\n }\n }\n}\n\n/**\n * Helper function which dual searches the user/group maps first for original value, then for lowercased value.\n * @param map - The map of DN's user or group as the key usually multicased.\n * @param searchValue - The DN/memberOf search criteria which could potentially not match the map DN by case.\n * @returns The value/result of the search criteria dual searching.\n */\nfunction getValueFromMapWithInsensitiveKey(\n map: Map<string, any>,\n searchValue: string,\n) {\n const result = map.get(searchValue);\n return result ? result : map.get(searchValue.toLocaleLowerCase('en-US'));\n}\n\n/**\n * Takes groups and entities with empty relations, and fills in the various\n * relations that were returned by the readers, and forms the org hierarchy.\n *\n * @param groups - Group entities with empty relations; modified in place\n * @param users - User entities with empty relations; modified in place\n * @param userMemberOf - For a user DN, the set of group DNs or UUIDs that the\n * user is a member of\n * @param groupMemberOf - For a group DN, the set of group DNs or UUIDs that\n * the group is a member of (parents in the hierarchy)\n * @param groupMember - For a group DN, the set of group DNs or UUIDs that are\n * members of the group (children in the hierarchy)\n */\nexport function resolveRelations(\n groups: GroupEntity[],\n users: UserEntity[],\n userMemberOf: Map<string, Set<string>>,\n groupMemberOf: Map<string, Set<string>>,\n groupMember: Map<string, Set<string>>,\n) {\n // Build reference lookup tables - all of the relations that are output from\n // the above calls can be expressed as either DNs or UUIDs so we need to be\n // able to find by both, as well as the entity reference. Note that we expect them to not\n // collide here - this is a reasonable assumption as long as the fields are\n // the supported forms.\n const userMap: Map<string, UserEntity> = new Map(); // by entityRef, dn, uuid\n const groupMap: Map<string, GroupEntity> = new Map(); // by entityRef, dn, uuid\n for (const user of users) {\n userMap.set(stringifyEntityRef(user), user);\n userMap.set(user.metadata.annotations![LDAP_DN_ANNOTATION], user);\n userMap.set(\n user.metadata.annotations![LDAP_DN_ANNOTATION]?.toLocaleLowerCase(\n 'en-US',\n ),\n user,\n );\n userMap.set(user.metadata.annotations![LDAP_RDN_ANNOTATION], user);\n userMap.set(user.metadata.annotations![LDAP_UUID_ANNOTATION], user);\n }\n for (const group of groups) {\n groupMap.set(stringifyEntityRef(group), group);\n groupMap.set(group.metadata.annotations![LDAP_DN_ANNOTATION], group);\n groupMap.set(\n group.metadata.annotations![LDAP_DN_ANNOTATION]?.toLocaleLowerCase(\n 'en-US',\n ),\n group,\n );\n groupMap.set(group.metadata.annotations![LDAP_RDN_ANNOTATION], group);\n groupMap.set(group.metadata.annotations![LDAP_UUID_ANNOTATION], group);\n }\n\n // This can happen e.g. if entryUUID wasn't returned by the server\n userMap.delete('');\n groupMap.delete('');\n userMap.delete(undefined!);\n groupMap.delete(undefined!);\n\n // Fill in all of the immediate relations, now keyed on the entity reference. We\n // keep all parents at this point, whether the target model can support more\n // than one or not (it gets filtered farther down). And group children are\n // only groups in here.\n const newUserMemberOf: Map<string, Set<string>> = new Map();\n const newGroupParents: Map<string, Set<string>> = new Map();\n const newGroupChildren: Map<string, Set<string>> = new Map();\n\n // Resolve and store in the intermediaries. It may seem redundant that the\n // input data has both parent and children directions, as well as both\n // user->group and group->user - the reason is that different LDAP schemas\n // express relations in different directions. Some may have a user memberOf\n // overlay, some don't, for example.\n for (const [userN, groupsN] of userMemberOf.entries()) {\n const user = getValueFromMapWithInsensitiveKey(userMap, userN);\n if (user) {\n for (const groupN of groupsN) {\n const group = getValueFromMapWithInsensitiveKey(groupMap, groupN);\n if (group) {\n ensureItems(newUserMemberOf, stringifyEntityRef(user), [\n stringifyEntityRef(group),\n ]);\n }\n }\n }\n }\n for (const [groupN, parentsN] of groupMemberOf.entries()) {\n const group = getValueFromMapWithInsensitiveKey(groupMap, groupN);\n if (group) {\n for (const parentN of parentsN) {\n const parentGroup = getValueFromMapWithInsensitiveKey(\n groupMap,\n parentN,\n );\n if (parentGroup) {\n ensureItems(newGroupParents, stringifyEntityRef(group), [\n stringifyEntityRef(parentGroup),\n ]);\n ensureItems(newGroupChildren, stringifyEntityRef(parentGroup), [\n stringifyEntityRef(group),\n ]);\n }\n }\n }\n }\n for (const [groupN, membersN] of groupMember.entries()) {\n const group = getValueFromMapWithInsensitiveKey(groupMap, groupN);\n if (group) {\n for (const memberN of membersN) {\n // Group members can be both users and groups in the input model, so\n // try both\n const memberUser = getValueFromMapWithInsensitiveKey(userMap, memberN);\n if (memberUser) {\n ensureItems(newUserMemberOf, stringifyEntityRef(memberUser), [\n stringifyEntityRef(group),\n ]);\n } else {\n const memberGroup = getValueFromMapWithInsensitiveKey(\n groupMap,\n memberN,\n );\n if (memberGroup) {\n ensureItems(newGroupChildren, stringifyEntityRef(group), [\n stringifyEntityRef(memberGroup),\n ]);\n ensureItems(newGroupParents, stringifyEntityRef(memberGroup), [\n stringifyEntityRef(group),\n ]);\n }\n }\n }\n }\n }\n\n // Write down the relations again into the actual entities\n for (const [userN, groupsN] of newUserMemberOf.entries()) {\n const user = getValueFromMapWithInsensitiveKey(userMap, userN);\n if (user) {\n user.spec.memberOf = Array.from(groupsN).sort();\n }\n }\n for (const [groupN, parentsN] of newGroupParents.entries()) {\n if (parentsN.size === 1) {\n const group = getValueFromMapWithInsensitiveKey(groupMap, groupN);\n if (group) {\n group.spec.parent = parentsN.values().next().value;\n }\n }\n }\n for (const [groupN, childrenN] of newGroupChildren.entries()) {\n const group = getValueFromMapWithInsensitiveKey(groupMap, groupN);\n if (group) {\n group.spec.children = Array.from(childrenN).sort();\n }\n }\n\n // Fill out the rest of the hierarchy\n buildOrgHierarchy(groups);\n}\n"],"names":["lodashSet","cloneDeep","mapStringAttr","InputError","LDAP_RDN_ANNOTATION","LDAP_UUID_ANNOTATION","LDAP_DN_ANNOTATION","stringifyEntityRef","buildOrgHierarchy"],"mappings":"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"}
1
+ {"version":3,"file":"read.cjs.js","sources":["../../src/ldap/read.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n GroupEntity,\n stringifyEntityRef,\n UserEntity,\n} from '@backstage/catalog-model';\nimport { Entry } from 'ldapts';\nimport lodashSet from 'lodash/set';\nimport cloneDeep from 'lodash/cloneDeep';\nimport { buildOrgHierarchy } from './org';\nimport { LdapClient } from './client';\nimport { GroupConfig, UserConfig, VendorConfig } from './config';\nimport {\n LDAP_DN_ANNOTATION,\n LDAP_RDN_ANNOTATION,\n LDAP_UUID_ANNOTATION,\n} from './constants';\nimport { LdapVendor } from './vendors';\nimport { GroupTransformer, UserTransformer } from './types';\nimport { mapStringAttr } from './util';\nimport { LoggerService } from '@backstage/backend-plugin-api';\nimport { InputError } from '@backstage/errors';\n\n/**\n * The default implementation of the transformation from an LDAP entry to a\n * User entity.\n *\n * @public\n */\nexport async function defaultUserTransformer(\n vendor: LdapVendor,\n config: UserConfig,\n entry: Entry,\n): Promise<UserEntity | undefined> {\n const { set, map } = config;\n\n const entity: UserEntity = {\n apiVersion: 'backstage.io/v1beta1',\n kind: 'User',\n metadata: {\n name: '',\n annotations: {},\n },\n spec: {\n profile: {},\n memberOf: [],\n },\n };\n\n if (set) {\n for (const [path, value] of Object.entries(set)) {\n lodashSet(entity, path, cloneDeep(value));\n }\n }\n\n mapStringAttr(entry, vendor, map.name, v => {\n entity.metadata.name = v;\n });\n\n if (!entity.metadata.name) {\n throw new InputError(\n `User syncing failed: missing '${map.name}' attribute, consider applying a user filter to skip processing users with incomplete data.`,\n );\n }\n\n mapStringAttr(entry, vendor, map.description, v => {\n entity.metadata.description = v;\n });\n mapStringAttr(entry, vendor, map.rdn, v => {\n entity.metadata.annotations![LDAP_RDN_ANNOTATION] = v;\n });\n mapStringAttr(entry, vendor, vendor.uuidAttributeName, v => {\n entity.metadata.annotations![LDAP_UUID_ANNOTATION] = v;\n });\n mapStringAttr(entry, vendor, vendor.dnAttributeName, v => {\n entity.metadata.annotations![LDAP_DN_ANNOTATION] = v;\n });\n mapStringAttr(entry, vendor, map.displayName, v => {\n entity.spec.profile!.displayName = v;\n });\n mapStringAttr(entry, vendor, map.email, v => {\n entity.spec.profile!.email = v;\n });\n mapStringAttr(entry, vendor, map.picture, v => {\n entity.spec.profile!.picture = v;\n });\n\n return entity;\n}\n\n/**\n * Reads users out of an LDAP provider.\n *\n * @param client - The LDAP client\n * @param config - The user data configuration\n * @param opts - Additional options\n */\nexport async function readLdapUsers(\n client: LdapClient,\n userConfig: UserConfig[],\n vendorConfig: VendorConfig | undefined,\n opts?: { transformer?: UserTransformer },\n): Promise<{\n users: UserEntity[]; // With all relations empty\n userMemberOf: Map<string, Set<string>>; // DN -> DN or UUID of groups\n}> {\n if (userConfig.length === 0) {\n return { users: [], userMemberOf: new Map() };\n }\n const entities: UserEntity[] = [];\n const userMemberOf: Map<string, Set<string>> = new Map();\n const vendorDefaults = await client.getVendor();\n const vendor: LdapVendor = {\n dnAttributeName:\n vendorConfig?.dnAttributeName ?? vendorDefaults.dnAttributeName,\n uuidAttributeName:\n vendorConfig?.uuidAttributeName ?? vendorDefaults.uuidAttributeName,\n decodeStringAttribute: vendorDefaults.decodeStringAttribute,\n };\n const transformer = opts?.transformer ?? defaultUserTransformer;\n\n for (const cfg of userConfig) {\n const { dn, options, map } = cfg;\n const searchResult = await client.search(dn, options);\n for (const entry of searchResult.searchEntries) {\n const entity = await transformer(vendor, cfg, entry);\n\n if (!entity) {\n continue;\n }\n\n mapReferencesAttr(entry, vendor, map.memberOf, (myDn, vs) => {\n ensureItems(userMemberOf, myDn, vs);\n });\n\n entities.push(entity);\n }\n }\n\n return { users: entities, userMemberOf };\n}\n\n/**\n * The default implementation of the transformation from an LDAP entry to a\n * Group entity.\n *\n * @public\n */\nexport async function defaultGroupTransformer(\n vendor: LdapVendor,\n config: GroupConfig,\n entry: Entry,\n): Promise<GroupEntity | undefined> {\n const { set, map } = config;\n const entity: GroupEntity = {\n apiVersion: 'backstage.io/v1beta1',\n kind: 'Group',\n metadata: {\n name: '',\n annotations: {},\n },\n spec: {\n type: 'unknown',\n profile: {},\n children: [],\n },\n };\n\n if (set) {\n for (const [path, value] of Object.entries(set)) {\n lodashSet(entity, path, cloneDeep(value));\n }\n }\n\n mapStringAttr(entry, vendor, map.name, v => {\n entity.metadata.name = v;\n });\n\n if (!entity.metadata.name) {\n throw new InputError(\n `Group syncing failed: missing '${map.name}' attribute, consider applying a group filter to skip processing groups with incomplete data.`,\n );\n }\n\n mapStringAttr(entry, vendor, map.description, v => {\n entity.metadata.description = v;\n });\n mapStringAttr(entry, vendor, map.rdn, v => {\n entity.metadata.annotations![LDAP_RDN_ANNOTATION] = v;\n });\n mapStringAttr(entry, vendor, vendor.uuidAttributeName, v => {\n entity.metadata.annotations![LDAP_UUID_ANNOTATION] = v;\n });\n mapStringAttr(entry, vendor, vendor.dnAttributeName, v => {\n entity.metadata.annotations![LDAP_DN_ANNOTATION] = v;\n });\n mapStringAttr(entry, vendor, map.type, v => {\n entity.spec.type = v;\n });\n mapStringAttr(entry, vendor, map.displayName, v => {\n entity.spec.profile!.displayName = v;\n });\n mapStringAttr(entry, vendor, map.email, v => {\n entity.spec.profile!.email = v;\n });\n mapStringAttr(entry, vendor, map.picture, v => {\n entity.spec.profile!.picture = v;\n });\n\n return entity;\n}\n\n/**\n * Reads groups out of an LDAP provider.\n *\n * @param client - The LDAP client\n * @param config - The group data configuration\n * @param opts - Additional options\n */\nexport async function readLdapGroups(\n client: LdapClient,\n groupConfig: GroupConfig[],\n vendorConfig: VendorConfig | undefined,\n opts?: {\n transformer?: GroupTransformer;\n },\n): Promise<{\n groups: GroupEntity[]; // With all relations empty\n groupMemberOf: Map<string, Set<string>>; // DN -> DN or UUID of groups\n groupMember: Map<string, Set<string>>; // DN -> DN or UUID of groups & users\n}> {\n if (groupConfig.length === 0) {\n return { groups: [], groupMemberOf: new Map(), groupMember: new Map() };\n }\n const groups: GroupEntity[] = [];\n const groupMemberOf: Map<string, Set<string>> = new Map();\n const groupMember: Map<string, Set<string>> = new Map();\n\n const vendorDefaults = await client.getVendor();\n const vendor: LdapVendor = {\n dnAttributeName:\n vendorConfig?.dnAttributeName ?? vendorDefaults.dnAttributeName,\n uuidAttributeName:\n vendorConfig?.uuidAttributeName ?? vendorDefaults.uuidAttributeName,\n decodeStringAttribute: vendorDefaults.decodeStringAttribute,\n };\n\n const transformer = opts?.transformer ?? defaultGroupTransformer;\n\n for (const cfg of groupConfig) {\n const { dn, map, options } = cfg;\n const searchResult = await client.search(dn, options);\n for (const entry of searchResult.searchEntries) {\n const entity = await transformer(vendor, cfg, entry);\n\n if (!entity) {\n continue;\n }\n\n mapReferencesAttr(entry, vendor, map.memberOf, (myDn, vs) => {\n ensureItems(groupMemberOf, myDn, vs);\n });\n\n mapReferencesAttr(entry, vendor, map.members, (myDn, vs) => {\n ensureItems(groupMember, myDn, vs);\n });\n\n groups.push(entity);\n }\n }\n\n return {\n groups,\n groupMemberOf,\n groupMember,\n };\n}\n\n/**\n * Reads users and groups out of an LDAP provider.\n *\n * @param client - The LDAP client\n * @param userConfig - The user data configuration\n * @param groupConfig - The group data configuration\n * @param options - Additional options\n *\n * @public\n */\nexport async function readLdapOrg(\n client: LdapClient,\n userConfig: UserConfig[],\n groupConfig: GroupConfig[],\n vendorConfig: VendorConfig | undefined,\n options: {\n groupTransformer?: GroupTransformer;\n userTransformer?: UserTransformer;\n logger: LoggerService;\n },\n): Promise<{\n users: UserEntity[];\n groups: GroupEntity[];\n}> {\n // Invokes the above \"raw\" read functions and stitches together the results\n // with all relations etc filled in.\n\n const { users, userMemberOf } = await readLdapUsers(\n client,\n userConfig,\n vendorConfig,\n {\n transformer: options?.userTransformer,\n },\n );\n const { groups, groupMemberOf, groupMember } = await readLdapGroups(\n client,\n groupConfig,\n vendorConfig,\n { transformer: options?.groupTransformer },\n );\n\n resolveRelations(groups, users, userMemberOf, groupMemberOf, groupMember);\n users.sort((a, b) => a.metadata.name.localeCompare(b.metadata.name));\n groups.sort((a, b) => a.metadata.name.localeCompare(b.metadata.name));\n\n return { users, groups };\n}\n\n//\n// Helpers\n//\n\n// Maps a multi-valued attribute of references to other objects, to a consumer\nfunction mapReferencesAttr(\n entry: Entry,\n vendor: LdapVendor,\n attributeName: string | undefined | null,\n setter: (sourceDn: string, targets: string[]) => void,\n) {\n if (attributeName) {\n const values = vendor.decodeStringAttribute(entry, attributeName);\n const dn = vendor.decodeStringAttribute(entry, vendor.dnAttributeName);\n if (values && dn && dn.length === 1) {\n setter(dn[0], values);\n }\n }\n}\n\n// Inserts a number of values in a key-values mapping\nfunction ensureItems(\n target: Map<string, Set<string>>,\n key: string,\n values: string[],\n) {\n if (key) {\n let set = target.get(key);\n if (!set) {\n set = new Set();\n target.set(key, set);\n }\n for (const value of values) {\n if (value) {\n set!.add(value);\n }\n }\n }\n}\n\n/**\n * Helper function which dual searches the user/group maps first for original value, then for lowercased value.\n * @param map - The map of DN's user or group as the key usually multicased.\n * @param searchValue - The DN/memberOf search criteria which could potentially not match the map DN by case.\n * @returns The value/result of the search criteria dual searching.\n */\nfunction getValueFromMapWithInsensitiveKey(\n map: Map<string, any>,\n searchValue: string,\n) {\n const result = map.get(searchValue);\n return result ? result : map.get(searchValue.toLowerCase());\n}\n\n/**\n * Takes groups and entities with empty relations, and fills in the various\n * relations that were returned by the readers, and forms the org hierarchy.\n *\n * @param groups - Group entities with empty relations; modified in place\n * @param users - User entities with empty relations; modified in place\n * @param userMemberOf - For a user DN, the set of group DNs or UUIDs that the\n * user is a member of\n * @param groupMemberOf - For a group DN, the set of group DNs or UUIDs that\n * the group is a member of (parents in the hierarchy)\n * @param groupMember - For a group DN, the set of group DNs or UUIDs that are\n * members of the group (children in the hierarchy)\n */\nexport function resolveRelations(\n groups: GroupEntity[],\n users: UserEntity[],\n userMemberOf: Map<string, Set<string>>,\n groupMemberOf: Map<string, Set<string>>,\n groupMember: Map<string, Set<string>>,\n) {\n // Build reference lookup tables - all of the relations that are output from\n // the above calls can be expressed as either DNs or UUIDs so we need to be\n // able to find by both, as well as the entity reference. Note that we expect them to not\n // collide here - this is a reasonable assumption as long as the fields are\n // the supported forms.\n const userMap: Map<string, UserEntity> = new Map(); // by entityRef, dn, uuid\n const groupMap: Map<string, GroupEntity> = new Map(); // by entityRef, dn, uuid\n for (const user of users) {\n userMap.set(stringifyEntityRef(user), user);\n userMap.set(user.metadata.annotations![LDAP_DN_ANNOTATION], user);\n userMap.set(\n user.metadata.annotations![LDAP_DN_ANNOTATION]?.toLowerCase(),\n user,\n );\n userMap.set(user.metadata.annotations![LDAP_RDN_ANNOTATION], user);\n userMap.set(user.metadata.annotations![LDAP_UUID_ANNOTATION], user);\n }\n for (const group of groups) {\n groupMap.set(stringifyEntityRef(group), group);\n groupMap.set(group.metadata.annotations![LDAP_DN_ANNOTATION], group);\n groupMap.set(\n group.metadata.annotations![LDAP_DN_ANNOTATION]?.toLowerCase(),\n group,\n );\n groupMap.set(group.metadata.annotations![LDAP_RDN_ANNOTATION], group);\n groupMap.set(group.metadata.annotations![LDAP_UUID_ANNOTATION], group);\n }\n\n // This can happen e.g. if entryUUID wasn't returned by the server\n userMap.delete('');\n groupMap.delete('');\n userMap.delete(undefined!);\n groupMap.delete(undefined!);\n\n // Fill in all of the immediate relations, now keyed on the entity reference. We\n // keep all parents at this point, whether the target model can support more\n // than one or not (it gets filtered farther down). And group children are\n // only groups in here.\n const newUserMemberOf: Map<string, Set<string>> = new Map();\n const newGroupParents: Map<string, Set<string>> = new Map();\n const newGroupChildren: Map<string, Set<string>> = new Map();\n\n // Resolve and store in the intermediaries. It may seem redundant that the\n // input data has both parent and children directions, as well as both\n // user->group and group->user - the reason is that different LDAP schemas\n // express relations in different directions. Some may have a user memberOf\n // overlay, some don't, for example.\n for (const [userN, groupsN] of userMemberOf.entries()) {\n const user = getValueFromMapWithInsensitiveKey(userMap, userN);\n if (user) {\n for (const groupN of groupsN) {\n const group = getValueFromMapWithInsensitiveKey(groupMap, groupN);\n if (group) {\n ensureItems(newUserMemberOf, stringifyEntityRef(user), [\n stringifyEntityRef(group),\n ]);\n }\n }\n }\n }\n for (const [groupN, parentsN] of groupMemberOf.entries()) {\n const group = getValueFromMapWithInsensitiveKey(groupMap, groupN);\n if (group) {\n for (const parentN of parentsN) {\n const parentGroup = getValueFromMapWithInsensitiveKey(\n groupMap,\n parentN,\n );\n if (parentGroup) {\n ensureItems(newGroupParents, stringifyEntityRef(group), [\n stringifyEntityRef(parentGroup),\n ]);\n ensureItems(newGroupChildren, stringifyEntityRef(parentGroup), [\n stringifyEntityRef(group),\n ]);\n }\n }\n }\n }\n for (const [groupN, membersN] of groupMember.entries()) {\n const group = getValueFromMapWithInsensitiveKey(groupMap, groupN);\n if (group) {\n for (const memberN of membersN) {\n // Group members can be both users and groups in the input model, so\n // try both\n const memberUser = getValueFromMapWithInsensitiveKey(userMap, memberN);\n if (memberUser) {\n ensureItems(newUserMemberOf, stringifyEntityRef(memberUser), [\n stringifyEntityRef(group),\n ]);\n } else {\n const memberGroup = getValueFromMapWithInsensitiveKey(\n groupMap,\n memberN,\n );\n if (memberGroup) {\n ensureItems(newGroupChildren, stringifyEntityRef(group), [\n stringifyEntityRef(memberGroup),\n ]);\n ensureItems(newGroupParents, stringifyEntityRef(memberGroup), [\n stringifyEntityRef(group),\n ]);\n }\n }\n }\n }\n }\n\n // Write down the relations again into the actual entities\n for (const [userN, groupsN] of newUserMemberOf.entries()) {\n const user = getValueFromMapWithInsensitiveKey(userMap, userN);\n if (user) {\n user.spec.memberOf = Array.from(groupsN).sort();\n }\n }\n for (const [groupN, parentsN] of newGroupParents.entries()) {\n if (parentsN.size === 1) {\n const group = getValueFromMapWithInsensitiveKey(groupMap, groupN);\n if (group) {\n group.spec.parent = parentsN.values().next().value;\n }\n }\n }\n for (const [groupN, childrenN] of newGroupChildren.entries()) {\n const group = getValueFromMapWithInsensitiveKey(groupMap, groupN);\n if (group) {\n group.spec.children = Array.from(childrenN).sort();\n }\n }\n\n // Fill out the rest of the hierarchy\n buildOrgHierarchy(groups);\n}\n"],"names":["lodashSet","cloneDeep","mapStringAttr","InputError","LDAP_RDN_ANNOTATION","LDAP_UUID_ANNOTATION","LDAP_DN_ANNOTATION","stringifyEntityRef","buildOrgHierarchy"],"mappings":"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"}
@@ -53,7 +53,7 @@ const LLDAPVendor = {
53
53
  dnAttributeName: "dn",
54
54
  uuidAttributeName: "entryuuid",
55
55
  decodeStringAttribute: (entry, name) => {
56
- return decode(entry, name.toLocaleLowerCase("en-US"), (value) => {
56
+ return decode(entry, name.toLowerCase(), (value) => {
57
57
  return value.toString();
58
58
  });
59
59
  }
@@ -1 +1 @@
1
- {"version":3,"file":"vendors.cjs.js","sources":["../../src/ldap/vendors.ts"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Entry } from 'ldapts';\n\n/**\n * An LDAP Vendor handles unique nuances between different vendors.\n *\n * @public\n */\nexport type LdapVendor = {\n /**\n * The attribute name that holds the distinguished name (DN) for an entry.\n */\n dnAttributeName: string;\n /**\n * The attribute name that holds a universal unique identifier for an entry.\n */\n uuidAttributeName: string;\n\n /**\n * Decode ldap entry values for a given attribute name to their string representation.\n *\n * @param entry - The ldap entry\n * @param name - The attribute to decode\n */\n decodeStringAttribute: (entry: Entry, name: string) => string[];\n};\n\nexport const DefaultLdapVendor: LdapVendor = {\n dnAttributeName: 'entryDN',\n uuidAttributeName: 'entryUUID',\n decodeStringAttribute: (entry, name) => {\n return decode(entry, name, value => {\n return value.toString();\n });\n },\n};\n\nexport const ActiveDirectoryVendor: LdapVendor = {\n dnAttributeName: 'distinguishedName',\n uuidAttributeName: 'objectGUID',\n decodeStringAttribute: (entry, name) => {\n const decoder = (value: string | Buffer) => {\n if (name === ActiveDirectoryVendor.uuidAttributeName) {\n return formatGUID(value);\n }\n return value.toString();\n };\n return decode(entry, name, decoder);\n },\n};\n\nexport const FreeIpaVendor: LdapVendor = {\n dnAttributeName: 'dn',\n uuidAttributeName: 'ipaUniqueID',\n decodeStringAttribute: (entry, name) => {\n return decode(entry, name, value => {\n return value.toString();\n });\n },\n};\n\nexport const AEDirVendor: LdapVendor = {\n dnAttributeName: 'dn',\n uuidAttributeName: 'entryUUID',\n decodeStringAttribute: (entry, name) => {\n return decode(entry, name, value => {\n return value.toString();\n });\n },\n};\n\nexport const GoogleLdapVendor: LdapVendor = {\n dnAttributeName: 'dn',\n uuidAttributeName: 'uid',\n decodeStringAttribute: (entry, name) => {\n return decode(entry, name, value => {\n return value.toString();\n });\n },\n};\n\nexport const LLDAPVendor: LdapVendor = {\n dnAttributeName: 'dn',\n uuidAttributeName: 'entryuuid',\n decodeStringAttribute: (entry, name) => {\n return decode(entry, name.toLocaleLowerCase('en-US'), value => {\n return value.toString();\n });\n },\n};\n\n// Decode an attribute to a consumer\nfunction decode(\n entry: Entry,\n attributeName: string,\n decoder: (value: string | Buffer) => string,\n): string[] {\n const values = entry[attributeName];\n if (Array.isArray(values)) {\n return values.map(v => {\n return decoder(v);\n });\n } else if (values) {\n return [decoder(values)];\n }\n return [];\n}\n\n// Formats a Microsoft Active Directory binary-encoded uuid to a readable string\n// See https://github.com/ldapjs/node-ldapjs/issues/297#issuecomment-137765214\nfunction formatGUID(objectGUID: string | Buffer): string {\n let data: Buffer;\n if (typeof objectGUID === 'string') {\n data = Buffer.from(objectGUID, 'binary');\n } else {\n data = objectGUID;\n }\n // GUID_FORMAT_D\n let template = '{3}{2}{1}{0}-{5}{4}-{7}{6}-{8}{9}-{10}{11}{12}{13}{14}{15}';\n\n // check each byte\n for (let i = 0; i < data.length; i++) {\n let dataStr = data[i].toString(16);\n dataStr = data[i] >= 16 ? dataStr : `0${dataStr}`;\n\n // insert that character into the template\n template = template.replace(`{${i}}`, dataStr);\n }\n return template;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"vendors.cjs.js","sources":["../../src/ldap/vendors.ts"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Entry } from 'ldapts';\n\n/**\n * An LDAP Vendor handles unique nuances between different vendors.\n *\n * @public\n */\nexport type LdapVendor = {\n /**\n * The attribute name that holds the distinguished name (DN) for an entry.\n */\n dnAttributeName: string;\n /**\n * The attribute name that holds a universal unique identifier for an entry.\n */\n uuidAttributeName: string;\n\n /**\n * Decode ldap entry values for a given attribute name to their string representation.\n *\n * @param entry - The ldap entry\n * @param name - The attribute to decode\n */\n decodeStringAttribute: (entry: Entry, name: string) => string[];\n};\n\nexport const DefaultLdapVendor: LdapVendor = {\n dnAttributeName: 'entryDN',\n uuidAttributeName: 'entryUUID',\n decodeStringAttribute: (entry, name) => {\n return decode(entry, name, value => {\n return value.toString();\n });\n },\n};\n\nexport const ActiveDirectoryVendor: LdapVendor = {\n dnAttributeName: 'distinguishedName',\n uuidAttributeName: 'objectGUID',\n decodeStringAttribute: (entry, name) => {\n const decoder = (value: string | Buffer) => {\n if (name === ActiveDirectoryVendor.uuidAttributeName) {\n return formatGUID(value);\n }\n return value.toString();\n };\n return decode(entry, name, decoder);\n },\n};\n\nexport const FreeIpaVendor: LdapVendor = {\n dnAttributeName: 'dn',\n uuidAttributeName: 'ipaUniqueID',\n decodeStringAttribute: (entry, name) => {\n return decode(entry, name, value => {\n return value.toString();\n });\n },\n};\n\nexport const AEDirVendor: LdapVendor = {\n dnAttributeName: 'dn',\n uuidAttributeName: 'entryUUID',\n decodeStringAttribute: (entry, name) => {\n return decode(entry, name, value => {\n return value.toString();\n });\n },\n};\n\nexport const GoogleLdapVendor: LdapVendor = {\n dnAttributeName: 'dn',\n uuidAttributeName: 'uid',\n decodeStringAttribute: (entry, name) => {\n return decode(entry, name, value => {\n return value.toString();\n });\n },\n};\n\nexport const LLDAPVendor: LdapVendor = {\n dnAttributeName: 'dn',\n uuidAttributeName: 'entryuuid',\n decodeStringAttribute: (entry, name) => {\n return decode(entry, name.toLowerCase(), value => {\n return value.toString();\n });\n },\n};\n\n// Decode an attribute to a consumer\nfunction decode(\n entry: Entry,\n attributeName: string,\n decoder: (value: string | Buffer) => string,\n): string[] {\n const values = entry[attributeName];\n if (Array.isArray(values)) {\n return values.map(v => {\n return decoder(v);\n });\n } else if (values) {\n return [decoder(values)];\n }\n return [];\n}\n\n// Formats a Microsoft Active Directory binary-encoded uuid to a readable string\n// See https://github.com/ldapjs/node-ldapjs/issues/297#issuecomment-137765214\nfunction formatGUID(objectGUID: string | Buffer): string {\n let data: Buffer;\n if (typeof objectGUID === 'string') {\n data = Buffer.from(objectGUID, 'binary');\n } else {\n data = objectGUID;\n }\n // GUID_FORMAT_D\n let template = '{3}{2}{1}{0}-{5}{4}-{7}{6}-{8}{9}-{10}{11}{12}{13}{14}{15}';\n\n // check each byte\n for (let i = 0; i < data.length; i++) {\n let dataStr = data[i].toString(16);\n dataStr = data[i] >= 16 ? dataStr : `0${dataStr}`;\n\n // insert that character into the template\n template = template.replace(`{${i}}`, dataStr);\n }\n return template;\n}\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/plugin-catalog-backend-module-ldap",
3
- "version": "0.12.9-next.1",
3
+ "version": "0.12.9",
4
4
  "description": "A Backstage catalog backend module that helps integrate towards LDAP",
5
5
  "backstage": {
6
6
  "role": "backend-plugin-module",
@@ -41,18 +41,18 @@
41
41
  "test": "backstage-cli package test"
42
42
  },
43
43
  "dependencies": {
44
- "@backstage/backend-plugin-api": "1.10.1-next.1",
45
- "@backstage/catalog-model": "1.10.0",
46
- "@backstage/config": "1.3.9-next.0",
47
- "@backstage/errors": "1.3.1",
48
- "@backstage/plugin-catalog-common": "1.2.0-next.0",
49
- "@backstage/plugin-catalog-node": "2.2.5-next.1",
50
- "@backstage/types": "1.2.2",
44
+ "@backstage/backend-plugin-api": "^1.10.1",
45
+ "@backstage/catalog-model": "^1.10.1",
46
+ "@backstage/config": "^1.3.9",
47
+ "@backstage/errors": "^1.3.1",
48
+ "@backstage/plugin-catalog-common": "^1.2.0",
49
+ "@backstage/plugin-catalog-node": "^2.2.5",
50
+ "@backstage/types": "^1.2.2",
51
51
  "ldapts": "^8.0.6",
52
52
  "lodash": "^4.17.21"
53
53
  },
54
54
  "devDependencies": {
55
- "@backstage/cli": "0.36.6-next.1",
55
+ "@backstage/cli": "^0.36.6",
56
56
  "@types/lodash": "^4.14.151"
57
57
  },
58
58
  "configSchema": "config.schema.json",