backend-manager 2.3.20 → 2.4.2
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.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "backend-manager",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.2",
|
|
4
4
|
"description": "Quick tools for developing Firebase functions",
|
|
5
5
|
"main": "src/manager/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -27,11 +27,11 @@
|
|
|
27
27
|
},
|
|
28
28
|
"homepage": "https://itwcreativeworks.com",
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@firebase/rules-unit-testing": "^2.0.
|
|
30
|
+
"@firebase/rules-unit-testing": "^2.0.4",
|
|
31
31
|
"@google-cloud/storage": "^5.20.5",
|
|
32
32
|
"@sendgrid/mail": "^7.7.0",
|
|
33
33
|
"@sentry/node": "^6.19.7",
|
|
34
|
-
"backend-assistant": "^0.0.
|
|
34
|
+
"backend-assistant": "^0.0.71",
|
|
35
35
|
"busboy": "^1.6.0",
|
|
36
36
|
"chalk": "^4.1.2",
|
|
37
37
|
"cors": "^2.8.5",
|
|
@@ -42,6 +42,7 @@
|
|
|
42
42
|
"hcaptcha": "^0.1.1",
|
|
43
43
|
"inquirer": "^8.2.4",
|
|
44
44
|
"json5": "^2.2.1",
|
|
45
|
+
"jwt-decode": "^3.1.2",
|
|
45
46
|
"lodash": "^4.17.21",
|
|
46
47
|
"lowdb": "^1.0.0",
|
|
47
48
|
"mailchimp-api-v3": "^1.15.0",
|
|
@@ -66,4 +67,4 @@
|
|
|
66
67
|
"src/",
|
|
67
68
|
"templates/"
|
|
68
69
|
]
|
|
69
|
-
}
|
|
70
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
const decode = require('jwt-decode')
|
|
2
|
+
|
|
3
|
+
function OAuth2() {
|
|
4
|
+
const self = this;
|
|
5
|
+
self.service = 'google';
|
|
6
|
+
self.name = 'Google';
|
|
7
|
+
self.urls = {
|
|
8
|
+
authorize: 'https://accounts.google.com/o/oauth2/v2/auth',
|
|
9
|
+
tokenize: 'https://oauth2.googleapis.com/token',
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
OAuth2.prototype.buildUrl = function (state, url) {
|
|
14
|
+
const self = this;
|
|
15
|
+
|
|
16
|
+
return new Promise(function(resolve, reject) {
|
|
17
|
+
if (state === 'authorize') {
|
|
18
|
+
// do something with url
|
|
19
|
+
return resolve()
|
|
20
|
+
} else {
|
|
21
|
+
return resolve()
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
OAuth2.prototype.verifyIdentity = function (tokenizeResult) {
|
|
27
|
+
const self = this;
|
|
28
|
+
const Manager = self.Manager;
|
|
29
|
+
|
|
30
|
+
return new Promise(function(resolve, reject) {
|
|
31
|
+
const decoded = decode(tokenizeResult.id_token);
|
|
32
|
+
|
|
33
|
+
// console.log('---decoded', decoded);
|
|
34
|
+
|
|
35
|
+
// Check if exists
|
|
36
|
+
Manager.libraries.admin.firestore().collection(`users`)
|
|
37
|
+
.where(`oauth2.${self.service}.identity.email`, '==', decoded.email)
|
|
38
|
+
.get()
|
|
39
|
+
.then(async (snap) => {
|
|
40
|
+
if (snap.size === 0) {
|
|
41
|
+
return resolve(decoded);
|
|
42
|
+
} else {
|
|
43
|
+
return reject(new Error(`This ${self.name} account is already connected to a ${Manager.config.brand.name} account`));
|
|
44
|
+
}
|
|
45
|
+
})
|
|
46
|
+
.catch((e) => {
|
|
47
|
+
return reject(e);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
});
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
module.exports = OAuth2;
|
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
const _ = require('lodash')
|
|
2
|
+
const fetch = require('wonderful-fetch');
|
|
2
3
|
|
|
3
4
|
function Module() {
|
|
4
5
|
|
|
5
6
|
}
|
|
6
7
|
|
|
8
|
+
/*
|
|
9
|
+
authorize: redirect or send back the URL for authorization, which will go to UJ page that sends the data back to bm_api
|
|
10
|
+
- if no client_id is provided, fetch from ITW/APP
|
|
11
|
+
tokenize: save the credentials in firestore and redirect or respond with URL to the desired end page
|
|
12
|
+
deauthorize: delete from firestore
|
|
13
|
+
refresh: call refresh on token
|
|
14
|
+
*/
|
|
15
|
+
|
|
7
16
|
Module.prototype.main = function () {
|
|
8
17
|
const self = this;
|
|
9
18
|
const Manager = self.Manager;
|
|
@@ -14,9 +23,97 @@ Module.prototype.main = function () {
|
|
|
14
23
|
return new Promise(async function(resolve, reject) {
|
|
15
24
|
self.Api.resolveUser({adminRequired: true})
|
|
16
25
|
.then(async (user) => {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
26
|
+
|
|
27
|
+
self.ultimateJekyllOAuth2Url = assistant.meta.environment === 'development'
|
|
28
|
+
? `http://localhost:4000/oauth2`
|
|
29
|
+
: `${Manager.config.brand.url}/oauth2`
|
|
30
|
+
self.oauth2 = null;
|
|
31
|
+
self.omittedPayloadFields = ['redirect', 'referrer', 'service', 'state'];
|
|
32
|
+
|
|
33
|
+
// self.ultimateJekyllOAuth2Url = `${Manager.config.brand.url}/oauth2`;
|
|
34
|
+
|
|
35
|
+
// Options
|
|
36
|
+
// payload.data.payload.uid = payload.data.payload.uid;
|
|
37
|
+
payload.data.payload.redirect = typeof payload.data.payload.redirect === 'undefined'
|
|
38
|
+
? true
|
|
39
|
+
: payload.data.payload.redirect
|
|
40
|
+
|
|
41
|
+
payload.data.payload.referrer = typeof payload.data.payload.referrer === 'undefined'
|
|
42
|
+
? (assistant.meta.environment === 'development' ? `http://localhost:4000/oauth2` : `${Manager.config.brand.url}/oauth2`)
|
|
43
|
+
: payload.data.payload.referrer
|
|
44
|
+
|
|
45
|
+
payload.data.payload.service = payload.data.payload.service || '';
|
|
46
|
+
payload.data.payload.state = payload.data.payload.state || 'authorize'; // authorize, tokenize, deauthorize, refresh, get
|
|
47
|
+
payload.data.payload.redirect_uri = payload.data.payload.redirect_uri
|
|
48
|
+
? payload.data.payload.redirect_uri
|
|
49
|
+
: payload.data.payload.referrer;
|
|
50
|
+
|
|
51
|
+
// payload.data.payload.parameters = payload.data.payload.parameters || {}
|
|
52
|
+
|
|
53
|
+
// payload.data.payload.client_id = payload.data.payload.client_id;
|
|
54
|
+
// payload.data.payload.scope = payload.data.payload.scope;
|
|
55
|
+
|
|
56
|
+
let newUrl;
|
|
57
|
+
const state = {
|
|
58
|
+
code: 'success',
|
|
59
|
+
service: payload.data.payload.service,
|
|
60
|
+
authenticationToken: payload.data.authenticationToken,
|
|
61
|
+
serverUrl: `${Manager.project.functionsUrl}/bm_api`,
|
|
62
|
+
referrer: payload.data.payload.referrer,
|
|
63
|
+
redirectUrl: payload.data.payload.redirect_uri,
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
assistant.log('OAuth2 payload', payload.data.payload);
|
|
67
|
+
|
|
68
|
+
try {
|
|
69
|
+
self.oauth2 = new (require(`./oauth2/${payload.data.payload.service}.js`))();
|
|
70
|
+
self.oauth2.parent = self;
|
|
71
|
+
self.oauth2.Manager = self.Manager;
|
|
72
|
+
|
|
73
|
+
newUrl = self.oauth2.urls[payload.data.payload.state]
|
|
74
|
+
|
|
75
|
+
// Set parameters
|
|
76
|
+
if (newUrl) {
|
|
77
|
+
newUrl = new URL(newUrl)
|
|
78
|
+
|
|
79
|
+
if (payload.data.payload.state === 'authorize') {
|
|
80
|
+
newUrl.searchParams.set('state', JSON.stringify(state));
|
|
81
|
+
newUrl.searchParams.set('client_id', _.get(Manager.config, `oauth2.${payload.data.payload.service}.client_id`));
|
|
82
|
+
newUrl.searchParams.set('scope', payload.data.payload.scope);
|
|
83
|
+
newUrl.searchParams.set('redirect_uri', self.ultimateJekyllOAuth2Url);
|
|
84
|
+
|
|
85
|
+
newUrl.searchParams.set('access_type', typeof payload.data.payload.access_type === 'undefined' ? 'offline' : payload.data.payload.access_type)
|
|
86
|
+
newUrl.searchParams.set('include_granted_scopes', typeof payload.data.payload.include_granted_scopes === 'undefined' ? 'true' : payload.data.payload.include_granted_scopes)
|
|
87
|
+
newUrl.searchParams.set('response_type', typeof payload.data.payload.response_type === 'undefined' ? 'code' : payload.data.payload.response_type)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
await self.oauth2.buildUrl(payload.data.payload.state, newUrl)
|
|
91
|
+
.then(url => {
|
|
92
|
+
if (url) {
|
|
93
|
+
newUrl = url;
|
|
94
|
+
}
|
|
95
|
+
})
|
|
96
|
+
.catch(e => { throw e; });
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
} catch (e) {
|
|
100
|
+
return reject(e);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Process by state
|
|
104
|
+
if (payload.data.payload.state === 'authorize') {
|
|
105
|
+
self.processState_authorize(newUrl)
|
|
106
|
+
.then(r => {resolve(r)})
|
|
107
|
+
.catch(e => {reject(e)})
|
|
108
|
+
} else if (payload.data.payload.state === 'tokenize') {
|
|
109
|
+
self.processState_tokenize(newUrl)
|
|
110
|
+
.then(r => {resolve(r)})
|
|
111
|
+
.catch(e => {reject(e)})
|
|
112
|
+
} else if (payload.data.payload.state === 'deauthorize') {
|
|
113
|
+
self.processState_deauthorize(newUrl)
|
|
114
|
+
.then(r => {resolve(r)})
|
|
115
|
+
.catch(e => {reject(e)})
|
|
116
|
+
}
|
|
20
117
|
})
|
|
21
118
|
.catch(e => {
|
|
22
119
|
return reject(e);
|
|
@@ -25,5 +122,160 @@ Module.prototype.main = function () {
|
|
|
25
122
|
|
|
26
123
|
};
|
|
27
124
|
|
|
125
|
+
Module.prototype.processState_authorize = function (newUrl) {
|
|
126
|
+
const self = this;
|
|
127
|
+
const Manager = self.Manager;
|
|
128
|
+
const Api = self.Api;
|
|
129
|
+
const assistant = self.assistant;
|
|
130
|
+
const payload = self.payload;
|
|
131
|
+
|
|
132
|
+
return new Promise(async function(resolve, reject) {
|
|
133
|
+
const finalUrl = newUrl.toString();
|
|
134
|
+
|
|
135
|
+
return resolve({
|
|
136
|
+
data: {
|
|
137
|
+
authorizationUrl: finalUrl,
|
|
138
|
+
},
|
|
139
|
+
redirect: payload.data.payload.redirect ? finalUrl : null
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
Module.prototype.processState_tokenize = function (newUrl) {
|
|
145
|
+
const self = this;
|
|
146
|
+
const Manager = self.Manager;
|
|
147
|
+
const Api = self.Api;
|
|
148
|
+
const assistant = self.assistant;
|
|
149
|
+
const payload = self.payload;
|
|
150
|
+
|
|
151
|
+
return new Promise(async function(resolve, reject) {
|
|
152
|
+
const finalUrl = newUrl.toString();
|
|
153
|
+
|
|
154
|
+
const body = {
|
|
155
|
+
client_id: _.get(Manager.config, `oauth2.${payload.data.payload.service}.client_id`),
|
|
156
|
+
client_secret: _.get(Manager.config, `oauth2.${payload.data.payload.service}.client_secret`),
|
|
157
|
+
grant_type: 'authorization_code',
|
|
158
|
+
redirect_uri: self.ultimateJekyllOAuth2Url,
|
|
159
|
+
code: payload.data.payload.code,
|
|
160
|
+
// scope: '',
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
// console.log('----body', body);
|
|
164
|
+
|
|
165
|
+
const tokenizeResponse = await fetch(finalUrl, {
|
|
166
|
+
method: 'POST',
|
|
167
|
+
timeout: 60000,
|
|
168
|
+
response: 'json',
|
|
169
|
+
tries: 2,
|
|
170
|
+
log: true,
|
|
171
|
+
body: new URLSearchParams(body),
|
|
172
|
+
cacheBreaker: false,
|
|
173
|
+
headers: {
|
|
174
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
175
|
+
},
|
|
176
|
+
})
|
|
177
|
+
.then(json => json)
|
|
178
|
+
.catch(e => e)
|
|
179
|
+
|
|
180
|
+
// console.log('---tokenizeResponse', tokenizeResponse);
|
|
181
|
+
|
|
182
|
+
if (tokenizeResponse instanceof Error) {
|
|
183
|
+
return reject(tokenizeResponse);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// Determine identity
|
|
187
|
+
const verifiedIdentity = await self.oauth2.verifyIdentity(tokenizeResponse)
|
|
188
|
+
.then(identity => identity)
|
|
189
|
+
.catch(e => e);
|
|
190
|
+
|
|
191
|
+
// console.log('---verifiedIdentity', verifiedIdentity);
|
|
192
|
+
|
|
193
|
+
if (verifiedIdentity instanceof Error) {
|
|
194
|
+
return reject(verifiedIdentity);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
const storeResponse = await self.libraries.admin.firestore().doc(`users/${payload.user.auth.uid}`)
|
|
198
|
+
.set({
|
|
199
|
+
oauth2: {
|
|
200
|
+
[payload.data.payload.service]: {
|
|
201
|
+
code: _.omit(
|
|
202
|
+
_.merge({}, payload.data.payload),
|
|
203
|
+
self.omittedPayloadFields,
|
|
204
|
+
),
|
|
205
|
+
token: tokenizeResponse,
|
|
206
|
+
identity: verifiedIdentity,
|
|
207
|
+
updated: {
|
|
208
|
+
timestamp: assistant.meta.startTime.timestamp,
|
|
209
|
+
timestampUNIX: assistant.meta.startTime.timestampUNIX,
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}, { merge: true })
|
|
214
|
+
.then(r => r)
|
|
215
|
+
.catch(e => e)
|
|
216
|
+
|
|
217
|
+
// console.log('---storeResponse', storeResponse);
|
|
218
|
+
|
|
219
|
+
if (storeResponse instanceof Error) {
|
|
220
|
+
return reject(storeResponse);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
return resolve({
|
|
224
|
+
data: {success: true}
|
|
225
|
+
})
|
|
226
|
+
|
|
227
|
+
});
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
Module.prototype.processState_deauthorize = function () {
|
|
231
|
+
const self = this;
|
|
232
|
+
const Manager = self.Manager;
|
|
233
|
+
const Api = self.Api;
|
|
234
|
+
const assistant = self.assistant;
|
|
235
|
+
const payload = self.payload;
|
|
236
|
+
|
|
237
|
+
return new Promise(async function(resolve, reject) {
|
|
238
|
+
self.libraries.admin.firestore().doc(`users/${payload.user.auth.uid}`)
|
|
239
|
+
.set({
|
|
240
|
+
oauth2: {
|
|
241
|
+
[payload.data.payload.service]: {},
|
|
242
|
+
updated: {
|
|
243
|
+
timestamp: assistant.meta.startTime.timestamp,
|
|
244
|
+
timestampUNIX: assistant.meta.startTime.timestampUNIX,
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}, { merge: true })
|
|
248
|
+
.then(function(data) {
|
|
249
|
+
return resolve({
|
|
250
|
+
data: {success: true},
|
|
251
|
+
});
|
|
252
|
+
})
|
|
253
|
+
.catch(function(e) {
|
|
254
|
+
return reject(e);
|
|
255
|
+
})
|
|
256
|
+
});
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
Module.prototype.processState_template = function (newUrl) {
|
|
263
|
+
const self = this;
|
|
264
|
+
const Manager = self.Manager;
|
|
265
|
+
const Api = self.Api;
|
|
266
|
+
const assistant = self.assistant;
|
|
267
|
+
const payload = self.payload;
|
|
268
|
+
|
|
269
|
+
return new Promise(async function(resolve, reject) {
|
|
270
|
+
const finalUrl = newUrl.toString();
|
|
271
|
+
|
|
272
|
+
return resolve({
|
|
273
|
+
data: {
|
|
274
|
+
authorizationUrl: finalUrl,
|
|
275
|
+
},
|
|
276
|
+
redirect: payload.data.payload.redirect ? finalUrl : null
|
|
277
|
+
});
|
|
278
|
+
});
|
|
279
|
+
};
|
|
28
280
|
|
|
29
281
|
module.exports = Module;
|
|
@@ -33,6 +33,7 @@ Module.prototype.init = function (Manager, data) {
|
|
|
33
33
|
|
|
34
34
|
Module.prototype.main = function() {
|
|
35
35
|
const self = this;
|
|
36
|
+
const Manager = self.Manager;
|
|
36
37
|
const libraries = self.libraries;
|
|
37
38
|
const assistant = self.assistant;
|
|
38
39
|
const req = self.req;
|
|
@@ -45,6 +46,7 @@ Module.prototype.main = function() {
|
|
|
45
46
|
const resolved = self.resolveCommand(self.payload.data.command);
|
|
46
47
|
|
|
47
48
|
self.assistant.log(`Executing: ${resolved.command}`, self.payload, JSON.stringify(self.payload), {environment: 'production'})
|
|
49
|
+
self.assistant.log(`Resolved URL: ${Manager.project.functionsUrl}?command=${encodeURIComponent(resolved.command)}&payload=${encodeURIComponent(JSON.stringify(self.assistant.request.data.payload))}`, {environment: 'development'})
|
|
48
50
|
|
|
49
51
|
if (!resolved.exists) {
|
|
50
52
|
self.payload.response.status = 400;
|
|
@@ -61,6 +63,7 @@ Module.prototype.main = function() {
|
|
|
61
63
|
// console.log('---self.payload.response.data', self.payload.response.data);
|
|
62
64
|
self.payload.response.status = result.status || self.payload.response.status || 200;
|
|
63
65
|
self.payload.response.data = result.data || self.payload.response.data || {};
|
|
66
|
+
self.payload.response.redirect = result.redirect || self.payload.response.redirect || null;
|
|
64
67
|
})
|
|
65
68
|
.catch(e => {
|
|
66
69
|
self.payload.response.status = e.code || 500;
|
|
@@ -77,13 +80,22 @@ Module.prototype.main = function() {
|
|
|
77
80
|
})
|
|
78
81
|
}
|
|
79
82
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
+
self.payload.response.status = _fixStatus(self.payload.response.status);
|
|
84
|
+
|
|
85
|
+
res.status(self.payload.response.status)
|
|
86
|
+
|
|
87
|
+
if (self.payload.response.status >= 200 && self.payload.response.status < 300) {
|
|
88
|
+
self.assistant.log(`Finished ${resolved.command} (status=${self.payload.response.status})`, self.payload, JSON.stringify(self.payload), {environment: 'production'})
|
|
89
|
+
|
|
90
|
+
if (self.payload.response.redirect) {
|
|
91
|
+
return res.redirect(self.payload.response.redirect);
|
|
92
|
+
} else {
|
|
93
|
+
return res.json(self.payload.response.data);
|
|
94
|
+
}
|
|
83
95
|
} else {
|
|
84
|
-
console.error(`Error executing ${resolved.command} @ ${resolved.path}
|
|
85
|
-
// return res.
|
|
86
|
-
return res.
|
|
96
|
+
console.error(`Error executing ${resolved.command} @ ${resolved.path} (status=${self.payload.response.status}):`, self.payload.response.error)
|
|
97
|
+
// return res.send(self.payload.response.error.message);
|
|
98
|
+
return res.send(`${self.payload.response.error}`);
|
|
87
99
|
}
|
|
88
100
|
});
|
|
89
101
|
}
|
|
@@ -252,4 +264,16 @@ Module.prototype.resolveUser = function (options) {
|
|
|
252
264
|
});
|
|
253
265
|
};
|
|
254
266
|
|
|
267
|
+
function _fixStatus(status) {
|
|
268
|
+
if (typeof status === 'number') {
|
|
269
|
+
return status;
|
|
270
|
+
} else {
|
|
271
|
+
if (status === 'ok') {
|
|
272
|
+
return 200
|
|
273
|
+
} else {
|
|
274
|
+
return 500
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
255
279
|
module.exports = Module;
|
package/src/manager/index.js
CHANGED
|
@@ -19,6 +19,8 @@ function Manager(exporter, options) {
|
|
|
19
19
|
storage: {},
|
|
20
20
|
};
|
|
21
21
|
|
|
22
|
+
// self.isDevelopment = false;
|
|
23
|
+
|
|
22
24
|
return self;
|
|
23
25
|
}
|
|
24
26
|
|
|
@@ -36,6 +38,7 @@ Manager.prototype.init = function (exporter, options) {
|
|
|
36
38
|
options.setupFunctions = typeof options.setupFunctions === 'undefined' ? true : options.setupFunctions;
|
|
37
39
|
options.setupFunctionsLegacy = typeof options.setupFunctionsLegacy === 'undefined' ? true : options.setupFunctionsLegacy;
|
|
38
40
|
options.initializeLocalStorage = typeof options.initializeLocalStorage === 'undefined' ? false : options.initializeLocalStorage;
|
|
41
|
+
options.resourceZone = typeof options.resourceZone === 'undefined' ? 'us-central1' : options.resourceZone;
|
|
39
42
|
options.sentry = typeof options.sentry === 'undefined' ? true : options.sentry;
|
|
40
43
|
options.reportErrorsInDev = typeof options.reportErrorsInDev === 'undefined' ? false : options.reportErrorsInDev;
|
|
41
44
|
options.firebaseConfig = options.firebaseConfig;
|
|
@@ -70,7 +73,9 @@ Manager.prototype.init = function (exporter, options) {
|
|
|
70
73
|
|
|
71
74
|
// Set properties
|
|
72
75
|
self.options = options;
|
|
73
|
-
self.project = options.firebaseConfig || JSON.parse(process.env.FIREBASE_CONFIG);
|
|
76
|
+
self.project = options.firebaseConfig || JSON.parse(process.env.FIREBASE_CONFIG || '{}');
|
|
77
|
+
self.project.resourceZone = options.resourceZone;
|
|
78
|
+
|
|
74
79
|
self.cwd = process.cwd();
|
|
75
80
|
self.package = resolveProjectPackage();
|
|
76
81
|
self.config = merge(
|
|
@@ -78,10 +83,17 @@ Manager.prototype.init = function (exporter, options) {
|
|
|
78
83
|
self.libraries.functions.config()
|
|
79
84
|
);
|
|
80
85
|
|
|
86
|
+
// Init assistant
|
|
81
87
|
self.assistant = self.Assistant().init(undefined, options.assistant);
|
|
82
88
|
|
|
83
89
|
process.env.ENVIRONMENT = !process.env.ENVIRONMENT ? self.assistant.meta.environment : process.env.ENVIRONMENT;
|
|
84
90
|
|
|
91
|
+
// set more properties (need to wait for assistant to determine if DEV)
|
|
92
|
+
self.project.functionsUrl = self.assistant.meta.environment === 'development'
|
|
93
|
+
? `http://localhost:5001/${self.project.projectId}/${self.project.resourceZone}`
|
|
94
|
+
: `https://${self.project.resourceZone}-${self.project.projectId}.cloudfunctions.net`;
|
|
95
|
+
|
|
96
|
+
|
|
85
97
|
// Use the working Firebase logger that they disabled for whatever reason
|
|
86
98
|
if (self.assistant.meta.environment !== 'development' && options.useFirebaseLogger) {
|
|
87
99
|
require('firebase-functions/lib/logger/compat');
|