1
0
mirror of https://github.com/bitwarden/browser.git synced 2024-09-13 01:58:44 +02:00

event logs for users. ip address. useEvents checks

This commit is contained in:
Kyle Spearrin 2017-12-18 13:17:49 -05:00
parent 828149b2d6
commit f54884eb79
11 changed files with 168 additions and 7 deletions

View File

@ -83,7 +83,8 @@
appName: eventInfo.appName,
userId: userId,
userName: userId ? (orgUsersUserIdDict[userId] || '-') : '-',
date: list.Data[i].Date
date: list.Data[i].Date,
ip: list.Data[i].IpAddress
});
}
if ($scope.events && $scope.events.length > 0) {

View File

@ -5,6 +5,7 @@
toastr, $analytics) {
$scope.users = [];
$scope.useGroups = false;
$scope.useEvents = false;
$scope.$on('$viewContentLoaded', function () {
loadList();
@ -13,6 +14,7 @@
if (profile.organizations) {
var org = profile.organizations[$state.params.orgId];
$scope.useGroups = !!org.useGroups;
$scope.useEvents = !!org.useEvents;
}
});
});
@ -110,6 +112,18 @@
});
};
$scope.events = function (user) {
$uibModal.open({
animation: true,
templateUrl: 'app/organization/views/organizationPeopleEvents.html',
controller: 'organizationPeopleEventsController',
resolve: {
orgUser: function () { return user; },
orgId: function () { return $state.params.orgId; }
}
});
};
function loadList() {
apiService.organizationUsers.list({ orgId: $state.params.orgId }, function (list) {
var users = [];

View File

@ -0,0 +1,74 @@
angular
.module('bit.organization')
.controller('organizationPeopleEventsController', function ($scope, apiService, $uibModalInstance,
orgUser, $analytics, eventService, orgId) {
$analytics.eventTrack('organizationPeopleEventsController', { category: 'Modal' });
$scope.email = orgUser.email;
$scope.events = [];
$scope.loading = true;
$scope.continuationToken = null;
var defaultFilters = eventService.getDefaultDateFilters();
$scope.filterStart = defaultFilters.start;
$scope.filterEnd = defaultFilters.end;
$uibModalInstance.opened.then(function () {
loadEvents(true);
});
$scope.refresh = function () {
loadEvents(true);
};
$scope.next = function () {
loadEvents(false);
};
function loadEvents(clearExisting) {
var filterResult = eventService.formatDateFilters($scope.filterStart, $scope.filterEnd);
if (filterResult.error) {
alert(filterResult.error);
return;
}
if (clearExisting) {
$scope.continuationToken = null;
$scope.events = [];
}
$scope.loading = true;
return apiService.events.listOrganizationUser({
orgId: orgId,
id: orgUser.id,
start: filterResult.start,
end: filterResult.end,
continuationToken: $scope.continuationToken
}).$promise.then(function (list) {
$scope.continuationToken = list.ContinuationToken;
var events = [];
for (var i = 0; i < list.Data.length; i++) {
var eventInfo = eventService.getEventInfo(list.Data[i]);
events.push({
message: eventInfo.message,
appIcon: eventInfo.appIcon,
appName: eventInfo.appName,
date: list.Data[i].Date,
ip: list.Data[i].IpAddress
});
}
if ($scope.events && $scope.events.length > 0) {
$scope.events = $scope.events.concat(events);
}
else {
$scope.events = events;
}
$scope.loading = false;
});
}
$scope.close = function () {
$uibModalInstance.dismiss('cancel');
};
});

View File

@ -1,7 +1,7 @@
angular
.module('bit.organization')
.controller('organizationVaultCipherEventsController', function ($scope, apiService, $uibModalInstance, cipherService,
.controller('organizationVaultCipherEventsController', function ($scope, apiService, $uibModalInstance,
cipher, $analytics, eventService) {
$analytics.eventTrack('organizationVaultCipherEventsController', { category: 'Modal' });
$scope.cipher = cipher;
@ -84,7 +84,8 @@
appName: eventInfo.appName,
userId: userId,
userName: userId ? (orgUsersUserIdDict[userId] || '-') : '-',
date: list.Data[i].Date
date: list.Data[i].Date,
ip: list.Data[i].IpAddress
});
}
if ($scope.events && $scope.events.length > 0) {

View File

@ -6,8 +6,16 @@
$scope.ciphers = [];
$scope.collections = [];
$scope.loading = true;
$scope.useEvents = false;
$scope.$on('$viewContentLoaded', function () {
authService.getUserProfile().then(function (profile) {
if (profile.organizations) {
var org = profile.organizations[$state.params.orgId];
$scope.useEvents = !!org.useEvents;
}
});
var collectionPromise = apiService.collections.listOrganization({ orgId: $state.params.orgId }, function (collections) {
var decCollections = [{
id: null,

View File

@ -47,7 +47,7 @@
{{event.userName}}
</td>
<td style="width: 20px;" class="text-center">
<i class="text-muted fa fa-lg {{event.appIcon}}" title="{{event.appName}}"></i>
<i class="text-muted fa fa-lg {{event.appIcon}}" title="{{event.appName}}, {{event.ip}}"></i>
</td>
<td>
{{event.message}}

View File

@ -46,6 +46,12 @@
<i class="fa fa-fw fa-sitemap"></i> Groups
</a>
</li>
<li>
<a href="#" stop-click ng-click="events(user)"
ng-if="useEvents && user.status === 2">
<i class="fa fa-fw fa-file-text-o"></i> Event Logs
</a>
</li>
<li ng-show="user.status === 1">
<a href="#" stop-click ng-click="confirm(user)">
<i class="fa fa-fw fa-check"></i> Confirm

View File

@ -0,0 +1,56 @@
<div class="modal-header">
<button type="button" class="close" ng-click="close()" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title"><i class="fa fa-file-text-o"></i> User Event Logs <small>{{email}}</small></h4>
</div>
<div class="modal-body">
<div class="hidden-xs">
<input type="datetime-local" ng-model="filterStart" required
class="form-control input-sm" style="width:initial; display: inline;" />
-
<input type="datetime-local" ng-model="filterEnd" required
class="form-control input-sm" style="width:initial; display: inline;" />
<button type="button" class="btn btn-primary btn-sm btn-flat" ng-click="refresh()">
<i class="fa fa-fw fa-refresh" ng-class="{'fa-spin': loading}"></i> Refresh
</button>
<hr />
</div>
<div ng-show="loading && !events.length">
Loading...
</div>
<div ng-show="!loading && !events.length">
<p>There are no events to list.</p>
</div>
<div class="table-responsive" ng-show="events.length" style="margin: 0;">
<table class="table table-striped table-hover" style="{{ !continuationToken ? 'margin: 0;' : '' }}">
<thead>
<tr>
<th>Timestamp</th>
<th><span class="sr-only">App</span></th>
<th>Event</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="event in filteredEvents = (events)">
<td style="width: 210px; min-width: 100px;">
{{event.date | date:'medium'}}
</td>
<td style="width: 20px;" class="text-center">
<i class="text-muted fa fa-lg {{event.appIcon}}" title="{{event.appName}}, {{event.ip}}"></i>
</td>
<td>
{{event.message}}
</td>
</tr>
</tbody>
</table>
</div>
<div class="text-center" ng-show="continuationToken">
<button class="btn btn-link btn-block" ng-click="next()" ng-if="!loading">
Load more...
</button>
<i class="fa fa-fw fa-refresh fa-spin text-muted" ng-if="loading"></i>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default btn-flat" ng-click="close()">Close</button>
</div>

View File

@ -57,7 +57,7 @@
</a>
</li>
<li>
<a href="#" stop-click ng-click="viewEvents(cipher)">
<a href="#" stop-click ng-click="viewEvents(cipher)" ng-if="useEvents">
<i class="fa fa-fw fa-file-text-o"></i> Event Logs
</a>
</li>

View File

@ -39,7 +39,7 @@
{{event.userName}}
</td>
<td style="width: 20px;" class="text-center">
<i class="text-muted fa fa-lg {{event.appIcon}}" title="{{event.appName}}"></i>
<i class="text-muted fa fa-lg {{event.appIcon}}" title="{{event.appName}}, {{event.ip}}"></i>
</td>
<td>
{{event.message}}

View File

@ -185,6 +185,7 @@
<script src="app/organization/organizationPeopleInviteController.js"></script>
<script src="app/organization/organizationPeopleEditController.js"></script>
<script src="app/organization/organizationPeopleGroupsController.js"></script>
<script src="app/organization/organizationPeopleEventsController.js"></script>
<script src="app/organization/organizationCollectionsController.js"></script>
<script src="app/organization/organizationCollectionsAddController.js"></script>
<script src="app/organization/organizationCollectionsEditController.js"></script>
@ -204,13 +205,13 @@
<script src="app/organization/organizationVaultAddCipherController.js"></script>
<script src="app/organization/organizationVaultEditCipherController.js"></script>
<script src="app/organization/organizationVaultCipherCollectionsController.js"></script>
<script src="app/organization/organizationVaultCipherEventsController.js"></script>
<script src="app/organization/organizationVaultAttachmentsController.js"></script>
<script src="app/organization/organizationGroupsController.js"></script>
<script src="app/organization/organizationGroupsAddController.js"></script>
<script src="app/organization/organizationGroupsEditController.js"></script>
<script src="app/organization/organizationGroupsUsersController.js"></script>
<script src="app/organization/organizationEventsController.js"></script>
<script src="app/organization/organizationVaultCipherEventsController.js"></script>
<script src="app/settings/settingsModule.js"></script>
<script src="app/settings/settingsController.js"></script>