Skip to content

Commit

Permalink
Fix handling of verification of Enrollee Email Address (CFM-333)
Browse files Browse the repository at this point in the history
  • Loading branch information
Benn Oshrin committed Aug 29, 2025
1 parent d739d25 commit 2b32421
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public function dispatch(string $id) {
comment: $comment
);

if($approved == StatusEnum::Denied) {
if($approved != StatusEnum::Approved) {
// If we have a denial Message Template, send the notification to the enrollee
// email address. We don't currently support using a Notification, since in most
// cases the Enrollee will not have a Person record yet. (There are some edge
Expand Down
67 changes: 51 additions & 16 deletions app/plugins/CoreEnroller/src/Model/Table/EmailVerifiersTable.php
Original file line number Diff line number Diff line change
Expand Up @@ -216,26 +216,61 @@ public function assembleVerifiableAddresses(

if(!$verified) {
// We can consider this address verified if there was a transition _to_ a Step
// with an Enrollee actor no later than the current Step.
// with an Enrollee actor no later than the current Step. In order to allow this
// we need to confirm that the Petitioner is not also the Enrollee. We can't rely
// on the Enrollment Flow Petitioner Authorization because for any possible setting
// the Enrollee could also be the Petitioner (eg: Additional Role Enrollment,
// Account Linking, etc).

// We can definitively compare petitioner_identifier with enrollee_identifier
// (if both are set) or petitioner_person_id and enrollee_person_id (if both
// are set), or if neither petitioner value is set (unauthenticated enrollments
// are presumed to be self signups).

// We default to the initial Actor being Enrollee to require an Actor flip
// if we can't otherwise determine that the Petitioner is the Enrollee.
$lastActor = EnrollmentActorEnum::Enrollee;

// We basically look to see if we can confirm the Petitioner is _not_ the
// Enrollee, and if we can then we flip $lastActor to Petitioner.

if(!empty($petition->petitioner_person_id)) {
// This Petitioner is an authenticated, registered Person, and is not
// the Enrollee.

if(empty($petition->enrollee_person_id)
|| $petition->petitioner_person_id != $petition->enrollee_person_id) {
$lastActor = EnrollmentActorEnum::Petitioner;
}

foreach($steps as $step) {
if($step->status == SuspendableStatusEnum::Active
&& $step->actor_type == EnrollmentActorEnum::Enrollee) {
$this->llog('debug', "Flagging " . $petition->enrollee_email . " as verified via Handoff");
// There could potentially be other scenarios, but currently the above is
// the only one we can confirm.
}

$ret[ $petition->enrollee_email ] = $PetitionVerifications->verifyFromHandoff(
$petition->id,
$emailVerifier->enrollment_flow_step_id,
$petition->enrollee_email
);
$petitionerIsEnrollee = false;

$verified = true;
break;
}
foreach($steps as $step) {
if($step->status == SuspendableStatusEnum::Active) {
if($lastActor != EnrollmentActorEnum::Enrollee
&& $step->actor_type == EnrollmentActorEnum::Enrollee) {
$this->llog('debug', "Flagging " . $petition->enrollee_email . " as verified via Handoff");

$ret[ $petition->enrollee_email ] = $PetitionVerifications->verifyFromHandoff(
$petition->id,
$emailVerifier->enrollment_flow_step_id,
$petition->enrollee_email
);

$verified = true;
break;

if($step->id == $emailVerifier->enrollment_flow_step_id) {
// Don't check future Steps
break;
}
}

if($step->id == $emailVerifier->enrollment_flow_step_id) {
// Don't check future Steps
break;
$lastActor = $step->actor_type;
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion app/src/Controller/EnrollmentFlowsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ public function start(string $id) {
$actor = $this->getCurrentActor();

if($this->request->is(['post', 'put'])) {
// We should now have an enrollee email, so we can create the Pettion.
// We should now have an enrollee email, so we can create the Petition.
// Saving the entity should syntactically validate the email address.

$petition = $this->EnrollmentFlows->Petitions->start(
Expand Down

0 comments on commit 2b32421

Please sign in to comment.