Repository: gratipay/gratipay.com

Issue:
Replace temporary 'email2' param with 'email' when verifying emails
In https://github.com/gratipay/gratipay.com/pull/3965, we changed the value of the `email` parameter to be query-string encoded instead of raw text. To make this backward compatible, we changed the parameter name from `email` to `email2` and retained support for both. 

This was a **long** time ago, time to clean up. 

**Current**: We support `email2` (if the value is encoded) and `email` (if it isn't encoded. 
**End Goal**: Support only `email`, with encoded value

To achieve this without breaking existing links, we'll need an intermediary step. 

- Add support for `email`, with encoded value + send `email` in the links instead of `email2`. Don't drop support for `email2` as of yet. 
- Once the above is done, wait for the duration that verification links live - and then drop support for `email2`. 

Here's the related code: https://github.com/gratipay/gratipay.com/blob/master/www/~/%25username/emails/verify.html.spt#L14


Discussion:
@rohitpaulk  I am up for it and submit the patch in a week. This is my first PR.

Resolving patch:
diff --git a/gratipay/models/participant/email.py b/gratipay/models/participant/email.py
--- a/gratipay/models/participant/email.py
+++ b/gratipay/models/participant/email.py
@@ -159,7 +159,7 @@ def get_email_verification_link(self, c, email, *packages):
         nonce = self.get_email_verification_nonce(c, email)
         if packages:
             self.start_package_claims(c, nonce, *packages)
-        link = "{base_url}/~{username}/emails/verify.html?email2={encoded_email}&nonce={nonce}"
+        link = "{base_url}/~{username}/emails/verify.html?email={encoded_email}&nonce={nonce}"
         return link.format( base_url=gratipay.base_url
                           , username=self.username_lower
                           , encoded_email=encode_for_querystring(email)


Test patch:
diff --git a/tests/py/test_participant_emails.py b/tests/py/test_participant_emails.py
--- a/tests/py/test_participant_emails.py
+++ b/tests/py/test_participant_emails.py
@@ -63,7 +63,7 @@ def hit_email_spt(self, action, address, user='alice', package_ids=[], should_fa
 
     def hit_verify_spt(self, email, nonce, username='alice', should_fail=False):
         # Email address is encoded in url.
-        url = '/~%s/emails/verify.html?email2=%s&nonce=%s'
+        url = '/~%s/emails/verify.html?email=%s&nonce=%s'
         url %= (username, encode_for_querystring(email), nonce)
         f = self.client.GxT if should_fail else self.client.GET
         return f(url, auth_as=username)
@@ -93,7 +93,7 @@ def test_email_address_is_encoded_in_sent_verification_link(self):
         encoded = encode_for_querystring(address)
         self.hit_email_spt('add-email', address)
         last_email = self.get_last_email()
-        assert "~alice/emails/verify.html?email2="+encoded in last_email['body_text']
+        assert "~alice/emails/verify.html?email="+encoded in last_email['body_text']
 
     def test_verification_email_doesnt_contain_unsubscribe(self):
         self.hit_email_spt('add-email', 'alice@gratipay.com')
@@ -190,14 +190,17 @@ def test_empty_nonce_fails(self):
             assert result == (_email.VERIFICATION_FAILED, None, None)
 
     def test_email_verification_is_backwards_compatible(self):
-        """Test email verification still works with unencoded email in verification link.
+        """Test email verification still works with 'email2' field in verification link.
         """
-        self.hit_email_spt('add-email', 'alice@example.com')
-        nonce = self.alice.get_email('alice@example.com').nonce
-        url = '/~alice/emails/verify.html?email=alice@example.com&nonce='+nonce
-        self.client.GET(url, auth_as='alice')
-        expected = 'alice@example.com'
-        actual = P('alice').email_address
+        username = 'alice'
+        email = 'alice@example.com'
+        self.hit_email_spt('add-email', email)
+        nonce = self.alice.get_email(email).nonce
+        url = '/~%s/emails/verify.html?email2=%s&nonce=%s'
+        url %= (username, encode_for_querystring(email), nonce)
+        self.client.GET(url, auth_as=username)
+        expected = email
+        actual = P(username).email_address
         assert expected == actual
 
     def test_verified_email_is_not_changed_after_update(self):
@@ -573,7 +576,7 @@ def test_returns_a_link(self):
         with self.db.get_cursor() as c:
             alice = self.make_participant('alice')
             link = alice.get_email_verification_link(c, 'alice@example.com')
-        assert link.startswith('/~alice/emails/verify.html?email2=YWxpY2VAZXhhbXBsZS5jb20~&nonce=')
+        assert link.startswith('/~alice/emails/verify.html?email=YWxpY2VAZXhhbXBsZS5jb20~&nonce=')
 
     def test_makes_no_claims_by_default(self):
         with self.db.get_cursor() as c: