Skip to content

Commit ab0f31c

Browse files
authored
Merge branch 'master' into dependabot/npm_and_yarn/bin/scripts/device_list/csvtojson-2.0.13
2 parents 1059cd9 + 21a2823 commit ab0f31c

File tree

11 files changed

+163
-38
lines changed

11 files changed

+163
-38
lines changed

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
## Version 25.03.25
2+
Fixes:
3+
- [crashes] Fixed resolving audit log recording
4+
- [location] Fixed updating none gps coordinate location after gps location was used
5+
-
6+
Enterprise Fixes:
7+
- [ab-testing] Add script for fixing variant cohort
8+
- [groups] Fix user permission update after updating user group permission
9+
10+
111
## Version 25.03.24
212
Fixes:
313
- [jobs] Fix condition for scheduling alert job

api/parts/data/usage.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1030,7 +1030,7 @@ plugins.register("/sdk/user_properties", async function(ob) {
10301030

10311031
if (plugins.getConfig('api', params.app && params.app.plugins, true).city_data === true && !userProps.loc && typeof data.lat !== "undefined" && typeof data.lon !== "undefined") {
10321032
// only override lat/lon if no recent gps location exists in user document
1033-
if (!params.app_user.loc || (params.app_user.loc.gps && params.time.mstimestamp - params.app_user.loc.date > 7 * 24 * 3600)) {
1033+
if (!params.app_user.loc || !params.app_user.loc.gps || params.time.mstimestamp - params.app_user.loc.date > 7 * 24 * 3600) {
10341034
userProps.loc = {
10351035
gps: false,
10361036
geo: {
@@ -1061,7 +1061,7 @@ plugins.register("/sdk/user_properties", async function(ob) {
10611061

10621062
if (plugins.getConfig('api', params.app && params.app.plugins, true).city_data === true && !userProps.loc && data.ll && typeof data.ll[0] !== "undefined" && typeof data.ll[1] !== "undefined") {
10631063
// only override lat/lon if no recent gps location exists in user document
1064-
if (!params.app_user.loc || (params.app_user.loc.gps && params.time.mstimestamp - params.app_user.loc.date > 7 * 24 * 3600)) {
1064+
if (!params.app_user.loc || !params.app_user.loc.gps || params.time.mstimestamp - params.app_user.loc.date > 7 * 24 * 3600) {
10651065
userProps.loc = {
10661066
gps: false,
10671067
geo: {
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/*
2+
* Sends recalculate request for all ab testing experiment variant cohorts
3+
* Server: countly
4+
* Path: $(countly dir)/bin/scripts/fix-data
5+
* Command: node recalculate_ab_test_cohorts.js
6+
*/
7+
8+
// API key here with permission to update cohorts
9+
const API_KEY = '';
10+
// Countly app id, if not specified will do nothing
11+
const APP_ID = '';
12+
// ab test experiment id, will do nothing if not specified
13+
const EXPERIMENT_ID = '';
14+
// countly instance public url, something like 'https://name.count.ly'
15+
const SERVER_URL = '';
16+
17+
const pluginManager = require('../../../plugins/pluginManager.js');
18+
const request = require('countly-request')(pluginManager.getConfig('security'));
19+
20+
if (API_KEY.length === 0) {
21+
console.warn('Please provide an API_KEY');
22+
process.exit(1);
23+
}
24+
25+
pluginManager.dbConnection('countly_out').then(async(db) => {
26+
let urlObj = {};
27+
try {
28+
urlObj = new URL(SERVER_URL);
29+
}
30+
catch (err) {
31+
urlObj = new URL((process.env.COUNTLY_CONFIG_PROTOCOL || "http") + "://" + (process.env.COUNTLY_CONFIG_HOSTNAME || "localhost"));
32+
}
33+
urlObj.pathname = 'i/cohorts/recalculate';
34+
urlObj.searchParams.append('api_key', API_KEY);
35+
urlObj.searchParams.append('app_id', APP_ID);
36+
37+
console.log(`Finding ab test experiment ${EXPERIMENT_ID} in app ${APP_ID}`);
38+
39+
const experimentCollectionName = `ab_testing_experiments${APP_ID}`;
40+
const experiment = await db.collection(experimentCollectionName).findOne({ _id: db.ObjectID(EXPERIMENT_ID) });
41+
42+
if (experiment?.variants?.length > 0) {
43+
for (let varIdx = 0; varIdx < experiment.variants.length; varIdx += 1) {
44+
const variant = experiment.variants[varIdx];
45+
46+
if (variant?.cohorts && Object.keys(variant.cohorts).length > 0) {
47+
for (let cohIdx = 0; cohIdx < Object.keys(variant.cohorts).length; cohIdx += 1) {
48+
const cohortId = variant.cohorts[Object.keys(variant.cohorts)[cohIdx]];
49+
console.log(`Sending recalculate request for variant ${variant.name}, cohort ${cohortId}`);
50+
51+
urlObj.searchParams.delete('cohort_id');
52+
urlObj.searchParams.append('cohort_id', cohortId);
53+
54+
await new Promise((resolve) => {
55+
request.get(urlObj.href, (err, _, body) => {
56+
if (err) {
57+
console.warn('Request failed ', JSON.stringify(cohortId), err);
58+
}
59+
else {
60+
console.log('Request finished ', JSON.stringify(cohortId), body);
61+
}
62+
resolve();
63+
});
64+
});
65+
}
66+
}
67+
}
68+
}
69+
else {
70+
console.warn(`Experiments ${EXPERIMENT_ID} not found in app ${APP_ID}`);
71+
}
72+
73+
db.close();
74+
});

frontend/express/public/core/user-management/javascripts/countly.views.js

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -866,6 +866,7 @@
866866
}
867867
},
868868
onOpen: function() {
869+
this.patchUserPermission();
869870
this.changePasswordFlag = false;
870871
// types
871872
var types = ['c', 'r', 'u', 'd'];
@@ -879,7 +880,7 @@
879880
// if it's in edit mode
880881
if (this.settings.editMode) {
881882
// is user member of a group?
882-
if (this.user.group_id && countlyGlobal.plugins.indexOf('groups') > -1) {
883+
if (this.user.group_id && this.user.group_id.length && countlyGlobal.plugins.indexOf('groups') > -1) {
883884
// set groups state
884885
if (Array.isArray(this.user.group_id)) {
885886
this.groups = this.user.group_id;
@@ -982,7 +983,31 @@
982983
},
983984
onRoleChange: function(role) {
984985
this.roles[role.name] = role;
985-
}
986+
},
987+
patchUserPermission: function() {
988+
if (this.user && this.user.permission && this.user.permission._ && this.user.permission._.u) {
989+
var appIdReducer = function(acc, curr) {
990+
if (curr.length > 0) {
991+
acc.push(curr);
992+
}
993+
return acc;
994+
};
995+
996+
var _u = this.user.permission._.u.reduce(function(acc, curr) {
997+
if (curr.length > 0) {
998+
var appIds = curr.reduce(appIdReducer, []);
999+
1000+
if (appIds.length > 0) {
1001+
acc.push(appIds);
1002+
}
1003+
}
1004+
return acc;
1005+
}, []);
1006+
1007+
this.user.permission._.u = _u;
1008+
this.$refs.userDrawer.editedObject.permission._.u = _u;
1009+
}
1010+
},
9861011
},
9871012
watch: {
9881013
'groups': function() {

frontend/express/public/javascripts/countly/vue/components/content.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -774,6 +774,8 @@
774774
template: CV.T('/javascripts/countly/vue/templates/content/UI/content-sidebar-input.html')
775775
}));
776776

777+
const DEFAULT_LIST_BLOCK_IMAGE_PLACEHOLDER_URL = '/content/images/fullscreenPlaceholderImage.png';
778+
777779
Vue.component('cly-content-block-list-input', countlyVue.components.create({
778780
props: {
779781
blockInputs: {
@@ -788,6 +790,19 @@
788790
'input'
789791
],
790792

793+
computed: {
794+
mappedBlockInputs() {
795+
return this.blockInputs.map(block => {
796+
return block.map(blockInput => ({
797+
...blockInput,
798+
...(blockInput.id.includes('image') && !blockInput.value) && {
799+
value: DEFAULT_LIST_BLOCK_IMAGE_PLACEHOLDER_URL
800+
}
801+
}));
802+
});
803+
}
804+
},
805+
791806
methods: {
792807
onAddAsset(payload) {
793808
this.$emit('add-asset', payload);

frontend/express/public/javascripts/countly/vue/templates/UI/color-picker.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
<el-input
6363
v-model="hexColor"
6464
class="cly-vue-color-picker__color-input cly-vue-color-picker__color-input--hex"
65+
:test-id="testId + '-hex-input'"
6566
>
6667
<template #prepend>
6768
<span>#</span>

frontend/express/public/javascripts/countly/vue/templates/content/UI/content-block-list-input.html

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
<div class="cly-content-block-list-input">
2-
<!-- v-tooltip.right="step.componentTooltip" -->
32
<el-collapse
4-
v-for="(block, blockIndex) in blockInputs"
3+
v-for="(block, blockIndex) in mappedBlockInputs"
54
:key="`list-block-${blockIndex}`"
65
class="cly-content-block-list-input__list-block"
76
>
@@ -12,7 +11,7 @@
1211
<img
1312
class="cly-content-block-list-input__list-block-header-display-icon"
1413
:data-test-id="'fullscreen-blocks-icon-block-' + blockIndex"
15-
:src="block[0].value || '/content/images/fullscreenPlaceholderImage.png'"
14+
:src="block[0].value"
1615
>
1716
<p
1817
class="cly-content-block-list-input__list-block-header-display-title"

package-lock.json

Lines changed: 29 additions & 29 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@
8787
"moment-timezone": "0.6.0",
8888
"mongodb": "6.20.0",
8989
"nginx-conf": "2.1.0",
90-
"nodemailer": "7.0.9",
90+
"nodemailer": "7.0.10",
9191
"object-hash": "3.0.0",
9292
"offline-geocoder": "git+https://github.com/Countly/offline-geocoder.git",
9393
"properties-parser": "0.6.0",

plugins/crashes/api/api.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1487,7 +1487,7 @@ plugins.setConfigs("crashes", {
14871487
var crashes = params.qstring.args.crashes || [params.qstring.args.crash_id];
14881488
common.db.collection('app_crashgroups' + params.qstring.app_id).update({'_id': {$in: crashes} }, {"$set": {is_resolving: true}}, {multi: true}, function() {
14891489
for (var i = 0; i < crashes.length; i++) {
1490-
plugins.dispatch("/systemlogs", {params: params, action: "crash_shown", data: {app_id: params.qstring.app_id, crash_id: params.qstring.args.crash_id}});
1490+
plugins.dispatch("/systemlogs", {params: params, action: "crash_resolving", data: {app_id: params.qstring.app_id, crash_id: params.qstring.args.crash_id}});
14911491
}
14921492
common.returnMessage(params, 200, 'Success');
14931493
return true;

0 commit comments

Comments
 (0)