Skip to content

Commit 03f4c96

Browse files
authored
Merge branch 'master' into dependabot/npm_and_yarn/plugins/push/tar-fs-2.1.2
2 parents b63956d + e275acb commit 03f4c96

50 files changed

Lines changed: 2208 additions & 1020 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,5 @@ log/
4444
log/supervisord/
4545
plugins/plugins.json.*
4646
.sdk
47-
dump
47+
dump
48+
dist/

CHANGELOG.md

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,26 @@
1-
## Version 25.03.x
1+
## Version 25.03.4
2+
Features:
3+
- Add ability to allow multiple CORS per app for web apps
4+
- Add app id and name as view segment for self-tracking
5+
- [dashboards] Added the option to set a refresh rate for dashboards, allowing data to update more frequently for selected dashboards
6+
7+
Enterprise Features:
8+
- [license] Update locking conditions for expired license and over limit usage
9+
- [license] Enable force locking with remote config
10+
- [license] Update dashboard lock with redirection to home page for non admin user
11+
12+
Fixes:
13+
- [core] Allow downloading data also from other databases in dbviewer
14+
- [crashes] Fix unescaped SDK logs
15+
- [crash_symbolication] Symbolication server api end point test fix
16+
- [star-rating] Added missing columns to Rating Widgets table edit
17+
- [ui] Fix alignment of drawers title and close icon
18+
- [push] Fixed push notifications title and content text and variables combination
19+
- [reports] Correctly match event for email report if event key contains '.'
20+
21+
Enterprise Fixes:
22+
- [cohorts] Fixed issue with combining multiple cohorts
23+
- [drill] Do not recheck old collections on app_user data deletion if querying from old collections is disabled
224

325
Dependencies:
426
- Bump body-parser from 1.20.3 to 2.2.0

api/jobs/topEvents.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,14 +138,19 @@ class TopEventsJob extends job.Job {
138138
* The errors of all functions will be caught here.
139139
*/
140140
async getAllApps() {
141+
log.d("Fetching all apps");
141142
try {
142143
const getAllApps = await new Promise((res, rej) => common.db.collection("apps").find({}, { _id: 1, timezone: 1 }).toArray((err, apps) => err ? rej(err) : res(apps)));
143-
await Promise.all(getAllApps.map((app) => this.getAppEvents(app)));
144+
for (var z = 0; z < getAllApps.length; z++) {
145+
//Calculating for each app serially.
146+
await this.getAppEvents(getAllApps[z]);
147+
}
144148
}
145149
catch (error) {
146150
log.e("TopEvents Job has a error: ", error);
147151
throw error;
148152
}
153+
log.d("Finished processing");
149154
}
150155

151156
/**
@@ -178,6 +183,7 @@ class TopEventsJob extends job.Job {
178183
* @param {Object} app - saveAppEvents object
179184
*/
180185
async getAppEvents(app) {
186+
log.d(app._id + ": Fetching app events");
181187
const getEvents = await new Promise((res, rej) => common.db.collection("events").findOne({ _id: app._id }, (errorEvents, result) => errorEvents ? rej(errorEvents) : res(result)));
182188
if (getEvents && 'list' in getEvents) {
183189
const eventMap = this.eventsFilter(getEvents.list);
@@ -199,6 +205,7 @@ class TopEventsJob extends job.Job {
199205
let totalDuration = 0;
200206
let prevTotalDuration = 0;
201207
for (const event of eventMap) {
208+
log.d(" getting event data for event: " + event + " (" + period + ")");
202209
const collectionNameEvents = this.eventsCollentions({ event, id: app._id });
203210
await this.getEventsCount({ collectionNameEvents, ob, data, event });
204211
totalCount += data[event].data.count.total;
@@ -208,11 +215,16 @@ class TopEventsJob extends job.Job {
208215
totalDuration += data[event].data.duration.total;
209216
prevTotalDuration += data[event].data.duration["prev-total"];
210217
}
218+
log.d(" getting session count (" + period + ")");
211219
await this.getSessionCount({ ob, sessionData, usersData, usersCollectionName });
220+
log.d(" saving data (" + period + ")");
212221
await this.saveAppEvents({ app, data, sessionData, usersData, period, totalCount, prevTotalCount, totalSum, prevTotalSum, totalDuration, prevTotalDuration });
213222
}
214223
}
215224
}
225+
else {
226+
log.d(" No events found for app");
227+
}
216228

217229
}
218230

api/lib/countly.common.js

Lines changed: 31 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,15 @@
33
* @module "api/lib/countly.common"
44
*/
55

6+
/**
7+
* @typedef {import('moment-timezone').Moment} MomentTimezone
8+
*/
9+
610
/** @lends module:api/lib/countly.common */
711
var countlyCommon = {},
12+
/**
13+
* Reference to momentjs
14+
*/
815
moment = require('moment-timezone'),
916
underscore = require('underscore');
1017

@@ -16,57 +23,11 @@ var _period = "hour",
1623
// Private Methods
1724

1825
/**
19-
* Returns array with unique ticks for period
20-
* @param {moment} startTimestamp - start of period
21-
* @param {moment} endTimestamp - end of period
22-
* @returns {array} unique array ticks for period
23-
**/
24-
/*function getTicksBetween(startTimestamp, endTimestamp) {
25-
var dayIt = startTimestamp.clone(),
26-
ticks = [];
27-
28-
while (dayIt < endTimestamp) {
29-
let daysLeft = Math.round(moment.duration(endTimestamp - dayIt).asDays());
30-
if (daysLeft >= dayIt.daysInMonth() && dayIt.date() === 1) {
31-
ticks.push(dayIt.format("YYYY.M"));
32-
dayIt.add(1 + dayIt.daysInMonth() - dayIt.date(), "days");
33-
}
34-
else if (daysLeft >= (7 - dayIt.day()) && dayIt.day() === 1) {
35-
ticks.push(dayIt.format("YYYY.[w]W"));
36-
dayIt.add(8 - dayIt.day(), "days");
37-
}
38-
else {
39-
ticks.push(dayIt.format("YYYY.M.D"));
40-
dayIt.add(1, "day");
41-
}
42-
}
43-
44-
return ticks;
45-
}*/
46-
47-
/**
48-
* Returns array with more generalized unique ticks for period
49-
* @param {moment} startTimestamp - start of period
50-
* @param {moment} endTimestamp - end of period
51-
* @returns {array} unique array ticks for period
52-
**/
53-
/*function getTicksCheckBetween(startTimestamp, endTimestamp) {
54-
var dayIt = startTimestamp.clone(),
55-
ticks = [];
56-
while (dayIt < endTimestamp) {
57-
let daysLeft = Math.round(moment.duration(endTimestamp - dayIt).asDays());
58-
if (daysLeft >= (dayIt.daysInMonth() * 0.5 - dayIt.date())) {
59-
ticks.push(dayIt.format("YYYY.M"));
60-
dayIt.add(1 + dayIt.daysInMonth() - dayIt.date(), "days");
61-
}
62-
else {
63-
ticks.push(dayIt.format("YYYY.[w]W"));
64-
dayIt.add(8 - dayIt.day(), "days");
65-
}
66-
}
67-
return ticks;
68-
}*/
69-
26+
* Calculates unique values from a hierarchical map structure
27+
* @param {Object} dbObj - Database object containing hierarchical data (years, months, weeks, days)
28+
* @param {Object} uniqueMap - Map with hierarchical structure (years, months, weeks, days) used to calculate unique values
29+
* @returns {number} - Count of unique items
30+
*/
7031
countlyCommon.calculateUniqueFromMap = function(dbObj, uniqueMap) {
7132
var u = 0;
7233
for (var year in uniqueMap) {
@@ -105,13 +66,13 @@ countlyCommon.calculateUniqueFromMap = function(dbObj, uniqueMap) {
10566
};
10667

10768
/** returns unique period check array
108-
* @param {array} weeksArray_pd - weeks array
109-
* @param {array} weekCounts_pd - week counts
110-
* @param {array} monthsArray_pd - months array
111-
* @param {array} monthCounts_pd - months counts
112-
* @param {array} periodArr_pd - period array
113-
* @returns {array} periods
114-
*/
69+
* @param {Array<string>} weeksArray_pd - weeks array
70+
* @param {Array<string>} weekCounts_pd - week counts
71+
* @param {Array<string>} monthsArray_pd - months array
72+
* @param {Array<string>} monthCounts_pd - months counts
73+
* @param {Array<string>} periodArr_pd - period array
74+
* @returns {Array<string>} periods
75+
*/
11576
function getUniqArray(weeksArray_pd, weekCounts_pd, monthsArray_pd, monthCounts_pd, periodArr_pd) {
11677

11778
if (_period === "month" || _period === "day" || _period === "yesterday" || _period === "hour") {
@@ -230,12 +191,12 @@ function getUniqArray(weeksArray_pd, weekCounts_pd, monthsArray_pd, monthCounts_
230191
return uniquePeriods;
231192
}
232193
/** returns unique period check array
233-
* @param {array} weeksArray_pd - weeks array
234-
* @param {array} weekCounts_pd - week counts
235-
* @param {array} monthsArray_pd - months array
236-
* @param {array} monthCounts_pd - months counts
237-
* @returns {array} periods
238-
*/
194+
* @param {Array<string>} weeksArray_pd - weeks array
195+
* @param {Array<string>} weekCounts_pd - week counts
196+
* @param {Array<string>} monthsArray_pd - months array
197+
* @param {Array<string>} monthCounts_pd - months counts
198+
* @returns {Array<string>} periods
199+
*/
239200
function getUniqCheckArray(weeksArray_pd, weekCounts_pd, monthsArray_pd, monthCounts_pd) {
240201

241202
if (_period === "month" || _period === "day" || _period === "yesterday" || _period === "hour") {
@@ -306,9 +267,9 @@ function getUniqCheckArray(weeksArray_pd, weekCounts_pd, monthsArray_pd, monthCo
306267
}
307268

308269
/** Function to clone object
309-
* @param {object} obj - object to clone
310-
* @returns {object} cloned object
311-
*/
270+
* @param {object} obj - object to clone
271+
* @returns {object|undefined|string|Array<string>|Date} cloned object
272+
*/
312273
function clone(obj) {
313274
if (null === obj || "object" !== typeof obj) {
314275
return obj;
@@ -342,8 +303,8 @@ function clone(obj) {
342303

343304
/**
344305
* Returns number for timestamp making sure it is 13 digits
345-
* @param {integer}ts - number we need to se as timestamp
346-
* @returns {integer} timestamp in ms
306+
* @param {number} ts - number we need to se as timestamp
307+
* @returns {number} timestamp in ms
347308
**/
348309
function fixTimestampToMilliseconds(ts) {
349310
if ((ts + "").length > 13) {
@@ -355,7 +316,7 @@ function fixTimestampToMilliseconds(ts) {
355316

356317
/**
357318
* Returns a period object used by all time related data calculation functions
358-
* @param {moment} prmPeriod period to be calculated (optional)
319+
* @param {string|any} prmPeriod period to be calculated (optional) todo:figure this type out
359320
* @param {string} bucket - daily or monthly. If bucket is set, period will be modified to fit full months or days
360321
* @returns {timeObject} time object
361322
**/

api/parts/data/batcher.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,7 @@ class ReadBatcher {
422422
* @param {string} id - id of cache
423423
* @param {string} query - query for the document
424424
* @param {string} projection - which fields to return
425-
* @param {bool} multi - true if multiple documents
425+
* @param {boolean} multi - true if multiple documents
426426
* @returns {Promise} promise
427427
*/
428428
getData(collection, id, query, projection, multi) {
@@ -517,7 +517,7 @@ class ReadBatcher {
517517
* @param {string} collection - name of the collection where to update data
518518
* @param {object} query - query for the document
519519
* @param {object} projection - which fields to return
520-
* @param {bool} multi - true if multiple documents
520+
* @param {boolean} multi - true if multiple documents
521521
*/
522522
invalidate(collection, query, projection, multi) {
523523
if (!this.onMaster || cluster.isMaster) {
@@ -539,7 +539,7 @@ class ReadBatcher {
539539
* @param {string} collection - name of the collection where to update data
540540
* @param {object} query - query for the document
541541
* @param {object} projection - which fields to return
542-
* @param {bool} multi - true if multiple documents
542+
* @param {boolean} multi - true if multiple documents
543543
* @returns {Promise} promise
544544
*/
545545
get(collection, query, projection, multi) {
@@ -651,7 +651,7 @@ class ReadBatcher {
651651
* @param {string} query - query for the document
652652
* @param {string} projection - which fields to return
653653
* @param {object} data - data from database
654-
* @param {bool} multi - true if multiple documents
654+
* @param {boolean} multi - true if multiple documents
655655
*/
656656
cache(collection, id, query, projection, data, multi) {
657657
if (this.process) {

api/parts/data/usage.js

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,7 @@ usage.returnAllProcessedMetrics = function(params) {
398398
continue;
399399
}
400400

401-
if (recvMetricValue) {
401+
if (recvMetricValue !== undefined && recvMetricValue !== null) {
402402
var escapedMetricVal = (recvMetricValue + "").replace(/^\$/, "").replace(/\./g, ":");
403403
processedMetrics[tmpMetric.short_code] = escapedMetricVal;
404404
}
@@ -705,7 +705,7 @@ function processMetrics(user, uniqueLevelsZero, uniqueLevelsMonth, params, done)
705705
continue;
706706
}
707707

708-
if (recvMetricValue) {
708+
if (recvMetricValue !== undefined && recvMetricValue !== null) {
709709
recvMetricValue = (recvMetricValue + "").replace(/^\$/, "").replace(/\./g, ":");
710710
postfix = common.crypto.createHash("md5").update(recvMetricValue).digest('base64')[0];
711711
metaToFetch[predefinedMetrics[i].db + params.app_id + "_" + dateIds.zero + "_" + postfix] = {
@@ -767,7 +767,7 @@ function processMetrics(user, uniqueLevelsZero, uniqueLevelsMonth, params, done)
767767
continue;
768768
}
769769

770-
if (recvMetricValue) {
770+
if (recvMetricValue !== undefined && recvMetricValue !== null) {
771771
escapedMetricVal = (recvMetricValue + "").replace(/^\$/, "").replace(/\./g, ":");
772772
postfix = common.crypto.createHash("md5").update(escapedMetricVal).digest('base64')[0];
773773

@@ -1110,6 +1110,15 @@ plugins.register("/sdk/user_properties", async function(ob) {
11101110
userProps[key] = up[key];
11111111
}
11121112
}
1113+
1114+
if (params.qstring.metrics._app_version) {
1115+
const versionComponents = common.parseAppVersion(params.qstring.metrics._app_version);
1116+
if (versionComponents.success) {
1117+
userProps.av_major = versionComponents.major;
1118+
userProps.av_minor = versionComponents.minor;
1119+
userProps.av_patch = versionComponents.patch;
1120+
}
1121+
}
11131122
}
11141123

11151124
if (params.qstring.session_duration) {

api/utils/authorizer.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,13 @@ const log = require('./log.js')('core:authorizer');
1515
* @param {object} options - options for the task
1616
* @param {object} options.db - database connection
1717
* @param {number} options.ttl - amount of seconds for token to work, 0 works indefinately
18-
* @param {bool} [options.multi=false] - if true, can be used many times until expired
18+
* @param {boolean} [options.multi=false] - if true, can be used many times until expired
1919
* @param {string} options.token - token to store, if not provided, will be generated
2020
* @param {string} options.owner - id of the user who created this token
2121
* @param {string} options.app - list of the apps for which token was created
2222
* @param {string} options.endpoint - regexp of endpoint(any string - is used as substring,to mach exact ^{yourpath}$)
2323
* @param {string} options.tryReuse - if true - tries to find not expired token with same parameters. If not founds cretes new token. If found - updates token expiration time to new one and returns token.
24-
* @param {bool} [options.temporary=false] - If logged in with temporary token. Doesn't kill other sessions on logout.
24+
* @param {boolean} [options.temporary=false] - If logged in with temporary token. Doesn't kill other sessions on logout.
2525
* @param {function} options.callback - function called when saving was completed or errored, providing error object as first param and token string as second
2626
*/
2727
authorizer.save = function(options) {

0 commit comments

Comments
 (0)