summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpolo <ordipolo@gmx.fr>2026-01-05 22:40:48 +0100
committerpolo <ordipolo@gmx.fr>2026-01-05 22:40:48 +0100
commit0ad85125a52a01dbce5d8cb4a02730872e403906 (patch)
tree647c58e4520a0c93b8d80bf53edc47a14ca6b9fc
parent5d87ee20d0d34ba676b10b5f67f4251428e1f2f7 (diff)
downloadtinymce-0ad85125a52a01dbce5d8cb4a02730872e403906.tar.gz
tinymce-0ad85125a52a01dbce5d8cb4a02730872e403906.tar.bz2
tinymce-0ad85125a52a01dbce5d8cb4a02730872e403906.zip
sécurisation du code
-rw-r--r--public/index.php88
1 files changed, 51 insertions, 37 deletions
diff --git a/public/index.php b/public/index.php
index f46b384..c81728a 100644
--- a/public/index.php
+++ b/public/index.php
@@ -271,8 +271,12 @@ elseif(isset($_GET['action']) && $_GET['action'] == 'upload_file'){
271 271
272 function openEditor(article_id){ 272 function openEditor(article_id){
273 // Récupérer et sauvegarder le contenu d'origine de l'article 273 // Récupérer et sauvegarder le contenu d'origine de l'article
274 const articleContent = document.getElementById(article_id).innerHTML; 274 const element = document.getElementById(article_id);
275 document.getElementById(article_id).setAttribute('data-original-content', articleContent); 275 if (!element) {
276 return;
277 }
278 const articleContent = element.innerHTML;
279 element.setAttribute('data-original-content', articleContent);
276 280
277 tinymce.init({ 281 tinymce.init({
278 selector: `#${article_id}`, 282 selector: `#${article_id}`,
@@ -306,12 +310,11 @@ elseif(isset($_GET['action']) && $_GET['action'] == 'upload_file'){
306 }); 310 });
307 let skipPastePreProcess = false; 311 let skipPastePreProcess = false;
308 editor.on('Paste', function (e){ // déclenchement AVANT PastePreProcess et quelque que soit le contenu collé 312 editor.on('Paste', function (e){ // déclenchement AVANT PastePreProcess et quelque que soit le contenu collé
309 const clipboardData = (e.clipboardData || e.originalEvent.clipboardData); 313 if (!e.clipboardData) { // e.clipboardData: DataTransfer
310 if(!clipboardData){
311 return; 314 return;
312 } 315 }
313 const items = clipboardData.items; // base64 316 const items = e.clipboardData.items; // base64
314 const files = clipboardData.files; // explorateur de fichiers 317 const files = e.clipboardData.files; // explorateur de fichiers
315 let found_file = false; 318 let found_file = false;
316 319
317 // données dans files 320 // données dans files
@@ -319,7 +322,7 @@ elseif(isset($_GET['action']) && $_GET['action'] == 'upload_file'){
319 for(let i = 0; i < files.length; i++){ 322 for(let i = 0; i < files.length; i++){
320 let file = files[i]; 323 let file = files[i];
321 324
322 if(extensions_white_list.includes(file.name.split('.').pop().toLowerCase())){ 325 if(extensions_white_list.includes(file.name.split('.').pop()?.toLowerCase() || '')){
323 found_file = true; 326 found_file = true;
324 uploadDocument(file, editor); 327 uploadDocument(file, editor);
325 } 328 }
@@ -337,7 +340,12 @@ elseif(isset($_GET['action']) && $_GET['action'] == 'upload_file'){
337 if(item.type.indexOf('image') !== -1){ // test type MIME contenant image 340 if(item.type.indexOf('image') !== -1){ // test type MIME contenant image
338 found_file = true; 341 found_file = true;
339 const file = item.getAsFile(); // presse-papier => fichier lisible 342 const file = item.getAsFile(); // presse-papier => fichier lisible
340 uploadImageBase64(file, editor); 343 if(file){
344 uploadImageBase64(file, editor);
345 }
346 else{
347 console.error('fichier invalide');
348 }
341 } 349 }
342 } 350 }
343 } 351 }
@@ -406,7 +414,7 @@ elseif(isset($_GET['action']) && $_GET['action'] == 'upload_file'){
406 414
407 let has_documents = false; 415 let has_documents = false;
408 for(let i = 0; i < files.length; i++){ 416 for(let i = 0; i < files.length; i++){
409 if(extensions_white_list.includes(files[i].name.split('.').pop().toLowerCase())){ 417 if(extensions_white_list.includes(files[i].name.split('.').pop()?.toLowerCase() || '')){
410 has_documents = true; 418 has_documents = true;
411 break; 419 break;
412 } 420 }
@@ -419,7 +427,7 @@ elseif(isset($_GET['action']) && $_GET['action'] == 'upload_file'){
419 for(let i = 0; i < files.length; i++){ 427 for(let i = 0; i < files.length; i++){
420 let file = files[i]; 428 let file = files[i];
421 429
422 if(extensions_white_list.includes(file.name.split('.').pop().toLowerCase())){ 430 if(extensions_white_list.includes(file.name.split('.').pop()?.toLowerCase() || '')){
423 uploadDocument(file, editor); 431 uploadDocument(file, editor);
424 } 432 }
425 else if(file.type.indexOf('image') !== -1){ 433 else if(file.type.indexOf('image') !== -1){
@@ -435,25 +443,25 @@ elseif(isset($_GET['action']) && $_GET['action'] == 'upload_file'){
435 // upload de documents avec le bouton "insérer un lien" 443 // upload de documents avec le bouton "insérer un lien"
436 files_upload_handler: files_upload_handler, // = fonction fléchée 444 files_upload_handler: files_upload_handler, // = fonction fléchée
437 documents_file_types: [ // files_upload_handler a besoin qu'on lui donne tous les types mime 445 documents_file_types: [ // files_upload_handler a besoin qu'on lui donne tous les types mime
438 { mimeType: 'application/pdf', extensions: [ 'pdf' ] }, 446 { mimeType: 'application/pdf', extensions: [ 'pdf' ] },
439 { mimeType: 'application/rtf', extensions: [ 'rtf' ] }, 447 { mimeType: 'application/rtf', extensions: [ 'rtf' ] },
440 { mimeType: 'application/msword', extensions: [ 'doc' ] }, 448 { mimeType: 'application/msword', extensions: [ 'doc' ] },
441 { mimeType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', extensions: [ 'docx' ] }, 449 { mimeType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', extensions: [ 'docx' ] },
442 { mimeType: 'application/vnd.ms-excel', extensions: [ 'xls' ] }, 450 { mimeType: 'application/vnd.ms-excel', extensions: [ 'xls' ] },
443 { mimeType: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', extensions: [ 'xlsx' ] }, 451 { mimeType: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', extensions: [ 'xlsx' ] },
444 { mimeType: 'application/vnd.ms-powerpoint', extensions: [ 'ppt' ] }, 452 { mimeType: 'application/vnd.ms-powerpoint', extensions: [ 'ppt' ] },
445 { mimeType: 'application/vnd.openxmlformats-officedocument.presentationml.presentation', extensions: [ 'pptx' ] }, 453 { mimeType: 'application/vnd.openxmlformats-officedocument.presentationml.presentation', extensions: [ 'pptx' ] },
446 { mimeType: 'application/vnd.oasis.opendocument.text', extensions: [ 'odt' ] }, 454 { mimeType: 'application/vnd.oasis.opendocument.text', extensions: [ 'odt' ] },
447 { mimeType: 'application/vnd.oasis.opendocument.spreadsheet', extensions: [ 'ods' ] }, 455 { mimeType: 'application/vnd.oasis.opendocument.spreadsheet', extensions: [ 'ods' ] },
448 { mimeType: 'application/vnd.oasis.opendocument.presentation', extensions: [ 'odp' ] } 456 { mimeType: 'application/vnd.oasis.opendocument.presentation', extensions: [ 'odp' ] }
449 ], 457 ],
450 image_caption: true 458 image_caption: true
451 }); 459 });
452 460
453 // Remplacer le contenu de l'article par l'éditeur 461 // Remplacer le contenu de l'article par l'éditeur
454 document.getElementById(article_id).innerHTML = articleContent; 462 element.innerHTML = articleContent;
455 } 463 }
456 464
457 const images_upload_handler = (blobInfo, progress) => new Promise((resolve, reject) => { 465 const images_upload_handler = (blobInfo, progress) => new Promise((resolve, reject) => {
458 const formData = new FormData(); 466 const formData = new FormData();
459 formData.append("file", blobInfo.blob()); 467 formData.append("file", blobInfo.blob());
@@ -465,7 +473,7 @@ elseif(isset($_GET['action']) && $_GET['action'] == 'upload_file'){
465 .then(response => response.json()) 473 .then(response => response.json())
466 .then(data => { 474 .then(data => {
467 if(data.location){ 475 if(data.location){
468 resolve({url: data.location}); 476 resolve(data.location);
469 } 477 }
470 else{ 478 else{
471 reject("Erreur: Chemin d'image invalide"); 479 reject("Erreur: Chemin d'image invalide");
@@ -475,7 +483,6 @@ elseif(isset($_GET['action']) && $_GET['action'] == 'upload_file'){
475 reject("Erreur lors de l'upload"); 483 reject("Erreur lors de l'upload");
476 }); 484 });
477 }); 485 });
478
479 const files_upload_handler = (blobInfo, progress) => new Promise((resolve, reject) => { // utilisation = bouton "link" (OU drag & drop, et oui) 486 const files_upload_handler = (blobInfo, progress) => new Promise((resolve, reject) => { // utilisation = bouton "link" (OU drag & drop, et oui)
480 const formData = new FormData(); 487 const formData = new FormData();
481 formData.append("file", blobInfo.blob()); 488 formData.append("file", blobInfo.blob());
@@ -520,7 +527,7 @@ elseif(isset($_GET['action']) && $_GET['action'] == 'upload_file'){
520 if (data.success) { 527 if (data.success) {
521 // Supprimer l'article du DOM 528 // Supprimer l'article du DOM
522 const articleElement = document.getElementById(article_id); 529 const articleElement = document.getElementById(article_id);
523 articleElement.parentElement.remove(); 530 articleElement?.parentElement?.remove();
524 } 531 }
525 else { 532 else {
526 alert('Erreur lors de la suppression de l\'article.'); 533 alert('Erreur lors de la suppression de l\'article.');
@@ -531,17 +538,20 @@ elseif(isset($_GET['action']) && $_GET['action'] == 'upload_file'){
531 }); 538 });
532 } 539 }
533 } 540 }
534
535 function closeEditor(article_id){ 541 function closeEditor(article_id){
536 // Récupérer le contenu d'origine de l'article 542 // Récupérer le contenu d'origine de l'article
537 const originalContent = document.getElementById(article_id).getAttribute('data-original-content'); 543 const element = document.getElementById(article_id);
544 if(!element){
545 return;
546 }
547 const originalContent = element.getAttribute('data-original-content');
538 548
539 // Fermer l'éditeur 549 // Fermer l'éditeur
540 tinymce.remove(`#${article_id}`); 550 tinymce.remove(`#${article_id}`);
541 delete editors[article_id]; 551 delete editors[article_id];
542 552
543 // Restaurer le contenu d'origine de l'article 553 // Restaurer le contenu d'origine de l'article
544 document.getElementById(article_id).innerHTML = originalContent; 554 element.innerHTML = originalContent ?? '';
545 555
546 // Afficher le bouton "Modifier" et masquer les boutons "Annuler" et "Soumettre" 556 // Afficher le bouton "Modifier" et masquer les boutons "Annuler" et "Soumettre"
547 document.querySelector(`#edit-${article_id}`).classList.remove('hidden'); 557 document.querySelector(`#edit-${article_id}`).classList.remove('hidden');
@@ -549,11 +559,11 @@ elseif(isset($_GET['action']) && $_GET['action'] == 'upload_file'){
549 document.querySelector(`#cancel-${article_id}`).classList.add('hidden'); 559 document.querySelector(`#cancel-${article_id}`).classList.add('hidden');
550 document.querySelector(`#submit-${article_id}`).classList.add('hidden'); 560 document.querySelector(`#submit-${article_id}`).classList.add('hidden');
551 } 561 }
552
553 function submitArticle(article_id) { 562 function submitArticle(article_id) {
554 // Récupérer l'éditeur correspondant à l'article 563 // Récupérer l'éditeur correspondant à l'article
555 const editor = editors[article_id]; 564 const editor = editors[article_id];
556 if(!editor){ 565 const element = document.getElementById(article_id);
566 if(!editor || !element){
557 console.error('Éditeur non trouvé pour l\'article:', article_id); 567 console.error('Éditeur non trouvé pour l\'article:', article_id);
558 return; 568 return;
559 } 569 }
@@ -571,14 +581,14 @@ elseif(isset($_GET['action']) && $_GET['action'] == 'upload_file'){
571 }) 581 })
572 .then(response => response.json()) 582 .then(response => response.json())
573 .then(data => { 583 .then(data => {
574 // Fermer l'éditeur et mettre à jour le contenu de l'article 584 // Fermer l'éditeur et mettre à jour le contenu de l'article
575 closeEditor(article_id); 585 closeEditor(article_id);
576 document.getElementById(article_id).innerHTML = newContent; 586 element.innerHTML = newContent;
577 //console.log(newContent); 587 //console.log(newContent);
578 if(data.success){ 588 if(data.success){
579 // Fermer l'éditeur et mettre à jour le contenu de l'article 589 // Fermer l'éditeur et mettre à jour le contenu de l'article
580 tinymce.remove(`#${article_id}`); 590 tinymce.remove(`#${article_id}`);
581 document.getElementById(article_id).innerHTML = newContent; 591 element.innerHTML = newContent;
582 } 592 }
583 else{ 593 else{
584 alert('Erreur lors de la sauvegarde de l\'article.'); 594 alert('Erreur lors de la sauvegarde de l\'article.');
@@ -593,12 +603,16 @@ elseif(isset($_GET['action']) && $_GET['action'] == 'upload_file'){
593 const reader = new FileReader(); 603 const reader = new FileReader();
594 604
595 reader.onload = function (event){ // fonction exécutée lorsque reader.readAsDataURL(file) est terminée 605 reader.onload = function (event){ // fonction exécutée lorsque reader.readAsDataURL(file) est terminée
596 const base64 = event.target.result; // données de l'image 606 const base64_target = event.target;
607 if(!base64_target || !base64_target.result){
608 console.error("erreur de lecture du fichier");
609 return;
610 }
597 611
598 fetch('index.php?action=upload_image_base64', { 612 fetch('index.php?action=upload_image_base64', {
599 method: 'POST', 613 method: 'POST',
600 headers: { 'Content-Type': 'application/json' }, 614 headers: { 'Content-Type': 'application/json' },
601 body: JSON.stringify({ image_base64: base64 }) 615 body: JSON.stringify({ image_base64: base64_target.result })
602 }) 616 })
603 .then(response => response.json()) 617 .then(response => response.json())
604 .then(data => { 618 .then(data => {
@@ -625,7 +639,7 @@ elseif(isset($_GET['action']) && $_GET['action'] == 'upload_file'){
625 if(data.location){ 639 if(data.location){
626 // créer le lien <a> 640 // créer le lien <a>
627 const file_name = file.name; 641 const file_name = file.name;
628 const extension = file_name.split('.').pop().toLowerCase(); 642 const extension = file_name.split('.').pop()?.toLowerCase() || '';
629 const target = extension === 'pdf' ? 'target="_blank"' : ''; // PDF = page 643 const target = extension === 'pdf' ? 'target="_blank"' : ''; // PDF = page
630 editor.insertContent(`<a href="${data.location}" ${target} title="${file_name}">[${extension}] ${file_name}</a>`); 644 editor.insertContent(`<a href="${data.location}" ${target} title="${file_name}">[${extension}] ${file_name}</a>`);
631 } 645 }