* (bug 13450) Email confirmation can now be canceled before the expiration
authorBrion Vibber <brion@users.mediawiki.org>
Tue, 25 Mar 2008 22:03:00 +0000 (22:03 +0000)
committerBrion Vibber <brion@users.mediawiki.org>
Tue, 25 Mar 2008 22:03:00 +0000 (22:03 +0000)
patch by MrZ-man - https://bugzilla.wikimedia.org/attachment.cgi?id=4764
Plus text strings copied back from https://bugzilla.wikimedia.org/attachment.cgi?id=4761

RELEASE-NOTES
includes/AutoLoader.php
includes/SpecialConfirmemail.php
includes/SpecialPage.php
includes/User.php
languages/messages/MessagesEn.php

index 99cb7eb..fbf36c0 100644 (file)
@@ -54,6 +54,7 @@ it from source control: http://www.mediawiki.org/wiki/Download_from_SVN
 * (bug 1459) Search for duplicate files by hash: Special:FileDuplicateSearch
 * (bug 9447) Added hooks for search result headings
 * Image redirects are now enabled
+* (bug 13450) Email confirmation can now be canceled before the expiration
 
 
 === Bug fixes in 1.13 ===
index dbc697c..421610d 100644 (file)
@@ -73,6 +73,7 @@ function __autoload($className) {
                'eAccelBagOStuff' => 'includes/BagOStuff.php',
                'EditPage' => 'includes/EditPage.php',
                'EmailConfirmation' => 'includes/SpecialConfirmemail.php',
+               'EmailInvalidation' => 'includes/SpecialConfirmemail.php',
                'EmaillingJob' => 'includes/EmaillingJob.php',
                'EmaillingJob' => 'includes/JobQueue.php',
                'EmailNotification' => 'includes/UserMailer.php',
index c3aa53c..98ec109 100644 (file)
@@ -101,4 +101,44 @@ class EmailConfirmation extends UnlistedSpecialPage {
        
 }
 
-
+/**
+ * Special page allows users to cancel an email confirmation using the e-mail 
+ * confirmation code
+ *
+ * @addtogroup SpecialPage
+ */
+class EmailInvalidation extends UnlistedSpecialPage {
+       
+       public function __construct() {
+               parent::__construct( 'Invalidateemail' );
+       }
+       
+       function execute( $code ) {
+               $this->setHeaders();
+               $this->attemptInvalidate( $code );
+       }
+       
+       /**
+        * Attempt to invalidate the user's email address and show success or failure
+        * as needed; if successful, link to main page
+        *
+        * @param $code Confirmation code
+        */
+       function attemptInvalidate( $code ) {
+               global $wgUser, $wgOut;
+               $user = User::newFromConfirmationCode( $code );
+               if( is_object( $user ) ) {
+                       $user->invalidateEmail();
+                       if( $user->invalidateEmail() ) {
+                               $wgOut->addWikiMsg( 'confirmemail_invalidated' );
+                               if( !$wgUser->isLoggedIn() ) {
+                                       $wgOut->returnToMain();
+                               }
+                       } else {
+                               $wgOut->addWikiMsg( 'confirmemail_error' );
+                       }
+               } else {
+                       $wgOut->addWikiMsg( 'confirmemail_invalid' );
+               }
+       }       
+}
index c9380ba..8a157eb 100644 (file)
@@ -182,6 +182,7 @@ class SpecialPage
 
                if( $wgEmailAuthentication ) {
                        self::$mList['Confirmemail'] = 'EmailConfirmation';
+                       self::$mList['Invalidateemail'] = 'EmailInvalidation';
                }
 
                # Add extension special pages
index a8bfbe6..c64145c 100644 (file)
@@ -2020,7 +2020,9 @@ class User {
                                'user_email_authenticated' => $dbw->timestampOrNull( $this->mEmailAuthenticated ),
                                'user_options' => $this->encodeOptions(),
                                'user_touched' => $dbw->timestamp($this->mTouched),
-                               'user_token' => $this->mToken
+                               'user_token' => $this->mToken,
+                               'user_email_token' => $this->mEmailToken,
+                               'user_email_token_expires' => $this->mEmailTokenExpires
                        ), array( /* WHERE */
                                'user_id' => $this->mId
                        ), __METHOD__
@@ -2376,7 +2378,7 @@ class User {
        }
 
        /**
-        * Generate a new e-mail confirmation token and send a confirmation
+        * Generate a new e-mail confirmation token and send a confirmation/invalidation
         * mail to the user's given address.
         *
         * @return mixed True on success, a WikiError object on failure.
@@ -2384,13 +2386,16 @@ class User {
        function sendConfirmationMail() {
                global $wgContLang;
                $expiration = null; // gets passed-by-ref and defined in next line.
-               $url = $this->confirmationTokenUrl( $expiration );
+               $token = $this->confirmationToken( $expiration );
+               $url = $this->confirmationTokenUrl( $token );
+               $invalidateURL = $this->invalidationTokenUrl( $token );
                return $this->sendMail( wfMsg( 'confirmemail_subject' ),
                        wfMsg( 'confirmemail_body',
                                wfGetIP(),
                                $this->getName(),
                                $url,
-                               $wgContLang->timeanddate( $expiration, false ) ) );
+                               $wgContLang->timeanddate( $expiration, false ),
+                               $invalidateURL ) );
        }
 
        /**
@@ -2424,32 +2429,35 @@ class User {
                $now = time();
                $expires = $now + 7 * 24 * 60 * 60;
                $expiration = wfTimestamp( TS_MW, $expires );
-
                $token = $this->generateToken( $this->mId . $this->mEmail . $expires );
                $hash = md5( $token );
-
-               $dbw = wfGetDB( DB_MASTER );
-               $dbw->update( 'user',
-                       array( 'user_email_token'         => $hash,
-                              'user_email_token_expires' => $dbw->timestamp( $expires ) ),
-                       array( 'user_id'                  => $this->mId ),
-                       __METHOD__ );
-
+               $this->load();
+               $this->mEmailToken = $hash;
+               $this->mEmailTokenExpires = $expiration;
+               $this->saveSettings();
                return $token;
        }
 
        /**
-        * Generate and store a new e-mail confirmation token, and return
-        * the URL the user can use to confirm.
-        * @param &$expiration mixed output: accepts the expiration time
+       * Return a URL the user can use to confirm their email address. 
+        * @param $token: accepts the email confirmation token
         * @return string
         * @private
         */
-       function confirmationTokenUrl( &$expiration ) {
-               $token = $this->confirmationToken( $expiration );
+       function confirmationTokenUrl( $token ) {
                $title = SpecialPage::getTitleFor( 'Confirmemail', $token );
                return $title->getFullUrl();
        }
+       /**
+        * Return a URL the user can use to invalidate their email address.
+        * @param $token: accepts the email confirmation token
+        * @return string
+        * @private
+        */
+        function invalidationTokenUrl( $token ) {
+               $title = SpecialPage::getTitleFor( 'Invalidateemail', $token );
+               return $title->getFullUrl();
+       }
 
        /**
         * Mark the e-mail address confirmed and save.
@@ -2460,6 +2468,19 @@ class User {
                $this->saveSettings();
                return true;
        }
+       
+       /**
+        * Invalidate the user's email confirmation, unauthenticate the email
+        * if it was already confirmed and save.
+        */
+       function invalidateEmail() {
+               $this->load();
+               $this->mEmailToken = null;
+               $this->mEmailTokenExpires = null;
+               $this->mEmailAuthenticated = null;
+               $this->saveSettings();
+               return true;
+       }
 
        /**
         * Is this user allowed to send e-mails within limits of current
index b69119a..1a4a2c5 100644 (file)
@@ -428,6 +428,7 @@ $specialPageAliases = array(
        'Withoutinterwiki'          => array( 'WithoutInterwiki' ),
        'MergeHistory'              => array( 'MergeHistory' ),
        'Filepath'                  => array( 'FilePath' ),
+       'Invalidateemail'           => array( 'InvalidateEmail' ),
 );
 
 /**
@@ -2908,14 +2909,22 @@ You may now log in and enjoy the wiki.',
 'confirmemail_loggedin'   => 'Your e-mail address has now been confirmed.',
 'confirmemail_error'      => 'Something went wrong saving your confirmation.',
 'confirmemail_subject'    => '{{SITENAME}} e-mail address confirmation',
-'confirmemail_body'       => 'Someone, probably you, from IP address $1, has registered an account "$2" with this e-mail address on {{SITENAME}}.
+'confirmemail_body'       => 'Someone, probably you, from IP address $1,
+has registered an account "$2" with this e-mail address on {{SITENAME}}.
 
-To confirm that this account really does belong to you and activate e-mail features on {{SITENAME}}, open this link in your browser:
+To confirm that this account really does belong to you and activate
+e-mail features on {{SITENAME}}, open this link in your browser:
 
 $3
 
-If this is *not* you, don\'t follow the link.
+If you did *not* register the account, follow this link
+to cancel the email address confirmation:
+
+$5
+
 This confirmation code will expire at $4.',
+'confirmemail_invalidated' => 'E-mail address confirmation canceled',
+'invalidateemail'          => 'Cancel E-mail confirmation',
 
 # Scary transclusion
 'scarytranscludedisabled' => '[Interwiki transcluding is disabled]',