mirror of
https://github.com/bitwarden/web
synced 2025-12-12 14:23:18 +00:00
event logs for users. ip address. useEvents checks
This commit is contained in:
@@ -83,7 +83,8 @@
|
|||||||
appName: eventInfo.appName,
|
appName: eventInfo.appName,
|
||||||
userId: userId,
|
userId: userId,
|
||||||
userName: userId ? (orgUsersUserIdDict[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) {
|
if ($scope.events && $scope.events.length > 0) {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
toastr, $analytics) {
|
toastr, $analytics) {
|
||||||
$scope.users = [];
|
$scope.users = [];
|
||||||
$scope.useGroups = false;
|
$scope.useGroups = false;
|
||||||
|
$scope.useEvents = false;
|
||||||
|
|
||||||
$scope.$on('$viewContentLoaded', function () {
|
$scope.$on('$viewContentLoaded', function () {
|
||||||
loadList();
|
loadList();
|
||||||
@@ -13,6 +14,7 @@
|
|||||||
if (profile.organizations) {
|
if (profile.organizations) {
|
||||||
var org = profile.organizations[$state.params.orgId];
|
var org = profile.organizations[$state.params.orgId];
|
||||||
$scope.useGroups = !!org.useGroups;
|
$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() {
|
function loadList() {
|
||||||
apiService.organizationUsers.list({ orgId: $state.params.orgId }, function (list) {
|
apiService.organizationUsers.list({ orgId: $state.params.orgId }, function (list) {
|
||||||
var users = [];
|
var users = [];
|
||||||
|
|||||||
74
src/app/organization/organizationPeopleEventsController.js
Normal file
74
src/app/organization/organizationPeopleEventsController.js
Normal 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');
|
||||||
|
};
|
||||||
|
});
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
angular
|
angular
|
||||||
.module('bit.organization')
|
.module('bit.organization')
|
||||||
|
|
||||||
.controller('organizationVaultCipherEventsController', function ($scope, apiService, $uibModalInstance, cipherService,
|
.controller('organizationVaultCipherEventsController', function ($scope, apiService, $uibModalInstance,
|
||||||
cipher, $analytics, eventService) {
|
cipher, $analytics, eventService) {
|
||||||
$analytics.eventTrack('organizationVaultCipherEventsController', { category: 'Modal' });
|
$analytics.eventTrack('organizationVaultCipherEventsController', { category: 'Modal' });
|
||||||
$scope.cipher = cipher;
|
$scope.cipher = cipher;
|
||||||
@@ -84,7 +84,8 @@
|
|||||||
appName: eventInfo.appName,
|
appName: eventInfo.appName,
|
||||||
userId: userId,
|
userId: userId,
|
||||||
userName: userId ? (orgUsersUserIdDict[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) {
|
if ($scope.events && $scope.events.length > 0) {
|
||||||
|
|||||||
@@ -6,8 +6,16 @@
|
|||||||
$scope.ciphers = [];
|
$scope.ciphers = [];
|
||||||
$scope.collections = [];
|
$scope.collections = [];
|
||||||
$scope.loading = true;
|
$scope.loading = true;
|
||||||
|
$scope.useEvents = false;
|
||||||
|
|
||||||
$scope.$on('$viewContentLoaded', function () {
|
$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 collectionPromise = apiService.collections.listOrganization({ orgId: $state.params.orgId }, function (collections) {
|
||||||
var decCollections = [{
|
var decCollections = [{
|
||||||
id: null,
|
id: null,
|
||||||
|
|||||||
@@ -47,7 +47,7 @@
|
|||||||
{{event.userName}}
|
{{event.userName}}
|
||||||
</td>
|
</td>
|
||||||
<td style="width: 20px;" class="text-center">
|
<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>
|
||||||
<td>
|
<td>
|
||||||
{{event.message}}
|
{{event.message}}
|
||||||
|
|||||||
@@ -46,6 +46,12 @@
|
|||||||
<i class="fa fa-fw fa-sitemap"></i> Groups
|
<i class="fa fa-fw fa-sitemap"></i> Groups
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</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">
|
<li ng-show="user.status === 1">
|
||||||
<a href="#" stop-click ng-click="confirm(user)">
|
<a href="#" stop-click ng-click="confirm(user)">
|
||||||
<i class="fa fa-fw fa-check"></i> Confirm
|
<i class="fa fa-fw fa-check"></i> Confirm
|
||||||
|
|||||||
56
src/app/organization/views/organizationPeopleEvents.html
Normal file
56
src/app/organization/views/organizationPeopleEvents.html
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
<div class="modal-header">
|
||||||
|
<button type="button" class="close" ng-click="close()" aria-label="Close"><span aria-hidden="true">×</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>
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<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
|
<i class="fa fa-fw fa-file-text-o"></i> Event Logs
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
@@ -39,7 +39,7 @@
|
|||||||
{{event.userName}}
|
{{event.userName}}
|
||||||
</td>
|
</td>
|
||||||
<td style="width: 20px;" class="text-center">
|
<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>
|
||||||
<td>
|
<td>
|
||||||
{{event.message}}
|
{{event.message}}
|
||||||
|
|||||||
@@ -185,6 +185,7 @@
|
|||||||
<script src="app/organization/organizationPeopleInviteController.js"></script>
|
<script src="app/organization/organizationPeopleInviteController.js"></script>
|
||||||
<script src="app/organization/organizationPeopleEditController.js"></script>
|
<script src="app/organization/organizationPeopleEditController.js"></script>
|
||||||
<script src="app/organization/organizationPeopleGroupsController.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/organizationCollectionsController.js"></script>
|
||||||
<script src="app/organization/organizationCollectionsAddController.js"></script>
|
<script src="app/organization/organizationCollectionsAddController.js"></script>
|
||||||
<script src="app/organization/organizationCollectionsEditController.js"></script>
|
<script src="app/organization/organizationCollectionsEditController.js"></script>
|
||||||
@@ -204,13 +205,13 @@
|
|||||||
<script src="app/organization/organizationVaultAddCipherController.js"></script>
|
<script src="app/organization/organizationVaultAddCipherController.js"></script>
|
||||||
<script src="app/organization/organizationVaultEditCipherController.js"></script>
|
<script src="app/organization/organizationVaultEditCipherController.js"></script>
|
||||||
<script src="app/organization/organizationVaultCipherCollectionsController.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/organizationVaultAttachmentsController.js"></script>
|
||||||
<script src="app/organization/organizationGroupsController.js"></script>
|
<script src="app/organization/organizationGroupsController.js"></script>
|
||||||
<script src="app/organization/organizationGroupsAddController.js"></script>
|
<script src="app/organization/organizationGroupsAddController.js"></script>
|
||||||
<script src="app/organization/organizationGroupsEditController.js"></script>
|
<script src="app/organization/organizationGroupsEditController.js"></script>
|
||||||
<script src="app/organization/organizationGroupsUsersController.js"></script>
|
<script src="app/organization/organizationGroupsUsersController.js"></script>
|
||||||
<script src="app/organization/organizationEventsController.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/settingsModule.js"></script>
|
||||||
<script src="app/settings/settingsController.js"></script>
|
<script src="app/settings/settingsController.js"></script>
|
||||||
|
|||||||
Reference in New Issue
Block a user