backend-manager 1.1.105 → 2.0.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 +19 -20
- package/src/cli/cli.js +25 -7
- package/src/manager/functions/core/actions/api/admin/create-post.js +160 -0
- package/src/manager/functions/core/actions/api/admin/firestore-query.js +172 -0
- package/src/manager/functions/core/actions/api/admin/firestore-read.js +54 -0
- package/src/manager/functions/core/actions/api/admin/firestore-write.js +47 -0
- package/src/manager/functions/core/actions/api/admin/get-stats.js +206 -0
- package/src/manager/functions/core/actions/api/admin/payment-processor.js +56 -0
- package/src/manager/functions/core/actions/api/admin/send-notification.js +189 -0
- package/src/manager/functions/core/actions/api/general/generate-uuid.js +49 -0
- package/src/manager/functions/core/actions/api/handler/create-post.js +118 -0
- package/src/manager/functions/core/actions/api/template.js +34 -0
- package/src/manager/functions/core/actions/api/test/authenticate.js +31 -0
- package/src/manager/functions/core/actions/api/test/create-test-accounts.js +36 -0
- package/src/manager/functions/core/actions/api/test/webhook.js +35 -0
- package/src/manager/functions/core/actions/api/user/create-custom-token.js +63 -0
- package/src/manager/functions/core/actions/api/user/delete.js +73 -0
- package/src/manager/functions/core/actions/api/user/get-subscription-info.js +63 -0
- package/src/manager/functions/core/actions/api/user/sign-out-all-sessions.js +86 -0
- package/src/manager/functions/core/actions/api/user/sign-up.js +241 -0
- package/src/manager/functions/core/actions/api.js +117 -323
- package/src/manager/functions/core/actions/old/api-2.js +414 -0
- package/src/manager/functions/core/admin/create-post.js +1 -1
- package/src/manager/index.js +1 -18
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
function Module() {
|
|
2
|
+
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
Module.prototype.init = async function (s, payload) {
|
|
6
|
+
const self = this;
|
|
7
|
+
self.Manager = s.Manager;
|
|
8
|
+
self.libraries = s.Manager.libraries;
|
|
9
|
+
self.assistant = s.Manager.assistant;
|
|
10
|
+
self.payload = payload;
|
|
11
|
+
|
|
12
|
+
return self;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
Module.prototype.main = function () {
|
|
16
|
+
const self = this;
|
|
17
|
+
const Manager = self.Manager;
|
|
18
|
+
const assistant = self.assistant;
|
|
19
|
+
const payload = self.payload;
|
|
20
|
+
|
|
21
|
+
return new Promise(async function(resolve, reject) {
|
|
22
|
+
|
|
23
|
+
if (!payload.user.roles.admin) {
|
|
24
|
+
return reject(assistant.errorManager(`Admin required.`, {code: 401, sentry: false, send: false, log: false}).error)
|
|
25
|
+
} else {
|
|
26
|
+
const stats = self.libraries.admin.firestore().doc(`meta/stats`)
|
|
27
|
+
await stats
|
|
28
|
+
.get()
|
|
29
|
+
.then(async (doc) => {
|
|
30
|
+
let data = doc.data() || {};
|
|
31
|
+
let error = null;
|
|
32
|
+
|
|
33
|
+
await self.fixStats(data)
|
|
34
|
+
.catch(e => {
|
|
35
|
+
error = e;
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
await self.updateStats()
|
|
39
|
+
.catch(e => {
|
|
40
|
+
error = e;
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
if (error) {
|
|
44
|
+
return reject(assistant.errorManager(error, {code: 500, sentry: false, send: false, log: false}).error)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
await stats
|
|
48
|
+
.get()
|
|
49
|
+
.then(doc => {
|
|
50
|
+
data = doc.data() || {};
|
|
51
|
+
})
|
|
52
|
+
.catch((e) => {
|
|
53
|
+
error = e;
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
if (error) {
|
|
57
|
+
return reject(assistant.errorManager(error, {code: 500, sentry: false, send: false, log: false}).error)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return resolve({data: data})
|
|
61
|
+
})
|
|
62
|
+
.catch(function (e) {
|
|
63
|
+
return reject(assistant.errorManager(`Failed to get: ${e}`, {code: 500, sentry: false, send: false, log: false}).error)
|
|
64
|
+
})
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
Module.prototype.fixStats = function (data) {
|
|
71
|
+
const self = this;
|
|
72
|
+
|
|
73
|
+
return new Promise(async function(resolve, reject) {
|
|
74
|
+
const stats = self.libraries.admin.firestore().doc(`meta/stats`);
|
|
75
|
+
|
|
76
|
+
if (!data || !data.users || !data.users.total || !data.subscriptions || !data.subscriptions.total) {
|
|
77
|
+
let usersTotal = 0;
|
|
78
|
+
let subscriptionsTotal = 0;
|
|
79
|
+
let error = null;
|
|
80
|
+
await self.getAllUsers()
|
|
81
|
+
.then(r => {
|
|
82
|
+
usersTotal = r.length
|
|
83
|
+
})
|
|
84
|
+
.catch(e => {
|
|
85
|
+
error = new Error(`Failed fixing stats: ${e}`);
|
|
86
|
+
self.assistant.error(error, {environment: 'production'});
|
|
87
|
+
})
|
|
88
|
+
await self.getAllSubscriptions()
|
|
89
|
+
.then(r => {
|
|
90
|
+
subscriptionsTotal = r
|
|
91
|
+
})
|
|
92
|
+
.catch(e => {
|
|
93
|
+
error = new Error(`Failed getting subscriptions: ${e}`);
|
|
94
|
+
self.assistant.error(error, {environment: 'production'});
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
if (error) {
|
|
98
|
+
return reject(error);
|
|
99
|
+
}
|
|
100
|
+
await stats
|
|
101
|
+
.set({
|
|
102
|
+
users: {
|
|
103
|
+
total: usersTotal,
|
|
104
|
+
},
|
|
105
|
+
subscriptions: {
|
|
106
|
+
total: subscriptionsTotal,
|
|
107
|
+
},
|
|
108
|
+
}, { merge: true })
|
|
109
|
+
.catch(function (e) {
|
|
110
|
+
return reject(e);
|
|
111
|
+
})
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return resolve(data);
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
Module.prototype.updateStats = function () {
|
|
119
|
+
const self = this;
|
|
120
|
+
|
|
121
|
+
return new Promise(async function(resolve, reject) {
|
|
122
|
+
const stats = self.libraries.admin.firestore().doc(`meta/stats`);
|
|
123
|
+
let online = self.libraries.admin.database().ref(`gatherings/online`);
|
|
124
|
+
let onlineCount = 0;
|
|
125
|
+
let error = null;
|
|
126
|
+
|
|
127
|
+
await online
|
|
128
|
+
.once('value')
|
|
129
|
+
.then((snap) => {
|
|
130
|
+
let data = snap.val() || {};
|
|
131
|
+
let keys = Object.keys(data);
|
|
132
|
+
onlineCount = keys.length;
|
|
133
|
+
})
|
|
134
|
+
.catch(e => {
|
|
135
|
+
error = new Error(`Failed getting online users: ${e}`);
|
|
136
|
+
})
|
|
137
|
+
|
|
138
|
+
if (error) {
|
|
139
|
+
return reject(error);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
await stats
|
|
143
|
+
.set({
|
|
144
|
+
users: {
|
|
145
|
+
online: onlineCount
|
|
146
|
+
}
|
|
147
|
+
}, { merge: true })
|
|
148
|
+
.catch(function (e) {
|
|
149
|
+
return reject(`Failed getting stats: ${e}`);
|
|
150
|
+
})
|
|
151
|
+
|
|
152
|
+
return resolve();
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
Module.prototype.getAllUsers = function () {
|
|
157
|
+
const self = this;
|
|
158
|
+
return new Promise(async function(resolve, reject) {
|
|
159
|
+
self.users = [];
|
|
160
|
+
await getUsersBatch(self)
|
|
161
|
+
.catch(e => {
|
|
162
|
+
return reject(e);
|
|
163
|
+
})
|
|
164
|
+
return resolve(self.users);
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
Module.prototype.getAllSubscriptions = function () {
|
|
169
|
+
const self = this;
|
|
170
|
+
return new Promise(async function(resolve, reject) {
|
|
171
|
+
await self.libraries.admin.firestore().collection('notifications/subscriptions/all')
|
|
172
|
+
.get()
|
|
173
|
+
.then(function(querySnapshot) {
|
|
174
|
+
return resolve(querySnapshot.size)
|
|
175
|
+
})
|
|
176
|
+
.catch(function(e) {
|
|
177
|
+
return reject(e)
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
function getUsersBatch(self, nextPageToken) {
|
|
183
|
+
return new Promise(async function(resolve, reject) {
|
|
184
|
+
self.libraries.admin.auth().listUsers(1000, nextPageToken)
|
|
185
|
+
.then(function(listUsersResult) {
|
|
186
|
+
self.users = self.users.concat(listUsersResult.users);
|
|
187
|
+
if (listUsersResult.pageToken) {
|
|
188
|
+
// List next batch of users.
|
|
189
|
+
getUsersBatch(self, listUsersResult.pageToken)
|
|
190
|
+
.then(() => {
|
|
191
|
+
return resolve(listUsersResult.users);
|
|
192
|
+
})
|
|
193
|
+
.catch((e) => {
|
|
194
|
+
return reject(e);
|
|
195
|
+
})
|
|
196
|
+
} else {
|
|
197
|
+
return resolve(listUsersResult.users);
|
|
198
|
+
}
|
|
199
|
+
})
|
|
200
|
+
.catch(function(e) {
|
|
201
|
+
return reject(e);
|
|
202
|
+
});
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
module.exports = Module;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
const _ = require('lodash');
|
|
2
|
+
|
|
3
|
+
function Module() {
|
|
4
|
+
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
Module.prototype.init = async function (s, payload) {
|
|
8
|
+
const self = this;
|
|
9
|
+
self.Manager = s.Manager;
|
|
10
|
+
self.libraries = s.Manager.libraries;
|
|
11
|
+
self.assistant = s.Manager.assistant;
|
|
12
|
+
self.payload = payload;
|
|
13
|
+
|
|
14
|
+
return self;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
Module.prototype.main = function () {
|
|
18
|
+
const self = this;
|
|
19
|
+
const Manager = self.Manager;
|
|
20
|
+
const assistant = self.assistant;
|
|
21
|
+
const payload = self.payload;
|
|
22
|
+
|
|
23
|
+
return new Promise(async function(resolve, reject) {
|
|
24
|
+
|
|
25
|
+
if (!payload.user.roles.admin) {
|
|
26
|
+
return reject(assistant.errorManager(`Admin required.`, {code: 401, sentry: false, send: false, log: false}).error)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const productId = _.get(payload, 'data.payload.payload.details.productIdGlobal');
|
|
30
|
+
if (!productId) {
|
|
31
|
+
return reject(assistant.errorManager(`No productId`, {code: 400, sentry: false, send: false, log: false}).error)
|
|
32
|
+
}
|
|
33
|
+
const processorPath = `${process.cwd()}/payment-processors/${productId}.js`
|
|
34
|
+
let processor;
|
|
35
|
+
// console.log('---processorPath', processorPath);
|
|
36
|
+
try {
|
|
37
|
+
processor = new (require(processorPath));
|
|
38
|
+
processor.Manager = self.Manager;
|
|
39
|
+
} catch (e) {
|
|
40
|
+
self.assistant.error('Error loading processor', processorPath, e, {environment: 'production'})
|
|
41
|
+
return resolve({data: {}})
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
await processor.process(payload.data.payload)
|
|
45
|
+
.then(result => {
|
|
46
|
+
return resolve({data: result});
|
|
47
|
+
})
|
|
48
|
+
.catch(e => {
|
|
49
|
+
return reject(assistant.errorManager(`Payment processor @ "${processorPath}" failed: ${e}`, {code: 400, sentry: true, send: false, log: false}).error)
|
|
50
|
+
})
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
module.exports = Module;
|
|
@@ -0,0 +1,189 @@
|
|
|
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.init = async function (s, payload) {
|
|
10
|
+
const self = this;
|
|
11
|
+
self.Manager = s.Manager;
|
|
12
|
+
self.libraries = s.Manager.libraries;
|
|
13
|
+
self.assistant = s.assistant;
|
|
14
|
+
self.payload = payload;
|
|
15
|
+
|
|
16
|
+
return self;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
Module.prototype.main = function () {
|
|
20
|
+
const self = this;
|
|
21
|
+
const Manager = self.Manager;
|
|
22
|
+
const assistant = self.assistant;
|
|
23
|
+
const payload = self.payload;
|
|
24
|
+
|
|
25
|
+
return new Promise(async function(resolve, reject) {
|
|
26
|
+
|
|
27
|
+
// console.log('----self.Manager.libraries', self.Manager.libraries);
|
|
28
|
+
// console.log('----self.Manager.libraries.sentry 1', self.Manager.libraries.sentry);
|
|
29
|
+
|
|
30
|
+
if (!payload.user.roles.admin) {
|
|
31
|
+
return reject(assistant.errorManager(`Admin required.`, {code: 401, sentry: false, send: false, log: false}).error)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (!payload.data.payload.title || !payload.data.payload.body) {
|
|
35
|
+
return reject(assistant.errorManager(`Parameters <title> and <body> required`, {code: 400, sentry: true, send: false, log: false}).error)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
await self.getTokens({tags: false})
|
|
39
|
+
.then(r => {
|
|
40
|
+
return resolve({data: r})
|
|
41
|
+
})
|
|
42
|
+
.catch(e => {
|
|
43
|
+
return reject(assistant.errorManager(`Failed to send notification: ${e}`, {code: 400, sentry: true, send: false, log: false}).error)
|
|
44
|
+
})
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
// HELPERS //
|
|
50
|
+
Module.prototype.getTokens = function (options) {
|
|
51
|
+
const self = this;
|
|
52
|
+
options = options || {};
|
|
53
|
+
options.tags = options.tags || false;
|
|
54
|
+
|
|
55
|
+
return new Promise(async function(resolve, reject) {
|
|
56
|
+
let subs = self.libraries.admin.firestore().collection(path_subscriptions);
|
|
57
|
+
let batchPromises = [];
|
|
58
|
+
|
|
59
|
+
if (options.tags) {
|
|
60
|
+
subs.where('tags', 'array-contains-any', options.tags)
|
|
61
|
+
}
|
|
62
|
+
await subs
|
|
63
|
+
.get()
|
|
64
|
+
.then(function(querySnapshot) {
|
|
65
|
+
self.assistant.log(`Queried ${querySnapshot.size} tokens.`);
|
|
66
|
+
// self.result.subscriptionsStart = querySnapshot.size;
|
|
67
|
+
let batchCurrentSize = 0;
|
|
68
|
+
let batchSizeMax = 1000;
|
|
69
|
+
|
|
70
|
+
let batchCurrent = [];
|
|
71
|
+
let batchLoops = 1;
|
|
72
|
+
|
|
73
|
+
querySnapshot.forEach(function(doc) {
|
|
74
|
+
// log(self, 'loading... ', batchLoops+'/'+querySnapshot.size);
|
|
75
|
+
if ((batchCurrentSize < batchSizeMax - 1) && (batchLoops < querySnapshot.size)) {
|
|
76
|
+
batchCurrent.push(doc.data().token);
|
|
77
|
+
batchCurrentSize++;
|
|
78
|
+
} else {
|
|
79
|
+
let batchId = batchPromises.length + 1;
|
|
80
|
+
batchCurrent.push(doc.data().token);
|
|
81
|
+
batchCurrentSize++;
|
|
82
|
+
console.log(`Got batch ID: ${batchId} with ${batchCurrentSize} tokens.`);
|
|
83
|
+
batchPromises.push(self.sendBatch(batchCurrent, batchId));
|
|
84
|
+
batchCurrent = [];
|
|
85
|
+
batchCurrentSize = 0;
|
|
86
|
+
}
|
|
87
|
+
batchLoops++;
|
|
88
|
+
});
|
|
89
|
+
})
|
|
90
|
+
.catch(function(e) {
|
|
91
|
+
self.assistant.error('Error querying tokens: ', e, {environment: 'production'})
|
|
92
|
+
reject(error);
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
await Promise.all(batchPromises)
|
|
96
|
+
.then(function(values) {
|
|
97
|
+
self.assistant.log('Finished all batches.');
|
|
98
|
+
})
|
|
99
|
+
.catch(function(e) {
|
|
100
|
+
self.assistant.error('Error sending batches: ', e, {environment: 'production'})
|
|
101
|
+
});
|
|
102
|
+
resolve();
|
|
103
|
+
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
Module.prototype.sendBatch = function (batch, id) {
|
|
108
|
+
const self = this;
|
|
109
|
+
return new Promise(async function(resolve, reject) {
|
|
110
|
+
// self.assistant.log(`Sending batch ID: ${id}`, batch);
|
|
111
|
+
self.assistant.log(`Sending batch ID: ${id}`);
|
|
112
|
+
|
|
113
|
+
// self.assistant.log('payload', payload);
|
|
114
|
+
|
|
115
|
+
let payload = {};
|
|
116
|
+
payload.notification = {};
|
|
117
|
+
payload.notification.title = self.payload.data.payload.title;
|
|
118
|
+
payload.notification.clickAction = self.payload.data.payload.click_action || self.payload.data.payload.clickAction;
|
|
119
|
+
payload.notification.click_action = self.payload.data.payload.click_action || self.payload.data.payload.clickAction;
|
|
120
|
+
payload.notification.body = self.payload.data.payload.body;
|
|
121
|
+
payload.notification.icon = self.payload.data.payload.icon || self.Manager.config.brand.brandmark;
|
|
122
|
+
|
|
123
|
+
// payload.data = {};
|
|
124
|
+
// payload.data.clickAction = self.payload.data.payload.click_action || self.payload.data.payload.clickAction;
|
|
125
|
+
// payload.data.click_action = self.payload.data.payload.click_action || self.payload.data.payload.clickAction;
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
await self.libraries.admin.messaging().sendToDevice(batch, payload)
|
|
129
|
+
.then(async function (response) {
|
|
130
|
+
// self.result.batches.list.push('#' + id + ' | ' + '✅ ' + response.successCount + ' | ' + '❌ ' + response.failureCount);
|
|
131
|
+
self.assistant.log('Sent batch #' + id);
|
|
132
|
+
// self.result.successes += response.successCount;
|
|
133
|
+
// self.result.failures += response.failureCount;
|
|
134
|
+
// console.log('RESP', response);
|
|
135
|
+
if (response.failureCount > 0) {
|
|
136
|
+
await self.cleanTokens(batch, response.results, id);
|
|
137
|
+
}
|
|
138
|
+
resolve();
|
|
139
|
+
})
|
|
140
|
+
.catch(function (e) {
|
|
141
|
+
self.assistant.error('Error sending batch #' + id, e, {environment: 'production'});
|
|
142
|
+
// self.result.status = 'fail';
|
|
143
|
+
reject(e);
|
|
144
|
+
})
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
Module.prototype.cleanTokens = function (batch, results, id) {
|
|
149
|
+
const self = this;
|
|
150
|
+
|
|
151
|
+
return new Promise(async function(resolve, reject) {
|
|
152
|
+
let cleanPromises = [];
|
|
153
|
+
// self.assistant.log(`Cleaning tokens of batch ID: ${id}`, results);
|
|
154
|
+
self.assistant.log(`Cleaning tokens of batch ID: ${id}`);
|
|
155
|
+
|
|
156
|
+
results.forEach(function (item, index) {
|
|
157
|
+
if (!item.error) { return false; }
|
|
158
|
+
let curCode = item.error.code;
|
|
159
|
+
let token = batch[index];
|
|
160
|
+
self.assistant.log(`Found bad token: ${index} = ${curCode}`);
|
|
161
|
+
if (badTokenReasons.includes(curCode)) {
|
|
162
|
+
cleanPromises.push(self.deleteToken(token, curCode));
|
|
163
|
+
}
|
|
164
|
+
})
|
|
165
|
+
await Promise.all(cleanPromises)
|
|
166
|
+
.catch(function(e) {
|
|
167
|
+
self.assistant.log('error', "Error cleaning failed tokens: ", e);
|
|
168
|
+
});
|
|
169
|
+
resolve();
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
Module.prototype.deleteToken = function (token, errorCode) {
|
|
174
|
+
const self = this;
|
|
175
|
+
return new Promise(function(resolve, reject) {
|
|
176
|
+
self.libraries.admin.firestore().doc(`${path_subscriptions}/${token}`)
|
|
177
|
+
.delete()
|
|
178
|
+
.then(function() {
|
|
179
|
+
self.assistant.log(`Deleting bad token: ${token} for reason ${errorCode}`);
|
|
180
|
+
resolve();
|
|
181
|
+
})
|
|
182
|
+
.catch(function(error) {
|
|
183
|
+
self.assistant.log('error', `Error deleting bad token: ${token} for reason ${errorCode} because of error ${error}`);
|
|
184
|
+
resolve();
|
|
185
|
+
})
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
module.exports = Module;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
const uuid = require('uuid');
|
|
2
|
+
|
|
3
|
+
function Module() {
|
|
4
|
+
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
Module.prototype.init = async function (s, payload) {
|
|
8
|
+
const self = this;
|
|
9
|
+
self.Manager = s.Manager;
|
|
10
|
+
self.libraries = s.Manager.libraries;
|
|
11
|
+
self.assistant = s.Manager.assistant;
|
|
12
|
+
self.payload = payload;
|
|
13
|
+
|
|
14
|
+
return self;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
Module.prototype.main = function () {
|
|
18
|
+
const self = this;
|
|
19
|
+
const Manager = self.Manager;
|
|
20
|
+
const assistant = self.assistant;
|
|
21
|
+
const payload = self.payload;
|
|
22
|
+
|
|
23
|
+
return new Promise(async function(resolve, reject) {
|
|
24
|
+
|
|
25
|
+
let result = '';
|
|
26
|
+
payload.data.payload.namespace = payload.data.payload.namespace || Manager.config.backend_manager.namespace;
|
|
27
|
+
payload.data.payload.version = `${payload.data.payload.version || '5'}`.replace('v', '');
|
|
28
|
+
payload.data.payload.name = payload.data.payload.name || payload.data.payload.input;
|
|
29
|
+
|
|
30
|
+
if (payload.data.payload.version === '5') {
|
|
31
|
+
if (!payload.data.payload.name) {
|
|
32
|
+
return reject(assistant.errorManager(`You must provide a name to hash for uuid v5.`, {code: 400, sentry: false, send: false, log: false}).error)
|
|
33
|
+
} else {
|
|
34
|
+
result = uuid.v5(payload.data.payload.name, payload.data.payload.namespace);
|
|
35
|
+
}
|
|
36
|
+
} else if (payload.data.payload.version === '4') {
|
|
37
|
+
result = uuid.v4();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
assistant.log('UUID Generated', payload.data.payload, result, {environment: 'production'});
|
|
41
|
+
|
|
42
|
+
return resolve({data: {uuid: result}});
|
|
43
|
+
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
module.exports = Module;
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
const fetch = require('node-fetch');
|
|
2
|
+
const _ = require('lodash')
|
|
3
|
+
|
|
4
|
+
function Module() {
|
|
5
|
+
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
Module.prototype.init = async function (s, payload) {
|
|
9
|
+
const self = this;
|
|
10
|
+
self.Manager = s.Manager;
|
|
11
|
+
self.libraries = s.Manager.libraries;
|
|
12
|
+
self.assistant = s.Manager.assistant;
|
|
13
|
+
self.payload = payload;
|
|
14
|
+
|
|
15
|
+
return self;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
Module.prototype.main = function () {
|
|
19
|
+
const self = this;
|
|
20
|
+
const Manager = self.Manager;
|
|
21
|
+
const assistant = self.assistant;
|
|
22
|
+
const payload = self.payload;
|
|
23
|
+
|
|
24
|
+
return new Promise(async function(resolve, reject) {
|
|
25
|
+
|
|
26
|
+
if (!payload.user.roles.admin) {
|
|
27
|
+
return reject(assistant.errorManager(`Admin required.`, {code: 401, sentry: false, send: false, log: false}).error)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const createdInvoice = await fetch('https://us-central1-itw-creative-works.cloudfunctions.net/wrapper', {
|
|
31
|
+
method: 'POST',
|
|
32
|
+
headers: { 'Content-Type': 'application/json' },
|
|
33
|
+
body: JSON.stringify({
|
|
34
|
+
authenticationToken: Manager.config.backend_manager.key,
|
|
35
|
+
method: 'post',
|
|
36
|
+
service: 'paypal',
|
|
37
|
+
command: 'v2/invoicing/invoices',
|
|
38
|
+
body: {
|
|
39
|
+
detail: {
|
|
40
|
+
currency_code: 'USD',
|
|
41
|
+
note: `Post to ${Manager.config.brand.name}`,
|
|
42
|
+
},
|
|
43
|
+
primary_recipients: [
|
|
44
|
+
{
|
|
45
|
+
billing_info: {
|
|
46
|
+
email_address: payload.data.payload.invoiceEmail,
|
|
47
|
+
},
|
|
48
|
+
}
|
|
49
|
+
],
|
|
50
|
+
items: [
|
|
51
|
+
{
|
|
52
|
+
name: `Guest post`,
|
|
53
|
+
description: `blog/${payload.data.payload.url}`,
|
|
54
|
+
quantity: '1',
|
|
55
|
+
unit_amount: {
|
|
56
|
+
currency_code: 'USD',
|
|
57
|
+
value: `${payload.data.payload.invoicePrice}`
|
|
58
|
+
},
|
|
59
|
+
// discount: {
|
|
60
|
+
// percent: '5'
|
|
61
|
+
// },
|
|
62
|
+
unit_of_measure: 'QUANTITY'
|
|
63
|
+
},
|
|
64
|
+
],
|
|
65
|
+
}
|
|
66
|
+
}),
|
|
67
|
+
})
|
|
68
|
+
.then(function (res) {
|
|
69
|
+
return res.text()
|
|
70
|
+
.then(function (data) {
|
|
71
|
+
if (res.ok) {
|
|
72
|
+
return JSON.parse(data)
|
|
73
|
+
} else {
|
|
74
|
+
throw new Error(data || res.statusText || 'Unknown error.')
|
|
75
|
+
}
|
|
76
|
+
})
|
|
77
|
+
})
|
|
78
|
+
.catch(function (e) {
|
|
79
|
+
return e;
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
if (createdInvoice instanceof Error) {
|
|
83
|
+
return reject(assistant.errorManager(createdInvoice, {code: 400, sentry: false, send: false, log: false}).error)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const createdInvoiceId = _.get(createdInvoice, 'href', '').split('/').pop();
|
|
87
|
+
const sentInvoice = await fetch('https://us-central1-itw-creative-works.cloudfunctions.net/wrapper', {
|
|
88
|
+
method: 'POST',
|
|
89
|
+
headers: { 'Content-Type': 'application/json' },
|
|
90
|
+
body: JSON.stringify({
|
|
91
|
+
authenticationToken: Manager.config.backend_manager.key,
|
|
92
|
+
service: 'paypal',
|
|
93
|
+
command: `v2/invoicing/invoices/${createdInvoiceId}/send`,
|
|
94
|
+
method: 'post',
|
|
95
|
+
body: {
|
|
96
|
+
}
|
|
97
|
+
}),
|
|
98
|
+
})
|
|
99
|
+
.then(function (res) {
|
|
100
|
+
return res.text()
|
|
101
|
+
.then(function (data) {
|
|
102
|
+
if (res.ok) {
|
|
103
|
+
return resolve({data: JSON.parse(data)})
|
|
104
|
+
} else {
|
|
105
|
+
throw new Error(data || res.statusText || 'Unknown error.')
|
|
106
|
+
}
|
|
107
|
+
})
|
|
108
|
+
})
|
|
109
|
+
.catch(function (e) {
|
|
110
|
+
return reject(assistant.errorManager(e, {code: 500, sentry: false, send: false, log: false}).error)
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
module.exports = Module;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
function Module() {
|
|
2
|
+
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
Module.prototype.init = async function (s, payload) {
|
|
6
|
+
const self = this;
|
|
7
|
+
self.Manager = s.Manager;
|
|
8
|
+
self.libraries = s.Manager.libraries;
|
|
9
|
+
self.assistant = s.Manager.assistant;
|
|
10
|
+
self.payload = payload;
|
|
11
|
+
|
|
12
|
+
return self;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
Module.prototype.main = function () {
|
|
16
|
+
const self = this;
|
|
17
|
+
const Manager = self.Manager;
|
|
18
|
+
const assistant = self.assistant;
|
|
19
|
+
const payload = self.payload;
|
|
20
|
+
|
|
21
|
+
return new Promise(async function(resolve, reject) {
|
|
22
|
+
|
|
23
|
+
if (!payload.user.roles.admin) {
|
|
24
|
+
return reject(assistant.errorManager(`Admin required.`, {code: 401, sentry: false, send: false, log: false}).error)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return resolve({data: {success: true}});
|
|
28
|
+
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
module.exports = Module;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
function Module() {
|
|
2
|
+
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
Module.prototype.init = async function (s, payload) {
|
|
6
|
+
const self = this;
|
|
7
|
+
self.Manager = s.Manager;
|
|
8
|
+
self.libraries = s.Manager.libraries;
|
|
9
|
+
self.assistant = s.Manager.assistant;
|
|
10
|
+
self.payload = payload;
|
|
11
|
+
|
|
12
|
+
return self;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
Module.prototype.main = function () {
|
|
16
|
+
const self = this;
|
|
17
|
+
const Manager = self.Manager;
|
|
18
|
+
const assistant = self.assistant;
|
|
19
|
+
const payload = self.payload;
|
|
20
|
+
|
|
21
|
+
return new Promise(async function(resolve, reject) {
|
|
22
|
+
|
|
23
|
+
assistant.log('User:', payload.user);
|
|
24
|
+
|
|
25
|
+
return resolve({data: {user: payload.user}});
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
module.exports = Module;
|