backend-manager 5.0.76 → 5.0.78
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 +1 -1
- package/src/manager/cron/daily/ghostii-auto-publisher.js +44 -26
- package/src/manager/functions/core/actions/api/firebase/get-providers.js +2 -46
- package/src/manager/functions/core/actions/api/general/send-email.js +1 -1
- package/src/manager/functions/core/actions/api/special/setup-electron-manager-client.js +14 -29
- package/src/manager/functions/core/actions/api/user/submit-feedback.js +30 -44
- package/src/manager/functions/core/actions/api.js +1 -1
- package/src/manager/helpers/analytics.js +10 -10
- package/src/manager/helpers/api-manager.js +1 -1
- package/src/manager/helpers/assistant.js +28 -57
- package/src/manager/helpers/middleware.js +2 -1
- package/src/manager/helpers/usage.js +1 -1
- package/src/manager/helpers/user.js +23 -23
- package/src/manager/index.js +0 -31
- package/src/manager/libraries/openai.js +1 -1
- package/src/manager/routes/app/get.js +40 -0
- package/src/manager/routes/general/email/post.js +1 -1
- package/src/manager/routes/special/electron-client/post.js +4 -18
- package/src/manager/routes/user/feedback/post.js +2 -12
- package/src/manager/schemas/app/get.js +1 -0
- package/templates/backend-manager-config.json +9 -0
- package/src/manager/routes/firebase/providers/get.js +0 -80
- package/src/manager/schemas/firebase/providers/get.js +0 -6
package/package.json
CHANGED
|
@@ -16,7 +16,6 @@ const USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
|
|
|
16
16
|
|
|
17
17
|
// State
|
|
18
18
|
let postId;
|
|
19
|
-
let appObject;
|
|
20
19
|
|
|
21
20
|
/**
|
|
22
21
|
* Ghostii Auto Publisher cron job
|
|
@@ -30,11 +29,8 @@ module.exports = async ({ Manager, assistant, context, libraries }) => {
|
|
|
30
29
|
// Set post ID
|
|
31
30
|
postId = moment().unix();
|
|
32
31
|
|
|
33
|
-
//
|
|
34
|
-
appObject =
|
|
35
|
-
if (appObject instanceof Error) {
|
|
36
|
-
throw appObject;
|
|
37
|
-
}
|
|
32
|
+
// Build app object from local config
|
|
33
|
+
const appObject = buildAppObject(Manager.config);
|
|
38
34
|
|
|
39
35
|
// Log
|
|
40
36
|
assistant.log('App object', appObject);
|
|
@@ -44,8 +40,6 @@ module.exports = async ({ Manager, assistant, context, libraries }) => {
|
|
|
44
40
|
|
|
45
41
|
// Loop through each item
|
|
46
42
|
for (const settings of settingsArray) {
|
|
47
|
-
const appId = settings.app || appObject.id;
|
|
48
|
-
|
|
49
43
|
// Fix settings
|
|
50
44
|
settings.articles = settings.articles || 0;
|
|
51
45
|
settings.sources = randomize(settings.sources || []);
|
|
@@ -53,16 +47,23 @@ module.exports = async ({ Manager, assistant, context, libraries }) => {
|
|
|
53
47
|
settings.prompt = settings.prompt || '';
|
|
54
48
|
settings.chance = settings.chance || 1.0;
|
|
55
49
|
settings.author = settings.author || undefined;
|
|
56
|
-
settings.app = await getAppData(appId).catch((e) => e);
|
|
57
50
|
|
|
58
|
-
//
|
|
59
|
-
if (settings.app
|
|
60
|
-
|
|
61
|
-
|
|
51
|
+
// Resolve app data for this ghostii item
|
|
52
|
+
if (settings.app && settings.appUrl) {
|
|
53
|
+
// Cross-app: fetch from the other project's /app endpoint
|
|
54
|
+
settings.app = await fetchRemoteApp(settings.appUrl).catch((e) => e);
|
|
55
|
+
|
|
56
|
+
if (settings.app instanceof Error) {
|
|
57
|
+
assistant.error('Error fetching remote app data', settings.app);
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
} else {
|
|
61
|
+
// Same-app: use local config
|
|
62
|
+
settings.app = appObject;
|
|
62
63
|
}
|
|
63
64
|
|
|
64
65
|
// Log
|
|
65
|
-
assistant.log(`Settings (app=${
|
|
66
|
+
assistant.log(`Settings (app=${settings.app.id})`, settings);
|
|
66
67
|
|
|
67
68
|
// Quit if articles are disabled
|
|
68
69
|
if (!settings.articles || !settings.sources.length) {
|
|
@@ -88,6 +89,35 @@ module.exports = async ({ Manager, assistant, context, libraries }) => {
|
|
|
88
89
|
}
|
|
89
90
|
};
|
|
90
91
|
|
|
92
|
+
/**
|
|
93
|
+
* Build app object from Manager.config (same shape as getApp response)
|
|
94
|
+
*/
|
|
95
|
+
function buildAppObject(config) {
|
|
96
|
+
return {
|
|
97
|
+
id: config.app?.id,
|
|
98
|
+
name: config.brand?.name,
|
|
99
|
+
brand: {
|
|
100
|
+
description: config.brand?.description || '',
|
|
101
|
+
},
|
|
102
|
+
url: config.brand?.url,
|
|
103
|
+
github: {
|
|
104
|
+
user: config.github?.user,
|
|
105
|
+
repo: (config.github?.repo_website || '').split('/').pop(),
|
|
106
|
+
},
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Fetch app data from a remote BEM project's /app endpoint
|
|
112
|
+
*/
|
|
113
|
+
function fetchRemoteApp(appUrl) {
|
|
114
|
+
return fetch(`${appUrl}/backend-manager/app`, {
|
|
115
|
+
timeout: 30000,
|
|
116
|
+
tries: 3,
|
|
117
|
+
response: 'json',
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
91
121
|
async function harvest(assistant, settings) {
|
|
92
122
|
const date = moment().format('MMMM YYYY');
|
|
93
123
|
|
|
@@ -151,18 +181,6 @@ async function harvest(assistant, settings) {
|
|
|
151
181
|
}
|
|
152
182
|
}
|
|
153
183
|
|
|
154
|
-
function getAppData(id) {
|
|
155
|
-
return fetch('https://us-central1-itw-creative-works.cloudfunctions.net/getApp', {
|
|
156
|
-
method: 'post',
|
|
157
|
-
timeout: 30000,
|
|
158
|
-
tries: 3,
|
|
159
|
-
response: 'json',
|
|
160
|
-
body: {
|
|
161
|
-
id: id,
|
|
162
|
-
},
|
|
163
|
-
});
|
|
164
|
-
}
|
|
165
|
-
|
|
166
184
|
function getURLContent(url) {
|
|
167
185
|
return fetch(url, {
|
|
168
186
|
timeout: 30000,
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
const fetch = require('wonderful-fetch');
|
|
2
1
|
const { merge } = require('lodash');
|
|
3
2
|
|
|
4
3
|
function Module() {
|
|
@@ -8,9 +7,7 @@ function Module() {
|
|
|
8
7
|
Module.prototype.main = function () {
|
|
9
8
|
const self = this;
|
|
10
9
|
const Manager = self.Manager;
|
|
11
|
-
const Api = self.Api;
|
|
12
10
|
const assistant = self.assistant;
|
|
13
|
-
const payload = self.payload;
|
|
14
11
|
|
|
15
12
|
return new Promise(async function(resolve, reject) {
|
|
16
13
|
const defaultProviders = {
|
|
@@ -40,14 +37,8 @@ Module.prototype.main = function () {
|
|
|
40
37
|
},
|
|
41
38
|
}
|
|
42
39
|
|
|
43
|
-
//
|
|
44
|
-
const
|
|
45
|
-
if (appObject instanceof Error) {
|
|
46
|
-
return reject(assistant.errorify(`Failed to get app object: ${appObject}`, {code: 500}));
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// Merge the default providers with the app providers
|
|
50
|
-
const providers = merge(defaultProviders, appObject.authentication);
|
|
40
|
+
// Merge the default providers with the config providers
|
|
41
|
+
const providers = merge(defaultProviders, Manager.config.authentication || {});
|
|
51
42
|
|
|
52
43
|
// Reformat the object so it's just provider=true/false
|
|
53
44
|
const finalProviders = {};
|
|
@@ -64,39 +55,4 @@ Module.prototype.main = function () {
|
|
|
64
55
|
|
|
65
56
|
};
|
|
66
57
|
|
|
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
|
-
}
|
|
86
|
-
})
|
|
87
|
-
.then((r) => {
|
|
88
|
-
assistant.log('getAppObject(): Response', r);
|
|
89
|
-
|
|
90
|
-
// If data is missing, return an error
|
|
91
|
-
if (!r) {
|
|
92
|
-
throw new Error(`App with id ${id} not found`);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
// Return the app object
|
|
96
|
-
return resolve(r);
|
|
97
|
-
})
|
|
98
|
-
.catch(e => reject(e));
|
|
99
|
-
});
|
|
100
|
-
};
|
|
101
|
-
|
|
102
58
|
module.exports = Module;
|
|
@@ -49,7 +49,7 @@ Module.prototype.main = function () {
|
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
const storage = Manager.storage({temporary: true});
|
|
52
|
-
const ipPath = ['api:general:send-email', 'ips', assistant.request.geolocation.ip];
|
|
52
|
+
const ipPath = ['api:general:send-email', 'ips', assistant.request.geolocation.ip || 'unknown'];
|
|
53
53
|
const emailPath = ['api:general:send-email', 'emails', payload.data.payload.email];
|
|
54
54
|
|
|
55
55
|
const ipData = storage.get(ipPath).value() || {};
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const { buildPublicConfig } = require(path.join(__dirname, '..', '..', '..', '..', '..', 'routes', 'app', 'get.js'));
|
|
3
|
+
|
|
1
4
|
function Module() {
|
|
2
5
|
|
|
3
6
|
}
|
|
@@ -11,10 +14,7 @@ Module.prototype.main = function () {
|
|
|
11
14
|
|
|
12
15
|
return new Promise(async function(resolve, reject) {
|
|
13
16
|
|
|
14
|
-
const fetch = Manager.require('wonderful-fetch');
|
|
15
|
-
|
|
16
17
|
let uid = payload.data.payload.uid;
|
|
17
|
-
const app = payload.data.payload.appId || payload.data.payload.app || Manager.config.app.id;
|
|
18
18
|
let config = payload.data.payload.config || {};
|
|
19
19
|
|
|
20
20
|
let uuid = null;
|
|
@@ -68,32 +68,17 @@ Module.prototype.main = function () {
|
|
|
68
68
|
config = {};
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
return resolve({
|
|
83
|
-
data: {
|
|
84
|
-
uuid: uuid,
|
|
85
|
-
signInToken: signInToken,
|
|
86
|
-
timestamp: new Date().toISOString(),
|
|
87
|
-
ip: assistant.request.geolocation.ip,
|
|
88
|
-
country: assistant.request.geolocation.country,
|
|
89
|
-
app: result,
|
|
90
|
-
config: config,
|
|
91
|
-
}
|
|
92
|
-
});
|
|
93
|
-
})
|
|
94
|
-
.catch(e => {
|
|
95
|
-
return reject(assistant.errorify(`Error fetching app details: ${e}`, {code: 500}));
|
|
96
|
-
})
|
|
71
|
+
return resolve({
|
|
72
|
+
data: {
|
|
73
|
+
uuid: uuid,
|
|
74
|
+
signInToken: signInToken,
|
|
75
|
+
timestamp: new Date().toISOString(),
|
|
76
|
+
ip: assistant.request.geolocation.ip,
|
|
77
|
+
country: assistant.request.geolocation.country,
|
|
78
|
+
app: buildPublicConfig(Manager.config),
|
|
79
|
+
config: config,
|
|
80
|
+
}
|
|
81
|
+
});
|
|
97
82
|
|
|
98
83
|
});
|
|
99
84
|
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
const pushid = require('pushid');
|
|
2
|
-
const fetch = require('wonderful-fetch');
|
|
3
2
|
const powertools = require('node-powertools');
|
|
4
3
|
|
|
5
4
|
function Module() {
|
|
@@ -34,55 +33,42 @@ Module.prototype.main = function () {
|
|
|
34
33
|
decision.promptReview = true;
|
|
35
34
|
}
|
|
36
35
|
|
|
37
|
-
// Get
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
body: {
|
|
42
|
-
id: Manager.config.app.id,
|
|
43
|
-
}
|
|
44
|
-
})
|
|
45
|
-
.then((response) => {
|
|
46
|
-
response.reviews = response.reviews || {};
|
|
47
|
-
response.reviews.enabled = typeof response.reviews.enabled === 'undefined' ? true : response.reviews.enabled;
|
|
48
|
-
response.reviews.sites = response.reviews.sites || [];
|
|
36
|
+
// Get review config from local config
|
|
37
|
+
const reviews = { ...(Manager.config.reviews || {}) };
|
|
38
|
+
reviews.enabled = typeof reviews.enabled === 'undefined' ? true : reviews.enabled;
|
|
39
|
+
reviews.sites = reviews.sites || [];
|
|
49
40
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
41
|
+
// If reviews are enabled and there are review sites, prompt review
|
|
42
|
+
if (decision.promptReview && reviews.enabled && reviews.sites.length > 0) {
|
|
43
|
+
decision.reviewURL = powertools.random(reviews.sites);
|
|
44
|
+
} else {
|
|
45
|
+
decision.promptReview = false;
|
|
46
|
+
}
|
|
56
47
|
|
|
57
|
-
|
|
48
|
+
assistant.log('Feedback submitted', docId, {appReviewData: reviews, request: request, decision: decision});
|
|
58
49
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
})
|
|
78
|
-
.catch((e) => {
|
|
79
|
-
return reject(assistant.errorify(`Failed to save feedback: ${e.message}`, {code: 500, sentry: true}));
|
|
80
|
-
})
|
|
50
|
+
// Save feedback to firestore
|
|
51
|
+
self.libraries.admin.firestore().doc(`feedback/${docId}`)
|
|
52
|
+
.set({
|
|
53
|
+
created: assistant.meta.startTime,
|
|
54
|
+
feedback: request,
|
|
55
|
+
decision: decision,
|
|
56
|
+
owner: {
|
|
57
|
+
uid: user?.auth?.uid ?? null,
|
|
58
|
+
},
|
|
59
|
+
metadata: Manager.Metadata().set({tag: 'user:submit-feedback'}),
|
|
60
|
+
}, {merge: true})
|
|
61
|
+
.then(r => {
|
|
62
|
+
return resolve({
|
|
63
|
+
data: {
|
|
64
|
+
review: decision,
|
|
65
|
+
originalRequest: request,
|
|
66
|
+
}
|
|
67
|
+
});
|
|
81
68
|
})
|
|
82
69
|
.catch((e) => {
|
|
83
|
-
return reject(assistant.errorify(`Failed to
|
|
70
|
+
return reject(assistant.errorify(`Failed to save feedback: ${e.message}`, {code: 500, sentry: true}));
|
|
84
71
|
})
|
|
85
|
-
|
|
86
72
|
})
|
|
87
73
|
.catch((e) => {
|
|
88
74
|
return reject(e);
|
|
@@ -82,7 +82,7 @@ Module.prototype.main = function() {
|
|
|
82
82
|
// Log
|
|
83
83
|
// assistant.log(`Executing: ${resolved.command}`, self.payload, JSON.stringify(self.payload))
|
|
84
84
|
// assistant.log(`Resolved URL: ${Manager.project.functionsUrl}?command=${encodeURIComponent(resolved.command)}&payload=${encodeURIComponent(JSON.stringify(self.assistant.request.data.payload))}`)
|
|
85
|
-
assistant.log(`bm_api(${resolved.command}): Request (${geolocation.ip} @ ${geolocation.country}, ${geolocation.region}, ${geolocation.city}) [${method} > ${strippedUrl}]`, JSON.stringify(assistant.request.data));
|
|
85
|
+
assistant.log(`bm_api(${resolved.command}): Request (${geolocation.ip || 'unknown'} @ ${geolocation.country || '?'}, ${geolocation.region || '?'}, ${geolocation.city || '?'}) [${method} > ${strippedUrl}]`, JSON.stringify(assistant.request.data));
|
|
86
86
|
assistant.log(`bm_api(${resolved.command}): Headers`, JSON.stringify(headers));
|
|
87
87
|
|
|
88
88
|
|
|
@@ -23,21 +23,21 @@ function Analytics(Manager, options) {
|
|
|
23
23
|
|
|
24
24
|
// Set request properties
|
|
25
25
|
self.request = {
|
|
26
|
-
ip: self.assistant?.request?.geolocation?.ip ||
|
|
27
|
-
country: self.assistant?.request?.geolocation?.country ||
|
|
28
|
-
city: self.assistant?.request?.geolocation?.city ||
|
|
29
|
-
region: self.assistant?.request?.geolocation?.region ||
|
|
30
|
-
referrer: self.assistant?.request?.referrer ||
|
|
31
|
-
userAgent: self.assistant?.request?.client?.userAgent ||
|
|
32
|
-
language: (self.assistant?.request?.client?.language || '').split(',')[0],
|
|
26
|
+
ip: self.assistant?.request?.geolocation?.ip || null,
|
|
27
|
+
country: self.assistant?.request?.geolocation?.country || null,
|
|
28
|
+
city: self.assistant?.request?.geolocation?.city || null,
|
|
29
|
+
region: self.assistant?.request?.geolocation?.region || null,
|
|
30
|
+
referrer: self.assistant?.request?.referrer || null,
|
|
31
|
+
userAgent: self.assistant?.request?.client?.userAgent || null,
|
|
32
|
+
language: (self.assistant?.request?.client?.language || '').split(',')[0] || null,
|
|
33
33
|
mobile: self.assistant?.request?.client?.mobile || false,
|
|
34
|
-
platform: self.assistant?.request?.client?.platform ||
|
|
34
|
+
platform: self.assistant?.request?.client?.platform || null,
|
|
35
35
|
name: self.assistant?.meta?.name || '',
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
// Remove blacklisted user agents
|
|
39
|
-
self.request.userAgent = BLOCKED_USER_AGENTS.some((regex) => self.request.userAgent.match(regex))
|
|
40
|
-
?
|
|
39
|
+
self.request.userAgent = self.request.userAgent && BLOCKED_USER_AGENTS.some((regex) => self.request.userAgent.match(regex))
|
|
40
|
+
? null
|
|
41
41
|
: self.request.userAgent;
|
|
42
42
|
|
|
43
43
|
// Fix options
|
|
@@ -170,7 +170,7 @@ ApiManager.prototype.getUser = async function (assistant) {
|
|
|
170
170
|
// console.log('---authenticatedUser', authenticatedUser);
|
|
171
171
|
const planId = authenticatedUser?.subscription?.product?.id || 'basic';
|
|
172
172
|
let workingUID = !authenticatedUser.authenticated
|
|
173
|
-
? uuidv5(assistant.request.geolocation.ip, '1b671a64-40d5-491e-99b0-da01ff1f3341')
|
|
173
|
+
? uuidv5(assistant.request.geolocation.ip || 'unknown', '1b671a64-40d5-491e-99b0-da01ff1f3341')
|
|
174
174
|
: authenticatedUser.auth.uid
|
|
175
175
|
authenticatedUser.ip = assistant.request.geolocation.ip;
|
|
176
176
|
authenticatedUser.country = assistant.request.geolocation.country;
|
|
@@ -792,43 +792,35 @@ BackendAssistant.prototype.parseRepo = function (repo) {
|
|
|
792
792
|
BackendAssistant.prototype.getHeaderIp = function (headers) {
|
|
793
793
|
headers = headers || {};
|
|
794
794
|
|
|
795
|
-
|
|
795
|
+
const value =
|
|
796
796
|
// these are present for cloudflare requests (11/21/2020)
|
|
797
797
|
headers['cf-connecting-ip']
|
|
798
798
|
|| headers['fastly-temp-xff']
|
|
799
799
|
|
|
800
800
|
// these are present for non-cloudflare requests (11/21/2020)
|
|
801
801
|
|| headers['x-appengine-user-ip']
|
|
802
|
-
|| headers['x-forwarded-for']
|
|
802
|
+
|| headers['x-forwarded-for'];
|
|
803
803
|
|
|
804
804
|
// Not sure about these
|
|
805
805
|
// || headers['fastly-client-ip']
|
|
806
806
|
|
|
807
|
-
|
|
808
|
-
|| '127.0.0.1'
|
|
809
|
-
)
|
|
810
|
-
.split(',')[0]
|
|
811
|
-
.trim();
|
|
807
|
+
return value ? value.split(',')[0].trim() : null;
|
|
812
808
|
}
|
|
813
809
|
|
|
814
810
|
BackendAssistant.prototype.getHeaderContinent = function (headers) {
|
|
815
811
|
headers = headers || {};
|
|
816
812
|
|
|
817
|
-
|
|
813
|
+
const value =
|
|
818
814
|
// these are present for cloudflare requests (11/21/2020)
|
|
819
|
-
headers['cf-ipcontinent']
|
|
815
|
+
headers['cf-ipcontinent'];
|
|
820
816
|
|
|
821
|
-
|
|
822
|
-
|| 'ZZ'
|
|
823
|
-
)
|
|
824
|
-
.split(',')[0]
|
|
825
|
-
.trim();
|
|
817
|
+
return value ? value.split(',')[0].trim() : null;
|
|
826
818
|
}
|
|
827
819
|
|
|
828
820
|
BackendAssistant.prototype.getHeaderCountry = function (headers) {
|
|
829
821
|
headers = headers || {};
|
|
830
822
|
|
|
831
|
-
|
|
823
|
+
const value =
|
|
832
824
|
// these are present for cloudflare requests (11/21/2020)
|
|
833
825
|
headers['cf-ipcountry']
|
|
834
826
|
|
|
@@ -836,46 +828,34 @@ BackendAssistant.prototype.getHeaderCountry = function (headers) {
|
|
|
836
828
|
|| headers['x-country-code']
|
|
837
829
|
|
|
838
830
|
// these are present for non-cloudflare requests (11/21/2020)
|
|
839
|
-
|| headers['x-appengine-country']
|
|
831
|
+
|| headers['x-appengine-country'];
|
|
840
832
|
|
|
841
|
-
|
|
842
|
-
|| 'ZZ'
|
|
843
|
-
)
|
|
844
|
-
.split(',')[0]
|
|
845
|
-
.trim();
|
|
833
|
+
return value ? value.split(',')[0].trim() : null;
|
|
846
834
|
}
|
|
847
835
|
|
|
848
836
|
BackendAssistant.prototype.getHeaderRegion = function (headers) {
|
|
849
837
|
headers = headers || {};
|
|
850
838
|
|
|
851
|
-
|
|
839
|
+
const value =
|
|
852
840
|
// these are present for cloudflare requests (11/21/2020)
|
|
853
841
|
headers['cf-region']
|
|
854
842
|
|
|
855
843
|
// these are present for non-cloudflare requests (11/21/2020)
|
|
856
|
-
|| headers['x-appengine-region']
|
|
844
|
+
|| headers['x-appengine-region'];
|
|
857
845
|
|
|
858
|
-
|
|
859
|
-
|| 'Unknown'
|
|
860
|
-
)
|
|
861
|
-
.split(',')[0]
|
|
862
|
-
.trim();
|
|
846
|
+
return value ? value.split(',')[0].trim() : null;
|
|
863
847
|
}
|
|
864
848
|
|
|
865
849
|
BackendAssistant.prototype.getHeaderCity = function (headers) {
|
|
866
850
|
headers = headers || {};
|
|
867
851
|
|
|
868
|
-
|
|
852
|
+
const value =
|
|
869
853
|
// these are present for cloudflare requests (11/21/2020)
|
|
870
854
|
headers['cf-ipcity']
|
|
871
855
|
|
|
872
|
-
|| headers['x-appengine-city']
|
|
856
|
+
|| headers['x-appengine-city'];
|
|
873
857
|
|
|
874
|
-
|
|
875
|
-
|| 'Unknown'
|
|
876
|
-
)
|
|
877
|
-
.split(',')[0]
|
|
878
|
-
.trim();
|
|
858
|
+
return value ? value.split(',')[0].trim() : null;
|
|
879
859
|
}
|
|
880
860
|
|
|
881
861
|
BackendAssistant.prototype.getHeaderLatitude = function (headers) {
|
|
@@ -914,33 +894,27 @@ BackendAssistant.prototype.getHeaderLongitude = function (headers) {
|
|
|
914
894
|
BackendAssistant.prototype.getHeaderUserAgent = function (headers) {
|
|
915
895
|
headers = headers || {};
|
|
916
896
|
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
)
|
|
921
|
-
.trim();
|
|
897
|
+
const value = headers['user-agent'];
|
|
898
|
+
|
|
899
|
+
return value ? value.trim() : null;
|
|
922
900
|
}
|
|
923
901
|
|
|
924
902
|
BackendAssistant.prototype.getHeaderLanguage = function (headers) {
|
|
925
903
|
headers = headers || {};
|
|
926
904
|
|
|
927
|
-
|
|
905
|
+
const value =
|
|
928
906
|
headers['accept-language']
|
|
929
|
-
|| headers['x-orig-accept-language']
|
|
930
|
-
|
|
931
|
-
)
|
|
932
|
-
.trim();
|
|
907
|
+
|| headers['x-orig-accept-language'];
|
|
908
|
+
|
|
909
|
+
return value ? value.trim() : null;
|
|
933
910
|
}
|
|
934
911
|
|
|
935
912
|
BackendAssistant.prototype.getHeaderPlatform = function (headers) {
|
|
936
913
|
headers = headers || {};
|
|
937
914
|
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
)
|
|
942
|
-
.replace(/"/ig, '')
|
|
943
|
-
.trim();
|
|
915
|
+
const value = headers['sec-ch-ua-platform'];
|
|
916
|
+
|
|
917
|
+
return value ? value.replace(/"/ig, '').trim() : null;
|
|
944
918
|
}
|
|
945
919
|
|
|
946
920
|
BackendAssistant.prototype.getHeaderMobile = function (headers) {
|
|
@@ -956,7 +930,7 @@ BackendAssistant.prototype.getHeaderUrl = function (headers) {
|
|
|
956
930
|
const self = this;
|
|
957
931
|
headers = headers || {};
|
|
958
932
|
|
|
959
|
-
|
|
933
|
+
const value =
|
|
960
934
|
// Origin header (most reliable for CORS requests)
|
|
961
935
|
headers['origin']
|
|
962
936
|
|
|
@@ -965,12 +939,9 @@ BackendAssistant.prototype.getHeaderUrl = function (headers) {
|
|
|
965
939
|
|| headers['referer']
|
|
966
940
|
|
|
967
941
|
// Reconstruct from host and path if available
|
|
968
|
-
|| (headers['host'] ? `https://${headers['host']}${self.ref.req?.originalUrl || self.ref.req?.url || ''}` :
|
|
942
|
+
|| (headers['host'] ? `https://${headers['host']}${self.ref.req?.originalUrl || self.ref.req?.url || ''}` : null);
|
|
969
943
|
|
|
970
|
-
|
|
971
|
-
|| ''
|
|
972
|
-
)
|
|
973
|
-
.trim();
|
|
944
|
+
return value ? value.trim() : null;
|
|
974
945
|
}
|
|
975
946
|
|
|
976
947
|
/**
|
|
@@ -78,7 +78,7 @@ Middleware.prototype.run = function (libPath, options) {
|
|
|
78
78
|
const strippedUrl = stripUrl(url);
|
|
79
79
|
|
|
80
80
|
// Log
|
|
81
|
-
assistant.log(`Middleware.process(): Request (${geolocation.ip} @ ${geolocation.country}, ${geolocation.region}, ${geolocation.city}) [${method} > ${strippedUrl}]`, safeStringify(data));
|
|
81
|
+
assistant.log(`Middleware.process(): Request (${geolocation.ip || 'unknown'} @ ${geolocation.country || '?'}, ${geolocation.region || '?'}, ${geolocation.city || '?'}) [${method} > ${strippedUrl}]`, safeStringify(data));
|
|
82
82
|
assistant.log(`Middleware.process(): Headers`, safeStringify(headers));
|
|
83
83
|
|
|
84
84
|
// Set paths
|
|
@@ -133,6 +133,7 @@ Middleware.prototype.run = function (libPath, options) {
|
|
|
133
133
|
const uuid = assistant?.usage?.user?.auth?.uid
|
|
134
134
|
|| assistant.request.user.auth.uid
|
|
135
135
|
|| assistant.request.geolocation.ip
|
|
136
|
+
|| 'unknown'
|
|
136
137
|
|
|
137
138
|
assistant.analytics = Manager.Analytics({
|
|
138
139
|
assistant: assistant,
|
|
@@ -59,7 +59,7 @@ Usage.prototype.init = function (assistant, options) {
|
|
|
59
59
|
self.storage = Manager.storage({name: 'usage', temporary: true, clear: options.clear, log: options.log});
|
|
60
60
|
|
|
61
61
|
// Set local key
|
|
62
|
-
self.key = (options.key || self.assistant.request.geolocation.ip || '')
|
|
62
|
+
self.key = (options.key || self.assistant.request.geolocation.ip || 'unknown')
|
|
63
63
|
// .replace(/[\.:]/g, '_');
|
|
64
64
|
|
|
65
65
|
// Set paths
|
|
@@ -51,7 +51,7 @@ function User(Manager, settings, options) {
|
|
|
51
51
|
timestampUNIX: getWithDefault(settings?.subscription?.expires?.timestampUNIX, oldDateUNIX, defaults),
|
|
52
52
|
},
|
|
53
53
|
trial: {
|
|
54
|
-
|
|
54
|
+
claimed: getWithDefault(settings?.subscription?.trial?.claimed, false, defaults),
|
|
55
55
|
expires: {
|
|
56
56
|
timestamp: getWithDefault(settings?.subscription?.trial?.expires?.timestamp, oldDate, defaults),
|
|
57
57
|
timestampUNIX: getWithDefault(settings?.subscription?.trial?.expires?.timestampUNIX, oldDateUNIX, defaults),
|
|
@@ -109,24 +109,24 @@ function User(Manager, settings, options) {
|
|
|
109
109
|
timestampUNIX: getWithDefault(settings?.activity?.created?.timestampUNIX, nowUNIX, defaults),
|
|
110
110
|
},
|
|
111
111
|
geolocation: {
|
|
112
|
-
ip:
|
|
113
|
-
continent:
|
|
114
|
-
country:
|
|
115
|
-
region:
|
|
116
|
-
city:
|
|
112
|
+
ip: settings?.activity?.geolocation?.ip ?? null,
|
|
113
|
+
continent: settings?.activity?.geolocation?.continent ?? null,
|
|
114
|
+
country: settings?.activity?.geolocation?.country ?? null,
|
|
115
|
+
region: settings?.activity?.geolocation?.region ?? null,
|
|
116
|
+
city: settings?.activity?.geolocation?.city ?? null,
|
|
117
117
|
latitude: getWithDefault(settings?.activity?.geolocation?.latitude, 0, defaults),
|
|
118
118
|
longitude: getWithDefault(settings?.activity?.geolocation?.longitude, 0, defaults),
|
|
119
119
|
},
|
|
120
120
|
client: {
|
|
121
|
-
language:
|
|
121
|
+
language: settings?.activity?.client?.language ?? null,
|
|
122
122
|
mobile: getWithDefault(settings?.activity?.client?.mobile, false, defaults),
|
|
123
|
-
device:
|
|
124
|
-
platform:
|
|
125
|
-
browser:
|
|
126
|
-
vendor:
|
|
127
|
-
runtime:
|
|
128
|
-
userAgent:
|
|
129
|
-
url:
|
|
123
|
+
device: settings?.activity?.client?.device ?? null,
|
|
124
|
+
platform: settings?.activity?.client?.platform ?? null,
|
|
125
|
+
browser: settings?.activity?.client?.browser ?? null,
|
|
126
|
+
vendor: settings?.activity?.client?.vendor ?? null,
|
|
127
|
+
runtime: settings?.activity?.client?.runtime ?? null,
|
|
128
|
+
userAgent: settings?.activity?.client?.userAgent ?? null,
|
|
129
|
+
url: settings?.activity?.client?.url ?? null,
|
|
130
130
|
},
|
|
131
131
|
},
|
|
132
132
|
api: {
|
|
@@ -138,7 +138,7 @@ function User(Manager, settings, options) {
|
|
|
138
138
|
period: getWithDefault(settings?.usage?.requests?.period, 0, defaults),
|
|
139
139
|
total: getWithDefault(settings?.usage?.requests?.total, 0, defaults),
|
|
140
140
|
last: {
|
|
141
|
-
id:
|
|
141
|
+
id: settings?.usage?.requests?.last?.id ?? null,
|
|
142
142
|
timestamp: getWithDefault(settings?.usage?.requests?.last?.timestamp, oldDate, defaults),
|
|
143
143
|
timestampUNIX: getWithDefault(settings?.usage?.requests?.last?.timestampUNIX, oldDateUNIX, defaults),
|
|
144
144
|
},
|
|
@@ -149,19 +149,19 @@ function User(Manager, settings, options) {
|
|
|
149
149
|
timestamp: getWithDefault(settings?.personal?.birthday?.timestamp, oldDate, defaults),
|
|
150
150
|
timestampUNIX: getWithDefault(settings?.personal?.birthday?.timestampUNIX, oldDateUNIX, defaults),
|
|
151
151
|
},
|
|
152
|
-
gender:
|
|
152
|
+
gender: settings?.personal?.gender ?? null,
|
|
153
153
|
location: {
|
|
154
|
-
country:
|
|
155
|
-
region:
|
|
156
|
-
city:
|
|
154
|
+
country: settings?.personal?.location?.country ?? null,
|
|
155
|
+
region: settings?.personal?.location?.region ?? null,
|
|
156
|
+
city: settings?.personal?.location?.city ?? null,
|
|
157
157
|
},
|
|
158
158
|
name: {
|
|
159
|
-
first:
|
|
160
|
-
last:
|
|
159
|
+
first: settings?.personal?.name?.first ?? null,
|
|
160
|
+
last: settings?.personal?.name?.last ?? null,
|
|
161
161
|
},
|
|
162
162
|
company: {
|
|
163
|
-
name:
|
|
164
|
-
position:
|
|
163
|
+
name: settings?.personal?.company?.name ?? null,
|
|
164
|
+
position: settings?.personal?.company?.position ?? null,
|
|
165
165
|
},
|
|
166
166
|
telephone: {
|
|
167
167
|
countryCode: getWithDefault(settings?.personal?.telephone?.countryCode, 0, defaults),
|
package/src/manager/index.js
CHANGED
|
@@ -1111,37 +1111,6 @@ Manager.prototype.setupCustomServer = function (_library, options) {
|
|
|
1111
1111
|
});
|
|
1112
1112
|
}
|
|
1113
1113
|
|
|
1114
|
-
// Setup Custom Server
|
|
1115
|
-
Manager.prototype.getApp = function (id) {
|
|
1116
|
-
const self = this;
|
|
1117
|
-
|
|
1118
|
-
// Get the app
|
|
1119
|
-
return new Promise(function(resolve, reject) {
|
|
1120
|
-
const fetch = require('wonderful-fetch');
|
|
1121
|
-
|
|
1122
|
-
// Set ID
|
|
1123
|
-
id = id || self.config.app.id;
|
|
1124
|
-
|
|
1125
|
-
// If no ID, reject
|
|
1126
|
-
if (!id) {
|
|
1127
|
-
return reject(new Error('No ID provided'));
|
|
1128
|
-
}
|
|
1129
|
-
|
|
1130
|
-
// Fetch the app
|
|
1131
|
-
fetch(`https://us-central1-itw-creative-works.cloudfunctions.net/getApp`, {
|
|
1132
|
-
method: 'post',
|
|
1133
|
-
response: 'json',
|
|
1134
|
-
timeout: 30000,
|
|
1135
|
-
tries: 3,
|
|
1136
|
-
body: {
|
|
1137
|
-
id: id,
|
|
1138
|
-
}
|
|
1139
|
-
})
|
|
1140
|
-
.then((r) => resolve(r))
|
|
1141
|
-
.catch((e) => reject(e));
|
|
1142
|
-
});
|
|
1143
|
-
}
|
|
1144
|
-
|
|
1145
1114
|
function resolveProjectPackage(dir) {
|
|
1146
1115
|
try {
|
|
1147
1116
|
return require(path.resolve(dir, 'functions', 'package.json'));
|
|
@@ -243,7 +243,7 @@ OpenAI.prototype.request = function (options) {
|
|
|
243
243
|
// Load prompt
|
|
244
244
|
const prompt = loadContent(options.prompt, _log);
|
|
245
245
|
const message = loadContent(options.message, _log);
|
|
246
|
-
const user = options.user?.auth?.uid || assistant.request.geolocation.ip;
|
|
246
|
+
const user = options.user?.auth?.uid || assistant.request.geolocation.ip || 'unknown';
|
|
247
247
|
|
|
248
248
|
// Log
|
|
249
249
|
_log('Prompt', prompt);
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GET /app - Public app configuration
|
|
3
|
+
* Returns a safe subset of the project's config (no secrets)
|
|
4
|
+
*/
|
|
5
|
+
module.exports = async ({ assistant, Manager }) => {
|
|
6
|
+
const config = Manager.config;
|
|
7
|
+
|
|
8
|
+
return assistant.respond(buildPublicConfig(config));
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Build a public-safe config object from Manager.config
|
|
13
|
+
* Excludes sensitive fields: sentry, google_analytics, ghostii, etc.
|
|
14
|
+
*/
|
|
15
|
+
function buildPublicConfig(config) {
|
|
16
|
+
return {
|
|
17
|
+
id: config.app?.id,
|
|
18
|
+
name: config.brand?.name,
|
|
19
|
+
description: config.brand?.description,
|
|
20
|
+
url: config.brand?.url,
|
|
21
|
+
email: config.brand?.contact?.email,
|
|
22
|
+
images: config.brand?.images || {},
|
|
23
|
+
github: {
|
|
24
|
+
user: config.github?.user,
|
|
25
|
+
repo: (config.github?.repo_website || '').split('/').pop(),
|
|
26
|
+
},
|
|
27
|
+
reviews: config.reviews || {},
|
|
28
|
+
firebaseConfig: config.firebaseConfig || {},
|
|
29
|
+
products: (config.products || []).map(p => ({
|
|
30
|
+
id: p.id,
|
|
31
|
+
name: p.name,
|
|
32
|
+
type: p.type,
|
|
33
|
+
limits: p.limits || {},
|
|
34
|
+
trial: p.trial || {},
|
|
35
|
+
prices: p.prices || {},
|
|
36
|
+
})),
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
module.exports.buildPublicConfig = buildPublicConfig;
|
|
@@ -43,7 +43,7 @@ module.exports = async ({ assistant, Manager, settings, analytics }) => {
|
|
|
43
43
|
|
|
44
44
|
// Check spam filter using local storage
|
|
45
45
|
const storage = Manager.storage({ temporary: true });
|
|
46
|
-
const ipPath = ['api:general:email', 'ips', assistant.request.geolocation.ip];
|
|
46
|
+
const ipPath = ['api:general:email', 'ips', assistant.request.geolocation.ip || 'unknown'];
|
|
47
47
|
const emailPath = ['api:general:email', 'emails', settings.email];
|
|
48
48
|
|
|
49
49
|
const ipData = storage.get(ipPath).value() || {};
|
|
@@ -2,13 +2,14 @@
|
|
|
2
2
|
* POST /special/electron-client - Setup Electron Manager client
|
|
3
3
|
* Returns client configuration with optional auth
|
|
4
4
|
*/
|
|
5
|
+
const path = require('path');
|
|
6
|
+
const { buildPublicConfig } = require(path.join(__dirname, '..', '..', 'app', 'get.js'));
|
|
7
|
+
|
|
5
8
|
module.exports = async ({ assistant, Manager, settings, analytics, libraries }) => {
|
|
6
|
-
const fetch = Manager.require('wonderful-fetch');
|
|
7
9
|
const { admin } = libraries;
|
|
8
10
|
|
|
9
11
|
// appId/app fallback to Manager.config
|
|
10
12
|
let uid = settings.uid;
|
|
11
|
-
const app = settings.appId || settings.app || Manager.config.app.id;
|
|
12
13
|
let config = settings.config;
|
|
13
14
|
|
|
14
15
|
let uuid = null;
|
|
@@ -42,21 +43,6 @@ module.exports = async ({ assistant, Manager, settings, analytics, libraries })
|
|
|
42
43
|
config = {};
|
|
43
44
|
}
|
|
44
45
|
|
|
45
|
-
// Fetch app details
|
|
46
|
-
const appDetails = await fetch('https://us-central1-itw-creative-works.cloudfunctions.net/getApp', {
|
|
47
|
-
method: 'post',
|
|
48
|
-
timeout: 30000,
|
|
49
|
-
tries: 3,
|
|
50
|
-
response: 'json',
|
|
51
|
-
body: {
|
|
52
|
-
id: app,
|
|
53
|
-
},
|
|
54
|
-
}).catch(e => e);
|
|
55
|
-
|
|
56
|
-
if (appDetails instanceof Error) {
|
|
57
|
-
return assistant.respond(`Error fetching app details: ${appDetails}`, { code: 500 });
|
|
58
|
-
}
|
|
59
|
-
|
|
60
46
|
// Track analytics
|
|
61
47
|
analytics.event('special/electron-client', { action: 'setup' });
|
|
62
48
|
|
|
@@ -66,7 +52,7 @@ module.exports = async ({ assistant, Manager, settings, analytics, libraries })
|
|
|
66
52
|
timestamp: new Date().toISOString(),
|
|
67
53
|
ip: assistant.request.geolocation.ip,
|
|
68
54
|
country: assistant.request.geolocation.country,
|
|
69
|
-
app:
|
|
55
|
+
app: buildPublicConfig(Manager.config),
|
|
70
56
|
config: config,
|
|
71
57
|
});
|
|
72
58
|
};
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
const pushid = require('pushid');
|
|
2
|
-
const fetch = require('wonderful-fetch');
|
|
3
2
|
const powertools = require('node-powertools');
|
|
4
3
|
|
|
5
4
|
/**
|
|
@@ -30,17 +29,8 @@ module.exports = async ({ assistant, Manager, user, settings, libraries }) => {
|
|
|
30
29
|
decision.promptReview = true;
|
|
31
30
|
}
|
|
32
31
|
|
|
33
|
-
// Get
|
|
34
|
-
const
|
|
35
|
-
method: 'post',
|
|
36
|
-
response: 'json',
|
|
37
|
-
body: { id: Manager.config.app.id },
|
|
38
|
-
}).catch((e) => {
|
|
39
|
-
assistant.error(`Failed to get app: ${e.message}`);
|
|
40
|
-
return {};
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
const reviews = appResponse.reviews || {};
|
|
32
|
+
// Get review config from local config
|
|
33
|
+
const reviews = { ...(Manager.config.reviews || {}) };
|
|
44
34
|
reviews.enabled = typeof reviews.enabled === 'undefined' ? true : reviews.enabled;
|
|
45
35
|
reviews.sites = reviews.sites || [];
|
|
46
36
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = () => ({});
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
brand: {
|
|
3
3
|
id: 'my-app',
|
|
4
4
|
name: 'My Brand',
|
|
5
|
+
description: '',
|
|
5
6
|
url: 'https://example.com',
|
|
6
7
|
contact: {
|
|
7
8
|
email: 'support@example.com',
|
|
@@ -12,6 +13,12 @@
|
|
|
12
13
|
combomark: 'https://example.com/combomark.png',
|
|
13
14
|
},
|
|
14
15
|
},
|
|
16
|
+
reviews: {
|
|
17
|
+
enabled: true,
|
|
18
|
+
sites: [
|
|
19
|
+
'trustpilot.com',
|
|
20
|
+
],
|
|
21
|
+
},
|
|
15
22
|
github: {
|
|
16
23
|
user: 'username',
|
|
17
24
|
repo_website: 'https://github.com/username/backend-manager',
|
|
@@ -45,6 +52,8 @@
|
|
|
45
52
|
prompt: '',
|
|
46
53
|
chance: 1.0,
|
|
47
54
|
author: 'alex-raeburn',
|
|
55
|
+
// app: 'other-app-id', // Optional: target a different app
|
|
56
|
+
// appUrl: 'https://api.otherapp.com', // Required if app is set (fetches /backend-manager/app)
|
|
48
57
|
}
|
|
49
58
|
],
|
|
50
59
|
products: [
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* GET /firebase/providers - Get authentication providers
|
|
3
|
-
* Returns enabled auth providers for the app
|
|
4
|
-
*/
|
|
5
|
-
const { merge } = require('lodash');
|
|
6
|
-
|
|
7
|
-
module.exports = async ({ assistant, Manager, analytics }) => {
|
|
8
|
-
const fetch = Manager.require('wonderful-fetch');
|
|
9
|
-
|
|
10
|
-
const defaultProviders = {
|
|
11
|
-
['password']: {
|
|
12
|
-
enabled: true,
|
|
13
|
-
},
|
|
14
|
-
['google.com']: {
|
|
15
|
-
enabled: true,
|
|
16
|
-
},
|
|
17
|
-
['facebook.com']: {
|
|
18
|
-
enabled: false,
|
|
19
|
-
},
|
|
20
|
-
['twitter.com']: {
|
|
21
|
-
enabled: false,
|
|
22
|
-
},
|
|
23
|
-
['github.com']: {
|
|
24
|
-
enabled: false,
|
|
25
|
-
},
|
|
26
|
-
['microsoft.com']: {
|
|
27
|
-
enabled: false,
|
|
28
|
-
},
|
|
29
|
-
['yahoo.com']: {
|
|
30
|
-
enabled: false,
|
|
31
|
-
},
|
|
32
|
-
['apple.com']: {
|
|
33
|
-
enabled: false,
|
|
34
|
-
},
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
// Get app object
|
|
38
|
-
const appObject = await getAppObject(Manager, assistant).catch(e => e);
|
|
39
|
-
if (appObject instanceof Error) {
|
|
40
|
-
return assistant.respond(`Failed to get app object: ${appObject}`, { code: 500 });
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// Merge the default providers with the app providers
|
|
44
|
-
const providers = merge(defaultProviders, appObject.authentication);
|
|
45
|
-
|
|
46
|
-
// Reformat the object so it's just provider=true/false
|
|
47
|
-
const finalProviders = {};
|
|
48
|
-
Object.keys(providers).forEach(key => {
|
|
49
|
-
finalProviders[key] = providers[key].enabled;
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
assistant.log('Providers', finalProviders);
|
|
53
|
-
|
|
54
|
-
// Track analytics
|
|
55
|
-
analytics.event('firebase/providers', { action: 'get' });
|
|
56
|
-
|
|
57
|
-
return assistant.respond(finalProviders);
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
// Helper: Get app object from ITW
|
|
61
|
-
async function getAppObject(Manager, assistant) {
|
|
62
|
-
const fetch = Manager.require('wonderful-fetch');
|
|
63
|
-
const id = Manager.config.app.id;
|
|
64
|
-
|
|
65
|
-
const result = await fetch('https://us-central1-itw-creative-works.cloudfunctions.net/getApp', {
|
|
66
|
-
method: 'post',
|
|
67
|
-
response: 'json',
|
|
68
|
-
body: {
|
|
69
|
-
id: id,
|
|
70
|
-
}
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
assistant.log('getAppObject(): Response', result);
|
|
74
|
-
|
|
75
|
-
if (!result) {
|
|
76
|
-
throw new Error(`App with id ${id} not found`);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
return result;
|
|
80
|
-
}
|