Jump to content
Kian

cPanel & Plesk login button in My Services list

Recommended Posts

Posted (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).

whmcs-login-to-plesk-cpanel-from-service-list.thumb.png.4302dfe6eb8fb1f0635a72eefc00b5f4.png

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.

whmcs-quick-login-to-plesk-cpanel-1.png.efd50c271f7dcde0a97ed8b957aa684e.png

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 by Kian

Share this post


Link to post
Share on other sites
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 ??

Share this post


Link to post
Share on other sites
Posted (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...

sample-452.thumb.png.d4dd0798f7c55de4e76596994a193f37.png

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 by Kian

Share this post


Link to post
Share on other sites

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;
    }
});

 

Share this post


Link to post
Share on other sites
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?

RnydF7t.png

a couple of other thoughts re the documentation...

  1. 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).

  2. 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 ?

Share this post


Link to post
Share on other sites
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 🙏

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use & Guidelines and understand your posts will initially be pre-moderated