77 parent::__construct( $params );
79 if ( isset( $params[
'emailEnabled'] ) ) {
80 $this->emailEnabled = (bool)$params[
'emailEnabled'];
82 if ( isset( $params[
'newPasswordExpiry'] ) ) {
83 $this->newPasswordExpiry = (int)$params[
'newPasswordExpiry'];
85 if ( isset( $params[
'passwordReminderResendTime'] ) ) {
86 $this->passwordReminderResendTime = $params[
'passwordReminderResendTime'];
95 $this->passwordReminderResendTime ??=
103 'msg' =>
wfMessage(
'resetpass-temp-emailed' ),
123 isset( $options[
'username'] ) &&
124 !$this->userNameUtils->isTemp( $options[
'username'] ) &&
143 if ( !$req || $req->username ===
null || $req->password ===
null ) {
147 $username = $this->userNameUtils->getCanonical(
148 $req->username, UserRigorOptions::RIGOR_USABLE );
149 if ( $username ===
false ) {
153 [ $tempPassHash, $tempPassTime ] = $this->
getTemporaryPassword( $username, IDBAccessObject::READ_LATEST );
154 if ( !$tempPassHash ) {
159 if ( !$status->isOK() ) {
163 if ( !$tempPassHash->verify( $req->password ) ||
164 !$this->isTimestampValid( $tempPassTime )
172 $this->logger->info(
"{user} successfully logged in using temp password",
174 'provider' => static::class,
176 'requestIP' => $this->manager->getRequest()->getIP()
187 $username = $this->userNameUtils->getCanonical( $username, UserRigorOptions::RIGOR_USABLE );
188 if ( $username ===
false ) {
193 return $tempPassHash &&
202 if ( get_class( $req ) !== TemporaryPasswordAuthenticationRequest::class ) {
204 return \StatusValue::newGood(
'ignored' );
208 return \StatusValue::newGood();
211 $username = $this->userNameUtils->getCanonical(
212 $req->username, UserRigorOptions::RIGOR_USABLE );
213 if ( $username ===
false ) {
214 return \StatusValue::newGood(
'ignored' );
217 [ $tempPassHash, $tempPassTime ] = $this->
getTemporaryPassword( $username, IDBAccessObject::READ_LATEST );
218 if ( !$tempPassHash ) {
219 return \StatusValue::newGood(
'ignored' );
222 $sv = \StatusValue::newGood();
223 if ( $req->password !==
null ) {
226 if ( $req->mailpassword ) {
227 if ( !$this->emailEnabled ) {
228 return \StatusValue::newFatal(
'passwordreset-emaildisabled' );
237 $this->passwordReminderResendTime
239 && time() < (
int)
wfTimestamp( TS_UNIX, $tempPassTime )
240 + $this->passwordReminderResendTime * 3600
244 return \StatusValue::newFatal(
'throttled-mailpassword',
245 round( $this->passwordReminderResendTime, 3 ) );
248 if ( !$req->caller ) {
249 return \StatusValue::newFatal(
'passwordreset-nocaller' );
251 if ( !IPUtils::isValid( $req->caller ) ) {
252 $caller = User::newFromName( $req->caller );
254 return \StatusValue::newFatal(
'passwordreset-nosuchcaller', $req->caller );
263 $username = $req->username !==
null ?
264 $this->userNameUtils->getCanonical( $req->username, UserRigorOptions::RIGOR_USABLE ) :
false;
265 if ( $username ===
false ) {
271 get_class( $req ) === TemporaryPasswordAuthenticationRequest::class
275 $sendMail = $req->mailpassword;
277 $req->mailpassword =
false;
280 $tempPassHash = PasswordFactory::newInvalidPassword();
281 $tempPassTime =
null;
300 $reqs, TemporaryPasswordAuthenticationRequest::class
303 $ret = \StatusValue::newGood();
305 if ( $req->mailpassword ) {
306 if ( !$this->emailEnabled ) {
307 $ret->merge( \StatusValue::newFatal(
'emaildisabled' ) );
309 $ret->merge( \StatusValue::newFatal(
'noemailcreate' ) );
324 $reqs, TemporaryPasswordAuthenticationRequest::class
326 if ( $req && $req->username !==
null && $req->password !==
null ) {
328 if ( $req->username !== $user->
getName() ) {
330 $req->username = $user->
getName();
333 if ( $req->mailpassword ) {
335 $this->manager->setAuthenticationSessionData(
'no-email',
true );
339 $ret->createRequest = $req;
348 $req = $res->createRequest;
349 $mailpassword = $req->mailpassword;
351 $req->mailpassword =
false;
356 if ( $mailpassword ) {
360 return $mailpassword ?
'byemail' :
null;
371 if ( $time !==
null ) {
373 if ( time() >= $expiry ) {
393 $this->dbProvider->getPrimaryDatabase()->onTransactionCommitOrIdle(
394 function () use ( $user, $creatingUser, $password ) {
410 $ip = $creatingUser->getRequest()->getIP();
417 $this->getHookRunner()->onUser__mailPasswordInternal( $creatingUser, $ip, $user );
419 $mainPageUrl = Title::newMainPage()->getCanonicalURL();
420 $userLanguage = $this->userOptionsLookup->getOption( $user,
'language' );
421 $subjectMessage =
wfMessage(
'createaccount-title' )->inLanguage( $userLanguage );
422 $bodyMessage =
wfMessage(
'createaccount-text', $ip, $user->
getName(), $password,
423 '<' . $mainPageUrl .
'>', round( $this->newPasswordExpiry / 86400 ) )
424 ->inLanguage( $userLanguage );
426 $status = $user->
sendMail( $subjectMessage->text(), $bodyMessage->text() );
429 if ( !$status->isGood() ) {
430 $this->logger->warning(
'Could not send account creation email: ' .
431 $status->getWikiText(
false,
false,
'en' ) );
446 $this->dbProvider->getPrimaryDatabase()->onTransactionCommitOrIdle(
447 function () use ( $req ) {
448 $this->sendPasswordResetEmail( $req );
461 $user =
User::newFromName( $req->username );
465 $userLanguage = $this->userOptionsLookup->getOption( $user,
'language' );
466 $callerIsAnon = IPUtils::isValid( $req->caller );
467 $callerName = $callerIsAnon ? $req->caller : User::newFromName( $req->caller )->getName();
468 $passwordMessage =
wfMessage(
'passwordreset-emailelement', $user->
getName(),
469 $req->password )->inLanguage( $userLanguage );
470 $emailMessage =
wfMessage( $callerIsAnon ?
'passwordreset-emailtext-ip'
471 :
'passwordreset-emailtext-user' )->inLanguage( $userLanguage );
472 $body = $emailMessage->params( $callerName, $passwordMessage->text(), 1,
473 '<' . Title::newMainPage()->getCanonicalURL() .
'>',
474 round( $this->newPasswordExpiry / 86400 ) )->text();
478 !$this->userOptionsLookup->getBoolOption( $user,
'requireemail' )
480 $url = SpecialPage::getTitleFor(
'Preferences',
false,
'mw-prefsection-personal-email' )
482 $body .=
"\n\n" .
wfMessage(
'passwordreset-emailtext-require-email' )
483 ->inLanguage( $userLanguage )
488 $emailTitle =
wfMessage(
'passwordreset-emailtitle' )->inLanguage( $userLanguage );
489 $user->
sendMail( $emailTitle->text(), $body );
508 abstract protected function getTemporaryPassword(
string $username, $flags = IDBAccessObject::READ_NORMAL ): array;
wfTimestampOrNull( $outputtype=TS_UNIX, $ts=null)
Return a formatted timestamp, or null if input is null.
wfTimestampNow()
Convenience function; returns MediaWiki timestamp for the present time.
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
A class containing constants representing the names of configuration variables.
const PasswordReminderResendTime
Name constant for the PasswordReminderResendTime setting, for use with Config::get()
const EnableEmail
Name constant for the EnableEmail setting, for use with Config::get()
const NewPasswordExpiry
Name constant for the NewPasswordExpiry setting, for use with Config::get()
Parent class for all special pages.