@manyos/smileconnect-api 1.74.2 → 1.74.3

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.
@@ -9,7 +9,8 @@
9
9
  "WebFetch(domain:unpkg.com)",
10
10
  "WebFetch(domain:www.npmjs.com)",
11
11
  "Bash(node *)",
12
- "Bash(grep -E '^\\(p-queue|proper-lockfile|async-mutex|p-limit\\)$')"
12
+ "Bash(grep -E '^\\(p-queue|proper-lockfile|async-mutex|p-limit\\)$')",
13
+ "Bash(awk NR>=160 && NR<=165 {printf \"%d: \", NR; for \\(i=1;i<=length\\($0\\);i++\\) {c=substr\\($0,i,1\\); printf \"%s\", c} printf \"\\\\n\"} *)"
13
14
  ]
14
15
  }
15
16
  }
package/docs/releases.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # Release Notes
2
2
 
3
3
  ## API
4
- ### 1.74.2 - 20.05.26
4
+ ### 1.74.3 - 20.05.26
5
5
  Improve client config validation to avoid duplicate client configs.
6
6
 
7
7
  ### 1.74.1 - 12.05.26
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@manyos/smileconnect-api",
3
- "version": "1.74.2",
3
+ "version": "1.74.3",
4
4
  "description": "A proxy and abstraction layer for BMCs IT Service Management Suite",
5
5
  "main": "app.js",
6
6
  "scripts": {
@@ -295,7 +295,7 @@ module.exports = (function() {
295
295
  });
296
296
 
297
297
  routes.delete('/clients/:id', isAuthorizedAdmin,
298
- function (req, res, next) {
298
+ async function (req, res, next) {
299
299
  const id = req.params.id;
300
300
  setEventData(
301
301
  req,
@@ -305,7 +305,11 @@ module.exports = (function() {
305
305
  id
306
306
  );
307
307
  try {
308
- config.deleteClient(id);
308
+ const removed = await config.deleteClient(id);
309
+ if (!removed) {
310
+ req.errorStatus = 404;
311
+ return next(new Error(`client '${id}' not found`));
312
+ }
309
313
  req.result = {
310
314
  "status": "success"
311
315
  };
package/util/config.js CHANGED
@@ -132,6 +132,8 @@ async function setClient(clientName, clientConfig) {
132
132
  if (!clientConfig || typeof clientConfig !== 'object' || !clientConfig.name) {
133
133
  throw new Error('setClient: clientConfig.name is required');
134
134
  }
135
+ const normalizedParam = typeof clientName === 'string' ? clientName.trim() : clientName;
136
+ clientConfig.name = clientConfig.name.trim();
135
137
  return clientConfigWriteLimit(async () => {
136
138
  let config;
137
139
  try {
@@ -142,8 +144,8 @@ async function setClient(clientName, clientConfig) {
142
144
  config = [];
143
145
  }
144
146
  if (!Array.isArray(config)) config = [];
145
- const namesToRemove = new Set([clientName, clientConfig.name].filter(Boolean));
146
- config = config.filter(obj => obj && !namesToRemove.has(obj.name));
147
+ const namesToRemove = new Set([normalizedParam, clientConfig.name].filter(Boolean));
148
+ config = config.filter(obj => obj && !namesToRemove.has(obj.name && obj.name.trim ? obj.name.trim() : obj.name));
147
149
  config.push(clientConfig);
148
150
  log.debug('new config size', config.length);
149
151
  const tmp = `${clientConfigFile}.tmp.${process.pid}.${crypto.randomBytes(4).toString('hex')}`;
@@ -153,16 +155,37 @@ async function setClient(clientName, clientConfig) {
153
155
  });
154
156
  }
155
157
 
156
- function deleteClient(clientName) {
158
+ async function deleteClient(clientName) {
157
159
  log.debug('start to update config in file', clientConfigFile);
158
160
  log.debug('delete client data', clientName);
159
- let config = JSON.parse(fs.readFileSync(clientConfigFile)) || {};
160
- config = config.filter(function( obj ) {
161
- return obj.name !== clientName;
161
+ const normalizedName = typeof clientName === 'string' ? clientName.trim() : clientName;
162
+ return clientConfigWriteLimit(async () => {
163
+ let config;
164
+ try {
165
+ const raw = await fsPromises.readFile(clientConfigFile, 'utf8');
166
+ config = JSON.parse(raw);
167
+ } catch (e) {
168
+ log.warn('deleteClient: cannot parse existing clients.json, nothing to delete', e.message);
169
+ return false;
170
+ }
171
+ if (!Array.isArray(config)) return false;
172
+ const before = config.length;
173
+ config = config.filter(obj => {
174
+ if (!obj || !obj.name) return true;
175
+ const objName = typeof obj.name === 'string' ? obj.name.trim() : obj.name;
176
+ return objName !== normalizedName;
177
+ });
178
+ const removed = before - config.length;
179
+ if (removed === 0) {
180
+ log.warn('deleteClient: no entry matched', clientName);
181
+ return false;
182
+ }
183
+ const tmp = `${clientConfigFile}.tmp.${process.pid}.${crypto.randomBytes(4).toString('hex')}`;
184
+ await fsPromises.writeFile(tmp, JSON.stringify(config, null, 2));
185
+ await fsPromises.rename(tmp, clientConfigFile);
186
+ log.debug('deleteClient: removed', removed, 'entries for', normalizedName);
187
+ return true;
162
188
  });
163
- log.debug('new config', config);
164
- fs.writeFileSync(clientConfigFile, JSON.stringify(config, null, 2));
165
- return true
166
189
  }
167
190
 
168
191
  function getConstants(objectType) {