Skip to content

Commit 499e87c

Browse files
authored
Merge branch 'next' into SER-683
2 parents d0c79c2 + b551e81 commit 499e87c

File tree

145 files changed

+5840
-3847
lines changed

Some content is hidden

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

145 files changed

+5840
-3847
lines changed

CHANGELOG.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,26 @@
1+
## Version 24.05.13
2+
Fixes:
3+
- [alerts] Fixed bugs related to NPS alerts
4+
- [crash] Reworked symbol files upload to support larger symbol files
5+
- [push] Fixed bug that would surface when sending Array or Object related payload
6+
7+
Enterprise fixes:
8+
- [ab-testing] Slight improvements to the UI and UX
9+
- [remote-config] Slight improvements to the UI and UX
10+
11+
Enterprise Features:
12+
- [ab-testing] Improved UI for selecting AB test expiration
13+
14+
## Version 24.05.12
15+
Fixes:
16+
- [dashboards] Fixes for dashboards grid
17+
- [dasboards] UI fix for dashboard widget action menu
18+
- [push] Refactored fcm API related code
19+
- [reports] Use config for encryption key in reports
20+
21+
Enterprise fixes:
22+
- [retention] Fixes for byval retention query calculation
23+
124
## Version 24.05.11
225
Fixes:
326
- [cache] Use a cursor without timeout

api/api.js

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -370,10 +370,18 @@ plugins.connectToAllDatabases().then(function() {
370370
}
371371

372372
const form = new formidable.IncomingForm(formidableOptions);
373-
req.body = '';
374-
req.on('data', (data) => {
375-
req.body += data;
376-
});
373+
if (/crash_symbols\/(add_symbol|upload_symbol)/.test(req.url)) {
374+
req.body = [];
375+
req.on('data', (data) => {
376+
req.body.push(data);
377+
});
378+
}
379+
else {
380+
req.body = '';
381+
req.on('data', (data) => {
382+
req.body += data;
383+
});
384+
}
377385

378386
let multiFormData = false;
379387
// Check if we have 'multipart/form-data'
@@ -432,4 +440,4 @@ plugins.connectToAllDatabases().then(function() {
432440

433441
plugins.loadConfigs(common.db);
434442
}
435-
});
443+
});

api/config.sample.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ var countlyConfig = {
9999
* @property {string} algorithm - name of the algorithm to use for encryption. The algorithm is dependent on OpenSSL, examples are 'aes192', etc. On recent OpenSSL releases, openssl list-cipher-algorithms will display the available cipher algorithms. Default value is aes-256-cbc
100100
* @property {string} input_encoding - how encryption input is encoded. Used as output for decrypting. Default utf-8.
101101
* @property {string} output_encoding - how encryption output is encoded. Used as input for decrypting. Default hex.
102+
* @property {string} reports_key - key used for encryption of reports links
102103
*/
103104
encryption: {},
104105

api/lib/countly.common.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1533,9 +1533,6 @@ countlyCommon.extractTwoLevelData = function(db, rangeArray, clearFunction, data
15331533
periodObj = countlyCommon.periodObj;
15341534
}
15351535

1536-
if (!rangeArray) {
1537-
return {"chartData": tableData};
1538-
}
15391536
var periodMin = 0,
15401537
periodMax = 0,
15411538
dataObj = {},
@@ -1544,6 +1541,10 @@ countlyCommon.extractTwoLevelData = function(db, rangeArray, clearFunction, data
15441541
propertyFunctions = underscore.pluck(dataProperties, "func"),
15451542
propertyValue = 0;
15461543

1544+
if (!rangeArray) {
1545+
return {"chartData": tableData};
1546+
}
1547+
15471548
if (!periodObj.isSpecialPeriod) {
15481549
periodMin = periodObj.periodMin;
15491550
periodMax = (periodObj.periodMax + 1);

api/parts/data/batcher.js

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ class WriteBatcher {
232232
updateOne: {
233233
filter: {_id: this.data[db][collection][key].id},
234234
update: this.data[db][collection][key].value,
235-
upsert: true
235+
upsert: this.data[db][collection][key].upsert
236236
}
237237
});
238238
}
@@ -340,18 +340,25 @@ class WriteBatcher {
340340
* @param {string} id - id of the document
341341
* @param {object} operation - operation
342342
* @param {string} db - name of the database for which to write data
343+
* @param {object=} options - options for operation ((upsert: false) - if you don't want to upsert document)
343344
*/
344-
add(collection, id, operation, db = "countly") {
345+
add(collection, id, operation, db = "countly", options) {
345346
if (!this.shared || cluster.isMaster) {
346347
if (!this.data[db][collection]) {
347348
this.data[db][collection] = {};
348349
}
349350
if (!this.data[db][collection][id]) {
350-
this.data[db][collection][id] = {id: id, value: operation};
351+
this.data[db][collection][id] = {id: id, value: operation, upsert: true};
352+
if (options && options.upsert === false) {
353+
this.data[db][collection][id].upsert = false;
354+
}
351355
batcherStats.update_queued++;
352356
}
353357
else {
354358
this.data[db][collection][id].value = common.mergeQuery(this.data[db][collection][id].value, operation);
359+
if (options && options.upsert === false) {
360+
this.data[db][collection][id].upsert = this.data[db][collection][id].upsert || false;
361+
}
355362
}
356363
if (!this.process) {
357364
this.flush(db, collection);

api/parts/data/cache.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -971,7 +971,7 @@ class StreamedCollection {
971971
let [col, last] = await createCollection(this.db, this.name, 1e7);
972972

973973
this.col = col;
974-
this.stream = col.find({_id: {$gt: last}}, {tailable: true, awaitData: true, noCursorTimeout: true, numberOfRetries: -1}).stream();
974+
this.stream = col.find({_id: {$gt: last}}, {tailable: true, awaitData: true, numberOfRetries: -1}).stream();
975975

976976
this.stream.on('data', doc => {
977977
if (this.inserts.indexOf(doc._id.toString()) !== -1) {

api/parts/data/fetch.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1614,7 +1614,7 @@ function fetchTimeObj(collection, params, isCustomEvent, options, callback) {
16141614
options = {};
16151615
}
16161616

1617-
if (typeof options === "undefined") {
1617+
if (!options) {
16181618
options = {};
16191619
}
16201620

@@ -1704,7 +1704,7 @@ function fetchTimeObj(collection, params, isCustomEvent, options, callback) {
17041704

17051705
var zeroDocs = [zeroIdToFetch];
17061706
var monthDocs = [monthIdToFetch];
1707-
if (!(options && options.dontBreak)) {
1707+
if (!options.dontBreak) {
17081708
for (let i = 0; i < common.base64.length; i++) {
17091709
zeroDocs.push(zeroIdToFetch + "_" + common.base64[i]);
17101710
monthDocs.push(monthIdToFetch + "_" + common.base64[i]);

api/parts/jobs/job.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1068,9 +1068,16 @@ class IPCFaçadeJob extends ResourcefulJob {
10681068
this.ipcChannel.remove();
10691069
}, (error) => {
10701070
this.ipcChannel.remove();
1071-
log.e('[%s] Error in IPCFaçadeJob %s: %j / %j', this.job.channel, this.resourceFaçade._id, error, error.stack);
1071+
if (error) {
1072+
log.e('[%s] Error in IPCFaçadeJob %s: %j / %j', this.job.channel, this.resourceFaçade._id, error, error.stack);
1073+
}
1074+
else {
1075+
log.e('[%s] Error in IPCFaçadeJob %s: Unknown error', this.job.channel, this.resourceFaçade._id);
1076+
}
10721077
this.job._finish(error || 'Aborted').catch(()=>{});
1073-
throw error;
1078+
if (error) {
1079+
throw error;
1080+
}
10741081
});
10751082
}
10761083

api/parts/mgmt/apps.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -613,6 +613,7 @@ appsApi.updateAppPlugins = function(params) {
613613
* @returns {boolean} true if operation successful
614614
**/
615615
appsApi.deleteApp = function(params) {
616+
params = params || {};
616617
var argProps = {
617618
'app_id': {
618619
'required': true,

api/parts/mgmt/cms.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,10 +157,21 @@ function syncCMSDataToDB(params) {
157157
}
158158

159159
cmsApi.saveEntries = function(params) {
160+
161+
var entries = [];
162+
try {
163+
entries = JSON.parse(params.qstring.entries);
164+
}
165+
catch (ex) {
166+
log.e(params.qstring.entries);
167+
common.returnMessage(params, 400, 'Invalid entries parameter');
168+
return;
169+
}
170+
160171
transformAndStoreData(
161172
Object.assign({dataTransformed: true}, params),
162173
null,
163-
JSON.parse(params.qstring.entries),
174+
entries,
164175
function(err1) {
165176
if (err1) {
166177
log.e('An error occured while storing entries in DB: ' + err1);

0 commit comments

Comments
 (0)