Skip to content

Commit da48beb

Browse files
Merge pull request #8: require recipient confirmation before report send
Require recipient confirmation before sending a detailed report
2 parents b4f8b4f + f34744a commit da48beb

2 files changed

Lines changed: 16 additions & 0 deletions

File tree

‎integrations/wordpress/ct-scan.php‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1242,6 +1242,10 @@ function ct_scan_admin_send_report( $job_id ) {
12421242
|| '' === trim( (string) $row->manual_remainder_notes ) ) {
12431243
return new WP_Error( 'report_not_ready', 'Complete and review the manual remainder before sending.' );
12441244
}
1245+
// Detailed findings go only to a recipient who confirmed the request, whatever the terminal state.
1246+
if ( empty( $row->confirmed_at ) ) {
1247+
return new WP_Error( 'report_recipient_unconfirmed', 'The recipient never confirmed this request. Detailed findings cannot be sent.' );
1248+
}
12451249
if ( ! is_email( $row->contact_email )
12461250
|| ct_scan_meta_string( (int) $row->request_id, '_ct_scan_email' ) !== $row->contact_email
12471251
|| ct_scan_meta_string( (int) $row->request_id, '_ct_terms_version' ) !== $row->terms_version

‎integrations/wordpress/tests/integration.php‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,10 +180,22 @@ function ct_test_queue_job( $job_id ) {
180180
ct_test_assert( is_wp_error( ct_scan_admin_save_manual_remainder( $event['job_id'], 'Edited after send' ) ), 'Report details must freeze after a send attempt.' );
181181
ct_test_assert( true === ct_scan_admin_record_delivery( $event['job_id'] ), 'Independently confirmed delivery did not persist.' );
182182

183+
// An expired, never-confirmed request cannot receive detailed findings, even after manual review.
184+
list( $unconfirmed_id, $unconfirmed_fields ) = ct_test_request( 'unconfirmed-report-fixture.example.net' );
185+
$request_ids[] = $unconfirmed_id;
186+
$unconfirmed_event = ct_scan_on_request_ready( $unconfirmed_id, $unconfirmed_fields );
187+
$wpdb->update( $jobs, array( 'status' => 'expired', 'error_code' => 'confirmation_expired', 'finished_at' => ct_scan_utc_now(), 'confirmation_token_hash' => null ), array( 'job_id' => (int) $unconfirmed_event['job_id'] ) );
188+
ct_test_assert( true === ct_scan_admin_save_manual_remainder( $unconfirmed_event['job_id'], 'Operator notes entered after expiry.' ), 'Unconfirmed fixture manual notes failed.' );
189+
$mail_count = count( $mail_calls );
190+
$unconfirmed_send = ct_scan_admin_send_report( $unconfirmed_event['job_id'] );
191+
ct_test_assert( is_wp_error( $unconfirmed_send ) && 'report_recipient_unconfirmed' === $unconfirmed_send->get_error_code(), 'An unconfirmed recipient was allowed a detailed report.' );
192+
ct_test_assert( count( $mail_calls ) === $mail_count && 'not_sent' === ct_scan_row( $unconfirmed_event['job_id'] )->report_notification_status, 'A refused unconfirmed report must not send or change send state.' );
193+
183194
// Unknown mail outcomes remain one-shot; independently confirmed delivery can still be recorded.
184195
list( $unknown_id, $unknown_fields ) = ct_test_request( 'unknown-mail-fixture.example.net' );
185196
$request_ids[] = $unknown_id;
186197
$unknown_event = ct_scan_on_request_ready( $unknown_id, $unknown_fields );
198+
ct_test_queue_job( $unknown_event['job_id'] );
187199
$wpdb->update( $jobs, array( 'status' => 'failed', 'finished_at' => ct_scan_utc_now() ), array( 'job_id' => (int) $unknown_event['job_id'] ) );
188200
ct_test_assert( true === ct_scan_admin_save_manual_remainder( $unknown_event['job_id'], 'No remaining work was performed in this fixture.' ), 'Unknown-mail fixture manual notes failed.' );
189201
$mail_mode = false;

0 commit comments

Comments
 (0)