How to add recaptcha to PHPLIST

PHPlist is a great free PHP based mailing list installation you can add to your server, like WordPress – also running with MySQL. This has been added to version v3.2.7.

Note that if you upgrade your installation, you will need to add this again – and completely new versions of PHPLIST may change how they work, though it shouldn’t be so drastic as to render this all unusable. 

Admin login

Open /list/admin/login.php

at the bottom of the file, add this code before the submit button:

 echo ' <tr><td><script src="https://www.google.com/recaptcha/api.js" async defer></script><div class="g-recaptcha" data-sitekey="###YOUR-SITE-KEY###" data-size="compact"></div><br /><input class="submit" type="submit" name="process" value="' . $GLOBALS['I18N']->get('Continue') . '" /></td></tr>';

Note this ‘name=process, get->Continue input appears in 2 places

Then open /list/admin/index.php and search for this code, adding what’s in green, replace the red text with your own ID, Classes and Google ID codes.

 if ((!isset($_SESSION['adminloggedin']) || !$_SESSION['adminloggedin']) && isset($_REQUEST['login']) && isset($_REQUEST['password']) && !empty($_REQUEST['password'])) {

 /*RECAP*/
$captcha = "";
if (isset($_POST["g-recaptcha-response"])){
 $captcha = $_POST["g-recaptcha-response"];
}
if (!$captcha){
 echo '<p style="color:#fff;padding: 25px; background-color: #2f2f2f;">Please complete the captcha to prove you\'re not an internet virus robot <a href="'. $_SERVER['REQUEST_URI'] .'" id="pushkacombutton" >Go Back</a></p>';
 exit;
 return; //this switches off the index file - so it shows a blank page. I'll try change it to just break out of this if clause
}
// handling the captcha and checking if it's ok
$secret = "###YOUR-SITE-SECRET-KEY###";
$response = json_decode(file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=".$secret."&response=".$captcha."&remoteip=".$_SERVER["REMOTE_ADDR"]), true);
// if the captcha is cleared with google, continue PHPLIST auth as usual, else - stop index.php
if (intval($response["success"]) !== 1) {
 echo '<p style="color:#fff;padding: 25px; background-color: #2f2f2f;">Captcha error - please complete the captcha to prove you\'re not an internet virus robot <a href="'. $_SERVER['REQUEST_URI'] .'" id="pushkacombutton" >Go Back</a></p>';
 exit;
} 

And there you have it. Register for recaptcha for free by googling it, add your site domain(s) to make them work.

Subscribe/ unsubscribe pages

This may be a little bit more tricky – since there are more than one ways to do this – so you don’t want to block real people, but you don’t want to leave a loophole for spammers.

These are the ways to subscribe/ unsubscribe to lists:

  • Through your installation index.php file /list/ – there is a form that submits using POST
  • Through an email link GET request, UID and unsubscribe variables
  • Through an optional 3rd party form (you can have a subscribe form sent through ajax on your website which subscribes people without them ever seeing your PHPLIST installation – if you do this – it will be the same process as the 1st form, so you can send the recaptcha value along with the ajax request

The strategy I’m using for now is to check if POST>>email value is being sent, if so, there should also be a recaptcha POST entry. For email unsubscribe links, they will use GET – and they obviously can’t use recaptcha, unless you create an intermediary page. 

/list/index.php

$userid = '';
$userpassword = '';
$emailcheck = '';


/*recap*/
if(isset($_POST['email'])){ //recap check for sub/unsub via post
 $captcha = "";
 if (isset($_POST["g-recaptcha-response"])){
 $captcha = $_POST["g-recaptcha-response"];
 }
 if (!$captcha){
 echo '<p style="padding: 25px;" >Please complete the captcha to prove you\'re not an internet virus robot <button onclick="goBack()" id="pushkacombutton" >Go Back</button> <script> function goBack() { window.history.back();} </script></p>';
 exit;
 return; //this switches off the index file - so it shows a blank page. I'll try change it to just break out of this if clause
 }
 // handling the captcha and checking if it's ok
 $secret = "###YOUR-SITE-SECRET-KEY###";
 $response = json_decode(file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=".$secret."&response=".$captcha."&remoteip=".$_SERVER["REMOTE_ADDR"]), true);
 // if the captcha is cleared with google, continue PHPLIST auth as usual, else - stop index.php
 if (intval($response["success"]) !== 1) {
 echo '<p style="padding: 25px;" >Captcha error - please complete the captcha to prove you\'re not an internet virus robot <button onclick="goBack()" id="pushkacombutton" >Go Back</button> <script> function goBack() { window.history.back();} </script></p>';
 exit;
 return; //this switches off the index file - so it shows a blank page. I'll try change it to just break out of this if clause
 } 
}

in the same index file – you can add a recaptcha field for the login form

 $html .= '</table>';
 $html .= '<p><script src="https://www.google.com/recaptcha/api.js" async defer></script><div class="g-recaptcha" data-sitekey="###YOUR-SITE-KEY###" ></div><br /><input type=submit name="login" value="' . $GLOBALS['strLogin'] . '"></p>';

Then to add recatcha to the subscribe form:

 if (USE_SPAM_BLOCK) {
 $html .= '<div style="display:none"><input type="text" name="VerificationCodeX" value="" size="20"></div>';
 }
 $html .= '<p><script src="https://www.google.com/recaptcha/api.js" async defer></script><div class="g-recaptcha" data-sitekey="###YOUR-SITE-KEY###" ></div><br /><input type=submit name="subscribe" value="' . $GLOBALS['pagedata']['button'] . '" onClick="return checkform();"></p></form>';

And finally the unsubscribe form:

 if (!$email) {
 $res .= '<script src="https://www.google.com/recaptcha/api.js" async defer></script><div class="g-recaptcha" data-sitekey="###YOUR-SITE-KEY###" ></div><br /><input type="submit" name="unsubscribe" value="' . $GLOBALS['strContinue'] . '"></form>';

There is another unsubscribe submit button:

        $res .= '<p><script src="https://www.google.com/recaptcha/api.js" async defer></script><div class="g-recaptcha" data-sitekey="###YOUR-SITE-KEY###" ></div><br /><input type=submit name="unsubscribe" value="' . $GLOBALS['strUnsubscribe'] . '"></p>';

The CSS I use for my PHPLIST instalation is:

#newsfeed,#forgotpassword-form,#context-menu,.buttonhelp {display: none;}
body #pushkacombutton,body #login{
 background-color: #4f8ff5 ;
 color: #fff !important;
 padding: 8px 30px !important;
 text-align: center ;
 white-space: nowrap ;
 vertical-align: middle ;
 -ms-touch-action: manipulation ;
 touch-action: manipulation ;
 cursor: pointer ;
 -webkit-user-select: none ;
 -moz-user-select: none ;
 -ms-user-select: none ;
 user-select: none ;
 background-image: none ;
 position: relative ;
 border: 0 ;
 margin: 10px 1px ;
 cursor: pointer ;
 border-radius: 2px ;
 text-decoration: none ;
 transition: background-color .2s ease,box-shadow .28s cubic-bezier(.4,0,.2,1) ;
 outline: none ;
 height: auto ;
 line-height: inherit ;
}
body #login:hover,body #login:active,body #pushkacombutton:hover,body #pushkacombutton:active{
 color: #fff !important;
 box-shadow: 0 1px 6px 0 rgba(0,0,0,.12), 0 1px 6px 0 rgba(0,0,0,.12) !important ;
 background-color: #1d3da8 !important ;
 background-image: none !important;
 -webkit-user-select: none !important ;
 -moz-user-select: none !important ;
 -ms-user-select: none !important ;
 user-select: none !important;
 background-image: none !important ;
 border: 0 !important ;
 border-radius: 2px !important ;
 outline: none !important ;height: auto ;line-height: inherit ;
 text-align: center ;
 white-space: nowrap ;
 vertical-align: middle ;
 -ms-touch-action: manipulation ;
 touch-action: manipulation ;
}

You can add an external style sheet to the header here:

Add to /list/admin/ui/dressprow/pagetop_minified.php

And you can replace the logo of the site here:

/list/admin/ui/dressprow/header.inc