Skip to content

Commit 60664e1

Browse files
authored
Merge branch 'next' into initial-screen
2 parents a1670fa + 413eaa8 commit 60664e1

File tree

75 files changed

+1177
-708
lines changed

Some content is hidden

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

75 files changed

+1177
-708
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

+6-4
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ 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'),
14+
fs = require('fs'),
1515
countlyFs = require('./../../utils/countlyFs.js');
1616

1717
/**
@@ -175,7 +175,9 @@ const iconUpload = function(params) {
175175
}
176176
icon.cover(72, 72).getBuffer(jimp.MIME_PNG, function(err2, buffer) {
177177
countlyFs.saveData("appimages", target_path, buffer, {id: appId + ".png", writeMode: "overwrite"}, function(err3) {
178-
log.e(err3, err3.stack);
178+
if (err3) {
179+
log.e(err3, err3.stack);
180+
}
179181
fs.unlink(tmp_path, function() {});
180182
});
181183
});
@@ -563,8 +565,8 @@ appsApi.deleteApp = function(params) {
563565
return false;
564566
}
565567

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

569571
common.db.collection('members').update({}, {
570572
$pull: {

api/parts/mgmt/users.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -234,9 +234,9 @@ usersApi.createUser = function(params) {
234234
/**
235235
* Creates user document with hashed password
236236
**/
237-
function createUser() {
237+
async function createUser() {
238238
var passwordNoHash = newMember.password;
239-
newMember.password = common.sha512Hash(newMember.password);
239+
newMember.password = await common.argon2Hash(newMember.password);
240240
newMember.password_changed = 0;
241241
newMember.created_at = Math.floor(((new Date()).getTime()) / 1000); //TODO: Check if UTC
242242
newMember.admin_of = newMember.admin_of || [];
@@ -275,7 +275,7 @@ usersApi.createUser = function(params) {
275275
* @param {params} params - params object
276276
* @returns {boolean} true if user was updated
277277
**/
278-
usersApi.updateUser = function(params) {
278+
usersApi.updateUser = async function(params) {
279279
var argProps = {
280280
'user_id': {
281281
'required': true,
@@ -346,7 +346,7 @@ usersApi.updateUser = function(params) {
346346

347347
if (updatedMember.password) {
348348
passwordNoHash = updatedMember.password;
349-
updatedMember.password = common.sha512Hash(updatedMember.password);
349+
updatedMember.password = await common.argon2Hash(updatedMember.password);
350350
if (params.member._id !== params.qstring.args.user_id) {
351351
updatedMember.password_changed = 0;
352352
}

api/utils/common.js

+11-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ var common = {},
1111
logger = require('./log.js'),
1212
mcc_mnc_list = require('mcc-mnc-list'),
1313
plugins = require('../../plugins/pluginManager.js'),
14-
countlyConfig = require('./../config', 'dont-enclose');
14+
countlyConfig = require('./../config', 'dont-enclose'),
15+
argon2 = require('argon2');
1516

1617
var matchHtmlRegExp = /"|'|&(?!amp;|quot;|#39;|lt;|gt;|#46;|#36;)|<|>/;
1718
var matchLessHtmlRegExp = /[<>]/;
@@ -458,6 +459,15 @@ common.sha512Hash = function(str, addSalt) {
458459
return crypto.createHmac('sha512', salt + '').update(str + '').digest('hex');
459460
};
460461

462+
/**
463+
* Create argon2 hash string
464+
* @param {string} str - string to hash
465+
* @returns {promise} hash promise
466+
**/
467+
common.argon2Hash = function(str) {
468+
return argon2.hash(str);
469+
};
470+
461471
/**
462472
* Create MD5 hash from provided value
463473
* @param {string} str - value to hash

api/utils/render.js

+125-88
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ var pathModule = require('path');
99
var exec = require('child_process').exec;
1010
var alternateChrome = true;
1111
var chromePath = "";
12+
var countlyFs = require('./countlyFs');
13+
var log = require('./log.js')('core:render');
14+
var countlyConfig = require('./../config', 'dont-enclose');
15+
1216

1317
/**
1418
* Function to render views as images
@@ -40,120 +44,131 @@ exports.renderView = function(options, cb) {
4044
});
4145
}
4246

43-
if (!chromePath && alternateChrome) {
44-
chromePath = yield fetchChromeExecutablePath();
45-
}
47+
try {
48+
if (!chromePath && alternateChrome) {
49+
chromePath = yield fetchChromeExecutablePath();
50+
}
4651

47-
var browser = "";
48-
if (chromePath) {
49-
browser = yield puppeteer.launch({
52+
var settings = {
5053
headless: true,
5154
args: ['--no-sandbox', '--disable-setuid-sandbox'],
52-
executablePath: chromePath
53-
});
54-
}
55-
else {
56-
browser = yield puppeteer.launch({
57-
headless: true,
58-
args: ['--no-sandbox', '--disable-setuid-sandbox']
59-
});
60-
}
55+
ignoreHTTPSErrors: true
56+
};
57+
58+
if (chromePath) {
59+
settings.executablePath = chromePath;
60+
}
6161

62-
var page = yield browser.newPage();
62+
var browser = yield puppeteer.launch(settings);
6363

64-
var host = options.host;
65-
var token = options.token;
66-
var view = options.view;
67-
var id = options.id;
68-
var path = options.savePath || pathModule.resolve(__dirname, "../../frontend/express/public/images/screenshots/" + "screenshot_" + Date.now() + ".png");
69-
var cbFn = options.cbFn || function() {};
70-
var beforeScrnCbFn = options.beforeScrnCbFn || function() {};
64+
var page = yield browser.newPage();
7165

72-
options.dimensions = {
73-
width: options.dimensions && options.dimensions.width ? options.dimensions.width : 1366,
74-
height: options.dimensions && options.dimensions.height ? options.dimensions.height : 0,
75-
padding: options.dimensions && options.dimensions.padding ? options.dimensions.padding : 0,
76-
scale: options.dimensions && options.dimensions.scale ? options.dimensions.scale : 2
77-
};
66+
var host = "http://127.0.0.1" + countlyConfig.path;
7867

79-
yield page.goto(host + '/login/token/' + token);
68+
if (options.host) {
69+
host = options.host + countlyConfig.path;
70+
}
8071

81-
yield timeout(10000);
72+
var token = options.token;
73+
var view = options.view;
74+
var id = options.id;
75+
var path = options.savePath || pathModule.resolve(__dirname, "../../frontend/express/public/images/screenshots/" + "screenshot_" + Date.now() + ".png");
76+
var cbFn = options.cbFn || function() {};
77+
var beforeScrnCbFn = options.beforeScrnCbFn || function() {};
78+
var source = options.source;
79+
var navigationTimeout = options.timeout || 30000;
80+
81+
options.dimensions = {
82+
width: options.dimensions && options.dimensions.width ? options.dimensions.width : 1366,
83+
height: options.dimensions && options.dimensions.height ? options.dimensions.height : 0,
84+
padding: options.dimensions && options.dimensions.padding ? options.dimensions.padding : 0,
85+
scale: options.dimensions && options.dimensions.scale ? options.dimensions.scale : 2
86+
};
8287

83-
yield page.goto(host + view);
88+
page.setDefaultNavigationTimeout(navigationTimeout);
8489

85-
yield timeout(10000);
90+
yield page.goto(host + '/login/token/' + token);
8691

87-
yield page.evaluate(cbFn);
92+
yield timeout(10000);
8893

89-
yield timeout(3000);
94+
yield page.goto(host + view);
9095

91-
yield page.setViewport({
92-
width: parseInt(options.dimensions.width),
93-
height: parseInt(options.dimensions.height),
94-
deviceScaleFactor: options.dimensions.scale
95-
});
96+
yield timeout(10000);
9697

97-
yield timeout(3000);
98+
yield page.evaluate(cbFn);
9899

99-
var bodyHandle = yield page.$('body');
100-
var dimensions = yield bodyHandle.boundingBox();
100+
yield timeout(3000);
101101

102-
yield page.setViewport({
103-
width: parseInt(options.dimensions.width || dimensions.width),
104-
height: parseInt(dimensions.height - options.dimensions.padding),
105-
deviceScaleFactor: options.dimensions.scale
106-
});
102+
yield page.setViewport({
103+
width: parseInt(options.dimensions.width),
104+
height: parseInt(options.dimensions.height),
105+
deviceScaleFactor: options.dimensions.scale
106+
});
107107

108-
yield timeout(3000);
108+
yield timeout(3000);
109109

110-
yield page.evaluate(beforeScrnCbFn);
110+
var bodyHandle = yield page.$('body');
111+
var dimensions = yield bodyHandle.boundingBox();
111112

112-
yield timeout(3000);
113+
yield page.setViewport({
114+
width: parseInt(options.dimensions.width || dimensions.width),
115+
height: parseInt(dimensions.height - options.dimensions.padding),
116+
deviceScaleFactor: options.dimensions.scale
117+
});
113118

114-
var image = "";
115-
if (id) {
116-
var rect = yield page.evaluate(function(selector) {
117-
var element = document.querySelector(selector);
118-
dimensions = element.getBoundingClientRect();
119-
return {
120-
left: dimensions.x,
121-
top: dimensions.y,
122-
width: dimensions.width,
123-
height: dimensions.height,
124-
id: element.id
125-
};
126-
}, id);
119+
yield timeout(3000);
120+
121+
yield page.evaluate(beforeScrnCbFn);
122+
123+
yield timeout(3000);
127124

128-
var clip = {
129-
x: rect.left,
130-
y: rect.top,
131-
width: rect.width,
132-
height: rect.height
125+
var image = "";
126+
var screenshotOptions = {
127+
type: 'png',
128+
encoding: 'binary'
133129
};
134130

135-
image = yield page.screenshot({
136-
path: path,
137-
clip: clip,
138-
type: 'png'
139-
});
140-
}
141-
else {
142-
image = yield page.screenshot({
143-
path: path,
144-
type: 'png'
145-
});
146-
}
131+
if (id) {
132+
var rect = yield page.evaluate(function(selector) {
133+
var element = document.querySelector(selector);
134+
dimensions = element.getBoundingClientRect();
135+
return {
136+
left: dimensions.x,
137+
top: dimensions.y,
138+
width: dimensions.width,
139+
height: dimensions.height,
140+
id: element.id
141+
};
142+
}, id);
143+
144+
var clip = {
145+
x: rect.left,
146+
y: rect.top,
147+
width: rect.width,
148+
height: rect.height
149+
};
147150

148-
yield bodyHandle.dispose();
149-
yield browser.close();
151+
screenshotOptions.clip = clip;
152+
}
153+
154+
image = yield page.screenshot(screenshotOptions);
155+
156+
yield bodyHandle.dispose();
157+
yield browser.close();
150158

151-
var imageData = {
152-
image: image,
153-
path: path
154-
};
159+
yield saveScreenshot(image, path, source);
160+
161+
var imageData = {
162+
image: image,
163+
path: path
164+
};
155165

156-
return imageData;
166+
return imageData;
167+
}
168+
catch (e) {
169+
log.e(e, e.stack);
170+
throw e;
171+
}
157172
})().then(function(response) {
158173
if (cb) {
159174
return cb(null, response);
@@ -196,4 +211,26 @@ function fetchChromeExecutablePath() {
196211
});
197212
});
198213
});
214+
}
215+
/**
216+
* Function to save screenshots
217+
* @param {Buffer} image - image data to store
218+
* @param {String} path - path where image should be stored
219+
* @param {String} source - who provided image
220+
* @returns {Promise} Promise
221+
*/
222+
function saveScreenshot(image, path, source) {
223+
return new Promise(function(resolve) {
224+
var buffer = image;
225+
var saveDataOptions = {writeMode: "overwrite"};
226+
if (source && source.length) {
227+
saveDataOptions.id = source;
228+
}
229+
countlyFs.saveData("screenshots", path, buffer, saveDataOptions, function(err3) {
230+
if (err3) {
231+
log.e(err3, err3.stack);
232+
}
233+
return resolve();
234+
});
235+
});
199236
}

bin/countly.install_rhel.sh

+10-7
Original file line numberDiff line numberDiff line change
@@ -47,16 +47,9 @@ fi
4747
yum -y install policycoreutils-python
4848
yum -y install nginx
4949

50-
#configure and start nginx
5150
set +e
5251
useradd www-data
5352
unalias cp
54-
countly save /etc/nginx/conf.d/default.conf $DIR/config/nginx
55-
countly save /etc/nginx/nginx.conf $DIR/config/nginx
56-
cp $DIR/config/nginx.server.conf /etc/nginx/conf.d/default.conf
57-
cp $DIR/config/nginx.conf /etc/nginx/nginx.conf
58-
service nginx restart
59-
systemctl enable nginx
6053
set -e
6154

6255
#install supervisor
@@ -102,6 +95,16 @@ chmod 0440 /etc/sudoers
10295

10396
bash $DIR/scripts/detect.init.sh
10497

98+
#configure and start nginx
99+
set +e
100+
countly save /etc/nginx/conf.d/default.conf $DIR/config/nginx
101+
countly save /etc/nginx/nginx.conf $DIR/config/nginx
102+
cp $DIR/config/nginx.server.conf /etc/nginx/conf.d/default.conf
103+
cp $DIR/config/nginx.conf /etc/nginx/nginx.conf
104+
service nginx restart
105+
systemctl enable nginx
106+
set -e
107+
105108
#create configuration files from samples
106109
if [ ! -f $DIR/../api/config.js ]; then
107110
cp $DIR/../api/config.sample.js $DIR/../api/config.js

0 commit comments

Comments
 (0)