Added analytics telemetry throughout the application. Make sure angulartics bundles before the ga dependency.
This commit is contained in:
parent
ffbf25b62f
commit
92e0537bed
|
@ -289,6 +289,7 @@ gulp.task('dist:js:lib', function () {
|
|||
.src([
|
||||
paths.libDir + 'sjcl/sjcl.js',
|
||||
paths.libDir + 'sjcl/*.js',
|
||||
paths.libDir + 'angulartics/angulartics.js',
|
||||
paths.libDir + '**/*.js',
|
||||
'!' + paths.libDir + '**/*.min.js',
|
||||
'!' + paths.libDir + 'angular/**/*',
|
||||
|
|
|
@ -47,3 +47,24 @@
|
|||
/// <reference path="app/vault/vaultEditFolderController.js" />
|
||||
/// <reference path="app/vault/vaultEditSiteController.js" />
|
||||
/// <reference path="app/vault/vaultmodule.js" />
|
||||
/// <reference path="lib/admin-lte/js/app.js" />
|
||||
/// <reference path="lib/angular/angular.js" />
|
||||
/// <reference path="lib/angular-bootstrap/angular-bootstrap-tpls.js" />
|
||||
/// <reference path="lib/angular-bootstrap-show-errors/showErrors.js" />
|
||||
/// <reference path="lib/angular-cookies/angular-cookies.js" />
|
||||
/// <reference path="lib/angular-jwt/angular-jwt.js" />
|
||||
/// <reference path="lib/angular-md5/angular-md5.js" />
|
||||
/// <reference path="lib/angular-messages/angular-messages.js" />
|
||||
/// <reference path="lib/angular-resource/angular-resource.js" />
|
||||
/// <reference path="lib/angular-toastr/angular-toastr.js" />
|
||||
/// <reference path="lib/angular-toastr/angular-toastr.tpls.js" />
|
||||
/// <reference path="lib/angular-ui-router/angular-ui-router.js" />
|
||||
/// <reference path="lib/bootstrap/js/bootstrap.min.js" />
|
||||
/// <reference path="lib/clipboard/clipboard.js" />
|
||||
/// <reference path="lib/jquery/jquery.js" />
|
||||
/// <reference path="lib/ngclipboard/ngclipboard.js" />
|
||||
/// <reference path="lib/ngstorage/ngStorage.js" />
|
||||
/// <reference path="lib/papaparse/papaparse.js" />
|
||||
/// <reference path="lib/sjcl/bitArray.js" />
|
||||
/// <reference path="lib/sjcl/cbc.js" />
|
||||
/// <reference path="lib/sjcl/sjcl.js" />
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
angular
|
||||
.module('bit.accounts')
|
||||
|
||||
.controller('accountsLoginController', function ($scope, $rootScope, $cookies, apiService, cryptoService, authService, $state, appSettings) {
|
||||
.controller('accountsLoginController', function ($scope, $rootScope, $cookies, apiService, cryptoService, authService, $state, appSettings, $analytics) {
|
||||
var rememberedEmail = $cookies.get(appSettings.rememberdEmailCookieName);
|
||||
if (rememberedEmail) {
|
||||
$scope.model = {
|
||||
|
@ -29,9 +29,11 @@ angular
|
|||
|
||||
var profile = authService.getUserProfile();
|
||||
if (profile.twoFactor) {
|
||||
$analytics.eventTrack('Logged In To Two-step');
|
||||
$state.go('frontend.login.twoFactor');
|
||||
}
|
||||
else {
|
||||
$analytics.eventTrack('Logged In');
|
||||
$state.go('backend.vault');
|
||||
}
|
||||
});
|
||||
|
@ -42,6 +44,7 @@ angular
|
|||
$scope.twoFactorPromise = authService.logInTwoFactor(model.code, "Authenticator");
|
||||
|
||||
$scope.twoFactorPromise.then(function () {
|
||||
$analytics.eventTrack('Logged In From Two-step');
|
||||
$state.go('backend.vault');
|
||||
});
|
||||
};
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
angular
|
||||
.module('bit.accounts')
|
||||
|
||||
.controller('accountsLogoutController', function ($scope, authService, $state) {
|
||||
.controller('accountsLogoutController', function ($scope, authService, $state, $analytics) {
|
||||
authService.logOut();
|
||||
$analytics.eventTrack('Logged Out');
|
||||
$state.go('frontend.login.info');
|
||||
});
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
angular
|
||||
.module('bit.accounts')
|
||||
|
||||
.controller('accountsRegisterController', function ($scope, $location, apiService, cryptoService, validationService) {
|
||||
.controller('accountsRegisterController', function ($scope, $location, apiService, cryptoService, validationService, $analytics) {
|
||||
var params = $location.search();
|
||||
|
||||
$scope.success = false;
|
||||
|
@ -11,7 +11,7 @@ angular
|
|||
|
||||
$scope.registerPromise = null;
|
||||
$scope.register = function (form) {
|
||||
if ($scope.model.masterPassword != $scope.model.confirmMasterPassword) {
|
||||
if ($scope.model.masterPassword !== $scope.model.confirmMasterPassword) {
|
||||
validationService.addError(form, 'ConfirmMasterPassword', 'Master password confirmation does not match.', true);
|
||||
return;
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ angular
|
|||
|
||||
$scope.registerPromise = apiService.accounts.register(request, function () {
|
||||
$scope.success = true;
|
||||
$analytics.eventTrack('Registered');
|
||||
}).$promise;
|
||||
};
|
||||
});
|
||||
|
|
|
@ -18,7 +18,7 @@ angular
|
|||
}
|
||||
|
||||
var key = cryptoService.makeKey(value, profile.email, true);
|
||||
var valid = key == cryptoService.getKey(true);
|
||||
var valid = key === cryptoService.getKey(true);
|
||||
ngModel.$setValidity('masterPassword', valid);
|
||||
return valid ? value : undefined;
|
||||
});
|
||||
|
@ -30,7 +30,7 @@ angular
|
|||
}
|
||||
|
||||
var key = cryptoService.makeKey(value, profile.email, true);
|
||||
var valid = key == cryptoService.getKey(true);
|
||||
var valid = key === cryptoService.getKey(true);
|
||||
|
||||
ngModel.$setValidity('masterPassword', valid);
|
||||
return value;
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
angular
|
||||
.module('bit.settings')
|
||||
|
||||
.controller('settingsChangeEmailController', function ($scope, $state, apiService, $uibModalInstance, cryptoService, cipherService, authService, $q, toastr) {
|
||||
.controller('settingsChangeEmailController', function ($scope, $state, apiService, $uibModalInstance, cryptoService, cipherService, authService, $q, toastr, $analytics) {
|
||||
$analytics.eventTrack('settingsChangeEmailController', { category: 'Modal' });
|
||||
var _masterPasswordHash,
|
||||
_newMasterPasswordHash,
|
||||
_newKey;
|
||||
|
@ -48,6 +49,7 @@
|
|||
|
||||
$scope.confirmPromise = apiService.accounts.email(request, function () {
|
||||
$uibModalInstance.dismiss('cancel');
|
||||
$analytics.eventTrack('Changed Email');
|
||||
authService.logOut();
|
||||
$state.go('frontend.login.info').then(function () {
|
||||
toastr.success('Please log back in.', 'Email Changed');
|
||||
|
|
|
@ -2,9 +2,10 @@
|
|||
.module('bit.settings')
|
||||
|
||||
.controller('settingsChangePasswordController', function ($scope, $state, apiService, $uibModalInstance,
|
||||
cryptoService, authService, cipherService, validationService, $q, toastr) {
|
||||
cryptoService, authService, cipherService, validationService, $q, toastr, $analytics) {
|
||||
$analytics.eventTrack('settingsChangePasswordController', { category: 'Modal' });
|
||||
$scope.save = function (model, form) {
|
||||
if ($scope.model.newMasterPassword != $scope.model.confirmNewMasterPassword) {
|
||||
if ($scope.model.newMasterPassword !== $scope.model.confirmNewMasterPassword) {
|
||||
validationService.addError(form, 'ConfirmNewMasterPassword', 'New master password confirmation does not match.', true);
|
||||
return;
|
||||
}
|
||||
|
@ -36,6 +37,7 @@
|
|||
$scope.savePromise = apiService.accounts.putPassword(request, function () {
|
||||
$uibModalInstance.dismiss('cancel');
|
||||
authService.logOut();
|
||||
$analytics.eventTrack('Changed Password');
|
||||
$state.go('frontend.login.info').then(function () {
|
||||
toastr.success('Please log back in.', 'Master Password Changed');
|
||||
});
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
angular
|
||||
.module('bit.settings')
|
||||
|
||||
.controller('settingsDeleteController', function ($scope, $state, apiService, $uibModalInstance, cryptoService, authService, toastr) {
|
||||
.controller('settingsDeleteController', function ($scope, $state, apiService, $uibModalInstance, cryptoService, authService, toastr, $analytics) {
|
||||
$analytics.eventTrack('settingsDeleteController', { category: 'Modal' });
|
||||
$scope.submit = function (model) {
|
||||
var request = {
|
||||
masterPasswordHash: cryptoService.hashPassword(model.masterPassword)
|
||||
|
@ -10,6 +11,7 @@
|
|||
$scope.submitPromise = apiService.accounts.postDelete(request, function () {
|
||||
$uibModalInstance.dismiss('cancel');
|
||||
authService.logOut();
|
||||
$analytics.eventTrack('Deleted Account');
|
||||
$state.go('frontend.login.info').then(function () {
|
||||
toastr.success('Your account has been closed and all associated data has been deleted.', 'Account Deleted');
|
||||
});
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
angular
|
||||
.module('bit.settings')
|
||||
|
||||
.controller('settingsSessionsController', function ($scope, $state, apiService, $uibModalInstance, cryptoService, authService, toastr) {
|
||||
.controller('settingsSessionsController', function ($scope, $state, apiService, $uibModalInstance, cryptoService, authService, toastr, $analytics) {
|
||||
$analytics.eventTrack('settingsSessionsController', { category: 'Modal' });
|
||||
$scope.submit = function (model) {
|
||||
var request = {
|
||||
masterPasswordHash: cryptoService.hashPassword(model.masterPassword)
|
||||
|
@ -10,6 +11,7 @@
|
|||
$scope.submitPromise = apiService.accounts.putSecurityStamp(request, function () {
|
||||
$uibModalInstance.dismiss('cancel');
|
||||
authService.logOut();
|
||||
$analytics.eventTrack('Deauthorized Sessions');
|
||||
$state.go('frontend.login.info').then(function () {
|
||||
toastr.success('Please log back in.', 'All Sessions Deauthorized');
|
||||
});
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
angular
|
||||
.module('bit.settings')
|
||||
|
||||
.controller('settingsTwoFactorController', function ($scope, apiService, $uibModalInstance, cryptoService, authService, $q, toastr) {
|
||||
.controller('settingsTwoFactorController', function ($scope, apiService, $uibModalInstance, cryptoService, authService, $q, toastr, $analytics) {
|
||||
$analytics.eventTrack('settingsTwoFactorController', { category: 'Modal' });
|
||||
var _issuer = 'bitwarden',
|
||||
_profile = authService.getUserProfile(),
|
||||
_masterPasswordHash;
|
||||
|
@ -39,15 +40,17 @@
|
|||
var request = {
|
||||
enabled: !currentlyEnabled,
|
||||
token: model ? model.token : null,
|
||||
masterPasswordHash: _masterPasswordHash,
|
||||
masterPasswordHash: _masterPasswordHash
|
||||
};
|
||||
|
||||
$scope.updatePromise = apiService.accounts.putTwoFactor({}, request, function (response) {
|
||||
if (response.TwoFactorEnabled) {
|
||||
$analytics.eventTrack('Enabled Two-step Login');
|
||||
toastr.success('Two-step login has been enabled.');
|
||||
if (_profile.extended) _profile.extended.twoFactorEnabled = true;
|
||||
}
|
||||
else {
|
||||
$analytics.eventTrack('Disabled Two-step Login');
|
||||
toastr.success('Two-step login has been disabled.');
|
||||
if (_profile.extended) _profile.extended.twoFactorEnabled = false;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
angular
|
||||
.module('bit.tools')
|
||||
|
||||
.controller('toolsAuditsController', function ($scope, apiService, $uibModalInstance, toastr) {
|
||||
.controller('toolsAuditsController', function ($scope, apiService, $uibModalInstance, toastr, $analytics) {
|
||||
$analytics.eventTrack('toolsAuditsController', { category: 'Modal' });
|
||||
$scope.close = function () {
|
||||
$uibModalInstance.dismiss('cancel');
|
||||
};
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
angular
|
||||
.module('bit.tools')
|
||||
|
||||
.controller('toolsExportController', function ($scope, apiService, authService, $uibModalInstance, cryptoService, cipherService, $q, toastr) {
|
||||
.controller('toolsExportController', function ($scope, apiService, authService, $uibModalInstance, cryptoService, cipherService, $q, toastr, $analytics) {
|
||||
$analytics.eventTrack('toolsExportController', { category: 'Modal' });
|
||||
$scope.export = function (model) {
|
||||
$scope.startedExport = true;
|
||||
apiService.sites.list({ expand: ['folder'] }, function (sites) {
|
||||
|
@ -36,6 +37,7 @@
|
|||
document.body.removeChild(a);
|
||||
}
|
||||
|
||||
$analytics.eventTrack('Exported Data');
|
||||
toastr.success('Your data has been exported. Check your browser\'s downloads folder.', 'Success!');
|
||||
$scope.close();
|
||||
}
|
||||
|
@ -56,7 +58,7 @@
|
|||
function makeFileName() {
|
||||
var now = new Date();
|
||||
var dateString =
|
||||
now.getFullYear() + '' + padNumber((now.getMonth() + 1), 2) + '' + padNumber(now.getDate(), 2) +
|
||||
now.getFullYear() + '' + padNumber(now.getMonth() + 1, 2) + '' + padNumber(now.getDate(), 2) +
|
||||
padNumber(now.getHours(), 2) + '' + padNumber(now.getMinutes(), 2) +
|
||||
padNumber(now.getSeconds(), 2);
|
||||
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
angular
|
||||
.module('bit.tools')
|
||||
|
||||
.controller('toolsImportController', function ($scope, $state, apiService, $uibModalInstance, cryptoService, cipherService, toastr, importService) {
|
||||
.controller('toolsImportController', function ($scope, $state, apiService, $uibModalInstance, cryptoService, cipherService, toastr, importService, $analytics) {
|
||||
$analytics.eventTrack('toolsImportController', { category: 'Modal' });
|
||||
$scope.model = { source: 'local' };
|
||||
|
||||
$scope.import = function (model) {
|
||||
|
@ -18,6 +19,7 @@
|
|||
}, function () {
|
||||
$uibModalInstance.dismiss('cancel');
|
||||
$state.go('backend.vault').then(function () {
|
||||
$analytics.eventTrack('Imported Data', { label: model.source });
|
||||
toastr.success('Data has been successfully imported into your vault.', 'Import Success');
|
||||
});
|
||||
}, importError);
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
angular
|
||||
.module('bit.vault')
|
||||
|
||||
.controller('vaultAddFolderController', function ($scope, apiService, $uibModalInstance, cryptoService, cipherService) {
|
||||
.controller('vaultAddFolderController', function ($scope, apiService, $uibModalInstance, cryptoService, cipherService, $analytics) {
|
||||
$analytics.eventTrack('vaultAddFolderController', { category: 'Modal' });
|
||||
$scope.savePromise = null;
|
||||
$scope.save = function (model) {
|
||||
var folder = cipherService.encryptFolder(model);
|
||||
$scope.savePromise = apiService.folders.post(folder, function (response) {
|
||||
$analytics.eventTrack('Created Folder');
|
||||
var decFolder = cipherService.decryptFolder(response);
|
||||
$uibModalInstance.close(decFolder);
|
||||
}).$promise;
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
angular
|
||||
.module('bit.vault')
|
||||
|
||||
.controller('vaultAddSiteController', function ($scope, apiService, $uibModalInstance, cryptoService, cipherService, passwordService, folders, selectedFolder) {
|
||||
.controller('vaultAddSiteController', function ($scope, apiService, $uibModalInstance, cryptoService, cipherService, passwordService, folders, selectedFolder, $analytics) {
|
||||
$analytics.eventTrack('vaultAddSiteController', { category: 'Modal' });
|
||||
$scope.folders = folders;
|
||||
$scope.site = {
|
||||
folderId: selectedFolder ? selectedFolder.id : null
|
||||
|
@ -11,6 +12,7 @@
|
|||
$scope.save = function (model) {
|
||||
var site = cipherService.encryptSite(model);
|
||||
$scope.savePromise = apiService.sites.post(site, function (siteResponse) {
|
||||
$analytics.eventTrack('Created Site');
|
||||
var decSite = cipherService.decryptSite(siteResponse);
|
||||
$uibModalInstance.close(decSite);
|
||||
}).$promise;
|
||||
|
@ -18,6 +20,7 @@
|
|||
|
||||
$scope.generatePassword = function () {
|
||||
if (!$scope.site.password || confirm('Are you sure you want to overwrite the current password?')) {
|
||||
$analytics.eventTrack('Generated Password From Add');
|
||||
$scope.site.password = passwordService.generatePassword({ length: 10, special: true });
|
||||
}
|
||||
};
|
||||
|
@ -36,7 +39,7 @@
|
|||
|
||||
function selectPassword(e) {
|
||||
var target = $(e.trigger).parent().prev();
|
||||
if (target.attr('type') == 'text') {
|
||||
if (target.attr('type') === 'text') {
|
||||
target.select();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
angular
|
||||
.module('bit.vault')
|
||||
|
||||
.controller('vaultEditFolderController', function ($scope, apiService, $uibModalInstance, cryptoService, cipherService, folderId) {
|
||||
.controller('vaultEditFolderController', function ($scope, apiService, $uibModalInstance, cryptoService, cipherService, folderId, $analytics) {
|
||||
$analytics.eventTrack('vaultEditFolderController', { category: 'Modal' });
|
||||
$scope.folder = {};
|
||||
|
||||
apiService.folders.get({ id: folderId }, function (folder) {
|
||||
|
@ -12,6 +13,7 @@
|
|||
$scope.save = function (model) {
|
||||
var folder = cipherService.encryptFolder(model);
|
||||
$scope.savePromise = apiService.folders.put({ id: folderId }, folder, function (response) {
|
||||
$analytics.eventTrack('Edited Folder');
|
||||
var decFolder = cipherService.decryptFolder(response);
|
||||
$uibModalInstance.close(decFolder);
|
||||
}).$promise;
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
angular
|
||||
.module('bit.vault')
|
||||
|
||||
.controller('vaultEditSiteController', function ($scope, apiService, $uibModalInstance, cryptoService, cipherService, passwordService, siteId, folders) {
|
||||
.controller('vaultEditSiteController', function ($scope, apiService, $uibModalInstance, cryptoService, cipherService, passwordService, siteId, folders, $analytics) {
|
||||
$analytics.eventTrack('vaultEditSiteController', { category: 'Modal' });
|
||||
$scope.folders = folders;
|
||||
$scope.site = {};
|
||||
|
||||
|
@ -12,6 +13,7 @@
|
|||
$scope.save = function (model) {
|
||||
var site = cipherService.encryptSite(model);
|
||||
$scope.savePromise = apiService.sites.put({ id: siteId }, site, function (siteResponse) {
|
||||
$analytics.eventTrack('Edited Site');
|
||||
var decSite = cipherService.decryptSite(siteResponse);
|
||||
$uibModalInstance.close(decSite);
|
||||
}).$promise;
|
||||
|
@ -19,6 +21,7 @@
|
|||
|
||||
$scope.generatePassword = function () {
|
||||
if (!$scope.site.password || confirm('Are you sure you want to overwrite the current password?')) {
|
||||
$analytics.eventTrack('Generated Password From Edit');
|
||||
$scope.site.password = passwordService.generatePassword({ length: 10, special: true });
|
||||
}
|
||||
};
|
||||
|
@ -37,7 +40,7 @@
|
|||
|
||||
function selectPassword(e) {
|
||||
var target = $(e.trigger).parent().prev();
|
||||
if (target.attr('type') == 'text') {
|
||||
if (target.attr('type') === 'text') {
|
||||
target.select();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue