wingbot-mongodb 3.2.4 → 3.2.5-test.1

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.
@@ -0,0 +1 @@
1
+ {"parent":null,"pid":26311,"argv":["/usr/local/bin/node","/Users/david/Development/wingbot-mongodb/node_modules/.bin/mocha","./test"],"execArgv":[],"cwd":"/Users/david/Development/wingbot-mongodb","time":1681982211291,"ppid":26310,"coverageFilename":"/Users/david/Development/wingbot-mongodb/.nyc_output/fb200475-7184-4caf-a314-c2fe4216d1dc.json","externalId":"","uuid":"fb200475-7184-4caf-a314-c2fe4216d1dc","files":["/Users/david/Development/wingbot-mongodb/src/BaseStorage.js","/Users/david/Development/wingbot-mongodb/src/defaultLogger.js","/Users/david/Development/wingbot-mongodb/src/AttachmentCache.js","/Users/david/Development/wingbot-mongodb/src/AuditLogStorage.js","/Users/david/Development/wingbot-mongodb/src/BotConfigStorage.js","/Users/david/Development/wingbot-mongodb/src/BotTokenStorage.js","/Users/david/Development/wingbot-mongodb/src/tokenFactory.js","/Users/david/Development/wingbot-mongodb/src/ChatLogStorage.js","/Users/david/Development/wingbot-mongodb/src/NotificationsStorage.js","/Users/david/Development/wingbot-mongodb/src/StateStorage.js"]}
@@ -1 +1 @@
1
- {"processes":{"8db620e2-5deb-4db5-b239-32d4e6eb824a":{"parent":null,"children":[]}},"files":{"/Users/david/Development/wingbot-mongodb/src/BaseStorage.js":["8db620e2-5deb-4db5-b239-32d4e6eb824a"],"/Users/david/Development/wingbot-mongodb/src/defaultLogger.js":["8db620e2-5deb-4db5-b239-32d4e6eb824a"],"/Users/david/Development/wingbot-mongodb/src/AttachmentCache.js":["8db620e2-5deb-4db5-b239-32d4e6eb824a"],"/Users/david/Development/wingbot-mongodb/src/AuditLogStorage.js":["8db620e2-5deb-4db5-b239-32d4e6eb824a"],"/Users/david/Development/wingbot-mongodb/src/BotConfigStorage.js":["8db620e2-5deb-4db5-b239-32d4e6eb824a"],"/Users/david/Development/wingbot-mongodb/src/BotTokenStorage.js":["8db620e2-5deb-4db5-b239-32d4e6eb824a"],"/Users/david/Development/wingbot-mongodb/src/tokenFactory.js":["8db620e2-5deb-4db5-b239-32d4e6eb824a"],"/Users/david/Development/wingbot-mongodb/src/ChatLogStorage.js":["8db620e2-5deb-4db5-b239-32d4e6eb824a"],"/Users/david/Development/wingbot-mongodb/src/NotificationsStorage.js":["8db620e2-5deb-4db5-b239-32d4e6eb824a"],"/Users/david/Development/wingbot-mongodb/src/StateStorage.js":["8db620e2-5deb-4db5-b239-32d4e6eb824a"]},"externalIds":{}}
1
+ {"processes":{"fb200475-7184-4caf-a314-c2fe4216d1dc":{"parent":null,"children":[]}},"files":{"/Users/david/Development/wingbot-mongodb/src/BaseStorage.js":["fb200475-7184-4caf-a314-c2fe4216d1dc"],"/Users/david/Development/wingbot-mongodb/src/defaultLogger.js":["fb200475-7184-4caf-a314-c2fe4216d1dc"],"/Users/david/Development/wingbot-mongodb/src/AttachmentCache.js":["fb200475-7184-4caf-a314-c2fe4216d1dc"],"/Users/david/Development/wingbot-mongodb/src/AuditLogStorage.js":["fb200475-7184-4caf-a314-c2fe4216d1dc"],"/Users/david/Development/wingbot-mongodb/src/BotConfigStorage.js":["fb200475-7184-4caf-a314-c2fe4216d1dc"],"/Users/david/Development/wingbot-mongodb/src/BotTokenStorage.js":["fb200475-7184-4caf-a314-c2fe4216d1dc"],"/Users/david/Development/wingbot-mongodb/src/tokenFactory.js":["fb200475-7184-4caf-a314-c2fe4216d1dc"],"/Users/david/Development/wingbot-mongodb/src/ChatLogStorage.js":["fb200475-7184-4caf-a314-c2fe4216d1dc"],"/Users/david/Development/wingbot-mongodb/src/NotificationsStorage.js":["fb200475-7184-4caf-a314-c2fe4216d1dc"],"/Users/david/Development/wingbot-mongodb/src/StateStorage.js":["fb200475-7184-4caf-a314-c2fe4216d1dc"]},"externalIds":{}}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wingbot-mongodb",
3
- "version": "3.2.4",
3
+ "version": "3.2.5-test.1",
4
4
  "description": "MongoDB storage for wingbot.ai",
5
5
  "main": "src/main.js",
6
6
  "scripts": {
@@ -9,7 +9,7 @@
9
9
  "test:unit:watch": "npm run test:unit -- --watch",
10
10
  "test:cosmos": "cross-env DB_TYPE=cosmos mocha ./test",
11
11
  "test:coverage": "nyc --reporter=html mocha ./test && nyc report",
12
- "test:coverage:threshold": "nyc check-coverage --lines 80 --functions 75 --branches 75",
12
+ "test:coverage:threshold": "nyc check-coverage --lines 80 --functions 73 --branches 75",
13
13
  "test:lint": "eslint ./src/**/*.js ./bin/**/*.js ./test/**/*.js ",
14
14
  "doc": "node ./bin/makeApiDoc.js"
15
15
  },
@@ -103,6 +103,8 @@ class BaseStorage {
103
103
 
104
104
  this._fixtures = [];
105
105
 
106
+ this._uniqueIndexFailed = false;
107
+
106
108
  if (typeof isCosmo === 'number') {
107
109
  BaseStorage.netFailuresCount = isCosmo;
108
110
  }
@@ -303,6 +305,9 @@ class BaseStorage {
303
305
  return p
304
306
  .then(() => collection.createIndex(i.index, i.options))
305
307
  .catch((e) => {
308
+ if (i.options.unique) {
309
+ this._uniqueIndexFailed = true;
310
+ }
306
311
  this._log.error(`DB.${this._collectionName} failed to create index ${i.options.name} on ${collection.collectionName}`, e);
307
312
  })
308
313
  .then(() => true);
@@ -366,6 +371,10 @@ class BaseStorage {
366
371
  const objToSign = this._objectToSign(object);
367
372
  const sign = this._signWithSecret(objToSign, secret);
368
373
 
374
+ if (this.logSig) {
375
+ this._log.log(`sign ${this._collectionName}`, JSON.stringify(objToSign, null, 2));
376
+ }
377
+
369
378
  return Object.assign(objToSign, {
370
379
  sign
371
380
  });
@@ -114,6 +114,7 @@ class ChatLogStorage extends BaseStorage {
114
114
  const compare = this._signWithSecret(objToSign, secret);
115
115
  const ok = compare === sign;
116
116
  if (!ok) {
117
+ this._log.log(`compare ${this._collectionName}`, JSON.stringify(objToSign, null, 2));
117
118
  this._log.error(`ChatLog: found wrong signature at pageId: "${r.pageId}", senderId: "${r.senderId}", at: ${r.timestamp}`, r);
118
119
  }
119
120
 
@@ -51,6 +51,8 @@ class StateStorage extends BaseStorage {
51
51
  { name: LAST_INTERACTION_INDEX }
52
52
  );
53
53
 
54
+ this.logCollisionsAsErrors = false;
55
+
54
56
  if (isCosmo) {
55
57
  this.addIndex(
56
58
  { name: 1 },
@@ -84,7 +86,12 @@ class StateStorage extends BaseStorage {
84
86
  */
85
87
  async getState (senderId, pageId) {
86
88
  const c = await this._getCollection();
87
- const doc = await c.findOne({ senderId, pageId }, { projection: { _id: 0 } });
89
+ const doc = await c.findOne({
90
+ senderId, pageId
91
+ }, {
92
+ projection: { _id: 0 },
93
+ ...(this._uniqueIndexFailed ? { sort: { lastInteraction: -1 } } : {})
94
+ });
88
95
  // @ts-ignore
89
96
  return doc;
90
97
  }
@@ -123,12 +130,44 @@ class StateStorage extends BaseStorage {
123
130
  $set
124
131
  }, {
125
132
  upsert: true,
133
+ ...(this._uniqueIndexFailed ? { sort: { lastInteraction: -1 } } : {}),
126
134
  returnDocument: 'after',
127
135
  projection: {
128
136
  _id: 0
129
137
  }
130
138
  }));
131
139
 
140
+ if (this._uniqueIndexFailed && !res.value.lastInteraction) {
141
+ // check if there was a locked state
142
+ const existing = await c.find({
143
+ senderId,
144
+ pageId
145
+ })
146
+ .sort({ lastInteraction: -1 })
147
+ .toArray();
148
+
149
+ if (existing.length > 1) {
150
+
151
+ // remove entries without lastInteraction
152
+ const $in = existing
153
+ .filter((s) => !s.lastInteraction && (s.lock === now || s.lock < $lt))
154
+ .map((s) => s._id);
155
+
156
+ const logLevel = this.logCollisionsAsErrors ? 'error' : 'log';
157
+ this._log[logLevel]('StateStorage: unique index workaround DETECTED', {
158
+ v: res.value, existing, $in: $in.map((i) => i.toString())
159
+ });
160
+
161
+ if ($in.length > 0) {
162
+ await c.deleteMany({ _id: { $in } });
163
+ }
164
+
165
+ throw Object.assign(new Error('State was locked'), { code: 11000 });
166
+ } else {
167
+ this._log.log('StateStorage: unique index workaround OK', res.value);
168
+ }
169
+ }
170
+
132
171
  return res.value;
133
172
  }
134
173
 
@@ -245,13 +284,24 @@ class StateStorage extends BaseStorage {
245
284
 
246
285
  const { senderId, pageId } = state;
247
286
 
248
- await c.updateOne({
249
- senderId, pageId
250
- }, {
251
- $set: state
252
- }, {
253
- upsert: true
254
- });
287
+ if (this._uniqueIndexFailed) {
288
+ await c.findOneAndUpdate({
289
+ senderId, pageId
290
+ }, {
291
+ $set: state
292
+ }, {
293
+ sort: { lastInteraction: -1 },
294
+ upsert: true
295
+ });
296
+ } else {
297
+ await c.updateOne({
298
+ senderId, pageId
299
+ }, {
300
+ $set: state
301
+ }, {
302
+ upsert: true
303
+ });
304
+ }
255
305
 
256
306
  return state;
257
307
  }