backend-manager 2.5.30 → 2.5.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -2
- package/src/manager/functions/core/actions/api/general/emails/general:download-app-link.js +3 -3
- package/src/manager/functions/core/actions/api/general/send-email.js +1 -1
- package/src/manager/functions/core/actions/api/user/oauth2/discord.js +1 -0
- package/src/manager/functions/core/actions/api/user/oauth2/google.js +1 -0
- package/src/manager/functions/core/actions/api/user/oauth2.js +104 -14
- package/src/manager/index.js +10 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "backend-manager",
|
|
3
|
-
"version": "2.5.
|
|
3
|
+
"version": "2.5.32",
|
|
4
4
|
"description": "Quick tools for developing Firebase functions",
|
|
5
5
|
"main": "src/manager/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -61,4 +61,4 @@
|
|
|
61
61
|
"wonderful-fetch": "^0.0.14",
|
|
62
62
|
"yargs": "^17.5.1"
|
|
63
63
|
}
|
|
64
|
-
}
|
|
64
|
+
}
|
|
@@ -14,7 +14,7 @@ module.exports = function (payload, config) {
|
|
|
14
14
|
{
|
|
15
15
|
to: [
|
|
16
16
|
{
|
|
17
|
-
name: payload.name
|
|
17
|
+
name: payload.name,
|
|
18
18
|
email: payload.email,
|
|
19
19
|
},
|
|
20
20
|
],
|
|
@@ -47,9 +47,9 @@ module.exports = function (payload, config) {
|
|
|
47
47
|
email: config.brand.email,
|
|
48
48
|
},
|
|
49
49
|
subject: subject,
|
|
50
|
-
template_id:
|
|
50
|
+
template_id: templateId,
|
|
51
51
|
asm: {
|
|
52
|
-
group_id:
|
|
52
|
+
group_id: groupId,
|
|
53
53
|
},
|
|
54
54
|
categories: ['transactional', 'download', config.app.id],
|
|
55
55
|
}
|
|
@@ -16,7 +16,7 @@ Module.prototype.main = function () {
|
|
|
16
16
|
return new Promise(async function(resolve, reject) {
|
|
17
17
|
payload.data.payload.id = payload.data.payload.id;
|
|
18
18
|
payload.data.payload.email = payload.data.payload.email;
|
|
19
|
-
payload.data.payload.name = payload.data.payload.name
|
|
19
|
+
payload.data.payload.name = payload.data.payload.name;
|
|
20
20
|
|
|
21
21
|
const DEFAULT = {
|
|
22
22
|
spamFilter: {
|
|
@@ -9,6 +9,7 @@ function OAuth2() {
|
|
|
9
9
|
self.urls = {
|
|
10
10
|
authorize: 'https://accounts.google.com/o/oauth2/v2/auth',
|
|
11
11
|
tokenize: 'https://oauth2.googleapis.com/token',
|
|
12
|
+
refresh: 'https://oauth2.googleapis.com/token',
|
|
12
13
|
// status: 'https://oauth2.googleapis.com/tokeninfo?id_token={token}'
|
|
13
14
|
status: 'https://oauth2.googleapis.com/tokeninfo',
|
|
14
15
|
removeAccess: 'https://myaccount.google.com/security',
|
|
@@ -119,19 +119,23 @@ Module.prototype.main = function () {
|
|
|
119
119
|
|
|
120
120
|
// Process by state
|
|
121
121
|
if (payload.data.payload.state === 'authorize') {
|
|
122
|
-
self.processState_authorize(newUrl)
|
|
122
|
+
self.processState_authorize(newUrl, user)
|
|
123
123
|
.then(r => {resolve(r)})
|
|
124
124
|
.catch(e => {reject(e)})
|
|
125
125
|
} else if (payload.data.payload.state === 'tokenize') {
|
|
126
|
-
self.processState_tokenize(newUrl)
|
|
126
|
+
self.processState_tokenize(newUrl, user)
|
|
127
127
|
.then(r => {resolve(r)})
|
|
128
128
|
.catch(e => {reject(e)})
|
|
129
|
+
} else if (payload.data.payload.state === 'refresh') {
|
|
130
|
+
self.processState_refresh(newUrl, user)
|
|
131
|
+
.then(r => {resolve(r)})
|
|
132
|
+
.catch(e => {reject(e)})
|
|
129
133
|
} else if (payload.data.payload.state === 'deauthorize') {
|
|
130
|
-
self.processState_deauthorize(newUrl)
|
|
134
|
+
self.processState_deauthorize(newUrl, user)
|
|
131
135
|
.then(r => {resolve(r)})
|
|
132
136
|
.catch(e => {reject(e)})
|
|
133
137
|
} else if (payload.data.payload.state === 'status') {
|
|
134
|
-
self.processState_status(newUrl)
|
|
138
|
+
self.processState_status(newUrl, user)
|
|
135
139
|
.then(r => {resolve(r)})
|
|
136
140
|
.catch(e => {reject(e)})
|
|
137
141
|
}
|
|
@@ -143,7 +147,7 @@ Module.prototype.main = function () {
|
|
|
143
147
|
|
|
144
148
|
};
|
|
145
149
|
|
|
146
|
-
Module.prototype.processState_authorize = function (newUrl) {
|
|
150
|
+
Module.prototype.processState_authorize = function (newUrl, user) {
|
|
147
151
|
const self = this;
|
|
148
152
|
const Manager = self.Manager;
|
|
149
153
|
const Api = self.Api;
|
|
@@ -162,7 +166,7 @@ Module.prototype.processState_authorize = function (newUrl) {
|
|
|
162
166
|
});
|
|
163
167
|
};
|
|
164
168
|
|
|
165
|
-
Module.prototype.processState_tokenize = function (newUrl) {
|
|
169
|
+
Module.prototype.processState_tokenize = function (newUrl, user) {
|
|
166
170
|
const self = this;
|
|
167
171
|
const Manager = self.Manager;
|
|
168
172
|
const Api = self.Api;
|
|
@@ -219,7 +223,7 @@ Module.prototype.processState_tokenize = function (newUrl) {
|
|
|
219
223
|
return reject(new Error(`Missing "refresh_token" in response. This is likely because you disconnected your account and tried to reconnect it. Visit ${self.oauth2.urls.removeAccess} and remove our app from your account and then try again or contact us if you need help!`));
|
|
220
224
|
}
|
|
221
225
|
|
|
222
|
-
const storeResponse = await self.libraries.admin.firestore().doc(`users/${
|
|
226
|
+
const storeResponse = await self.libraries.admin.firestore().doc(`users/${user.auth.uid}`)
|
|
223
227
|
.set({
|
|
224
228
|
oauth2: {
|
|
225
229
|
[payload.data.payload.provider]: {
|
|
@@ -239,7 +243,7 @@ Module.prototype.processState_tokenize = function (newUrl) {
|
|
|
239
243
|
.then(r => r)
|
|
240
244
|
.catch(e => e)
|
|
241
245
|
|
|
242
|
-
assistant.log('storeResponse', storeResponse, {environment: 'production'});
|
|
246
|
+
assistant.log('storeResponse', user.auth.uid, storeResponse, {environment: 'production'});
|
|
243
247
|
|
|
244
248
|
if (storeResponse instanceof Error) {
|
|
245
249
|
return reject(storeResponse);
|
|
@@ -252,7 +256,93 @@ Module.prototype.processState_tokenize = function (newUrl) {
|
|
|
252
256
|
});
|
|
253
257
|
};
|
|
254
258
|
|
|
255
|
-
Module.prototype.
|
|
259
|
+
Module.prototype.processState_refresh = function (newUrl, user) {
|
|
260
|
+
const self = this;
|
|
261
|
+
const Manager = self.Manager;
|
|
262
|
+
const Api = self.Api;
|
|
263
|
+
const assistant = self.assistant;
|
|
264
|
+
const payload = self.payload;
|
|
265
|
+
|
|
266
|
+
return new Promise(async function(resolve, reject) {
|
|
267
|
+
const finalUrl = newUrl.toString();
|
|
268
|
+
|
|
269
|
+
assistant.log('Running processState_refresh()', {environment: 'production'});
|
|
270
|
+
|
|
271
|
+
const body = {
|
|
272
|
+
client_id: _.get(Manager.config, `oauth2.${payload.data.payload.provider}.client_id`),
|
|
273
|
+
client_secret: _.get(Manager.config, `oauth2.${payload.data.payload.provider}.client_secret`),
|
|
274
|
+
grant_type: 'refresh_token',
|
|
275
|
+
refresh_token: _.get(user, `oauth2.${payload.data.payload.provider}.token.refresh_token`),
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
assistant.log('body', body, {environment: 'production'});
|
|
279
|
+
|
|
280
|
+
const refreshResponse = await fetch(finalUrl, {
|
|
281
|
+
method: 'POST',
|
|
282
|
+
timeout: 60000,
|
|
283
|
+
response: 'json',
|
|
284
|
+
tries: 1,
|
|
285
|
+
log: true,
|
|
286
|
+
body: new URLSearchParams(body),
|
|
287
|
+
cacheBreaker: false,
|
|
288
|
+
headers: {
|
|
289
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
290
|
+
},
|
|
291
|
+
})
|
|
292
|
+
.then(json => json)
|
|
293
|
+
.catch(e => e)
|
|
294
|
+
|
|
295
|
+
assistant.log('refreshResponse', refreshResponse, {environment: 'production'});
|
|
296
|
+
|
|
297
|
+
if (refreshResponse instanceof Error) {
|
|
298
|
+
return reject(refreshResponse);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// DISABLED .verifyIdentity() BECAUSE IT WILL TRY TO CHECK IF IT EXISTS
|
|
302
|
+
// Determine identity
|
|
303
|
+
// const verifiedIdentity = await self.oauth2.verifyIdentity(refreshResponse)
|
|
304
|
+
// .then(identity => identity)
|
|
305
|
+
// .catch(e => e);
|
|
306
|
+
|
|
307
|
+
// assistant.log('verifiedIdentity', verifiedIdentity, {environment: 'production'});
|
|
308
|
+
|
|
309
|
+
// if (verifiedIdentity instanceof Error) {
|
|
310
|
+
// return reject(verifiedIdentity);
|
|
311
|
+
// } else if (refreshResponse && !refreshResponse.refresh_token) {
|
|
312
|
+
// return reject(new Error(`Missing "refresh_token" in response. This is likely because you disconnected your account and tried to reconnect it. Visit ${self.oauth2.urls.removeAccess} and remove our app from your account and then try again or contact us if you need help!`));
|
|
313
|
+
// }
|
|
314
|
+
|
|
315
|
+
const storeResponse = await self.libraries.admin.firestore().doc(`users/${user.auth.uid}`)
|
|
316
|
+
.set({
|
|
317
|
+
oauth2: {
|
|
318
|
+
[payload.data.payload.provider]: {
|
|
319
|
+
token: refreshResponse,
|
|
320
|
+
// identity: verifiedIdentity,
|
|
321
|
+
updated: {
|
|
322
|
+
timestamp: assistant.meta.startTime.timestamp,
|
|
323
|
+
timestampUNIX: assistant.meta.startTime.timestampUNIX,
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}, { merge: true })
|
|
328
|
+
.then(r => r)
|
|
329
|
+
.catch(e => e)
|
|
330
|
+
|
|
331
|
+
assistant.log('storeResponse', user.auth.uid, storeResponse, {environment: 'production'});
|
|
332
|
+
|
|
333
|
+
if (storeResponse instanceof Error) {
|
|
334
|
+
return reject(storeResponse);
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
return resolve({
|
|
338
|
+
data: {success: true}
|
|
339
|
+
})
|
|
340
|
+
|
|
341
|
+
});
|
|
342
|
+
};
|
|
343
|
+
|
|
344
|
+
|
|
345
|
+
Module.prototype.processState_deauthorize = function (newUrl, user) {
|
|
256
346
|
const self = this;
|
|
257
347
|
const Manager = self.Manager;
|
|
258
348
|
const Api = self.Api;
|
|
@@ -260,7 +350,7 @@ Module.prototype.processState_deauthorize = function () {
|
|
|
260
350
|
const payload = self.payload;
|
|
261
351
|
|
|
262
352
|
return new Promise(async function(resolve, reject) {
|
|
263
|
-
self.libraries.admin.firestore().doc(`users/${
|
|
353
|
+
self.libraries.admin.firestore().doc(`users/${user.auth.uid}`)
|
|
264
354
|
.set({
|
|
265
355
|
oauth2: {
|
|
266
356
|
[payload.data.payload.provider]: {},
|
|
@@ -281,7 +371,7 @@ Module.prototype.processState_deauthorize = function () {
|
|
|
281
371
|
});
|
|
282
372
|
};
|
|
283
373
|
|
|
284
|
-
Module.prototype.processState_status = function (newUrl) {
|
|
374
|
+
Module.prototype.processState_status = function (newUrl, user) {
|
|
285
375
|
const self = this;
|
|
286
376
|
const Manager = self.Manager;
|
|
287
377
|
const Api = self.Api;
|
|
@@ -301,7 +391,7 @@ Module.prototype.processState_status = function (newUrl) {
|
|
|
301
391
|
return resolve();
|
|
302
392
|
}
|
|
303
393
|
|
|
304
|
-
Manager.libraries.admin.firestore().doc(`users/${
|
|
394
|
+
Manager.libraries.admin.firestore().doc(`users/${user.auth.uid}`)
|
|
305
395
|
.set({
|
|
306
396
|
oauth2: {
|
|
307
397
|
[payload.data.payload.provider]: {},
|
|
@@ -312,7 +402,7 @@ Module.prototype.processState_status = function (newUrl) {
|
|
|
312
402
|
}
|
|
313
403
|
}, { merge: true })
|
|
314
404
|
.then(async () => {
|
|
315
|
-
assistant.log(`Removed disconnected token for user: ${
|
|
405
|
+
assistant.log(`Removed disconnected token for user: ${user.auth.uid}`)
|
|
316
406
|
})
|
|
317
407
|
.catch((e) => e)
|
|
318
408
|
.finally(() => {
|
|
@@ -321,7 +411,7 @@ Module.prototype.processState_status = function (newUrl) {
|
|
|
321
411
|
});
|
|
322
412
|
}
|
|
323
413
|
|
|
324
|
-
Manager.libraries.admin.firestore().doc(`users/${
|
|
414
|
+
Manager.libraries.admin.firestore().doc(`users/${user.auth.uid}`)
|
|
325
415
|
.get()
|
|
326
416
|
.then(async (doc) => {
|
|
327
417
|
const data = doc.data();
|
package/src/manager/index.js
CHANGED
|
@@ -83,6 +83,9 @@ Manager.prototype.init = function (exporter, options) {
|
|
|
83
83
|
self.libraries.functions.config()
|
|
84
84
|
);
|
|
85
85
|
|
|
86
|
+
// Saved config
|
|
87
|
+
const appId = get(self.config, 'app.id');
|
|
88
|
+
|
|
86
89
|
// Init assistant
|
|
87
90
|
self.assistant = self.Assistant().init(undefined, options.assistant);
|
|
88
91
|
|
|
@@ -134,9 +137,13 @@ Manager.prototype.init = function (exporter, options) {
|
|
|
134
137
|
self.assistant.log('Resolved backendManagerConfigPath', self.project.backendManagerConfigPath);
|
|
135
138
|
}
|
|
136
139
|
|
|
140
|
+
if (!appId) {
|
|
141
|
+
console.warn('⚠️ Missing config.app.id');
|
|
142
|
+
}
|
|
143
|
+
|
|
137
144
|
// Setup sentry
|
|
138
145
|
if (self.options.sentry) {
|
|
139
|
-
const sentryRelease = `${
|
|
146
|
+
const sentryRelease = `${appId || self.project.projectId}@${self.package.version}`;
|
|
140
147
|
const sentryDSN = get(self.config, 'sentry.dsn', '');
|
|
141
148
|
// console.log('Sentry', sentryRelease, sentryDSN);
|
|
142
149
|
|
|
@@ -175,8 +182,8 @@ Manager.prototype.init = function (exporter, options) {
|
|
|
175
182
|
|
|
176
183
|
// const loadedProjectId = get(self.libraries.initializedAdmin, 'options_.credential.projectId', null);
|
|
177
184
|
const loadedProjectId = serviceAccount.project_id;
|
|
178
|
-
if (!loadedProjectId || !loadedProjectId.includes(
|
|
179
|
-
self.assistant.error(`Loaded app may have wrong service account: ${loadedProjectId} =/= ${
|
|
185
|
+
if (!loadedProjectId || !loadedProjectId.includes(appId)) {
|
|
186
|
+
self.assistant.error(`Loaded app may have wrong service account: ${loadedProjectId} =/= ${appId}`, {environment: 'production'});
|
|
180
187
|
}
|
|
181
188
|
}
|
|
182
189
|
|