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 ??=
102 'msg' =>
wfMessage(
'resetpass-temp-emailed' ),
121 isset( $options[
'username'] ) &&
122 !$this->userNameUtils->isTemp( $options[
'username'] ) &&
140 if ( !$req || $req->username ===
null || $req->password ===
null ) {
144 $username = $this->userNameUtils->getCanonical(
145 $req->username, UserRigorOptions::RIGOR_USABLE );
146 if ( $username ===
false ) {
150 [ $tempPassHash, $tempPassTime ] = $this->
getTemporaryPassword( $username, IDBAccessObject::READ_LATEST );
151 if ( !$tempPassHash ) {
156 if ( !$status->isOK() ) {
160 if ( !$tempPassHash->verify( $req->password ) ||
161 !$this->isTimestampValid( $tempPassTime )
169 $this->logger->info(
"{user} successfully logged in using temp password",
171 'provider' => static::class,
173 'requestIP' => $this->manager->getRequest()->getIP()
183 $username = $this->userNameUtils->getCanonical( $username, UserRigorOptions::RIGOR_USABLE );
184 if ( $username ===
false ) {
189 return $tempPassHash &&
197 if ( get_class( $req ) !== TemporaryPasswordAuthenticationRequest::class ) {
199 return \StatusValue::newGood(
'ignored' );
203 return \StatusValue::newGood();
206 $username = $this->userNameUtils->getCanonical(
207 $req->username, UserRigorOptions::RIGOR_USABLE );
208 if ( $username ===
false ) {
209 return \StatusValue::newGood(
'ignored' );
212 [ $tempPassHash, $tempPassTime ] = $this->
getTemporaryPassword( $username, IDBAccessObject::READ_LATEST );
213 if ( !$tempPassHash ) {
214 return \StatusValue::newGood(
'ignored' );
217 $sv = \StatusValue::newGood();
218 if ( $req->password !==
null ) {
221 if ( $req->mailpassword ) {
222 if ( !$this->emailEnabled ) {
223 return \StatusValue::newFatal(
'passwordreset-emaildisabled' );
232 $this->passwordReminderResendTime
234 && time() < (
int)
wfTimestamp( TS_UNIX, $tempPassTime )
235 + $this->passwordReminderResendTime * 3600
239 return \StatusValue::newFatal(
'throttled-mailpassword',
240 round( $this->passwordReminderResendTime, 3 ) );
243 if ( !$req->caller ) {
244 return \StatusValue::newFatal(
'passwordreset-nocaller' );
246 if ( !IPUtils::isValid( $req->caller ) ) {
247 $caller = User::newFromName( $req->caller );
249 return \StatusValue::newFatal(
'passwordreset-nosuchcaller', $req->caller );
258 $username = $req->username !==
null ?
259 $this->userNameUtils->getCanonical( $req->username, UserRigorOptions::RIGOR_USABLE ) :
false;
260 if ( $username ===
false ) {
266 get_class( $req ) === TemporaryPasswordAuthenticationRequest::class
270 $sendMail = $req->mailpassword;
272 $req->mailpassword =
false;
275 $tempPassHash = PasswordFactory::newInvalidPassword();
276 $tempPassTime =
null;
293 $reqs, TemporaryPasswordAuthenticationRequest::class
296 $ret = \StatusValue::newGood();
298 if ( $req->mailpassword ) {
299 if ( !$this->emailEnabled ) {
300 $ret->merge( \StatusValue::newFatal(
'emaildisabled' ) );
302 $ret->merge( \StatusValue::newFatal(
'noemailcreate' ) );
316 $reqs, TemporaryPasswordAuthenticationRequest::class
318 if ( $req && $req->username !==
null && $req->password !==
null ) {
320 if ( $req->username !== $user->
getName() ) {
322 $req->username = $user->
getName();
325 if ( $req->mailpassword ) {
327 $this->manager->setAuthenticationSessionData(
'no-email',
true );
331 $ret->createRequest = $req;
339 $req = $res->createRequest;
340 $mailpassword = $req->mailpassword;
342 $req->mailpassword =
false;
347 if ( $mailpassword ) {
351 return $mailpassword ?
'byemail' :
null;
362 if ( $time !==
null ) {
364 if ( time() >= $expiry ) {
384 $this->dbProvider->getPrimaryDatabase()->onTransactionCommitOrIdle(
385 function () use ( $user, $creatingUser, $password ) {
401 $ip = $creatingUser->getRequest()->getIP();
408 $this->getHookRunner()->onUser__mailPasswordInternal( $creatingUser, $ip, $user );
410 $mainPageUrl = Title::newMainPage()->getCanonicalURL();
411 $userLanguage = $this->userOptionsLookup->getOption( $user,
'language' );
412 $subjectMessage =
wfMessage(
'createaccount-title' )->inLanguage( $userLanguage );
413 $bodyMessage =
wfMessage(
'createaccount-text', $ip, $user->
getName(), $password,
414 '<' . $mainPageUrl .
'>', round( $this->newPasswordExpiry / 86400 ) )
415 ->inLanguage( $userLanguage );
417 $status = $user->
sendMail( $subjectMessage->text(), $bodyMessage->text() );
420 if ( !$status->isGood() ) {
421 $this->logger->warning(
'Could not send account creation email: ' .
422 $status->getWikiText(
false,
false,
'en' ) );
437 $this->dbProvider->getPrimaryDatabase()->onTransactionCommitOrIdle(
438 function () use ( $req ) {
439 $this->sendPasswordResetEmail( $req );
452 $user =
User::newFromName( $req->username );
456 $userLanguage = $this->userOptionsLookup->getOption( $user,
'language' );
457 $callerIsAnon = IPUtils::isValid( $req->caller );
458 $callerName = $callerIsAnon ? $req->caller : User::newFromName( $req->caller )->getName();
459 $passwordMessage =
wfMessage(
'passwordreset-emailelement', $user->
getName(),
460 $req->password )->inLanguage( $userLanguage );
461 $emailMessage =
wfMessage( $callerIsAnon ?
'passwordreset-emailtext-ip'
462 :
'passwordreset-emailtext-user' )->inLanguage( $userLanguage );
463 $body = $emailMessage->params( $callerName, $passwordMessage->text(), 1,
464 '<' . Title::newMainPage()->getCanonicalURL() .
'>',
465 round( $this->newPasswordExpiry / 86400 ) )->text();
469 !$this->userOptionsLookup->getBoolOption( $user,
'requireemail' )
471 $url = SpecialPage::getTitleFor(
'Preferences',
false,
'mw-prefsection-personal-email' )
473 $body .=
"\n\n" .
wfMessage(
'passwordreset-emailtext-require-email' )
474 ->inLanguage( $userLanguage )
479 $emailTitle =
wfMessage(
'passwordreset-emailtitle' )->inLanguage( $userLanguage );
480 $user->
sendMail( $emailTitle->text(), $body );
499 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.
array $params
The job parameters.
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.