Problem/Motivation
When a registered users receives a newsletter and uses the "manage-url" link to change their subscriptions, they are told to log into their user account after (!) completing the form.
Steps to reproduce
Create a user. Add subscriptions for some newsletter types. Receive a newsletter email. Click the link from the [simplenews-subscriber:manage-url] token. Having followed the link, make some changes in the form and submit.
It results in the following error: There is an account registered for the e-mail address %mail. Please log in to manage your newsletter subscriptions.
Proposed resolution
Accept the verification via the access hash from the link as sufficient validation, and do not require additional login for registered users.
Remaining tasks
None
User interface changes
None.
API changes
None.
Data model changes
None.
Comments
Comment #2
PhilippVerpoortThis does the desired. An update function still needs to be added to create the config entry for
require_user_logininsimplenews.settings.Otherwise, this needs review.
Comment #5
adamps commentedThanks. I suggest that we don't even need a config option.
I guess the possible danger case is that I forward my newsletter to someone and they maliciously take the chance to alter my subscription. However I guess that this same risk is present in many major online newsletters.
Ideally this would have a test. It definitely would need one if adding a config option:-).
Comment #6
adamps commentedUpdated answer:
The current code insists that users log in to manage their subscription. This is the correct behaviour in almost all cases. NB the code that this patch is altering is on the base subscription form used by all 4 different sub-forms. The only exception to the need to log in is the case that a valid token has been used for SubscriptionsPageForm. In this case
SubscriptionsPageForm::buildForm()loaded the entity. AlsoSubscriptionsAccountForm::buildForm()tries to load an entity. SubscriberForm will always have an entity I would expect. I didn't check all the others but I expect it will be similar. So the correct fix toSubscriptionsFormBase::validateForm()should be to replace the call to\Drupal::currentUser()->isAnonymous()with something that checks if there is a valid entity loaded. There is no need to introduce a config option.Comment #7
PhilippVerpoortOK cool! I'll work something out and upload another patch when I find the time. :)
And agreed, we don't necessarily need a config option for this. (And if somebody *really* insists that they want people to log in first, they can always patch it up themselves in the code, it should then be just altering a single line of code.)
Comment #8
PhilippVerpoortI'm uploading a new patch, which aims to implement the suggested changes by Adam in #6.
I've removed the config option, as I agree it's not necessary.
@AdamPS, could you confirm that what I did is vaguely what you were expecting?
I did a quick manual check to confirm it at least resolves the reported bug. It's possible it'll introduce new bugs though. Let's find out what the tests are going to say.
Comment #9
PhilippVerpoortComment #10
adamps commentedWhat you have produces the right answer but it can be simpler/clearer. I think that if a user is loaded then the email address is always taken from that user so it can't possibly be wrong. Here is my suggestion:
Starting from the existing code, replace this:
\Drupal::currentUser()->isAnonymous()with this:
!$this->isAuthenticated()And add something like this
Comment #11
PhilippVerpoortOkay, makes sense! Here goes another attempt. I tested this patch it manually, and worked fine on my end.
Let's see what the tests say.
Comment #12
PhilippVerpoortAdam, can you review and then commit?
Comment #13
adamps commentedGreat thanks. A minor comment:
would be better as
Then sorry to be tedious but it would be really great to have a quick test for this case as it would be easy for it to break in future.
Comment #14
PhilippVerpoortCould you confirm what exactly you were referring to when you were saying:
Because I wasn't able to find
$user_loaded->isAuthenticated()anywhere in fileSubscriptionsFormBase.php.Comment #15
jonathanshawAdam is referring to the isAuthenticated method you've added,
This could be
return ($user_loaded && $user_loaded->isAuthenticated())Comment #16
adamps commentedThanks Philipp for your work on this. I have a need for it now so I am happy to finish it off.
Comment #17
adamps commentedComment #18
adamps commentedComment #19
adamps commentedComment #21
adamps commentedComment #22
adamps commentedComment #23
jonathanshawLooks good to me.
Comment #25
adamps commentedComment #27
PhilippVerpoortAmazing, thanks for finishing this off!