Resolved styling issues from Clinical Meteor packages, added HIPAA Audit Log package
This commit is contained in:
parent
98222abd0a
commit
2ea9eae0aa
@ -21,6 +21,7 @@ cornerstone
|
|||||||
worklist
|
worklist
|
||||||
viewerbase
|
viewerbase
|
||||||
dicomweb
|
dicomweb
|
||||||
|
accounts-base
|
||||||
accounts-password
|
accounts-password
|
||||||
|
|
||||||
ian:accounts-ui-bootstrap-3
|
ian:accounts-ui-bootstrap-3
|
||||||
@ -40,12 +41,10 @@ momentjs:moment
|
|||||||
clinical:router
|
clinical:router
|
||||||
clinical:extended-api
|
clinical:extended-api
|
||||||
clinical:active-entry
|
clinical:active-entry
|
||||||
clinical:static-pages
|
|
||||||
clinical:error-pages
|
clinical:error-pages
|
||||||
clinical:theming
|
clinical:theming
|
||||||
clinical:theming-ui
|
|
||||||
clinical:fonts
|
clinical:fonts
|
||||||
clinical:glass-ui
|
clinical:hipaa-audit-log
|
||||||
clinical:hipaa-logger
|
clinical:hipaa-logger
|
||||||
anti:gagarin@=0.4.11
|
anti:gagarin@=0.4.11
|
||||||
check
|
check
|
||||||
|
|||||||
@ -4,7 +4,6 @@ anti:gagarin@0.4.11
|
|||||||
anti:i18n@0.4.3
|
anti:i18n@0.4.3
|
||||||
arsnebula:reactive-promise@0.9.1
|
arsnebula:reactive-promise@0.9.1
|
||||||
autoupdate@1.2.4
|
autoupdate@1.2.4
|
||||||
awatson1978:fonts-helveticas@1.0.4
|
|
||||||
babel-compiler@5.8.24_1
|
babel-compiler@5.8.24_1
|
||||||
babel-runtime@0.1.4
|
babel-runtime@0.1.4
|
||||||
base64@1.0.4
|
base64@1.0.4
|
||||||
@ -18,19 +17,17 @@ caching-html-compiler@1.0.2
|
|||||||
callback-hook@1.0.4
|
callback-hook@1.0.4
|
||||||
check@1.1.0
|
check@1.1.0
|
||||||
clinical:active-entry@1.5.14
|
clinical:active-entry@1.5.14
|
||||||
clinical:barcode@3.0.1
|
clinical:auto-resizing@0.1.2
|
||||||
clinical:error-pages@0.1.1
|
clinical:error-pages@0.1.1
|
||||||
clinical:extended-api@2.2.1
|
clinical:extended-api@2.2.1
|
||||||
clinical:fonts@1.0.0
|
clinical:fonts@1.0.0
|
||||||
clinical:glass-ui@1.3.7
|
clinical:hipaa-audit-log@2.4.2
|
||||||
clinical:hipaa-logger@1.0.1
|
clinical:hipaa-logger@1.0.1
|
||||||
clinical:router@2.0.17
|
clinical:router@2.0.17
|
||||||
clinical:router-location@2.0.14
|
clinical:router-location@2.0.14
|
||||||
clinical:router-middleware-stack@2.0.13
|
clinical:router-middleware-stack@2.0.13
|
||||||
clinical:router-url@2.0.15
|
clinical:router-url@2.0.15
|
||||||
clinical:static-pages@1.0.7
|
|
||||||
clinical:theming@0.3.1
|
clinical:theming@0.3.1
|
||||||
clinical:theming-ui@0.2.3
|
|
||||||
coffeescript@1.0.11
|
coffeescript@1.0.11
|
||||||
cornerstone@0.0.1
|
cornerstone@0.0.1
|
||||||
ddp@1.2.2
|
ddp@1.2.2
|
||||||
@ -78,6 +75,7 @@ mobile-status-bar@1.0.6
|
|||||||
momentjs:moment@2.10.6
|
momentjs:moment@2.10.6
|
||||||
mongo@1.1.3
|
mongo@1.1.3
|
||||||
mongo-id@1.0.1
|
mongo-id@1.0.1
|
||||||
|
mrt:moment@2.8.1
|
||||||
npm-bcrypt@0.7.8_2
|
npm-bcrypt@0.7.8_2
|
||||||
npm-mongo@1.4.39_1
|
npm-mongo@1.4.39_1
|
||||||
observe-sequence@1.0.7
|
observe-sequence@1.0.7
|
||||||
|
|||||||
@ -4,22 +4,23 @@
|
|||||||
|
|
||||||
|
|
||||||
// this probably wants to be moved into clinical:glass-ui
|
// this probably wants to be moved into clinical:glass-ui
|
||||||
input, button, select{
|
.entryPage {
|
||||||
font-size: 14px;
|
input, button, select{
|
||||||
line-height: 20px;
|
font-size: 14px;
|
||||||
font-family: 'Open Sans', "Helvetica Neue", Helvetica, Arial, sans-serif;
|
line-height: 20px;
|
||||||
font-style: 400;
|
font-family: 'Open Sans', "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||||
padding: .75rem 0;
|
font-style: 400;
|
||||||
line-height: 1.5rem !important;
|
padding: .75rem 0;
|
||||||
border: none;
|
line-height: 1.5rem !important;
|
||||||
border-radius: 0;
|
border: none;
|
||||||
box-sizing: border-box;
|
border-radius: 0;
|
||||||
//color: #333333;
|
box-sizing: border-box;
|
||||||
outline: none;
|
//color: #333333;
|
||||||
padding-left: 3em;
|
outline: none;
|
||||||
|
padding-left: 3em;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.entryLogo{
|
.entryLogo{
|
||||||
//background-color: lightgray;
|
//background-color: lightgray;
|
||||||
height: 200px;
|
height: 200px;
|
||||||
|
|||||||
1
Packages/hipaa-audit-log/.gitignore
vendored
Normal file
1
Packages/hipaa-audit-log/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
.build*
|
||||||
13
Packages/hipaa-audit-log/.travis.yml
Normal file
13
Packages/hipaa-audit-log/.travis.yml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
language: node_js
|
||||||
|
node_js:
|
||||||
|
- "0.10"
|
||||||
|
#sudo: required
|
||||||
|
|
||||||
|
sudo: required
|
||||||
|
|
||||||
|
env:
|
||||||
|
global:
|
||||||
|
- METEOR_ENV=development
|
||||||
|
|
||||||
|
before_install:
|
||||||
|
- "curl -L http://git.io/ejPSng | /bin/sh"
|
||||||
9
Packages/hipaa-audit-log/History.md
Normal file
9
Packages/hipaa-audit-log/History.md
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
|
||||||
|
#### v2.3.7
|
||||||
|
|
||||||
|
* Updated to use clinical:router
|
||||||
|
|
||||||
|
#### v2.4.0
|
||||||
|
|
||||||
|
* clinical:hipaa-loger extracted from package
|
||||||
|
* HipaaLogger and HipaaLog removed
|
||||||
71
Packages/hipaa-audit-log/README.md
Normal file
71
Packages/hipaa-audit-log/README.md
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
clinical:hipaa-audit-log
|
||||||
|
====================================================
|
||||||
|
|
||||||
|
HIPAA logging and audit features for Meteor Apps built with Clinical UI.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
====================================================
|
||||||
|
#### Installation
|
||||||
|
|
||||||
|
The HIPAA audit log is now split into two packages: one for the logging, and one for the UI. Please see [``clinical:hipaa-logger``](https://github.com/clinical-meteor/hipaa-logger) for the logging portion.
|
||||||
|
|
||||||
|
````
|
||||||
|
meteor add clinical:hipaa-audit-log
|
||||||
|
meteor add clinical:hipaa-logger
|
||||||
|
````
|
||||||
|
|
||||||
|
====================================================
|
||||||
|
#### URL Routes
|
||||||
|
|
||||||
|
Navigate to the audit log via the default route:
|
||||||
|
|
||||||
|
````js
|
||||||
|
Router.go('/audit');
|
||||||
|
````
|
||||||
|
|
||||||
|
====================================================
|
||||||
|
#### Provided Templates
|
||||||
|
|
||||||
|
Three templates are provided by this package:
|
||||||
|
|
||||||
|
````html
|
||||||
|
{{>hipaaAuditLog}}
|
||||||
|
{{>hipaaRibbon}}
|
||||||
|
{{>hipaaLogPage}}
|
||||||
|
````
|
||||||
|
|
||||||
|
====================================================
|
||||||
|
#### Styling and Classes
|
||||||
|
|
||||||
|
You can adjust the styling of the audit log through the configuration object. The following example shows how to style the audit log with Bootstrap controls.
|
||||||
|
|
||||||
|
````js
|
||||||
|
HipaaAuditLog.configure({
|
||||||
|
classes: {
|
||||||
|
input: "form-control squee",
|
||||||
|
select: "form-control",
|
||||||
|
ribbon: ""
|
||||||
|
},
|
||||||
|
highlightColor: "#006289"
|
||||||
|
});
|
||||||
|
````
|
||||||
|
|
||||||
|
|
||||||
|
====================================================
|
||||||
|
#### StarryNight/Nightwatch API - Provides
|
||||||
|
|
||||||
|
````js
|
||||||
|
// component API calls
|
||||||
|
reviewHipaaAuditLogPage()
|
||||||
|
hipaaLogEntryContains(rowIndex, hipaaEvent)
|
||||||
|
|
||||||
|
// actions
|
||||||
|
logHipaaEvent(hipaaEvent, timeout)
|
||||||
|
````
|
||||||
|
|
||||||
|
|
||||||
|
------------------------
|
||||||
|
### License
|
||||||
|
|
||||||
|

|
||||||
@ -0,0 +1,171 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<template name="hipaaAuditLog">
|
||||||
|
<ul id="hipaaAuditLog" class="list-group">
|
||||||
|
{{#each hipaaAudit}}
|
||||||
|
{{> hipaaEntry}}
|
||||||
|
{{/each}}
|
||||||
|
</ul>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template name="hipaaEntry">
|
||||||
|
{{#if logMessageType 'init'}}
|
||||||
|
<li class="hipaaAuditItem list-group-item">
|
||||||
|
<div class="media">
|
||||||
|
<i class="pull-left fa fa-gears fa-2x lightgray"></i>
|
||||||
|
<div class="media-body">
|
||||||
|
<span class="small gray">{{entryTimestamp}}</span><br>
|
||||||
|
<span style="{{getHighlightColor}}">{{userName}}</span> initialized HIPAA Audit Log.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
|
||||||
|
{{#if logMessageType 'access'}}
|
||||||
|
<li class="hipaaAuditItem list-group-item">
|
||||||
|
<div class="media">
|
||||||
|
<i class="pull-left fa fa-database fa-2x lightgray"></i>
|
||||||
|
<div class="media-body">
|
||||||
|
<span class="small gray">{{entryTimestamp}}</span><br>
|
||||||
|
<span class="userName" style="{{getHighlightColor}}">{{userName}}</span> accessed record(s) <span class="mongoRecordId" style="{{getHighlightColor}}">{{getRecordId}}</span> in the <span class="collectionName" style="{{getHighlightColor}}">{{getCollectionName}}</span> collection.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
|
||||||
|
{{#if logMessageType 'create'}}
|
||||||
|
<li class="hipaaAuditItem list-group-item">
|
||||||
|
<div class="media">
|
||||||
|
<i class="pull-left fa fa-plus-circle fa-2x lightgray"></i>
|
||||||
|
<div class="media-body">
|
||||||
|
<span class="small gray">{{entryTimestamp}}</span><br>
|
||||||
|
{{#if hasPatientInfo}}
|
||||||
|
<span class="userName" style="{{getHighlightColor}}">{{userName}}</span> created record <span class="mongoRecordId" style="{{getHighlightColor}}">{{getRecordId}}</span> in the <span class="collectionName" style="{{getHighlightColor}}">{{getCollectionName}}</span> collection, regarding patient <span class="patientName" style="{{getHighlightColor}}">{{getPatientName}}</span>.
|
||||||
|
{{else}}
|
||||||
|
<span class="userName" style="{{getHighlightColor}}">{{userName}}</span> created record <span class="mongoRecordId" style="{{getHighlightColor}}">{{getRecordId}}</span> in the <span class="collectionName" style="{{getHighlightColor}}">{{getCollectionName}}</span> collection.
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
|
||||||
|
{{#if logMessageType 'modify'}}
|
||||||
|
<li class="hipaaAuditItem list-group-item">
|
||||||
|
<div class="media">
|
||||||
|
<i class="pull-left fa fa-pencil fa-2x lightgray"></i>
|
||||||
|
<div class="media-body">
|
||||||
|
<span class="small gray">{{entryTimestamp}}</span><br>
|
||||||
|
{{#if hasPatientInfo}}
|
||||||
|
<span class="userName" style="{{getHighlightColor}}">{{userName}}</span> modified record <span class="mongoRecordId" style="{{getHighlightColor}}">{{getRecordId}}</span> in the <span class="collectionName" style="{{getHighlightColor}}">{{getCollectionName}}</span> collection, regarding patient <span class="patientName {{getHighlightColor}}">{{getPatientName}}</span>.
|
||||||
|
{{else}}
|
||||||
|
<span class="userName" style="{{getHighlightColor}}">{{userName}}</span> modified record <span class="mongoRecordId" style="{{getHighlightColor}}">{{getRecordId}}</span> in the <span class="collectionName" style="{{getHighlightColor}}">{{getCollectionName}}</span> collection.
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
|
||||||
|
{{#if logMessageType 'clone'}}
|
||||||
|
<li class="hipaaAuditItem list-group-item">
|
||||||
|
<div class="media">
|
||||||
|
<i class="pull-left fa fa-code-fork fa-2x lightgray"></i>
|
||||||
|
<div class="media-body">
|
||||||
|
<span class="small gray">{{entryTimestamp}}</span><br>
|
||||||
|
<span style="{{getHighlightColor}}">{{userName}}</span> cloned record <span style="{{getHighlightColor}}">{{getRecordId}}</span> in the <span style="{{getHighlightColor}}">{{getCollectionName}}</span> collection.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
|
||||||
|
{{#if logMessageType 'delete'}}
|
||||||
|
<li class="hipaaAuditItem list-group-item">
|
||||||
|
<div class="media">
|
||||||
|
<i class="pull-left fa fa-minus-circle fa-2x lightgray"></i>
|
||||||
|
<div class="media-body">
|
||||||
|
<span class="small gray">{{entryTimestamp}}</span><br>
|
||||||
|
<span style="{{getHighlightColor}}">{{userName}}</span> deleted record <span style="{{getHighlightColor}}">{{getRecordId}}</span> in the <span style="{{getHighlightColor}}">{{getCollectionName}}</span> collection.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
|
||||||
|
{{#if logMessageType 'denied'}}
|
||||||
|
<li class="hipaaAuditItem list-group-item">
|
||||||
|
<div class="media">
|
||||||
|
<i class="pull-left fa fa-warning fa-2x lightgray"></i>
|
||||||
|
<div class="media-body">
|
||||||
|
<span class="small gray">{{entryTimestamp}}</span><br>
|
||||||
|
<span style="{{getHighlightColor}}">{{userName}}</span> was denied access to record <span style="{{getHighlightColor}}">{{getRecordId}}</span> in the <span style="{{getHighlightColor}}">{{getCollectionName}}</span> collection.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
|
||||||
|
{{#if logMessageType 'viewed'}}
|
||||||
|
<li class="hipaaAuditItem list-group-item">
|
||||||
|
<div class="media">
|
||||||
|
<i class="pull-left fa fa-eye fa-2x lightgray"></i>
|
||||||
|
<div class="media-body">
|
||||||
|
<span class="small gray">{{entryTimestamp}}</span><br>
|
||||||
|
{{#if hasPatientInfo}}
|
||||||
|
<span style="{{getHighlightColor}}">{{userName}}</span> viewed record <span style="{{getHighlightColor}}">{{getRecordId}}</span> in the <span style="{{getHighlightColor}}">{{getCollectionName}}</span> collection, regarding patient <span style="{{getHighlightColor}}">{{getPatientName}}</span>.
|
||||||
|
{{else}}
|
||||||
|
<span style="{{getHighlightColor}}">{{userName}}</span> viewed record <span style="{{getHighlightColor}}">{{getRecordId}}</span> in the <span style="{{getHighlightColor}}">{{getCollectionName}}</span> collection.
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
|
||||||
|
{{#if logMessageType 'publish'}}
|
||||||
|
<li class="hipaaAuditItem list-group-item">
|
||||||
|
<div class="media">
|
||||||
|
<i class="pull-left fa fa-rss fa-2x lightgray"></i>
|
||||||
|
<div class="media-body">
|
||||||
|
<span class="small gray">{{entryTimestamp}}</span><br>
|
||||||
|
<span style="{{getHighlightColor}}">{{userName}}</span> published record <span style="{{getHighlightColor}}">{{getRecordId}}</span> in the <span style="{{getHighlightColor}}">{{getCollectionName}}</span> collection.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
|
||||||
|
{{#if logMessageType 'unpublish'}}
|
||||||
|
<li class="hipaaAuditItem list-group-item">
|
||||||
|
<div class="media">
|
||||||
|
<i class="pull-left fa fa-circle-o fa-2x lightgray"></i>
|
||||||
|
<div class="media-body">
|
||||||
|
<span class="small gray">{{entryTimestamp}}</span><br>
|
||||||
|
<span style="{{getHighlightColor}}">{{userName}}</span> unpublished record <span style="{{getHighlightColor}}">{{getRecordId}}</span> in the <span style="{{getHighlightColor}}">{{getCollectionName}}</span> collection.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
|
||||||
|
{{#if logMessageType 'error'}}
|
||||||
|
<li class="hipaaAuditItem list-group-item">
|
||||||
|
<div class="media">
|
||||||
|
<i class="pull-left fa fa-bomb fa-2x lightgray"></i>
|
||||||
|
<div class="media-body">
|
||||||
|
<span class="small gray">{{entryTimestamp}}</span><br>
|
||||||
|
<span style="{{getHighlightColor}}">{{userName}}</span> received a data access error while performing an action!<br>
|
||||||
|
<span class="error">{{getErrorMessage}}</span>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
|
||||||
|
</template>
|
||||||
@ -0,0 +1,131 @@
|
|||||||
|
//Hipaa = new Meteor.Collection("hipaa");
|
||||||
|
|
||||||
|
Session.setDefault("hipaaSearchFilter", '');
|
||||||
|
Session.setDefault("hipaaTypeFilter", '');
|
||||||
|
|
||||||
|
// search window defaults to seven days in the past and one day in the future
|
||||||
|
Session.setDefault("beginDateFilter", new Date(moment().subtract(7, "days")).toISOString());
|
||||||
|
Session.setDefault("endDateFilter", new Date(moment().add(1, "days")).toISOString());
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Template.hipaaAuditLog.onRendered(function () {
|
||||||
|
Session.set("ribbonWidth", $('#hipaaRibbon').width());
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.hipaaAuditLog.helpers({
|
||||||
|
getHipaaSearchFilter: function () {
|
||||||
|
return Session.get('hipaaSearchFilter');
|
||||||
|
},
|
||||||
|
hipaaAudit: function () {
|
||||||
|
// return HipaaLog.find();
|
||||||
|
return HipaaLog.find({
|
||||||
|
$or: [
|
||||||
|
{
|
||||||
|
userName: {
|
||||||
|
$regex: Session.get('hipaaSearchFilter'),
|
||||||
|
$options: 'i'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
patientName: {
|
||||||
|
$regex: Session.get('hipaaSearchFilter'),
|
||||||
|
$options: 'i'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
eventType: {
|
||||||
|
$regex: Session.get("hipaaTypeFilter"),
|
||||||
|
$options: 'i'
|
||||||
|
},
|
||||||
|
timestamp: {
|
||||||
|
$lte: new Date(Session.get('endDateFilter')),
|
||||||
|
$gte: new Date(Session.get('beginDateFilter'))
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
sort: {
|
||||||
|
timestamp: -1
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.hipaaAuditLog.events({
|
||||||
|
"keyup #hipaaSearchFilter": function (event, template) {
|
||||||
|
Session.set("hipaaSearchFilter", $('#hipaaSearchFilter').val());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
//==================================================================================================
|
||||||
|
// HIPAA EVENT RECORD
|
||||||
|
|
||||||
|
Template.hipaaEntry.helpers({
|
||||||
|
getHighlightColor: function () {
|
||||||
|
var hipaaAuditLog = Session.get('HipaaAuditLogConfig');
|
||||||
|
if (hipaaAuditLog) {
|
||||||
|
return "color:" + hipaaAuditLog.highlightColor;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getUserName: function () {
|
||||||
|
if (this.userName) {
|
||||||
|
return this.userName;
|
||||||
|
} else {
|
||||||
|
return "---";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getPatientName: function () {
|
||||||
|
if (this.patientName) {
|
||||||
|
return this.patientName;
|
||||||
|
} else {
|
||||||
|
return "---";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
hasPatientInfo: function () {
|
||||||
|
if (this.patientName) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getErrorMessage: function () {
|
||||||
|
if (this.message) {
|
||||||
|
return this.message;
|
||||||
|
} else {
|
||||||
|
return "---";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getCollectionName: function () {
|
||||||
|
if (this.collectionName) {
|
||||||
|
return this.collectionName;
|
||||||
|
} else {
|
||||||
|
return "---";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getRecordId: function () {
|
||||||
|
if (this.recordId) {
|
||||||
|
return this.recordId;
|
||||||
|
} else {
|
||||||
|
return "---";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
entryTimestamp: function () {
|
||||||
|
return moment(this.timestamp).format("YYYY, MMM DD, hh:mm A");
|
||||||
|
},
|
||||||
|
entryTime: function () {
|
||||||
|
return moment(this.timestamp).format("HH:MM A");
|
||||||
|
},
|
||||||
|
entryDate: function () {
|
||||||
|
return moment(this.timestamp).format("YYYY, MMM DD");
|
||||||
|
},
|
||||||
|
logMessageType: function (eventType) {
|
||||||
|
if (this.eventType === eventType) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
@ -0,0 +1,74 @@
|
|||||||
|
#hipaaAuditLog{
|
||||||
|
padding-left: 0px !important;
|
||||||
|
|
||||||
|
li{
|
||||||
|
list-style: none;
|
||||||
|
padding-top: 5px;
|
||||||
|
padding-left: 20px;
|
||||||
|
}
|
||||||
|
.gray{
|
||||||
|
color: gray;
|
||||||
|
}
|
||||||
|
.lightgray{
|
||||||
|
color: #aaaaaa;
|
||||||
|
}
|
||||||
|
.iconColumn{
|
||||||
|
width: 10%;
|
||||||
|
}
|
||||||
|
.messageClumn{
|
||||||
|
width: 80%;
|
||||||
|
}
|
||||||
|
.fa{
|
||||||
|
padding-right: 12px;
|
||||||
|
padding-left: 4px;
|
||||||
|
padding-top: 6px;
|
||||||
|
width: 40px;
|
||||||
|
//border: 1px solid orange;
|
||||||
|
}
|
||||||
|
.fa-recycle{
|
||||||
|
padding-top: 8px;
|
||||||
|
}
|
||||||
|
.fa-plus-circle{
|
||||||
|
padding-left: 6px !important;
|
||||||
|
}
|
||||||
|
.fa-circle-o{
|
||||||
|
padding-left: 6px !important;
|
||||||
|
}
|
||||||
|
.fa-minus-circle{
|
||||||
|
padding-left: 6px !important;
|
||||||
|
}
|
||||||
|
.fa-database{
|
||||||
|
padding-left: 7px !important;
|
||||||
|
}
|
||||||
|
.fa-pencil{
|
||||||
|
padding-left: 6px !important;
|
||||||
|
}
|
||||||
|
.fa-code-fork{
|
||||||
|
padding-left: 12px !important;
|
||||||
|
}
|
||||||
|
.fa-warning{
|
||||||
|
padding-left: 5px !important
|
||||||
|
}
|
||||||
|
.fa-rss{
|
||||||
|
padding-left: 7px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hipaaAuditItem{
|
||||||
|
border-top: 1px solid lightgray;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
}
|
||||||
|
.hipaaAuditItem:nth-child(1){
|
||||||
|
border-top: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.media-body{
|
||||||
|
padding-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#hipaaAuditLog{
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
<template name="hipaaLogPage">
|
||||||
|
<div id="hipaaLogPage" class="page">
|
||||||
|
{{> hipaaRibbon }}
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
{{> hipaaAuditLog}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
Router.route("/audit", {
|
||||||
|
name:"hipaaAuditLogRoute",
|
||||||
|
template:"hipaaLogPage"
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
Template.hipaaLogPage.helpers({});
|
||||||
|
|
||||||
|
Template.hipaaLogPage.events({});
|
||||||
|
|
||||||
|
// We probably don't need this, but the subscription in subscriptions.js doesn't seem to be working?
|
||||||
|
Template.hipaaLogPage.onCreated(function() {
|
||||||
|
this.subscribe('HipaaLog');
|
||||||
|
})
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
|
||||||
|
|
||||||
|
#hipaaLogPage{
|
||||||
|
background-color: white;
|
||||||
|
//padding-top: 80px;
|
||||||
|
|
||||||
|
#hipaaLogTitle{
|
||||||
|
left: 30px;
|
||||||
|
position: absolute;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
<template name="hipaaRibbon">
|
||||||
|
<aside id="hipaaRibbon" class="{{getRibbonClass}}">
|
||||||
|
<input type="text" name="hipaaSearchFilter" id="hipaaSearchFilter" class="{{getInputClass}}" value="{{getHipaaSearchFilter}}" placeholder="Search User" style="{{getSearchFilterStyling}}">
|
||||||
|
<input type="date" id="beginDateInput" class="{{getInputClass}}" value="{{getBeginDate}}" style="{{getDateRangeStyling}}">
|
||||||
|
<input type="date" id="endDateInput" class="{{getInputClass}}" value="{{getEndDate}}" style="{{getDateRangeStyling}}">
|
||||||
|
<select id="actionFilter" name="actionFilter" class="{{getSelectClass}}" style="{{getSelectStyling}}">
|
||||||
|
<option id="filterCreatedButton">Created</option>
|
||||||
|
<option id="filterModifiedButton">Modified</option>
|
||||||
|
<option id="filterViewedButton">Viewed</option>
|
||||||
|
<option id="filterAllButton">All</option>
|
||||||
|
</select>
|
||||||
|
</aside>
|
||||||
|
|
||||||
|
</template>
|
||||||
@ -0,0 +1,99 @@
|
|||||||
|
Template.hipaaRibbon.events({
|
||||||
|
'keyup #hipaaSearchFilter': function () {
|
||||||
|
Session.set("hipaaSearchFilter", $('#hipaaSearchFilter').val());
|
||||||
|
},
|
||||||
|
"change #beginDateInput": function (event, template) {
|
||||||
|
Session.set("beginDateFilter", $('#beginDateInput').val() + "T00:00:00.000Z");
|
||||||
|
},
|
||||||
|
"change #endDateInput": function (event, template) {
|
||||||
|
Session.set("endDateFilter", $('#endDateInput').val() + "T00:00:00.000Z");
|
||||||
|
},
|
||||||
|
|
||||||
|
'click #filterCreatedButton': function () {
|
||||||
|
Session.set("hipaaTypeFilter", 'create');
|
||||||
|
},
|
||||||
|
'click #filterModifiedButton': function () {
|
||||||
|
Session.set("hipaaTypeFilter", 'modify');
|
||||||
|
},
|
||||||
|
'click #filterViewedButton': function () {
|
||||||
|
Session.set("hipaaTypeFilter", 'viewed');
|
||||||
|
},
|
||||||
|
'click #filterAllButton': function () {
|
||||||
|
Session.set("hipaaTypeFilter", '');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var ribbonBreakPoint = 760;
|
||||||
|
|
||||||
|
|
||||||
|
Meteor.startup(function(){
|
||||||
|
$(window).resize(function(evt) {
|
||||||
|
Session.set("ribbonWidth", $('#hipaaRibbon').width());
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.hipaaRibbon.helpers({
|
||||||
|
getSearchFilterStyling: function () {
|
||||||
|
// spacing between inputs should be 20px each
|
||||||
|
// if the overall width of the audit log is less than N, show the fullwidth
|
||||||
|
if(Session.get('ribbonWidth') > ribbonBreakPoint){
|
||||||
|
var searchFilterWidth = Session.get('ribbonWidth') - 575;
|
||||||
|
return "margin-left: 10px; margin-right: 5px; width:" + searchFilterWidth + "px;";
|
||||||
|
}else{
|
||||||
|
var ribbonWidth = Session.get('ribbonWidth') - 40;
|
||||||
|
return "width: " + ribbonWidth + "px; margin-left: 10px; margin-right: 10px;";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getDateRangeStyling: function () {
|
||||||
|
// spacing between inputs should be 20px each
|
||||||
|
// date range inputs shouldn't be less than 170 px
|
||||||
|
// if the overall width of the audit log is less than N, dont even show them
|
||||||
|
if(Session.get('ribbonWidth') > ribbonBreakPoint){
|
||||||
|
return "visbility: visible; margin-left: 5px; margin-right: 5px; width: 170px;";
|
||||||
|
}else{
|
||||||
|
return "display: none; visibility: hidden";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getSelectStyling: function () {
|
||||||
|
// spacing between inputs should be 20px each
|
||||||
|
// select input should be the same as daterange
|
||||||
|
if(Session.get('ribbonWidth') > ribbonBreakPoint){
|
||||||
|
return "visbility: visible; margin-left: 5px; margin-right: 5px; width: 170px;";
|
||||||
|
}else{
|
||||||
|
return "display: none; visibility: hidden";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getRibbonClass: function () {
|
||||||
|
var hipaaAuditLog = Session.get('HipaaAuditLogConfig');
|
||||||
|
if (hipaaAuditLog && hipaaAuditLog.classes) {
|
||||||
|
return hipaaAuditLog.classes.ribbon;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getSelectClass: function () {
|
||||||
|
var hipaaAuditLog = Session.get('HipaaAuditLogConfig');
|
||||||
|
if (hipaaAuditLog && hipaaAuditLog.classes) {
|
||||||
|
return hipaaAuditLog.classes.select;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getInputClass: function () {
|
||||||
|
var hipaaAuditLog = Session.get('HipaaAuditLogConfig');
|
||||||
|
if (hipaaAuditLog && hipaaAuditLog.classes) {
|
||||||
|
return hipaaAuditLog.classes.input;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getHipaaSearchFilter: function () {
|
||||||
|
return Session.get('hipaaSearchFilter');
|
||||||
|
},
|
||||||
|
getBeginDate: function () {
|
||||||
|
return moment(Session.get("beginDateFilter")).format("YYYY-MM-DD");
|
||||||
|
},
|
||||||
|
getEndDate: function () {
|
||||||
|
return moment(Session.get("endDateFilter")).format("YYYY-MM-DD");
|
||||||
|
}
|
||||||
|
});
|
||||||
@ -0,0 +1,35 @@
|
|||||||
|
|
||||||
|
#hipaaRibbon{
|
||||||
|
position: static;
|
||||||
|
width: 100%;
|
||||||
|
padding-top: 10px;
|
||||||
|
height: 60px;
|
||||||
|
//background-color: lightgray;
|
||||||
|
|
||||||
|
input[type="date"]{
|
||||||
|
padding-left: 10px;
|
||||||
|
}
|
||||||
|
input[type="text"]{
|
||||||
|
// padding-left: 10px;
|
||||||
|
// padding-right: 10px;
|
||||||
|
}
|
||||||
|
select{
|
||||||
|
display: inline-block;
|
||||||
|
height: 40px;
|
||||||
|
// padding-left: 10px;
|
||||||
|
// padding-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#hipaaSearchFilter{
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
//---------------------------------------
|
||||||
|
// Bootstrap users
|
||||||
|
.form-control{
|
||||||
|
display: inline-block !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// @media only screen and (max-width: 850px) {
|
||||||
|
//
|
||||||
|
// }
|
||||||
1
Packages/hipaa-audit-log/components/subscriptions.js
Normal file
1
Packages/hipaa-audit-log/components/subscriptions.js
Normal file
@ -0,0 +1 @@
|
|||||||
|
Meteor.subscribe('HipaaLog');
|
||||||
19
Packages/hipaa-audit-log/lib/HipaaAuditLog.js
Normal file
19
Packages/hipaa-audit-log/lib/HipaaAuditLog.js
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
HipaaAuditLog = {
|
||||||
|
configure: function (configObject) {
|
||||||
|
if (Meteor.isClient) {
|
||||||
|
Session.set('HipaaAuditLogConfig', configObject);
|
||||||
|
}
|
||||||
|
//console.log("HipaaAuditLogConfig.configObject", configObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Meteor.isClient) {
|
||||||
|
Session.setDefault('HipaaAuditLogConfig', {
|
||||||
|
classes: {
|
||||||
|
input: "",
|
||||||
|
select: "",
|
||||||
|
ribbon: ""
|
||||||
|
},
|
||||||
|
highlightColor: ""
|
||||||
|
});
|
||||||
|
}
|
||||||
59
Packages/hipaa-audit-log/package.js
Normal file
59
Packages/hipaa-audit-log/package.js
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
Package.describe({
|
||||||
|
summary: "HIPAA audit log for ClinicalFramework.",
|
||||||
|
version: "2.4.2",
|
||||||
|
git: "http://github.com/clinical-meteor/clinical-hipaa-audit-log.git",
|
||||||
|
name: "clinical:hipaa-audit-log"
|
||||||
|
});
|
||||||
|
|
||||||
|
Package.on_use(function (api) {
|
||||||
|
api.versionsFrom('1.1.0.3');
|
||||||
|
|
||||||
|
api.use('meteor-platform');
|
||||||
|
|
||||||
|
api.use('mrt:moment@2.8.1', 'client');
|
||||||
|
api.use('grove:less@0.1.1', 'client');
|
||||||
|
|
||||||
|
api.use('clinical:router@2.0.17');
|
||||||
|
api.use('clinical:fonts@1.0.0', 'client');
|
||||||
|
api.use('clinical:auto-resizing@0.1.2', 'client');
|
||||||
|
api.use('clinical:hipaa-logger@1.0.0');
|
||||||
|
|
||||||
|
api.imply('clinical:hipaa-logger');
|
||||||
|
|
||||||
|
api.addFiles('lib/HipaaAuditLog.js');
|
||||||
|
|
||||||
|
api.addFiles('server/initialize.js', "server");
|
||||||
|
api.addFiles('server/publication.js', "server");
|
||||||
|
|
||||||
|
api.addFiles('components/hipaaRibbon/hipaaRibbon.html', "client");
|
||||||
|
api.addFiles('components/hipaaRibbon/hipaaRibbon.js', "client");
|
||||||
|
api.addFiles('components/hipaaRibbon/hipaaRibbon.less', "client");
|
||||||
|
|
||||||
|
api.addFiles('components/hipaaAuditLog/hipaaAuditLog.html', "client");
|
||||||
|
api.addFiles('components/hipaaAuditLog/hipaaAuditLog.js', "client");
|
||||||
|
api.addFiles('components/hipaaAuditLog/hipaaAuditLog.less', "client");
|
||||||
|
|
||||||
|
api.addFiles('components/hipaaLogPage/hipaaLogPage.html', "client");
|
||||||
|
api.addFiles('components/hipaaLogPage/hipaaLogPage.js', "client");
|
||||||
|
api.addFiles('components/hipaaLogPage/hipaaLogPage.less', "client");
|
||||||
|
|
||||||
|
api.export('HipaaAuditLog');
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Package.onTest(function (api) {
|
||||||
|
api.use('tinytest');
|
||||||
|
|
||||||
|
api.use('meteor-platform');
|
||||||
|
api.use('iron:router@1.0.4', 'client');
|
||||||
|
api.use('mrt:moment@2.8.1', 'client');
|
||||||
|
api.use('grove:less@0.1.1', 'client');
|
||||||
|
|
||||||
|
api.use('clinical:verification');
|
||||||
|
api.use('clinical:fonts@1.0.0');
|
||||||
|
api.use('clinical:hipaa-audit-log');
|
||||||
|
api.use('clinical:hipaa-logger@1.0.0');
|
||||||
|
|
||||||
|
api.addFiles('tests/tinytest/audit-log-tests.js');
|
||||||
|
});
|
||||||
BIN
Packages/hipaa-audit-log/screenshots/auditlog.png
Normal file
BIN
Packages/hipaa-audit-log/screenshots/auditlog.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 304 KiB |
26
Packages/hipaa-audit-log/server/initialize.js
Normal file
26
Packages/hipaa-audit-log/server/initialize.js
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
Meteor.methods({
|
||||||
|
initializeDemoLog:function (){
|
||||||
|
console.log('initializeDemoLog');
|
||||||
|
|
||||||
|
// hipaaEvent, userId, userName, collectionName, recordId, patientId, patientName, message
|
||||||
|
HipaaLogger.logEvent("init", Meteor.userId(), "Ada Lovelace");
|
||||||
|
|
||||||
|
HipaaLogger.logEvent("create", Meteor.userId(), "Ada Lovelace", "Users", Random.id(), Random.id(), "John Doe");
|
||||||
|
|
||||||
|
HipaaLogger.logEvent("viewed", Meteor.userId(), "Mary Shelley", "Users", Random.id(), Random.id(), "John Doe");
|
||||||
|
HipaaLogger.logEvent("create", Meteor.userId(), "Florence Nightingale", "Vitals", Random.id(), Random.id(), "John Doe");
|
||||||
|
HipaaLogger.logEvent("viewed", Meteor.userId(), "Florence Nightingale", "Medications", Random.id(), Random.id(), "John Doe");
|
||||||
|
HipaaLogger.logEvent("create", Meteor.userId(), "Florence Nightingale", "Medications", Random.id(), Random.id(), "John Doe");
|
||||||
|
HipaaLogger.logEvent("denied", Meteor.userId(), "Kurt Vonnegut", "MedicationPlans", Random.id(), Random.id(), "John Doe");
|
||||||
|
HipaaLogger.logEvent("create", Meteor.userId(), "Florence Nightingale", "Vitals", Random.id(), Random.id(), "John Doe");
|
||||||
|
HipaaLogger.logEvent("viewed", Meteor.userId(), "Florence Nightingale", "MedicationPlans", Random.id(), Random.id(), "John Doe");
|
||||||
|
HipaaLogger.logEvent("modify", Meteor.userId(), "Florence Nightingale", "MedicationPlans", Random.id(), Random.id(), "John Doe");
|
||||||
|
HipaaLogger.logEvent("viewed", Meteor.userId(), "Edward Doisy", "Users", Random.id(), Random.id(), "John Doe");
|
||||||
|
HipaaLogger.logEvent("clone", Meteor.userId(), "Edward Doisy", "MedicationPlans", Random.id(), Random.id(), "John Doe");
|
||||||
|
HipaaLogger.logEvent("publish", Meteor.userId(), "Edward Doisy", "MedicationPlans", Random.id(), Random.id(), "John Doe");
|
||||||
|
HipaaLogger.logEvent("unpublish", Meteor.userId(), "Edward Doisy", "MedicationPlans", Random.id(), Random.id(), "John Doe");
|
||||||
|
HipaaLogger.logEvent("delete", Meteor.userId(), "Ada Lovelace", "MedicationPlans", Random.id(), Random.id(), "John Doe");
|
||||||
|
HipaaLogger.logEvent("viewed", Meteor.userId(), "Florence Nightingale", "Vitals", Random.id(), Random.id(), "John Doe");
|
||||||
|
HipaaLogger.logEvent("create", Meteor.userId(), "Florence Nightingale", "Vitals", Random.id(), Random.id(), "John Doe");
|
||||||
|
}
|
||||||
|
});
|
||||||
4
Packages/hipaa-audit-log/server/publication.js
Normal file
4
Packages/hipaa-audit-log/server/publication.js
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
|
||||||
|
Meteor.publish('HipaaLog', function () {
|
||||||
|
return HipaaLog.find();
|
||||||
|
});
|
||||||
72
Packages/hipaa-audit-log/tests/gagarin/HipaaAuditLogTests.js
Normal file
72
Packages/hipaa-audit-log/tests/gagarin/HipaaAuditLogTests.js
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
|
||||||
|
describe('clinical:hipaa-audit-log', function () {
|
||||||
|
var server = meteor();
|
||||||
|
var client = browser(server);
|
||||||
|
|
||||||
|
// beforeEach(function () {
|
||||||
|
// server.execute(function () {
|
||||||
|
//
|
||||||
|
// }).then(function (value){
|
||||||
|
//
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
// afterEach(function () {
|
||||||
|
// server.execute(function () {
|
||||||
|
//
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
|
||||||
|
it('HipaaLogger should exist on the client', function () {
|
||||||
|
return client.execute(function () {
|
||||||
|
expect(HipaaLogger).to.exist;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('HipaaLogger should exist on the server', function () {
|
||||||
|
return server.execute(function () {
|
||||||
|
expect(HipaaLogger).to.exist;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
it("HipaaLogger can log events on the client", function () {
|
||||||
|
return client.execute(function () {
|
||||||
|
HipaaLogger.logEvent({
|
||||||
|
eventType: "modified",
|
||||||
|
userId: "janedoe",
|
||||||
|
userName: "Jane Doe",
|
||||||
|
collectionName: "Medications",
|
||||||
|
recordId: "123",
|
||||||
|
patientId: "123",
|
||||||
|
patientName: "abc"
|
||||||
|
});
|
||||||
|
return HipaaLog.findOne();
|
||||||
|
}).then(function (eventRecord){
|
||||||
|
server.wait(500, "", function (){
|
||||||
|
expect(eventRecord).to.exist;
|
||||||
|
expect(eventRecord.userId).to.equal("janedoe");
|
||||||
|
expect(eventRecord.userName).to.equal("Jane Doe");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("HipaaLogger can log events on the server", function () {
|
||||||
|
return server.execute(function () {
|
||||||
|
HipaaLogger.logEvent({
|
||||||
|
eventType: "modified",
|
||||||
|
userId: "janedoe",
|
||||||
|
userName: "Jane Doe",
|
||||||
|
collectionName: "Medications",
|
||||||
|
recordId: "123",
|
||||||
|
patientId: "123",
|
||||||
|
patientName: "abc"
|
||||||
|
});
|
||||||
|
|
||||||
|
var eventRecord = HipaaLog.findOne();
|
||||||
|
|
||||||
|
expect(eventRecord).to.exist;
|
||||||
|
expect(eventRecord.userId).to.equal("janedoe");
|
||||||
|
expect(eventRecord.userName).to.equal("Jane Doe");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
exports.command = function(rowIndex, hipaaEvent) {
|
||||||
|
this
|
||||||
|
.verify.elementPresent("#hipaaAuditLog .hipaaAuditItem:nth-child(" + rowIndex + ")")
|
||||||
|
|
||||||
|
if(hipaaEvent.type === "create"){
|
||||||
|
this
|
||||||
|
.verify.elementPresent("#hipaaAuditLog .hipaaAuditItem:nth-child(" + rowIndex + ") .userName", hipaaEvent.userName)
|
||||||
|
.verify.elementPresent("#hipaaAuditLog .hipaaAuditItem:nth-child(" + rowIndex + ") .recordId", hipaaEvent.recordId)
|
||||||
|
.verify.elementPresent("#hipaaAuditLog .hipaaAuditItem:nth-child(" + rowIndex + ") .collectionName", hipaaEvent.collectionName)
|
||||||
|
|
||||||
|
if(hipaaEvent.patientName){
|
||||||
|
this.verify.elementPresent("#hipaaAuditLog .hipaaAuditItem:nth-child(" + rowIndex + ") .patientName", hipaaEvent.patientName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
};
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
|
||||||
|
|
||||||
|
exports.command = function() {
|
||||||
|
this
|
||||||
|
.verify.elementPresent("#hipaaLogPage")
|
||||||
|
.verify.elementPresent("#hipaaAuditLog")
|
||||||
|
|
||||||
|
return this;
|
||||||
|
};
|
||||||
@ -0,0 +1,41 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// syncrhonous version; doesn't work well
|
||||||
|
/*exports.command = function(hipaaEvent, timeout) {
|
||||||
|
var client = this;
|
||||||
|
this
|
||||||
|
.execute(function(data){
|
||||||
|
return HipaaLogger.logEventObject(data);
|
||||||
|
}, [hipaaEvent], function(result){
|
||||||
|
console.log("result.value", result.value);
|
||||||
|
client.assert.ok(result.value);
|
||||||
|
}).pause(1000)
|
||||||
|
return this;
|
||||||
|
};*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// async version calls method on the server
|
||||||
|
exports.command = function(hipaaEvent, timeout) {
|
||||||
|
var client = this;
|
||||||
|
if (!timeout) {
|
||||||
|
timeout = 5000;
|
||||||
|
}
|
||||||
|
|
||||||
|
this
|
||||||
|
.timeoutsAsyncScript(timeout)
|
||||||
|
.executeAsync(function(data, meteorCallback){
|
||||||
|
//return HipaaLogger.logEventObject(data);
|
||||||
|
Meteor.call('logHipaaEvent', data, function(meteorError, meteorResult){
|
||||||
|
var response = (meteorError ? { error: meteorError } : { result: meteorResult });
|
||||||
|
meteorCallback(response);
|
||||||
|
})
|
||||||
|
}, [hipaaEvent], function(result){
|
||||||
|
console.log("result.value", result.value);
|
||||||
|
client.assert.ok(result.value);
|
||||||
|
}).pause(1000)
|
||||||
|
return this;
|
||||||
|
};
|
||||||
25
Packages/hipaa-audit-log/tests/tinytest/audit-log-tests.js
Normal file
25
Packages/hipaa-audit-log/tests/tinytest/audit-log-tests.js
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
describe('clinical:hipaa-audit-log', function () {
|
||||||
|
|
||||||
|
describe('user interface', function () {
|
||||||
|
it.client('displays an audit log', function () {
|
||||||
|
|
||||||
|
});
|
||||||
|
it.client('has a search button', function () {
|
||||||
|
|
||||||
|
});
|
||||||
|
it.client('has filter buttons', function () {
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('server functionality', function () {
|
||||||
|
it.client('logs hipaa events to a HIPAA collection', function () {
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
it.client('doesnt allow users to delete or modify events', function () {
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -55,6 +55,21 @@ getStudyMetadata = function(studyInstanceUid, doneCallback) {
|
|||||||
|
|
||||||
// Finally, we fire the doneCallback with this study meta data
|
// Finally, we fire the doneCallback with this study meta data
|
||||||
doneCallback(study);
|
doneCallback(study);
|
||||||
|
|
||||||
|
// Temporary: Testing out the Clinical Meteor HIPAA Audit log
|
||||||
|
if (Meteor.user()) {
|
||||||
|
log.info('Adding access to HIPAA Log');
|
||||||
|
var hipaaEvent = {
|
||||||
|
eventType: "access",
|
||||||
|
userId: Meteor.userId(),
|
||||||
|
userName: Meteor.user().profile.fullName,
|
||||||
|
collectionName: "Studies",
|
||||||
|
recordId: studyInstanceUid,
|
||||||
|
patientId: null,
|
||||||
|
patientName: null
|
||||||
|
};
|
||||||
|
HipaaLogger.logEvent(hipaaEvent);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user