backend-manager 2.0.17 → 2.0.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -2
- package/src/manager/helpers/api-manager.js +137 -51
package/package.json
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const moment = require('moment');
|
|
2
|
+
const fetch = require('node-fetch');
|
|
2
3
|
const uuidv5 = require('uuid').v5;
|
|
3
4
|
const { get, set, merge } = require('lodash');
|
|
4
5
|
|
|
@@ -12,16 +13,20 @@ let sampleUser = {
|
|
|
12
13
|
}
|
|
13
14
|
},
|
|
14
15
|
authenticated: false,
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
_APIManager: {
|
|
17
|
+
meta: {
|
|
18
|
+
lastStatsReset: new Date(),
|
|
19
|
+
lastUserFetch: new Date(),
|
|
20
|
+
}
|
|
18
21
|
}
|
|
19
22
|
}
|
|
20
23
|
|
|
21
|
-
function ApiManager() {
|
|
24
|
+
function ApiManager(m) {
|
|
22
25
|
const self = this;
|
|
26
|
+
self.Manager = m;
|
|
23
27
|
self.options = {
|
|
24
|
-
|
|
28
|
+
appId: '',
|
|
29
|
+
plans: {},
|
|
25
30
|
maxUsersStored: 10000,
|
|
26
31
|
refetchInterval: 60,
|
|
27
32
|
resetInterval: 60 * 24,
|
|
@@ -33,27 +38,71 @@ function ApiManager() {
|
|
|
33
38
|
|
|
34
39
|
ApiManager.prototype.init = function (options) {
|
|
35
40
|
const self = this;
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
41
|
+
return new Promise(async function(resolve, reject) {
|
|
42
|
+
options = options || {};
|
|
43
|
+
options.app = options.app || '';
|
|
44
|
+
options.plans = options.plans || {};
|
|
45
|
+
|
|
46
|
+
// await self.Manager.libraries.admin.firestore
|
|
47
|
+
// options.plans.basic = options.plans.basic || {requests: 100};
|
|
48
|
+
|
|
49
|
+
options.maxUsersStored = options.maxUsersStored || 10000;
|
|
50
|
+
options.refetchInterval = options.refetchInterval || 60;
|
|
51
|
+
options.resetInterval = options.resetInterval || (60 * 24);
|
|
52
|
+
options.officialAPIKeys = options.officialAPIKeys || [];
|
|
53
|
+
options.whitelistedAPIKeys = options.whitelistedAPIKeys || [];
|
|
39
54
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
55
|
+
await fetch('https://us-central1-itw-creative-works.cloudfunctions.net/getApp', {
|
|
56
|
+
method: 'POST',
|
|
57
|
+
headers: { 'Content-Type': 'application/json' },
|
|
58
|
+
body: JSON.stringify({
|
|
59
|
+
id: options.app,
|
|
60
|
+
}),
|
|
61
|
+
})
|
|
62
|
+
.then(res => {
|
|
63
|
+
res.text()
|
|
64
|
+
.then(text => {
|
|
65
|
+
if (res.ok) {
|
|
66
|
+
const data = JSON.parse(text);
|
|
44
67
|
|
|
45
|
-
|
|
68
|
+
options.plans = {};
|
|
46
69
|
|
|
47
|
-
|
|
70
|
+
Object.keys(data.products)
|
|
71
|
+
.forEach((id, i) => {
|
|
72
|
+
const product = data.products[id]
|
|
73
|
+
options.plans[product.planId] = {}
|
|
74
|
+
options.plans[product.planId].limits = product.limits || {};
|
|
75
|
+
});
|
|
48
76
|
|
|
49
|
-
|
|
77
|
+
self.options = options;
|
|
78
|
+
self.initialized = true;
|
|
79
|
+
|
|
80
|
+
return resolve(self);
|
|
81
|
+
} else {
|
|
82
|
+
throw new Error(text || res.statusText || 'Unknown error.')
|
|
83
|
+
}
|
|
84
|
+
})
|
|
85
|
+
})
|
|
86
|
+
.catch(e => {
|
|
87
|
+
return reject(e)
|
|
88
|
+
})
|
|
89
|
+
});
|
|
50
90
|
};
|
|
51
91
|
|
|
52
|
-
ApiManager.prototype._createNewUser = function (authenticatedUser, planId, persistentData, isRefetch) {
|
|
92
|
+
ApiManager.prototype._createNewUser = function (authenticatedUser, planId, persistentData, isRefetch, apiKey) {
|
|
53
93
|
const self = this;
|
|
94
|
+
const _APIManager_default = {
|
|
95
|
+
stats: {
|
|
96
|
+
requests: 0,
|
|
97
|
+
},
|
|
98
|
+
meta: {
|
|
99
|
+
lastStatsReset: new Date(),
|
|
100
|
+
lastUserFetch: new Date(),
|
|
101
|
+
},
|
|
102
|
+
providedAPIKey: apiKey,
|
|
103
|
+
}
|
|
54
104
|
persistentData = persistentData || {};
|
|
55
|
-
persistentData.
|
|
56
|
-
persistentData._stats = persistentData._stats || {};
|
|
105
|
+
persistentData._APIManager = persistentData._APIManager || merge({}, _APIManager_default);
|
|
57
106
|
|
|
58
107
|
let newUser = {
|
|
59
108
|
api: get(authenticatedUser, 'api', {}),
|
|
@@ -61,35 +110,43 @@ ApiManager.prototype._createNewUser = function (authenticatedUser, planId, persi
|
|
|
61
110
|
plan: {
|
|
62
111
|
id: planId,
|
|
63
112
|
limits: {
|
|
64
|
-
requests: get(authenticatedUser, 'plan.limits.requests', get(self.options, `planData.${planId}.limits.requests`, 93)),
|
|
65
113
|
}
|
|
66
114
|
},
|
|
67
115
|
authenticated: authenticatedUser.authenticated,
|
|
68
116
|
ip: authenticatedUser.ip,
|
|
69
117
|
country: authenticatedUser.country,
|
|
70
|
-
|
|
71
|
-
requests: 0,
|
|
72
|
-
},
|
|
73
|
-
_meta: {
|
|
74
|
-
lastStatsReset: new Date(),
|
|
75
|
-
lastUserFetch: new Date(),
|
|
76
|
-
}
|
|
118
|
+
_APIManager: merge({}, _APIManager_default),
|
|
77
119
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
120
|
+
|
|
121
|
+
// Setup newUser
|
|
122
|
+
const currentPlan = get(self.options, `plans.${planId}.limits`, {})
|
|
123
|
+
Object.keys(currentPlan)
|
|
124
|
+
.forEach((id, i) => {
|
|
125
|
+
// console.log('----id', id);
|
|
126
|
+
// console.log('======currentPlan[id]', currentPlan[id]);
|
|
127
|
+
newUser.plan.limits[id] = get(authenticatedUser, `plan.limits.${id}`, currentPlan[id])
|
|
128
|
+
// const product = data.products[id]
|
|
129
|
+
// options.plans[product.planId] = {}
|
|
130
|
+
// options.plans[product.planId].limits = product.limits || {};
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
// console.log('-----MIN', moment().diff(moment(persistentData._APIManager.meta.lastStatsReset), 'minutes', true), self.options.resetInterval);
|
|
136
|
+
if (moment().diff(moment(persistentData._APIManager.meta.lastStatsReset), 'minutes', true) < self.options.resetInterval) {
|
|
137
|
+
newUser._APIManager.meta.lastStatsReset = persistentData._APIManager.meta.lastStatsReset || newUser._APIManager.meta.lastStatsReset;
|
|
138
|
+
newUser._APIManager.meta.lastUserFetch = persistentData._APIManager.meta.lastUserFetch || newUser._APIManager.meta.lastUserFetch;
|
|
139
|
+
Object.keys(persistentData._APIManager.stats)
|
|
83
140
|
.forEach((key, i) => {
|
|
84
|
-
newUser.
|
|
141
|
+
newUser._APIManager.stats[key] = persistentData._APIManager.stats[key];
|
|
85
142
|
});
|
|
86
143
|
} else {
|
|
87
144
|
// console.log('---RESSET INTERVAL REACHED');
|
|
88
|
-
newUser.
|
|
145
|
+
newUser._APIManager.meta.lastUserFetch = persistentData._APIManager.meta.lastUserFetch;
|
|
89
146
|
}
|
|
90
147
|
|
|
91
148
|
if (isRefetch) {
|
|
92
|
-
newUser.
|
|
149
|
+
newUser._APIManager.meta.lastUserFetch = new Date();
|
|
93
150
|
}
|
|
94
151
|
|
|
95
152
|
return newUser;
|
|
@@ -106,14 +163,14 @@ ApiManager.prototype.getUser = async function (assistant) {
|
|
|
106
163
|
if (apiKey) {
|
|
107
164
|
newUser = self.userList.filter(user => user.api.privateKey === apiKey);
|
|
108
165
|
if (newUser[0]) {
|
|
109
|
-
if (newUser.length > 1 || moment().diff(moment(newUser[0].
|
|
166
|
+
if (newUser.length > 1 || moment().diff(moment(newUser[0]._APIManager.meta.lastUserFetch), 'minutes', true) > self.options.refetchInterval) {
|
|
110
167
|
// console.log('----REFETCHING');
|
|
111
|
-
persistentData = {set: true,
|
|
168
|
+
persistentData = {set: true, _APIManager: merge({}, newUser[0]._APIManager)};
|
|
112
169
|
|
|
113
170
|
self.userList = self.userList.filter(user => user.api.privateKey !== apiKey)
|
|
114
171
|
newUser = null;
|
|
115
172
|
} else {
|
|
116
|
-
persistentData = {set: true,
|
|
173
|
+
persistentData = {set: true, _APIManager: merge({}, newUser[0]._APIManager)};
|
|
117
174
|
|
|
118
175
|
newUser = newUser[0];
|
|
119
176
|
}
|
|
@@ -139,20 +196,20 @@ ApiManager.prototype.getUser = async function (assistant) {
|
|
|
139
196
|
let existingUser = self.userList.find(user => user.auth.uid === workingUID);
|
|
140
197
|
if (existingUser) {
|
|
141
198
|
// console.log('---actually does exist so setting');
|
|
142
|
-
// console.log('----1111 MIN lastUserFetch', moment().diff(moment(existingUser.
|
|
143
|
-
persistentData = !persistentData.set ? {set: true,
|
|
199
|
+
// console.log('----1111 MIN lastUserFetch', moment().diff(moment(existingUser._APIManager.meta.lastUserFetch), 'minutes', true), self.options.refetchInterval);
|
|
200
|
+
persistentData = !persistentData.set ? {set: true, _APIManager: merge({}, existingUser._APIManager)} : persistentData;
|
|
144
201
|
// console.log('----persistentData 2', persistentData);
|
|
145
|
-
if (moment().diff(moment(existingUser.
|
|
202
|
+
if (moment().diff(moment(existingUser._APIManager.meta.lastUserFetch), 'minutes', true) > self.options.refetchInterval) {
|
|
146
203
|
// console.log('----REFETCHING');
|
|
147
204
|
self.userList = self.userList.filter(user => user.auth.uid !== workingUID)
|
|
148
|
-
existingUser = self._createNewUser(authenticatedUser, planId, persistentData, true);
|
|
205
|
+
existingUser = self._createNewUser(authenticatedUser, planId, persistentData, true, apiKey);
|
|
149
206
|
existingUser.auth.uid = workingUID;
|
|
150
207
|
self.userList = self.userList.concat(existingUser);
|
|
151
208
|
}
|
|
152
209
|
newUser = existingUser
|
|
153
210
|
} else {
|
|
154
211
|
// console.log('---actually doesnt exist making new user');
|
|
155
|
-
newUser = self._createNewUser(authenticatedUser, planId, persistentData)
|
|
212
|
+
newUser = self._createNewUser(authenticatedUser, planId, persistentData, false, apiKey)
|
|
156
213
|
newUser.auth.uid = workingUID;
|
|
157
214
|
self.userList = self.userList.concat(newUser);
|
|
158
215
|
}
|
|
@@ -164,27 +221,56 @@ ApiManager.prototype.getUser = async function (assistant) {
|
|
|
164
221
|
|
|
165
222
|
};
|
|
166
223
|
|
|
167
|
-
|
|
224
|
+
function _getUserStat(self, user, stat, def) {
|
|
225
|
+
const isWhitelistedAPIKey = self.options.whitelistedAPIKeys.includes(
|
|
226
|
+
get(user, `api.privateKey`, get(user, `_APIManager.providedAPIKey`))
|
|
227
|
+
);
|
|
228
|
+
// console.log('----user', user);
|
|
229
|
+
// console.log('----isWhitelistedAPIKey', isWhitelistedAPIKey);
|
|
230
|
+
return {
|
|
231
|
+
current: !isWhitelistedAPIKey ? get(user, `_APIManager.stats.${stat}`, typeof def !== 'undefined' ? def : 0) : 0,
|
|
232
|
+
limit: !isWhitelistedAPIKey ? get(user, `plan.limits.${stat}`, typeof def !== 'undefined' ? def : 0) : Infinity,
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
ApiManager.prototype.isUserOverStat = function (user, stat, def, frame) {
|
|
168
237
|
const self = this;
|
|
169
238
|
if (!user || !stat) {
|
|
170
239
|
throw new Error('<user> and <stat> required')
|
|
171
240
|
}
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
241
|
+
const result = self.getUserStat(user, stat, def);
|
|
242
|
+
frame = frame || 'daily';
|
|
243
|
+
let limit = result.limit;
|
|
244
|
+
// console.log('---result', result);
|
|
245
|
+
// console.log('---typeof result.current', typeof result.current);
|
|
246
|
+
// console.log('----limit', limit);
|
|
247
|
+
if (typeof result.limit === 'number') {
|
|
248
|
+
if (frame === 'daily') {
|
|
249
|
+
limit = Math.floor(result.limit / 31);
|
|
250
|
+
}
|
|
251
|
+
// console.log('----limit', limit);
|
|
252
|
+
// console.log('-----result.current < limit', result.current < limit);
|
|
253
|
+
return limit >= result.current;
|
|
175
254
|
}
|
|
255
|
+
|
|
256
|
+
return false;
|
|
176
257
|
}
|
|
177
258
|
|
|
178
|
-
ApiManager.prototype.
|
|
259
|
+
ApiManager.prototype.getUserStat = function (user, stat, def, ) {
|
|
179
260
|
const self = this;
|
|
180
261
|
if (!user || !stat) {
|
|
181
262
|
throw new Error('<user> and <stat> required')
|
|
182
263
|
}
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
264
|
+
return _getUserStat(self, user, stat, def);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
ApiManager.prototype.incrementUserStat = function (user, stat, amount) {
|
|
268
|
+
const self = this;
|
|
269
|
+
if (!user || !stat) {
|
|
270
|
+
throw new Error('<user> and <stat> required')
|
|
187
271
|
}
|
|
272
|
+
set(user, `_APIManager.stats.${stat}`, get(user, `_APIManager.stats.${stat}`, 0) + amount)
|
|
273
|
+
return _getUserStat(self, user, stat, 0);
|
|
188
274
|
}
|
|
189
275
|
|
|
190
276
|
|