backend-manager 3.2.6 → 3.2.8

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 (38) hide show
  1. package/package.json +1 -1
  2. package/src/cli/cli.js +17 -0
  3. package/src/manager/functions/core/actions/api/admin/backup.js +3 -2
  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 +3 -3
  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 +6 -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 -7
  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 +4 -4
  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 +4 -4
  33. package/src/manager/helpers/assistant.js +4 -3
  34. package/src/manager/helpers/middleware.js +7 -3
  35. package/src/manager/helpers/settings.js +28 -4
  36. package/src/manager/helpers/usage.js +2 -2
  37. package/templates/public/404.html +26 -0
  38. package/templates/public/index.html +24 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "backend-manager",
3
- "version": "3.2.6",
3
+ "version": "3.2.8",
4
4
  "description": "Quick tools for developing Firebase functions",
5
5
  "main": "src/manager/index.js",
6
6
  "bin": {
package/src/cli/cli.js CHANGED
@@ -17,6 +17,7 @@ const { spawn, child, exec, fork } = require('child_process');
17
17
  const JSON5 = require('json5');
18
18
  const fetch = require('wonderful-fetch');
19
19
  const argv = require('yargs').argv;
20
+ const powertools = require('node-powertools');
20
21
 
21
22
  // function parseArgumentsIntoOptions(rawArgs) {
22
23
  // const args = arg(
@@ -558,6 +559,22 @@ Main.prototype.setup = async function () {
558
559
  return true;
559
560
  }, NOFIX);
560
561
 
562
+ await self.test('create public .html files', function () {
563
+ const options = {url: self.bemConfigJSON.brand.url}
564
+ // index.html
565
+ const templateIndex = jetpack.read(path.resolve(`${__dirname}/../../templates/public/index.html`));
566
+ jetpack.write(`${self.firebaseProjectPath}/public/index.html`,
567
+ powertools.template(templateIndex, options)
568
+ )
569
+
570
+ // 404.html
571
+ const template404 = jetpack.read(path.resolve(`${__dirname}/../../templates/public/404.html`));
572
+ jetpack.write(`${self.firebaseProjectPath}/public/404.html`,
573
+ powertools.template(template404, options)
574
+ )
575
+ return true;
576
+ }, NOFIX);
577
+
561
578
  // await self.test('add roles/datastore.importExportAdmin', function () {
562
579
  // const result = await cmd_iamImportExport(self);
563
580
  // console.log('---result', result);
@@ -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.meta.environment === 'production') {
22
- return reject(assistant.errorify(`Admin required.`, {code: 401, sentry: false, send: false, log: false}).error)
22
+ return reject(assistant.errorify(`Admin required.`, {code: 401, sentry: false, send: false, log: false}));
23
23
  }
24
24
 
25
25
  // https://googleapis.dev/nodejs/firestore/latest/v1.FirestoreAdminClient.html#exportDocuments
@@ -61,7 +61,8 @@ Module.prototype.main = function () {
61
61
  })
62
62
  .catch(async (e) => {
63
63
  await self._setMetaStats(e);
64
- return reject(assistant.errorify(e, {code: 500, sentry: false, send: false, log: true}).error)
64
+
65
+ return reject(assistant.errorify(e, {code: 500, sentry: false, send: false, log: true}));
65
66
  });
66
67
 
67
68
  });
@@ -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}).error)
21
+ return reject(assistant.errorify(`Admin required.`, {code: 401, sentry: false, send: false, log: false}));
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}).error)
48
+ return reject(assistant.errorify(`Failed to post: ${finalPost}`, {code: 500, sentry: false, send: false, log: false}));
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}).error)
71
+ return reject(assistant.errorify(`Failed to post: ${e}`, {code: 500, sentry: false, send: false, log: false}));
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.meta.environment === 'production') {
16
- return reject(assistant.errorify(`Admin required.`, {code: 401, sentry: false, send: false, log: false}).error)
16
+ return reject(assistant.errorify(`Admin required.`, {code: 401, sentry: false, send: false, log: false}));
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}).error)
21
+ return reject(assistant.errorify(`Missing parameter {id}`, {code: 400, sentry: false, send: false, log: false}));
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}).error)
30
+ return reject(assistant.errorify(e, {code: 400, sentry: false, send: false, log: false}));
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}).error)
19
+ return reject(assistant.errorify(`Admin required.`, {code: 401, sentry: false, send: false, log: false}));
20
20
  } else if (!payload.data.payload.path) {
21
- return reject(assistant.errorify(`<path> parameter required`, {code: 400, sentry: false, send: false, log: false}).error)
21
+ return reject(assistant.errorify(`<path> parameter required`, {code: 400, sentry: false, send: false, log: false}));
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}).error)
20
+ return reject(assistant.errorify(`Admin required.`, {code: 401, sentry: false, send: false, log: false}));
21
21
  } else if (!payload.data.payload.path) {
22
- return reject(assistant.errorify(`<path> parameter required`, {code: 400, sentry: false, send: false, log: false}).error);
22
+ return reject(assistant.errorify(`<path> parameter required`, {code: 400, sentry: false, send: false, log: false}));
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}).error)
32
+ return reject(assistant.errorify(e, {code: 500, sentry: false, send: false, log: false}));
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}).error)
18
+ return reject(assistant.errorify(`Admin required.`, {code: 401, sentry: false, send: false, log: false}));
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}).error)
38
+ return reject(assistant.errorify(e, {code: 500, sentry: false, send: false, log: false}));
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}).error)
19
+ return reject(assistant.errorify(`Admin required.`, {code: 401, sentry: false, send: false, log: false}));
20
20
  } else if (!payload.data.payload.path) {
21
- return reject(assistant.errorify(`<path> parameter required`, {code: 400, sentry: false, send: false, log: false}).error)
21
+ return reject(assistant.errorify(`<path> parameter required`, {code: 400, sentry: false, send: false, log: false}));
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}).error)
31
+ return reject(assistant.errorify(e, {code: 500, sentry: false, send: false, log: false}));
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}).error)
22
+ return reject(assistant.errorify(`Admin required.`, {code: 401, sentry: false, send: false, log: false}));
23
23
  } else if (!payload.data.payload.path) {
24
- return reject(assistant.errorify(`Path parameter required.`, {code: 400, sentry: false, send: false, log: false}).error)
24
+ return reject(assistant.errorify(`Path parameter required.`, {code: 400, sentry: false, send: false, log: false}));
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}).error)
40
+ return reject(assistant.errorify(e, {code: 500, sentry: false, send: false, log: false}));
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}).error)
20
+ return reject(assistant.errorify(`Admin required.`, {code: 401, sentry: false, send: false, log: false}));
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}).error)
37
+ return reject(assistant.errorify(data, {code: 500, sentry: false, send: false, log: false}));
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}).error)
50
+ return reject(assistant.errorify(data, {code: 500, sentry: false, send: false, log: false}));
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}).error)
56
+ return reject(assistant.errorify(`Failed to get: ${e}`, {code: 500, sentry: false, send: false, log: false}));
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}).error)
18
+ return reject(assistant.errorify(`Admin required.`, {code: 401, sentry: false, send: false, log: false}));
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}).error)
23
+ return reject(assistant.errorify(`No productId`, {code: 400, sentry: false, send: false, log: false}));
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}).error)
48
+ return reject(assistant.errorify(`Payment processor @ "${processorPath}" failed: ${e}`, {code: 400, sentry: true, send: false, log: false}));
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, sentry: false, send: false, 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}).error)
46
+ return reject(assistant.errorify(`Admin required.`, {code: 401, sentry: false, send: false, log: false}));
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}).error)
50
+ return reject(assistant.errorify(`Parameters <title> and <body> required`, {code: 400, sentry: true, send: false, log: false}));
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}).error)
58
+ return reject(assistant.errorify(`Failed to send notification: ${e}`, {code: 400, sentry: true, send: false, log: false}));
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.meta.environment === 'production') {
18
- return reject(assistant.errorify(`Admin required.`, {code: 401, sentry: false, send: false, log: false}).error)
18
+ return reject(assistant.errorify(`Admin required.`, {code: 401, sentry: false, send: false, log: false}));
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}).error)
119
+ return reject(assistant.errorify(e, {code: 500, sentry: false, send: false, log: false}));
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}).error)
47
+ return reject(assistant.errorify(`The firebaseApiKey parameter is required.`, {code: 400, sentry: false, send: false, log: false}));
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}`, {sentry: true, send: false, log: true});
95
95
  payload.response.data[provider.name] = false;
96
96
  }
97
97
  })
@@ -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}).error)
147
+ return reject(assistant.errorify(`Failed to check providers: ${e}`, {code: 500, sentry: false, send: false, log: false}));
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}).error)
23
+ return reject(assistant.errorify(`You must provide a name to hash for uuid v5.`, {code: 400, sentry: false, send: false, log: false}));
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}).error)
30
+ return reject(assistant.errorify(`v${payload.data.payload.version} is not a valid version.`, {code: 400, sentry: false, send: false, log: false}));
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}).error)
35
+ return reject(assistant.errorify(`Parameter {id} is required.`, {code: 400, sentry: false, send: false, log: false}));
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}).error)
37
+ return reject(assistant.errorify(`Parameter {email} is required.`, {code: 400, sentry: false, send: false, log: false}));
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}).error)
49
+ return reject(assistant.errorify(`${payload.data.payload.id} is not a valid email ID.`, {code: 400, sentry: false, send: false, log: false}));
50
50
  }
51
51
 
52
52
  const storage = Manager.storage({temporary: true});
@@ -70,7 +70,8 @@ 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, sentry: false, send: false, log: true});
74
+
74
75
  return resolve({data: {success: true}});
75
76
  }
76
77
 
@@ -99,7 +100,7 @@ Module.prototype.main = function () {
99
100
  });
100
101
  })
101
102
  .catch(e => {
102
- return reject(assistant.errorify(`Error sending email: ${e}`, {code: 500, sentry: true, send: false, log: false}).error)
103
+ return reject(assistant.errorify(`Error sending email: ${e}`, {code: 500, sentry: true, send: false, log: false}));
103
104
  });
104
105
 
105
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}).error)
18
+ return reject(assistant.errorify(`Admin required.`, {code: 401, sentry: false, send: false, log: false}));
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}).error)
86
+ return reject(assistant.errorify(createdInvoice, {code: 400, sentry: false, send: false, log: false}));
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}).error)
107
+ return reject(assistant.errorify(sentInvoice, {code: 500, sentry: false, send: false, log: false}));
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}).error
35
+ error = assistant.errorify(`Failed to create custom token: ${e}`, {code: 500, sentry: false, send: false, log: false});
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, sentry: false, send: false, log: true});
40
40
  })
41
41
 
42
42
  if (error) {
@@ -93,15 +93,11 @@ 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}).error)
96
+ return reject(assistant.errorify(`Error fetching app details: ${e}`, {code: 500, sentry: false, send: false, log: false}));
97
97
  })
98
98
 
99
-
100
-
101
-
102
99
  });
103
100
 
104
101
  };
105
102
 
106
-
107
103
  module.exports = Module;
@@ -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}).error)
15
+ return reject(assistant.errorify(`Admin required.`, {code: 401, sentry: false, send: false, log: false}));
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}).error)
15
+ return reject(assistant.errorify(`Admin required.`, {code: 401, sentry: false, send: false, log: false}));
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}).error)
22
+ return reject(assistant.errorify(payload.data.payload.response || 'Unknown error message provided', {code: payload.data.payload.status, sentry: false, send: false, log: false}));
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}).error)
22
+ return reject(assistant.errorify(`Failed to create custom token: ${e}`, {code: 400, sentry: false, send: false, log: false}));
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}).error)
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}));
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}).error)
57
+ return reject(assistant.errorify(`Failed to delete user: ${e}`, {code: 400, sentry: false, send: false, log: false}));
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}).error)
33
+ return reject(assistant.errorify(`Session query error: ${e}`, {code: 500, sentry: false, send: false, log: false}));
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}).error)
42
+ return reject(assistant.errorify(`Failed to generate keys: ${e}`, {code: 500, sentry: true, send: false, log: false}));
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}).error)
40
+ return reject(assistant.errorify(`Failed to sign out of all sessions: ${e}`, {code: 500, sentry: false, send: false, log: false}));
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}).error)
43
+ return reject(assistant.errorify(`Failed to sign out of all sessions: ${e}`, {code: 500, sentry: false, send: false, log: false}));
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, send: false, log: true});
112
112
 
113
113
  return reject(e);
114
114
  })
@@ -26,7 +26,7 @@ Module.prototype.main = function () {
26
26
  const usage = await Manager.Usage().init(assistant, {log: true, key: ip});
27
27
 
28
28
  if (authUser instanceof Error) {
29
- return reject(assistant.errorify(`Failed to get auth user: ${authUser}`, {code: 500, sentry: false, send: false, log: false}).error)
29
+ return reject(assistant.errorify(`Failed to get auth user: ${authUser}`, {code: 500, sentry: false, send: false, log: false}));
30
30
  }
31
31
 
32
32
  // Age in seconds
@@ -34,7 +34,7 @@ Module.prototype.main = function () {
34
34
 
35
35
  // If the user is not new, reject
36
36
  if (ageInSeconds >= MAX_AGE) {
37
- return reject(assistant.errorify(`User is not new.`, {code: 400, sentry: false, send: false, log: false}).error)
37
+ return reject(assistant.errorify(`User is not new.`, {code: 400, sentry: false, send: false, log: false}));
38
38
  }
39
39
 
40
40
  // Check if IP has signed up too many times
@@ -86,7 +86,7 @@ Module.prototype.main = function () {
86
86
  });
87
87
 
88
88
  // Reject
89
- return reject(assistant.errorify(`Too many signups from this IP (${ip}).`, {code: 429, sentry: false, send: false, log: false}).error)
89
+ return reject(assistant.errorify(`Too many signups from this IP (${ip}).`, {code: 429, sentry: false, send: false, log: false}));
90
90
  }
91
91
 
92
92
  // Increment signups
@@ -121,7 +121,7 @@ Module.prototype.main = function () {
121
121
  return resolve({data: result});
122
122
  })
123
123
  .catch(function (e) {
124
- return reject(assistant.errorify(`Failed to sign up: ${e}`, {code: 500, sentry: false, send: false, log: false}).error)
124
+ return reject(assistant.errorify(`Failed to sign up: ${e}`, {code: 500, sentry: false, send: false, log: false}));
125
125
  })
126
126
  })
127
127
  .catch(e => {
@@ -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}).error)
80
+ return reject(assistant.errorify(`Failed to save feedback: ${e.message}`, {code: 500, sentry: true, send: false, log: 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}).error)
84
+ return reject(assistant.errorify(`Failed to get app: ${e.message}`, {code: 500, sentry: true, send: false, log: 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}).error);
31
+ return reject(assistant.errorify(`Defaults file at ${resolvedPath} does not exist, please add it manually.`, {code: 500, sentry: true, send: false, log: 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}).error);
43
+ return reject(assistant.errorify(`Unable to load file at ${resolvedPath}: ${e}`, {code: 500, sentry: true, send: false, log: 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}).error;
276
+ user = self.assistant.errorify('Admin required', {code: 401, sentry: false, send: false, log: false});
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}).error;
285
+ user = self.assistant.errorify(`User does not exist: ${options.uid}`, {code: 400, sentry: false, send: false, log: false});
286
286
  }
287
287
  })
288
288
  .catch(function (e) {
289
- user = self.assistant.errorify(e, {code: 500, sentry: false, send: false, log: false}).error;
289
+ user = self.assistant.errorify(e, {code: 500, sentry: false, send: false, log: false});
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}).error);
301
+ return reject(self.assistant.errorify('Unable to resolve user', {code: 500, sentry: false, send: false, log: false}));
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}).error)
108
+ return reject(assistant.errorify(`Failed to check providers: ${metrics}`, {code: 500, sentry: false, send: false, log: false}));
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}`, {sentry: false, send: false, log: true});
144
144
  })
145
145
  }
146
146
 
@@ -159,7 +159,7 @@ 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}`, {sentry: false, send: false, log: true});
163
163
  })
164
164
  }
165
165
 
@@ -169,7 +169,7 @@ Module.prototype.clearFirestore = function() {
169
169
  assistant.log(`cron/daily/reset-usage() [firestore]: Deleted temporary/usage`);
170
170
  })
171
171
  .catch(e => {
172
- assistant.errorify(`Error deleting temporary/usage: ${e}`, {sentry: false, send: false, log: true})
172
+ assistant.errorify(`Error deleting temporary/usage: ${e}`, {sentry: false, send: false, log: true});
173
173
  })
174
174
 
175
175
  return resolve();
@@ -395,9 +395,10 @@ BackendAssistant.prototype.errorify = function (e, options) {
395
395
  .send(sendable);
396
396
  }
397
397
 
398
- return {
399
- error: newError,
400
- }
398
+ // return {
399
+ // error: newError,
400
+ // }
401
+ return newError;
401
402
  }
402
403
 
403
404
  BackendAssistant.prototype.errorManager = BackendAssistant.prototype.errorify;
@@ -34,7 +34,7 @@ Middleware.prototype.run = function (library, options) {
34
34
  options.setupAnalytics = typeof options.setupAnalytics === 'boolean' ? options.setupAnalytics : true;
35
35
  options.setupUsage = typeof options.setupUsage === 'boolean' ? options.setupUsage : true;
36
36
  options.setupSettings = typeof options.setupSettings === 'undefined' ? true : options.setupSettings;
37
- options.schema = typeof options.schema === 'undefined' ? '' : options.schema;
37
+ options.schema = typeof options.schema === 'undefined' ? undefined : options.schema;
38
38
 
39
39
  // Log
40
40
  assistant.log(`Middleware.process(): Request (${geolocation.ip} @ ${geolocation.country}, ${geolocation.region}, ${geolocation.city})`, JSON.stringify(data));
@@ -73,11 +73,15 @@ Middleware.prototype.run = function (library, options) {
73
73
 
74
74
  // Resolve settings
75
75
  if (options.setupSettings) {
76
+ // assistant.log(`Middleware.process(): Resolving settings with schema ${options.schema}...`);
77
+
76
78
  try {
77
- assistant.settings = Manager.Settings().resolve(assistant, options.schema, assistant.request.data);
79
+ assistant.settings = Manager.Settings().resolve(assistant, options.schema, data);
78
80
  } catch (e) {
79
- return assistant.errorify(`Unable to resolve schema @ (${options.schema}): ${e.message}`, {sentry: true, send: true, log: true});
81
+ return assistant.errorify(`Unable to resolve schema ${options.schema}: ${e.message}`, {code: e.code, sentry: true, send: true, log: true});
80
82
  }
83
+
84
+ assistant.log(`Middleware.process(): Resolved settings with schema ${options.schema}`, JSON.stringify(assistant.settings));
81
85
  }
82
86
 
83
87
  // Process
@@ -21,22 +21,46 @@ Settings.prototype.resolve = function (assistant, schema, settings) {
21
21
  const Manager = self.Manager;
22
22
 
23
23
  // Set settings
24
- schema = schema || {};
25
- settings = settings || {};
24
+ schema = schema;
25
+ settings = typeof settings === 'undefined' ? {} : settings;
26
+
27
+ // Throw error if there is no schema
28
+ if (typeof schema === 'undefined') {
29
+ throw assistant.errorify(`Schema is undefined`, {code: 500, sentry: false, send: false, log: false});
30
+ }
26
31
 
27
32
  // Reset settings
28
33
  self.settings = null;
29
34
 
30
- assistant.log('Resolving settings for', schema, settings);
31
-
35
+ // Load schema
32
36
  if (typeof schema === 'string') {
33
37
  const schemaPath = path.resolve(process.cwd(), `schemas/${schema.replace('.js', '')}.js`);
34
38
 
35
39
  schema = loadSchema(assistant, schemaPath, settings);
36
40
  }
37
41
 
42
+ // Resolve settings
38
43
  self.settings = powertools.defaults(settings, schema);
39
44
 
45
+ // Check for missing required keys
46
+ powertools.getKeys(schema).forEach((key) => {
47
+ const isRequired = key.endsWith('.required') ? _.get(schema, key, false) : false;
48
+
49
+ // Skip if not required
50
+ if (!isRequired) {
51
+ return;
52
+ }
53
+
54
+ // Use regex to replace '.required' only if it's at the end of the string
55
+ const settingsKey = key.replace(/\.required$/, '');
56
+
57
+ // Check if the required key is missing
58
+ if (typeof _.get(settings, settingsKey, undefined) === 'undefined') {
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});
61
+ }
62
+ });
63
+
40
64
  // Resolve
41
65
  return self.settings;
42
66
  };
@@ -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}).error
174
+ assistant.errorify(`Captcha verification failed.`, {code: 400, sentry: false, send: false, log: false})
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}).error
181
+ assistant.errorify(`You have exceeded your ${path} usage limit of ${period}/${allowed}.`, {code: 429, sentry: false, send: false, log: false})
182
182
  );
183
183
  });
184
184
  };
@@ -0,0 +1,26 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta http-equiv="X-UA-Compatible" content="IE=edge" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>404 Error Page</title>
8
+ <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
9
+ </head>
10
+
11
+ <body>
12
+ <div class="d-flex align-items-center justify-content-center vh-100">
13
+ <div class="text-center">
14
+ <h1 class="display-1 fw-bold">404</h1>
15
+
16
+ <p class="fs-3"> <span class="text-danger">Opps!</span> Page not found.</p>
17
+
18
+ <p class="lead">
19
+ The page you're looking for doesn't exist.
20
+ </p>
21
+
22
+ <a href="{url}" class="btn btn-primary">Go Home</a>
23
+ </div>
24
+ </div>
25
+ </body>
26
+ </html>
@@ -0,0 +1,24 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta http-equiv="X-UA-Compatible" content="IE=edge" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>Simple Index Page</title>
8
+ <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
9
+ </head>
10
+
11
+ <body>
12
+ <div class="container py-5">
13
+ <div class="row">
14
+ <div class="col text-center">
15
+ <h1>Welcome</h1>
16
+
17
+ <p class="lead">This is an internal page, please return to our main website</p>
18
+
19
+ <a href="{url}" class="btn btn-primary">Go Home</a>
20
+ </div>
21
+ </div>
22
+ </div>
23
+ </body>
24
+ </html>