backend-manager 3.2.151 → 3.2.153

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,154 @@
1
+ const fetch = require('wonderful-fetch');
2
+ const _ = require('lodash');
3
+
4
+ function Module() {
5
+
6
+ }
7
+
8
+ Module.prototype.main = function () {
9
+ const self = this;
10
+ const Manager = self.Manager;
11
+ const Api = self.Api;
12
+ const assistant = self.assistant;
13
+ const payload = self.payload;
14
+
15
+ return new Promise(async function(resolve, reject) {
16
+
17
+ // console.log('---self.libraries.admin', self.libraries.admin);
18
+ // console.log('---self.libraries.admin.credential', self.libraries.admin.credential);
19
+ // console.log('---self.libraries.admin.credential.cert()', self.libraries.admin.credential.cert());
20
+ // console.log('---self.libraries.admin.credential.refreshToken()', self.libraries.admin.credential.refreshToken());
21
+ // console.log('---self.libraries.admin.default', self.libraries.admin.default);
22
+ // console.log('---self.libraries.initializedAdmin', self.libraries.initializedAdmin);
23
+ // console.log('---self.libraries.admin.INTERNAL', self.libraries.admin.INTERNAL);
24
+ // console.log('---self.libraries.initializedAdmin.options_.credential', self.libraries.initializedAdmin.options_.credential);
25
+ // console.log('---self.libraries.initializedAdmin.options_.credential.refreshToken', self.libraries.initializedAdmin.options_.credential.refreshToken);
26
+ // console.log('---self.libraries.initializedAdmin.options_.credential.refreshToken', self.libraries.initializedAdmin.options_.credential.refreshToken);
27
+ // console.log('---self.libraries.initializedAdmin.INTERNAL', self.libraries.initializedAdmin.INTERNAL);
28
+ // const powertools = require('node-powertools');
29
+ // console.log('---self.libraries.admin', powertools.stringify(self.libraries.admin));
30
+ // console.log('---self.libraries.initializedAdmin', powertools.stringify(self.libraries.initializedAdmin));
31
+
32
+ const providers = [
33
+ { name: 'google.com', prefix: ['id_token'] },
34
+ { name: 'facebook.com', prefix: ['access_token'] },
35
+ { name: 'twitter.com', prefix: ['access_token', 'oauth_token_secret'] },
36
+ { name: 'github.com', prefix: ['access_token'] },
37
+ { name: 'microsoft.com', prefix: ['id_token'] },
38
+ // { name: 'microsoft.com', prefix: ['context', 'continueUri', 'sessionId'] },
39
+ { name: 'yahoo.com', prefix: ['id_token'] },
40
+ { name: 'apple.com', prefix: ['id_token'] },
41
+ ]
42
+ const promises = []
43
+
44
+ payload.data.payload.firebaseApiKey = payload.data.payload.firebaseApiKey || _.get(Manager, 'config.firebaseConfig.apiKey') || false;
45
+
46
+ if (!payload.data.payload.firebaseApiKey) {
47
+ return reject(assistant.errorify(`The firebaseApiKey parameter is required.`, {code: 400}));
48
+ }
49
+
50
+ // Default
51
+ payload.response.data.password = true;
52
+
53
+ assistant.log('Checking providers for firebaseApiKey', payload.data.payload.firebaseApiKey);
54
+
55
+ function request(provider) {
56
+ return new Promise(function(resolve, reject) {
57
+ let prefix = '';
58
+ provider.prefix
59
+ .forEach((item, i) => {
60
+ prefix += `${item}=LOL&`
61
+ });
62
+
63
+ // https://firebase.google.com/docs/reference/rest/auth#section-sign-in-with-oauth-credential
64
+ fetch(`https://identitytoolkit.googleapis.com/v1/accounts:signInWithIdp?key=${payload.data.payload.firebaseApiKey}`, {
65
+ method: 'post',
66
+ body: {
67
+ postBody: `${prefix}providerId=${provider.name}`,
68
+ requestUri: 'http://localhost',
69
+ returnIdpCredential: true,
70
+ returnSecureToken: true
71
+ }
72
+ })
73
+ .then(response => {
74
+ payload.response.data[provider.name] = true;
75
+ })
76
+ .catch(e => {
77
+ try {
78
+ const errorJson = JSON.parse(e.message);
79
+ const errorArray = errorJson.error.errors || [];
80
+ let result = true;
81
+
82
+ errorArray
83
+ .forEach((error, i) => {
84
+ if (error.message.includes('OPERATION_NOT_ALLOWED') || error.message.includes('INVALID_CREDENTIAL_OR_PROVIDER_ID')) {
85
+ result = false;
86
+ }
87
+ assistant.log('Provider check', provider.name, error);
88
+ });
89
+
90
+ assistant.log('Provider response', provider.name, result);
91
+
92
+ payload.response.data[provider.name] = result;
93
+ } catch (e) {
94
+ assistant.errorify(`Error parsing error: ${e}`, {code: 500, sentry: true});
95
+ payload.response.data[provider.name] = false;
96
+ }
97
+ })
98
+ .finally(r => {
99
+ return resolve();
100
+ })
101
+ });
102
+ }
103
+
104
+ providers
105
+ .forEach((provider, i) => {
106
+ payload.response.data[provider.name] = false;
107
+ promises.push(request(provider))
108
+ });
109
+
110
+ assistant.log('Checking providers...');
111
+
112
+ await Promise.all(promises)
113
+ .then(response => {
114
+ // console.log('--payload.response.data', promises.length, payload.response.data);
115
+
116
+ fetch(`https://us-central1-itw-creative-works.cloudfunctions.net/getApp`, {
117
+ method: 'post',
118
+ response: 'json',
119
+ body: {
120
+ id: Manager.config.app.id,
121
+ }
122
+ })
123
+ .then(response => {
124
+ assistant.log('getApp response', response);
125
+ response.authentication = response.authentication || {};
126
+
127
+ Object.keys(response.authentication)
128
+ .forEach((provider, i) => {
129
+ response.authentication[provider] = response.authentication[provider] || {};
130
+
131
+ if (typeof response.authentication[provider].enabled !== 'undefined') {
132
+ payload.response.data[provider] = response.authentication[provider].enabled;
133
+ assistant.log(`Overwriting ${provider} to ${payload.response.data[provider]}...`);
134
+ }
135
+ });
136
+
137
+ })
138
+ .catch(e => {
139
+ assistant.errorify(`Error getting app data: ${e}`, {code: 500, log: true})
140
+ })
141
+ .finally(r => {
142
+ return resolve({data: payload.response.data});
143
+ })
144
+
145
+ })
146
+ .catch(e => {
147
+ return reject(assistant.errorify(`Failed to check providers: ${e}`, {code: 500}));
148
+ })
149
+
150
+ });
151
+
152
+ };
153
+
154
+ module.exports = Module;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "backend-manager",
3
- "version": "3.2.151",
3
+ "version": "3.2.153",
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
@@ -963,22 +963,27 @@ function fix_indexesSync(self) {
963
963
 
964
964
  function fix_setStoragePolicy(self) {
965
965
  return new Promise(function(resolve, reject) {
966
- fetch(self.bemApiURL, {
967
- method: 'post',
968
- timeout: 30000,
969
- response: 'json',
970
- body: {
971
- command: 'admin:backup',
972
- },
973
- })
974
- .then(json => {
975
- console.log('Response', json);
976
- return resolve();
977
- })
978
- .catch(e => {
979
- console.error(chalk.red(`There is no automatic fix. Please run: \n${chalk.bold('firebase deploy && npx bm setup')}`));
980
- return reject();
981
- });
966
+ // fetch(self.bemApiURL, {
967
+ // method: 'post',
968
+ // timeout: 30000,
969
+ // response: 'json',
970
+ // body: {
971
+ // command: 'admin:backup',
972
+ // },
973
+ // })
974
+ // .then(json => {
975
+ // console.log('Response', json);
976
+ // return resolve();
977
+ // })
978
+ // .catch(e => {
979
+ // console.error(chalk.red(`There is no automatic fix. Please run: \n${chalk.bold('firebase deploy && npx bm setup')}`));
980
+ // return reject();
981
+ // });
982
+ // Log
983
+ console.error(chalk.red(`There is no automatic fix. Please run: \n${chalk.bold('firebase deploy && npx bm setup')}`));
984
+
985
+ // Reject
986
+ return reject();
982
987
  });
983
988
  };
984
989
 
@@ -90,7 +90,7 @@ Module.prototype._setMetaStats = function (error, meta) {
90
90
  },
91
91
  status: {
92
92
  success: !isError,
93
- error: error,
93
+ error: isError ? error.message : null,
94
94
  }
95
95
  }
96
96
  },
@@ -0,0 +1,158 @@
1
+ const fetch = require('wonderful-fetch');
2
+ const moment = require('moment');
3
+ const jetpack = require('fs-jetpack');
4
+ const powertools = require('node-powertools');
5
+ const uuidv4 = require('uuid').v4;
6
+ const path = require('path');
7
+ const { Octokit } = require('@octokit/rest');
8
+
9
+ function Module() {
10
+
11
+ }
12
+
13
+ Module.prototype.main = function () {
14
+ const self = this;
15
+ const Manager = self.Manager;
16
+ const Api = self.Api;
17
+ const assistant = self.assistant;
18
+ const payload = self.payload;
19
+
20
+ return new Promise(async function(resolve, reject) {
21
+ try {
22
+ // Perform checks
23
+ if (!payload.user.roles.admin && !payload.user.roles.blogger) {
24
+ return reject(assistant.errorify(`Admin required.`, {code: 401}));
25
+ }
26
+
27
+ // Log payload
28
+ assistant.log(`main(): payload.data`, payload.data);
29
+
30
+ // Set now
31
+ const now = assistant.meta.startTime.timestamp;
32
+ const bemRepo = assistant.parseRepo(Manager?.config?.github?.repo_website);
33
+
34
+ // Setup Octokit
35
+ self.octokit = new Octokit({
36
+ auth: Manager?.config?.github?.key,
37
+ });
38
+
39
+ // Check for required values
40
+ if (!payload.data.payload.url) {
41
+ return reject(assistant.errorify(`Missing required parameter: url`, {code: 400}));
42
+ } else if (!payload.data.payload.body) {
43
+ return reject(assistant.errorify(`Missing required parameter: body`, {code: 400}));
44
+ }
45
+
46
+ // Set defaults
47
+ payload.data.payload.url = payload.data.payload.url
48
+ // Replace blog/
49
+ .replace(/blog\//ig, '')
50
+ // Remove leading and trailing slashes
51
+ .replace(/^\/|\/$/g, '')
52
+ // Trim
53
+ .trim();
54
+ payload.data.payload.body = payload.data.payload.body
55
+ .replace(powertools.regexify(`/# ${payload.data.payload.title}/i`), '')
56
+ .replace(/\n\n\n+/g, '\n\n')
57
+ .trim();
58
+
59
+ // Fix even more values
60
+ payload.data.payload.path = `_posts/${moment(now).format('YYYY')}/${payload.data.payload.path || 'guest'}`;
61
+ payload.data.payload.githubUser = payload.data.payload.githubUser || bemRepo.user;
62
+ payload.data.payload.githubRepo = payload.data.payload.githubRepo || bemRepo.name;
63
+
64
+ // Log
65
+ assistant.log(`main(): Editing post...`, payload.data.payload);
66
+
67
+ // Upload post
68
+ const fetchedPost = await self.fetchPost(payload.data.payload.url);
69
+
70
+ // Upload post
71
+ const uploadPost = await self.uploadPost(fetchedPost, payload.data.payload.body);
72
+
73
+ // Log
74
+ assistant.log(`main(): uploadPost`, uploadPost);
75
+
76
+ // Resolve
77
+ return resolve({data: payload.data.payload});
78
+ } catch (e) {
79
+ return reject(e);
80
+ }
81
+ });
82
+ };
83
+
84
+ // Fetch post
85
+ Module.prototype.fetchPost = function (url) {
86
+ const self = this;
87
+
88
+ const Manager = self.Manager;
89
+ const Api = self.Api;
90
+ const assistant = self.assistant;
91
+ const payload = self.payload;
92
+
93
+ return new Promise(async function(resolve, reject) {
94
+ fetch(`${Manager.project.functionsUrl}/bm_api`, {
95
+ method: 'post',
96
+ response: 'json',
97
+ timeout: 190000,
98
+ tries: 1,
99
+ body: {
100
+ command: 'general:fetch-post',
101
+ payload: {
102
+ url: url,
103
+ },
104
+ },
105
+ })
106
+ .then((r) => {
107
+ assistant.log(`fetchPost(): Result`, r);
108
+
109
+ return resolve(r);
110
+ })
111
+ .catch((e) => {
112
+ assistant.log(`fetchPost(): Error`, e);
113
+
114
+ return reject(e);
115
+ });
116
+ })
117
+ };
118
+
119
+ Module.prototype.uploadPost = function (fetchedPost, content) {
120
+ const self = this;
121
+ const Manager = self.Manager;
122
+ const Api = self.Api;
123
+ const assistant = self.assistant;
124
+ const payload = self.payload;
125
+
126
+ return new Promise(async function(resolve, reject) {
127
+ const filename = fetchedPost.path;
128
+ const sha = fetchedPost.sha;
129
+ const frontmatter = fetchedPost.frontmatter;
130
+ const owner = payload.data.payload.githubUser;
131
+ const repo = payload.data.payload.githubRepo;
132
+
133
+ // Combine content
134
+ const fullContent = '---\n'
135
+ + `${frontmatter}\n`
136
+ + '---\n'
137
+ + '\n'
138
+ + content;
139
+
140
+ // Upload post
141
+ await self.octokit.rest.repos.createOrUpdateFileContents({
142
+ owner: owner,
143
+ repo: repo,
144
+ path: filename,
145
+ sha: sha,
146
+ message: `📦 admin:edit-post:upload-post ${filename}`,
147
+ content: Buffer.from(fullContent).toString('base64'),
148
+ })
149
+ .then((r) => {
150
+ assistant.log(`uploadPost(): Result`, r);
151
+
152
+ return resolve(r);
153
+ })
154
+ .catch((e) => reject(e));
155
+ });
156
+ };
157
+
158
+ module.exports = Module;
@@ -1,5 +1,5 @@
1
1
  const fetch = require('wonderful-fetch');
2
- const _ = require('lodash');
2
+ const { merge } = require('lodash');
3
3
 
4
4
  function Module() {
5
5
 
@@ -13,142 +13,90 @@ Module.prototype.main = function () {
13
13
  const payload = self.payload;
14
14
 
15
15
  return new Promise(async function(resolve, reject) {
16
-
17
- // console.log('---self.libraries.admin', self.libraries.admin);
18
- // console.log('---self.libraries.admin.credential', self.libraries.admin.credential);
19
- // console.log('---self.libraries.admin.credential.cert()', self.libraries.admin.credential.cert());
20
- // console.log('---self.libraries.admin.credential.refreshToken()', self.libraries.admin.credential.refreshToken());
21
- // console.log('---self.libraries.admin.default', self.libraries.admin.default);
22
- // console.log('---self.libraries.initializedAdmin', self.libraries.initializedAdmin);
23
- // console.log('---self.libraries.admin.INTERNAL', self.libraries.admin.INTERNAL);
24
- // console.log('---self.libraries.initializedAdmin.options_.credential', self.libraries.initializedAdmin.options_.credential);
25
- // console.log('---self.libraries.initializedAdmin.options_.credential.refreshToken', self.libraries.initializedAdmin.options_.credential.refreshToken);
26
- // console.log('---self.libraries.initializedAdmin.options_.credential.refreshToken', self.libraries.initializedAdmin.options_.credential.refreshToken);
27
- // console.log('---self.libraries.initializedAdmin.INTERNAL', self.libraries.initializedAdmin.INTERNAL);
28
- // const powertools = require('node-powertools');
29
- // console.log('---self.libraries.admin', powertools.stringify(self.libraries.admin));
30
- // console.log('---self.libraries.initializedAdmin', powertools.stringify(self.libraries.initializedAdmin));
31
-
32
- const providers = [
33
- { name: 'google.com', prefix: ['id_token'] },
34
- { name: 'facebook.com', prefix: ['access_token'] },
35
- { name: 'twitter.com', prefix: ['access_token', 'oauth_token_secret'] },
36
- { name: 'github.com', prefix: ['access_token'] },
37
- { name: 'microsoft.com', prefix: ['id_token'] },
38
- // { name: 'microsoft.com', prefix: ['context', 'continueUri', 'sessionId'] },
39
- { name: 'yahoo.com', prefix: ['id_token'] },
40
- { name: 'apple.com', prefix: ['id_token'] },
41
- ]
42
- const promises = []
43
-
44
- payload.data.payload.firebaseApiKey = payload.data.payload.firebaseApiKey || _.get(Manager, 'config.firebaseConfig.apiKey') || false;
45
-
46
- if (!payload.data.payload.firebaseApiKey) {
47
- return reject(assistant.errorify(`The firebaseApiKey parameter is required.`, {code: 400}));
16
+ const defaultProviders = {
17
+ ['password']: {
18
+ enabled: true,
19
+ },
20
+ ['google.com']: {
21
+ enabled: true,
22
+ },
23
+ ['facebook.com']: {
24
+ enabled: false,
25
+ },
26
+ ['twitter.com']: {
27
+ enabled: false,
28
+ },
29
+ ['github.com']: {
30
+ enabled: false,
31
+ },
32
+ ['microsoft.com']: {
33
+ enabled: false,
34
+ },
35
+ ['yahoo.com']: {
36
+ enabled: false,
37
+ },
38
+ ['apple.com']: {
39
+ enabled: false,
40
+ },
48
41
  }
49
42
 
50
- // Default
51
- payload.response.data.password = true;
52
-
53
- assistant.log('Checking providers for firebaseApiKey', payload.data.payload.firebaseApiKey);
54
-
55
- function request(provider) {
56
- return new Promise(function(resolve, reject) {
57
- let prefix = '';
58
- provider.prefix
59
- .forEach((item, i) => {
60
- prefix += `${item}=LOL&`
61
- });
62
-
63
- // https://firebase.google.com/docs/reference/rest/auth#section-sign-in-with-oauth-credential
64
- fetch(`https://identitytoolkit.googleapis.com/v1/accounts:signInWithIdp?key=${payload.data.payload.firebaseApiKey}`, {
65
- method: 'post',
66
- body: {
67
- postBody: `${prefix}providerId=${provider.name}`,
68
- requestUri: 'http://localhost',
69
- returnIdpCredential: true,
70
- returnSecureToken: true
71
- }
72
- })
73
- .then(response => {
74
- payload.response.data[provider.name] = true;
75
- })
76
- .catch(e => {
77
- try {
78
- const errorJson = JSON.parse(e.message);
79
- const errorArray = errorJson.error.errors || [];
80
- let result = true;
81
-
82
- errorArray
83
- .forEach((error, i) => {
84
- if (error.message.includes('OPERATION_NOT_ALLOWED') || error.message.includes('INVALID_CREDENTIAL_OR_PROVIDER_ID')) {
85
- result = false;
86
- }
87
- assistant.log('Provider check', provider.name, error);
88
- });
89
-
90
- assistant.log('Provider response', provider.name, result);
91
-
92
- payload.response.data[provider.name] = result;
93
- } catch (e) {
94
- assistant.errorify(`Error parsing error: ${e}`, {code: 500, sentry: true});
95
- payload.response.data[provider.name] = false;
96
- }
97
- })
98
- .finally(r => {
99
- return resolve();
100
- })
101
- });
43
+ // Get app
44
+ const appObject = await self.getAppObject();
45
+ if (appObject instanceof Error) {
46
+ return reject(assistant.errorify(`Failed to get app object: ${appObject}`, {code: 500}));
102
47
  }
103
48
 
104
- providers
105
- .forEach((provider, i) => {
106
- payload.response.data[provider.name] = false;
107
- promises.push(request(provider))
49
+ // Merge the default providers with the app providers
50
+ const providers = merge(defaultProviders, appObject.authentication);
51
+
52
+ // Reformat the object so it's just provider=true/false
53
+ const finalProviders = {};
54
+ Object.keys(providers).forEach(key => {
55
+ finalProviders[key] = providers[key].enabled;
108
56
  });
109
57
 
110
- assistant.log('Checking providers...');
111
-
112
- await Promise.all(promises)
113
- .then(response => {
114
- // console.log('--payload.response.data', promises.length, payload.response.data);
115
-
116
- fetch(`https://us-central1-itw-creative-works.cloudfunctions.net/getApp`, {
117
- method: 'post',
118
- response: 'json',
119
- body: {
120
- id: Manager.config.app.id,
121
- }
122
- })
123
- .then(response => {
124
- assistant.log('getApp response', response);
125
- response.authentication = response.authentication || {};
126
-
127
- Object.keys(response.authentication)
128
- .forEach((provider, i) => {
129
- response.authentication[provider] = response.authentication[provider] || {};
130
-
131
- if (typeof response.authentication[provider].enabled !== 'undefined') {
132
- payload.response.data[provider] = response.authentication[provider].enabled;
133
- assistant.log(`Overwriting ${provider} to ${payload.response.data[provider]}...`);
134
- }
135
- });
136
-
137
- })
138
- .catch(e => {
139
- assistant.errorify(`Error getting app data: ${e}`, {code: 500, log: true})
140
- })
141
- .finally(r => {
142
- return resolve({data: payload.response.data});
143
- })
58
+ // Log
59
+ assistant.log('Providers', finalProviders);
144
60
 
61
+ // Resolve
62
+ return resolve({data: finalProviders});
63
+ });
64
+
65
+ };
66
+
67
+ // Get app object
68
+ Module.prototype.getAppObject = function () {
69
+ const self = this;
70
+
71
+ const Manager = self.Manager;
72
+ const Api = self.Api;
73
+ const assistant = self.assistant;
74
+ const payload = self.payload;
75
+
76
+ return new Promise(async function(resolve, reject) {
77
+ const id = Manager.config.app.id;
78
+
79
+ // Get the app settings
80
+ fetch(`https://us-central1-itw-creative-works.cloudfunctions.net/getApp`, {
81
+ method: 'post',
82
+ response: 'json',
83
+ body: {
84
+ id: id,
85
+ }
145
86
  })
146
- .catch(e => {
147
- return reject(assistant.errorify(`Failed to check providers: ${e}`, {code: 500}));
148
- })
87
+ .then((r) => {
88
+ assistant.log('getAppObject(): Response', r);
149
89
 
150
- });
90
+ // If data is missing, return an error
91
+ if (!r) {
92
+ throw new Error(`App with id ${id} not found`);
93
+ }
151
94
 
95
+ // Return the app object
96
+ return resolve(r);
97
+ })
98
+ .catch(e => reject(e));
99
+ });
152
100
  };
153
101
 
154
102
  module.exports = Module;
@@ -84,6 +84,10 @@ Module.prototype.main = function () {
84
84
  // Return
85
85
  return resolve({
86
86
  data: {
87
+ name: post.data.name,
88
+ path: post.data.path,
89
+ size: post.data.size,
90
+ sha: post.data.sha,
87
91
  frontmatter: frontmatter,
88
92
  body: body,
89
93
  }
@@ -40,6 +40,7 @@
40
40
  '$app',
41
41
  // Add more sources here
42
42
  ],
43
+ links: [],
43
44
  prompt: '',
44
45
  }
45
46
  ],