How to prevent password reset from disclosing private email addresses?User registration error : Two different values for password in database?How can I know if JTable->save() is inserting or updating a record?Disable front-end registrators from recving a confirmation emailDisabling Joomla Unique Email FunctionalityLogin user by Username without getting passwordRegister user via external script and a random passwordHow should I register my users without email address?Alerts not appearing on registration pageBreezingForms unique user email validation problemHow to remove username field from the reset password confirmation form?

For the Single Entry Schengen visa, do the microstates (Monaco, San Marino and the Vatican City) count?

How can I more clearly ask people to accomodate for my autism?

How are astronauts in the ISS protected from electric shock?

Find d this ones stumped me help?

What would you do? Different results than what is reported

List of instances where Rambam argues on the Rif

Holding cost vs carrying cost vs storage cost

Is it OK to call company for more details about a job post (not an application)?

Python algorithm that converts array-like data into MathJax

Auto adjust the width of a tcolorbox right part

Wood glue versus epoxy for doweling stripped screw holes

What happened to the SEV instruction on the 6502?

Why are one-word titles so dominant in books, film, and games?

Program to print the multiple occurrence of numbers in a list

Asimov's story where a man's speech contains no information

When are homomorphisms between Banach algebras contractions?

Implement the 2D Hadamard Transform

Meaning of 早口 - fast talker

Is rent considered a debt?

Why do the Romance languages use definite articles, when Latin doesn't?

Why am i getting the wrong IP from DNS lookups

Which 50 amp breaker do I need for my old Eaton panel?

As tourist in China do I have to fear consequences for having publicly liked South Park

What would cause all humans to stop having kids cheerfully, painlessly, voluntarily?



How to prevent password reset from disclosing private email addresses?


User registration error : Two different values for password in database?How can I know if JTable->save() is inserting or updating a record?Disable front-end registrators from recving a confirmation emailDisabling Joomla Unique Email FunctionalityLogin user by Username without getting passwordRegister user via external script and a random passwordHow should I register my users without email address?Alerts not appearing on registration pageBreezingForms unique user email validation problemHow to remove username field from the reset password confirmation form?






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty
margin-bottom:0;









3

















The "Forgot your password?" password reset form in Joomla 3.x can disclose that an email address is registered with the site. This is a personal privacy violation which is illegal under some privacy laws.



The problem is that the core Joomla function reports two different messages and formats:



  1. "Reset password failed: Invalid email address" when a
    non-registered address is entered into the reset form, and

  2. "An email has been sent to your email address. The email has a verification code, please paste the verification code in the field
    below to prove that you are the owner of this account." when a
    registered address is entered.

A third party can therefore determine that any email address is registered to and is associated with the site. Email addresses are commonly widely known, and in many cases are in the form Firstname.Lastname@



Can this be corrected with an override, to return the #2 response above regardless of the not/registered status of the email address entered?



If not, what core file(s) need to be changed?



I am not mentioning Username here because I am using a plugin which allows authentication by email address and password instead of Username and password.



Please note! If you are unfamiliar with these specific responses, they are different. #1 is text that appears in a Joomla error box. #2 appears as text at the top of the form. This disclosure problem is not solved by a language file override making the text identical.










share|improve this question







New contributor



brett is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.























  • I love this phoenix which has risen from the ashes of an earlier difficult question. This is good content. A clear and useful question peppered with very different and insightful answers. This is the best kind of outcome. Lots of knowledge being shared here, good job everyone -- very proud of this community right now.

    – mickmackusa
    2 days ago











  • I'm delighted with the answers, all which I have read. I have not quite had time to dig in and apply them (disruptive life situation) but they have already served as a educational and useful point which to move forward on. One delay: I'm finally setting up Eclipse on Joomla so I can step through the code and understand the Joomla classes and MVC more clearly. I'll report back this week and also select an answer. Thank for everyone's help, forgiveness for my earlier muddled question and impatience.

    – brett
    23 hours ago


















3

















The "Forgot your password?" password reset form in Joomla 3.x can disclose that an email address is registered with the site. This is a personal privacy violation which is illegal under some privacy laws.



The problem is that the core Joomla function reports two different messages and formats:



  1. "Reset password failed: Invalid email address" when a
    non-registered address is entered into the reset form, and

  2. "An email has been sent to your email address. The email has a verification code, please paste the verification code in the field
    below to prove that you are the owner of this account." when a
    registered address is entered.

A third party can therefore determine that any email address is registered to and is associated with the site. Email addresses are commonly widely known, and in many cases are in the form Firstname.Lastname@



Can this be corrected with an override, to return the #2 response above regardless of the not/registered status of the email address entered?



If not, what core file(s) need to be changed?



I am not mentioning Username here because I am using a plugin which allows authentication by email address and password instead of Username and password.



Please note! If you are unfamiliar with these specific responses, they are different. #1 is text that appears in a Joomla error box. #2 appears as text at the top of the form. This disclosure problem is not solved by a language file override making the text identical.










share|improve this question







New contributor



brett is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.























  • I love this phoenix which has risen from the ashes of an earlier difficult question. This is good content. A clear and useful question peppered with very different and insightful answers. This is the best kind of outcome. Lots of knowledge being shared here, good job everyone -- very proud of this community right now.

    – mickmackusa
    2 days ago











  • I'm delighted with the answers, all which I have read. I have not quite had time to dig in and apply them (disruptive life situation) but they have already served as a educational and useful point which to move forward on. One delay: I'm finally setting up Eclipse on Joomla so I can step through the code and understand the Joomla classes and MVC more clearly. I'll report back this week and also select an answer. Thank for everyone's help, forgiveness for my earlier muddled question and impatience.

    – brett
    23 hours ago














3












3








3








The "Forgot your password?" password reset form in Joomla 3.x can disclose that an email address is registered with the site. This is a personal privacy violation which is illegal under some privacy laws.



The problem is that the core Joomla function reports two different messages and formats:



  1. "Reset password failed: Invalid email address" when a
    non-registered address is entered into the reset form, and

  2. "An email has been sent to your email address. The email has a verification code, please paste the verification code in the field
    below to prove that you are the owner of this account." when a
    registered address is entered.

A third party can therefore determine that any email address is registered to and is associated with the site. Email addresses are commonly widely known, and in many cases are in the form Firstname.Lastname@



Can this be corrected with an override, to return the #2 response above regardless of the not/registered status of the email address entered?



If not, what core file(s) need to be changed?



I am not mentioning Username here because I am using a plugin which allows authentication by email address and password instead of Username and password.



Please note! If you are unfamiliar with these specific responses, they are different. #1 is text that appears in a Joomla error box. #2 appears as text at the top of the form. This disclosure problem is not solved by a language file override making the text identical.










share|improve this question







New contributor



brett is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.












The "Forgot your password?" password reset form in Joomla 3.x can disclose that an email address is registered with the site. This is a personal privacy violation which is illegal under some privacy laws.



The problem is that the core Joomla function reports two different messages and formats:



  1. "Reset password failed: Invalid email address" when a
    non-registered address is entered into the reset form, and

  2. "An email has been sent to your email address. The email has a verification code, please paste the verification code in the field
    below to prove that you are the owner of this account." when a
    registered address is entered.

A third party can therefore determine that any email address is registered to and is associated with the site. Email addresses are commonly widely known, and in many cases are in the form Firstname.Lastname@



Can this be corrected with an override, to return the #2 response above regardless of the not/registered status of the email address entered?



If not, what core file(s) need to be changed?



I am not mentioning Username here because I am using a plugin which allows authentication by email address and password instead of Username and password.



Please note! If you are unfamiliar with these specific responses, they are different. #1 is text that appears in a Joomla error box. #2 appears as text at the top of the form. This disclosure problem is not solved by a language file override making the text identical.







joomla-3.x login






share|improve this question







New contributor



brett is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











share|improve this question







New contributor



brett is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.








share|improve this question




share|improve this question






New contributor



brett is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.








asked Oct 12 at 21:56









brettbrett

164 bronze badges




164 bronze badges




New contributor



brett is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.




New contributor




brett is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

















  • I love this phoenix which has risen from the ashes of an earlier difficult question. This is good content. A clear and useful question peppered with very different and insightful answers. This is the best kind of outcome. Lots of knowledge being shared here, good job everyone -- very proud of this community right now.

    – mickmackusa
    2 days ago











  • I'm delighted with the answers, all which I have read. I have not quite had time to dig in and apply them (disruptive life situation) but they have already served as a educational and useful point which to move forward on. One delay: I'm finally setting up Eclipse on Joomla so I can step through the code and understand the Joomla classes and MVC more clearly. I'll report back this week and also select an answer. Thank for everyone's help, forgiveness for my earlier muddled question and impatience.

    – brett
    23 hours ago


















  • I love this phoenix which has risen from the ashes of an earlier difficult question. This is good content. A clear and useful question peppered with very different and insightful answers. This is the best kind of outcome. Lots of knowledge being shared here, good job everyone -- very proud of this community right now.

    – mickmackusa
    2 days ago











  • I'm delighted with the answers, all which I have read. I have not quite had time to dig in and apply them (disruptive life situation) but they have already served as a educational and useful point which to move forward on. One delay: I'm finally setting up Eclipse on Joomla so I can step through the code and understand the Joomla classes and MVC more clearly. I'll report back this week and also select an answer. Thank for everyone's help, forgiveness for my earlier muddled question and impatience.

    – brett
    23 hours ago

















I love this phoenix which has risen from the ashes of an earlier difficult question. This is good content. A clear and useful question peppered with very different and insightful answers. This is the best kind of outcome. Lots of knowledge being shared here, good job everyone -- very proud of this community right now.

– mickmackusa
2 days ago





I love this phoenix which has risen from the ashes of an earlier difficult question. This is good content. A clear and useful question peppered with very different and insightful answers. This is the best kind of outcome. Lots of knowledge being shared here, good job everyone -- very proud of this community right now.

– mickmackusa
2 days ago













I'm delighted with the answers, all which I have read. I have not quite had time to dig in and apply them (disruptive life situation) but they have already served as a educational and useful point which to move forward on. One delay: I'm finally setting up Eclipse on Joomla so I can step through the code and understand the Joomla classes and MVC more clearly. I'll report back this week and also select an answer. Thank for everyone's help, forgiveness for my earlier muddled question and impatience.

– brett
23 hours ago






I'm delighted with the answers, all which I have read. I have not quite had time to dig in and apply them (disruptive life situation) but they have already served as a educational and useful point which to move forward on. One delay: I'm finally setting up Eclipse on Joomla so I can step through the code and understand the Joomla classes and MVC more clearly. I'll report back this week and also select an answer. Thank for everyone's help, forgiveness for my earlier muddled question and impatience.

– brett
23 hours ago











3 Answers
3






active

oldest

votes


















2


















Great Question Brett. This is one of the only core hacks I've ever had to make. If someone has a better solution then please post it here.



In this file:
https://github.com/joomla/joomla-cms/blob/staging/components/com_users/models/reset.php



In the public function processResetRequest($data)



Where it checks to see if the user exists just return true early. This thus stops the email and reset process but also shows the regular success message to the user.



Original lines 398-404



// Check for a user.
if (empty($userId))

$this->setError(JText::_('COM_USERS_INVALID_EMAIL'));
return false;



Changed to:



// Check for a user.
if (empty($userId))

/* === BEGIN CORE HACK === */
return true;
/* === END CORE HACK ===== */

$this->setError(JText::_('COM_USERS_INVALID_EMAIL'));
return false;






share|improve this answer




























  • Thanks for a super clear answer James. Unfortunately I'm still getting the Joomla error text box vs in-form status messages. Looking at the code you pointed me to (thanks!) I don't see why it wouldn't work at this late hour. Maybe something related to the auth-email plugin I am using changed something related? I will look at this more closely tomorrow and report my findings. BTW, I like your clear commenting, "BEGIN CORE HACK"

    – brett
    Oct 13 at 3:19












  • Note that if a nonexistent user takes a different amount of time to return, it will still be possible to tell if the email address is registered or not, even if the response message is identical. Also if there's some check when you register that tells you the email address is already taken or not, then this is pointless.

    – Kat
    Oct 13 at 15:31


















2


















To avoid a core hack there are two approaches I would suggest you could either create your own Model that would extend UserModelReset so that you can insert a fake user id when a valid one is not found.
Or create an override for /com_users/view/reset/tmpl/default.php and replace line 24 to not call reset.request in the subcontroller reset.php but some code of your own.



<form id="user-registration" action="<?php echo JRoute::_('index.php?option=com_users&task=reset.request'); ?>" method="post" class="form-validate form-horizontal well">


Or if the plugin you mention is something you can edit then I would suggest you do your own check if the user exists in the com_user table and if not then pass a valid but fake userid to the regular processing, just don't allow a non-existent user to be passed. Not knowing when the plugin gets involved, I can't be sure this is a valid option for you, but would be easiest and cleanest way to do it.



If you follow the process of a normal password reset then you can see what is happening and why the code hack described by @jamesgarret is not working for you and you aren't getting to the final page displayed with the 'email sent' message. I would guess that your Plugin is calling processResetRequest directly and not going through the subcontroller reset.request.



As mentioned above default.php calls the subcontrolelr reset.php and function request. function request in turn calls processResetRequest in com_user/models/reset.php



If you read what is going on processResetRequest you can see that a database call for the user email address is made and that variable of $userId is returned at line 389.



As per @jamesgarret answer at line 399 a check is done for an empty $userId and it is at this point that you do NOT want have an empty $userId. If you used the core hack from @jamesgarret with the normal processing then return true gets you back to reset.request but if your Plugin is what called processResetRequest then you need to handle the redirect to the correct page yourself.



If you haven't already checked and passed a fake user id via your plugin then at line 401 you need to create a valid user id and give it to $userId so the processing can continue with valid User Id.




(changing line 401 would be a core hack or in an extended processReserRequest)



You have to create a fake user id in your com_user table that isn't a super user and has a valid email address that you can automatically discard when it is received by your mail server/account.



The reason you need this fake user id is so that processing can complete, an email is sent and you get to the bottom of the processResetRequest so that you get returned to the request function in the reset subcontroller. This is what redirects you to com_user/views/reset/tmpl/reset.php which is the screen you want with the right message that an email has been sent and everything looks genuine.



Incidentally the message you want to appear




"An email has been sent to your email address. The email has a
verification code, please paste the verification code in the field
below to prove that you are the owner of this account."




comes from com_users/models/forms/reset_confirm.xml and is a fieldset label at line 3.



<fieldset name="default" label="COM_USERS_RESET_CONFIRM_LABEL">





share|improve this answer

































    2


















    You can use a plugin onAfterRoute event to override controller tasks in a sense. It's not perfect but it beats core hacking. The following example mimics UsersControllerReset:request() but redirects to confirmation page even when model returns false.



    defined('_JEXEC') or die;

    use JoomlaCMSLanguageText;
    use JoomlaCMSPluginCMSPlugin;
    use JoomlaCMSRouterRoute;

    class PlgSystemExample extends CMSPlugin

    protected $app;

    public function onAfterRoute()

    // Check that we are performing the correct task.
    if ($this->app->input->get('option') === 'com_users' && $this->app->input->get('task') === 'reset.request')

    $this->request();



    protected function request()

    // Check the request token.
    if (!$this->app->getSession()->checkToken('post'))

    $this->app->enqueueMessage(Text::_('JINVALID_TOKEN_NOTICE'), 'error');
    $this->app->redirect(Route::_('index.php?option=com_users&view=reset', false));


    $option = $this->app->input->get('option');

    // Define component paths. The model may need them.
    if (!defined('JPATH_COMPONENT'))

    define('JPATH_COMPONENT', JPATH_BASE . '/components/' . $option);


    if (!defined('JPATH_COMPONENT_SITE'))

    define('JPATH_COMPONENT_SITE', JPATH_SITE . '/components/' . $option);


    if (!defined('JPATH_COMPONENT_ADMINISTRATOR'))

    define('JPATH_COMPONENT_ADMINISTRATOR', JPATH_ADMINISTRATOR . '/components/' . $option);


    // Load com_users language files.
    $this->app->getLanguage()->load('com_users');

    // Register com_users models.
    JModelLegacy::addIncludePath(JPATH_SITE . '/components/com_users/models', 'UsersModel');

    // Fetch the model.
    $model = JModelLegacy::getInstance('Reset', 'UsersModel');

    // Submit the password reset request.
    $data = $this->app->input->post->get('jform', array(), 'array');
    $return = $model->processResetRequest($data);

    // Check for a hard error. It can occur when sending mail fails.
    if ($return instanceof Exception)

    // Get the error message to display.
    if ($this->app->get('error_reporting'))

    $message = $return->getMessage();

    else

    $message = Text::_('COM_USERS_RESET_REQUEST_ERROR');


    // Go back to the request form.
    $this->app->enqueueMessage($message, 'error');
    $this->app->redirect(Route::_('index.php?option=com_users&view=reset', false));


    // Redirect to confirmation page.
    $this->app->redirect(Route::_('index.php?option=com_users&view=reset&layout=confirm', false));







    share|improve this answer


























    • This would be a great plugin if someone could throw together in GitHub or whatnot so basic users could download/install.

      – YellowWebMonkey
      22 hours ago












    Your Answer








    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "555"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: false,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/4.0/"u003ecc by-sa 4.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    noCode: true, onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );







    brett is a new contributor. Be nice, and check out our Code of Conduct.









    draft saved

    draft discarded
















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fjoomla.stackexchange.com%2fquestions%2f26252%2fhow-to-prevent-password-reset-from-disclosing-private-email-addresses%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown


























    3 Answers
    3






    active

    oldest

    votes








    3 Answers
    3






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    2


















    Great Question Brett. This is one of the only core hacks I've ever had to make. If someone has a better solution then please post it here.



    In this file:
    https://github.com/joomla/joomla-cms/blob/staging/components/com_users/models/reset.php



    In the public function processResetRequest($data)



    Where it checks to see if the user exists just return true early. This thus stops the email and reset process but also shows the regular success message to the user.



    Original lines 398-404



    // Check for a user.
    if (empty($userId))

    $this->setError(JText::_('COM_USERS_INVALID_EMAIL'));
    return false;



    Changed to:



    // Check for a user.
    if (empty($userId))

    /* === BEGIN CORE HACK === */
    return true;
    /* === END CORE HACK ===== */

    $this->setError(JText::_('COM_USERS_INVALID_EMAIL'));
    return false;






    share|improve this answer




























    • Thanks for a super clear answer James. Unfortunately I'm still getting the Joomla error text box vs in-form status messages. Looking at the code you pointed me to (thanks!) I don't see why it wouldn't work at this late hour. Maybe something related to the auth-email plugin I am using changed something related? I will look at this more closely tomorrow and report my findings. BTW, I like your clear commenting, "BEGIN CORE HACK"

      – brett
      Oct 13 at 3:19












    • Note that if a nonexistent user takes a different amount of time to return, it will still be possible to tell if the email address is registered or not, even if the response message is identical. Also if there's some check when you register that tells you the email address is already taken or not, then this is pointless.

      – Kat
      Oct 13 at 15:31















    2


















    Great Question Brett. This is one of the only core hacks I've ever had to make. If someone has a better solution then please post it here.



    In this file:
    https://github.com/joomla/joomla-cms/blob/staging/components/com_users/models/reset.php



    In the public function processResetRequest($data)



    Where it checks to see if the user exists just return true early. This thus stops the email and reset process but also shows the regular success message to the user.



    Original lines 398-404



    // Check for a user.
    if (empty($userId))

    $this->setError(JText::_('COM_USERS_INVALID_EMAIL'));
    return false;



    Changed to:



    // Check for a user.
    if (empty($userId))

    /* === BEGIN CORE HACK === */
    return true;
    /* === END CORE HACK ===== */

    $this->setError(JText::_('COM_USERS_INVALID_EMAIL'));
    return false;






    share|improve this answer




























    • Thanks for a super clear answer James. Unfortunately I'm still getting the Joomla error text box vs in-form status messages. Looking at the code you pointed me to (thanks!) I don't see why it wouldn't work at this late hour. Maybe something related to the auth-email plugin I am using changed something related? I will look at this more closely tomorrow and report my findings. BTW, I like your clear commenting, "BEGIN CORE HACK"

      – brett
      Oct 13 at 3:19












    • Note that if a nonexistent user takes a different amount of time to return, it will still be possible to tell if the email address is registered or not, even if the response message is identical. Also if there's some check when you register that tells you the email address is already taken or not, then this is pointless.

      – Kat
      Oct 13 at 15:31













    2














    2










    2









    Great Question Brett. This is one of the only core hacks I've ever had to make. If someone has a better solution then please post it here.



    In this file:
    https://github.com/joomla/joomla-cms/blob/staging/components/com_users/models/reset.php



    In the public function processResetRequest($data)



    Where it checks to see if the user exists just return true early. This thus stops the email and reset process but also shows the regular success message to the user.



    Original lines 398-404



    // Check for a user.
    if (empty($userId))

    $this->setError(JText::_('COM_USERS_INVALID_EMAIL'));
    return false;



    Changed to:



    // Check for a user.
    if (empty($userId))

    /* === BEGIN CORE HACK === */
    return true;
    /* === END CORE HACK ===== */

    $this->setError(JText::_('COM_USERS_INVALID_EMAIL'));
    return false;






    share|improve this answer
















    Great Question Brett. This is one of the only core hacks I've ever had to make. If someone has a better solution then please post it here.



    In this file:
    https://github.com/joomla/joomla-cms/blob/staging/components/com_users/models/reset.php



    In the public function processResetRequest($data)



    Where it checks to see if the user exists just return true early. This thus stops the email and reset process but also shows the regular success message to the user.



    Original lines 398-404



    // Check for a user.
    if (empty($userId))

    $this->setError(JText::_('COM_USERS_INVALID_EMAIL'));
    return false;



    Changed to:



    // Check for a user.
    if (empty($userId))

    /* === BEGIN CORE HACK === */
    return true;
    /* === END CORE HACK ===== */

    $this->setError(JText::_('COM_USERS_INVALID_EMAIL'));
    return false;







    share|improve this answer















    share|improve this answer




    share|improve this answer








    edited Oct 13 at 1:49

























    answered Oct 13 at 1:44









    jamesgarrettjamesgarrett

    2,6341 gold badge5 silver badges13 bronze badges




    2,6341 gold badge5 silver badges13 bronze badges















    • Thanks for a super clear answer James. Unfortunately I'm still getting the Joomla error text box vs in-form status messages. Looking at the code you pointed me to (thanks!) I don't see why it wouldn't work at this late hour. Maybe something related to the auth-email plugin I am using changed something related? I will look at this more closely tomorrow and report my findings. BTW, I like your clear commenting, "BEGIN CORE HACK"

      – brett
      Oct 13 at 3:19












    • Note that if a nonexistent user takes a different amount of time to return, it will still be possible to tell if the email address is registered or not, even if the response message is identical. Also if there's some check when you register that tells you the email address is already taken or not, then this is pointless.

      – Kat
      Oct 13 at 15:31

















    • Thanks for a super clear answer James. Unfortunately I'm still getting the Joomla error text box vs in-form status messages. Looking at the code you pointed me to (thanks!) I don't see why it wouldn't work at this late hour. Maybe something related to the auth-email plugin I am using changed something related? I will look at this more closely tomorrow and report my findings. BTW, I like your clear commenting, "BEGIN CORE HACK"

      – brett
      Oct 13 at 3:19












    • Note that if a nonexistent user takes a different amount of time to return, it will still be possible to tell if the email address is registered or not, even if the response message is identical. Also if there's some check when you register that tells you the email address is already taken or not, then this is pointless.

      – Kat
      Oct 13 at 15:31
















    Thanks for a super clear answer James. Unfortunately I'm still getting the Joomla error text box vs in-form status messages. Looking at the code you pointed me to (thanks!) I don't see why it wouldn't work at this late hour. Maybe something related to the auth-email plugin I am using changed something related? I will look at this more closely tomorrow and report my findings. BTW, I like your clear commenting, "BEGIN CORE HACK"

    – brett
    Oct 13 at 3:19






    Thanks for a super clear answer James. Unfortunately I'm still getting the Joomla error text box vs in-form status messages. Looking at the code you pointed me to (thanks!) I don't see why it wouldn't work at this late hour. Maybe something related to the auth-email plugin I am using changed something related? I will look at this more closely tomorrow and report my findings. BTW, I like your clear commenting, "BEGIN CORE HACK"

    – brett
    Oct 13 at 3:19














    Note that if a nonexistent user takes a different amount of time to return, it will still be possible to tell if the email address is registered or not, even if the response message is identical. Also if there's some check when you register that tells you the email address is already taken or not, then this is pointless.

    – Kat
    Oct 13 at 15:31





    Note that if a nonexistent user takes a different amount of time to return, it will still be possible to tell if the email address is registered or not, even if the response message is identical. Also if there's some check when you register that tells you the email address is already taken or not, then this is pointless.

    – Kat
    Oct 13 at 15:31













    2


















    To avoid a core hack there are two approaches I would suggest you could either create your own Model that would extend UserModelReset so that you can insert a fake user id when a valid one is not found.
    Or create an override for /com_users/view/reset/tmpl/default.php and replace line 24 to not call reset.request in the subcontroller reset.php but some code of your own.



    <form id="user-registration" action="<?php echo JRoute::_('index.php?option=com_users&task=reset.request'); ?>" method="post" class="form-validate form-horizontal well">


    Or if the plugin you mention is something you can edit then I would suggest you do your own check if the user exists in the com_user table and if not then pass a valid but fake userid to the regular processing, just don't allow a non-existent user to be passed. Not knowing when the plugin gets involved, I can't be sure this is a valid option for you, but would be easiest and cleanest way to do it.



    If you follow the process of a normal password reset then you can see what is happening and why the code hack described by @jamesgarret is not working for you and you aren't getting to the final page displayed with the 'email sent' message. I would guess that your Plugin is calling processResetRequest directly and not going through the subcontroller reset.request.



    As mentioned above default.php calls the subcontrolelr reset.php and function request. function request in turn calls processResetRequest in com_user/models/reset.php



    If you read what is going on processResetRequest you can see that a database call for the user email address is made and that variable of $userId is returned at line 389.



    As per @jamesgarret answer at line 399 a check is done for an empty $userId and it is at this point that you do NOT want have an empty $userId. If you used the core hack from @jamesgarret with the normal processing then return true gets you back to reset.request but if your Plugin is what called processResetRequest then you need to handle the redirect to the correct page yourself.



    If you haven't already checked and passed a fake user id via your plugin then at line 401 you need to create a valid user id and give it to $userId so the processing can continue with valid User Id.




    (changing line 401 would be a core hack or in an extended processReserRequest)



    You have to create a fake user id in your com_user table that isn't a super user and has a valid email address that you can automatically discard when it is received by your mail server/account.



    The reason you need this fake user id is so that processing can complete, an email is sent and you get to the bottom of the processResetRequest so that you get returned to the request function in the reset subcontroller. This is what redirects you to com_user/views/reset/tmpl/reset.php which is the screen you want with the right message that an email has been sent and everything looks genuine.



    Incidentally the message you want to appear




    "An email has been sent to your email address. The email has a
    verification code, please paste the verification code in the field
    below to prove that you are the owner of this account."




    comes from com_users/models/forms/reset_confirm.xml and is a fieldset label at line 3.



    <fieldset name="default" label="COM_USERS_RESET_CONFIRM_LABEL">





    share|improve this answer






























      2


















      To avoid a core hack there are two approaches I would suggest you could either create your own Model that would extend UserModelReset so that you can insert a fake user id when a valid one is not found.
      Or create an override for /com_users/view/reset/tmpl/default.php and replace line 24 to not call reset.request in the subcontroller reset.php but some code of your own.



      <form id="user-registration" action="<?php echo JRoute::_('index.php?option=com_users&task=reset.request'); ?>" method="post" class="form-validate form-horizontal well">


      Or if the plugin you mention is something you can edit then I would suggest you do your own check if the user exists in the com_user table and if not then pass a valid but fake userid to the regular processing, just don't allow a non-existent user to be passed. Not knowing when the plugin gets involved, I can't be sure this is a valid option for you, but would be easiest and cleanest way to do it.



      If you follow the process of a normal password reset then you can see what is happening and why the code hack described by @jamesgarret is not working for you and you aren't getting to the final page displayed with the 'email sent' message. I would guess that your Plugin is calling processResetRequest directly and not going through the subcontroller reset.request.



      As mentioned above default.php calls the subcontrolelr reset.php and function request. function request in turn calls processResetRequest in com_user/models/reset.php



      If you read what is going on processResetRequest you can see that a database call for the user email address is made and that variable of $userId is returned at line 389.



      As per @jamesgarret answer at line 399 a check is done for an empty $userId and it is at this point that you do NOT want have an empty $userId. If you used the core hack from @jamesgarret with the normal processing then return true gets you back to reset.request but if your Plugin is what called processResetRequest then you need to handle the redirect to the correct page yourself.



      If you haven't already checked and passed a fake user id via your plugin then at line 401 you need to create a valid user id and give it to $userId so the processing can continue with valid User Id.




      (changing line 401 would be a core hack or in an extended processReserRequest)



      You have to create a fake user id in your com_user table that isn't a super user and has a valid email address that you can automatically discard when it is received by your mail server/account.



      The reason you need this fake user id is so that processing can complete, an email is sent and you get to the bottom of the processResetRequest so that you get returned to the request function in the reset subcontroller. This is what redirects you to com_user/views/reset/tmpl/reset.php which is the screen you want with the right message that an email has been sent and everything looks genuine.



      Incidentally the message you want to appear




      "An email has been sent to your email address. The email has a
      verification code, please paste the verification code in the field
      below to prove that you are the owner of this account."




      comes from com_users/models/forms/reset_confirm.xml and is a fieldset label at line 3.



      <fieldset name="default" label="COM_USERS_RESET_CONFIRM_LABEL">





      share|improve this answer




























        2














        2










        2









        To avoid a core hack there are two approaches I would suggest you could either create your own Model that would extend UserModelReset so that you can insert a fake user id when a valid one is not found.
        Or create an override for /com_users/view/reset/tmpl/default.php and replace line 24 to not call reset.request in the subcontroller reset.php but some code of your own.



        <form id="user-registration" action="<?php echo JRoute::_('index.php?option=com_users&task=reset.request'); ?>" method="post" class="form-validate form-horizontal well">


        Or if the plugin you mention is something you can edit then I would suggest you do your own check if the user exists in the com_user table and if not then pass a valid but fake userid to the regular processing, just don't allow a non-existent user to be passed. Not knowing when the plugin gets involved, I can't be sure this is a valid option for you, but would be easiest and cleanest way to do it.



        If you follow the process of a normal password reset then you can see what is happening and why the code hack described by @jamesgarret is not working for you and you aren't getting to the final page displayed with the 'email sent' message. I would guess that your Plugin is calling processResetRequest directly and not going through the subcontroller reset.request.



        As mentioned above default.php calls the subcontrolelr reset.php and function request. function request in turn calls processResetRequest in com_user/models/reset.php



        If you read what is going on processResetRequest you can see that a database call for the user email address is made and that variable of $userId is returned at line 389.



        As per @jamesgarret answer at line 399 a check is done for an empty $userId and it is at this point that you do NOT want have an empty $userId. If you used the core hack from @jamesgarret with the normal processing then return true gets you back to reset.request but if your Plugin is what called processResetRequest then you need to handle the redirect to the correct page yourself.



        If you haven't already checked and passed a fake user id via your plugin then at line 401 you need to create a valid user id and give it to $userId so the processing can continue with valid User Id.




        (changing line 401 would be a core hack or in an extended processReserRequest)



        You have to create a fake user id in your com_user table that isn't a super user and has a valid email address that you can automatically discard when it is received by your mail server/account.



        The reason you need this fake user id is so that processing can complete, an email is sent and you get to the bottom of the processResetRequest so that you get returned to the request function in the reset subcontroller. This is what redirects you to com_user/views/reset/tmpl/reset.php which is the screen you want with the right message that an email has been sent and everything looks genuine.



        Incidentally the message you want to appear




        "An email has been sent to your email address. The email has a
        verification code, please paste the verification code in the field
        below to prove that you are the owner of this account."




        comes from com_users/models/forms/reset_confirm.xml and is a fieldset label at line 3.



        <fieldset name="default" label="COM_USERS_RESET_CONFIRM_LABEL">





        share|improve this answer














        To avoid a core hack there are two approaches I would suggest you could either create your own Model that would extend UserModelReset so that you can insert a fake user id when a valid one is not found.
        Or create an override for /com_users/view/reset/tmpl/default.php and replace line 24 to not call reset.request in the subcontroller reset.php but some code of your own.



        <form id="user-registration" action="<?php echo JRoute::_('index.php?option=com_users&task=reset.request'); ?>" method="post" class="form-validate form-horizontal well">


        Or if the plugin you mention is something you can edit then I would suggest you do your own check if the user exists in the com_user table and if not then pass a valid but fake userid to the regular processing, just don't allow a non-existent user to be passed. Not knowing when the plugin gets involved, I can't be sure this is a valid option for you, but would be easiest and cleanest way to do it.



        If you follow the process of a normal password reset then you can see what is happening and why the code hack described by @jamesgarret is not working for you and you aren't getting to the final page displayed with the 'email sent' message. I would guess that your Plugin is calling processResetRequest directly and not going through the subcontroller reset.request.



        As mentioned above default.php calls the subcontrolelr reset.php and function request. function request in turn calls processResetRequest in com_user/models/reset.php



        If you read what is going on processResetRequest you can see that a database call for the user email address is made and that variable of $userId is returned at line 389.



        As per @jamesgarret answer at line 399 a check is done for an empty $userId and it is at this point that you do NOT want have an empty $userId. If you used the core hack from @jamesgarret with the normal processing then return true gets you back to reset.request but if your Plugin is what called processResetRequest then you need to handle the redirect to the correct page yourself.



        If you haven't already checked and passed a fake user id via your plugin then at line 401 you need to create a valid user id and give it to $userId so the processing can continue with valid User Id.




        (changing line 401 would be a core hack or in an extended processReserRequest)



        You have to create a fake user id in your com_user table that isn't a super user and has a valid email address that you can automatically discard when it is received by your mail server/account.



        The reason you need this fake user id is so that processing can complete, an email is sent and you get to the bottom of the processResetRequest so that you get returned to the request function in the reset subcontroller. This is what redirects you to com_user/views/reset/tmpl/reset.php which is the screen you want with the right message that an email has been sent and everything looks genuine.



        Incidentally the message you want to appear




        "An email has been sent to your email address. The email has a
        verification code, please paste the verification code in the field
        below to prove that you are the owner of this account."




        comes from com_users/models/forms/reset_confirm.xml and is a fieldset label at line 3.



        <fieldset name="default" label="COM_USERS_RESET_CONFIRM_LABEL">






        share|improve this answer













        share|improve this answer




        share|improve this answer










        answered Oct 13 at 13:09









        IrataIrata

        6421 silver badge9 bronze badges




        6421 silver badge9 bronze badges
























            2


















            You can use a plugin onAfterRoute event to override controller tasks in a sense. It's not perfect but it beats core hacking. The following example mimics UsersControllerReset:request() but redirects to confirmation page even when model returns false.



            defined('_JEXEC') or die;

            use JoomlaCMSLanguageText;
            use JoomlaCMSPluginCMSPlugin;
            use JoomlaCMSRouterRoute;

            class PlgSystemExample extends CMSPlugin

            protected $app;

            public function onAfterRoute()

            // Check that we are performing the correct task.
            if ($this->app->input->get('option') === 'com_users' && $this->app->input->get('task') === 'reset.request')

            $this->request();



            protected function request()

            // Check the request token.
            if (!$this->app->getSession()->checkToken('post'))

            $this->app->enqueueMessage(Text::_('JINVALID_TOKEN_NOTICE'), 'error');
            $this->app->redirect(Route::_('index.php?option=com_users&view=reset', false));


            $option = $this->app->input->get('option');

            // Define component paths. The model may need them.
            if (!defined('JPATH_COMPONENT'))

            define('JPATH_COMPONENT', JPATH_BASE . '/components/' . $option);


            if (!defined('JPATH_COMPONENT_SITE'))

            define('JPATH_COMPONENT_SITE', JPATH_SITE . '/components/' . $option);


            if (!defined('JPATH_COMPONENT_ADMINISTRATOR'))

            define('JPATH_COMPONENT_ADMINISTRATOR', JPATH_ADMINISTRATOR . '/components/' . $option);


            // Load com_users language files.
            $this->app->getLanguage()->load('com_users');

            // Register com_users models.
            JModelLegacy::addIncludePath(JPATH_SITE . '/components/com_users/models', 'UsersModel');

            // Fetch the model.
            $model = JModelLegacy::getInstance('Reset', 'UsersModel');

            // Submit the password reset request.
            $data = $this->app->input->post->get('jform', array(), 'array');
            $return = $model->processResetRequest($data);

            // Check for a hard error. It can occur when sending mail fails.
            if ($return instanceof Exception)

            // Get the error message to display.
            if ($this->app->get('error_reporting'))

            $message = $return->getMessage();

            else

            $message = Text::_('COM_USERS_RESET_REQUEST_ERROR');


            // Go back to the request form.
            $this->app->enqueueMessage($message, 'error');
            $this->app->redirect(Route::_('index.php?option=com_users&view=reset', false));


            // Redirect to confirmation page.
            $this->app->redirect(Route::_('index.php?option=com_users&view=reset&layout=confirm', false));







            share|improve this answer


























            • This would be a great plugin if someone could throw together in GitHub or whatnot so basic users could download/install.

              – YellowWebMonkey
              22 hours ago















            2


















            You can use a plugin onAfterRoute event to override controller tasks in a sense. It's not perfect but it beats core hacking. The following example mimics UsersControllerReset:request() but redirects to confirmation page even when model returns false.



            defined('_JEXEC') or die;

            use JoomlaCMSLanguageText;
            use JoomlaCMSPluginCMSPlugin;
            use JoomlaCMSRouterRoute;

            class PlgSystemExample extends CMSPlugin

            protected $app;

            public function onAfterRoute()

            // Check that we are performing the correct task.
            if ($this->app->input->get('option') === 'com_users' && $this->app->input->get('task') === 'reset.request')

            $this->request();



            protected function request()

            // Check the request token.
            if (!$this->app->getSession()->checkToken('post'))

            $this->app->enqueueMessage(Text::_('JINVALID_TOKEN_NOTICE'), 'error');
            $this->app->redirect(Route::_('index.php?option=com_users&view=reset', false));


            $option = $this->app->input->get('option');

            // Define component paths. The model may need them.
            if (!defined('JPATH_COMPONENT'))

            define('JPATH_COMPONENT', JPATH_BASE . '/components/' . $option);


            if (!defined('JPATH_COMPONENT_SITE'))

            define('JPATH_COMPONENT_SITE', JPATH_SITE . '/components/' . $option);


            if (!defined('JPATH_COMPONENT_ADMINISTRATOR'))

            define('JPATH_COMPONENT_ADMINISTRATOR', JPATH_ADMINISTRATOR . '/components/' . $option);


            // Load com_users language files.
            $this->app->getLanguage()->load('com_users');

            // Register com_users models.
            JModelLegacy::addIncludePath(JPATH_SITE . '/components/com_users/models', 'UsersModel');

            // Fetch the model.
            $model = JModelLegacy::getInstance('Reset', 'UsersModel');

            // Submit the password reset request.
            $data = $this->app->input->post->get('jform', array(), 'array');
            $return = $model->processResetRequest($data);

            // Check for a hard error. It can occur when sending mail fails.
            if ($return instanceof Exception)

            // Get the error message to display.
            if ($this->app->get('error_reporting'))

            $message = $return->getMessage();

            else

            $message = Text::_('COM_USERS_RESET_REQUEST_ERROR');


            // Go back to the request form.
            $this->app->enqueueMessage($message, 'error');
            $this->app->redirect(Route::_('index.php?option=com_users&view=reset', false));


            // Redirect to confirmation page.
            $this->app->redirect(Route::_('index.php?option=com_users&view=reset&layout=confirm', false));







            share|improve this answer


























            • This would be a great plugin if someone could throw together in GitHub or whatnot so basic users could download/install.

              – YellowWebMonkey
              22 hours ago













            2














            2










            2









            You can use a plugin onAfterRoute event to override controller tasks in a sense. It's not perfect but it beats core hacking. The following example mimics UsersControllerReset:request() but redirects to confirmation page even when model returns false.



            defined('_JEXEC') or die;

            use JoomlaCMSLanguageText;
            use JoomlaCMSPluginCMSPlugin;
            use JoomlaCMSRouterRoute;

            class PlgSystemExample extends CMSPlugin

            protected $app;

            public function onAfterRoute()

            // Check that we are performing the correct task.
            if ($this->app->input->get('option') === 'com_users' && $this->app->input->get('task') === 'reset.request')

            $this->request();



            protected function request()

            // Check the request token.
            if (!$this->app->getSession()->checkToken('post'))

            $this->app->enqueueMessage(Text::_('JINVALID_TOKEN_NOTICE'), 'error');
            $this->app->redirect(Route::_('index.php?option=com_users&view=reset', false));


            $option = $this->app->input->get('option');

            // Define component paths. The model may need them.
            if (!defined('JPATH_COMPONENT'))

            define('JPATH_COMPONENT', JPATH_BASE . '/components/' . $option);


            if (!defined('JPATH_COMPONENT_SITE'))

            define('JPATH_COMPONENT_SITE', JPATH_SITE . '/components/' . $option);


            if (!defined('JPATH_COMPONENT_ADMINISTRATOR'))

            define('JPATH_COMPONENT_ADMINISTRATOR', JPATH_ADMINISTRATOR . '/components/' . $option);


            // Load com_users language files.
            $this->app->getLanguage()->load('com_users');

            // Register com_users models.
            JModelLegacy::addIncludePath(JPATH_SITE . '/components/com_users/models', 'UsersModel');

            // Fetch the model.
            $model = JModelLegacy::getInstance('Reset', 'UsersModel');

            // Submit the password reset request.
            $data = $this->app->input->post->get('jform', array(), 'array');
            $return = $model->processResetRequest($data);

            // Check for a hard error. It can occur when sending mail fails.
            if ($return instanceof Exception)

            // Get the error message to display.
            if ($this->app->get('error_reporting'))

            $message = $return->getMessage();

            else

            $message = Text::_('COM_USERS_RESET_REQUEST_ERROR');


            // Go back to the request form.
            $this->app->enqueueMessage($message, 'error');
            $this->app->redirect(Route::_('index.php?option=com_users&view=reset', false));


            // Redirect to confirmation page.
            $this->app->redirect(Route::_('index.php?option=com_users&view=reset&layout=confirm', false));







            share|improve this answer














            You can use a plugin onAfterRoute event to override controller tasks in a sense. It's not perfect but it beats core hacking. The following example mimics UsersControllerReset:request() but redirects to confirmation page even when model returns false.



            defined('_JEXEC') or die;

            use JoomlaCMSLanguageText;
            use JoomlaCMSPluginCMSPlugin;
            use JoomlaCMSRouterRoute;

            class PlgSystemExample extends CMSPlugin

            protected $app;

            public function onAfterRoute()

            // Check that we are performing the correct task.
            if ($this->app->input->get('option') === 'com_users' && $this->app->input->get('task') === 'reset.request')

            $this->request();



            protected function request()

            // Check the request token.
            if (!$this->app->getSession()->checkToken('post'))

            $this->app->enqueueMessage(Text::_('JINVALID_TOKEN_NOTICE'), 'error');
            $this->app->redirect(Route::_('index.php?option=com_users&view=reset', false));


            $option = $this->app->input->get('option');

            // Define component paths. The model may need them.
            if (!defined('JPATH_COMPONENT'))

            define('JPATH_COMPONENT', JPATH_BASE . '/components/' . $option);


            if (!defined('JPATH_COMPONENT_SITE'))

            define('JPATH_COMPONENT_SITE', JPATH_SITE . '/components/' . $option);


            if (!defined('JPATH_COMPONENT_ADMINISTRATOR'))

            define('JPATH_COMPONENT_ADMINISTRATOR', JPATH_ADMINISTRATOR . '/components/' . $option);


            // Load com_users language files.
            $this->app->getLanguage()->load('com_users');

            // Register com_users models.
            JModelLegacy::addIncludePath(JPATH_SITE . '/components/com_users/models', 'UsersModel');

            // Fetch the model.
            $model = JModelLegacy::getInstance('Reset', 'UsersModel');

            // Submit the password reset request.
            $data = $this->app->input->post->get('jform', array(), 'array');
            $return = $model->processResetRequest($data);

            // Check for a hard error. It can occur when sending mail fails.
            if ($return instanceof Exception)

            // Get the error message to display.
            if ($this->app->get('error_reporting'))

            $message = $return->getMessage();

            else

            $message = Text::_('COM_USERS_RESET_REQUEST_ERROR');


            // Go back to the request form.
            $this->app->enqueueMessage($message, 'error');
            $this->app->redirect(Route::_('index.php?option=com_users&view=reset', false));


            // Redirect to confirmation page.
            $this->app->redirect(Route::_('index.php?option=com_users&view=reset&layout=confirm', false));








            share|improve this answer













            share|improve this answer




            share|improve this answer










            answered 2 days ago









            SharkySharky

            3,7063 silver badges11 bronze badges




            3,7063 silver badges11 bronze badges















            • This would be a great plugin if someone could throw together in GitHub or whatnot so basic users could download/install.

              – YellowWebMonkey
              22 hours ago

















            • This would be a great plugin if someone could throw together in GitHub or whatnot so basic users could download/install.

              – YellowWebMonkey
              22 hours ago
















            This would be a great plugin if someone could throw together in GitHub or whatnot so basic users could download/install.

            – YellowWebMonkey
            22 hours ago





            This would be a great plugin if someone could throw together in GitHub or whatnot so basic users could download/install.

            – YellowWebMonkey
            22 hours ago











            brett is a new contributor. Be nice, and check out our Code of Conduct.









            draft saved

            draft discarded

















            brett is a new contributor. Be nice, and check out our Code of Conduct.












            brett is a new contributor. Be nice, and check out our Code of Conduct.











            brett is a new contributor. Be nice, and check out our Code of Conduct.














            Thanks for contributing an answer to Joomla Stack Exchange!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fjoomla.stackexchange.com%2fquestions%2f26252%2fhow-to-prevent-password-reset-from-disclosing-private-email-addresses%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown









            Popular posts from this blog

            Canceling a color specificationRandomly assigning color to Graphics3D objects?Default color for Filling in Mathematica 9Coloring specific elements of sets with a prime modified order in an array plotHow to pick a color differing significantly from the colors already in a given color list?Detection of the text colorColor numbers based on their valueCan color schemes for use with ColorData include opacity specification?My dynamic color schemes

            Invision Community Contents History See also References External links Navigation menuProprietaryinvisioncommunity.comIPS Community ForumsIPS Community Forumsthis blog entry"License Changes, IP.Board 3.4, and the Future""Interview -- Matt Mecham of Ibforums""CEO Invision Power Board, Matt Mecham Is a Liar, Thief!"IPB License Explanation 1.3, 1.3.1, 2.0, and 2.1ArchivedSecurity Fixes, Updates And Enhancements For IPB 1.3.1Archived"New Demo Accounts - Invision Power Services"the original"New Default Skin"the original"Invision Power Board 3.0.0 and Applications Released"the original"Archived copy"the original"Perpetual licenses being done away with""Release Notes - Invision Power Services""Introducing: IPS Community Suite 4!"Invision Community Release Notes

            199年 目錄 大件事 到箇年出世嗰人 到箇年死嗰人 節慶、風俗習慣 導覽選單