Kian Posted July 22, 2020 Share Posted July 22, 2020 (edited) The following hook allows customers to login to Plesk, cPanel, DirectAdmin and any other panel directly from My Services list. Here's a preview (last column). Below I'm going to post the action hook but keep in mind that you'll need to make some changes to a couple of template files. The hook works with any control panel. The only requirement is that servers and products have been configured correctly. <?php /** * Auto-Login to cPanel/Plesk from My Services * * @written_by Kian */ use WHMCS\Database\Capsule; add_hook('ClientAreaPage', 1, function($vars) { if ($vars['filename'] == 'clientarea' AND $_GET['action'] == 'services') { $productIDs = Capsule::select(Capsule::raw('SELECT t1.id, t2.type FROM tblhosting AS t1 LEFT JOIN tblservers AS t2 ON t1.server = t2.id WHERE t1.userid = ' . $_SESSION['uid'] . ' AND t1.server != "0" AND t1.domainstatus IN ("Active", "Suspended") AND t1.username IS NOT NULL AND t1.password IS NOT NULL AND t2.type IS NOT NULL')); foreach ($productIDs as $v) { $output['kt_autologin'][$v->id] = $v; } return $output; } }); add_hook('ClientAreaHeadOutput', 1, function($vars) { if ($vars['filename'] == 'clientarea' AND $_GET['action'] == 'productdetails' AND $_GET['id'] AND $_GET['autologin']) { return <<<HTML <script type="text/javascript"> $(document).ready(function() { $("#domain form").removeAttr('target'); $("#domain form").submit(); }); </script> HTML; } }); Open your templates/{YOUR_TEMPLATE}/clientareaproducts.tpl where we need to add the new column. Let's begin from thead section. Add a new column like follows. Replace "Manage" defining a $LANG variable for multi-language support. Next move to tbody right inside foreach loop. Create a new cell like follows. <td class="text-center"> {if $kt_autologin[$service.id]} <div class="btn-group btn-group-sm plesk-login" style="width:60px;"> <a href="clientarea.php?action=productdetails&id={$service.id}&autologin=1" class="btn btn-primary btn-xs" alt="Click to Login" title="Click to Login" style="padding: 2px 5px;"><img src="templates/{$template}/img/katamaze_autologin/{$kt_autologin[$service.id]->type}.png" style="height:22px; max-width:39px"> <i class="fa fa-sign-in fa-fw" aria-hidden="true"></i></a> </div> {/if} </td> Replace "Click to Login" (alt and title attributes) with a $LANG variable. To display Plesk, cPanel, DirectAdmin (...) logo inside the button, create this directory templates/{YOUR_TEMPLATE}/img/katamaze_autologin. Here you have to add all logos in PNG format. The name of the file should be equal to module's system name: plesk.png cpanel.png directadmin.png etc. Now we have to disable sorting for the newly added column. At the very top of your template there's the following statement. Change (or add) noSortColumns="4" accordingly. "4" means that the 5th column will be not sortable (column count starts from zero). {include file="$template/includes/tablelist.tpl" tableName="ServicesList" noSortColumns="4" filterColumn="3"} Last but not least, open templates/{YOUR_TEMPLATE}/includes/head.tpl. Place this code at the very bottom of the file. {if $smarty.get.autologin} <style> body { visibility:hidden; } </style> {/if} A little bit of background For years I get used to show these buttons with a different approach. Basically I was retrieving and decrypting usernames and passwords from tblhosting and performing login with a separate form. For more than one reason (security & maintainability) I switched to this other approach. Edited July 22, 2020 by Kian 2 Quote Link to comment Share on other sites More sharing options...
brian! Posted July 22, 2020 Share Posted July 22, 2020 3 hours ago, Kian said: Replace "Click to Login" (alt and title attributes) with a $LANG variable. To display Plesk, cPanel, DirectAdmin (...) logo inside the button, create this directory templates/{YOUR_TEMPLATE}/img/katamaze_autologin. Here you have to add all logos in PNG format. it's a pity there aren't plesk or DA icons in FA5 - I can see they've been requested, and you will be able to upload your own icons with FA6 (when that arrives).... though I suppose there's an argument that you don't need to identify the server type in the icon/image as the user probably won't care less what it is. 3 hours ago, Kian said: Now we have to disable sorting for the newly added column. At the very top of your template there's the following statement. Change (or add) noSortColumns="4" accordingly. "4" means that the 5th column will be not sortable (column count starts from zero). if you were going to do this, shouldn't it be 0,5 rather than just 4 ? by default, the first column would contain the SSL icons (not shown on your screenshot) - so I think for most users, the "Manage" column would be the sixth, hence to use 0,5 to disable sorting on the first (SSL) and last (Manage) columns ?? 3 hours ago, Kian said: For years I get used to show these buttons with a different approach. Basically I was retrieving and decrypting usernames and passwords from tblhosting and performing login with a separate form. For more than one reason (security & maintainability) I switched to this other approach. does autologin functionality exist by default when you pass it in a url to clientarea.php or is that functionality that you've added elsewhere locally ? clientarea.php?action=productdetails&id={$service.id}&autologin=1 for me, it would just redirect to the productdetails page - however, if I change the link to... clientarea.php?action=productdetails&id={$service.id}&dosinglesignon=1 then that will log directly into cPanel from the My Services page - not sure if the same technique would work for plesk or DA ?? 0 Quote Link to comment Share on other sites More sharing options...
Kian Posted July 22, 2020 Author Share Posted July 22, 2020 (edited) 28 minutes ago, brian! said: if you were going to do this, shouldn't it be 0,5 rather than just 4 ? by default, the first column would contain the SSL icons (not shown on your screenshot) - so I think for most users, the "Manage" column would be the sixth, hence to use 0,5 to disable sorting on the first (SSL) and last (Manage) columns ?? That's correct. On standard WHMCS it is noSortColumns="0,5". Personally I always remove SSL column 😛 28 minutes ago, brian! said: does autologin functionality exist by default when you pass it in a url to clientarea.php or is that functionality that you've added elsewhere locally ? You can't belive how stupid is this script 🤣 When I'm on this URL... clientarea.php?action=productdetails&id={$service.id}&autologin=1 I run a jQuery script (the one in ClientAreaHeadOutput) that automatically submits this form... Anyway you are correct. cPanel is different. I will post the updated script asap. The reason why I'm using this approach is that I got tired to reinvent the wheel every time Plesk/DA or any other panel changes the API. The "auto-login" integrated in WHMCS always work (on paper). I prefer to use it instead of repeating and updating integrations with things like Centova, Plesk etc. Edited July 22, 2020 by Kian 0 Quote Link to comment Share on other sites More sharing options...
Kian Posted July 24, 2020 Author Share Posted July 24, 2020 The updated version below solves the problem with cPanel. I've also prepared a switch() to deal with any other possible exception. <?php /** * Auto-Login to cPanel/Plesk from My Services * * @writtenby Kian */ // IMPORTANT! The hook requires changes to two template files. Read the following for instructions // https://github.com/Katamaze/WHMCS-Free-Action-Hooks/blob/master/README.md#cpanel--plesk-login-button-in-my-services use WHMCS\Database\Capsule; add_hook('ClientAreaPage', 1, function($vars) { if ($vars['filename'] == 'clientarea' AND $_GET['action'] == 'services' AND $_SESSION['uid']) { $productIDs = Capsule::select(Capsule::raw('SELECT t1.id, t2.type FROM tblhosting AS t1 LEFT JOIN tblservers AS t2 ON t1.server = t2.id WHERE t1.userid = ' . $_SESSION['uid'] . ' AND t1.server != "0" AND t1.domainstatus IN ("Active", "Suspended") AND t1.username IS NOT NULL AND t1.password IS NOT NULL AND t2.type IS NOT NULL')); foreach ($productIDs as $v) { $output['kt_autologin'][$v->id] = $v; } return $output; } elseif ($vars['filename'] == 'clientarea' AND $_GET['action'] == 'productdetails' AND $_GET['id'] AND $_GET['autologin']) { $product = Capsule::select(Capsule::raw('SELECT t2.type FROM tblhosting AS t1 LEFT JOIN tblservers AS t2 ON t1.server = t2.id WHERE t1.id = ' . $_GET['id'] . ' AND t1.server != "0" AND t1.domainstatus IN ("Active", "Suspended") AND t1.username IS NOT NULL AND t1.password IS NOT NULL AND t2.type IS NOT NULL LIMIT 1'))[0]; switch ($product->type) { case 'cpanel': header('Location: clientarea.php?action=productdetails&id=' . $_GET['id'] . '&dosinglesignon=1'); die(); break; } } }); add_hook('ClientAreaHeadOutput', 1, function($vars) { if ($vars['filename'] == 'clientarea' AND $_GET['action'] == 'productdetails' AND $_GET['id'] AND $_GET['autologin']) { return <<<HTML <script type="text/javascript"> $(document).ready(function() { $("#domain form").removeAttr('target'); $("#domain form").submit(); }); </script> HTML; } }); 0 Quote Link to comment Share on other sites More sharing options...
brian! Posted July 25, 2020 Share Posted July 25, 2020 14 hours ago, Kian said: The updated version below solves the problem with cPanel. I've also prepared a switch() to deal with any other possible exception. in one of my test accounts that has active cPanel products within it, it's returning manage buttons for 2 services - one of them has a valid username & password and that now logs straight into cPanel as expected; however, the other service doesn't have a domain or username entry (both are empty), but the hook is still generating a manage button for it? a couple of other thoughts re the documentation... there is already a default language string for "Manage", so you could add that to your template code changes... <th>{$LANG.manage}</th> and then it should translate for all languages (assuming WHMCS have translated for all languages). is there any reason why the Smarty code to be added manually to the end of head.tpl, can't be added using the (or another) clientareaheadoutput hook ? 0 Quote Link to comment Share on other sites More sharing options...
Kian Posted July 25, 2020 Author Share Posted July 25, 2020 17 minutes ago, brian! said: is there any reason why the Smarty code to be added manually to the end of head.tpl, can't be added using the (or another) clientareaheadoutput hook ? +1 18 minutes ago, brian! said: there is already a default language string for "Manage", so you could add that to your template code changes... +1 I'm going to update the hook and check for the following: 19 minutes ago, brian! said: however, the other service doesn't have a domain or username entry (both are empty), but the hook is still generating a manage button for it? Thanks for suggestions 🙏 0 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.