backend-manager 1.1.103 → 2.0.0

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 (24) hide show
  1. package/package.json +19 -20
  2. package/src/cli/cli.js +22 -7
  3. package/src/manager/functions/core/actions/api/admin/create-post.js +160 -0
  4. package/src/manager/functions/core/actions/api/admin/firestore-query.js +172 -0
  5. package/src/manager/functions/core/actions/api/admin/firestore-read.js +54 -0
  6. package/src/manager/functions/core/actions/api/admin/firestore-write.js +47 -0
  7. package/src/manager/functions/core/actions/api/admin/get-stats.js +206 -0
  8. package/src/manager/functions/core/actions/api/admin/payment-processor.js +56 -0
  9. package/src/manager/functions/core/actions/api/admin/send-notification.js +189 -0
  10. package/src/manager/functions/core/actions/api/general/generate-uuid.js +49 -0
  11. package/src/manager/functions/core/actions/api/handler/create-post.js +118 -0
  12. package/src/manager/functions/core/actions/api/template.js +34 -0
  13. package/src/manager/functions/core/actions/api/test/authenticate.js +31 -0
  14. package/src/manager/functions/core/actions/api/test/create-test-accounts.js +36 -0
  15. package/src/manager/functions/core/actions/api/test/webhook.js +35 -0
  16. package/src/manager/functions/core/actions/api/user/create-custom-token.js +63 -0
  17. package/src/manager/functions/core/actions/api/user/delete.js +73 -0
  18. package/src/manager/functions/core/actions/api/user/get-subscription-info.js +63 -0
  19. package/src/manager/functions/core/actions/api/user/sign-out-all-sessions.js +86 -0
  20. package/src/manager/functions/core/actions/api/user/sign-up.js +241 -0
  21. package/src/manager/functions/core/actions/api.js +117 -323
  22. package/src/manager/functions/core/actions/old/api-2.js +414 -0
  23. package/src/manager/functions/core/admin/create-post.js +1 -1
  24. package/src/manager/index.js +1 -18
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "backend-manager",
3
- "version": "1.1.103",
3
+ "version": "2.0.0",
4
4
  "description": "Quick tools for developing Firebase functions",
5
5
  "main": "src/manager/index.js",
6
6
  "bin": {
@@ -27,38 +27,37 @@
27
27
  },
28
28
  "homepage": "https://itwcreativeworks.com",
29
29
  "dependencies": {
30
- "@firebase/rules-unit-testing": "^2.0.1",
31
- "@google-cloud/storage": "^5.16.0",
32
- "@sendgrid/mail": "^7.6.0",
33
- "@sentry/node": "^6.15.0",
34
- "backend-assistant": "^0.0.55",
30
+ "@firebase/rules-unit-testing": "^2.0.2",
31
+ "@google-cloud/storage": "^5.19.2",
32
+ "@sendgrid/mail": "^7.6.2",
33
+ "@sentry/node": "^6.19.6",
34
+ "backend-assistant": "^0.0.58",
35
35
  "busboy": "^0.3.1",
36
36
  "chalk": "^4.1.2",
37
37
  "cors": "^2.8.5",
38
- "dotenv": "^10.0.0",
38
+ "dotenv": "^16.0.0",
39
39
  "firebase-admin": "^9.12.0",
40
- "firebase-functions": "^3.16.0",
41
- "fs-jetpack": "^4.2.0",
42
- "hcaptcha": "^0.1.0",
43
- "inquirer": "^8.2.0",
44
- "json5": "^2.2.0",
40
+ "firebase-functions": "^3.20.1",
41
+ "fs-jetpack": "^4.3.1",
42
+ "hcaptcha": "^0.1.1",
43
+ "inquirer": "^8.2.2",
44
+ "json5": "^2.2.1",
45
45
  "lodash": "^4.17.21",
46
46
  "mailchimp-api-v3": "^1.15.0",
47
- "mocha": "^9.1.3",
48
- "moment": "^2.29.1",
49
- "node-fetch": "^2.6.5",
47
+ "mocha": "^9.2.2",
48
+ "moment": "^2.29.3",
49
+ "node-fetch": "^2.6.7",
50
50
  "node-powertools": "^0.0.10",
51
- "npm": "^7.24.2",
52
51
  "npm-api": "^1.0.1",
53
52
  "paypal-server-api": "^0.0.5",
54
53
  "pushid": "^1.0.0",
55
- "semver": "^7.3.5",
54
+ "semver": "^7.3.7",
56
55
  "shortid": "^2.2.16",
57
56
  "uid-generator": "^2.0.0",
58
- "ultimate-jekyll-poster": "^0.0.9",
59
- "universal-analytics": "^0.4.23",
57
+ "ultimate-jekyll-poster": "^0.0.10",
58
+ "universal-analytics": "^0.5.3",
60
59
  "uuid": "^8.3.2",
61
- "yargs": "^17.2.1"
60
+ "yargs": "^17.4.1"
62
61
  },
63
62
  "files": [
64
63
  "bin/",
package/src/cli/cli.js CHANGED
@@ -280,11 +280,15 @@ Main.prototype.setup = async function () {
280
280
  // let latest = semver.clean(await getPkgVersion(pkg));
281
281
  let latest = semver.clean(cleanPackageVersion(self.packageJSON.dependencies['firebase-admin']));
282
282
  let mine = cleanPackageVersion(self.package.dependencies[pkg] || '0.0.0');
283
-
283
+ const majorVersionMismatch = ((semver.major(latest) > semver.major(mine)));
284
284
  let bemv = cleanPackageVersion(self.packageJSON.dependencies[pkg]);
285
285
  bemPackageVersionWarning(pkg, bemv, latest);
286
286
 
287
- return !(semver.gt(latest, mine));
287
+ if (majorVersionMismatch) {
288
+ console.log(chalk.red(`Version ${chalk.bold(latest)} of ${chalk.bold(pkg)} available but you must install this manually because it is a major update.`));
289
+ }
290
+
291
+ return !(semver.gt(latest, mine)) || majorVersionMismatch;
288
292
  }, fix_fba);
289
293
 
290
294
  await this.test('using updated firebase-functions', async function () {
@@ -292,19 +296,28 @@ Main.prototype.setup = async function () {
292
296
  // let latest = semver.clean(await getPkgVersion(pkg));
293
297
  let latest = semver.clean(cleanPackageVersion(self.packageJSON.dependencies['firebase-functions']));
294
298
  let mine = cleanPackageVersion(self.package.dependencies[pkg] || '0.0.0');
295
-
299
+ const majorVersionMismatch = ((semver.major(latest) > semver.major(mine)));
296
300
  let bemv = cleanPackageVersion(self.packageJSON.dependencies[pkg]);
297
301
  bemPackageVersionWarning(pkg, bemv, latest);
298
302
 
299
- return !(semver.gt(latest, mine));
303
+ if (majorVersionMismatch) {
304
+ console.log(chalk.red(`Version ${chalk.bold(latest)} of ${chalk.bold(pkg)} available but you must install this manually because it is a major update.`));
305
+ }
306
+
307
+ return !(semver.gt(latest, mine)) || majorVersionMismatch;
300
308
  }, fix_fbf);
301
309
 
302
310
  await this.test('using updated backend-manager', async function () {
303
311
  let pkg = 'backend-manager';
304
312
  let latest = semver.clean(await getPkgVersion(pkg));
305
313
  let mine = cleanPackageVersion(self.package.dependencies[pkg] || '0.0.0');
314
+ const majorVersionMismatch = !isLocal(mine) && ((semver.major(latest) > semver.major(mine)));
315
+
316
+ if (majorVersionMismatch) {
317
+ console.log(chalk.red(`Version ${chalk.bold(latest)} of ${chalk.bold(pkg)} available but you must install this manually because it is a major update.`));
318
+ }
306
319
 
307
- return isLocal(mine) || !(semver.gt(latest, mine));
320
+ return isLocal(mine) || !(semver.gt(latest, mine)) || majorVersionMismatch;
308
321
  }, fix_bem);
309
322
 
310
323
  (async function() {
@@ -694,10 +707,12 @@ function fix_packageversion(self) {
694
707
  };
695
708
 
696
709
  async function fix_fbf(self) {
697
- return await installPkg('firebase-functions', `@${self.packageJSON.dependencies['firebase-functions']}`)
710
+ console.log('----FIX FBF'); return Promise.resolve();
711
+ // return await installPkg('firebase-functions', `@${self.packageJSON.dependencies['firebase-functions']}`)
698
712
  };
699
713
  async function fix_fba(self) {
700
- return await installPkg('firebase-admin', `@${self.packageJSON.dependencies['firebase-admin']}`)
714
+ console.log('----FIX FBA'); return Promise.resolve();
715
+ // return await installPkg('firebase-admin', `@${self.packageJSON.dependencies['firebase-admin']}`)
701
716
  };
702
717
  async function fix_bem(self) {
703
718
  return await installPkg('backend-manager')
@@ -0,0 +1,160 @@
1
+ const fetch = require('node-fetch');
2
+ const Poster = require('ultimate-jekyll-poster');
3
+ const pathApi = require('path');
4
+ const { get } = require('lodash');
5
+
6
+ function Module() {
7
+
8
+ }
9
+
10
+ Module.prototype.init = async function (s, payload) {
11
+ const self = this;
12
+ self.Manager = s.Manager;
13
+ self.libraries = s.Manager.libraries;
14
+ self.assistant = s.assistant;
15
+ self.payload = payload;
16
+
17
+ return self;
18
+ };
19
+
20
+ Module.prototype.main = function () {
21
+ const self = this;
22
+ const Manager = self.Manager;
23
+ const assistant = self.assistant;
24
+ const payload = self.payload;
25
+
26
+ return new Promise(async function(resolve, reject) {
27
+ if (!payload.user.roles.admin) {
28
+ return reject(assistant.errorManager(`Admin required.`, {code: 401, sentry: false, send: false, log: false}).error)
29
+ }
30
+
31
+ const repoInfo = assistant.parseRepo(get(self.Manager.config, 'github.repo_website'));
32
+
33
+ const poster = new Poster();
34
+
35
+ // Save to disk OR commit
36
+ poster.onDownload = async function (meta) {
37
+ return new Promise(async function(resolve, reject) {
38
+ let finalPath = poster.removeDirDot(meta.finalPath);
39
+ let tempPath = (meta.tempPath);
40
+ await createFile(get(self.Manager.config, 'github.user'), repoInfo.user, repoInfo.name, get(self.Manager.config, 'github.key'), finalPath, await poster.readImage(tempPath))
41
+ .catch((e) => {
42
+ // console.log('---CAUGHT 1', e);
43
+ })
44
+ resolve();
45
+ });
46
+ }
47
+
48
+ const finalPost = await poster.create(payload.data);
49
+
50
+ // Save post OR commit
51
+ await createFile(get(self.Manager.config, 'github.user'), repoInfo.user, repoInfo.name, get(self.Manager.config, 'github.key'), poster.removeDirDot(finalPost.path), finalPost.content)
52
+ .catch((e) => {
53
+ return reject(assistant.errorManager(`Failed to post: ${e}`, {code: 500, sentry: false, send: false, log: false}).error)
54
+ })
55
+
56
+ return resolve({data: finalPost});
57
+ });
58
+
59
+ };
60
+
61
+ // HELPERS //
62
+ async function createFile(user, repoUser, repoName, key, path, contents) {
63
+ let fileParsed = pathApi.parse(path);
64
+
65
+ let base64Data = Buffer.from(contents).toString('base64');
66
+ // base64Data = contents;
67
+ // console.log('--------base64Data', base64Data);
68
+ return new Promise(async (resolve, reject) => {
69
+ let sha;
70
+ try {
71
+
72
+ // let pathGet = `https://api.github.com/repos/iwiedenm/ultimate-jekyll/git/trees/template:${encodeURIComponent(path_noExt)}`;
73
+ let branch = (repoName === 'ultimate-jekyll') ? 'template' : 'master';
74
+
75
+ let pathGet = `https://api.github.com/repos/${repoUser}/${repoName}/git/trees/${branch}:${encodeURIComponent(pathApi.dirname(path))}`;
76
+ await makeRequest({
77
+ method: 'GET',
78
+ url: pathGet,
79
+ body: {
80
+ },
81
+ timeout: 30000,
82
+ json: true,
83
+ headers: {
84
+ 'User-Agent': user,
85
+ // 'Authorization': `Basic ${user}:${key}`,
86
+ 'Authorization': `Basic ${Buffer.from(user + ':' + key).toString('base64')}`,
87
+ }
88
+ })
89
+ .then(function (resp) {
90
+ // sha = resp.sha;
91
+ sha = resp.tree.find(function (element) {
92
+ // console.log('checiing', element.path, fileParsed.base);
93
+ return element.path === fileParsed.base;
94
+ });
95
+ sha = sha.sha;
96
+ });
97
+ } catch (e) {
98
+ sha = null;
99
+ }
100
+
101
+ let pathPut = `https://api.github.com/repos/${repoUser}/${repoName}/contents/${path}`;
102
+ let writeRequest =
103
+ {
104
+ // url: `https://api.github.com/repos/:owner/:repo/contents/:path`,
105
+ method: 'PUT',
106
+ url: pathPut,
107
+ body: {
108
+ message: `BackendManager Post: ${new Date().toISOString()}`,
109
+ content: base64Data,
110
+ },
111
+ timeout: 30000,
112
+ json: true,
113
+ headers: {
114
+ 'User-Agent': user,
115
+ // 'Authorization': `Basic ${user}:${key}`,
116
+ 'Authorization': `Basic ${Buffer.from(user + ':' + key).toString('base64')}`,
117
+ }
118
+ }
119
+ if (sha) {
120
+ writeRequest.body.sha = sha;
121
+ }
122
+ // console.log('--------PUT', pathPut);
123
+ await makeRequest(writeRequest)
124
+ .then((json) => {
125
+ if (!json || (json.message && (json.message === 'Not Found' || json.message.includes('Invalid request'))) ) {
126
+ return reject(new Error(json.message));
127
+ }
128
+ })
129
+ .catch((e) => {
130
+ return reject(e);
131
+ })
132
+ return resolve(true)
133
+ });
134
+ }
135
+
136
+ function makeRequest(options) {
137
+ return new Promise(function(resolve, reject) {
138
+ options.headers = options.headers || {};
139
+ options.headers['Content-Type'] = 'application/json';
140
+ let hasBody = Object.keys(options.body || {}).length > 0
141
+ fetch(options.url, {
142
+ method: options.method,
143
+ body: hasBody ? JSON.stringify(options.body) : undefined,
144
+ timeout: 30000,
145
+ headers: options.headers,
146
+ auth: options.auth,
147
+ })
148
+ .then(res => res.json())
149
+ .then(json => {
150
+ return resolve(json);
151
+ })
152
+ .catch(e => {
153
+ // console.error('e', e);
154
+ return reject(e);
155
+ })
156
+
157
+ });
158
+ }
159
+
160
+ module.exports = Module;
@@ -0,0 +1,172 @@
1
+ const _ = require('lodash');
2
+ const powertools = require('node-powertools');
3
+
4
+ function Module() {
5
+
6
+ }
7
+
8
+ Module.prototype.init = async function (s, payload) {
9
+ const self = this;
10
+ self.Manager = s.Manager;
11
+ self.libraries = s.Manager.libraries;
12
+ self.assistant = s.Manager.assistant;
13
+ self.payload = payload;
14
+
15
+ return self;
16
+ };
17
+
18
+ Module.prototype.main = function () {
19
+ const self = this;
20
+ const Manager = self.Manager;
21
+ const assistant = self.assistant;
22
+ const payload = self.payload;
23
+
24
+ return new Promise(async function(resolve, reject) {
25
+
26
+ if (!payload.user.roles.admin) {
27
+ return reject(assistant.errorManager(`Admin required.`, {code: 401, sentry: false, send: false, log: false}).error)
28
+ }
29
+
30
+ self.docs = [];
31
+ assistant.log('Queries', payload.data.payload.queries);
32
+ let queries = powertools.arrayify(payload.data.payload.queries || []);
33
+
34
+ let promises = [];
35
+ for (var i = 0; i < queries.length; i++) {
36
+ queries[i]
37
+ promises.push(self.runQuery(queries[i]))
38
+ }
39
+
40
+ await Promise.all(promises)
41
+ .then((r) => {
42
+ return resolve({data: self.docs});
43
+ })
44
+ .catch((e) => {
45
+ return reject(assistant.errorManager(e, {code: 500, sentry: false, send: false, log: false}).error)
46
+ })
47
+
48
+ });
49
+
50
+ };
51
+
52
+ Module.prototype.runQuery = function (query) {
53
+ const self = this;
54
+ const Manager = self.Manager;
55
+ const assistant = self.assistant;
56
+
57
+ query = query || {};
58
+ query.where = powertools.arrayify(query.where || []);
59
+ query.filter = powertools.arrayify(query.filter || []);
60
+ query.orderBy = powertools.arrayify(query.orderBy || []);
61
+
62
+ // self.assistant.log('Query', query);
63
+
64
+ return new Promise(function(resolve, reject) {
65
+ let collection;
66
+
67
+ if (!query.collection) {
68
+ return resolve([]);
69
+ // return reject(new Error('No collection specified.'));
70
+ }
71
+
72
+ collection = self.libraries.admin.firestore().collection(query.collection);
73
+
74
+ for (var i = 0; i < query.where.length; i++) {
75
+ let cur = query.where[i];
76
+ collection = collection.where(cur.field, cur.operator, cur.value);
77
+ }
78
+ for (var i = 0; i < query.orderBy.length; i++) {
79
+ let cur = query.orderBy[i];
80
+ collection = collection.orderBy(cur.field, cur.order)
81
+ }
82
+ if (query.limit) {
83
+ collection = collection.limit(query.limit)
84
+ }
85
+ if (query.startAt) {
86
+ collection = collection.startAt(query.startAt)
87
+ }
88
+ if (query.startAfter) {
89
+ collection = collection.startAfter(query.startAfter)
90
+ }
91
+ if (query.endAt) {
92
+ collection = collection.endAt(query.endAt)
93
+ }
94
+ if (query.endBefore) {
95
+ collection = collection.endBefore(query.endBefore)
96
+ }
97
+
98
+ collection
99
+ .get()
100
+ .then(function (querySnapshot) {
101
+ querySnapshot.forEach(function (doc) {
102
+
103
+ let exists = self.docs.find(item => {
104
+ return item.path === doc.ref.path
105
+ })
106
+
107
+ if (!exists && checkFilter(doc.data(), query.filter)) {
108
+ self.docs.push({
109
+ path: doc.ref.path,
110
+ data: doc.data(),
111
+ });
112
+ }
113
+
114
+ });
115
+
116
+ if (query.filterIndex) {
117
+ let iS = query.filterIndex[0];
118
+ let iF = query.filterIndex[1];
119
+ iF = iF > self.docs.length ? self.docs.length - 1 : iF;
120
+ self.docs = self.docs.slice(iS, iF);
121
+ }
122
+
123
+ return resolve(self.docs);
124
+ })
125
+ .catch(function (error) {
126
+ self.assistant.error(error, {environment: 'production'})
127
+ return reject(error);
128
+ });
129
+ });
130
+
131
+
132
+ };
133
+
134
+ function checkFilter(data, filter) {
135
+
136
+ // Loop through all filters
137
+ for (var i = 0, l = filter.length; i < l; i++) {
138
+ // Set up field and checks
139
+ let field = `${filter[i].field}`.split(' || ');
140
+ field = powertools.arrayify(field);
141
+ let matches = filter[i].matches || '';
142
+ let regex = powertools.regexify(matches);
143
+
144
+ // Pass/fail
145
+ let innerPassed = false;
146
+
147
+ // Loop through each filter's fields
148
+ for (var i2 = 0, l2 = field.length; i2 < l2; i2++) {
149
+ let fieldInner = field[i2];
150
+ let value = _.get(data, fieldInner, undefined);
151
+
152
+ if (typeof value === 'undefined') {
153
+ innerPassed = false;
154
+ continue;
155
+ } else if (typeof value === 'string') {
156
+ if (value.match(regex)) {
157
+ innerPassed = true;
158
+ break;
159
+ }
160
+ }
161
+ }
162
+
163
+ // If there was not a successful innerPassed then break (innerPassed works on OR logic)
164
+ if (!innerPassed) {
165
+ return false;
166
+ }
167
+
168
+ }
169
+ return true;
170
+ }
171
+
172
+ module.exports = Module;
@@ -0,0 +1,54 @@
1
+ function Module() {
2
+
3
+ }
4
+
5
+ Module.prototype.init = async function (s, payload) {
6
+ const self = this;
7
+ self.Manager = s.Manager;
8
+ self.libraries = s.Manager.libraries;
9
+ self.assistant = s.Manager.assistant;
10
+ self.payload = payload;
11
+
12
+ return self;
13
+ };
14
+
15
+ Module.prototype.main = function () {
16
+ const self = this;
17
+ const Manager = self.Manager;
18
+ const assistant = self.assistant;
19
+ const payload = self.payload;
20
+
21
+ return new Promise(async function(resolve, reject) {
22
+
23
+ if (payload.user.authenticated || payload.user.roles.admin) {
24
+
25
+ // console.log('---payload.data.payload', payload.data.payload);
26
+
27
+ payload.data.payload.path = `${payload.data.payload.path || ''}`;
28
+ payload.data.payload.document = payload.data.payload.document || {};
29
+ payload.data.payload.options = payload.data.payload.options || { merge: true };
30
+
31
+
32
+ if (!payload.data.payload.path) {
33
+ return reject(assistant.errorManager(`<path> parameter required`, {code: 400, sentry: false, send: false, log: false}).error)
34
+ } else {
35
+ await self.libraries.admin.firestore().doc(payload.data.payload.path)
36
+ .get()
37
+ .then(doc => {
38
+ return resolve({data: doc.data()});
39
+ })
40
+ .catch(e => {
41
+ return reject(assistant.errorManager(e, {code: 500, sentry: false, send: false, log: false}).error)
42
+ })
43
+ }
44
+
45
+ } else {
46
+ return reject(assistant.errorManager(`Admin required.`, {code: 401, sentry: false, send: false, log: false}).error)
47
+ }
48
+
49
+ });
50
+
51
+ };
52
+
53
+
54
+ module.exports = Module;
@@ -0,0 +1,47 @@
1
+ function Module() {
2
+
3
+ }
4
+
5
+ Module.prototype.init = async function (s, payload) {
6
+ const self = this;
7
+ self.Manager = s.Manager;
8
+ self.libraries = s.Manager.libraries;
9
+ self.assistant = s.Manager.assistant;
10
+ self.payload = payload;
11
+
12
+ return self;
13
+ };
14
+
15
+ Module.prototype.main = function () {
16
+ const self = this;
17
+ const Manager = self.Manager;
18
+ const assistant = self.assistant;
19
+ const payload = self.payload;
20
+
21
+ return new Promise(async function(resolve, reject) {
22
+
23
+ payload.data.payload.path = `${payload.data.payload.path || ''}`;
24
+ payload.data.payload.document = payload.data.payload.document || {};
25
+ payload.data.payload.options = payload.data.payload.options || {};
26
+ payload.data.payload.options.merge = typeof payload.data.payload.options.merge === 'undefined' ? true : payload.data.payload.options.merge;
27
+
28
+ if (!payload.user.roles.admin) {
29
+ return reject(assistant.errorManager(`Admin required.`, {code: 401, sentry: false, send: false, log: false}).error)
30
+ } else if (!payload.data.payload.path) {
31
+ return reject(assistant.errorManager(`Path parameter required.`, {code: 400, sentry: false, send: false, log: false}).error)
32
+ } else {
33
+ await self.libraries.admin.firestore().doc(payload.data.payload.path)
34
+ .set(payload.data.payload.document, payload.data.payload.options)
35
+ .then(r => {
36
+ return resolve({data: {path: payload.data.payload.path}});
37
+ })
38
+ .catch(e => {
39
+ return reject(assistant.errorManager(e, {code: 500, sentry: false, send: false, log: false}).error)
40
+ })
41
+ }
42
+ });
43
+
44
+ };
45
+
46
+
47
+ module.exports = Module;