backend-manager 4.1.0 → 4.1.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/CHANGELOG.md +6 -1
- package/package.json +6 -6
- package/src/manager/functions/core/actions/api/admin/payment-processor.js +1 -1
- package/src/manager/functions/core/actions/api/admin/run-hook.js +2 -2
- package/src/manager/functions/core/actions/api/user/validate-settings.js +1 -1
- package/src/manager/functions/core/actions/api.js +1 -1
- package/src/manager/helpers/middleware.js +15 -2
- package/src/manager/helpers/usage.js +61 -19
- package/src/manager/routes/restart/index.js +1 -1
- package/src/manager/routes/test/index.js +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -14,7 +14,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|
|
14
14
|
- `Fixed` for any bug fixes.
|
|
15
15
|
- `Security` in case of vulnerabilities.
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
---#
|
|
18
|
+
# [4.1.0] - 2024-12-19
|
|
19
|
+
### Changed
|
|
20
|
+
- Attach `schema` to `bm-properties` response header.
|
|
21
|
+
- `assistant.request.url` is now properly set for all environments (development, production, etc) and works whether called from custom domain or Firebase default function domain.
|
|
22
|
+
|
|
18
23
|
## [4.0.0] - 2024-05-08
|
|
19
24
|
### ⚠️ BREAKING
|
|
20
25
|
- Require Node.js version `18` or higher.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "backend-manager",
|
|
3
|
-
"version": "4.1.
|
|
3
|
+
"version": "4.1.2",
|
|
4
4
|
"description": "Quick tools for developing Firebase functions",
|
|
5
5
|
"main": "src/manager/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -50,10 +50,10 @@
|
|
|
50
50
|
"busboy": "^1.6.0",
|
|
51
51
|
"chalk": "^4.1.2",
|
|
52
52
|
"cors": "^2.8.5",
|
|
53
|
-
"dotenv": "^16.4.
|
|
54
|
-
"express": "^4.21.
|
|
53
|
+
"dotenv": "^16.4.7",
|
|
54
|
+
"express": "^4.21.2",
|
|
55
55
|
"firebase-admin": "^12.7.0",
|
|
56
|
-
"firebase-functions": "^6.1.
|
|
56
|
+
"firebase-functions": "^6.1.2",
|
|
57
57
|
"fs-jetpack": "^5.1.0",
|
|
58
58
|
"glob": "^11.0.0",
|
|
59
59
|
"hcaptcha": "^0.1.1",
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
"mime-types": "^2.1.35",
|
|
68
68
|
"mocha": "^8.4.0",
|
|
69
69
|
"moment": "^2.30.1",
|
|
70
|
-
"nanoid": "^3.3.
|
|
70
|
+
"nanoid": "^3.3.8",
|
|
71
71
|
"node-fetch": "^2.7.0",
|
|
72
72
|
"node-powertools": "^1.7.0",
|
|
73
73
|
"npm-api": "^1.0.1",
|
|
@@ -80,7 +80,7 @@
|
|
|
80
80
|
"uid-generator": "^2.0.0",
|
|
81
81
|
"ultimate-jekyll-poster": "^1.0.2",
|
|
82
82
|
"uuid": "^9.0.1",
|
|
83
|
-
"wonderful-fetch": "^1.
|
|
83
|
+
"wonderful-fetch": "^1.3.0",
|
|
84
84
|
"wonderful-log": "^1.0.7",
|
|
85
85
|
"yaml": "^2.6.1",
|
|
86
86
|
"yargs": "^17.7.2"
|
|
@@ -8,7 +8,7 @@ function Module() {
|
|
|
8
8
|
Module.prototype.main = function () {
|
|
9
9
|
const self = this;
|
|
10
10
|
|
|
11
|
-
//
|
|
11
|
+
// Shortcuts
|
|
12
12
|
const Manager = self.Manager;
|
|
13
13
|
const Api = self.Api;
|
|
14
14
|
const assistant = self.assistant;
|
|
@@ -55,7 +55,7 @@ Module.prototype.main = function () {
|
|
|
55
55
|
Module.prototype.loadHook = function () {
|
|
56
56
|
const self = this;
|
|
57
57
|
|
|
58
|
-
//
|
|
58
|
+
// Shortcuts
|
|
59
59
|
const Manager = self.Manager;
|
|
60
60
|
const assistant = self.assistant;
|
|
61
61
|
const payload = self.payload;
|
|
@@ -331,7 +331,7 @@ function resolveBasePath(basePath, command) {
|
|
|
331
331
|
Module.prototype.resolveApiPath = function (command) {
|
|
332
332
|
const self = this;
|
|
333
333
|
|
|
334
|
-
//
|
|
334
|
+
// Shortcuts
|
|
335
335
|
const Manager = self.Manager;
|
|
336
336
|
const libraries = self.libraries;
|
|
337
337
|
const assistant = self.assistant;
|
|
@@ -18,7 +18,7 @@ function Middleware(m, req, res) {
|
|
|
18
18
|
Middleware.prototype.run = function (libPath, options) {
|
|
19
19
|
const self = this;
|
|
20
20
|
|
|
21
|
-
//
|
|
21
|
+
// Shortcuts
|
|
22
22
|
const Manager = self.Manager;
|
|
23
23
|
const req = self.req;
|
|
24
24
|
const res = self.res;
|
|
@@ -27,11 +27,17 @@ Middleware.prototype.run = function (libPath, options) {
|
|
|
27
27
|
return cors(req, res, async () => {
|
|
28
28
|
const assistant = Manager.Assistant({req: req, res: res});
|
|
29
29
|
|
|
30
|
+
// Set properties
|
|
30
31
|
const data = assistant.request.data;
|
|
31
32
|
const headers = assistant.request.headers;
|
|
33
|
+
const method = assistant.request.method;
|
|
34
|
+
const url = assistant.request.url;
|
|
32
35
|
const geolocation = assistant.request.geolocation;
|
|
33
36
|
const client = assistant.request.client;
|
|
34
37
|
|
|
38
|
+
// Strip URL
|
|
39
|
+
const strippedUrl = stripUrl(url);
|
|
40
|
+
|
|
35
41
|
// Set options
|
|
36
42
|
options = options || {};
|
|
37
43
|
options.authenticate = typeof options.authenticate === 'boolean' ? options.authenticate : true;
|
|
@@ -47,7 +53,7 @@ Middleware.prototype.run = function (libPath, options) {
|
|
|
47
53
|
options.schemasDir = typeof options.schemasDir === 'undefined' ? `${Manager.cwd}/schemas` : options.schemasDir;
|
|
48
54
|
|
|
49
55
|
// Log
|
|
50
|
-
assistant.log(`Middleware.process(): Request (${geolocation.ip} @ ${geolocation.country}, ${geolocation.region}, ${geolocation.city})`, JSON.stringify(data));
|
|
56
|
+
assistant.log(`Middleware.process(): Request (${geolocation.ip} @ ${geolocation.country}, ${geolocation.region}, ${geolocation.city}) [${method} > ${strippedUrl}]`, JSON.stringify(data));
|
|
51
57
|
assistant.log(`Middleware.process(): Headers`, JSON.stringify(headers));
|
|
52
58
|
|
|
53
59
|
// Set paths
|
|
@@ -62,6 +68,7 @@ Middleware.prototype.run = function (libPath, options) {
|
|
|
62
68
|
}
|
|
63
69
|
|
|
64
70
|
// Load library
|
|
71
|
+
// TODO: Support for methods, so first check for method specific file then fallback to index.js
|
|
65
72
|
let library;
|
|
66
73
|
try {
|
|
67
74
|
libPath = path.resolve(routesDir, `index.js`);
|
|
@@ -153,4 +160,10 @@ function clean(obj) {
|
|
|
153
160
|
}
|
|
154
161
|
}
|
|
155
162
|
|
|
163
|
+
function stripUrl(url) {
|
|
164
|
+
const newUrl = new URL(url);
|
|
165
|
+
|
|
166
|
+
return `${newUrl.hostname}${newUrl.pathname}`.replace(/\/$/, '');
|
|
167
|
+
}
|
|
168
|
+
|
|
156
169
|
module.exports = Middleware;
|
|
@@ -107,21 +107,15 @@ Usage.prototype.init = function (assistant, options) {
|
|
|
107
107
|
|
|
108
108
|
// Get app data to get plan limits using cached data if possible
|
|
109
109
|
if (diff > 1 || options.refetch) {
|
|
110
|
-
await
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
self.storage.set(`${self.paths.app}.data`, json).write();
|
|
120
|
-
self.storage.set(`${self.paths.app}.lastFetched`, new Date().toISOString()).write();
|
|
121
|
-
})
|
|
122
|
-
.catch(e => {
|
|
123
|
-
assistant.errorify(`Usage.init(): Error fetching app data: ${e}`, {code: 500, sentry: true});
|
|
124
|
-
})
|
|
110
|
+
await self.getApp(options.app)
|
|
111
|
+
.then((json) => {
|
|
112
|
+
// Write data and last fetched to storage
|
|
113
|
+
self.storage.set(`${self.paths.app}.data`, json).write();
|
|
114
|
+
self.storage.set(`${self.paths.app}.lastFetched`, new Date().toISOString()).write();
|
|
115
|
+
})
|
|
116
|
+
.catch(e => {
|
|
117
|
+
assistant.errorify(`Usage.init(): Error fetching app data: ${e}`, {code: 500, sentry: true});
|
|
118
|
+
});
|
|
125
119
|
}
|
|
126
120
|
|
|
127
121
|
// Get app data
|
|
@@ -311,14 +305,17 @@ Usage.prototype.getLimit = function (name) {
|
|
|
311
305
|
Usage.prototype.update = function () {
|
|
312
306
|
const self = this;
|
|
313
307
|
|
|
308
|
+
// Shortcuts
|
|
309
|
+
const Manager = self.Manager;
|
|
310
|
+
const assistant = self.assistant;
|
|
311
|
+
|
|
314
312
|
return new Promise(async function(resolve, reject) {
|
|
315
|
-
const
|
|
316
|
-
const assistant = self.assistant;
|
|
313
|
+
const { admin } = Manager.libraries;
|
|
317
314
|
|
|
318
315
|
// Write self.user to firestore or local if no user or if key is set
|
|
319
316
|
if (self.useUnauthenticatedStorage) {
|
|
320
317
|
if (self.options.unauthenticatedMode === 'firestore') {
|
|
321
|
-
|
|
318
|
+
admin.firestore().doc(`temporary/${self.key}`)
|
|
322
319
|
.set({
|
|
323
320
|
usage: self.user.usage,
|
|
324
321
|
}, {merge: true})
|
|
@@ -338,7 +335,7 @@ Usage.prototype.update = function () {
|
|
|
338
335
|
return resolve(self.user.usage);
|
|
339
336
|
}
|
|
340
337
|
} else {
|
|
341
|
-
|
|
338
|
+
admin.firestore().doc(`users/${self.user.auth.uid}`)
|
|
342
339
|
.set({
|
|
343
340
|
usage: self.user.usage,
|
|
344
341
|
}, {merge: true})
|
|
@@ -378,4 +375,49 @@ Usage.prototype.log = function () {
|
|
|
378
375
|
}
|
|
379
376
|
};
|
|
380
377
|
|
|
378
|
+
Usage.prototype.getApp = function (id) {
|
|
379
|
+
const self = this;
|
|
380
|
+
|
|
381
|
+
// Shortcuts
|
|
382
|
+
const Manager = self.Manager;
|
|
383
|
+
const assistant = self.assistant;
|
|
384
|
+
|
|
385
|
+
return new Promise(function(resolve, reject) {
|
|
386
|
+
const { admin } = Manager.libraries;
|
|
387
|
+
|
|
388
|
+
try {
|
|
389
|
+
// If we're on ITW, we can read directly from Firestore
|
|
390
|
+
// If we don't do this, calling getApp on ITW will call getApp on ITW again and again
|
|
391
|
+
if (Manager.config.app.id === 'itw-creative-works') {
|
|
392
|
+
admin.firestore().doc(`apps/${id}`)
|
|
393
|
+
.get()
|
|
394
|
+
.then((r) => {
|
|
395
|
+
const data = r.data();
|
|
396
|
+
|
|
397
|
+
// Check for data
|
|
398
|
+
if (!data) {
|
|
399
|
+
return reject(new Error('No data found'));
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
// Resolve
|
|
403
|
+
return resolve(data);
|
|
404
|
+
})
|
|
405
|
+
.catch((e) => reject(e));
|
|
406
|
+
} else {
|
|
407
|
+
fetch('https://us-central1-itw-creative-works.cloudfunctions.net/getApp', {
|
|
408
|
+
method: 'post',
|
|
409
|
+
response: 'json',
|
|
410
|
+
body: {
|
|
411
|
+
id: id,
|
|
412
|
+
},
|
|
413
|
+
})
|
|
414
|
+
.then((json) => resolve(json))
|
|
415
|
+
.catch((e) => reject(e));
|
|
416
|
+
}
|
|
417
|
+
} catch (e) {
|
|
418
|
+
return reject(e);
|
|
419
|
+
}
|
|
420
|
+
});
|
|
421
|
+
};
|
|
422
|
+
|
|
381
423
|
module.exports = Usage;
|