backend-manager 3.2.170 → 3.2.172
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/LICENSE +1 -1
- package/README.md +1 -1
- package/dist/cli/cli.js +1534 -0
- package/dist/manager/functions/core/actions/api/admin/backup.js +338 -0
- package/dist/manager/functions/core/actions/api/admin/create-post.js +388 -0
- package/dist/manager/functions/core/actions/api/admin/cron.js +37 -0
- package/dist/manager/functions/core/actions/api/admin/database-read.js +35 -0
- package/dist/manager/functions/core/actions/api/admin/database-write.js +39 -0
- package/dist/manager/functions/core/actions/api/admin/edit-post.js +158 -0
- package/dist/manager/functions/core/actions/api/admin/firestore-query.js +165 -0
- package/dist/manager/functions/core/actions/api/admin/firestore-read.js +38 -0
- package/dist/manager/functions/core/actions/api/admin/firestore-write.js +54 -0
- package/dist/manager/functions/core/actions/api/admin/get-stats.js +269 -0
- package/dist/manager/functions/core/actions/api/admin/payment-processor.js +57 -0
- package/dist/manager/functions/core/actions/api/admin/run-hook.js +95 -0
- package/dist/manager/functions/core/actions/api/admin/send-notification.js +197 -0
- package/dist/manager/functions/core/actions/api/admin/sync-users.js +125 -0
- package/dist/manager/functions/core/actions/api/admin/templates/post.html +16 -0
- package/dist/manager/functions/core/actions/api/firebase/get-providers.js +102 -0
- package/dist/manager/functions/core/actions/api/general/emails/general:download-app-link.js +21 -0
- package/dist/manager/functions/core/actions/api/general/fetch-post.js +99 -0
- package/dist/manager/functions/core/actions/api/general/generate-uuid.js +41 -0
- package/dist/manager/functions/core/actions/api/general/send-email.js +112 -0
- package/dist/manager/functions/core/actions/api/handler/create-post.js +146 -0
- package/dist/manager/functions/core/actions/api/special/setup-electron-manager-client.js +103 -0
- package/dist/manager/functions/core/actions/api/template.js +33 -0
- package/dist/manager/functions/core/actions/api/test/authenticate.js +22 -0
- package/dist/manager/functions/core/actions/api/test/create-test-accounts.js +27 -0
- package/dist/manager/functions/core/actions/api/test/lab.js +55 -0
- package/dist/manager/functions/core/actions/api/test/redirect.js +26 -0
- package/dist/manager/functions/core/actions/api/test/webhook.js +30 -0
- package/dist/manager/functions/core/actions/api/user/create-custom-token.js +32 -0
- package/dist/manager/functions/core/actions/api/user/delete.js +68 -0
- package/dist/manager/functions/core/actions/api/user/get-active-sessions.js +45 -0
- package/dist/manager/functions/core/actions/api/user/get-subscription-info.js +49 -0
- package/dist/manager/functions/core/actions/api/user/oauth2/discord.js +114 -0
- package/dist/manager/functions/core/actions/api/user/oauth2/google.js +99 -0
- package/dist/manager/functions/core/actions/api/user/oauth2.js +476 -0
- package/dist/manager/functions/core/actions/api/user/regenerate-api-keys.js +54 -0
- package/dist/manager/functions/core/actions/api/user/resolve.js +32 -0
- package/dist/manager/functions/core/actions/api/user/sign-out-all-sessions.js +118 -0
- package/dist/manager/functions/core/actions/api/user/sign-up copy.js +544 -0
- package/dist/manager/functions/core/actions/api/user/sign-up.js +99 -0
- package/dist/manager/functions/core/actions/api/user/submit-feedback.js +96 -0
- package/dist/manager/functions/core/actions/api/user/validate-settings.js +86 -0
- package/dist/manager/functions/core/actions/api.js +354 -0
- package/dist/manager/functions/core/actions/create-post-handler.js +184 -0
- package/dist/manager/functions/core/actions/generate-uuid.js +62 -0
- package/dist/manager/functions/core/actions/sign-up-handler.js +205 -0
- package/dist/manager/functions/core/admin/create-post.js +206 -0
- package/dist/manager/functions/core/admin/firestore-write.js +72 -0
- package/dist/manager/functions/core/admin/get-stats.js +218 -0
- package/dist/manager/functions/core/admin/query.js +198 -0
- package/dist/manager/functions/core/admin/send-notification.js +206 -0
- package/dist/manager/functions/core/cron/daily/ghostii-auto-publisher.js +377 -0
- package/dist/manager/functions/core/cron/daily/reset-usage.js +197 -0
- package/dist/manager/functions/core/cron/daily.js +114 -0
- package/dist/manager/functions/core/events/auth/before-create.js +124 -0
- package/dist/manager/functions/core/events/auth/before-signin.js +62 -0
- package/dist/manager/functions/core/events/auth/on-create copy.js +121 -0
- package/dist/manager/functions/core/events/auth/on-create.js +564 -0
- package/dist/manager/functions/core/events/auth/on-delete.js +72 -0
- package/dist/manager/functions/core/events/firestore/on-subscription.js +107 -0
- package/dist/manager/functions/test/authenticate.js +38 -0
- package/dist/manager/functions/test/create-test-accounts.js +144 -0
- package/dist/manager/functions/test/webhook.js +37 -0
- package/dist/manager/functions/wrappers/mailchimp/addToList.js +25 -0
- package/dist/manager/helpers/analytics copy.js +217 -0
- package/dist/manager/helpers/analytics.js +467 -0
- package/dist/manager/helpers/api-manager.js +324 -0
- package/dist/manager/helpers/assistant.js +1043 -0
- package/dist/manager/helpers/metadata.js +32 -0
- package/dist/manager/helpers/middleware.js +154 -0
- package/dist/manager/helpers/roles.js +69 -0
- package/dist/manager/helpers/settings.js +158 -0
- package/dist/manager/helpers/subscription-resolver-new.js +828 -0
- package/dist/manager/helpers/subscription-resolver.js +842 -0
- package/dist/manager/helpers/usage.js +381 -0
- package/dist/manager/helpers/user.js +198 -0
- package/dist/manager/helpers/utilities.js +292 -0
- package/dist/manager/index.js +1076 -0
- package/dist/manager/libraries/openai.js +460 -0
- package/dist/manager/routes/restart/index.js +52 -0
- package/dist/manager/routes/test/index.js +43 -0
- package/dist/manager/schemas/restart.js +13 -0
- package/dist/manager/schemas/test.js +13 -0
- package/dist/require.js +3 -0
- package/package.json +19 -9
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
const path_processing = 'notifications/processing/all/{notificationId}';
|
|
2
|
+
const path_subscriptions = 'notifications/subscriptions/all';
|
|
3
|
+
const badTokenReasons = ['messaging/invalid-registration-token', 'messaging/registration-token-not-registered']
|
|
4
|
+
|
|
5
|
+
function Module() {
|
|
6
|
+
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
Module.prototype.main = function () {
|
|
10
|
+
const self = this;
|
|
11
|
+
const Manager = self.Manager;
|
|
12
|
+
const Api = self.Api;
|
|
13
|
+
const assistant = self.assistant;
|
|
14
|
+
const payload = self.payload;
|
|
15
|
+
|
|
16
|
+
return new Promise(async function(resolve, reject) {
|
|
17
|
+
|
|
18
|
+
// Set up response obj
|
|
19
|
+
payload.response.data = {
|
|
20
|
+
subscribers: 0,
|
|
21
|
+
batches: 0,
|
|
22
|
+
sent: 0,
|
|
23
|
+
deleted: 0,
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Fix notification payload
|
|
27
|
+
self._notificationPayload = {
|
|
28
|
+
notification: self.payload.data.payload.notification || {},
|
|
29
|
+
};
|
|
30
|
+
self._notificationPayload.notification.title = self.payload.data.payload.title || self.payload.data.payload.notification.title || 'Notification';
|
|
31
|
+
self._notificationPayload.notification.click_action = self.payload.data.payload.click_action || self.payload.data.payload.notification.click_action || 'https://itwcreativeworks.com';
|
|
32
|
+
self._notificationPayload.notification.body = self.payload.data.payload.body || self.payload.data.payload.notification.body || 'Check this out';
|
|
33
|
+
self._notificationPayload.notification.icon = self.payload.data.payload.icon || self.payload.data.payload.notification.icon || self.Manager.config.brand.brandmark || 'https://cdn.itwcreativeworks.com/assets/itw-creative-works/images/socials/itw-creative-works-brandmark-square-black-1024x1024.png';
|
|
34
|
+
|
|
35
|
+
try {
|
|
36
|
+
self._notificationPayload.notification.click_action = new URL(self._notificationPayload.notification.click_action);
|
|
37
|
+
self._notificationPayload.notification.click_action.searchParams.set('cb', new Date().getTime())
|
|
38
|
+
self._notificationPayload.notification.click_action = self._notificationPayload.notification.click_action.toString()
|
|
39
|
+
} catch (e) {
|
|
40
|
+
assistant.errorify(`Failed to add cb to URL: ${e}`, {code: 500, log: true});
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
assistant.log('Resolved notification payload', self._notificationPayload)
|
|
44
|
+
|
|
45
|
+
if (!payload.user.roles.admin) {
|
|
46
|
+
return reject(assistant.errorify(`Admin required.`, {code: 401}));
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (!payload.data.payload.title || !payload.data.payload.body) {
|
|
50
|
+
return reject(assistant.errorify(`Parameters <title> and <body> required`, {code: 400, sentry: true}));
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
await self.getTokens({tags: false})
|
|
54
|
+
.then(r => {
|
|
55
|
+
return resolve({data: payload.response.data})
|
|
56
|
+
})
|
|
57
|
+
.catch(e => {
|
|
58
|
+
return reject(assistant.errorify(`Failed to send notification: ${e}`, {code: 400, sentry: true}));
|
|
59
|
+
})
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
// HELPERS //
|
|
65
|
+
Module.prototype.getTokens = function (options) {
|
|
66
|
+
const self = this;
|
|
67
|
+
options = options || {};
|
|
68
|
+
options.tags = options.tags || false;
|
|
69
|
+
|
|
70
|
+
return new Promise(async function(resolve, reject) {
|
|
71
|
+
let subs = self.libraries.admin.firestore().collection(path_subscriptions);
|
|
72
|
+
let batchPromises = [];
|
|
73
|
+
|
|
74
|
+
if (options.tags) {
|
|
75
|
+
subs.where('tags', 'array-contains-any', options.tags)
|
|
76
|
+
}
|
|
77
|
+
await subs
|
|
78
|
+
.get()
|
|
79
|
+
.then(function(querySnapshot) {
|
|
80
|
+
self.assistant.log(`Queried ${querySnapshot.size} tokens.`);
|
|
81
|
+
self.payload.response.data.subscribers = querySnapshot.size;
|
|
82
|
+
// self.result.subscriptionsStart = querySnapshot.size;
|
|
83
|
+
let batchCurrentSize = 0;
|
|
84
|
+
let batchSizeMax = 1000;
|
|
85
|
+
|
|
86
|
+
let batchCurrent = [];
|
|
87
|
+
let batchLoops = 1;
|
|
88
|
+
|
|
89
|
+
querySnapshot.forEach(function(doc) {
|
|
90
|
+
// log(self, 'loading... ', batchLoops+'/'+querySnapshot.size);
|
|
91
|
+
if ((batchCurrentSize < batchSizeMax - 1) && (batchLoops < querySnapshot.size)) {
|
|
92
|
+
batchCurrent.push(doc.data().token);
|
|
93
|
+
batchCurrentSize++;
|
|
94
|
+
} else {
|
|
95
|
+
let batchId = batchPromises.length + 1;
|
|
96
|
+
batchCurrent.push(doc.data().token);
|
|
97
|
+
batchCurrentSize++;
|
|
98
|
+
console.log(`Got batch ID: ${batchId} with ${batchCurrentSize} tokens.`);
|
|
99
|
+
batchPromises.push(self.sendBatch(batchCurrent, batchId));
|
|
100
|
+
batchCurrent = [];
|
|
101
|
+
batchCurrentSize = 0;
|
|
102
|
+
self.payload.response.data.batches++;
|
|
103
|
+
}
|
|
104
|
+
batchLoops++;
|
|
105
|
+
});
|
|
106
|
+
})
|
|
107
|
+
.catch(function(e) {
|
|
108
|
+
self.assistant.error('Error querying tokens: ', e)
|
|
109
|
+
reject(error);
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
await Promise.all(batchPromises)
|
|
113
|
+
.then(function(values) {
|
|
114
|
+
self.assistant.log('Finished all batches.');
|
|
115
|
+
})
|
|
116
|
+
.catch(function(e) {
|
|
117
|
+
self.assistant.error('Error sending batches: ', e)
|
|
118
|
+
});
|
|
119
|
+
resolve();
|
|
120
|
+
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
Module.prototype.sendBatch = function (batch, id) {
|
|
125
|
+
const self = this;
|
|
126
|
+
return new Promise(async function(resolve, reject) {
|
|
127
|
+
// self.assistant.log(`Sending batch ID: ${id}`, batch);
|
|
128
|
+
self.assistant.log(`Sending batch ID: ${id}`);
|
|
129
|
+
|
|
130
|
+
// self.assistant.log('payload', payload);
|
|
131
|
+
|
|
132
|
+
await self.libraries.admin.messaging().sendToDevice(batch, self._notificationPayload)
|
|
133
|
+
.then(async function (response) {
|
|
134
|
+
// self.result.batches.list.push('#' + id + ' | ' + '✅ ' + response.successCount + ' | ' + '❌ ' + response.failureCount);
|
|
135
|
+
self.assistant.log('Sent batch #' + id);
|
|
136
|
+
// self.result.successes += response.successCount;
|
|
137
|
+
// self.result.failures += response.failureCount;
|
|
138
|
+
// console.log('RESP', response);
|
|
139
|
+
if (response.failureCount > 0) {
|
|
140
|
+
await self.cleanTokens(batch, response.results, id);
|
|
141
|
+
}
|
|
142
|
+
self.payload.response.data.sent += (batch.length - response.failureCount);
|
|
143
|
+
resolve();
|
|
144
|
+
})
|
|
145
|
+
.catch(function (e) {
|
|
146
|
+
self.assistant.error('Error sending batch #' + id, e);
|
|
147
|
+
// self.result.status = 'fail';
|
|
148
|
+
reject(e);
|
|
149
|
+
})
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
Module.prototype.cleanTokens = function (batch, results, id) {
|
|
154
|
+
const self = this;
|
|
155
|
+
|
|
156
|
+
return new Promise(async function(resolve, reject) {
|
|
157
|
+
let cleanPromises = [];
|
|
158
|
+
// self.assistant.log(`Cleaning tokens of batch ID: ${id}`, results);
|
|
159
|
+
self.assistant.log(`Cleaning tokens of batch ID: ${id}`);
|
|
160
|
+
|
|
161
|
+
results.forEach(function (item, index) {
|
|
162
|
+
if (!item.error) {
|
|
163
|
+
return false;
|
|
164
|
+
}
|
|
165
|
+
let curCode = item.error.code;
|
|
166
|
+
let token = batch[index];
|
|
167
|
+
self.assistant.log(`Found bad token: ${index} = ${curCode}`);
|
|
168
|
+
if (badTokenReasons.includes(curCode)) {
|
|
169
|
+
cleanPromises.push(self.deleteToken(token, curCode));
|
|
170
|
+
}
|
|
171
|
+
})
|
|
172
|
+
await Promise.all(cleanPromises)
|
|
173
|
+
.catch(function(e) {
|
|
174
|
+
self.assistant.log('error', "Error cleaning failed tokens: ", e);
|
|
175
|
+
});
|
|
176
|
+
resolve();
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
Module.prototype.deleteToken = function (token, errorCode) {
|
|
181
|
+
const self = this;
|
|
182
|
+
return new Promise(function(resolve, reject) {
|
|
183
|
+
self.libraries.admin.firestore().doc(`${path_subscriptions}/${token}`)
|
|
184
|
+
.delete()
|
|
185
|
+
.then(function() {
|
|
186
|
+
self.assistant.log(`Deleting bad token: ${token} for reason ${errorCode}`);
|
|
187
|
+
self.payload.response.data.deleted++;
|
|
188
|
+
resolve();
|
|
189
|
+
})
|
|
190
|
+
.catch(function(error) {
|
|
191
|
+
self.assistant.log('error', `Error deleting bad token: ${token} for reason ${errorCode} because of error ${error}`);
|
|
192
|
+
resolve();
|
|
193
|
+
})
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
module.exports = Module;
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
const {get, merge} = require('lodash');
|
|
2
|
+
|
|
3
|
+
function Module() {
|
|
4
|
+
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
Module.prototype.main = function () {
|
|
8
|
+
const self = this;
|
|
9
|
+
const Manager = self.Manager;
|
|
10
|
+
const Api = self.Api;
|
|
11
|
+
const assistant = self.assistant;
|
|
12
|
+
const payload = self.payload;
|
|
13
|
+
|
|
14
|
+
return new Promise(async function(resolve, reject) {
|
|
15
|
+
|
|
16
|
+
// If the user is not an admin, reject
|
|
17
|
+
if (!payload.user.roles.admin && assistant.isProduction()) {
|
|
18
|
+
return reject(assistant.errorify(`Admin required.`, {code: 401}));
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Get lastPageToken from meta/stats
|
|
22
|
+
self.libraries.admin.firestore().doc(`meta/stats`)
|
|
23
|
+
.get()
|
|
24
|
+
.then(async (doc) => {
|
|
25
|
+
const data = doc.data() || {};
|
|
26
|
+
const lastPageToken = get(data, 'syncUsers.lastPageToken', undefined);
|
|
27
|
+
let processedUsers = 0;
|
|
28
|
+
|
|
29
|
+
// Initial pageToken
|
|
30
|
+
assistant.log(`Running syn-users based on lastPageToken: ${lastPageToken}`);
|
|
31
|
+
|
|
32
|
+
// List firebase auth users
|
|
33
|
+
await Manager.Utilities().iterateUsers(function (batch, index) {
|
|
34
|
+
return new Promise(async function(resolve, reject) {
|
|
35
|
+
|
|
36
|
+
// Process user function
|
|
37
|
+
async function _process(user, i) {
|
|
38
|
+
const account = user.toJSON();
|
|
39
|
+
const uid = account.uid;
|
|
40
|
+
const email = account.email;
|
|
41
|
+
const created = new Date(account.metadata.creationTime);
|
|
42
|
+
const activity = new Date(account.metadata.lastSignInTime);
|
|
43
|
+
const isAnonymous = account.providerData.length === 0;
|
|
44
|
+
|
|
45
|
+
// Skip anonymous users
|
|
46
|
+
if (isAnonymous) {
|
|
47
|
+
return
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Add the user to the database only if it doesn't exist
|
|
51
|
+
await self.libraries.admin.firestore().doc(`users/${account.uid}`)
|
|
52
|
+
.get()
|
|
53
|
+
.then(async (doc) => {
|
|
54
|
+
const data = doc.data() || {};
|
|
55
|
+
|
|
56
|
+
const newUser = Manager.User({
|
|
57
|
+
auth: {
|
|
58
|
+
uid: uid,
|
|
59
|
+
email: email,
|
|
60
|
+
},
|
|
61
|
+
activity: {
|
|
62
|
+
created: {
|
|
63
|
+
timestamp: created.toISOString(),
|
|
64
|
+
timestampUNIX: Math.floor(created.getTime() / 1000),
|
|
65
|
+
},
|
|
66
|
+
lastActivity: {
|
|
67
|
+
timestamp: activity.toISOString(),
|
|
68
|
+
timestampUNIX: Math.floor(activity.getTime() / 1000),
|
|
69
|
+
},
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
const finalData = merge(newUser.properties, data);
|
|
74
|
+
|
|
75
|
+
// Set metadata
|
|
76
|
+
finalData.metadata = Manager.Metadata().set({tag: 'admin:sync-users'});
|
|
77
|
+
|
|
78
|
+
// Save to database
|
|
79
|
+
await self.libraries.admin.firestore().doc(`users/${account.uid}`)
|
|
80
|
+
.set(finalData, {merge: true})
|
|
81
|
+
.then(r => {
|
|
82
|
+
assistant.log(`Synched user: ${account.uid}`);
|
|
83
|
+
processedUsers++;
|
|
84
|
+
})
|
|
85
|
+
})
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Process each user
|
|
89
|
+
for (var i = 0; i < batch.users.length; i++) {
|
|
90
|
+
await _process(batch.users[i], i);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Save to database only if there is a page token
|
|
94
|
+
if (batch.pageToken) {
|
|
95
|
+
await self.libraries.admin.firestore().doc(`meta/stats`)
|
|
96
|
+
.update({
|
|
97
|
+
syncUsers: {
|
|
98
|
+
lastPageToken: batch.pageToken,
|
|
99
|
+
}
|
|
100
|
+
})
|
|
101
|
+
.then(r => {
|
|
102
|
+
assistant.log(`Saved lastPageToken: ${batch.pageToken}`);
|
|
103
|
+
})
|
|
104
|
+
.catch(e => {
|
|
105
|
+
assistant.error('Failed to update lastPageToken', e);
|
|
106
|
+
})
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return resolve();
|
|
110
|
+
})
|
|
111
|
+
}, {batchSize: 10, log: true, pageToken: lastPageToken})
|
|
112
|
+
|
|
113
|
+
assistant.log(`Processed ${processedUsers} users.`);
|
|
114
|
+
|
|
115
|
+
// Complete
|
|
116
|
+
return resolve();
|
|
117
|
+
})
|
|
118
|
+
.catch(e => {
|
|
119
|
+
return reject(assistant.errorify(e, {code: 500}));
|
|
120
|
+
})
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
module.exports = Module;
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
const fetch = require('wonderful-fetch');
|
|
2
|
+
const { merge } = 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
|
+
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
|
+
},
|
|
41
|
+
}
|
|
42
|
+
|
|
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}));
|
|
47
|
+
}
|
|
48
|
+
|
|
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;
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
// Log
|
|
59
|
+
assistant.log('Providers', finalProviders);
|
|
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
|
+
}
|
|
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
|
+
module.exports = Module;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module.exports = function (payload, config) {
|
|
2
|
+
return {
|
|
3
|
+
// spamFilter: {
|
|
4
|
+
// ip: 3,
|
|
5
|
+
// email: 3,
|
|
6
|
+
// },
|
|
7
|
+
// delay: 30000,
|
|
8
|
+
payload: {
|
|
9
|
+
to: {
|
|
10
|
+
email: payload.email,
|
|
11
|
+
name: payload.name,
|
|
12
|
+
},
|
|
13
|
+
categories: ['download'],
|
|
14
|
+
subject: `Free ${config.brand.name} download link for ${payload.name || 'you'}!`,
|
|
15
|
+
template: 'd-1d730ac8cc544b7cbccc8fa4a4b3f9ce',
|
|
16
|
+
group: 25927,
|
|
17
|
+
copy: false,
|
|
18
|
+
data: {},
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
const { Octokit } = require('@octokit/rest');
|
|
2
|
+
|
|
3
|
+
function Module() {
|
|
4
|
+
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
Module.prototype.main = function () {
|
|
8
|
+
const self = this;
|
|
9
|
+
const Manager = self.Manager;
|
|
10
|
+
const Api = self.Api;
|
|
11
|
+
const assistant = self.assistant;
|
|
12
|
+
const payload = self.payload;
|
|
13
|
+
|
|
14
|
+
return new Promise(async function(resolve, reject) {
|
|
15
|
+
// Setup Octokit
|
|
16
|
+
const octokit = new Octokit({
|
|
17
|
+
auth: Manager?.config?.github?.key,
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
// Setup options
|
|
21
|
+
payload.data.payload.url = payload.data.payload.url || '';
|
|
22
|
+
|
|
23
|
+
// Check for required parameters
|
|
24
|
+
if (!payload.data.payload.url) {
|
|
25
|
+
return reject(assistant.errorify(`Missing required parameter: url`, {code: 400}));
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
let url;
|
|
29
|
+
try {
|
|
30
|
+
url = new URL(payload.data.payload.url);
|
|
31
|
+
} catch (e) {
|
|
32
|
+
return reject(assistant.errorify(`Invalid URL`, {code: 400}));
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Get the post
|
|
36
|
+
const filename = url.pathname.replace(/blog|\//ig, '')
|
|
37
|
+
const repoInfo = assistant.parseRepo(self?.Manager?.config?.github?.repo_website);
|
|
38
|
+
const query = `title+repo:${repoInfo.user}/${repoInfo.name}+filename:${filename}`;
|
|
39
|
+
|
|
40
|
+
assistant.log('Running search', query, repoInfo);
|
|
41
|
+
|
|
42
|
+
// Using octokit, search the repo for the file matching the url
|
|
43
|
+
// https://stackoverflow.com/questions/25564760/how-can-i-search-file-name-in-specific-github-repository
|
|
44
|
+
// https://docs.github.com/en/search-github/searching-on-github/searching-code#search-by-filename
|
|
45
|
+
const results = await octokit.rest.search.code({
|
|
46
|
+
q: query,
|
|
47
|
+
}).catch(e => e);
|
|
48
|
+
|
|
49
|
+
// Log
|
|
50
|
+
assistant.log('Results', results);
|
|
51
|
+
|
|
52
|
+
// Check for errors
|
|
53
|
+
if (results instanceof Error) {
|
|
54
|
+
return reject(assistant.errorify(`Error searching for post: ${results}`, {code: 500}));
|
|
55
|
+
} else if (results?.data?.total_count === 0) {
|
|
56
|
+
return reject(assistant.errorify(`Post not found`, {code: 404}));
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Get the first results
|
|
60
|
+
const firstResult = results.data.items[0];
|
|
61
|
+
|
|
62
|
+
// Fetch the content of the post
|
|
63
|
+
const post = await octokit.rest.repos.getContent({
|
|
64
|
+
owner: repoInfo.user,
|
|
65
|
+
repo: repoInfo.name,
|
|
66
|
+
path: firstResult.path,
|
|
67
|
+
}).catch(e => e);
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
// Log
|
|
71
|
+
assistant.log('Post', post);
|
|
72
|
+
|
|
73
|
+
// Check for errors
|
|
74
|
+
if (post instanceof Error) {
|
|
75
|
+
return reject(assistant.errorify(`Error fetching post: ${post}`, {code: 500}));
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Decode the content
|
|
79
|
+
const fullContent = Buffer.from(post.data.content, 'base64').toString();
|
|
80
|
+
const splitContent = fullContent.split('---');
|
|
81
|
+
const frontmatter = splitContent[1].trim();
|
|
82
|
+
const body = splitContent.slice(2).join('---').trim();
|
|
83
|
+
|
|
84
|
+
// Return
|
|
85
|
+
return resolve({
|
|
86
|
+
data: {
|
|
87
|
+
name: post.data.name,
|
|
88
|
+
path: post.data.path,
|
|
89
|
+
size: post.data.size,
|
|
90
|
+
sha: post.data.sha,
|
|
91
|
+
frontmatter: frontmatter,
|
|
92
|
+
body: body,
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
module.exports = Module;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
const uuid = require('uuid');
|
|
2
|
+
|
|
3
|
+
function Module() {
|
|
4
|
+
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
Module.prototype.main = function () {
|
|
8
|
+
const self = this;
|
|
9
|
+
const Manager = self.Manager;
|
|
10
|
+
const Api = self.Api;
|
|
11
|
+
const assistant = self.assistant;
|
|
12
|
+
const payload = self.payload;
|
|
13
|
+
|
|
14
|
+
return new Promise(async function(resolve, reject) {
|
|
15
|
+
|
|
16
|
+
let result = '';
|
|
17
|
+
payload.data.payload.namespace = payload.data.payload.namespace || Manager.config.backend_manager.namespace;
|
|
18
|
+
payload.data.payload.version = `${payload.data.payload.version || '5'}`.replace('v', '');
|
|
19
|
+
payload.data.payload.name = payload.data.payload.name || payload.data.payload.input;
|
|
20
|
+
|
|
21
|
+
if (payload.data.payload.version === '5') {
|
|
22
|
+
if (!payload.data.payload.name) {
|
|
23
|
+
return reject(assistant.errorify(`You must provide a name to hash for uuid v5.`, {code: 400}));
|
|
24
|
+
} else {
|
|
25
|
+
result = uuid.v5(payload.data.payload.name, payload.data.payload.namespace);
|
|
26
|
+
}
|
|
27
|
+
} else if (payload.data.payload.version === '4') {
|
|
28
|
+
result = uuid.v4();
|
|
29
|
+
} else {
|
|
30
|
+
return reject(assistant.errorify(`v${payload.data.payload.version} is not a valid version.`, {code: 400}));
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
assistant.log('UUID Generated', payload.data.payload, result);
|
|
34
|
+
|
|
35
|
+
return resolve({data: {uuid: result}});
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
module.exports = Module;
|