1<?php 2 3use dokuwiki\Form\Form; 4use dokuwiki\plugin\twofactor\OtpField; 5use dokuwiki\plugin\twofactor\Provider; 6 7/** 8 * 2fa provider using an alternative email address 9 */ 10class action_plugin_twofactoraltemail extends Provider 11{ 12 /** @inheritdoc */ 13 public function getLabel() 14 { 15 $label = $this->getLang('name'); 16 $email = $this->settings->get('email'); 17 if ($email) $label .= ': ' . $email; 18 return $label; 19 } 20 21 /** @inheritdoc */ 22 public function isConfigured() 23 { 24 return $this->settings->get('email') && 25 $this->settings->get('verified'); 26 27 } 28 29 /** @inheritdoc */ 30 public function renderProfileForm(Form $form) 31 { 32 $email = $this->settings->get('email'); 33 34 if (!$email) { 35 $form->addHTML('<p>' . $this->getLang('intro') . '</p>'); 36 $form->addTextInput('newemail', $this->getLang('email'))->attr('autocomplete', 'off'); 37 } else { 38 $form->addHTML('<p>' . $this->getLang('verifynotice') . '</p>'); 39 $form->addElement(new OtpField('verify')); 40 } 41 42 return $form; 43 } 44 45 /** @inheritdoc */ 46 public function handleProfileForm() 47 { 48 global $INPUT; 49 global $USERINFO; 50 51 if ($INPUT->str('verify')) { 52 // verification code given, check the code 53 if ($this->checkCode($INPUT->str('verify'))) { 54 $this->settings->set('verified', true); 55 } else { 56 $this->settings->delete('email'); 57 } 58 } elseif ($INPUT->str('newemail')) { 59 $newmail = $INPUT->str('newemail'); 60 // check that it differs 61 if (strtolower($newmail) == strtolower($USERINFO['mail'])) { 62 msg($this->getLang('notsameemail'), -1); 63 return; 64 } 65 66 // new email has been, set init verification 67 $this->settings->set('email', $newmail); 68 69 try { 70 $this->initSecret(); 71 $code = $this->generateCode(); 72 $info = $this->transmitMessage($code); 73 msg(hsc($info), 1); 74 } catch (\Exception $e) { 75 msg(hsc($e->getMessage()), -1); 76 $this->settings->delete('email'); 77 } 78 } 79 } 80 81 /** @inheritdoc */ 82 public function getTolerance() 83 { 84 return $this->getConf('tolerance'); 85 } 86 87 /** @inheritdoc */ 88 public function transmitMessage($code) 89 { 90 $to = $this->settings->get('email'); 91 if (!$to) throw new \Exception($this->getLang('codesentfail')); 92 93 // Create the email object. 94 $body = io_readFile($this->localFN('mail')); 95 $mail = new Mailer(); 96 $mail->to($to); 97 $mail->subject($this->getLang('subject')); 98 $mail->setBody($body, ['CODE' => $code]); 99 $result = $mail->send(); 100 if (!$result) throw new \Exception($this->getLang('codesentfail')); 101 102 return $this->getLang('codesent'); 103 } 104} 105