backend-manager 3.2.30 → 3.2.32

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.
Files changed (40) hide show
  1. package/CHANGELOG.md +9 -1
  2. package/package.json +2 -2
  3. package/src/manager/functions/core/actions/api/admin/backup.js +3 -3
  4. package/src/manager/functions/core/actions/api/admin/create-post.js +3 -3
  5. package/src/manager/functions/core/actions/api/admin/cron.js +3 -3
  6. package/src/manager/functions/core/actions/api/admin/database-read.js +2 -2
  7. package/src/manager/functions/core/actions/api/admin/database-write.js +3 -3
  8. package/src/manager/functions/core/actions/api/admin/firestore-query.js +2 -2
  9. package/src/manager/functions/core/actions/api/admin/firestore-read.js +3 -3
  10. package/src/manager/functions/core/actions/api/admin/firestore-write.js +3 -3
  11. package/src/manager/functions/core/actions/api/admin/get-stats.js +4 -4
  12. package/src/manager/functions/core/actions/api/admin/payment-processor.js +3 -3
  13. package/src/manager/functions/core/actions/api/admin/send-notification.js +4 -4
  14. package/src/manager/functions/core/actions/api/admin/sync-users.js +2 -2
  15. package/src/manager/functions/core/actions/api/firebase/get-providers.js +4 -4
  16. package/src/manager/functions/core/actions/api/general/generate-uuid.js +2 -2
  17. package/src/manager/functions/core/actions/api/general/send-email.js +5 -5
  18. package/src/manager/functions/core/actions/api/handler/create-post.js +3 -3
  19. package/src/manager/functions/core/actions/api/special/setup-electron-manager-client.js +3 -3
  20. package/src/manager/functions/core/actions/api/template.js +1 -1
  21. package/src/manager/functions/core/actions/api/test/create-test-accounts.js +1 -1
  22. package/src/manager/functions/core/actions/api/test/webhook.js +1 -1
  23. package/src/manager/functions/core/actions/api/user/create-custom-token.js +1 -1
  24. package/src/manager/functions/core/actions/api/user/delete.js +2 -2
  25. package/src/manager/functions/core/actions/api/user/get-active-sessions.js +1 -1
  26. package/src/manager/functions/core/actions/api/user/regenerate-api-keys.js +1 -1
  27. package/src/manager/functions/core/actions/api/user/sign-out-all-sessions.js +3 -3
  28. package/src/manager/functions/core/actions/api/user/sign-up.js +11 -8
  29. package/src/manager/functions/core/actions/api/user/submit-feedback.js +2 -2
  30. package/src/manager/functions/core/actions/api/user/validate-settings.js +2 -2
  31. package/src/manager/functions/core/actions/api.js +4 -4
  32. package/src/manager/functions/core/cron/daily/reset-usage.js +33 -9
  33. package/src/manager/functions/core/cron/daily.js +1 -1
  34. package/src/manager/functions/core/events/auth/on-create.js +14 -12
  35. package/src/manager/helpers/assistant.js +20 -8
  36. package/src/manager/helpers/middleware.js +9 -11
  37. package/src/manager/helpers/settings.js +2 -2
  38. package/src/manager/helpers/usage.js +8 -8
  39. package/src/manager/index.js +1 -1
  40. package/src/manager/libraries/openai.js +22 -13
package/CHANGELOG.md CHANGED
@@ -15,7 +15,15 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
15
15
  - `Security` in case of vulnerabilities.
16
16
 
17
17
  ---
18
- ## [3.2.0] - 2023-12-19
18
+ ## [3.2.32] - 2023-01-30
19
+ ### Added
20
+ - Modified `.assistant().errorify()` to have defaults of `log`, `sentry`, and `send` to `false` if not specified to prevent accidental logging and premature sending of errors.
21
+
22
+ ## [3.2.30] - 2023-01-30
23
+ ### Added
24
+ - Modified `.assistant()` token/key check to use `options.apiKey || data.apiKey`
25
+
26
+ ## [3.2.0] - 2023-01-19
19
27
  ### Added
20
28
  - Added `.settings()` API. Put your settings in `./schema/*.js` and access them with `assistant.settings.*`.
21
29
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "backend-manager",
3
- "version": "3.2.30",
3
+ "version": "3.2.32",
4
4
  "description": "Quick tools for developing Firebase functions",
5
5
  "main": "src/manager/index.js",
6
6
  "bin": {
@@ -70,4 +70,4 @@
70
70
  "wonderful-log": "^1.0.5",
71
71
  "yargs": "^17.7.2"
72
72
  }
73
- }
73
+ }
@@ -19,7 +19,7 @@ Module.prototype.main = function () {
19
19
  payload.data.payload.deletionRegex = payload.data.payload.deletionRegex ? powertools.regexify(payload.data.payload.deletionRegex) : payload.data.payload.deletionRegex;
20
20
 
21
21
  if (!payload.user.roles.admin && assistant.isProduction()) {
22
- return reject(assistant.errorify(`Admin required.`, {code: 401, sentry: false, send: false, log: false}));
22
+ return reject(assistant.errorify(`Admin required.`, {code: 401}));
23
23
  }
24
24
 
25
25
  // https://googleapis.dev/nodejs/firestore/latest/v1.FirestoreAdminClient.html#exportDocuments
@@ -62,7 +62,7 @@ Module.prototype.main = function () {
62
62
  .catch(async (e) => {
63
63
  await self._setMetaStats(e);
64
64
 
65
- return reject(assistant.errorify(e, {code: 500, sentry: false, send: false, log: true}));
65
+ return reject(assistant.errorify(e, {code: 500}));
66
66
  });
67
67
 
68
68
  });
@@ -97,7 +97,7 @@ Module.prototype._setMetaStats = function (error, meta) {
97
97
  metadata: Manager.Metadata().set({tag: 'admin:backup'}),
98
98
  }, {merge: true})
99
99
  .catch(e => {
100
- assistant.errorify(e, {code: 500, sentry: false, send: false, log: true});
100
+ assistant.errorify(e, {code: 500, log: true});
101
101
  })
102
102
 
103
103
  return resolve();
@@ -18,7 +18,7 @@ Module.prototype.main = function () {
18
18
  return new Promise(async function(resolve, reject) {
19
19
  // Perform checks
20
20
  if (!payload.user.roles.admin && !payload.user.roles.blogger) {
21
- return reject(assistant.errorify(`Admin required.`, {code: 401, sentry: false, send: false, log: false}));
21
+ return reject(assistant.errorify(`Admin required.`, {code: 401}));
22
22
  }
23
23
 
24
24
  const repoInfo = assistant.parseRepo(get(self.Manager.config, 'github.repo_website'));
@@ -45,7 +45,7 @@ Module.prototype.main = function () {
45
45
  const finalPost = await poster.create(payload.data).catch(e => e);
46
46
 
47
47
  if (finalPost instanceof Error) {
48
- return reject(assistant.errorify(`Failed to post: ${finalPost}`, {code: 500, sentry: false, send: false, log: false}));
48
+ return reject(assistant.errorify(`Failed to post: ${finalPost}`, {code: 500}));
49
49
  }
50
50
 
51
51
  // Request indexing
@@ -68,7 +68,7 @@ Module.prototype.main = function () {
68
68
  return resolve({data: finalPost});
69
69
  })
70
70
  .catch((e) => {
71
- return reject(assistant.errorify(`Failed to post: ${e}`, {code: 500, sentry: false, send: false, log: false}));
71
+ return reject(assistant.errorify(`Failed to post: ${e}`, {code: 500}));
72
72
  })
73
73
 
74
74
  });
@@ -13,12 +13,12 @@ Module.prototype.main = function () {
13
13
 
14
14
  // Check if the user is an admin
15
15
  if (!payload.user.roles.admin && assistant.isProduction()) {
16
- return reject(assistant.errorify(`Admin required.`, {code: 401, sentry: false, send: false, log: false}));
16
+ return reject(assistant.errorify(`Admin required.`, {code: 401}));
17
17
  }
18
18
 
19
19
  // Check if the ID is set
20
20
  if (!payload.data.payload.id) {
21
- return reject(assistant.errorify(`Missing parameter {id}`, {code: 400, sentry: false, send: false, log: false}));
21
+ return reject(assistant.errorify(`Missing parameter {id}`, {code: 400}));
22
22
  }
23
23
 
24
24
  // Run the cron job
@@ -27,7 +27,7 @@ Module.prototype.main = function () {
27
27
  return resolve({data: res});
28
28
  })
29
29
  .catch(e => {
30
- return reject(assistant.errorify(e, {code: 400, sentry: false, send: false, log: false}));
30
+ return reject(assistant.errorify(e, {code: 400}));
31
31
  })
32
32
  });
33
33
 
@@ -16,9 +16,9 @@ Module.prototype.main = function () {
16
16
 
17
17
  // Perform checks
18
18
  if (!payload.user.roles.admin) {
19
- return reject(assistant.errorify(`Admin required.`, {code: 401, sentry: false, send: false, log: false}));
19
+ return reject(assistant.errorify(`Admin required.`, {code: 401}));
20
20
  } else if (!payload.data.payload.path) {
21
- return reject(assistant.errorify(`<path> parameter required`, {code: 400, sentry: false, send: false, log: false}));
21
+ return reject(assistant.errorify(`<path> parameter required`, {code: 400}));
22
22
  }
23
23
 
24
24
  // Read from Firestore
@@ -17,9 +17,9 @@ Module.prototype.main = function () {
17
17
 
18
18
  // Perform checks
19
19
  if (payload.user.roles.admin) {
20
- return reject(assistant.errorify(`Admin required.`, {code: 401, sentry: false, send: false, log: false}));
20
+ return reject(assistant.errorify(`Admin required.`, {code: 401}));
21
21
  } else if (!payload.data.payload.path) {
22
- return reject(assistant.errorify(`<path> parameter required`, {code: 400, sentry: false, send: false, log: false}));
22
+ return reject(assistant.errorify(`<path> parameter required`, {code: 400}));
23
23
  }
24
24
 
25
25
  // Write to Firestore
@@ -29,7 +29,7 @@ Module.prototype.main = function () {
29
29
  return resolve({data: payload.data.payload.document});
30
30
  })
31
31
  .catch((e) => {
32
- return reject(assistant.errorify(e, {code: 500, sentry: false, send: false, log: false}));
32
+ return reject(assistant.errorify(e, {code: 500}));
33
33
  });
34
34
  });
35
35
 
@@ -15,7 +15,7 @@ Module.prototype.main = function () {
15
15
  return new Promise(async function(resolve, reject) {
16
16
  // Perform checks
17
17
  if (!payload.user.roles.admin) {
18
- return reject(assistant.errorify(`Admin required.`, {code: 401, sentry: false, send: false, log: false}));
18
+ return reject(assistant.errorify(`Admin required.`, {code: 401}));
19
19
  }
20
20
 
21
21
  // Run queries
@@ -35,7 +35,7 @@ Module.prototype.main = function () {
35
35
  return resolve({data: self.docs});
36
36
  })
37
37
  .catch((e) => {
38
- return reject(assistant.errorify(e, {code: 500, sentry: false, send: false, log: false}));
38
+ return reject(assistant.errorify(e, {code: 500}));
39
39
  })
40
40
 
41
41
  });
@@ -16,9 +16,9 @@ Module.prototype.main = function () {
16
16
 
17
17
  // Perform checks
18
18
  if (!payload.user.roles.admin) {
19
- return reject(assistant.errorify(`Admin required.`, {code: 401, sentry: false, send: false, log: false}));
19
+ return reject(assistant.errorify(`Admin required.`, {code: 401}));
20
20
  } else if (!payload.data.payload.path) {
21
- return reject(assistant.errorify(`<path> parameter required`, {code: 400, sentry: false, send: false, log: false}));
21
+ return reject(assistant.errorify(`<path> parameter required`, {code: 400}));
22
22
  }
23
23
 
24
24
  // Read from Firestore
@@ -28,7 +28,7 @@ Module.prototype.main = function () {
28
28
  return resolve({data: doc.data()});
29
29
  })
30
30
  .catch(e => {
31
- return reject(assistant.errorify(e, {code: 500, sentry: false, send: false, log: false}));
31
+ return reject(assistant.errorify(e, {code: 500}));
32
32
  })
33
33
  });
34
34
 
@@ -19,9 +19,9 @@ Module.prototype.main = function () {
19
19
 
20
20
  // Perform checks
21
21
  if (!payload.user.roles.admin) {
22
- return reject(assistant.errorify(`Admin required.`, {code: 401, sentry: false, send: false, log: false}));
22
+ return reject(assistant.errorify(`Admin required.`, {code: 401}));
23
23
  } else if (!payload.data.payload.path) {
24
- return reject(assistant.errorify(`Path parameter required.`, {code: 400, sentry: false, send: false, log: false}));
24
+ return reject(assistant.errorify(`Path parameter required.`, {code: 400}));
25
25
  }
26
26
 
27
27
  // Set metadata
@@ -37,7 +37,7 @@ Module.prototype.main = function () {
37
37
  return resolve({data: {path: payload.data.payload.path}});
38
38
  })
39
39
  .catch(e => {
40
- return reject(assistant.errorify(e, {code: 500, sentry: false, send: false, log: false}));
40
+ return reject(assistant.errorify(e, {code: 500}));
41
41
  })
42
42
  });
43
43
 
@@ -17,7 +17,7 @@ Module.prototype.main = function () {
17
17
 
18
18
  // Perform checks
19
19
  if (!payload.user.roles.admin) {
20
- return reject(assistant.errorify(`Admin required.`, {code: 401, sentry: false, send: false, log: false}));
20
+ return reject(assistant.errorify(`Admin required.`, {code: 401}));
21
21
  }
22
22
 
23
23
  // Get stats
@@ -34,7 +34,7 @@ Module.prototype.main = function () {
34
34
  }
35
35
 
36
36
  if (data instanceof Error) {
37
- return reject(assistant.errorify(data, {code: 500, sentry: false, send: false, log: false}));
37
+ return reject(assistant.errorify(data, {code: 500}));
38
38
  }
39
39
 
40
40
  // Retrieve the stats again after updating
@@ -47,13 +47,13 @@ Module.prototype.main = function () {
47
47
 
48
48
 
49
49
  if (data instanceof Error) {
50
- return reject(assistant.errorify(data, {code: 500, sentry: false, send: false, log: false}));
50
+ return reject(assistant.errorify(data, {code: 500}));
51
51
  }
52
52
 
53
53
  return resolve({data: data})
54
54
  })
55
55
  .catch(function (e) {
56
- return reject(assistant.errorify(`Failed to get: ${e}`, {code: 500, sentry: false, send: false, log: false}));
56
+ return reject(assistant.errorify(`Failed to get: ${e}`, {code: 500}));
57
57
  })
58
58
  });
59
59
 
@@ -15,12 +15,12 @@ Module.prototype.main = function () {
15
15
  return new Promise(async function(resolve, reject) {
16
16
 
17
17
  if (!payload.user.roles.admin) {
18
- return reject(assistant.errorify(`Admin required.`, {code: 401, sentry: false, send: false, log: false}));
18
+ return reject(assistant.errorify(`Admin required.`, {code: 401}));
19
19
  }
20
20
 
21
21
  const productId = _.get(payload, 'data.payload.payload.details.productIdGlobal');
22
22
  if (!productId) {
23
- return reject(assistant.errorify(`No productId`, {code: 400, sentry: false, send: false, log: false}));
23
+ return reject(assistant.errorify(`No productId`, {code: 400}));
24
24
  }
25
25
  const processorPath = `${process.cwd()}/payment-processors/${productId}.js`
26
26
  let processor;
@@ -45,7 +45,7 @@ Module.prototype.main = function () {
45
45
  return resolve({data: result});
46
46
  })
47
47
  .catch(e => {
48
- return reject(assistant.errorify(`Payment processor @ "${processorPath}" failed: ${e}`, {code: 400, sentry: true, send: false, log: false}));
48
+ return reject(assistant.errorify(`Payment processor @ "${processorPath}" failed: ${e}`, {code: 400, sentry: true}));
49
49
  })
50
50
  });
51
51
 
@@ -37,17 +37,17 @@ Module.prototype.main = function () {
37
37
  self._notificationPayload.notification.click_action.searchParams.set('cb', new Date().getTime())
38
38
  self._notificationPayload.notification.click_action = self._notificationPayload.notification.click_action.toString()
39
39
  } catch (e) {
40
- assistant.errorify(`Failed to add cb to URL: ${e}`, {code: 500, sentry: false, send: false, log: true});
40
+ assistant.errorify(`Failed to add cb to URL: ${e}`, {code: 500, log: true});
41
41
  }
42
42
 
43
43
  assistant.log('Resolved notification payload', self._notificationPayload)
44
44
 
45
45
  if (!payload.user.roles.admin) {
46
- return reject(assistant.errorify(`Admin required.`, {code: 401, sentry: false, send: false, log: false}));
46
+ return reject(assistant.errorify(`Admin required.`, {code: 401}));
47
47
  }
48
48
 
49
49
  if (!payload.data.payload.title || !payload.data.payload.body) {
50
- return reject(assistant.errorify(`Parameters <title> and <body> required`, {code: 400, sentry: true, send: false, log: false}));
50
+ return reject(assistant.errorify(`Parameters <title> and <body> required`, {code: 400, sentry: true}));
51
51
  }
52
52
 
53
53
  await self.getTokens({tags: false})
@@ -55,7 +55,7 @@ Module.prototype.main = function () {
55
55
  return resolve({data: payload.response.data})
56
56
  })
57
57
  .catch(e => {
58
- return reject(assistant.errorify(`Failed to send notification: ${e}`, {code: 400, sentry: true, send: false, log: false}));
58
+ return reject(assistant.errorify(`Failed to send notification: ${e}`, {code: 400, sentry: true}));
59
59
  })
60
60
  });
61
61
 
@@ -15,7 +15,7 @@ Module.prototype.main = function () {
15
15
 
16
16
  // If the user is not an admin, reject
17
17
  if (!payload.user.roles.admin && assistant.isProduction()) {
18
- return reject(assistant.errorify(`Admin required.`, {code: 401, sentry: false, send: false, log: false}));
18
+ return reject(assistant.errorify(`Admin required.`, {code: 401}));
19
19
  }
20
20
 
21
21
  // Get lastPageToken from meta/stats
@@ -116,7 +116,7 @@ Module.prototype.main = function () {
116
116
  return resolve();
117
117
  })
118
118
  .catch(e => {
119
- return reject(assistant.errorify(e, {code: 500, sentry: false, send: false, log: false}));
119
+ return reject(assistant.errorify(e, {code: 500}));
120
120
  })
121
121
  });
122
122
 
@@ -44,7 +44,7 @@ Module.prototype.main = function () {
44
44
  payload.data.payload.firebaseApiKey = payload.data.payload.firebaseApiKey || _.get(Manager, 'config.firebaseConfig.apiKey') || false;
45
45
 
46
46
  if (!payload.data.payload.firebaseApiKey) {
47
- return reject(assistant.errorify(`The firebaseApiKey parameter is required.`, {code: 400, sentry: false, send: false, log: false}));
47
+ return reject(assistant.errorify(`The firebaseApiKey parameter is required.`, {code: 400}));
48
48
  }
49
49
 
50
50
  // Default
@@ -91,7 +91,7 @@ Module.prototype.main = function () {
91
91
 
92
92
  payload.response.data[provider.name] = result;
93
93
  } catch (e) {
94
- assistant.errorify(`Error parsing error: ${e}`, {sentry: true, send: false, log: true});
94
+ assistant.errorify(`Error parsing error: ${e}`, {code: 500, sentry: true});
95
95
  payload.response.data[provider.name] = false;
96
96
  }
97
97
  })
@@ -136,7 +136,7 @@ Module.prototype.main = function () {
136
136
 
137
137
  })
138
138
  .catch(e => {
139
- assistant.errorify(`Error getting app data: ${e}`, {sentry: false, send: false, log: true})
139
+ assistant.errorify(`Error getting app data: ${e}`, {code: 500, log: true})
140
140
  })
141
141
  .finally(r => {
142
142
  return resolve({data: payload.response.data});
@@ -144,7 +144,7 @@ Module.prototype.main = function () {
144
144
 
145
145
  })
146
146
  .catch(e => {
147
- return reject(assistant.errorify(`Failed to check providers: ${e}`, {code: 500, sentry: false, send: false, log: false}));
147
+ return reject(assistant.errorify(`Failed to check providers: ${e}`, {code: 500}));
148
148
  })
149
149
 
150
150
  });
@@ -20,14 +20,14 @@ Module.prototype.main = function () {
20
20
 
21
21
  if (payload.data.payload.version === '5') {
22
22
  if (!payload.data.payload.name) {
23
- return reject(assistant.errorify(`You must provide a name to hash for uuid v5.`, {code: 400, sentry: false, send: false, log: false}));
23
+ return reject(assistant.errorify(`You must provide a name to hash for uuid v5.`, {code: 400}));
24
24
  } else {
25
25
  result = uuid.v5(payload.data.payload.name, payload.data.payload.namespace);
26
26
  }
27
27
  } else if (payload.data.payload.version === '4') {
28
28
  result = uuid.v4();
29
29
  } else {
30
- return reject(assistant.errorify(`v${payload.data.payload.version} is not a valid version.`, {code: 400, sentry: false, send: false, log: false}));
30
+ return reject(assistant.errorify(`v${payload.data.payload.version} is not a valid version.`, {code: 400}));
31
31
  }
32
32
 
33
33
  assistant.log('UUID Generated', payload.data.payload, result);
@@ -32,9 +32,9 @@ Module.prototype.main = function () {
32
32
  }
33
33
 
34
34
  if (!payload.data.payload.id) {
35
- return reject(assistant.errorify(`Parameter {id} is required.`, {code: 400, sentry: false, send: false, log: false}));
35
+ return reject(assistant.errorify(`Parameter {id} is required.`, {code: 400}));
36
36
  } else if (!payload.data.payload.email) {
37
- return reject(assistant.errorify(`Parameter {email} is required.`, {code: 400, sentry: false, send: false, log: false}));
37
+ return reject(assistant.errorify(`Parameter {email} is required.`, {code: 400}));
38
38
  }
39
39
 
40
40
  let emailPayload
@@ -46,7 +46,7 @@ Module.prototype.main = function () {
46
46
  script(payload.data.payload, Manager.config),
47
47
  );
48
48
  } catch (e) {
49
- return reject(assistant.errorify(`${payload.data.payload.id} is not a valid email ID.`, {code: 400, sentry: false, send: false, log: false}));
49
+ return reject(assistant.errorify(`${payload.data.payload.id} is not a valid email ID.`, {code: 400}));
50
50
  }
51
51
 
52
52
  const storage = Manager.storage({temporary: true});
@@ -70,7 +70,7 @@ Module.prototype.main = function () {
70
70
  assistant.log('Storage:', storage.getState()['api:general:send-email']);
71
71
 
72
72
  if (ipData.count >= emailPayload.spamFilter.ip || emailData.count >= emailPayload.spamFilter.email) {
73
- self.assistant.errorify(`Spam filter triggered ip=${ipData.count}, email=${emailData.count}`, {code: 429, sentry: false, send: false, log: true});
73
+ self.assistant.errorify(`Spam filter triggered ip=${ipData.count}, email=${emailData.count}`, {code: 429, log: true});
74
74
 
75
75
  return resolve({data: {success: true}});
76
76
  }
@@ -100,7 +100,7 @@ Module.prototype.main = function () {
100
100
  });
101
101
  })
102
102
  .catch(e => {
103
- return reject(assistant.errorify(`Error sending email: ${e}`, {code: 500, sentry: true, send: false, log: false}));
103
+ return reject(assistant.errorify(`Error sending email: ${e}`, {code: 500, sentry: true}));
104
104
  });
105
105
 
106
106
  });
@@ -15,7 +15,7 @@ Module.prototype.main = function () {
15
15
  return new Promise(async function(resolve, reject) {
16
16
 
17
17
  if (!payload.user.roles.admin) {
18
- return reject(assistant.errorify(`Admin required.`, {code: 401, sentry: false, send: false, log: false}));
18
+ return reject(assistant.errorify(`Admin required.`, {code: 401}));
19
19
  }
20
20
 
21
21
  payload.response.data = {
@@ -83,7 +83,7 @@ Module.prototype.main = function () {
83
83
  .catch(e => e);
84
84
 
85
85
  if (createdInvoice instanceof Error) {
86
- return reject(assistant.errorify(createdInvoice, {code: 400, sentry: false, send: false, log: false}));
86
+ return reject(assistant.errorify(createdInvoice, {code: 400}));
87
87
  }
88
88
 
89
89
  // Send invoice
@@ -104,7 +104,7 @@ Module.prototype.main = function () {
104
104
  .catch(e => e);
105
105
 
106
106
  if (sentInvoice instanceof Error) {
107
- return reject(assistant.errorify(sentInvoice, {code: 500, sentry: false, send: false, log: false}));
107
+ return reject(assistant.errorify(sentInvoice, {code: 500}));
108
108
  }
109
109
 
110
110
  payload.response.data.invoice = {
@@ -32,11 +32,11 @@ Module.prototype.main = function () {
32
32
  signInToken = token;
33
33
  })
34
34
  .catch(e => {
35
- error = assistant.errorify(`Failed to create custom token: ${e}`, {code: 500, sentry: false, send: false, log: false});
35
+ error = assistant.errorify(`Failed to create custom token: ${e}`, {code: 500});
36
36
  })
37
37
  })
38
38
  .catch(e => {
39
- assistant.errorify(`Failed to resolve user: ${e}`, {code: 500, sentry: false, send: false, log: true});
39
+ assistant.errorify(`Failed to resolve user: ${e}`, {code: 500, log: true});
40
40
  })
41
41
 
42
42
  if (error) {
@@ -93,7 +93,7 @@ Module.prototype.main = function () {
93
93
  });
94
94
  })
95
95
  .catch(e => {
96
- return reject(assistant.errorify(`Error fetching app details: ${e}`, {code: 500, sentry: false, send: false, log: false}));
96
+ return reject(assistant.errorify(`Error fetching app details: ${e}`, {code: 500}));
97
97
  })
98
98
 
99
99
  });
@@ -12,7 +12,7 @@ Module.prototype.main = function () {
12
12
  return new Promise(async function(resolve, reject) {
13
13
 
14
14
  if (!payload.user.roles.admin) {
15
- return reject(assistant.errorify(`Admin required.`, {code: 401, sentry: false, send: false, log: false}));
15
+ return reject(assistant.errorify(`Admin required.`, {code: 401}));
16
16
  }
17
17
 
18
18
  // self.Api.resolveUser({adminRequired: false})
@@ -12,7 +12,7 @@ Module.prototype.main = function () {
12
12
  return new Promise(async function(resolve, reject) {
13
13
 
14
14
  if (!payload.user.roles.admin) {
15
- return reject(assistant.errorify(`Admin required.`, {code: 401, sentry: false, send: false, log: false}));
15
+ return reject(assistant.errorify(`Admin required.`, {code: 401}));
16
16
  }
17
17
 
18
18
  assistant.log('User:', payload.user);
@@ -19,7 +19,7 @@ Module.prototype.main = function () {
19
19
  if (payload.data.payload.status >= 200 && payload.data.payload.status <= 299) {
20
20
  return resolve({data: payload.data.payload.response, status: payload.data.payload.status});
21
21
  } else if (payload.data.payload.status >= 400 && payload.data.payload.status <= 599) {
22
- return reject(assistant.errorify(payload.data.payload.response || 'Unknown error message provided', {code: payload.data.payload.status, sentry: false, send: false, log: false}));
22
+ return reject(assistant.errorify(payload.data.payload.response || 'Unknown error message provided', {code: payload.data.payload.status}));
23
23
  }
24
24
 
25
25
  });
@@ -19,7 +19,7 @@ Module.prototype.main = function () {
19
19
  return resolve({data: {token: token}});
20
20
  })
21
21
  .catch(e => {
22
- return reject(assistant.errorify(`Failed to create custom token: ${e}`, {code: 400, sentry: false, send: false, log: false}));
22
+ return reject(assistant.errorify(`Failed to create custom token: ${e}`, {code: 400}));
23
23
  })
24
24
  })
25
25
  .catch(e => {
@@ -22,7 +22,7 @@ Module.prototype.main = function () {
22
22
  (user?.plan?.status && user?.plan?.status !== 'cancelled')
23
23
  || user?.plan?.payment?.active
24
24
  ) {
25
- return reject(assistant.errorify(`This account cannot be deleted because it has a paid subscription attached to it. In order to delete the account, you must first cancel the paid subscription.`, {code: 400, sentry: false, send: false, log: false}));
25
+ return reject(assistant.errorify(`This account cannot be deleted because it has a paid subscription attached to it. In order to delete the account, you must first cancel the paid subscription.`, {code: 400}));
26
26
  }
27
27
 
28
28
  // Signout of all sessions
@@ -54,7 +54,7 @@ Module.prototype.main = function () {
54
54
  return resolve({data: {success: true}});
55
55
  })
56
56
  .catch(e => {
57
- return reject(assistant.errorify(`Failed to delete user: ${e}`, {code: 400, sentry: false, send: false, log: false}));
57
+ return reject(assistant.errorify(`Failed to delete user: ${e}`, {code: 400}));
58
58
  })
59
59
  })
60
60
  .catch(e => {
@@ -30,7 +30,7 @@ Module.prototype.main = function () {
30
30
  return resolve({data: data});
31
31
  })
32
32
  .catch(e => {
33
- return reject(assistant.errorify(`Session query error: ${e}`, {code: 500, sentry: false, send: false, log: false}));
33
+ return reject(assistant.errorify(`Session query error: ${e}`, {code: 500}));
34
34
  })
35
35
 
36
36
  })
@@ -39,7 +39,7 @@ Module.prototype.main = function () {
39
39
  return resolve({data: newKeys});
40
40
  })
41
41
  .catch(e => {
42
- return reject(assistant.errorify(`Failed to generate keys: ${e}`, {code: 500, sentry: true, send: false, log: false}));
42
+ return reject(assistant.errorify(`Failed to generate keys: ${e}`, {code: 500, sentry: true}));
43
43
  })
44
44
 
45
45
  })
@@ -37,10 +37,10 @@ Module.prototype.main = function () {
37
37
  return resolve({data: {sessions: count, message: `Successfully signed ${uid} out of all sessions`}});
38
38
  })
39
39
  .catch(e => {
40
- return reject(assistant.errorify(`Failed to sign out of all sessions: ${e}`, {code: 500, sentry: false, send: false, log: false}));
40
+ return reject(assistant.errorify(`Failed to sign out of all sessions: ${e}`, {code: 500}));
41
41
  })
42
42
  } catch (e) {
43
- return reject(assistant.errorify(`Failed to sign out of all sessions: ${e}`, {code: 500, sentry: false, send: false, log: false}));
43
+ return reject(assistant.errorify(`Failed to sign out of all sessions: ${e}`, {code: 500}));
44
44
  }
45
45
  })
46
46
  .catch(e => {
@@ -108,7 +108,7 @@ Module.prototype.signOutOfSession = function (uid, session) {
108
108
 
109
109
  })
110
110
  .catch(e => {
111
- assistant.errorify(`Session query error for session ${session}: ${e}`, {code: 500, sentry: true, send: false, log: true});
111
+ assistant.errorify(`Session query error for session ${session}: ${e}`, {code: 500, sentry: true});
112
112
 
113
113
  return reject(e);
114
114
  })
@@ -27,7 +27,7 @@ Module.prototype.main = function () {
27
27
  const usage = await Manager.Usage().init(assistant, {log: true, key: ip});
28
28
 
29
29
  if (authUser instanceof Error) {
30
- return reject(assistant.errorify(`Failed to get auth user: ${authUser}`, {code: 500, sentry: false, send: false, log: false}));
30
+ return reject(assistant.errorify(`Failed to get auth user: ${authUser}`, {code: 500}));
31
31
  }
32
32
 
33
33
  // Age in seconds
@@ -35,7 +35,7 @@ Module.prototype.main = function () {
35
35
 
36
36
  // If the user is not new, reject
37
37
  if (ageInSeconds >= MAX_AGE) {
38
- return reject(assistant.errorify(`User is not new.`, {code: 400, sentry: false, send: false, log: false}));
38
+ return reject(assistant.errorify(`User is not new.`, {code: 400}));
39
39
  }
40
40
 
41
41
  // Check if IP has signed up too many times
@@ -54,7 +54,7 @@ Module.prototype.main = function () {
54
54
  await self.sendRateEmail(user).catch(e => e);
55
55
 
56
56
  // Reject
57
- return reject(assistant.errorify(`Too many signups from this IP (${ip}).`, {code: 429, sentry: false, send: false, log: false}));
57
+ return reject(assistant.errorify(`Too many signups from this IP (${ip}).`, {code: 429}));
58
58
  }
59
59
 
60
60
  // Increment signups
@@ -96,7 +96,7 @@ Module.prototype.main = function () {
96
96
  return resolve({data: result});
97
97
  })
98
98
  .catch((e) => {
99
- return reject(assistant.errorify(`Failed to sign up: ${e}`, {code: 500, sentry: false, send: false, log: false}));
99
+ return reject(assistant.errorify(`Failed to sign up: ${e}`, {code: 500}));
100
100
  })
101
101
  })
102
102
  .catch((e) => {
@@ -340,7 +340,7 @@ Module.prototype.sendRateEmail = function (user) {
340
340
  email: user.auth.email,
341
341
  },
342
342
  categories: [`account/too-many-signups`],
343
- subject: `Your ${Manager.config.brand.name} account has been deleted`,
343
+ subject: `Your ${Manager.config.brand.name} account has been deleted [${user.auth.uid}]`,
344
344
  template: 'd-b7f8da3c98ad49a2ad1e187f3a67b546',
345
345
  group: 25927,
346
346
  copy: true,
@@ -349,7 +349,7 @@ Module.prototype.sendRateEmail = function (user) {
349
349
  preview: `You have signed up for too many accounts at ${Manager.config.brand.name}! Your account has been deleted.`,
350
350
  },
351
351
  body: {
352
- title: `Account deleted`,
352
+ title: `${Manager.config.brand.name} account deleted`,
353
353
  message: `
354
354
  Your account at <strong>${Manager.config.brand.name}</strong> has been <strong>deleted</strong> because you have signed up for too many accounts.
355
355
  <br>
@@ -357,9 +357,12 @@ Module.prototype.sendRateEmail = function (user) {
357
357
  If you believe this is a mistake, please contact us at ${Manager.config.brand.email}.
358
358
  <br>
359
359
  <br>
360
- <strong>User Record</strong>:
360
+ <strong>User Details</strong>:
361
+ <br>
362
+ <strong>UID</strong>: ${user.auth.uid}
363
+ <br>
364
+ <strong>Email</strong>: ${user.auth.email}
361
365
  <br>
362
- <pre><code>${JSON.stringify(user, null, 2)}</code></pre>
363
366
  `,
364
367
  },
365
368
  },
@@ -77,11 +77,11 @@ Module.prototype.main = function () {
77
77
  });
78
78
  })
79
79
  .catch((e) => {
80
- return reject(assistant.errorify(`Failed to save feedback: ${e.message}`, {code: 500, sentry: true, send: false, log: true}));
80
+ return reject(assistant.errorify(`Failed to save feedback: ${e.message}`, {code: 500, sentry: true}));
81
81
  })
82
82
  })
83
83
  .catch((e) => {
84
- return reject(assistant.errorify(`Failed to get app: ${e.message}`, {code: 500, sentry: true, send: false, log: true}));
84
+ return reject(assistant.errorify(`Failed to get app: ${e.message}`, {code: 500, sentry: true}));
85
85
  })
86
86
 
87
87
  })
@@ -28,7 +28,7 @@ Module.prototype.main = function () {
28
28
 
29
29
  // Check if the file exists
30
30
  if (!jetpack.exists(resolvedPath)) {
31
- return reject(assistant.errorify(`Defaults file at ${resolvedPath} does not exist, please add it manually.`, {code: 500, sentry: true, send: false, log: true}));
31
+ return reject(assistant.errorify(`Defaults file at ${resolvedPath} does not exist, please add it manually.`, {code: 500, sentry: true}));
32
32
  }
33
33
 
34
34
  // Load the file
@@ -40,7 +40,7 @@ Module.prototype.main = function () {
40
40
 
41
41
  return resolve({data: powertools.defaults(settings, combined)});
42
42
  } catch (e) {
43
- return reject(assistant.errorify(`Unable to load file at ${resolvedPath}: ${e}`, {code: 500, sentry: true, send: false, log: true}));
43
+ return reject(assistant.errorify(`Unable to load file at ${resolvedPath}: ${e}`, {code: 500, sentry: true}));
44
44
  }
45
45
 
46
46
  })
@@ -273,7 +273,7 @@ Module.prototype.resolveUser = function (options) {
273
273
 
274
274
  if (options.uid) {
275
275
  if (options.adminRequired && !options.admin) {
276
- user = self.assistant.errorify('Admin required', {code: 401, sentry: false, send: false, log: false});
276
+ user = self.assistant.errorify('Admin required', {code: 401});
277
277
  } else {
278
278
  await self.libraries.admin.firestore().doc(`users/${options.uid}`)
279
279
  .get()
@@ -282,11 +282,11 @@ Module.prototype.resolveUser = function (options) {
282
282
  if (data) {
283
283
  user = data;
284
284
  } else {
285
- user = self.assistant.errorify(`User does not exist: ${options.uid}`, {code: 400, sentry: false, send: false, log: false});
285
+ user = self.assistant.errorify(`User does not exist: ${options.uid}`, {code: 400});
286
286
  }
287
287
  })
288
288
  .catch(function (e) {
289
- user = self.assistant.errorify(e, {code: 500, sentry: false, send: false, log: false});
289
+ user = self.assistant.errorify(e, {code: 500});
290
290
  })
291
291
  }
292
292
  } else if (self.payload.user.authenticated) {
@@ -298,7 +298,7 @@ Module.prototype.resolveUser = function (options) {
298
298
  if (user instanceof Error) {
299
299
  return reject(user);
300
300
  } else if (!user) {
301
- return reject(self.assistant.errorify('Unable to resolve user', {code: 500, sentry: false, send: false, log: false}));
301
+ return reject(self.assistant.errorify('Unable to resolve user', {code: 500}));
302
302
  } else {
303
303
  return resolve(user);
304
304
  }
@@ -105,7 +105,7 @@ Module.prototype.clearFirestore = function() {
105
105
  assistant.log(`cron/daily/reset-usage() [firestore]: Resetting metrics`, metrics);
106
106
 
107
107
  if (metrics instanceof Error) {
108
- return reject(assistant.errorify(`Failed to check providers: ${metrics}`, {code: 500, sentry: false, send: false, log: false}));
108
+ return reject(assistant.errorify(`Failed to check providers: ${metrics}`, {code: 500}));
109
109
  }
110
110
 
111
111
  // Reset all metrics with for loop of metrics
@@ -140,7 +140,7 @@ Module.prototype.clearFirestore = function() {
140
140
  assistant.log(`cron/daily/reset-usage() [firestore]: Reset ${metric} for ${doc.id} (${original} -> 0)`);
141
141
  })
142
142
  .catch(e => {
143
- assistant.errorify(`Error resetting ${metric} for ${doc.id}: ${e}`, {sentry: false, send: false, log: true});
143
+ assistant.errorify(`Error resetting ${metric} for ${doc.id}: ${e}`, {code: 500, log: true});
144
144
  })
145
145
  }
146
146
 
@@ -159,18 +159,42 @@ Module.prototype.clearFirestore = function() {
159
159
  assistant.log(`cron/daily/reset-usage() [firestore]: Reset ${metric} for all users complete!`);
160
160
  })
161
161
  .catch(e => {
162
- assistant.errorify(`Error resetting ${metric} for all users: ${e}`, {sentry: false, send: false, log: true});
162
+ assistant.errorify(`Error resetting ${metric} for all users: ${e}`, {code: 500, log: true});
163
163
  })
164
164
  }
165
165
 
166
166
  // Clear temporary/usage in firestore by deleting the doc
167
- await libraries.admin.firestore().doc(`temporary/usage`).delete()
168
- .then(r => {
169
- assistant.log(`cron/daily/reset-usage() [firestore]: Deleted temporary/usage`);
170
- })
171
- .catch(e => {
172
- assistant.errorify(`Error deleting temporary/usage: ${e}`, {sentry: false, send: false, log: true});
167
+ admin.firestore().collection('temporary').listDocuments()
168
+ .then((snap) => {
169
+ const chunks = []
170
+ for (let i = 0; i < snap.length; i += 500) {
171
+ chunks.push(snap.slice(i, i + 500))
172
+ }
173
+
174
+ // Delete in chunks
175
+ for (const chunk of chunks) {
176
+ // Get a new write batch
177
+ const batch = admin.firestore().batch()
178
+
179
+ chunk.map((doc) => {
180
+ assistant.log('Deleting', doc.id);
181
+
182
+ batch.delete(doc);
183
+ });
184
+
185
+ batch.commit()
186
+ .catch((e) => {
187
+ assistant.error('Error committing batch', e);
188
+ });
189
+ }
173
190
  })
191
+ // await libraries.admin.firestore().doc(`temporary/usage`).delete()
192
+ // .then(r => {
193
+ // assistant.log(`cron/daily/reset-usage() [firestore]: Deleted temporary/usage`);
194
+ // })
195
+ // .catch(e => {
196
+ // assistant.errorify(`Error deleting temporary/usage: ${e}`, {code: 500, log: true});
197
+ // })
174
198
 
175
199
  return resolve();
176
200
  });
@@ -50,7 +50,7 @@ Module.prototype.main = function() {
50
50
  assistant.log(`cron/daily(): Job ${jobName} completed...`);
51
51
  })
52
52
  .catch(e => {
53
- assistant.errorify(`Error executing ${jobName}: ${e}`, {sentry: true, send: false, log: true});
53
+ assistant.errorify(`Error executing ${jobName}: ${e}`, {code: 500, sentry: true});
54
54
  caught = e;
55
55
  })
56
56
  }
@@ -30,8 +30,16 @@ Module.prototype.main = function () {
30
30
 
31
31
  assistant.log(`Request: ${user.uid}`, user, context);
32
32
 
33
+ // Calculate user age before the poll
33
34
  const ageInSeconds = (Date.now() - new Date(user.metadata.creationTime)) / 1000;
34
35
 
36
+ // If user is not new, skip auth-on-create handler
37
+ if (ageInSeconds >= MAX_AGE) {
38
+ assistant.log(`Skipping because ${user.uid} is NOT NEW (age=${ageInSeconds}):`, existingUser);
39
+
40
+ return resolve(self);
41
+ }
42
+
35
43
  // Check if exists already
36
44
  let existingUser;
37
45
  await powertools.poll(async () => {
@@ -42,25 +50,19 @@ Module.prototype.main = function () {
42
50
 
43
51
  assistant.log(`Polling for existing user ${user.uid}...`, existingUser);
44
52
 
45
- return existingUser && !(existingUser instanceof Error);
53
+ if (existingUser instanceof Error) {
54
+ return false;
55
+ }
56
+
57
+ return existingUser;
46
58
  }, {interval: 1000, timeout: 30000})
47
59
  .catch(e => {
48
60
  assistant.error(`Timeout for existing user expired`, e);
49
61
  });
50
62
 
63
+ // Log existing user
51
64
  assistant.log(`Existing user ${user.uid} found (age=${ageInSeconds}):`, existingUser);
52
65
 
53
- if (ageInSeconds >= MAX_AGE) {
54
- existingUser = new Error(`User is not new (age=${ageInSeconds}).`);
55
- }
56
-
57
- // If user already exists, skip auth-on-create handler
58
- if (existingUser instanceof Error) {
59
- assistant.error(`Failed to get existing user ${user.uid}:`, existingUser);
60
-
61
- return reject(existingUser);
62
- }
63
-
64
66
  // Build user object
65
67
  let newUser = self.Manager.User().properties;
66
68
 
@@ -353,18 +353,28 @@ BackendAssistant.prototype.errorify = function (e, options) {
353
353
 
354
354
  // Set options
355
355
  options = options || {};
356
+
357
+ // Code: default to 500, or else use the user's option
356
358
  options.code = typeof options.code === 'undefined'
357
359
  ? 500
358
360
  : options.code;
359
- options.log = typeof options.log === 'undefined'
360
- ? true
361
- : options.log;
361
+
362
+ // Sentry: default to false, or else use the user's option
362
363
  options.sentry = typeof options.sentry === 'undefined'
363
- ? true
364
+ ? false
364
365
  : options.sentry;
366
+
367
+ // Log: default to sentry, or else use the user's option
368
+ options.log = typeof options.log === 'undefined'
369
+ ? options.sentry
370
+ : options.log;
371
+
372
+ // Send: default to false, or else use the user's option
365
373
  options.send = typeof options.send === 'undefined'
366
- ? true
374
+ ? false
367
375
  : options.send;
376
+
377
+ // Stack: default to false, or else use the user's option
368
378
  options.stack = typeof options.stack === 'undefined'
369
379
  ? false
370
380
  : options.stack;
@@ -392,7 +402,7 @@ BackendAssistant.prototype.errorify = function (e, options) {
392
402
  }
393
403
 
394
404
  // Quit and respond to the request
395
- if (options.send && res && res.status) {
405
+ if (options.send && res?.status) {
396
406
  let sendable = newError?.stack && options.stack
397
407
  ? newError?.stack
398
408
  : newError?.message;
@@ -452,7 +462,9 @@ BackendAssistant.prototype.respond = function(response, options) {
452
462
  response instanceof Error
453
463
  || isErrorCode
454
464
  ) {
455
- options.code = !isErrorCode ? undefined : options.code;
465
+ options.code = isErrorCode ? options.code : undefined;
466
+ options.send = true;
467
+
456
468
  return self.errorify(response, options);
457
469
  }
458
470
 
@@ -596,7 +608,7 @@ BackendAssistant.prototype.authenticate = async function (options) {
596
608
  return _resolve(self.request.user);
597
609
  }
598
610
  } else if (options.apiKey || data.apiKey) {
599
- const apiKey = apiKey || data.apiKey;
611
+ const apiKey = options.apiKey || data.apiKey;
600
612
  self.log('Found "options.apiKey"', apiKey, logOptions);
601
613
 
602
614
  if (apiKey.includes('test')) {
@@ -14,7 +14,7 @@ function Middleware(m, req, res) {
14
14
  self.res = res;
15
15
  }
16
16
 
17
- Middleware.prototype.run = function (library, options) {
17
+ Middleware.prototype.run = function (libPath, options) {
18
18
  const self = this;
19
19
  const Manager = self.Manager;
20
20
  const req = self.req;
@@ -39,14 +39,15 @@ Middleware.prototype.run = function (library, options) {
39
39
  // Log
40
40
  assistant.log(`Middleware.process(): Request (${geolocation.ip} @ ${geolocation.country}, ${geolocation.region}, ${geolocation.city})`, JSON.stringify(data));
41
41
 
42
- const basePath = path.resolve(process.cwd(), `methods/${library.replace('.js', '')}`);
42
+ const basePath = path.resolve(process.cwd(), `methods/${libPath.replace('.js', '')}`);
43
+ let library;
43
44
 
44
45
  // Load library
45
46
  try {
46
- library = path.resolve(basePath, `index.js`);
47
- library = new (require(library))();
47
+ libPath = path.resolve(basePath, `index.js`);
48
+ library = new (require(libPath))();
48
49
  } catch (e) {
49
- return assistant.errorify(`Unable to load library @ (${library}): ${e.message}`, {sentry: true, send: true, log: true});
50
+ return assistant.respond(new Error(`Unable to load library @ (${libPath}): ${e.message}`), {code: 500, sentry: true});
50
51
  }
51
52
 
52
53
  // Setup user
@@ -82,7 +83,7 @@ Middleware.prototype.run = function (library, options) {
82
83
  try {
83
84
  assistant.settings = Manager.Settings().resolve(assistant, options.schema, data);
84
85
  } catch (e) {
85
- return assistant.errorify(`Unable to resolve schema ${options.schema}: ${e.message}`, {code: e.code, sentry: true, send: true, log: true});
86
+ return assistant.respond(new Error(`Unable to resolve schema ${options.schema}: ${e.message}`), {code: 500, sentry: true});
86
87
  }
87
88
 
88
89
  assistant.log(`Middleware.process(): Resolved settings with schema ${options.schema}`, JSON.stringify(assistant.settings));
@@ -96,14 +97,11 @@ Middleware.prototype.run = function (library, options) {
96
97
 
97
98
  // Run library
98
99
  library.main(assistant, req, res)
99
- // .then(result => {
100
- // return res.status(200).json(result);
101
- // })
102
100
  .catch(e => {
103
- return assistant.errorify(e, {sentry: true, send: true, log: true});
101
+ return assistant.respond(e, {code: e.code, sentry: true});
104
102
  });
105
103
  } catch (e) {
106
- return assistant.errorify(e, {sentry: true, send: true, log: true});
104
+ return assistant.respond(e, {code: e.code, sentry: true});
107
105
  }
108
106
  });
109
107
  };
@@ -26,7 +26,7 @@ Settings.prototype.resolve = function (assistant, schema, settings) {
26
26
 
27
27
  // Throw error if there is no schema
28
28
  if (typeof schema === 'undefined') {
29
- throw assistant.errorify(`Schema is undefined`, {code: 500, sentry: false, send: false, log: false});
29
+ throw assistant.errorify(`Schema is undefined`, {code: 500});
30
30
  }
31
31
 
32
32
  // Reset settings
@@ -57,7 +57,7 @@ Settings.prototype.resolve = function (assistant, schema, settings) {
57
57
  // Check if the required key is missing
58
58
  if (typeof _.get(settings, settingsKey, undefined) === 'undefined') {
59
59
  // Handle the missing required key as needed
60
- throw assistant.errorify(`Required key '${settingsKey}' is missing in settings`, {code: 400, sentry: false, send: false, log: false});
60
+ throw assistant.errorify(`Required key '${settingsKey}' is missing in settings`, {code: 400});
61
61
  }
62
62
  });
63
63
 
@@ -82,11 +82,11 @@ Usage.prototype.init = function (assistant, options) {
82
82
 
83
83
  if (options.unauthenticatedMode === 'firestore') {
84
84
  // TODO: Make it request using .where() query so it doesnt use a read if it doesnt have to
85
- foundUsage = await Manager.libraries.admin.firestore().doc(`temporary/usage`)
85
+ foundUsage = await Manager.libraries.admin.firestore().doc(`temporary/${self.key}`)
86
86
  .get()
87
87
  .then((r) => _.get(r.data(), self.key))
88
88
  .catch((e) => {
89
- assistant.errorify(`Usage.init(): Error fetching usage data: ${e}`, {sentry: true, send: false, log: true});
89
+ assistant.errorify(`Usage.init(): Error fetching usage data: ${e}`, {code: 500, sentry: true});
90
90
  });
91
91
  } else {
92
92
  foundUsage = self.storage.get(`${self.paths.user}.usage`, {}).value();
@@ -113,7 +113,7 @@ Usage.prototype.init = function (assistant, options) {
113
113
  self.storage.set(`${self.paths.app}.lastFetched`, new Date().toISOString()).write();
114
114
  })
115
115
  .catch(e => {
116
- assistant.errorify(`Usage.init(): Error fetching app data: ${e}`, {sentry: true, send: false, log: true});
116
+ assistant.errorify(`Usage.init(): Error fetching app data: ${e}`, {code: 500, sentry: true});
117
117
  })
118
118
  }
119
119
 
@@ -171,14 +171,14 @@ Usage.prototype.validate = function (path, options) {
171
171
  // If the captcha is valid, resolve
172
172
  if (!captchaResult || captchaResult instanceof Error || !captchaResult.success) {
173
173
  return reject(
174
- assistant.errorify(`Captcha verification failed.`, {code: 400, sentry: false, send: false, log: false})
174
+ assistant.errorify(`Captcha verification failed.`, {code: 400})
175
175
  );
176
176
  }
177
177
  }
178
178
 
179
179
  // Otherwise, they are over the limit, reject
180
180
  return reject(
181
- assistant.errorify(`You have exceeded your ${path} usage limit of ${period}/${allowed}.`, {code: 429, sentry: false, send: false, log: false})
181
+ assistant.errorify(`You have exceeded your ${path} usage limit of ${period}/${allowed}.`, {code: 429})
182
182
  );
183
183
  });
184
184
  };
@@ -274,7 +274,7 @@ Usage.prototype.update = function () {
274
274
  // Write self.user to firestore or local if no user or if key is set
275
275
  if (self.useUnauthenticatedStorage) {
276
276
  if (self.options.unauthenticatedMode === 'firestore') {
277
- Manager.libraries.admin.firestore().doc(`temporary/usage`)
277
+ Manager.libraries.admin.firestore().doc(`temporary/${self.key}`)
278
278
  .set({
279
279
  [`${self.key}`]: self.user.usage,
280
280
  }, {merge: true})
@@ -284,7 +284,7 @@ Usage.prototype.update = function () {
284
284
  return resolve(self.user.usage);
285
285
  })
286
286
  .catch(e => {
287
- return reject(assistant.errorify(e, {sentry: true, send: false, log: false}));
287
+ return reject(assistant.errorify(e, {code: 500, sentry: true}));
288
288
  });
289
289
  } else {
290
290
  self.storage.set(`${self.paths.user}.usage`, self.user.usage).write();
@@ -304,7 +304,7 @@ Usage.prototype.update = function () {
304
304
  return resolve(self.user.usage);
305
305
  })
306
306
  .catch(e => {
307
- return reject(assistant.errorify(e, {sentry: true, send: false, log: false}));
307
+ return reject(assistant.errorify(e, {code: 500, sentry: true}));
308
308
  });
309
309
  }
310
310
  });
@@ -465,7 +465,7 @@ Manager.prototype._process = function (mod, options) {
465
465
  function _reject(e, log) {
466
466
  if (log) {
467
467
  // self.assistant.error(e);
468
- mod.assistant.errorify(e, {code: 500, sentry: true, send: false, log: true});
468
+ mod.assistant.respond(e, {code: 500, sentry: true});
469
469
  }
470
470
  // res.status(500).send(e.message);
471
471
  return resolve()
@@ -60,6 +60,7 @@ OpenAI.prototype.request = function (options) {
60
60
  options.model = typeof options.model === 'undefined' ? 'gpt-3.5-turbo' : options.model;
61
61
  options.timeout = typeof options.timeout === 'undefined' ? 120000 : options.timeout;
62
62
  options.moderate = typeof options.moderate === 'undefined' ? true : options.moderate;
63
+ options.log = typeof options.log === 'undefined' ? false : options.log;
63
64
  options.user = options.user || assistant.getUser();
64
65
 
65
66
  options.prompt = options.prompt || {};
@@ -80,17 +81,28 @@ OpenAI.prototype.request = function (options) {
80
81
  options.temperature = typeof options.temperature === 'undefined' ? 0.7 : options.temperature;
81
82
  options.maxTokens = typeof options.maxTokens === 'undefined' ? 512 : options.maxTokens;
82
83
 
83
- assistant.log('callOpenAI(): Starting', self.key);
84
- assistant.log('callOpenAI(): Starting', options);
84
+ function _log() {
85
+ if (!options.log) {
86
+ return;
87
+ }
88
+
89
+ _log('callOpenAI():', ...arguments);
90
+ }
85
91
 
86
92
  function _load(input) {
93
+ // console.log('*** input!!!', input.content.slice(0, 50), input.path);
94
+ // console.log('*** input.content', input.content.slice(0, 50));
95
+ // console.log('*** input.path', input.path);
87
96
  return powertools.template(
88
- input.content || jetpack.read(input.path),
97
+ input.path ? jetpack.read(input.path) : input.content,
89
98
  input.settings,
90
99
  )
91
100
  .trim();
92
101
  }
93
102
 
103
+ _log('Starting', self.key);
104
+ _log('Starting', options);
105
+
94
106
  // Load prompt
95
107
  const prompt = _load(options.prompt);
96
108
  const message = _load(options.message);
@@ -99,9 +111,9 @@ OpenAI.prototype.request = function (options) {
99
111
  ? { type: 'json_object' }
100
112
  : undefined;
101
113
 
102
- assistant.log('callOpenAI(): Prompt', prompt);
103
- assistant.log('callOpenAI(): Message', message);
104
- assistant.log('callOpenAI(): User', user);
114
+ _log('Prompt', prompt);
115
+ _log('Message', message);
116
+ _log('User', user);
105
117
 
106
118
  function _request(mode, options) {
107
119
  return new Promise(async function(resolve, reject) {
@@ -132,7 +144,7 @@ OpenAI.prototype.request = function (options) {
132
144
  });
133
145
 
134
146
  // Log message
135
- assistant.log('callOpenAI(): Messages', options.history.messages);
147
+ _log('Messages', options.history.messages);
136
148
 
137
149
  request.body = {
138
150
  model: options.model,
@@ -178,17 +190,14 @@ OpenAI.prototype.request = function (options) {
178
190
  if (options.moderate) {
179
191
  moderation = await _request('moderation', options)
180
192
  .then(async (r) => {
181
- assistant.log('callOpenAI(): Moderated', r);
182
-
183
- // Save moderation
184
- self.moderation = r;
193
+ _log('Moderated', r);
185
194
 
186
195
  return r;
187
196
  })
188
197
  .catch((e) => e);
189
198
 
190
199
  if (moderation.flagged) {
191
- return reject(assistant.errorify(`This request is inappropriate`, {code: 400, sentry: false, send: false, log: false}));
200
+ return reject(assistant.errorify(`This request is inappropriate`, {code: 400}));
192
201
  }
193
202
  }
194
203
 
@@ -204,7 +213,7 @@ OpenAI.prototype.request = function (options) {
204
213
  moderation: moderation,
205
214
  })
206
215
  } catch (e) {
207
- assistant.warn('callOpenAI(): Error parsing response', r, e);
216
+ assistant.warn('Error parsing response', r, e);
208
217
 
209
218
  return reject(e);
210
219
  }