UNPKG

@ministryofjustice/hmpps-prison-permissions-lib

Version:

A library to centralise the process of determining whether a user should have access to create/read/update/delete a prison resource, for example, accessing a prisoner's Prisoner Profile.

968 lines (862 loc) 72.7 kB
import { RestClient, asSystem } from '@ministryofjustice/hmpps-rest-client'; // eslint-disable-next-line import/prefer-default-export var PermissionCheckStatus; (function (PermissionCheckStatus) { PermissionCheckStatus["NOT_PERMITTED"] = "NOT_PERMITTED"; PermissionCheckStatus["NOT_IN_CASELOAD"] = "NOT_IN_CASELOAD"; PermissionCheckStatus["NOT_ACTIVE_CASELOAD"] = "NOT_ACTIVE_CASELOAD"; PermissionCheckStatus["RESTRICTED_PATIENT"] = "RESTRICTED_PATIENT"; PermissionCheckStatus["PRISONER_IS_RELEASED"] = "PRISONER_IS_RELEASED"; PermissionCheckStatus["PRISONER_IS_TRANSFERRING"] = "PRISONER_IS_TRANSFERRING"; PermissionCheckStatus["EXCEEDS_TIME_RESTRICTION"] = "EXCEEDS_TIME_RESTRICTION"; PermissionCheckStatus["ROLE_NOT_PRESENT"] = "ROLE_NOT_PRESENT"; PermissionCheckStatus["NOT_PRISON_USER"] = "NOT_PRISON_USER"; PermissionCheckStatus["READ_ONLY"] = "READ_ONLY"; PermissionCheckStatus["OK"] = "OK"; })(PermissionCheckStatus || (PermissionCheckStatus = {})); class PermissionsLogger { logger; telemetryClient; constructor(logger, telemetryClient) { this.logger = logger; this.telemetryClient = telemetryClient; } logPermissionCheckStatus(user, prisoner, permission, permissionCheckStatus) { if (permissionCheckStatus === PermissionCheckStatus.OK) return; if (this.telemetryClient) { this.telemetryClient.trackEvent({ name: 'prisoner-permission-denied', properties: { username: user.username, prisonerNumber: prisoner.prisonerNumber, activeCaseLoad: user.authSource === 'nomis' && user.activeCaseLoadId, permissionChecked: permission, status: permissionCheckStatus, }, }); } else { this.logger.info(`Prisoner permission denied: ${permission} (${permissionCheckStatus}) for user ${user.username}`); } } logPermissionGrantedByDuplicate(user, prisoner, duplicateRecords, permission) { if (this.telemetryClient) { this.telemetryClient.trackEvent({ name: 'prisoner-permission-requirement-upgraded-by-duplicate', properties: { username: user.username, prisonerNumber: prisoner.prisonerNumber, duplicatePrisonerNumbers: duplicateRecords.map(record => record.prisonerNumber).join(','), activeCaseLoad: user.authSource === 'nomis' && user.activeCaseLoadId, permissionChecked: permission, }, }); } else { this.logger.info(`Required prisoner permission upgraded by duplicate: ${permission} for user ${user.username}`); } } } class PrisonerSearchClient extends RestClient { constructor(logger, config, authenticationClient) { super('Prisoner Search', config, logger, authenticationClient); } getPrisonerDetails(prisonerNumber) { return this.get({ path: `/prisoner/${prisonerNumber}` }, asSystem()); } } var PersonSentenceCalculationPermission; (function (PersonSentenceCalculationPermission) { PersonSentenceCalculationPermission["read"] = "prisoner:person-sentence-calculation:read"; PersonSentenceCalculationPermission["edit_adjustments"] = "prisoner:person-sentence-calculation:adjustments:edit"; })(PersonSentenceCalculationPermission || (PersonSentenceCalculationPermission = {})); // eslint-disable-next-line import/prefer-default-export var Role; (function (Role) { Role["ActivityHub"] = "ROLE_ACTIVITY_HUB"; Role["AddSensitiveCaseNotes"] = "ROLE_ADD_SENSITIVE_CASE_NOTES"; Role["AdjustmentsMaintainer"] = "ROLE_ADJUSTMENTS_MAINTAINER"; Role["ApproveCategorisation"] = "ROLE_APPROVE_CATEGORISATION"; Role["CategorisationSecurity"] = "ROLE_CATEGORISATION_SECURITY"; Role["CellMove"] = "ROLE_CELL_MOVE"; Role["ContactsAdministrator"] = "ROLE_CONTACTS_ADMINISTRATOR"; Role["ContactsAuthoriser"] = "ROLE_CONTACTS_AUTHORISER"; Role["CreateCategorisation"] = "ROLE_CREATE_CATEGORISATION"; Role["CreateRecategorisation"] = "ROLE_CREATE_RECATEGORISATION"; Role["DeleteSensitiveCaseNotes"] = "ROLE_DELETE_SENSITIVE_CASE_NOTES"; Role["DietAndAllergiesEdit"] = "ROLE_DIET_AND_FOOD_ALLERGIES_EDIT"; Role["ExternalMovementsTemporaryAbsenceManagement"] = "ROLE_EXTERNAL_MOVEMENTS_TAP_RW"; Role["ExternalMovementsTemporaryAbsenceViewOnly"] = "ROLE_EXTERNAL_MOVEMENTS_TAP_RO"; Role["GlobalSearch"] = "ROLE_GLOBAL_SEARCH"; Role["InactiveBookings"] = "ROLE_INACTIVE_BOOKINGS"; Role["PathfinderApproval"] = "ROLE_PF_APPROVAL"; Role["PathfinderHQ"] = "ROLE_PF_HQ"; Role["PathfinderLocalReader"] = "ROLE_PF_LOCAL_READER"; Role["PathfinderNationalReader"] = "ROLE_PF_NATIONAL_READER"; Role["PathfinderPolice"] = "ROLE_PF_POLICE"; Role["PathfinderPsychologist"] = "ROLE_PF_PSYCHOLOGIST"; Role["PathfinderStdPrison"] = "ROLE_PF_STD_PRISON"; Role["PathfinderStdProbation"] = "ROLE_PF_STD_PROBATION"; Role["PathfinderUser"] = "ROLE_PF_USER"; Role["PomUser"] = "ROLE_POM"; Role["PrisonerProfilePhotoUpload"] = "ROLE_PRISONER_PROFILE_PHOTO_UPLOAD"; Role["PrisonerProfileSensitiveEdit"] = "ROLE_PRISONER_PROFILE_SENSITIVE_RW"; Role["ReceptionUser"] = "ROLE_PRISON_RECEPTION"; Role["ReleaseDatesCalculator"] = "ROLE_RELEASE_DATES_CALCULATOR"; Role["SocCommunity"] = "ROLE_SOC_COMMUNITY"; Role["SocCustody"] = "ROLE_SOC_CUSTODY"; Role["SocDataAnalyst"] = "ROLE_SOC_DATA_ANALYST"; Role["SocDataManager"] = "ROLE_SOC_DATA_MANAGER"; Role["UpdateAlert"] = "ROLE_UPDATE_ALERT"; Role["ViewProbationDocuments"] = "ROLE_VIEW_PROBATION_DOCUMENTS"; Role["ViewSensitiveCaseNotes"] = "ROLE_VIEW_SENSITIVE_CASE_NOTES"; })(Role || (Role = {})); var PrisonerBasePermission; (function (PrisonerBasePermission) { PrisonerBasePermission["read"] = "prisoner:base-record:read"; })(PrisonerBasePermission || (PrisonerBasePermission = {})); var PrisonerAdjudicationsPermission; (function (PrisonerAdjudicationsPermission) { PrisonerAdjudicationsPermission["read"] = "prisoner:prisoner-adjudications:read"; })(PrisonerAdjudicationsPermission || (PrisonerAdjudicationsPermission = {})); // eslint-disable-next-line import/prefer-default-export const prisonerAdjudicationsPermissionPaths = { [PrisonerAdjudicationsPermission.read]: `domainGroups.prisonerSpecific.prisonerAdjudications.${PrisonerAdjudicationsPermission.read}`, }; var PrisonerMoneyPermission; (function (PrisonerMoneyPermission) { PrisonerMoneyPermission["read"] = "prisoner:prisoner-money:read"; })(PrisonerMoneyPermission || (PrisonerMoneyPermission = {})); // eslint-disable-next-line import/prefer-default-export const prisonerMoneyPermissionPaths = { [PrisonerMoneyPermission.read]: `domainGroups.prisonerSpecific.prisonerMoney.${PrisonerMoneyPermission.read}`, }; var PrisonerIncentivesPermission; (function (PrisonerIncentivesPermission) { PrisonerIncentivesPermission["read_incentive_level"] = "prisoner:incentives:incentive-level:read"; PrisonerIncentivesPermission["read_incentive_level_history"] = "prisoner:incentives:incentive-level-history:read"; })(PrisonerIncentivesPermission || (PrisonerIncentivesPermission = {})); // eslint-disable-next-line import/prefer-default-export const prisonerIncentivesPermissionPaths = { [PrisonerIncentivesPermission.read_incentive_level]: `domainGroups.prisonerSpecific.prisonerIncentives.${PrisonerIncentivesPermission.read_incentive_level}`, [PrisonerIncentivesPermission.read_incentive_level_history]: `domainGroups.prisonerSpecific.prisonerIncentives.${PrisonerIncentivesPermission.read_incentive_level_history}`, }; var PersonPrisonCategoryPermission; (function (PersonPrisonCategoryPermission) { PersonPrisonCategoryPermission["read"] = "prisoner:person-prison-category:read"; PersonPrisonCategoryPermission["edit"] = "prisoner:person-prison-category:edit"; })(PersonPrisonCategoryPermission || (PersonPrisonCategoryPermission = {})); // eslint-disable-next-line import/prefer-default-export const personPrisonCategoryPermissionPaths = { [PersonPrisonCategoryPermission.read]: `domainGroups.prisonerSpecific.personPrisonCategory.${PersonPrisonCategoryPermission.read}`, [PersonPrisonCategoryPermission.edit]: `domainGroups.prisonerSpecific.personPrisonCategory.${PersonPrisonCategoryPermission.edit}`, }; var PrisonerSchedulePermission; (function (PrisonerSchedulePermission) { PrisonerSchedulePermission["read_schedule"] = "prisoner:schedule:read"; PrisonerSchedulePermission["edit_appointment"] = "prisoner:appointment:edit"; PrisonerSchedulePermission["edit_activity"] = "prisoner:activity:edit"; })(PrisonerSchedulePermission || (PrisonerSchedulePermission = {})); // eslint-disable-next-line import/prefer-default-export const prisonerSchedulePermissionPaths = { [PrisonerSchedulePermission.read_schedule]: `domainGroups.prisonerSpecific.prisonerSchedule.${PrisonerSchedulePermission.read_schedule}`, [PrisonerSchedulePermission.edit_appointment]: `domainGroups.prisonerSpecific.prisonerSchedule.${PrisonerSchedulePermission.edit_appointment}`, [PrisonerSchedulePermission.edit_activity]: `domainGroups.prisonerSpecific.prisonerSchedule.${PrisonerSchedulePermission.edit_activity}`, }; var UseOfForcePermission; (function (UseOfForcePermission) { UseOfForcePermission["edit"] = "prisoner:use-of-force:edit"; })(UseOfForcePermission || (UseOfForcePermission = {})); // eslint-disable-next-line import/prefer-default-export const useOfForcePermissionPaths = { [UseOfForcePermission.edit]: `domainGroups.prisonerSpecific.useOfForce.${UseOfForcePermission.edit}`, }; var PrisonerAlertsPermission; (function (PrisonerAlertsPermission) { PrisonerAlertsPermission["edit"] = "prisoner:prisoner-alerts:edit"; })(PrisonerAlertsPermission || (PrisonerAlertsPermission = {})); // eslint-disable-next-line import/prefer-default-export const prisonerAlertsPermissionPaths = { [PrisonerAlertsPermission.edit]: `domainGroups.prisonerSpecific.prisonerAlerts.${PrisonerAlertsPermission.edit}`, }; var PrisonerSpecificRisksPermission; (function (PrisonerSpecificRisksPermission) { PrisonerSpecificRisksPermission["read_csra_rating"] = "prisoner:csra-rating:read"; PrisonerSpecificRisksPermission["read_csra_assessment_history"] = "prisoner:csra-assessment-history:read"; })(PrisonerSpecificRisksPermission || (PrisonerSpecificRisksPermission = {})); // eslint-disable-next-line import/prefer-default-export const prisonerSpecificRisksPermissionPaths = { [PrisonerSpecificRisksPermission.read_csra_rating]: `domainGroups.prisonerSpecific.prisonerSpecificRisks.${PrisonerSpecificRisksPermission.read_csra_rating}`, [PrisonerSpecificRisksPermission.read_csra_assessment_history]: `domainGroups.prisonerSpecific.prisonerSpecificRisks.${PrisonerSpecificRisksPermission.read_csra_assessment_history}`, }; // eslint-disable-next-line import/prefer-default-export const prisonerSpecificDomainPermissionPaths = { ...prisonerMoneyPermissionPaths, ...prisonerAdjudicationsPermissionPaths, ...prisonerIncentivesPermissionPaths, ...personPrisonCategoryPermissionPaths, ...prisonerSchedulePermissionPaths, ...useOfForcePermissionPaths, ...prisonerAlertsPermissionPaths, ...prisonerSpecificRisksPermissionPaths, }; // eslint-disable-next-line import/prefer-default-export const personSentenceCalculationPermissionPaths = { [PersonSentenceCalculationPermission.read]: `domainGroups.sentenceAndOffence.personSentenceCalculation.${PersonSentenceCalculationPermission.read}`, [PersonSentenceCalculationPermission.edit_adjustments]: `domainGroups.sentenceAndOffence.personSentenceCalculation.${PersonSentenceCalculationPermission.edit_adjustments}`, }; // eslint-disable-next-line import/prefer-default-export const sentenceAndOffenceDomainPermissionPaths = { ...personSentenceCalculationPermissionPaths, }; var PrisonerVisitsAndVisitorsPermission; (function (PrisonerVisitsAndVisitorsPermission) { PrisonerVisitsAndVisitorsPermission["read"] = "prisoner:prisoner-visits-and-visitors:read"; })(PrisonerVisitsAndVisitorsPermission || (PrisonerVisitsAndVisitorsPermission = {})); // eslint-disable-next-line import/prefer-default-export const prisonerVisitsAndVisitorsPermissionPaths = { [PrisonerVisitsAndVisitorsPermission.read]: `domainGroups.runningAPrison.prisonerVisitsAndVisitors.${PrisonerVisitsAndVisitorsPermission.read}`, }; var PrisonerBaseLocationPermission; (function (PrisonerBaseLocationPermission) { PrisonerBaseLocationPermission["read_location_details"] = "prisoner:location-details:read"; PrisonerBaseLocationPermission["read_location_history"] = "prisoner:location-history:read"; PrisonerBaseLocationPermission["move_cell"] = "prisoner:location-cell:edit"; })(PrisonerBaseLocationPermission || (PrisonerBaseLocationPermission = {})); // eslint-disable-next-line import/prefer-default-export const prisonerBaseLocationPermissionPaths = { [PrisonerBaseLocationPermission.read_location_details]: `domainGroups.runningAPrison.prisonerBaseLocation.${PrisonerBaseLocationPermission.read_location_details}`, [PrisonerBaseLocationPermission.read_location_history]: `domainGroups.runningAPrison.prisonerBaseLocation.${PrisonerBaseLocationPermission.read_location_history}`, [PrisonerBaseLocationPermission.move_cell]: `domainGroups.runningAPrison.prisonerBaseLocation.${PrisonerBaseLocationPermission.move_cell}`, }; var PrisonerMovesPermission; (function (PrisonerMovesPermission) { PrisonerMovesPermission["read_temporary_absence"] = "prisoner:temporary-absence:read"; PrisonerMovesPermission["edit_temporary_absence"] = "prisoner:temporary-absence:edit"; })(PrisonerMovesPermission || (PrisonerMovesPermission = {})); // eslint-disable-next-line import/prefer-default-export const prisonerMovesPermissionPaths = { [PrisonerMovesPermission.read_temporary_absence]: `domainGroups.runningAPrison.prisonerMoves.${PrisonerMovesPermission.read_temporary_absence}`, [PrisonerMovesPermission.edit_temporary_absence]: `domainGroups.runningAPrison.prisonerMoves.${PrisonerMovesPermission.edit_temporary_absence}`, }; // eslint-disable-next-line import/prefer-default-export const runningAPrisonDomainPermissionPaths = { ...prisonerVisitsAndVisitorsPermissionPaths, ...prisonerBaseLocationPermissionPaths, ...prisonerMovesPermissionPaths, }; var CaseNotesPermission; (function (CaseNotesPermission) { CaseNotesPermission["read"] = "prisoner:case-notes:read"; CaseNotesPermission["edit"] = "prisoner:case-notes:edit"; CaseNotesPermission["read_sensitive"] = "prisoner:case-notes:sensitive:read"; CaseNotesPermission["delete_sensitive"] = "prisoner:case-notes:sensitive:delete"; CaseNotesPermission["edit_sensitive"] = "prisoner:case-notes:sensitive:edit"; })(CaseNotesPermission || (CaseNotesPermission = {})); // eslint-disable-next-line import/prefer-default-export const caseNotesPermissionPaths = { [CaseNotesPermission.read]: `domainGroups.person.caseNotes.${CaseNotesPermission.read}`, [CaseNotesPermission.edit]: `domainGroups.person.caseNotes.${CaseNotesPermission.edit}`, [CaseNotesPermission.read_sensitive]: `domainGroups.person.caseNotes.${CaseNotesPermission.read_sensitive}`, [CaseNotesPermission.delete_sensitive]: `domainGroups.person.caseNotes.${CaseNotesPermission.delete_sensitive}`, [CaseNotesPermission.edit_sensitive]: `domainGroups.person.caseNotes.${CaseNotesPermission.edit_sensitive}`, }; var CorePersonRecordPermission; (function (CorePersonRecordPermission) { CorePersonRecordPermission["read_physical_characteristics"] = "prisoner:physical_characteristics:read"; CorePersonRecordPermission["edit_physical_characteristics"] = "prisoner:physical_characteristics:edit"; CorePersonRecordPermission["read_photo"] = "prisoner:photo:read"; CorePersonRecordPermission["edit_photo"] = "prisoner:photo:edit"; CorePersonRecordPermission["read_place_of_birth"] = "prisoner:place-of-birth:read"; CorePersonRecordPermission["edit_place_of_birth"] = "prisoner:place-of-birth:edit"; CorePersonRecordPermission["read_military_history"] = "prisoner:military-history:read"; CorePersonRecordPermission["edit_military_history"] = "prisoner:military-history:edit"; CorePersonRecordPermission["read_name_and_aliases"] = "prisoner:name-and-aliases:read"; CorePersonRecordPermission["edit_name_and_aliases"] = "prisoner:name-and-aliases:edit"; CorePersonRecordPermission["read_date_of_birth"] = "prisoner:date-of-birth:read"; CorePersonRecordPermission["edit_date_of_birth"] = "prisoner:date-of-birth:edit"; // (Prisoner's address) CorePersonRecordPermission["read_address"] = "prisoner:address:read"; CorePersonRecordPermission["edit_address"] = "prisoner:address:edit"; CorePersonRecordPermission["read_nationality"] = "prisoner:nationality:read"; CorePersonRecordPermission["edit_nationality"] = "prisoner:nationality:edit"; // (Such as PNC / CRO / NI number...) CorePersonRecordPermission["read_identifiers"] = "prisoner:identifiers:read"; CorePersonRecordPermission["edit_identifiers"] = "prisoner:identifiers:edit"; CorePersonRecordPermission["read_phone_numbers"] = "prisoner:phone-numbers:read"; CorePersonRecordPermission["edit_phone_numbers"] = "prisoner:phone-numbers:edit"; CorePersonRecordPermission["read_email_addresses"] = "prisoner:email-addresses:read"; CorePersonRecordPermission["edit_email_addresses"] = "prisoner:email-addresses:edit"; CorePersonRecordPermission["read_distinguishing_marks"] = "prisoner:distinguishing-marks:read"; CorePersonRecordPermission["edit_distinguishing_marks"] = "prisoner:distinguishing-marks:edit"; })(CorePersonRecordPermission || (CorePersonRecordPermission = {})); const basePath$4 = 'domainGroups.person.corePersonRecord'; // eslint-disable-next-line import/prefer-default-export const corePersonRecordPermissionPaths = { [CorePersonRecordPermission.read_physical_characteristics]: `${basePath$4}.${CorePersonRecordPermission.read_physical_characteristics}`, [CorePersonRecordPermission.edit_physical_characteristics]: `${basePath$4}.${CorePersonRecordPermission.edit_physical_characteristics}`, [CorePersonRecordPermission.read_photo]: `${basePath$4}.${CorePersonRecordPermission.read_photo}`, [CorePersonRecordPermission.edit_photo]: `${basePath$4}.${CorePersonRecordPermission.edit_photo}`, [CorePersonRecordPermission.read_place_of_birth]: `${basePath$4}.${CorePersonRecordPermission.read_place_of_birth}`, [CorePersonRecordPermission.edit_place_of_birth]: `${basePath$4}.${CorePersonRecordPermission.edit_place_of_birth}`, [CorePersonRecordPermission.read_military_history]: `${basePath$4}.${CorePersonRecordPermission.read_military_history}`, [CorePersonRecordPermission.edit_military_history]: `${basePath$4}.${CorePersonRecordPermission.edit_military_history}`, [CorePersonRecordPermission.read_name_and_aliases]: `${basePath$4}.${CorePersonRecordPermission.read_name_and_aliases}`, [CorePersonRecordPermission.edit_name_and_aliases]: `${basePath$4}.${CorePersonRecordPermission.edit_name_and_aliases}`, [CorePersonRecordPermission.read_date_of_birth]: `${basePath$4}.${CorePersonRecordPermission.read_date_of_birth}`, [CorePersonRecordPermission.edit_date_of_birth]: `${basePath$4}.${CorePersonRecordPermission.edit_date_of_birth}`, [CorePersonRecordPermission.read_address]: `${basePath$4}.${CorePersonRecordPermission.read_address}`, [CorePersonRecordPermission.edit_address]: `${basePath$4}.${CorePersonRecordPermission.edit_address}`, [CorePersonRecordPermission.read_nationality]: `${basePath$4}.${CorePersonRecordPermission.read_nationality}`, [CorePersonRecordPermission.edit_nationality]: `${basePath$4}.${CorePersonRecordPermission.edit_nationality}`, [CorePersonRecordPermission.read_identifiers]: `${basePath$4}.${CorePersonRecordPermission.read_identifiers}`, [CorePersonRecordPermission.edit_identifiers]: `${basePath$4}.${CorePersonRecordPermission.edit_identifiers}`, [CorePersonRecordPermission.read_phone_numbers]: `${basePath$4}.${CorePersonRecordPermission.read_phone_numbers}`, [CorePersonRecordPermission.edit_phone_numbers]: `${basePath$4}.${CorePersonRecordPermission.edit_phone_numbers}`, [CorePersonRecordPermission.read_email_addresses]: `${basePath$4}.${CorePersonRecordPermission.read_email_addresses}`, [CorePersonRecordPermission.edit_email_addresses]: `${basePath$4}.${CorePersonRecordPermission.edit_email_addresses}`, [CorePersonRecordPermission.read_distinguishing_marks]: `${basePath$4}.${CorePersonRecordPermission.read_distinguishing_marks}`, [CorePersonRecordPermission.edit_distinguishing_marks]: `${basePath$4}.${CorePersonRecordPermission.edit_distinguishing_marks}`, }; var PersonProtectedCharacteristicsPermission; (function (PersonProtectedCharacteristicsPermission) { PersonProtectedCharacteristicsPermission["read_sexual_orientation"] = "prisoner:sexual-orientation:read"; PersonProtectedCharacteristicsPermission["edit_sexual_orientation"] = "prisoner:sexual-orientation:edit"; PersonProtectedCharacteristicsPermission["read_religion_and_belief"] = "prisoner:religion-and-belief:read"; PersonProtectedCharacteristicsPermission["edit_religion_and_belief"] = "prisoner:religion-and-belief:edit"; PersonProtectedCharacteristicsPermission["read_ethnicity"] = "prisoner:ethnicity:read"; PersonProtectedCharacteristicsPermission["edit_ethnicity"] = "prisoner:ethnicity:edit"; })(PersonProtectedCharacteristicsPermission || (PersonProtectedCharacteristicsPermission = {})); const basePath$3 = 'domainGroups.person.personProtectedCharacteristics'; // eslint-disable-next-line import/prefer-default-export const personProtectedCharacteristicsPermissionPaths = { [PersonProtectedCharacteristicsPermission.read_sexual_orientation]: `${basePath$3}.${PersonProtectedCharacteristicsPermission.read_sexual_orientation}`, [PersonProtectedCharacteristicsPermission.edit_sexual_orientation]: `${basePath$3}.${PersonProtectedCharacteristicsPermission.edit_sexual_orientation}`, [PersonProtectedCharacteristicsPermission.read_religion_and_belief]: `${basePath$3}.${PersonProtectedCharacteristicsPermission.read_religion_and_belief}`, [PersonProtectedCharacteristicsPermission.edit_religion_and_belief]: `${basePath$3}.${PersonProtectedCharacteristicsPermission.edit_religion_and_belief}`, [PersonProtectedCharacteristicsPermission.read_ethnicity]: `${basePath$3}.${PersonProtectedCharacteristicsPermission.read_ethnicity}`, [PersonProtectedCharacteristicsPermission.edit_ethnicity]: `${basePath$3}.${PersonProtectedCharacteristicsPermission.edit_ethnicity}`, }; var PersonHealthAndMedicationPermission; (function (PersonHealthAndMedicationPermission) { PersonHealthAndMedicationPermission["read_pregnancy"] = "prisoner:pregnancy:read"; PersonHealthAndMedicationPermission["edit_pregnancy"] = "prisoner:pregnancy:edit"; PersonHealthAndMedicationPermission["read_diet"] = "prisoner:diet:read"; PersonHealthAndMedicationPermission["edit_diet"] = "prisoner:diet:edit"; PersonHealthAndMedicationPermission["read_smoker"] = "prisoner:smoker:read"; PersonHealthAndMedicationPermission["edit_smoker"] = "prisoner:smoker:edit"; })(PersonHealthAndMedicationPermission || (PersonHealthAndMedicationPermission = {})); const basePath$2 = 'domainGroups.person.personHealthAndMedication'; // eslint-disable-next-line import/prefer-default-export const personHealthAndMedicationPermissionPaths = { [PersonHealthAndMedicationPermission.read_pregnancy]: `${basePath$2}.${PersonHealthAndMedicationPermission.read_pregnancy}`, [PersonHealthAndMedicationPermission.edit_pregnancy]: `${basePath$2}.${PersonHealthAndMedicationPermission.edit_pregnancy}`, [PersonHealthAndMedicationPermission.read_diet]: `${basePath$2}.${PersonHealthAndMedicationPermission.read_diet}`, [PersonHealthAndMedicationPermission.edit_diet]: `${basePath$2}.${PersonHealthAndMedicationPermission.edit_diet}`, [PersonHealthAndMedicationPermission.read_smoker]: `${basePath$2}.${PersonHealthAndMedicationPermission.read_smoker}`, [PersonHealthAndMedicationPermission.edit_smoker]: `${basePath$2}.${PersonHealthAndMedicationPermission.edit_smoker}`, }; var PersonalRelationshipsPermission; (function (PersonalRelationshipsPermission) { PersonalRelationshipsPermission["read_number_of_children"] = "prisoner:number-of-children:read"; PersonalRelationshipsPermission["edit_number_of_children"] = "prisoner:number-of-children:edit"; PersonalRelationshipsPermission["read_domestic_status"] = "prisoner:domestic-status:read"; PersonalRelationshipsPermission["edit_domestic_status"] = "prisoner:domestic-status:edit"; // Next of kin & emergency contacts (via prisoner profile) // This needs a review once both the contacts service and the // profile edit have been rolled out wider: PersonalRelationshipsPermission["read_emergency_contacts"] = "prisoner:emergency-contacts:read"; PersonalRelationshipsPermission["edit_emergency_contacts"] = "prisoner:emergency-contacts:edit"; // All social and official contacts: PersonalRelationshipsPermission["read_contacts"] = "prisoner:contacts:read"; PersonalRelationshipsPermission["edit_contacts"] = "prisoner:contacts:edit"; PersonalRelationshipsPermission["edit_contact_restrictions"] = "prisoner:contact-restrictions:edit"; PersonalRelationshipsPermission["edit_contact_visit_approval"] = "prisoner:contact-visit-approval:edit"; })(PersonalRelationshipsPermission || (PersonalRelationshipsPermission = {})); const basePath$1 = 'domainGroups.person.personalRelationships'; // eslint-disable-next-line import/prefer-default-export const personalRelationshipsPermissionPaths = { [PersonalRelationshipsPermission.read_number_of_children]: `${basePath$1}.${PersonalRelationshipsPermission.read_number_of_children}`, [PersonalRelationshipsPermission.edit_number_of_children]: `${basePath$1}.${PersonalRelationshipsPermission.edit_number_of_children}`, [PersonalRelationshipsPermission.read_domestic_status]: `${basePath$1}.${PersonalRelationshipsPermission.read_domestic_status}`, [PersonalRelationshipsPermission.edit_domestic_status]: `${basePath$1}.${PersonalRelationshipsPermission.edit_domestic_status}`, [PersonalRelationshipsPermission.read_contacts]: `${basePath$1}.${PersonalRelationshipsPermission.read_contacts}`, [PersonalRelationshipsPermission.edit_contacts]: `${basePath$1}.${PersonalRelationshipsPermission.edit_contacts}`, [PersonalRelationshipsPermission.edit_contact_restrictions]: `${basePath$1}.${PersonalRelationshipsPermission.edit_contact_restrictions}`, [PersonalRelationshipsPermission.edit_contact_visit_approval]: `${basePath$1}.${PersonalRelationshipsPermission.edit_contact_visit_approval}`, [PersonalRelationshipsPermission.read_emergency_contacts]: `${basePath$1}.${PersonalRelationshipsPermission.read_emergency_contacts}`, [PersonalRelationshipsPermission.edit_emergency_contacts]: `${basePath$1}.${PersonalRelationshipsPermission.edit_emergency_contacts}`, }; // eslint-disable-next-line import/prefer-default-export const personDomainPermissionPaths = { ...caseNotesPermissionPaths, ...corePersonRecordPermissionPaths, ...personProtectedCharacteristicsPermissionPaths, ...personHealthAndMedicationPermissionPaths, ...personalRelationshipsPermissionPaths, }; var PathfinderPermission; (function (PathfinderPermission) { PathfinderPermission["read"] = "prisoner:pathfinder:read"; PathfinderPermission["edit"] = "prisoner:pathfinder:edit"; })(PathfinderPermission || (PathfinderPermission = {})); // eslint-disable-next-line import/prefer-default-export const pathfinderPermissionPaths = { [PathfinderPermission.read]: `domainGroups.security.pathfinder.${PathfinderPermission.read}`, [PathfinderPermission.edit]: `domainGroups.security.pathfinder.${PathfinderPermission.edit}`, }; var SOCPermission; (function (SOCPermission) { SOCPermission["read"] = "prisoner:soc:read"; SOCPermission["edit"] = "prisoner:soc:edit"; })(SOCPermission || (SOCPermission = {})); // eslint-disable-next-line import/prefer-default-export const socPermissionPaths = { [SOCPermission.read]: `domainGroups.security.soc.${SOCPermission.read}`, [SOCPermission.edit]: `domainGroups.security.soc.${SOCPermission.edit}`, }; // eslint-disable-next-line import/prefer-default-export const securityDomainPermissionPaths = { ...pathfinderPermissionPaths, ...socPermissionPaths, }; var ProbationDocumentsPermission; (function (ProbationDocumentsPermission) { ProbationDocumentsPermission["read"] = "prisoner:probation-documents:read"; })(ProbationDocumentsPermission || (ProbationDocumentsPermission = {})); // eslint-disable-next-line import/prefer-default-export const probationDocumentsPermissionPaths = { [ProbationDocumentsPermission.read]: `domainGroups.probation.probationDocuments.${ProbationDocumentsPermission.read}`, }; // eslint-disable-next-line import/prefer-default-export const probationDomainPermissionPaths = { ...probationDocumentsPermissionPaths, }; var PersonInterventionsPermission; (function (PersonInterventionsPermission) { PersonInterventionsPermission["read_csip"] = "prisoner:csip:read"; PersonInterventionsPermission["edit_csip"] = "prisoner:csip:edit"; })(PersonInterventionsPermission || (PersonInterventionsPermission = {})); // eslint-disable-next-line import/prefer-default-export const personInterventionsPermissionPaths = { [PersonInterventionsPermission.read_csip]: `domainGroups.interventions.personInterventions.${PersonInterventionsPermission.read_csip}`, [PersonInterventionsPermission.edit_csip]: `domainGroups.interventions.personInterventions.${PersonInterventionsPermission.edit_csip}`, }; // eslint-disable-next-line import/prefer-default-export const interventionsDomainPermissionPaths = { ...personInterventionsPermissionPaths, }; var PersonCommunicationNeedsPermission; (function (PersonCommunicationNeedsPermission) { PersonCommunicationNeedsPermission["read_language"] = "prisoner:language:read"; PersonCommunicationNeedsPermission["edit_language"] = "prisoner:language:edit"; })(PersonCommunicationNeedsPermission || (PersonCommunicationNeedsPermission = {})); const basePath = 'domainGroups.personPlanAndNeeds.personCommunicationNeeds'; // eslint-disable-next-line import/prefer-default-export const personCommunicationNeedsPermissionPaths = { [PersonCommunicationNeedsPermission.read_language]: `${basePath}.${PersonCommunicationNeedsPermission.read_language}`, [PersonCommunicationNeedsPermission.edit_language]: `${basePath}.${PersonCommunicationNeedsPermission.edit_language}`, }; // eslint-disable-next-line import/prefer-default-export const personPlanAndNeedsDomainPermissionPaths = { ...personCommunicationNeedsPermissionPaths, }; // eslint-disable-next-line import/prefer-default-export const prisonerPermissionPaths = { [PrisonerBasePermission.read]: PrisonerBasePermission.read, ...interventionsDomainPermissionPaths, ...personDomainPermissionPaths, ...personPlanAndNeedsDomainPermissionPaths, ...prisonerSpecificDomainPermissionPaths, ...probationDomainPermissionPaths, ...runningAPrisonDomainPermissionPaths, ...securityDomainPermissionPaths, ...sentenceAndOffenceDomainPermissionPaths, }; // eslint-disable-next-line import/prefer-default-export function isGranted(permission, permissions) { // @ts-expect-error TS cannot guarantee the path ends with a boolean return prisonerPermissionPaths[permission].split('.').reduce((o, key) => o && o[key], permissions || {}); } function isRequiredPermission(permission, requiredPermissions) { return requiredPermissions.includes(permission); } function logDeniedPermissionCheck(permission, context, status) { const { user, prisoner, baseCheckStatus, requestDependentOn, permissionsLogger } = context; const baseCheckPassed = baseCheckStatus === PermissionCheckStatus.OK; if (isRequiredPermission(permission, requestDependentOn)) { permissionsLogger.logPermissionCheckStatus(user, prisoner, permission, baseCheckPassed ? status : baseCheckStatus); } } const isActiveCaseLoad = (prisonId, user) => user.authSource === 'nomis' && user.activeCaseLoadId === prisonId; function isInUsersCaseLoad(prisonId, user) { return user.authSource === 'nomis' && user.caseLoads?.some(caseLoad => caseLoad.caseLoadId === prisonId); } const isReleased = (prisoner) => { return !!prisoner?.prisonId && ['OUT'].includes(prisoner.prisonId); }; const isTransferring = (prisoner) => { return !!prisoner?.prisonId && ['TRN'].includes(prisoner.prisonId); }; const wasReleasedWithinThreeYears = (prisoner) => { return (isReleased(prisoner) && !!prisoner.releaseDate && Date.parse(prisoner.releaseDate) > Date.now() - 3 * 365 * 24 * 60 * 60 * 1000); }; function userHasSomeRolesFrom(rolesToCheck, user) { return (rolesToCheck.length === 0 || rolesToCheck.map(normaliseRoleText).some(role => user.userRoles.map(normaliseRoleText).includes(role))); } function userHasAllRoles(rolesToCheck, user) { return rolesToCheck.map(normaliseRoleText).every(role => user.userRoles.map(normaliseRoleText).includes(role)); } const userHasRole = (roleToCheck, user) => { return userHasAllRoles([roleToCheck], user); }; const normaliseRoleText = (role) => role.replace(/ROLE_/, ''); function setPrisonerPermission(permission, permitted, permissions) { const result = structuredClone(permissions); const keys = prisonerPermissionPaths[permission].split('.'); const lastKey = keys.pop(); // @ts-expect-error TS cannot determine object type // eslint-disable-next-line no-return-assign,no-param-reassign const lastObj = keys.reduce((obj, key) => (obj[key] = obj[key] || {}), result); // @ts-expect-error TS cannot determine object type lastObj[lastKey] = permitted; return result; } function upgradePermissions(basePermissions, additionalPermissions) { return Object.keys(prisonerPermissionPaths).reduce((updatedPermissions, key) => { const permission = key; if (!isGranted(permission, basePermissions)) { const additionalPermissionGranted = isGranted(permission, additionalPermissions); return setPrisonerPermission(permission, additionalPermissionGranted, updatedPermissions); } return updatedPermissions; }, structuredClone(basePermissions)); } function getPermissionStatus(user, prisoner, conditions) { // Currently we always require that the user is a Prison User: if (user.authSource !== 'nomis') return PermissionCheckStatus.NOT_PRISON_USER; // Check if any blanket user roles are required: if (!userHasAdditionalRequiredRoles(user, conditions)) return PermissionCheckStatus.ROLE_NOT_PRESENT; // Check if there's an overriding condition that takes precedence: if (conditions.overridingCondition) return conditions.overridingCondition(user, prisoner); // Restricted patients: if (prisoner.restrictedPatient) return conditions.ifRestrictedPatient(user, prisoner); // Released prisoners: if (isReleased(prisoner)) return conditions.ifReleasedPrisoner(user, prisoner); // Transferring prisoners: if (isTransferring(prisoner)) return conditions.ifTransferringPrisoner(user, prisoner); // When prisoner is outside user's caseload: if (!isInUsersCaseLoad(prisoner.prisonId, user)) return conditions.ifPrisonNotInCaseload(user, prisoner); // When prisoner IS inside user's caseload: return conditions.ifPrisonInCaseload(user, prisoner); } function userHasAdditionalRequiredRoles(user, conditions) { if (conditions.allRolesRequired && !userHasAllRoles(conditions.allRolesRequired, user)) { return false; } if (conditions.atLeastOneRoleRequiredFrom && !userHasSomeRolesFrom(conditions.atLeastOneRoleRequiredFrom, user)) { return false; } return true; } /* * Restricted patients can be accessed in the following circumstances: * - The user has the "Inactive Bookings" role * - The user is a POM user and has the supporting prison ID in their caseloads */ function restrictedPatientStatus(user, prisoner) { const pomUser = userHasRole(Role.PomUser, user); const inactiveBookingsUser = userHasRole(Role.InactiveBookings, user); const userHasSupportingPrisonInTheirCaseLoad = isInUsersCaseLoad(prisoner.supportingPrisonId, user); const userIsPomUserWithSupportingPrisonInTheirCaseLoad = pomUser && userHasSupportingPrisonInTheirCaseLoad; if (userIsPomUserWithSupportingPrisonInTheirCaseLoad) return PermissionCheckStatus.OK; if (inactiveBookingsUser) return PermissionCheckStatus.OK; return PermissionCheckStatus.RESTRICTED_PATIENT; } /* * Released prisoners can be accessed in the following circumstances: * - The user has the "Inactive Bookings" role */ function releasedPrisonerStatus(user) { const inactiveBookingsUser = userHasRole(Role.InactiveBookings, user); if (inactiveBookingsUser) return PermissionCheckStatus.OK; return PermissionCheckStatus.PRISONER_IS_RELEASED; } /* * Transferring prisoners can be accessed in the following circumstances: * - The user has the "Global search" role * - The user has the "Inactive Bookings" role */ function transferringPrisonerStatus(user) { const inactiveBookingsUser = userHasRole(Role.InactiveBookings, user); const globalSearchUser = userHasSomeRolesFrom([Role.GlobalSearch], user); if (globalSearchUser) return PermissionCheckStatus.OK; if (inactiveBookingsUser) return PermissionCheckStatus.OK; return PermissionCheckStatus.PRISONER_IS_TRANSFERRING; } /* * Prisoners in prisons outside the user's caseload can be accessed in the following circumstances: * - The user has the "Global search" role */ function prisonNotInCaseLoadStatus(user) { const globalSearchUser = userHasSomeRolesFrom([Role.GlobalSearch], user); if (globalSearchUser) return PermissionCheckStatus.OK; return PermissionCheckStatus.NOT_IN_CASELOAD; } /* * The "default" access checks for accessing information about a prisoner. * * This function can be used for checking what we consider the "base checks" for accessing a page on the prisoner profile * when no other special cases are given. */ const baseCheckConditions = { ifRestrictedPatient: restrictedPatientStatus, ifReleasedPrisoner: releasedPrisonerStatus, ifTransferringPrisoner: transferringPrisonerStatus, ifPrisonNotInCaseload: prisonNotInCaseLoadStatus, ifPrisonInCaseload: () => PermissionCheckStatus.OK, }; const baseCheckStatus = (user, prisoner) => getPermissionStatus(user, prisoner, baseCheckConditions); const matchBaseCheckAnd = (additionalConditions) => (permission, context) => { const { user, prisoner, baseCheckStatus, readOnly } = context; const baseCheckPassed = baseCheckStatus === PermissionCheckStatus.OK; const readOnlyCheckPassed = readOnly ? permission.endsWith(':read') : true; const permissionStatus = readOnlyCheckPassed ? getPermissionStatus(user, prisoner, { ...baseCheckConditions, ...additionalConditions, }) : PermissionCheckStatus.READ_ONLY; const permissionCheckPassed = baseCheckPassed && permissionStatus === PermissionCheckStatus.OK; if (!permissionCheckPassed) logDeniedPermissionCheck(permission, context, permissionStatus); return permissionCheckPassed; }; const checkWith = (context) => (permission, check) => { return { [permission]: check(permission, context) }; }; const baseCheckAndUserHasAllRoles = (roles) => matchBaseCheckAnd({ allRolesRequired: roles }); const baseCheckAndUserHasRole = (role) => baseCheckAndUserHasAllRoles([role]); const sentenceCalculationReadCheck = baseCheckAndUserHasRole(Role.ReleaseDatesCalculator); const sentenceCalculationEditAdjustmentCheck = baseCheckAndUserHasRole(Role.AdjustmentsMaintainer); function personSentenceCalculationCheck(context) { const check = checkWith(context); return { ...check(PersonSentenceCalculationPermission.read, sentenceCalculationReadCheck), ...check(PersonSentenceCalculationPermission.edit_adjustments, sentenceCalculationEditAdjustmentCheck), }; } function sentenceAndOffenceCheck(context) { return { personSentenceCalculation: personSentenceCalculationCheck(context), }; } const baseCheck = matchBaseCheckAnd({}); const inUsersCaseLoad = matchBaseCheckAnd({ overridingCondition: (user, prisoner) => isInUsersCaseLoad(prisoner.prisonId, user) ? PermissionCheckStatus.OK : PermissionCheckStatus.NOT_IN_CASELOAD, }); const prisonerMoneyReadCheck = inUsersCaseLoad; function prisonerMoneyCheck(context) { const check = checkWith(context); return { ...check(PrisonerMoneyPermission.read, prisonerMoneyReadCheck), }; } const prisonerAdjudicationsReadCheck = matchBaseCheckAnd({ overridingCondition: (user, prisoner) => isInUsersCaseLoad(prisoner.prisonId, user) || userHasSomeRolesFrom([Role.PomUser, Role.ReceptionUser], user) ? PermissionCheckStatus.OK : PermissionCheckStatus.NOT_IN_CASELOAD, }); function prisonerAdjudicationsCheck(context) { const check = checkWith(context); return { ...check(PrisonerAdjudicationsPermission.read, prisonerAdjudicationsReadCheck), }; } const incentiveLevelHistoryReadCheck = matchBaseCheckAnd({ // Transferring prisoner incentive history can only be accessed by users with the Global Search role: ifTransferringPrisoner: user => userHasSomeRolesFrom([Role.GlobalSearch], user) ? PermissionCheckStatus.OK : PermissionCheckStatus.PRISONER_IS_TRANSFERRING, // Global search is not sufficient for incentive level history access: ifPrisonNotInCaseload: () => PermissionCheckStatus.NOT_IN_CASELOAD, }); function prisonerIncentivesCheck(context) { const check = checkWith(context); return { ...check(PrisonerIncentivesPermission.read_incentive_level, baseCheck), ...check(PrisonerIncentivesPermission.read_incentive_level_history, incentiveLevelHistoryReadCheck), }; } const baseCheckAndUserHasSomeRolesFrom = (roles) => matchBaseCheckAnd({ atLeastOneRoleRequiredFrom: roles }); const personPrisonCategoryEditCheck = baseCheckAndUserHasSomeRolesFrom([ Role.CreateCategorisation, Role.CreateRecategorisation, Role.ApproveCategorisation, Role.CategorisationSecurity, ]); function personPrisonCategoryCheck(context) { const check = checkWith(context); return { ...check(PersonPrisonCategoryPermission.read, baseCheck), ...check(PersonPrisonCategoryPermission.edit, personPrisonCategoryEditCheck), }; } const inActiveCaseLoadAndUserHasSomeRolesFrom = (roles) => matchBaseCheckAnd({ overridingCondition: (user, prisoner) => { if (!userHasSomeRolesFrom(roles, user)) return PermissionCheckStatus.ROLE_NOT_PRESENT; return isActiveCaseLoad(prisoner.prisonId, user) ? PermissionCheckStatus.OK : PermissionCheckStatus.NOT_ACTIVE_CASELOAD; }, }); const inActiveCaseLoad = inActiveCaseLoadAndUserHasSomeRolesFrom([]); const prisonerAppointmentEditCheck = inActiveCaseLoad; const prisonerActivityEditCheck = matchBaseCheckAnd({ overridingCondition: (user, prisoner) => { if (!userHasRole(Role.ActivityHub, user)) return PermissionCheckStatus.ROLE_NOT_PRESENT; if (!isActiveCaseLoad(prisoner.prisonId, user)) return PermissionCheckStatus.NOT_ACTIVE_CASELOAD; return PermissionCheckStatus.OK; }, }); function prisonerScheduleCheck(context) { const check = checkWith(context); return { ...check(PrisonerSchedulePermission.read_schedule, inUsersCaseLoad), ...check(PrisonerSchedulePermission.edit_appointment, prisonerAppointmentEditCheck), ...check(PrisonerSchedulePermission.edit_activity, prisonerActivityEditCheck), }; } const requiresInactiveBookingRole = (user) => userHasRole(Role.InactiveBookings, user) ? PermissionCheckStatus.OK : PermissionCheckStatus.NOT_IN_CASELOAD; const useOfForceEditCheck = matchBaseCheckAnd({ ifRestrictedPatient: () => PermissionCheckStatus.NOT_IN_CASELOAD, ifReleasedPrisoner: requiresInactiveBookingRole, ifTransferringPrisoner: requiresInactiveBookingRole, ifPrisonNotInCaseload: () => PermissionCheckStatus.NOT_IN_CASELOAD, ifPrisonInCaseload: () => PermissionCheckStatus.OK, }); function useOfForceCheck(context) { const check = checkWith(context); return { ...check(UseOfForcePermission.edit, useOfForceEditCheck), }; } const prisonerAlertsEditCheck = matchBaseCheckAnd({ atLeastOneRoleRequiredFrom: [Role.UpdateAlert], // For transferring prisoners, only the Inactive Bookings role is acceptable, // Global Search role is not sufficient: ifTransferringPrisoner: user => userHasRole(Role.InactiveBookings, user) ? PermissionCheckStatus.OK : PermissionCheckStatus.PRISONER_IS_TRANSFERRING, // Global search does NOT allow edit access to alerts for prisoners outside of user's caseload: ifPrisonNotInCaseload: () => PermissionCheckStatus.NOT_IN_CASELOAD, }); function prisonerAlertsCheck(context) { const check = checkWith(context); return { ...check(PrisonerAlertsPermission.edit, prisonerAlertsEditCheck), }; } const csraAssessmentHistoryReadCheck = matchBaseCheckAnd({ ifRestrictedPatient: () => PermissionCheckStatus.NOT_IN_CASELOAD, ifReleasedPrisoner: () => PermissionCheckStatus.NOT_IN_CASELOAD, ifPrisonNotInCaseload: () => PermissionCheckStatus.NOT_IN_CASELOAD, // The Inactive Bookings role is NOT sufficient to access CSRA history for transferring prisoners: ifTransferringPrisoner: user => userHasRole(Role.GlobalSearch, user) ? PermissionCheckStatus.OK : PermissionCheckStatus.PRISONER_IS_TRANSFERRING, ifPrisonInCaseload: () => PermissionCheckStatus.OK, }); function prisonerSpecificRisksCheck(context) { const check = checkWith(context); return { ...check(PrisonerSpecificRisksPermission.read_csra_rating, baseCheck), ...check(PrisonerSpecificRisksPermission.read_csra_assessment_history, csraAssessmentHistoryReadCheck), }; } function prisonerSpecificCheck(context) { return { prisonerMoney: prisonerMoneyCheck(context), prisonerAdjudications: prisonerAdjudicationsCheck(context), prisonerIncentives: prisonerIncentivesCheck(context), personPrisonCategory: personPrisonCategoryCheck(context), prisonerSchedule: prisonerScheduleCheck(context), useOfForce: useOfForceCheck(context), prisonerAlerts: prisonerAlertsCheck(context), prisonerSpecificRisks: prisonerSpecificRisksCheck(context), }; } const prisonerVisitsAndVisitorsReadCheck = inUsersCaseLoad; function prisonerVisitsAndVisitorsCheck(context) { const check = checkWith(context); return { ...check(PrisonerVisitsAndVisitorsPermission.read, prisonerVisitsAndVisitorsReadCheck), }; } const moveCellCheck = matchBaseCheckAnd({ atLeastOneRoleRequiredFrom: [Role.CellMove], // Global search access is not allowed: ifPrisonNotInCaseload: () => PermissionCheckStatus.NOT_IN_CASELOAD, }); const locationDetailsAndHistoryReadCheck = matchBaseCheckAnd({ // Global search access is not allowed: ifPrisonNotInCaseload: () => PermissionCheckStatus.NOT_IN_CASELOAD, }); function prisonerBaseLocationCheck(context) { const check = checkWith(context); return { ...check(PrisonerBaseLocationPermission.read_location_details, locationDetailsAndHistoryReadCheck), ...check(PrisonerBaseLocationPermission.read_location_history, locationDetailsAndHistoryReadCheck), ...check(PrisonerBaseLocationPermission.move_cell, moveCellCheck), }; } function prisonerMovesCheck(context) { const check = checkWith(context); return { ...check(PrisonerMovesPermission.read_temporary_absence, baseCheckAndUserHasSomeRolesFrom([ Role.ExternalMovementsTemporaryAbsenceViewOnly, Role.ExternalMovementsTemporaryAbsenceManagement, ])), ...check(PrisonerMovesPermission.edit_temporary_absence, baseCheckAndUserHasRole(Role.ExternalMovementsTemporaryAbsenceManagement)), }; } function runningAPrisonCheck(context) { return { prisonerVisitsAndVisitors: prisonerVisitsAndVisitorsCheck(context), prisonerBaseLocation: prisonerBaseLocationCheck(context), prisonerMoves: prisonerMovesCheck(context), }; } function daysToMilliseconds(days) { return days * 24 * 60 * 60 * 1000; } function isDateWithinBounds(dateToCheckInMs, upperDateBoundInMs, lowerDateBoundInMs) { return dateToCheckInMs <= upperDateBoundInMs && lowerDateBoundInMs <= dateToCheckInMs; } const caseNotesAccessPeriodPostTransferInMs = daysToMilliseconds(90); const caseNotesReadAndEditConditions = { ifTransferringPrisoner: user => { return userHasRole(Role.InactiveBookings, user) ? PermissionCheckStatus.OK : PermissionCheckStatus.PRISONER_IS_TRANSFERRING; }, ifPrisonNotInCaseload: (user, prisoner) => { if (!userHasAllRoles([Role.GlobalSearch, Role.PomUser], user))