MediaWiki master
SpecialConfirmEmail.php
Go to the documentation of this file.
1<?php
21namespace MediaWiki\Specials;
22
34use Profiler;
36use Wikimedia\ScopedCallback;
37
52
53 private UserFactory $userFactory;
54
55 public function __construct( UserFactory $userFactory ) {
56 parent::__construct( 'Confirmemail', 'editmyprivateinfo' );
57
58 $this->userFactory = $userFactory;
59 }
60
61 public function doesWrites() {
62 return true;
63 }
64
73 public function execute( $code ) {
74 // Ignore things like primary queries/connections on GET requests.
75 // It's very convenient to just allow formless link usage.
76 $trxProfiler = Profiler::instance()->getTransactionProfiler();
77
78 $this->setHeaders();
79 $this->checkReadOnly();
80 $this->checkPermissions();
81
82 // This could also let someone check the current email address, so
83 // require both permissions.
84 if ( !$this->getAuthority()->isAllowed( 'viewmyprivateinfo' ) ) {
85 throw new PermissionsError( 'viewmyprivateinfo' );
86 }
87
88 if ( $code === null || $code === '' ) {
89 $this->requireNamedUser( 'confirmemail_needlogin', 'exception-nologin', true );
90 if ( Sanitizer::validateEmail( $this->getUser()->getEmail() ) ) {
91 $this->showRequestForm();
92 } else {
93 $this->getOutput()->addWikiMsg( 'confirmemail_noemail' );
94 }
95 } else {
96 $scope = $trxProfiler->silenceForScope( $trxProfiler::EXPECTATION_REPLICAS_ONLY );
97 $this->attemptConfirm( $code );
98 ScopedCallback::consume( $scope );
99 }
100 }
101
105 private function showRequestForm() {
106 $user = $this->getUser();
107 $out = $this->getOutput();
108
109 if ( !$user->isEmailConfirmed() ) {
110 $descriptor = [];
111 if ( $user->isEmailConfirmationPending() ) {
112 $descriptor += [
113 'pending' => [
114 'type' => 'info',
115 'raw' => true,
116 'default' => "<div class=\"error mw-confirmemail-pending\">\n" .
117 $this->msg( 'confirmemail_pending' )->escaped() .
118 "\n</div>",
119 ],
120 ];
121 }
122
123 $out->addWikiMsg( 'confirmemail_text' );
124 $form = HTMLForm::factory( 'ooui', $descriptor, $this->getContext() );
125 $form
126 ->setAction( $this->getPageTitle()->getLocalURL() )
127 ->setSubmitTextMsg( 'confirmemail_send' )
128 ->setSubmitCallback( [ $this, 'submitSend' ] );
129
130 $retval = $form->show();
131
132 if ( $retval === true ) {
133 // should never happen, but if so, don't let the user without any message
134 $out->addWikiMsg( 'confirmemail_sent' );
135 } elseif ( $retval instanceof Status && $retval->isGood() ) {
136 $out->addWikiTextAsInterface( $retval->getValue() );
137 }
138 } else {
139 // date and time are separate parameters to facilitate localisation.
140 // $time is kept for backward compat reasons.
141 // 'emailauthenticated' is also used in SpecialPreferences.php
142 $lang = $this->getLanguage();
143 $emailAuthenticated = $user->getEmailAuthenticationTimestamp();
144 $time = $lang->userTimeAndDate( $emailAuthenticated, $user );
145 $d = $lang->userDate( $emailAuthenticated, $user );
146 $t = $lang->userTime( $emailAuthenticated, $user );
147 $out->addWikiMsg( 'emailauthenticated', $time, $d, $t );
148 }
149 }
150
156 public function submitSend() {
157 $status = $this->getUser()->sendConfirmationMail();
158 if ( $status->isGood() ) {
159 return Status::newGood( $this->msg( 'confirmemail_sent' )->text() );
160 } else {
161 return Status::newFatal( new RawMessage(
162 $status->getWikiText( 'confirmemail_sendfailed', false, $this->getLanguage() )
163 ) );
164 }
165 }
166
173 private function attemptConfirm( $code ) {
174 $user = $this->userFactory->newFromConfirmationCode(
175 $code,
176 IDBAccessObject::READ_LATEST
177 );
178
179 if ( !is_object( $user ) ) {
180 if ( User::isWellFormedConfirmationToken( $code ) ) {
181 $this->getOutput()->addWikiMsg( 'confirmemail_invalid' );
182 } else {
183 $this->getOutput()->addWikiMsg( 'confirmemail_invalid_format' );
184 }
185
186 return;
187 }
188
189 // Enforce permissions, user blocks, and rate limits
190 $this->authorizeAction( 'confirmemail' )->throwErrorPageError();
191
192 $userLatest = $user->getInstanceForUpdate();
193 $userLatest->confirmEmail();
194 $userLatest->saveSettings();
195 $message = $this->getUser()->isNamed() ? 'confirmemail_loggedin' : 'confirmemail_success';
196 $this->getOutput()->addWikiMsg( $message );
197
198 if ( !$this->getUser()->isNamed() ) {
199 $title = SpecialPage::getTitleFor( 'Userlogin' );
200 $this->getOutput()->returnToMain( true, $title );
201 }
202 }
203}
204
206class_alias( SpecialConfirmEmail::class, 'SpecialConfirmEmail' );
Show an error when a user tries to do something they do not have the necessary permissions for.
Show an error when the wiki is locked/read-only and the user tries to do something that requires writ...
Redirect a user to the login page or account creation page.
Object handling generic submission, CSRF protection, layout and other logic for UI forms in a reusabl...
Definition HTMLForm.php:210
Variant of the Message class.
HTML sanitizer for MediaWiki.
Definition Sanitizer.php:46
Parent class for all special pages.
setHeaders()
Sets headers - this should be called from the execute() method of all derived classes!
static getTitleFor( $name, $subpage=false, $fragment='')
Get a localised Title object for a specified special page name If you don't need a full Title object,...
getUser()
Shortcut to get the User executing this instance.
authorizeAction(?string $action=null)
Utility function for authorizing an action to be performed by the special page.
requireNamedUser( $reasonMsg='exception-nologin-text', $titleMsg='exception-nologin', bool $alwaysRedirectToLoginPage=false)
If the user is not logged in or is a temporary user, throws UserNotLoggedIn.
getPageTitle( $subpage=false)
Get a self-referential title object.
checkPermissions()
Checks if userCanExecute, and if not throws a PermissionsError.
checkReadOnly()
If the wiki is currently in readonly mode, throws a ReadOnlyError.
getContext()
Gets the context this SpecialPage is executed in.
msg( $key,... $params)
Wrapper around wfMessage that sets the current context.
getOutput()
Get the OutputPage being used for this instance.
getAuthority()
Shortcut to get the Authority executing this instance.
getLanguage()
Shortcut to get user's language.
Shortcut to construct a special page which is unlisted by default.
Email confirmation for registered users.
doesWrites()
Indicates whether POST requests to this special page require write access to the wiki.
submitSend()
Callback for HTMLForm send confirmation mail.
Generic operation result class Has warning/error list, boolean status and arbitrary value.
Definition Status.php:54
Create User objects.
User class for the MediaWiki software.
Definition User.php:121
Profiler base class that defines the interface and some shared functionality.
Definition Profiler.php:37
static instance()
Definition Profiler.php:105
Interface for database access objects.