@ministryofjustice/hmpps-prison-permissions-lib 0.2.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +30 -0
- package/README.md +2 -0
- package/dist/contractTests/prisonerProfile/scenarios/domains/person/caseNotes/CaseNotesReadAndEditScenarios.d.ts +4 -0
- package/dist/contractTests/prisonerProfile/scenarios/domains/person/caseNotes/SensitiveCaseNotesBaseScenarios.d.ts +3 -0
- package/dist/contractTests/prisonerProfile/scenarios/domains/person/caseNotes/SensitiveCaseNotesDeleteScenarios.d.ts +2 -1
- package/dist/data/hmppsPrisonerSearch/interfaces/Prisoner.d.ts +2 -0
- package/dist/index.cjs +38 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +9 -7
- package/dist/index.esm.js +38 -11
- package/dist/index.esm.js.map +1 -1
- package/dist/services/permissions/checks/domains/person/caseNotes/CaseNotesReadAndEditCheckAndUserHasSomeRolesFrom.d.ts +4 -0
- package/dist/services/permissions/checks/domains/person/caseNotes/CaseNotesReadAndEditScenarios.d.ts +4 -0
- package/dist/services/permissions/checks/domains/person/caseNotes/SensitiveCaseNotesBaseScenarios.d.ts +3 -0
- package/dist/services/permissions/utils/DateUtils.d.ts +3 -0
- package/dist/services/permissions/utils/DateUtils.test.d.ts +1 -0
- package/dist/testUtils/TestScenario.d.ts +1 -0
- package/package.json +4 -4
- package/readme/mocking.md +66 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,36 @@
|
|
|
2
2
|
|
|
3
3
|
Please use this to capture reasoning behind changes:
|
|
4
4
|
|
|
5
|
+
## 0.3.0
|
|
6
|
+
|
|
7
|
+
Official release for updates to the Case Notes and Religion permissions.
|
|
8
|
+
|
|
9
|
+
**Case Notes Permissions:**
|
|
10
|
+
|
|
11
|
+
Previously if a user had both the `POM` and `GLOBAL_SEARCH` roles they would be able read/write case notes any prisoner. The case notes permissions have now been updated so that users with both the `POM` and `GLOBAL_SEARCH` roles will only be able to read/write a prisoner's case notes if the prisoner has been in the users establishment within the last 30 days.
|
|
12
|
+
|
|
13
|
+
The permissions check requires additional data to be passed in via the `Prisoner` which now expects the `previousPrisonId` and `previousPrisonLeavingDate` fields to be present. This data has been added to the prisoner search API so clients using the permissions library will need to ensure the following fields are present in the `Prisoner` interface.
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
export default interface Prisoner {
|
|
17
|
+
prisonerNumber: string
|
|
18
|
+
prisonId?: string
|
|
19
|
+
restrictedPatient: boolean
|
|
20
|
+
supportingPrisonId?: string
|
|
21
|
+
previousPrisonId?: string
|
|
22
|
+
previousPrisonLeavingDate?: string
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
**Religion and Belief Permissions:**
|
|
27
|
+
|
|
28
|
+
The permissions check for `PersonProtectedCharacteristicsPermission.read_religion_and_belief` updated to only allow read access to a
|
|
29
|
+
prisoner's religion data to users who are part of the prisoner's caseload.
|
|
30
|
+
|
|
31
|
+
## 0.3.0-alpha.1
|
|
32
|
+
|
|
33
|
+
Alpha release to test changes to the case notes and religion permissions.
|
|
34
|
+
|
|
5
35
|
## 0.2.0
|
|
6
36
|
|
|
7
37
|
Incident response. We are introducing an additional role enabling staff to upload photos via DPS.
|
package/README.md
CHANGED
|
@@ -1,2 +1,6 @@
|
|
|
1
1
|
import { TestScenarios } from '../../../../../../testUtils/TestScenario';
|
|
2
|
+
export declare const deniedCaseNotesReadAndEditScenarios: TestScenarios;
|
|
3
|
+
export declare const grantedCaseNotesReadAndEditAfterTransferScenarios: TestScenarios;
|
|
4
|
+
export declare const grantedCaseNotesReadAndEditTransferringPrisonerScenarios: TestScenarios;
|
|
5
|
+
export declare const grantedCaseNotesReadAndEditScenarios: TestScenarios;
|
|
2
6
|
export declare const caseNotesReadAndEditScenarios: TestScenarios;
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
import { TestScenarios } from '../../../../../../testUtils/TestScenario';
|
|
2
|
+
export declare const sensitiveCaseNotesDeleteScenarios: TestScenarios;
|
package/dist/index.cjs
CHANGED
|
@@ -521,6 +521,14 @@ exports.CaseNotesPermission = void 0;
|
|
|
521
521
|
CaseNotesPermission["edit_sensitive"] = "prisoner:case-notes:sensitive:edit";
|
|
522
522
|
})(exports.CaseNotesPermission || (exports.CaseNotesPermission = {}));
|
|
523
523
|
|
|
524
|
+
function daysToMilliseconds(days) {
|
|
525
|
+
return days * 24 * 60 * 60 * 1000;
|
|
526
|
+
}
|
|
527
|
+
function isDateWithinBounds(dateToCheckInMs, upperDateBoundInMs, lowerDateBoundInMs) {
|
|
528
|
+
return dateToCheckInMs <= upperDateBoundInMs && lowerDateBoundInMs <= dateToCheckInMs;
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
const caseNotesAccessPeriodPostTransferInMs = daysToMilliseconds(30);
|
|
524
532
|
function caseNotesReadAndEditCheck(permission, request) {
|
|
525
533
|
const baseCheckPassed = request.baseCheckStatus === exports.PermissionCheckStatus.OK;
|
|
526
534
|
const caseNotesCheckStatus = checkCaseNotesAccess(request);
|
|
@@ -530,6 +538,13 @@ function caseNotesReadAndEditCheck(permission, request) {
|
|
|
530
538
|
logDeniedPermissionCheck(permission, request, caseNotesCheckStatus);
|
|
531
539
|
return check;
|
|
532
540
|
}
|
|
541
|
+
function checkTimeBasedAccessToCaseNotesPostTransfer(user, prisoner, timePeriodForAccessPostTransferInMilliseconds) {
|
|
542
|
+
if (!isInUsersCaseLoad(prisoner.previousPrisonId, user) || !prisoner.previousPrisonLeavingDate)
|
|
543
|
+
return false;
|
|
544
|
+
const previousPrisonLeavingDate = Date.parse(prisoner.previousPrisonLeavingDate);
|
|
545
|
+
const today = Date.now();
|
|
546
|
+
return isDateWithinBounds(previousPrisonLeavingDate, today, today - timePeriodForAccessPostTransferInMilliseconds);
|
|
547
|
+
}
|
|
533
548
|
function checkCaseNotesAccess(request) {
|
|
534
549
|
const { user, prisoner } = request;
|
|
535
550
|
// Restricted patients follows the base check rules:
|
|
@@ -547,10 +562,13 @@ function checkCaseNotesAccess(request) {
|
|
|
547
562
|
// Case notes are accessible if the prisoner's prison is in the user's caseload:
|
|
548
563
|
if (isInUsersCaseLoad(prisoner.prisonId, user))
|
|
549
564
|
return exports.PermissionCheckStatus.OK;
|
|
550
|
-
|
|
551
|
-
|
|
565
|
+
if (!userHasAllRoles([exports.Role.GlobalSearch, exports.Role.PomUser], user))
|
|
566
|
+
return exports.PermissionCheckStatus.ROLE_NOT_PRESENT;
|
|
567
|
+
// Case notes for prisoners outside the user's caseload are only accessible with both Global Search and POM roles if the prisoner
|
|
568
|
+
// was previously in one of the users caseloads in the 30 days:
|
|
569
|
+
return checkTimeBasedAccessToCaseNotesPostTransfer(user, prisoner, caseNotesAccessPeriodPostTransferInMs)
|
|
552
570
|
? exports.PermissionCheckStatus.OK
|
|
553
|
-
: exports.PermissionCheckStatus.
|
|
571
|
+
: exports.PermissionCheckStatus.NOT_PERMITTED;
|
|
554
572
|
}
|
|
555
573
|
|
|
556
574
|
const permission$7 = exports.CaseNotesPermission.read;
|
|
@@ -558,10 +576,10 @@ function caseNotesReadCheck(request) {
|
|
|
558
576
|
return caseNotesReadAndEditCheck(permission$7, request);
|
|
559
577
|
}
|
|
560
578
|
|
|
561
|
-
function
|
|
562
|
-
const { user
|
|
563
|
-
const
|
|
564
|
-
const check =
|
|
579
|
+
function caseNotesReadAndEditCheckAndUserHasRolesFrom(roles, permission, request) {
|
|
580
|
+
const { user } = request;
|
|
581
|
+
const baseCaseNotesCheckPassed = caseNotesReadAndEditCheck(permission, request);
|
|
582
|
+
const check = baseCaseNotesCheckPassed && userHasSomeRolesFrom(roles, user);
|
|
565
583
|
if (!check)
|
|
566
584
|
logDeniedPermissionCheck(permission, request, exports.PermissionCheckStatus.ROLE_NOT_PRESENT);
|
|
567
585
|
return check;
|
|
@@ -569,17 +587,17 @@ function baseCheckAndUserHasSomeRolesFrom(roles, permission, request) {
|
|
|
569
587
|
|
|
570
588
|
const permission$6 = exports.CaseNotesPermission.read_sensitive;
|
|
571
589
|
function sensitiveCaseNotesReadCheck(request) {
|
|
572
|
-
return
|
|
590
|
+
return caseNotesReadAndEditCheckAndUserHasRolesFrom([exports.Role.PomUser, exports.Role.ViewSensitiveCaseNotes, exports.Role.AddSensitiveCaseNotes], permission$6, request);
|
|
573
591
|
}
|
|
574
592
|
|
|
575
593
|
const permission$5 = exports.CaseNotesPermission.delete_sensitive;
|
|
576
594
|
function sensitiveCaseNotesDeleteCheck(request) {
|
|
577
|
-
return
|
|
595
|
+
return caseNotesReadAndEditCheckAndUserHasRolesFrom([exports.Role.DeleteSensitiveCaseNotes], permission$5, request);
|
|
578
596
|
}
|
|
579
597
|
|
|
580
598
|
const permission$4 = exports.CaseNotesPermission.edit_sensitive;
|
|
581
599
|
function sensitiveCaseNotesEditCheck(request) {
|
|
582
|
-
return
|
|
600
|
+
return caseNotesReadAndEditCheckAndUserHasRolesFrom([exports.Role.PomUser, exports.Role.AddSensitiveCaseNotes], permission$4, request);
|
|
583
601
|
}
|
|
584
602
|
|
|
585
603
|
const permission$3 = exports.CaseNotesPermission.edit;
|
|
@@ -735,7 +753,7 @@ function personProtectedCharacteristicsCheck(request) {
|
|
|
735
753
|
return {
|
|
736
754
|
...readCheck$3(exports.PersonProtectedCharacteristicsPermission.read_sexual_orientation, request),
|
|
737
755
|
...sensitiveEditCheck$1(exports.PersonProtectedCharacteristicsPermission.edit_sexual_orientation, request),
|
|
738
|
-
|
|
756
|
+
[exports.PersonProtectedCharacteristicsPermission.read_religion_and_belief]: inUsersCaseLoad(exports.PersonProtectedCharacteristicsPermission.read_religion_and_belief, request),
|
|
739
757
|
...editCheck$3(exports.PersonProtectedCharacteristicsPermission.edit_religion_and_belief, request),
|
|
740
758
|
...readCheck$3(exports.PersonProtectedCharacteristicsPermission.read_ethnicity, request),
|
|
741
759
|
...sensitiveEditCheck$1(exports.PersonProtectedCharacteristicsPermission.edit_ethnicity, request),
|
|
@@ -850,6 +868,15 @@ function personCheck(request) {
|
|
|
850
868
|
};
|
|
851
869
|
}
|
|
852
870
|
|
|
871
|
+
function baseCheckAndUserHasSomeRolesFrom(roles, permission, request) {
|
|
872
|
+
const { user, baseCheckStatus } = request;
|
|
873
|
+
const baseCheckPassed = baseCheckStatus === exports.PermissionCheckStatus.OK;
|
|
874
|
+
const check = baseCheckPassed && userHasSomeRolesFrom(roles, user);
|
|
875
|
+
if (!check)
|
|
876
|
+
logDeniedPermissionCheck(permission, request, exports.PermissionCheckStatus.ROLE_NOT_PRESENT);
|
|
877
|
+
return check;
|
|
878
|
+
}
|
|
879
|
+
|
|
853
880
|
exports.PathfinderPermission = void 0;
|
|
854
881
|
(function (PathfinderPermission) {
|
|
855
882
|
PathfinderPermission["read"] = "prisoner:pathfinder:read";
|