<?php
/**
 * @version $Id$
 * @author Thomas Crespin <thomas.crespin@sesamath.net>
 * @copyright Thomas Crespin 2009-2022
 * 
 * ****************************************************************************************************
 * SACoche <https://sacoche.sesamath.net> - Suivi d’Acquisitions de Compétences
 * © Thomas Crespin pour Sésamath <https://www.sesamath.net> - Tous droits réservés.
 * Logiciel placé sous la licence libre Affero GPL 3 <https://www.gnu.org/licenses/agpl-3.0.html>.
 * ****************************************************************************************************
 * 
 * Ce fichier est une partie de SACoche.
 * 
 * SACoche est un logiciel libre ; vous pouvez le redistribuer ou le modifier suivant les termes 
 * de la “GNU Affero General Public License” telle que publiée par la Free Software Foundation :
 * soit la version 3 de cette licence, soit (à votre gré) toute version ultérieure.
 * 
 * SACoche est distribué dans l’espoir qu’il vous sera utile, mais SANS AUCUNE GARANTIE :
 * sans même la garantie implicite de COMMERCIALISABILITÉ ni d’ADÉQUATION À UN OBJECTIF PARTICULIER.
 * Consultez la Licence Publique Générale GNU Affero pour plus de détails.
 * 
 * Vous devriez avoir reçu une copie de la Licence Publique Générale GNU Affero avec SACoche ;
 * si ce n’est pas le cas, consultez : <http://www.gnu.org/licenses/>.
 * 
 */

if(!defined('SACoche')) {exit('Ce fichier ne peut être appelé directement !');}
$TITRE = 'Génération d’un nouveau mot de passe'; // Pas de traduction car pas de choix de langue à ce niveau.

// Outlook, par exemple, utilise le robot d’exploration BingPreview pour tester les liens dans les courriels !
// Du coup, quand l’utilisateur clique sur le lien, ça lui répond que le code est invalide ou périmé...
// Pour éviter cela, on peut essayer de détecter si on a affaire à un robot.
// Par exemple avec la librairie CrawlerDetect <https://github.com/JayBizzle/Crawler-Detect>.
// Mais c’est basé sur le UserAgent qui n’est que déclaratif, et la liste change régulièrement.
// Mieux et sans besoin de librairie : demander à l’utilisateur un formulaire avant de traiter son code, pour s’assurer qu’on n’a pas affaire à un robot.

// Récupération du code validé par formulaire

$code_post = Clean::post('code_mdp', 'code');

if($code_post)
{
  // Vérification que le formulaire a correctement été renseigné
  if( strpos($code_post,'h') )
  {
    exit_error( $TITRE /*titre*/ , 'L’option cochée n’était pas la bonne... Utiliser de nouveau le lien envoyé par courriel.' /*contenu*/ );
  }

  // Vérification de la structure du code
  list( $user_pass_key , $BASE ) = explode( 'g' , $code_post ) + array_fill(0,2,NULL) ; // Evite des NOTICE en initialisant les valeurs manquantes
  $BASE = (int)$BASE;

  if( (!$user_pass_key) || ( ($BASE==0) && (HEBERGEUR_INSTALLATION=='multi-structures') ) )
  {
    exit_error( $TITRE /*titre*/ , 'Le code transmis est incohérent (format inattendu).' /*contenu*/ );
  }

  // En cas de multi-structures, il faut charger les paramètres de connexion à la base concernée
  if(HEBERGEUR_INSTALLATION=='multi-structures')
  {
    $result = DBextra::charger_parametres_sql_supplementaires($BASE,FALSE);
    if(!$result)
    {
      exit_error( $TITRE /*titre*/ , 'Le code transmis est invalide ou périmé (base inexistante).' /*contenu*/ );
    }
  }

  // Récupération des données de l’utilisateur
  $DB_ROW = DB_STRUCTURE_PUBLIC::DB_recuperer_user_pour_requete_par_mail('user_pass_key',$user_pass_key);

  if(empty($DB_ROW))
  {
    exit_error( $TITRE /*titre*/ , 'Le code transmis est invalide ou périmé (absence de correspondance).' /*contenu*/ );
  }

  if( Outil::clef_md5($DB_ROW['user_id'].$DB_ROW['user_email'].$DB_ROW['user_password'].$DB_ROW['user_connexion_date']) != $user_pass_key )
  {
    exit_error( $TITRE /*titre*/ , 'Le code transmis est périmé (incompatible avec les données actuelles).' /*contenu*/ );
  }

  // Prendre en compte la demande de changement de mdp
  $newpass = Outil::fabriquer_mdp(); // On ne transmet pas de profil car necessite sinon une variable de session non définie à ce stade.
  DB_STRUCTURE_PUBLIC::DB_modifier_user_password_or_key ($DB_ROW['user_id'] , Outil::crypter_mdp($newpass) /*user_password*/ , '' /*user_pass_key*/ );

  // Affichage du résultat (confirmation + identifiants)
  echo'<p><label class="valide">Nouveau mot de passe généré avec succès !</label></p>'.NL;
  echo'<p>Veuillez noter vos identifiants de connexion :</p>'.NL;
  echo'<form>'.NL;
  echo'  <label class="tab">Nom d’utilisateur :</label><b>'.html($DB_ROW['user_login']).'</b><br>'.NL;
  echo'  <label class="tab">Mot de passe :</label><b>'.$newpass.'</b>'.NL;
  echo'</form>'.NL;
  echo'<p><span class="astuce">Le code transmis étant à usage unique, il ne peut pas être utilisé de nouveau.</span></p>'.NL;
  echo'<hr>'.NL;
  echo'<p class="hc"><a href="./index.php">[ Retour en page d’accueil ]</a></p>'.NL;

  return; // Ne pas exécuter la suite de ce fichier inclus.
}

// Sinon, récupération du code transmis dans l’adresse

$code_get = Clean::get('code_mdp', 'code');

if(!$code_get)
{
  exit_error( $TITRE /*titre*/ , 'Absence de code transmis dans l’adresse.' /*contenu*/ );
}

// Fabrication d’un formulaire avec plusieurs choix dont un seul correct
$bon_numero = mt_rand(0,9);
$tab_option = array();
for( $i=0 ; $i<=9 ; $i++ )
{
  $valeur = ($i==$bon_numero) ? $code_get : md5(mt_rand()).'h'.mt_rand(1,999) ;
  $tab_option[] = '<label for="option_'.$i.'"><input type="radio" name="code_mdp" id="option_'.$i.'" value="'.$valeur.'"> '.$i.'</label>' ;
}

// Affichage du résultat (formulaire anti-robot)
echo'<p>Pour confirmer que cette page n’est pas chargée par un robot, cocher la case <b>n°'.$bon_numero.'</b> puis valider :</p>'.NL;
echo'<form action="./index.php?page=public_nouveau_mdp" method="post">'.NL;
echo'  <p><span class="tab"></span>'.implode('&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;',$tab_option).'</p>'.NL;
echo'  <p><span class="tab"></span><button type="submit" class="valider">Obtenir mon nouveau mot de passe</button></p>'.NL;
echo'</form>'.NL;
?>
