For whoever stumbles on this, the issue was exactly in the FileContentTypes. Every type that should be forced to download should have a "+" in front, which I did not have. So, this is the correct setup in config.php (for my case):
$config->fileContentTypes = array(
'?' => '+application/octet-stream',
'txt' => '+text/plain',
'csv' => '+text/csv',
'pdf' => '+application/pdf',
'doc' => '+application/msword',
'docx' => '+application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'xls' => '+application/vnd.ms-excel',
'xlsx' => '+application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'ppt' => '+application/vnd.ms-powerpoint',
'pptx' => '+application/vnd.openxmlformats-officedocument.presentationml.presentation',
'rtf' => '+application/rtf',
'gif' => '+image/gif',
'jpg' => '+image/jpeg',
'jpeg' => '+image/jpeg',
'png' => '+image/png',
'svg' => '+image/svg+xml',
'webp' => '+image/webp',
'zip' => '+application/zip',
'mp3' => '+audio/mpeg',
);
In addition, I wanted to use original file names, not the ones that Processwire creates when uploading files. This modification to Zeka's code manages that through html_entity_decode:
if($input->urlSegment1 == 'download') {
if($input->urlSegment2) {
$names = array();
$urls = array();
$originalNames = array();
foreach ($page->handoff_files as $handoff_file_repeater) {
$file = $handoff_file_repeater->file;
$original_name_unencoded = html_entity_decode($file->uploadName);
array_push($names, $file->name);
array_push($urls, $file->filename);
array_push($originalNames, $original_name_unencoded);
}
$key = array_search($input->urlSegment2, $names);
if($key !== false) {
wireSendFile($urls[$key], [
"downloadFilename" => $originalNames[$key],
]);
} else {
throw new Wire404Exception();
}
}
} else if($input->urlSegment1) {
// unknown URL segment, send a 404
throw new Wire404Exception();
}
foreach ($page->handoff_files as $handoff_file_repeater){
$file = $handoff_file_repeater->file;
$fileSizeInBytes = $files->size($file->filename);
$formattedSize = formatFileSize($fileSizeInBytes);
$original_name_unencoded = html_entity_decode($file->uploadName);
?>
<div class="file-block">
<div class="file-info">
<h3><?=$original_name_unencoded;?></h3>
<p><?=$formattedSize;?></p>
</div>
<!--<a href="<?=$file->url;?>" download="<?=$original_name_unencoded;?>" class="download-button">download</a>-->
<a href="<?= 'download/'.$file->name; ?>" download="<?=$original_name_unencoded?>" class="download-button">download</a>
</div>
<?php
}
?>