CMSimple_XH 開発者ドキュメント
PasswordForgotten.php
1 <?php
2 
14 namespace XH;
15 
27 {
33  private $status = '';
34 
40  public function dispatch()
41  {
42  if (isset($_POST['xh_email'])) {
43  $this->submit();
44  } elseif (isset($_GET['xh_code']) && $this->checkMac($_GET['xh_code'])) {
45  $this->reset();
46  }
47  $this->render();
48  }
49 
61  private function render()
62  {
63  global $title, $o, $sn, $tx, $onload;
64 
65  $title = $tx['title']['password_forgotten'];
66  $o .= '<h1>' . $title . '</h1>';
67  switch ($this->status) {
68  case 'sent':
69  $o .= '<p>' . $tx['password_forgotten']['email1_sent'] . '</p>';
70  break;
71  case 'reset':
72  $o .= '<p>' . $tx['password_forgotten']['email2_sent'] . '</p>';
73  break;
74  default:
75  $o .= '<p>' . $tx['password_forgotten']['request'] . '</p>'
76  . '<form name="xh_forgotten" action="' . $sn . '?&function=forgotten"'
77  . ' method="post">'
78  . '<input type="text" name="xh_email">'
79  . '<input type="submit" class="submit" value="Send Reminder">'
80  . '</form>';
81  $onload .= 'document.forms[\'xh_forgotten\'].elements[\'xh_email\']'
82  . '.focus();';
83  }
84  }
85 
95  public function mac($previous = false)
96  {
97  global $cf;
98 
99  $email = $cf['security']['email'];
100  $date = date('Y-m-d h:00:00') . ($previous ? ' -1hour' : '');
101  $timestamp = strtotime($date);
102  $secret = $cf['security']['secret'];
103  $mac = md5($email . $timestamp . $secret);
104  return $mac;
105  }
106 
114  public function checkMac($mac)
115  {
116  return $mac == $this->mac() || $mac == $this->mac(true);
117  }
118 
129  private function submit()
130  {
131  global $cf, $tx, $e;
132 
133  if ($_POST['xh_email'] == $cf['security']['email']) {
134  $to = $cf['security']['email'];
135  $message = $tx['password_forgotten']['email1_text'] . "\r\n"
136  . '<' . CMSIMPLE_URL . '?&function=forgotten&xh_code='
137  . $this->mac() . '>';
138  $mail = new Mail();
139  $mail->setTo($to);
140  $mail->setSubject($tx['title']['password_forgotten']);
141  $mail->setMessage($message);
142  $mail->addHeader('From', $to);
143  $ok = $mail->send();
144  if ($ok) {
145  $this->status = 'sent';
146  } else {
147  $this->status = '';
148  $e .= '<li>' . $tx['mailform']['notsend'] . '</li>';
149  }
150  } else {
151  $this->status = '';
152  }
153  }
154 
165  private function reset()
166  {
167  global $pth, $cf, $tx;
168 
169  $password = bin2hex(random_bytes(8));
170  $hash = password_hash($password, PASSWORD_BCRYPT);
171  $to = $cf['security']['email'];
172  $message = $tx['password_forgotten']['email2_text'] . ' ' . $password;
173  $mail = new Mail();
174  $mail->setTo($to);
175  $mail->setSubject($tx['title']['password_forgotten']);
176  $mail->setMessage($message);
177  $mail->addHeader('From', $to);
178  $sent = $mail->send();
179  if ($sent) {
180  if (!$this->saveNewPassword($hash)) {
181  e('cntsave', 'config', $pth['file']['config']);
182  }
183  $this->status = 'reset';
184  } else {
185  $this->status = '';
186  }
187  }
188 
199  private function saveNewPassword($hash)
200  {
201  global $pth;
202 
203  $cf = XH_includeVar($pth['file']['config'], 'cf');
204  $cf['security']['password'] = $hash;
205  $o = '<?php' . PHP_EOL . PHP_EOL;
206  foreach ($cf as $cat => $opts) {
207  foreach ($opts as $name => $opt) {
208  $opt = addcslashes($opt, "\0..\37\"\$\\");
209  $o .= "\$cf['$cat']['$name']=\"$opt\";" . PHP_EOL;
210  }
211  }
212  $o .= PHP_EOL . '?>' . PHP_EOL;
213  return XH_writeFile($pth['file']['config'], $o);
214  }
215 }
XH_includeVar($_filename, $_varname)
Definition: functions.php:2251
$e
Definition: cms.php:127
const CMSIMPLE_URL
Definition: cms.php:761
XH_writeFile($filename, $contents)
Definition: functions.php:1626
mac($previous=false)
$title
Definition: cms.php:100
$cf
Definition: cms.php:272
$o
Definition: cms.php:113
$onload
Definition: cms.php:171
e($et, $ft, $fn)
Definition: functions.php:655
$sn
Definition: cms.php:434
$tx
Definition: cms.php:363
$pth
Definition: cms.php:230
Definition: Mail.php:28