@ministryofjustice/hmpps-prison-permissions-lib 1.1.2 → 2.0.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 CHANGED
@@ -2,6 +2,16 @@
2
2
 
3
3
  Please use this to capture reasoning behind changes:
4
4
 
5
+ # 2.0.0
6
+ Replaced contacts read permissions check with one that handles released prisoners differently. Checks for current prisoners are unaffected.
7
+
8
+ To be permitted to read contacts for released prisoners:
9
+ - the user's roles must include `InactiveBookings` and one or both of the following: `ContactsAdministrator, ContactsAuthoriser`
10
+ - the prisoner must have been released within the last 3 years (`PermissionCheckStatus.EXCEEDS_TIME_RESTRICTION`)
11
+ - the previous prison of the prisoner must match the user's caseload
12
+
13
+ These changes were requested by the contacts team after noticing the 'External Contacts' widget was not showing on the prisoner profiles of released prisoners. This was due to a caseload mismatch, as the assigned caseload for released prisoners is 'OUT'.
14
+
5
15
  ## 1.1.2
6
16
 
7
17
  Moved `@ministryofjustice/hmpps-npm-script-allowlist` to be a `dev` dependency as it’s used when working on this package
@@ -0,0 +1,4 @@
1
+ import { TestScenarios } from '../../../testUtils/TestScenario';
2
+ export declare const deniedContactsReadScenarios: TestScenarios;
3
+ export declare const grantedContactsReadScenarios: TestScenarios;
4
+ export declare const contactsReadCheckScenarios: TestScenarios;
@@ -0,0 +1,4 @@
1
+ import { TestScenarios } from '../../../../testUtils/TestScenario';
2
+ export declare const deniedContactsReadScenarios: TestScenarios;
3
+ export declare const grantedContactsReadScenarios: TestScenarios;
4
+ export declare const contactsReadCheckScenarios: TestScenarios;
package/dist/index.cjs CHANGED
@@ -11,6 +11,7 @@ exports.PermissionCheckStatus = void 0;
11
11
  PermissionCheckStatus["RESTRICTED_PATIENT"] = "RESTRICTED_PATIENT";
12
12
  PermissionCheckStatus["PRISONER_IS_RELEASED"] = "PRISONER_IS_RELEASED";
13
13
  PermissionCheckStatus["PRISONER_IS_TRANSFERRING"] = "PRISONER_IS_TRANSFERRING";
14
+ PermissionCheckStatus["EXCEEDS_TIME_RESTRICTION"] = "EXCEEDS_TIME_RESTRICTION";
14
15
  PermissionCheckStatus["ROLE_NOT_PRESENT"] = "ROLE_NOT_PRESENT";
15
16
  PermissionCheckStatus["NOT_PRISON_USER"] = "NOT_PRISON_USER";
16
17
  PermissionCheckStatus["OK"] = "OK";
@@ -119,6 +120,11 @@ const isReleased = (prisoner) => {
119
120
  const isTransferring = (prisoner) => {
120
121
  return !!prisoner?.prisonId && ['TRN'].includes(prisoner.prisonId);
121
122
  };
123
+ const wasReleasedWithinThreeYears = (prisoner) => {
124
+ return (isReleased(prisoner) &&
125
+ !!prisoner.previousPrisonLeavingDate &&
126
+ Date.parse(prisoner.previousPrisonLeavingDate) > Date.now() - 3 * 365 * 24 * 60 * 60 * 1000);
127
+ };
122
128
  function userHasSomeRolesFrom(rolesToCheck, user) {
123
129
  return (rolesToCheck.length === 0 ||
124
130
  rolesToCheck.map(normaliseRoleText).some(role => user.userRoles.map(normaliseRoleText).includes(role)));
@@ -745,6 +751,21 @@ const inUsersCaseLoadAndUserHasSomeRolesFrom = (roles) => matchBaseCheckAnd({
745
751
 
746
752
  const inUsersCaseLoadAndUserHasRole = (role) => inUsersCaseLoadAndUserHasSomeRolesFrom([role]);
747
753
 
754
+ const contactsReadCheck = matchBaseCheckAnd({
755
+ overridingCondition: (user, prisoner) => {
756
+ if (isReleased(prisoner)) {
757
+ if (!userHasSomeRolesFrom([exports.Role.ContactsAdministrator, exports.Role.ContactsAuthoriser], user))
758
+ return exports.PermissionCheckStatus.ROLE_NOT_PRESENT;
759
+ if (!wasReleasedWithinThreeYears(prisoner))
760
+ return exports.PermissionCheckStatus.EXCEEDS_TIME_RESTRICTION;
761
+ if (!isInUsersCaseLoad(prisoner.previousPrisonId, user))
762
+ return exports.PermissionCheckStatus.NOT_IN_CASELOAD;
763
+ return exports.PermissionCheckStatus.OK;
764
+ }
765
+ return isInUsersCaseLoad(prisoner.prisonId, user) ? exports.PermissionCheckStatus.OK : exports.PermissionCheckStatus.NOT_IN_CASELOAD;
766
+ },
767
+ });
768
+
748
769
  function personalRelationshipsCheck(context) {
749
770
  const check = checkWith(context);
750
771
  return {
@@ -754,7 +775,7 @@ function personalRelationshipsCheck(context) {
754
775
  ...check(exports.PersonalRelationshipsPermission.edit_domestic_status, prisonerProfileEditCheck),
755
776
  ...check(exports.PersonalRelationshipsPermission.read_emergency_contacts, baseCheck),
756
777
  ...check(exports.PersonalRelationshipsPermission.edit_emergency_contacts, prisonerProfileSensitiveEditCheck),
757
- ...check(exports.PersonalRelationshipsPermission.read_contacts, inUsersCaseLoad),
778
+ ...check(exports.PersonalRelationshipsPermission.read_contacts, contactsReadCheck),
758
779
  ...check(exports.PersonalRelationshipsPermission.edit_contacts, inUsersCaseLoadAndUserHasSomeRolesFrom([exports.Role.ContactsAdministrator, exports.Role.ContactsAuthoriser])),
759
780
  ...check(exports.PersonalRelationshipsPermission.edit_contact_restrictions, inUsersCaseLoadAndUserHasRole(exports.Role.ContactsAuthoriser)),
760
781
  ...check(exports.PersonalRelationshipsPermission.edit_contact_visit_approval, inUsersCaseLoadAndUserHasRole(exports.Role.ContactsAuthoriser)),