Skip to content

Commit cb52a01

Browse files
committed
Merge branch 'master' into next
# Conflicts: # api/parts/mgmt/apps.js # api/utils/render.js # frontend/express/app.js # plugins/reports/frontend/public/javascripts/countly.models.js
2 parents d20bfd3 + ed9b62c commit cb52a01

File tree

55 files changed

+621
-482
lines changed

Some content is hidden

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

55 files changed

+621
-482
lines changed

LICENSE

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
Countly Mobile & Web Analytics Community Edition License
1+
Countly Product Analytics - Community Edition License
22
--------------------------------------------------
33

4-
Copyright (C) 2011-2017 Countly, www.count.ly
4+
Copyright (C) 2011-2018 Countly, https://count.ly
55

66
Countly is provided under AGPL v3 with modified Section 7. In accordance
77
with Section 7 of the AGPL, the Works included in this package or repository
@@ -18,4 +18,4 @@ Countly name and logo from Countly software.
1818

1919
For more information, see Licensing FAQ:
2020

21-
http://resources.count.ly/docs/licencing-faq
21+
https://resources.count.ly/docs/licencing-faq

api/parts/mgmt/apps.js

+2-3
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ var appsApi = {},
1010
moment = require('moment-timezone'),
1111
crypto = require('crypto'),
1212
plugins = require('../../../plugins/pluginManager.js'),
13-
fs = require('fs'),
1413
jimp = require('jimp'),
1514
countlyFs = require('./../../utils/countlyFs.js');
1615

@@ -565,8 +564,8 @@ appsApi.deleteApp = function(params) {
565564
return false;
566565
}
567566

568-
var iconPath = __dirname + '/public/appimages/' + appId + '.png';
569-
fs.unlink(iconPath, function() {});
567+
var iconPath = __dirname + '/../../../frontend/express/public/appimages/' + appId + '.png';
568+
countlyFs.deleteFile("appimages", iconPath, {id: appId + ".png"}, function() {});
570569

571570
common.db.collection('members').update({}, {
572571
$pull: {

api/utils/render.js

+17-13
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ var alternateChrome = true;
1111
var chromePath = "";
1212
var countlyFs = require('./countlyFs');
1313
var log = require('./log.js')('core:render');
14+
var countlyConfig = require('./../config', 'dont-enclose');
15+
1416

1517
/**
1618
* Function to render views as images
@@ -47,24 +49,26 @@ exports.renderView = function(options, cb) {
4749
chromePath = yield fetchChromeExecutablePath();
4850
}
4951

50-
var browser = "";
52+
var settings = {
53+
headless: true,
54+
args: ['--no-sandbox', '--disable-setuid-sandbox'],
55+
ignoreHTTPSErrors: true
56+
};
57+
5158
if (chromePath) {
52-
browser = yield puppeteer.launch({
53-
headless: true,
54-
args: ['--no-sandbox', '--disable-setuid-sandbox'],
55-
executablePath: chromePath
56-
});
57-
}
58-
else {
59-
browser = yield puppeteer.launch({
60-
headless: true,
61-
args: ['--no-sandbox', '--disable-setuid-sandbox']
62-
});
59+
settings.executablePath = chromePath;
6360
}
6461

62+
var browser = yield puppeteer.launch(settings);
63+
6564
var page = yield browser.newPage();
6665

67-
var host = options.host;
66+
var host = "http://127.0.0.1" + countlyConfig.path;
67+
68+
if (options.host) {
69+
host = options.host + countlyConfig.path;
70+
}
71+
6872
var token = options.token;
6973
var view = options.view;
7074
var id = options.id;

bin/installer.sh

100644100755
+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ else
2727
else
2828
echo "Downloading from CDN..."
2929
PACKAGE_NAME=$(awk -F/ '{print $9}' <<< $LATEST)
30-
CDN_HOST=http://om65qc2mm.bkt.clouddn.com/
30+
CDN_HOST=http://countly-1252600587.cos.ap-guangzhou.myqcloud.com/
3131
if [[ "$LATEST" == *zip ]]
3232
then
3333
wget -nv $CDN_HOST$PACKAGE_NAME -O ./countly.zip ;

bin/scripts/mongodb.install.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ if [ -f /etc/lsb-release ]; then
4545
fi
4646
apt-get update
4747
#install mongodb
48-
apt-get -y install mongodb-org || (echo "Failed to install mongodb." ; exit)
48+
DEBIAN_FRONTEND="noninteractive" apt-get -y install mongodb-org || (echo "Failed to install mongodb." ; exit)
4949

5050
#disable transparent-hugepages (requires reboot)
5151
cp -f $DIR/disable-transparent-hugepages /etc/init.d/disable-transparent-hugepages

frontend/express/app.js

+46-38
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ var versionInfo = require('./version.info'),
3232
plugins = require('../../plugins/pluginManager.js'),
3333
countlyConfig = require('./config', 'dont-enclose'),
3434
log = require('../../api/utils/log.js')('core:app'),
35-
ip = require('../../api/parts/mgmt/ip.js'),
3635
url = require('url'),
3736
authorize = require('../../api/utils/authorizer.js'), //for token validations
3837
render = require('../../api/utils/render.js'),
@@ -365,6 +364,11 @@ app.use('/fonts/', function(req, res, next) {
365364
next();
366365
});
367366

367+
app.use('*.svg', function(req, res, next) {
368+
res.setHeader('Content-Type', 'image/svg+xml; charset=UTF-8');
369+
next();
370+
});
371+
368372
/**
369373
* Add headers to request
370374
* @param {object} req - request object
@@ -443,7 +447,6 @@ app.get(countlyConfig.path + '/appimages/*', function(req, res) {
443447
'Connection': 'keep-alive',
444448
'Date': new Date().toUTCString(),
445449
'Last-Modified': stats.mtime.toUTCString(),
446-
'Server': 'nginx/1.10.3 (Ubuntu)',
447450
'Content-Type': 'image/png',
448451
'Content-Length': stats.size
449452
});
@@ -536,8 +539,9 @@ app.use(function(req, res, next) {
536539
plugins.loadConfigs(countlyDb, function() {
537540
app.dashboard_headers = plugins.getConfig("security").dashboard_additional_headers;
538541
add_headers(req, res);
539-
bruteforce.fails = plugins.getConfig("security").login_tries || 3;
540-
bruteforce.wait = plugins.getConfig("security").login_wait || 5 * 60;
542+
const {login_tries, login_wait} = plugins.getConfig("security");
543+
bruteforce.fails = Number.isInteger(login_tries) ? login_tries : 3;
544+
bruteforce.wait = login_wait || 5 * 60;
541545

542546
curTheme = plugins.getConfig("frontend", req.session && req.session.settings).theme;
543547
app.loadThemeFiles(req.cookies.theme || plugins.getConfig("frontend", req.session && req.session.settings).theme, function(themeFiles) {
@@ -637,8 +641,8 @@ var checkRequestForSession = function(req, res, next) {
637641
if (parseInt(plugins.getConfig("frontend", req.session && req.session.settings).session_timeout)) {
638642
if (req.session.uid) {
639643
if (Date.now() > req.session.expires) {
640-
//logout user
641-
res.redirect(countlyConfig.path + '/logout?message=logout.inactivity');
644+
clearSession(req, res, next);
645+
res.redirect(countlyConfig.path + '/login?message=logout.inactivity');
642646
}
643647
else {
644648
//extend session
@@ -695,8 +699,13 @@ app.get(countlyConfig.path + '/session', function(req, res, next) {
695699
app.get(countlyConfig.path + '/dashboard', checkRequestForSession);
696700
app.post('*', checkRequestForSession);
697701

698-
699-
app.get(countlyConfig.path + '/logout', function(req, res, next) {
702+
/**
703+
* clear session info for request
704+
* @param {object} req - request object
705+
* @param {object} res - response object
706+
* @param {function} next - callback for next middleware
707+
**/
708+
function clearSession(req, res, next) {
700709
if (req.session) {
701710
if (req.session.uid && req.session.email) {
702711
plugins.callMethod("userLogout", {req: req, res: res, next: next, data: {uid: req.session.uid, email: req.session.email, query: req.query}});
@@ -712,9 +721,12 @@ app.get(countlyConfig.path + '/logout', function(req, res, next) {
712721
req.session.settings = null;
713722
res.clearCookie('uid');
714723
res.clearCookie('gadm');
715-
req.session.destroy(function() {
716-
});
724+
req.session.destroy(function() {});
717725
}
726+
}
727+
728+
app.post(countlyConfig.path + '/logout', function(req, res, next) {
729+
clearSession(req, res, next);
718730
if (req.query.message) {
719731
res.redirect(countlyConfig.path + '/login?message=' + req.query.message);
720732
}
@@ -1538,10 +1550,15 @@ app.post(countlyConfig.path + '/user/settings', function(req, res, next) {
15381550
}
15391551
var change = JSON.parse(JSON.stringify(updatedUser));
15401552
countlyDb.collection('members').findOne({"_id": countlyDb.ObjectID(req.session.uid)}, function(err, member) {
1541-
countlyDb.collection('members').findOne({username: req.body.username}, async function(err2, user) {
1553+
if (err || !member) {
1554+
return res.send(false);
1555+
}
1556+
countlyDb.collection('members').findOne({username: req.body.username}, function(err2, user) {
1557+
if (err) {
1558+
return res.send(false);
1559+
}
15421560
member.change = change;
1543-
1544-
if ((user && user._id.toString() !== req.session.uid) || err2) {
1561+
if ((user && user._id + "" !== req.session.uid + "") || err2) {
15451562
res.send("username-exists");
15461563
}
15471564
else {
@@ -1799,35 +1816,26 @@ app.get(countlyConfig.path + '/render', function(req, res) {
17991816
options.savePath = path.resolve(__dirname, "./public/images/screenshots/" + imageName);
18001817
options.source = "core";
18011818

1802-
ip.getHost(function(err, host) {
1803-
if (err) {
1804-
console.log(err);
1805-
return res.send(false);
1806-
}
1807-
1808-
options.host = host;
1819+
authorize.save({
1820+
db: countlyDb,
1821+
multi: false,
1822+
owner: req.session.uid,
1823+
purpose: "LoginAuthToken",
1824+
callback: function(err2, token) {
1825+
if (err2) {
1826+
console.log(err2);
1827+
return res.send(false);
1828+
}
18091829

1810-
authorize.save({
1811-
db: countlyDb,
1812-
multi: false,
1813-
owner: req.session.uid,
1814-
purpose: "LoginAuthToken",
1815-
callback: function(err2, token) {
1816-
if (err2) {
1817-
console.log(err2);
1830+
options.token = token;
1831+
render.renderView(options, function(err3) {
1832+
if (err3) {
18181833
return res.send(false);
18191834
}
18201835

1821-
options.token = token;
1822-
render.renderView(options, function(err3) {
1823-
if (err3) {
1824-
return res.send(false);
1825-
}
1826-
1827-
return res.send(true);
1828-
});
1829-
}
1830-
});
1836+
return res.send(true);
1837+
});
1838+
}
18311839
});
18321840
});
18331841

frontend/express/public/javascripts/countly/countly.common.js

+17-5
Original file line numberDiff line numberDiff line change
@@ -3690,11 +3690,23 @@
36903690
* @returns {string} return format "HH:MM:SS"
36913691
*/
36923692
countlyCommon.formatSecond = function(second) {
3693-
var s = parseInt(second);
3694-
var m = moment();
3695-
m.set({hour: 0, minute: 0, second: 0, millisecond: 0});
3696-
m.add(s, 's');
3697-
return m.format("HH:mm:ss");
3693+
var timeLeft = parseInt(second);
3694+
var dict = [
3695+
{k: 'day', v: 86400},
3696+
{k: 'hour', v: 3600},
3697+
{k: 'minute', v: 60},
3698+
{k: 'second', v: 1}
3699+
];
3700+
var result = {day: 0, hour: 0, minute: 0, second: 0};
3701+
for (var i = 0; i < dict.length; i++) {
3702+
result[dict[i].k] = Math.floor(timeLeft / dict[i].v);
3703+
timeLeft = timeLeft % dict[i].v;
3704+
}
3705+
var dayTrans = result.day > 1 ? jQuery.i18n.map["common.day.abrv"] : jQuery.i18n.map["common.day.abrv2"];
3706+
return (result.day > 0 ? result.day + " " + dayTrans + ',' : '') +
3707+
(result.hour >= 10 ? result.hour + ':' : ('0' + result.hour) + ":") +
3708+
(result.minute >= 10 ? result.minute + ':' : ('0' + result.minute) + ':') +
3709+
(result.second >= 10 ? result.second : ('0' + result.second));
36983710
};
36993711

37003712
/**

frontend/express/public/javascripts/countly/countly.event.js

+7-14
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/*global countlyCommon, countlyGlobal, _, jQuery*/
1+
/*global countlyCommon, _, jQuery*/
22
(function(countlyEvent, $, undefined) {
33

44
//Private Properties
@@ -44,13 +44,12 @@
4444
type: "GET",
4545
url: countlyCommon.API_PARTS.data.r,
4646
data: {
47-
"api_key": countlyGlobal.member.api_key,
4847
"app_id": countlyCommon.ACTIVE_APP_ID,
4948
"method": "get_events",
5049
"period": _period,
5150
"preventRequestAbort": true
5251
},
53-
dataType: "jsonp",
52+
dataType: "json",
5453
success: function(json) {
5554
_activeEvents = json;
5655
if (!_activeEvent && countlyEvent.getEvents()[0]) {
@@ -65,15 +64,14 @@
6564
type: "GET",
6665
url: countlyCommon.API_PARTS.data.r,
6766
data: {
68-
"api_key": countlyGlobal.member.api_key,
6967
"app_id": countlyCommon.ACTIVE_APP_ID,
7068
"method": "events",
7169
"event": _activeEvent,
7270
"segmentation": currentActiveSegmentation,
7371
"period": _period,
7472
"preventRequestAbort": true
7573
},
76-
dataType: "jsonp",
74+
dataType: "json",
7775
success: function(json) {
7876
if (currentActiveEvent === _activeEvent && currentActiveSegmentation === _activeSegmentation) {
7977
_activeLoadedEvent = _activeEvent;
@@ -120,7 +118,6 @@
120118
url: countlyCommon.API_PARTS.data.r,
121119
data: {
122120
"app_id": countlyCommon.ACTIVE_APP_ID,
123-
"api_key": countlyGlobal.member.api_key,
124121
"method": "events",
125122
"events": JSON.stringify(my_events),
126123
"period": countlyCommon.getPeriod(),
@@ -235,11 +232,10 @@
235232
type: "GET",
236233
url: countlyCommon.API_PARTS.data.r,
237234
data: {
238-
"api_key": countlyGlobal.member.api_key,
239235
"app_id": countlyCommon.ACTIVE_APP_ID,
240236
"method": "get_events"
241237
},
242-
dataType: "jsonp",
238+
dataType: "json",
243239
success: function(json) {
244240
_activeEvents = json;
245241
if (!_activeEvent && countlyEvent.getEvents()[0]) {
@@ -254,14 +250,13 @@
254250
type: "GET",
255251
url: countlyCommon.API_PARTS.data.r,
256252
data: {
257-
"api_key": countlyGlobal.member.api_key,
258253
"app_id": countlyCommon.ACTIVE_APP_ID,
259254
"method": "events",
260255
"action": "refresh",
261256
"event": _activeEvent,
262257
"segmentation": currentActiveSegmentation
263258
},
264-
dataType: "jsonp",
259+
dataType: "json",
265260
success: function(json) {
266261
if (currentActiveEvent === _activeEvent && currentActiveSegmentation === _activeSegmentation) {
267262
_activeLoadedEvent = _activeEvent;
@@ -302,11 +297,10 @@
302297
type: "GET",
303298
url: countlyCommon.API_PARTS.data.r,
304299
data: {
305-
"api_key": countlyGlobal.member.api_key,
306300
"app_id": countlyCommon.ACTIVE_APP_ID,
307301
"method": "get_events"
308302
},
309-
dataType: "jsonp",
303+
dataType: "json",
310304
success: function(json) {
311305
_activeEvents = json;
312306
if (!_activeEvent && countlyEvent.getEvents()[0]) {
@@ -852,12 +846,11 @@
852846
type: "GET",
853847
url: countlyCommon.API_PARTS.data.r,
854848
data: {
855-
"api_key": countlyGlobal.member.api_key,
856849
"app_id": countlyCommon.ACTIVE_APP_ID,
857850
"method": "events",
858851
"events": JSON.stringify(eventKeysArr)
859852
},
860-
dataType: "jsonp",
853+
dataType: "json",
861854
success: function(json) {
862855
callback(extractDataForGraphAndChart(json));
863856
}

0 commit comments

Comments
 (0)