Development Guides Home >> Guide to cPanel Interface Customization and Branding >> Guide to cPanel Interface Customization - The Login Theme

Guide to cPanel Interface Customization - Login Templates

Introduction

Template files determine the appearance of each login page. Each login theme includes template files for the main login pages, error pages, and templates for the Reset Password feature.

Templates

The locations listed below are relative to the /usr/local/cpanel/base/unprotected/cpanel/ directory, which contains the cPanel & WHM default login theme.

Select a template file below to view more information about that template file:

templates/_error_wrapper.tmpl

The system accesses this wrapper template whenever the user encounters an error.

Template variables

This template does not use template variables.

Default template example

[%

    #----------------------------------------------------------------------
    # Arguments received by this template:
    # This list may not be exhaustive, and other parameters may be added or available.
    #
    # app_name - What application is loading this interface (cpaneld, whostmgrd, webmaild)
    # http_status_code - HTTP Status code
    # page_to_show - Page to display

[%
SET app_images = {
    'whostmgrd' => 'whm-logo_white.svg',
    'webmaild'  => 'webmail-logo.svg',
    'cpaneld'   => 'cpanel-logo.svg',
};

SET app_image = app_images.$app_name || app_images.cpaneld;
SET app_image = MagicRevision(get_theme_url("images/$app_image"));
%]

[% IF page_to_show != "access_denied" %]
    <p class="logo"><img class="main-logo" src="[% app_image %]" alt="logo"></p>
[% END %]


<div class="error_notice">
    <div id="error-wrapper">
        <div id="error_msg_contents">
            <h2>[% locale.maketext('HTTP error [_1]',http_status_code) %]</h2>
[% content %]

templates/access_denied.tmpl

The system accesses this template whenever the server responds with an Access Denied error. This error occurs whenever a user attempts to log in with an invalid username or password.

Template variables

Variables Type Description
dest_uri string The URL to load after a user authenticates. This URL does not contain the security token.
error_msg string The error message to display.
form_ref hash A hash of the form variables to pass with the request. The system sends this hash to the location that the redirect_uri variable specifies.
parameterized_form hash A hash of form variables that the user provided as a URL query string.
theme string The theme to load.
user string The username to authenticate.

Default template example

[%

    #----------------------------------------------------------------------
    # Arguments received by this template:
    # This list may not be exhaustive, and other parameters may be added or available.
    #
    # uri - URI user tried to access without authorization
    # page_message - Additional message to display to the user

%]
[% WRAPPER 'templates/_error_wrapper' -%]
    <h2>[% uri.html() %]</h2>
    <p>[% locale.maketext('You do not have permission to access this page.') %]</p>
    [% IF page_message %]
      <blockquote>[% locale.makevar(page_message) FILTER html %]</blockquote>
    [% END %]

[% END -%]

templates/disabled.tmpl

The system accesses this template whenever the visitor attempts to access a disabled account.

Template variables

This template inherits the template variables from its parent template.

Default template example

[%

    #----------------------------------------------------------------------
    # Arguments received by this template:
    # This list may not be exhaustive, and other parameters may be added or available.
    #

%]
<div>
    <span id="resetpass-disabled">[%# marker for testing%]</span>
</div>

templates/error502.tmpl

The system accesses this template whenever the server responds with a 502 (server) error.

Template variables

Variable Type Description
dest_uri string The URL to load after a user authenticates. This URL does not contain the security token.
error_msg string The error message to display.
form_ref hash A hash of the form variables to pass with the request. The system sends this hash to the location that the redirect_uri variable specifies.
parameterized_form hash A hash of form variables that the user provided as a URL query string.
theme string The theme to load.
user string The username to authenticate.

Default template example

[%

    #----------------------------------------------------------------------
    # Arguments received by this template:
    # This list may not be exhaustive, and other parameters may be added or available.
    #

%]
[% WRAPPER 'templates/_error_wrapper' -%]
    <p>[% locale.maketext('The server received a bad response while acting as a proxy.') %]</p>
[% END -%]

templates/error503.tmpl

The system accesses this template whenever the server responds with a HTTP status 503. The system displays HTTP status 503 when the requested service is unavailable.

Template variables

Variable Type Description
dest_uri string The URL to load after a user authenticates. This URL does not contain the security token.
error_msg string The error message to display.
form_ref hash A hash of the form variables to pass with the request. The system sends this hash to the location that the redirect_uri variable specifies.
page_message string The optional message provides more details about why the service is unavailable.
parameterized_form hash A hash of form variables that the user provided as a URL query string.
theme string The theme to load.
user string The username to authenticate.

Default template example

[%

    #----------------------------------------------------------------------
    # Arguments received by this template:
    # This list may not be exhaustive, and other parameters may be added or available.
    #
    # page_message - Message to be displayed to the user

%]
[% WRAPPER 'templates/_error_wrapper' -%]
    <h2>[% locale.maketext('The service is unavailable.') %]</h2>
    [% IF page_message%]<p>[% page_message.html() %]</p>[%END%]
[% END -%]

templates/external_auth_header.tmpl

The system accesses this template in order to add the header for the External Authentication login section.

Template variables

This template inherits the template variables from its parent template.

Default template variables

[%

    #----------------------------------------------------------------------
    # Arguments received by this template:
    # This list may not be exhaustive, and other parameters may be added or available.
    #
    # https - Is the application running in https mode
    # link_account - Boolean are we currently trying to link an account

%]
[%-

USE ExternalAuthentication;
SET external_auth_modules = https && !link_account ? ExternalAuthentication.get_enabled_and_configured_openid_provider_display_configurations() : [];

-%]

templates/external_auth.tmpl

The system accesses this template in order to add the External Authentication login section.

Template variables

This template inherits the template variables from its parent template.

Default template variables

templates/external_auth.tmpl
The system accesses this template in order to add the External Authentication login section.

Template variables
This template inherits the template variables from its parent template.

Default template variables
[%

    #----------------------------------------------------------------------
    # Arguments received by this template:
    # This list may not be exhaustive, and other parameters may be added or available.
    #
    # external_auth_modules - What are the currently enabled external authentication modules (cpanel, google, facebook, etc)
    # page_to_show - Page to display
    # user - The cPanel user (or virtual user that is logged in)
    # parameterized_form - A dump of the postdata that is uri encoded
    # theme - The current cPanel theme that the user is using
    # goto_uri - The uri that the user requested

%]
[%-

USE HTTP;

SET query = {
    'user' => user,
    'theme' => theme,
    'parameterized_form' => parameterized_form,
    'goto_uri' => goto_uri,
    'goto_app' => goto_app,
};
IF page_to_show == 'token_denied';
    query.token_denied = 1;
END;

IF external_auth_modules.size > 0 && external_auth_modules

%]
<div id="external-auth-container">
    <div class="or-separator">
        <span class="or-separator-label">[% locale.maketext('OR[comment,this is a decoration separator, shortest form is best]') %]</span>
        <span class="or-separator-secondary-label">[% locale.maketext("Log in via"); %]</span>
    </div>
    <div class="controls external-auth-items">
        [% FOR auth_mod = external_auth_modules %]
          [%
          IF oidc_failed == auth_mod.provider_name;
                # This must match use the same regex as unprotected/cpanel/js/login.js
                IF ENV_REQUEST_URI.match('^\/(?:logout|login|openid_connect_callback)\/?');
                    SET xauth_link = auth_mod.link.html();
                ELSE;
                    SET xauth_link = ENV_REQUEST_URI.html;
                END;
          ELSE;
            SET xauth_link = auth_mod.link.html() _ '?' _ HTTP.make_query_string(query);
          END; %]
          <div class="external-auth-btn">
              <a class="external-auth-link" href="[% xauth_link %]" title="[% auth_mod.label.html() %]" style="background-color:#[% auth_mod.color %];color:#[% auth_mod.textcolor %]">
                  <i class="external-auth-icon" style="background-image:url(data:[% auth_mod.icon_type %];base64,[% auth_mod.icon %])"></i>
                  [% IF auth_mod.label == 'Log in via ' _ auth_mod.display_name %]
                    <span class="external-auth-btn-label">[% locale.maketext('Log in via [_1]', auth_mod.display_name.html()) %]</span>
                  [% ELSE %]
                    <span class="external-auth-btn-label">[% auth_mod.label.html() %]</span>
                  [% END %]
              </a>
          </div>
        [% END %]
    </div>
</div>
[% END %]

templates/fourohfour.tmpl

The system accesses this template whenever the server responds with a HTTP 404 (page not found) error.

Template variables

Variable Type Description
dest_uri string The URL to load after a user authenticates. This URL does not contain the security token.
error_msg string The error message to display.
form_ref hash A hash of the form variables to pass with the request. The system sends this hash to the location that the redirect_uri variable specifies.
parameterized_form hash A hash of form variables that the user provided as a URL query string.
theme string The theme to load.
user string The username to authenticate.

Default template example

[%

    #----------------------------------------------------------------------
    # Arguments received by this template:
    # This list may not be exhaustive, and other parameters may be added or available.
    #

%]
[% WRAPPER 'templates/_error_wrapper' -%]
    <p>[% locale.maketext('The requested page was not found.') %]</p>
    <h2>[% locale.maketext('Possible reasons why you are seeing this page:') %]</h2>
    <ul>
        <li>[% locale.maketext('A bookmarked URL may have changed since you last visited.') %]</li>
        <li>[% locale.maketext('The URL was entered incorrectly.') %]</li>
        <li>[% locale.maketext('The URL was entered with inaccurate capitalization (URLs are [output,url,_1,case sensitive]).','http://wikipedia.org/wiki/Case_sensitivity') %]</li>
    </ul>
    <p>[% locale.maketext('Please re-check the URL you are trying to reach. ([output,url,_1,Go Back])', 'javascript:history.back()' ) %]</p>
[% END -%]

templates/generic_error.tmpl

The system accesses this template whenever the server responds with a generic error.

Template variables

Variable Type Description
dest_uri string The URL to load after a user authenticates. This URL does not contain the security token.
error_msg string The error message to display.
form_ref hash A hash of the form variables to pass with the request. The system sends this hash to the location that the redirect_uri variable specifies.
parameterized_form hash A hash of form variables that the user provided as a URL query string.
theme string The theme to load.
user string The username to authenticate.

Default template example

[%

    #----------------------------------------------------------------------
    # Arguments received by this template:
    # This list may not be exhaustive, and other parameters may be added or available.
    #
    # uri - URI the user was trying to access when the error occurred
    # generic_error - The error message

%]
[% WRAPPER 'templates/_error_wrapper' -%]
    <h2>[% uri.html() %]</h2>
    <p>[% generic_error.html() %]</p>
[% END -%]

templates/invitation_failure.tmpl

The system accesses this template whenever it cannot properly process a new user invitation.

Template variables

This template inherits the template variables from its parent template.

Default template example

[%

    #----------------------------------------------------------------------
    # Arguments received by this template:
    # This list may not be exhaustive, and other parameters may be added or available.
    #
    # notice_class - class to add to the notice for styling purposes
    # reason - Reason the invitation failed.

%]
 <div id="notify">
    <div id="login-status"
         class="[% notice_class || 'error-notice' %]">
        <div id="login-detail">
            <div id="login-status-icon-container">
                <span class="login-status-icon"></span>
            </div>
            [% IF reason == 'unknown' %]
            <div id="unknown" class="login-status-message">
                [% locale.maketext('The system could not process the invitation due to an unknown error.') %]
            </div>
            [% ELSIF reason == 'bad-request' %]
            <div id="bad-request" class="login-status-message">
                [% locale.maketext('This invitation is not valid. It may have expired or the server administrator withdrew the invitation.') %]
            </div>
            [% ELSIF reason == 'suspended' %]
            <div id="suspended" class="login-status-message">
                [% locale.maketext('You cannot set your password because the [asis, cPanel] account that owns your [asis,Subaccount] is suspended.') %]
            </div>
            [% ELSIF reason == 'flooding' %]
            <div id="flooding" class="login-status-message">
                [% locale.maketext('You exceeded the maximum number of attempts to set your new account's password. Try again in one hour.') %]
            </div>
            [% ELSE %]
            <div id="change-password-failure" class="login-status-message">
                [% locale.maketext('The system failed to update your account's password. Additional information may exist in the server error log. Contact your server account provider, server administrator, or hosting provider.') %]
            </div>
            [% END %]
        </div>
    </div>
</div>
<span id="invitation-failure">[%# marker for testing%]</span>

templates/invitation_set_password.tmpl

The system accesses this template whenever an invited user needs to set a new password.

Template variables

This template inherits the template variables from its parent template.

Default template example

[%

    #----------------------------------------------------------------------
    # Arguments received by this template:
    # This list may not be exhaustive, and other parameters may be added or available.
    #
    # user - User being accessed / updated

    SET application_dir = 'cpanel';
    SET file = 'invitation';
%]

[% PROCESS '_assets/cjt2_header_include.tt' %]

<div id="content" ng-controller="setPasswordController">
    <div id="forms">
        <form id="reset_form" name="reset_form" action="/invitation" method="post" novalidate ng-cloak autocomplete="off" ng-submit="inProgress = true;">
            <input type="hidden" name="action" value="password">
            <input type="hidden" name="user" value="[%user%]">
            <input type="hidden" name="debug" value="[%CPANEL.is_debug_mode_enabled() ? '1' : '' %]">

            <!-- Password Input -->
            <div class="reset-input-group">
                <div class="input-req-login">
                    <label for="password">[% locale.maketext('New Password') %]</label>
                </div>
                <password name="password"
                          class="std_textbox"
                          tabindex="1"
                          auto-focus
                          autocomplete="off"
                          title="[% locale.maketext('Your new password.') %]"
                          minimum-strength="[% get_required_password_strength( 'virtual' ) %]"
                          placeholder="[% locale.maketext('Enter your new password') %]"
                          password="password"
                          show-meter="true"
                          show-strength="true"
                          show-generator="true"
                          minimum-length="5"
                          required
                          generate-minimum-length="5"
                          generate-maximum-length="18"
                          generate-button-tab-index="-1"
                          toggle-view-button-tab-index="-1"
                          generate-settings-tab-index="-1"
                          strength-meets-template="[% locale.lextext('This password has a strength of [numf,_1], which meets or exceeds the system requirement of [numf,_2].') %]"
                          strength-does-not-meet-template="[% locale.lextext('The password has a strength of [numf,_1], but your system requires a strength of [numf,_2].') %]"
                          password-strength="passwordStrength">
                </password>

                <ul validation-container field-name="password" ng-cloak>
                   <li validation-item field-name="password" validation-name="required" id="val-password-required">
                       [% locale.maketext('You must complete this field.') %]
                   </li>
                   <li validation-item field-name="password" validation-name="minlength" id="val-password-minlength">
                       [% locale.maketext('You must provide a password with at least 5 characters.') %]
                   </li>
                   <li validation-item field-name="password" validation-name="minimumPasswordStrength" id="val-password-minimum-strength">
                       [% locale.maketext('You must provide a stronger password.') %]
                   </li>
               </ul>
           </div>

            <!-- Password Confirmation -->
            <div class="reset-input-group">
                <div class="input-req-login">
                    <label for="confirm">[% locale.maketext('Confirm Password') %]</label>
                </div>
                <div class="input-field-login icon password-confirm-container">
                    <input name="confirm"
                           id="confirm"
                           type="password"
                           ng-model="passwordConfirm"
                           class="std_textbox"
                           tabindex="2"
                           placeholder="[% locale.maketext('Enter your new password, again.') %]"
                           validate-equals="reset_form.password"
                           required>
                </div>

                <ul validation-container field-name="confirm" ng-cloak>
                    <li validation-item field-name="confirm" validation-name="required" id="puzzle-guess-input-required">
                       [% locale.maketext('You must complete this field.') %]
                   </li>
                   <li validation-item field-name="confirm" validation-name="validateEquals" id="val-password-confirm-match">
                           [% locale.maketext('The passwords do not match.') %]
                       </li>
                </ul>
            </div>

            <div class="controls">
                <div class="login-btn">
                    <input name="login"
                           type="submit"
                           id="login"
                           value="[% locale.maketext('Set Password') %]"
                           ng-disabled="!reset_form.$valid || reset_form.$pending || inProgress">
                </div>
            </div>
        </form>
        <span id="invitation-set-password">[%# marker for testing%]</span>
    </div>
</div>

templates/invitation_success.tmpl

The system accesses this template whenever an invited user successfully accepts the invitation and sets their new password.

Template variables

This template inherits the template variables from its parent template.

Default template example

[%

    #----------------------------------------------------------------------
    # Arguments received by this template:
    # This list may not be exhaustive, and other parameters may be added or available.
    #
    # next_steps - List of invitation step objects
    #          {
    #               key => Key identifying the step type
    #               instructions => Instructions for that specific step
    #               services => List of services associate with that step
    #          }
    #
    # logins - List of login service objects
    #          {
    #              id => Dom Element ID
    #              url => url the button will direct them to when clicked
    #              button_text => label for the button
    #          }


%]
<div class="form-container">
    [% FOREACH step IN next_steps %]
        [% IF step.value.services.size() %]
    <p id="[% step.key %]-instructions">[% step.value.instructions %]</p>
        [% END %]
    [% END %]

    [% FOREACH login IN logins -%]
    <div class="controls">
        <div class="login-btn">
            <a class="loginbtn" href="[% login.url %]" id="[% login.id %]">
                [% login.button_text %]
            </a>
        </div>
    </div>
    [% END %]

    <span id="invitation-success">[%# marker for testing%]</span>
</div>

templates/login.tmpl

This template determines the appearance of the first login page that users see when they attempt to log in to cPanel, WHM, or Webmail.

Template variables

Variable Type Description
dest_uri string The URL to load after a user authenticates. This URL does not contain the security token.
msg_code string The Key that corresponds to the login_messages value. This message displays on the loading page after the user authenticates.

Default template example

[%

    #----------------------------------------------------------------------
    # Arguments received by this template:
    # This list may not be exhaustive, and other parameters may be added or available.
    #
    # allow_login_autocomplete - Boolean for autocompleting login names
    # app_name - What application is loading this interface (cpaneld, whostmgrd, webmaild)
    # goto_uri - The uri that the user requested
    # goto_app - App the user is attempting to log in to.
    # display_locales - Boolean for if the interface display the locales list
    # https - Is the application running in https mode
    # login_messages - Messages to present to the user pertaining to the login process
    # logout - Boolean of whether to display the login button
    # msg_code - Key for what we are currently doing in the login display (link_account, etc)
    # reset_pass - should be true if either resetpass or resetpass_sub is enabled (doesn't have to be both)

USE DataURI;
USE JSON;
USE Wbr;

SET disp_apps = {
    'whostmgrd' => 'WHM',
    'webmaild' => 'Webmail',
    'cpaneld' => 'cPanel',
};
SET disp_app  = disp_apps.item(app_name) || 'cPanel';

SET app_images = {
    'whostmgrd' => 'whm-logo_white.svg',
    'webmaild'  => 'webmail-logo.svg',
    'cpaneld'   => 'cpanel-logo.svg',
};

# get app modules based on $app_name
SET app_image = app_images.$app_name || app_images.cpaneld;
SET app_image = MagicRevision(get_theme_url("images/" _ app_image));

#If msg_code is 'link_account' we already have a separate display notice so don't need to show it twice
SET shownotice = logout || msg_code;
SET shownotice = msg_code == 'link_account' ? 0 : shownotice;
SET shownotice = msg_code == 'max_users_exceeded' ? 0 : shownotice;
SET notice_message = msg_code
    ? (login_messages.$msg_code || locale.maketext('An authorization error occurred. Please try again.') )
    : locale.maketext('You have logged out.');

    SET login_target = (goto_uri=='/') ? '_top' : '_self';

    #Windows XP doesn't have the fancy arrows, so use ellipsis for now.
    SET more_locales_symbol = "…";

    # Only run the display_locales function once by saving it into all_display_locales
    SET all_display_locales = display_locales;

    PROCESS "templates/external_auth_header.tmpl";

    SET login_classes = [];
    IF reset_pass;
        login_classes.push('has-pw-reset');
    END;
    UNLESS external_auth_modules;
        login_classes.push('no-external-auth-modules');
    END;

    SET notice_style_ = logout ? 'success-notice' : notice_style ? notice_style : 'error-notice';

    -%]

    [% MACRO ceil(n)
        GET n + (n - (n % (n + 1)) > 0 ? 1 : 0) FILTER format("%d");
    %]

    <input type="hidden" id="goto_uri" value="[% goto_uri.html() %]" />
    <input type="hidden" id="goto_app" value="[% goto_app.html() %]" />
    <!-- Do not remove msg_code as it is needed for automated testing - msg_code:[[%- msg_code -%]]  -->
    <div id="login-wrapper" class="group [% login_classes.join(' ') %]">
        <div class="wrapper">
        <div id="notify">
            <noscript>
                <div class="error-notice">
                    <img src="[% MagicRevision(get_theme_url('images/notice-error.png')) %]" alt="Error" align="left"/>
                    [% locale.maketext('JavaScript is disabled in your browser.') %]
                    [% locale.maketext('For [_1] to function properly, you must enable JavaScript.', disp_app) %]
                    [% locale.maketext('If you do not enable JavaScript, certain features in [_1] will not function correctly.', disp_app) %]
                </div>
                </noscript>
            [% IF msg_code == 'link_account' %]
            <div id="link-account">
                <div class="content-wrapper">
                    [% IF user_info_payload.picture %]
                      [% IF user_info_payload.picture.match('https://') %]
                        <span class='link-account-avatar' style="background-size: 100% 100%; background-image:url([% user_info_payload.picture.html() %])"></span>
                      [% ELSE %]
                        <span class='link-account-avatar' style="background-image:url('data:image/*;base64,[% user_info_payload.picture %]')"></span>
                      [% END %]
                    [% END %]
                    [% IF existing_link_count %]
                      [% locale.maketext('Your account “[_1]” is already associated with an existing “[_2]” account. Please log in to connect a new account.' , preferred_username , disp_app); %]
                    [% ELSE %]
                      [% locale.maketext('Your account “[_1]” is not associated with an existing “[_2]” account. Please log in to connect the account.' , preferred_username , disp_app); %]
                    [% END %]
                </div>
            </div>
            [% END %]
            [% IF msg_code == 'max_users_exceeded' %]
            <div id='login-status' class="[% notice_style_ %]">
                <div class="content-wrapper">
                    <div id="login-detail">
                        <div id="login-status-icon-container"><span class='login-status-icon'></span></div>
                        <div id="login-status-message">
                            <p><strong>[% locale.maketext('Maximum Users Exceeded.') %]</strong></p>
                            <p>[% locale.maketext('The number of users on the server exceeds the maximum number of allowed users for your host server.') %]</p>
                            <p>[% locale.maketext('For more information, contact your server administrator.') %]</p>
                        </div>
                    </div>
                </div>
            </div>
            [% END %]
            <div id='login-status' class="[% notice_style_ %]" style="visibility: [% shownotice ? 'visible' : 'hidden' %]">
                <div class="content-wrapper">
                    <div id="login-detail">
                        <div id="login-status-icon-container"><span class='login-status-icon'></span></div>
                        <div id="login-status-message">[% notice_message %]</div>
                    </div>
                </div>
            </div>
        </div>

        <div style="display:none">
               <div id="locale-container" style="visibility:hidden">
                   <div id="locale-inner-container">
                       <div id="locale-header">
                           <div class="locale-head">[% locale.maketext('Please select a locale:') %]</div>
                           <div class="close"><a href="javascript:void(0)" onclick="toggle_locales(false)">X [% locale.maketext('Close') %]</a></div>
                       </div>
                       <div id="locale-map">
                           <div class="scroller clear">
                               [% FOREACH cur_loc = all_display_locales %]
                                   <div class="locale-cell"><a href="?locale=[% cur_loc.tag %]">[% cur_loc.name %]</a></div>
                               [% END %]
                           </div>
                       </div>
                   </div>
               </div>
           </div>
           <div id="content-container">
               <div id="login-container">    

                 <div id="login-sub-container">
                    <div id="login-sub-header">
                        [% IF script_uri == "/cpsess0/scripts7/authorizesupport" %]
                        <img class="small-logo" src="[% app_image %]" alt="logo" />
                        &mdash;
                        [% locale.maketext('To grant [asis,cPanel] Support access to your server, log in to [asis,WHM] and click the “[_1]” button.', locale.maketext('Grant Access')) %]
                        </p>
                        [% ELSE %]
                        <img class="main-logo" src="[% app_image %]" alt="logo" />
                        [% END %]
                    </div>
                    <div id="login-sub"
                        [% IF linked_users && linked_users.size -%]
                            style="display:none"
                        [% END -%]
                        >
                        <div id="clickthrough_form" style="visibility:hidden">
                            <form action="javascript:void(0)">
                                <div class="notices"></div>
                                <button type="submit" class="clickthrough-cont-btn">[% locale.maketext('Continue') -%]</button>
                            </form>
                        </div>
                        <div id="forms">
[%# Don't change the form action or the ids/names of the username and password fields.
    Doing so will break browser-native login credential storage.
-%]
                            <form novalidate id="login_form" action="/login/" method="post" target="[% login_target %]" style="visibility:[% linked_users.size ? 'hidden' : '' %]">
                                <div class="input-req-login"><label for="user">[% IF app_name=="webmaild" %][% locale.maketext('Email Address') %][% ELSE %][% locale.maketext('Username') %][% END %]</label></div>
                                <div class="input-field-login icon username-container">
                                    <input name="user" id="user" autofocus="autofocus" value="[% user.html() %]" placeholder="[% IF app_name=="webmaild" %][% locale.maketext('Enter your email address.') %][% ELSE %][% locale.maketext('Enter your username.') %][% END %]" class="std_textbox" type="text" [% allow_login_autocomplete ? '' : 'autocomplete="off"' %] tabindex="1" required>
                                </div>
                                <div class="input-req-login login-password-field-label"><label for="pass">[% locale.maketext('Password') %]</label></div>
                                <div class="input-field-login icon password-container">
                                    <input name="pass" id="pass" placeholder="[% IF app_name=="webmaild" %][% locale.maketext('Enter your email password.') %][% ELSE %][% locale.maketext('Enter your account password.') %][% END %]" class="std_textbox" type="password" tabindex="2" [% allow_login_autocomplete ? '' : 'autocomplete="off"' %] required>
                                </div>
                                <div class="controls">
                                    <div class="login-btn">
                                        <button name="login" type="submit" id="login_submit" tabindex="3">[% locale.maketext('Log in') -%]</button>
                                    </div>

                                    [% IF reset_pass;
                                         SET reset_url = "/resetpass?start=1";
                                         IF !https;
                                            USE ApplicationUrl;
                                            SET secure_url = ApplicationUrl.get_secure_url(
                                                        host            => SERVER_NAME,
                                                        port            => SERVER_PORT,
                                                        proxysubdomains => cpconf.proxysubdomains);
                                            reset_url = secure_url _ reset_url;
                                        END;
                                        -%]
                                        <div class="reset-pw">
                                            <a href="[% reset_url %]" id="reset_password">[% locale.maketext('Reset Password') %]
                                            </a>
                                        </div>
                                    [% END -%]
                                </div>
                                <div class="clear" id="push"></div>
                            </form>
                        <!--CLOSE forms -->
                        </div>
                    <!--CLOSE login-sub -->
                    </div>
                    [% PROCESS "templates/external_auth.tmpl" %]
                    [% IF linked_users.size -%]
                        <div id="select_users_option_block" style="display:none">
                            <div class="or-separator" >
                                <span class="or-separator-label">[% locale.maketext('OR[comment,this is a decoration separator, shortest form is best]') %]</span>
                                <span class="or-separator-secondary-label">[% locale.maketext("Log in via"); %]</span>
                            </div>
                            <div class="controls external-auth-items">
                                <div class="btn">
                                    <button type="button" class="external-auth-select" style="background-color:#[% auth_mod.color %];text-color:#[% auth_mod.textcolor %]" onclick="show_select_user()">
                                        <span class="external-auth-btn-label">[% locale.maketext('Select user from list of linked accounts') %]</span>
                                    </button>
                                  </div>
                            </div>
                        </div>
                    [% END -%]
                <!--CLOSE wrapper -->
                </div>
            <!--CLOSE login-sub-container -->
            </div>
        <!--CLOSE login-container -->
        </div>
        [% #If we have multiple users the user must select one %]
        [% IF linked_users.size -%]
            [% #calculate left postion based on # of items with a max width of 6 %]
            [% SET max_width = linked_users.size < 6 ? ( linked_users.size + 1 ) * 100 : 600; %]
            <form id="select_user_form" novalidate>
                <div>
                [% FOREACH user IN linked_users -%]
                    <div class="button-wrapper">
                        <button name="openid_user_selection" type="submit" id="login_submit" tabindex="3" value="[% user.username %]" title="[% user.username %]">
                            <div class="image-wrapper">
                                <img src="https://gravatar.com/avatar/[% user.md5_hex %]?d=retro"
                                    onerror="if (this.src != '[% MagicRevision(get_theme_url('images/default-avatar.png')) %]') this.src = '[% MagicRevision(get_theme_url('images/default-avatar.png')) %]';"></img>
                            </div>
                            <div class="text-wrapper">
                                <div class="text-content">
                                    [% Wbr.wbr_on_at_symbol(user.username) %]
                                </div>
                            </div>
                        </button>
                    </div>
                [% END -%]
                    <div class="button-wrapper" >
                        <button name="openid_user_selection" type="button" id="login_submit" tabindex="3" onclick="show_login()">
                            <div class="image-wrapper">
                                <img src="https://gravatar.com/avatar/default_no_image?d=mm"
                                    onerror="if (this.src != '[% MagicRevision(get_theme_url('images/default-avatar.png')) %]') this.src = '[% MagicRevision(get_theme_url('images/default-avatar.png')) %]';"></img>
                            </div>
                            <div class="text-wrapper">
                                <div class="link-extra-account">
                                    [% locale.maketext('Link Another Account') %]
                                </div>
                            </div>
                        </button>
                    </div>
                </div>
                <div class="clear" id="push"></div>
            </form>
        [% END -%]
        <div id="locale-footer">
            <div class="locale-container">
                <noscript>
                    <form method="get" action=".">
                        <select name="locale">
                            <option value="">[% locale.maketext('Change locale') %]</option>
                            [% "<option value='${cur_loc.tag}'>${cur_loc.name}</option>" FOR cur_loc=all_display_locales -%]
                        </select>
                        <button style="margin-left: 10px" type="submit">[% locale.maketext('Change') %]</button>
                    </form>
                    <style type="text/css">#mobilelocalemenu, #locales_list {display:none}</style>
                </noscript>
                <ul id="locales_list">
                    [% FOREACH cur_loc = all_display_locales %]
                        [% LAST IF loop.index > 7 %]
                        <li><a href="/?locale=[% cur_loc.tag %]">[% cur_loc.name.replace(' ','&nbsp;') %]</a></li>
                    [% END %]
                    <li><a href="javascript:void(0)" id="morelocale" onclick="toggle_locales(true)" title="[% locale.maketext('More locales') %]">[% more_locales_symbol %]</a></li>
                </ul>
                <div id="mobilelocalemenu">[% locale.maketext("Select a locale:") %]
                    <a href="javascript:void(0)" onclick="toggle_locales(true)" title="[% locale.maketext('Change locale') %]">[% locale.get_language_tag_name() %]</a>
                </div>
            </div>
        </div>
<!--Close login-wrapper -->
</div>
<script>
    var MESSAGES = [% JSON.stringify(login_messages) -%];

    window.IS_LOGOUT = [% logout ? 'true' : 'false' %];

[%# Must not include external javascript -jnk 06.20.09 -%]
[%
FOR file = ['login.js', 'jstz.min.js', 'cptimezone_optimized.js'];
    SET js_url = get_theme_url("js-min/$file") || get_theme_url("js/$file");
    IF js_url;
        js_url = js_url.replace('^/','');
        "\n//$file\n";
        INSERT "$js_url";
    END;
END;
-%]
[% IF linked_users && linked_users.size %]
    var rows = [% ceil(linked_users.size / 6) %];
[% END %]

CPTimezone.reset_timezone();
</script>

<style>
    @media (min-width: 481px) {
        #select_user_form {
            width: [% max_width %]px;
        }
    }
</style>

main.tmpl

This template contains the conditions to perform the following actions:

  • Correctly set the title of the login page in the web browser.
  • Set the page's favicon.
  • Load the login theme CSS files.
  • Include the login page's copyright notice.

Template variables

This template does not use template variables.

Advanced use

The login application loads the main.tmpl template to determine how the system processes user input.

Application parameters

The login application uses the following parameters, which are only available in templates that use the main.tmpl parent template:

Parameter Type Description
app_name string The cPanel & WHM service that the user attempted to log in to:
  • cpaneld — The cPanel interface
  • whostmgrd — The WHM interface
  • webmaild — The Webmail interface.
http_status_code string The HTTP status code that the server used to respond to the request.
login_messages hash A hash of messages that the browser can display dynamically via Javascript.
logout Boolean Whether the user logged out recently:
  • 1 — The user logged out recently
  • 0 — The user has not logged out recently.
page_to_show string The sub-template that the login application calls after it loads the main.tmpl template:
  • access_denied — Access the templates/access_denied.tmpl template.
  • fourohfour — Access the templates/fourohfour.tmpl template.
  • login — Access the templates/login.tmpl template.
  • passthrough — Access the templates/passthrough.tmpl template.
  • referrer_denied — Access the templates/referrer_denied.tmpl template.
  • token_denied — Access the templates/token_denied.tmpl template.
reset_pass Boolean Whether to display the Reset Password link:
  • 1 – Display
  • 0 – Do not display.

templates/passthrough.tmpl

This template generates the page that displays when a user authenticates successfully after a Token Denied error.

Template variables

Variable Type Description
cp_security_token string The security token to use in the URL.
form_ref hash A hash of the form variables to pass with the request. The system sends this hash to the location that the redirect_uri variable specifies.
redirect_uri string The URL to which the system will redirect the user.

Default template example

[%

    #----------------------------------------------------------------------
    # Arguments received by this template:
    # This list may not be exhaustive, and other parameters may be added or available.
    #
    # goto_uri - The uri that the user requested
    # cp_security_token - cPanel Authentication token

%]

    <div class="error_notice">
        <div id="error-wrapper">
            <h1>[% locale.maketext('Security token updated.') %]</h1>
            <p>[% locale.maketext('The system has validated your login credentials. Redirecting …') %]</p>
            <form action="[% cp_security_token %][% goto_uri.html() %]" method="post" name="passthroughform">
            [% FOR pair=form_ref -%]
                <input type="hidden" name="[% pair.key.html() %]" value="[% pair.value.html() %]" />
            [% END -%]
            </form>
            <script type="text/javascript">
                document.passthroughform.submit();
            </script>
        </div>
    </div>

templates/referrer_denied.tmpl

The system accesses this template whenever the server returns a Referrer Denied error. The system returns this error if the server rejects the user's reference link.

Variable Type Description
dest_uri string The URL to load after a user authenticates. This URL does not contain the security token.
error_msg string The error message to display.
form_ref hash A hash of the form variables to pass with the request. The system sends this hash to the location that the redirect_uri variable specifies.
parameterized_form hash A hash of form variables that the user provided as a URL query string.
theme string The theme to load.
user string The username to authenticate.

Default template example

[%

    #----------------------------------------------------------------------
    # Arguments received by this template:
    # This list may not be exhaustive, and other parameters may be added or available.
    #
    # referrer - Invalid Referrer to display to the user

%]
[% WRAPPER 'templates/_error_wrapper' -%]
    [% referring_url = referrer.html(); -%]
    <p>[% locale.maketext('You do not have permission to access this page from "[_1]".', "<code>$referring_url</code>") %]</p>
[% END -%]

resetpass.tmpl

This template generates the page that instructs users to reset their passwords. Advanced users can update this template to modify the way in which the system processes user input.

Template variables

This template does not use template variables.

Advanced use

The resetpass application loads the resetpass.tmpl template to determine how the system processes user input when users reset their passwords. The resetpass application uses the resetpass-email.tmpl and resetpass-email-html.tmpl templates when it sends a confirmation email to the user.

Application parameters

The resetpass application uses the following parameters, which are only available in templates that use the resetpass.tmpl parent template:

Parameter Type Description
notice_class string The HTML class for the notice_text notice.
notice_text string The notice to display, if one exists.
page_to_show string The sub-template that the resetpass application calls after it loads the resetpass.tmpl template:
  • resetpass_confirmation – Access the templates/resetpass_confirmation template.
  • resetpass_no_user – Access the templates/resetpass_no_user.tmpl template.
  • resetpass_success – Access the templates/success.tmpl template.

Global objects

The Template::Toolkit module does not allow scoping. For more information, read our Guide to Template Toolkit in cPanel & WHM documentation.

When you modify the way in which this template processes input, you can also use the following global objects:

Global object Type Description
display_locales() function This function retrieves a list of the locales that are available on the server.
  • The function returns this list of locale information in an array of hashes.
  • This function does not accept arguments.
get_theme_url() function This function searches the /usr/local/cpanel/base/unprotected/ directory and its subdirectories for a specified file and returns its location. Use this function to ensure that the system displays the correct image for the server's current login theme.
  • This function matches against the filename that you request, regardless of the application name. For example, if you use this function to search for the logo.png file, the function would also search for the logo_whostmgr.png file.
  • You must pass values through the MagicRevision() function after you pass them through this function. For example, the following code passes the filename logo.png to the get_theme_url() function, and then passes the file through the MagicRevision() function:
    <img src="[% MagicRevision( get_theme_url('logo.png') ) %]" alt="logo">
locale Cpanel::Locale hash object instance This global object contains the current user's locale. For more information, read our How cPanel & WHM Determines a Browser's Locale and Guide to Locales documentation.
MagicRevision() function This function provides a caching system. Use this function to improve load times for users and decrease system I/O.
  • URLs that you pass through the MagicRevision() function contain the file's modification time in the URL path.
  • The cpsrvd daemon recognizes URL paths that contain a file modification time, and serves files as the browser cached them if no new changes have occurred.

Default template example

[%

    #----------------------------------------------------------------------
    # Arguments received by this template:
    # This list may not be exhaustive, and other parameters may be added or available.
    #
    # notice_text - Contents of the notice message to be displayed on page
    # entry_point - From where did the user come to get to this page (invitation / resetpass btn)

# Currently the only two modes are debug and release, but this
# might be expanded in the future.
IF CPANEL.is_debug_mode_enabled();
    SET mode = 'debug';
    SET optimized = 0;
ELSE;
    SET mode = 'release';
    SET optimized = 1;
END;

SET disp_apps = {
    'whostmgrd' => 'WHM',
    'webmaild' => 'Webmail',
    'cpaneld' => 'cPanel',
};
SET disp_app  = disp_apps.item(app_name) || 'cPanel';

SET app_images = {
    'whostmgrd' => 'whm-logo_white.svg',
    'webmaild'  => 'webmail-logo.svg',
    'cpaneld'   => 'cpanel-logo.svg',
};

# get app modules based on $app_name
SET app_image = app_images.$app_name || app_images.cpaneld;
SET app_image = MagicRevision(get_theme_url("images/" _ app_image));

SET stylesheets = [];
IF optimized;
    stylesheets.push(
        MagicRevision(get_theme_url('fonts/open_sans/open_sans.min.css')));
    stylesheets.push(
        MagicRevision(get_theme_url('style_v2_optimized.css')));
ELSE;
    stylesheets.push(
        MagicRevision(get_theme_url('fonts/open_sans/open_sans.css')));
    stylesheets.push(
        MagicRevision(get_theme_url('style_v2.css')));
END;

-%]
<!DOCTYPE html>
<html lang="[% locale.get_language_tag() %]" dir="[% locale.get_html_dir_attr() %]">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title>
        [%- IF entry_point == 'resetpass' -%]
        [% locale.maketext('Reset Password') %]
        [%- ELSIF entry_point == 'invitation' -%]
        [% locale.maketext('Set a password for your new account.') %]
        [%- END -%]
        </title>
        <meta name="viewport" content="width=device-width, initial-scale=1.0">

          <link rel="shortcut icon" href="[% MagicRevision(get_theme_url('favicon.ico')) FILTER html %]" type="image/x-icon" />

          <!-- EXTERNAL CSS -->
          [% FOR source IN stylesheets-%]
          <link href="[% source FILTER html %]" rel="stylesheet" type="text/css" />
          [%- END -%]
      </head>
      <body class="cp">
          <div id="login-wrapper">

              <div id="resetpass">
                  <div id="login-container">
                      <div id="login-sub-container">

                          <div id="login-sub-header">
                              <img src="[% app_image %]" height="50" alt="logo" />
                          </div>

                          <div id="notify"
                              [%- IF !notice_text %]
                               style="display:none"
                              [% END -%]>
                              <div id="login-status"
                                   class="[% notice_class || 'info-notice' %]">
                                  <div id="login-detail">
                                      <div id="login-status-icon-container">
                                          <span class="login-status-icon"></span>
                                      </div>
                                      <div id="[% notice_id || 'login-status-message' %]" class="login-status-message">
                                          [% notice_text %]
                                      </div>
                                  </div>
                              </div>
                          </div>

                          <div id="reset-sub">
                              [% PROCESS "templates/$page_to_show" %]
                          </div>
                      </div>
                  </div>
              </div>

          </div>

          <div class="copyright">
              [% locale.maketext('Copyright©[output,nbsp][current_year] WebPros International, LLC') %]
          </div>

          [% IF mode == 'debug' %]
          <script type="text/javascript">
              window.onload = function() {

                  // Warning Duplicate IDs
                  var ids = {};

                  if(document.querySelectorAll){
                      var els = document.querySelectorAll("[id]");
                      for(var i= 0; i < els.length; i++ ) {
                          var el = els[i];
                          if(ids[el.id]) {
                              console.warn('Duplicate ID #'+this.id);
                          }
                          ids[el.id] = 1;
                      }
                  }
              };
          </script>
          [% END %]
      </body>
<html>

templates/resetpass_confirmation.tmpl

This template generates the page that displays when a user clicks Reset Password and has entered a username in the Username text box.

  • When the system accesses this template, it also sends a confirmation code to the user via email. This email message uses either the resetpass-email.tmpl or resetpass-email-html.tmpl template, based on whether the user's email client can display HTML.
  • The user must enter the confirmation code that they receive in order to reset the password.

Template variables

This template does not use template variables.

Default template example

[%

    #----------------------------------------------------------------------
    # Arguments received by this template:
    # This list may not be exhaustive, and other parameters may be added or available.
    #
    # user - Reset password user

%]
<div id="reset-forms">
    <script type="text/javascript">
    function toggle(id) {
        var el = document.getElementById(id);
        if (el) {
            if (el.style.display === "none") {
                el.style.display = "";
            } else {
                el.style.display = "none";
            }
        }
    }
    </script>
    <form id="reset_form" novalidate action="resetpass" method="post">
        <!--prevent submit on Enter if login button is disabled-->
        <input style="display:none" />

        <input type="hidden" name="user" value="[% user.html() %]" />
        <input type="hidden" name="action" value="seccode" />
        <input type="hidden" name="debug" value="[%CPANEL.is_debug_mode_enabled() ? '1' : '' %]">

        <div class="input-req-login">
            <label for="confirmation">[% locale.maketext('Security Code') %]</label>
        </div>
        <div class="input-field-login no-icon">
            <input name="confirm" type="text" class="std_textbox" id="confirmation" maxlength="16" required autocomplete="off" autofocus>
        </div>
        <div class="pnlResend">
            <a id="btnResend"
               class="lnkResend"
               href="?user=[% user.html() %]&action=resend">
                [% locale.maketext('Send Security Code Again') %]
            </a>
            <a onclick="toggle('msgResendMore')" class="btnMore"
                  title="[% locale.maketext('More') %]">
                (?)
            </a>
            <span id="msgResendMore" style="display:none">
                [% locale.maketext('If you have not received the email that contains the security code, check your contact email account's spam. Some email providers may identify the password-reset email as spam. If necessary, you can request the server send another email.') %] <a id="btnCloseMore" class="btnMore" onclick="toggle('msgResendMore')">[% locale.maketext('Close') %]</a>
            </span>
        </div>
        <div id="reset-note" class="reset-input-note">
            <p>[% locale.maketext('[output,strong,Please keep this browser window open.]') %]</p>
            <p>[% locale.maketext('You must enter the code in the same browser from which you initiated the password reset request.') %]</p>
        </div>
        <div class="controls">
            <div id="confirm-submit-btn" class="login-btn">
                <button type="submit" id="confirm-submit">[% locale.maketext('Submit') %]</button>
            </div>
            <div class="reset-pw">
                <a href="/">[% locale.maketext('Cancel') %]</a>
            </div>
        </div>
        <div class="clear"></div>
    </form>
    <span id="resetpass-seccode">[%# marker for testing%]</span>
</div>

templates/resetpass_failure.tmpl

This template generates the page that displays when the system cannot reset the user's password. The system displays an error message.

Template variables

This template does not use template variables.

Default template example

[%

    #----------------------------------------------------------------------
    # Arguments received by this template:
    # This list may not be exhaustive, and other parameters may be added or available.
    #

%]
<div>
    <p>[% locale.maketext('The system failed to reset your account's password. Additional information may exist in the server error log. Contact your server administrator or hosting provider.') %]</p>
    <span id="resetpass-failure">[%# marker for testing%]</span>
</div>

templates/resetpassnouser.tmpl

This template generates the page that displays when a user clicks Reset Password without a username in the Username text box.

Template variables

This template does not use template variables.

Default template example

[%

    #----------------------------------------------------------------------
    # Arguments received by this template:
    # This list may not be exhaustive, and other parameters may be added or available.
    #

SET reset_url = "/resetpass";
IF !https;
USE ApplicationUrl;
SET secure_url = ApplicationUrl.get_secure_url(
    host            => SERVER_NAME,
    port            => SERVER_PORT,
    proxysubdomains => cpconf.proxysubdomains);
SET reset_url = secure_url _ reset_url;
END;
%]
<div id="reset-forms">
    [% IF !https %]
    <form id="reload_form" action="[% reset_url %]">
        [% IF CPANEL.is_debug_mode_enabled() %]
            <input type="hidden" name="debug" value="1">
        [% END %]
        <input type="hidden" name="start" value="1">
        <div class="alert alert-warning">
            <span class="fas fa-2x fa-exclamation-triangle" aria-hidden="true"></span>
            <div class="alert-message">
                <strong>[% locale.maketext('Warning:') %]</strong>
                [% locale.maketext('The Reset Password feature only supports the [asis,HTTPS] protocol.') %]
            </div>
        </div>
        <div class="controls">
            <div class="login-btn">
                <input id="login" type="submit" value="[% locale.maketext('Reload with [asis,HTTPS]') %]">
            </div>
        </div>
        <div class="controls">
            <div class="reset-pw">
                <a href="/">[% locale.maketext('Cancel') %]</a>
            </div>
        </div>
        <div class="clear"></div>
    </form>
    [% ELSE %]
    <form id="reset_form" action="/resetpass" method="POST">
        <!-- Prevent submit via Enter if submit button is disabled -->
        <input style="display:none" />

        [% IF CPANEL.is_debug_mode_enabled() %]
            <input type="hidden" name="debug" value="1">
        [% END %]

        <div class="input-req-login">
            <label for="username">[% locale.maketext('Username') %]</label>
        </div>
        <div class="input-field-login icon username-container">
            <input name="user" id="username" placeholder="[% locale.maketext('Enter your username.') %]" type="text"  autocomplete="off" class="std_textbox" tabindex="1" required autofocus >
        </div>
        <div class="controls">
            <div class="login-btn">
                <input name="login" type="submit" id="login" value="[% locale.maketext('Reset Password') %]" >
            </div>
        </div>
        <div class="controls">
            <div class="reset-pw">
                <a href="/">[% locale.maketext('Cancel') %]</a>
            </div>
        </div>
        <div class="clear"></div>
    </form>
    [% END %]
    <span id="resetpass-no-user">[%# marker for testing%]</span>
</div>

templates/resetpass_set_password.tmpl

This template generates the confirmation page that displays when a user requests a password reset.

Template variables

This template does not use template variables.

Default template example

[%

    #----------------------------------------------------------------------
    # Arguments received by this template:
    # This list may not be exhaustive, and other parameters may be added or available.
    #
    # user - Reset password user

    SET application_dir = 'cpanel';
    SET file = 'resetpass';
%]

[% PROCESS '_assets/cjt2_header_include.tt' %]

<div id="content" ng-controller="setPasswordController">
    <div id="forms">
        <form id="reset_form" name="reset_form" action="/resetpass" method="post" novalidate ng-cloak autocomplete="off" ng-submit="inProgress = true;">
            <!-- prevent password autofill -->
            <input type="text" style="display:none">
            <input type="password" autocomplete='off' style="display:none">
            <input type="hidden" name="action" value="password">
            <input type="hidden" name="user" value="[%user%]">
            <input type="hidden" name="debug" value="[%CPANEL.is_debug_mode_enabled() ? '1' : '' %]">

            <!-- Password Input -->
            <div class="reset-input-group">
                <div class="input-req-login">
                    <label for="password">[% locale.maketext('New Password') %]</label>
                </div>
                <password name="password"
                          class="std_textbox"
                          tabindex="1"
                          auto-focus
                          autocomplete="off"
                          title="[% locale.maketext('Your new password.') %]"
                          minimum-strength="[% get_required_password_strength( is_subaccount ? 'virtual' : 'passwd' ) %]"
                          placeholder="[% locale.maketext('Enter your new password') %]"
                          password="password"
                          show-meter="true"
                          show-strength="true"
                          show-generator="true"
                          minimum-length="5"
                          required
                          generate-minimum-length="5"
                          generate-maximum-length="18"
                          generate-button-tab-index="-1"
                          toggle-view-button-tab-index="-1"
                          generate-settings-tab-index="-1"
                          strength-meets-template="[% locale.lextext('This password has a strength of [numf,_1], which meets or exceeds the system requirement of [numf,_2].') %]"
                          strength-does-not-meet-template="[% locale.lextext('The password has a strength of [numf,_1], but your system requires a strength of [numf,_2].') %]"
                          password-strength="passwordStrength">
                </password>

                <ul validation-container field-name="password" ng-cloak>
                   <li validation-item field-name="password" validation-name="required" id="val-password-required">
                       [% locale.maketext('You must complete this field.') %]
                   </li>
                   <li validation-item field-name="password" validation-name="minlength" id="val-password-minlength">
                       [% locale.maketext('You must provide a password with at least 5 characters.') %]
                   </li>
                   <li validation-item field-name="password" validation-name="minimumPasswordStrength" id="val-password-minimum-strength">
                       [% locale.maketext('You must provide a stronger password.') %]
                   </li>
               </ul>
           </div>

            <!-- Password Confirmation -->
            <div class="reset-input-group">
                <div class="input-req-login">
                    <label for="confirm">[% locale.maketext('Confirm Password') %]</label>
                </div>
                <div class="input-field-login icon password-confirm-container">
                    <input name="confirm"
                           id="confirm"
                           type="password"
                           autocomplete='off'
                           ng-model="passwordConfirm"
                           class="std_textbox"
                           tabindex="2"
                           placeholder="[% locale.maketext('Enter your new password, again.') %]"
                           validate-equals="reset_form.password"
                           required>
                </div>

                <ul validation-container field-name="confirm" ng-cloak>
                    <li validation-item field-name="confirm" validation-name="required" id="puzzle-guess-input-required">
                       [% locale.maketext('You must complete this field.') %]
                   </li>
                   <li validation-item field-name="confirm" validation-name="validateEquals" id="val-password-confirm-match">
                           [% locale.maketext('The passwords do not match.') %]
                       </li>
                </ul>
            </div>

            <div class="controls">
                <div class="login-btn">
                    <input name="login"
                           type="submit"
                           id="login"
                           value="[% locale.maketext('Set Password') %]"
                           ng-disabled="!reset_form.$valid || reset_form.$pending || inProgress">
                </div>
            </div>
        </form>
        <span id="resetpass-set-password">[%# marker for testing%]</span>
    </div>
</div>

templates/resetpass_success.tmpl

This template generates the confirmation page that displays when a user resets a password successfully.

Template variables

This template does not use template variables.

Default template example

[%

    #----------------------------------------------------------------------
    # Arguments received by this template:
    # This list may not be exhaustive, and other parameters may be added or available.
    #
    # user - Reset password user
    # service_names - List of affected services
    # next_steps - List of invitation step objects
    #          {
    #               key => Key identifying the step type
    #               instructions => Instructions for that specific step
    #               services => List of services associate with that step
    #          }
    #
    # logins - List of login service objects
    #          {
    #              id => Dom Element ID
    #              url => url the button will direct them to when clicked
    #              button_text => label for the button
    #          }

%]
<div class="form-container">
    <p id="cpanel-services" >[% locale.maketext('Your change affects the following account services: [list_and,_1]', service_names) %]</p>

    [% FOREACH step IN next_steps %]
        [% IF step.value.services.size() %]
    <p id="[% step.key %]-instructions">[% step.value.instructions %]</p>
        [% END %]
    [% END %]

    [% FOREACH login IN logins -%]
    <div class="controls">
        <div class="login-btn">
            <a class="loginbtn" href="[% login.url %]" id="[% login.id %]">
                [% login.button_text %]
            </a>
        </div>
    </div>
    [% END %]

    <span id="resetpass-success">[%# marker for testing%]</span>
</div>

templates/resetpass_suspended.tmpl

This template generates the page that displays when a user attempts to reset the password on a suspended account.

Template variables

This template does not use template variables.

Default template example

[%

    #----------------------------------------------------------------------
    # Arguments received by this template:
    # This list may not be exhaustive, and other parameters may be added or available.
    #

%]
<div>
    <p>[% locale.maketext('Your account is suspended. Please contact the billing or support department or your server administrator.') %]</p>
    <span id="resetpass-suspended">[%# marker for testing%]</span>
</div>

securitypolicy_footer.html.tmpl

This template generates the Security Policy page's footer. Users set the security questions for their accounts through this page.

Template variables

This template does not use template variables.

Default template example

[%

    #----------------------------------------------------------------------
    # Arguments received by this template:
    # This list may not be exhaustive, and other parameters may be added or available.
    #

%]
</div>
</div>
<div class="clear"></div>
</div>
</div>
<!-- close login-wrapper -->
</div>
</div>
</div>
</div>
</div>
<div class="copyright">[% locale.maketext('Copyright©[output,nbsp][current_year] WebPros International, LLC') %]</div>
</div>
</body>
</html>

securitypolicy_header.html.tmpl

This template generates the Security Policy page's header. Users set the security questions for their accounts through this page.

Template variables

This template does not use template variables.

Default template example

[%

    #----------------------------------------------------------------------
    # Arguments received by this template:
    # This list may not be exhaustive, and other parameters may be added or available.
    #
    # action - Type of securty action being taken (setquestions, challenge)
    # app_name - What application is loading this interface (cpaneld, whostmgrd, webmaild)
    # error - Error being presented to the user
    # warning - Warning being presented to the user, possibly overriden in the template


IF action == 'setquestions';
    SET warning = locale.maketext('You have not set up security questions for your account.')
        _ " " _ locale.maketext('Please take a moment to set up your security questions.');
ELSIF action == 'challenge';
    SET warning = locale.maketext('You appear to be logging in from an unknown location.')
        _ " " _ locale.maketext('Please verify your identity by answering the following security questions:');
END;

SET body_class = '';
SWITCH app_name;
    CASE 'cpaneld';
        SET app = 'cPanel';
        SET body_class = "cp";
    CASE 'whostmgrd';
        SET app = 'WHM';
        SET body_class = "whm";
    CASE DEFAULT;
        SET app = 'Webmail';
        SET body_class = "wm";
END;

SET title = locale.maketext('[_1] Login Security',app);

SET app_images = {
    'whostmgrd' => 'whm-logo_white.svg',
    'webmaild'  => 'webmail-logo.svg',
    'cpaneld'   => 'cpanel-logo.svg',
};

SET app_image = app_images.$app_name || app_images.cpaneld;
SET app_image = MagicRevision(get_theme_url("images/$app_image"));


-%]
<!DOCTYPE html>
<html dir="[% locale.get_html_dir_attr() %]">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

<!-- EXTERNAL CSS -->
<link href="[% MagicRevision(get_theme_url('fonts/open_sans/open_sans.min.css')) FILTER html %]" rel="stylesheet" type="text/css" />
<link href="[% MagicRevision(get_theme_url('style_v2_optimized.css')) FILTER html %]" rel="stylesheet" type="text/css" />
<style type="text/css">
/* This css is included in the base template in case the css cannot be loaded because of access restrictions
    If this css is updated, please update main.tmpl as well */
.copyright {
background: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzNTlwdCIgaGVpZ2h0PSIzMjAiIHZpZXdCb3g9IjAgMCAzNTkgMjQwIj48ZGVmcz48Y2xpcFBhdGggaWQ9ImEiPjxwYXRoIGQ9Ik0xMjMgMGgyMzUuMzd2MjQwSDEyM3ptMCAwIi8+PC9jbGlwUGF0aD48L2RlZnM+PHBhdGggZD0iTTg5LjY5IDU5LjEwMmg2Ny44MDJsLTEwLjUgNDAuMmMtMS42MDUgNS42LTQuNjA1IDEwLjEtOSAxMy41LTQuNDAyIDMuNC05LjUwNCA1LjA5Ni0xNS4zIDUuMDk2aC0zMS41Yy03LjIgMC0xMy41NSAyLjEwMi0xOS4wNSA2LjMtNS41MDUgNC4yLTkuMzUzIDkuOTA0LTExLjU1MiAxNy4xMDMtMS40IDUuNDAzLTEuNTUgMTAuNS0uNDUgMTUuMzAyIDEuMDk4IDQuNzk2IDMuMDQ3IDkuMDUgNS44NTIgMTIuNzUgMi43OTcgMy43MDMgNi40IDYuNjUyIDEwLjc5NyA4Ljg1IDQuMzk3IDIuMiA5LjE5OCAzLjI5OCAxNC40IDMuMjk4aDE5LjJjMy42MDIgMCA2LjU0NyAxLjQ1MyA4Ljg1MiA0LjM1MiAyLjI5NyAyLjkwMiAyLjk0NSA2LjE0OCAxLjk1IDkuNzVsLTEyIDQ0LjM5OGgtMjFjLTE0LjQwMyAwLTI3LjY1My0zLjE0OC0zOS43NS05LjQ1LTEyLjEwMi02LjMtMjIuMTUzLTE0LjY0OC0zMC4xNTMtMjUuMDUtOC0xMC4zOTUtMTMuNDU0LTIyLjI0Ni0xNi4zNS0zNS41NDctMi45LTEzLjMtMi41NS0yNi45NSAxLjA1Mi00MC45NTNsMS4yLTQuNWMyLjU5Ny05LjYwMiA2LjY0OC0xOC40NSAxMi4xNDgtMjYuNTUgNS41LTguMDk4IDEyLTE1IDE5LjUtMjAuNyA3LjUtNS43IDE1Ljg1LTEwLjE0OCAyNS4wNS0xMy4zNTIgOS4yLTMuMTk1IDE4Ljc5Ny00Ljc5NiAyOC44LTQuNzk2IiBmaWxsPSIjZmY2YzJjIi8+PGcgY2xpcC1wYXRoPSJ1cmwoI2EpIj48cGF0aCBkPSJNMTIzLjg5IDI0MEwxODIuOTkgMTguNjAyYzEuNTk4LTUuNTk4IDQuNTk4LTEwLjA5OCA5LTEzLjVDMTk2LjM4OCAxLjcgMjAxLjQ4NCAwIDIwNy4yODggMGg2Mi43YzE0LjQwMyAwIDI3LjY1IDMuMTQ4IDM5Ljc1IDkuNDUgMTIuMTAyIDYuMyAyMi4xNTMgMTQuNjU1IDMwLjE1MyAyNS4wNSA3Ljk5NyAxMC40MDIgMTMuNSAyMi4yNTQgMTYuNSAzNS41NSAzIDEzLjMwNSAyLjU5NCAyNi45NTQtMS4yMDIgNDAuOTVsLTEuMiA0LjVjLTIuNTk3IDkuNjAyLTYuNTk3IDE4LjQ1LTEyIDI2LjU1LTUuMzk4IDguMDk4LTExLjg0NyAxNS4wNTItMTkuMzQ3IDIwLjg0OC03LjUgNS44MDUtMTUuODU1IDEwLjMwNS0yNS4wNSAxMy41LTkuMiAzLjIwNC0xOC44MDUgNC44MDUtMjguODA1IDQuODA1aC01NC4yOTdsMTAuOC00MC41YzEuNi01LjQwMiA0LjYtOS44IDktMTMuMjAzIDQuMzk2LTMuMzk4IDkuNDk3LTUuMTAyIDE1LjMwMi01LjEwMmgxNy4zOThjNy4yIDAgMTMuNjUzLTIuMiAxOS4zNTItNi41OTcgNS42OTUtNC4zOTggOS40NDUtMTAuMDk3IDExLjI1LTE3LjEgMS4zOTQtNC45OTcgMS41NDctOS45LjQ0NS0xNC43LTEuMS00LjgtMy4wNS05LjA0Ny01Ljg0OC0xMi43NS0yLjgtMy42OTUtNi40MDItNi42OTUtMTAuNzk2LTktNC40MDYtMi4yOTctOS4yMDYtMy40NS0xNC40MDItMy40NUgyMzMuMzlsLTQzLjggMTYyLjkwM2MtMS42MDYgNS40LTQuNjA2IDkuNzk3LTkgMTMuMTk1LTQuNDAzIDMuNDA3LTkuNDA2IDUuMTAyLTE1IDUuMTAyaC00MS43IiBmaWxsPSIjZmY2YzJjIi8+PC9nPjwvc3ZnPgo=) no-repeat scroll center top transparent;
background-size: 25px auto;
}
</style>

<title>[% title %]</title>
</head>

<body class="yui-skin-sam security_policy [% body_class %] [% IF small_form; 'small-size'; END; %]">
<div class="login-page">
    <div class="login-content">
        <div class="login-center-answer">
            <div id="login-wrapper">
            [% IF warning -%]
                <div id="login-status" class="warn-notice">
                    <div class="message-detail">
                        <div id="login-status-icon-container"><span class="login-status-icon"></span></div>
                        <div id="login-status-message">[% warning %]</div>
                    </div>
                </div>
            [% END -%]

            [% IF error -%]
                <div id="login-status" class="error-notice">
                    <div class="message-detail">
                        <div id="login-status-icon-container"><span class="login-status-icon"></span></div>
                        <div id="login-status-message">[% error %]</div>
                    </div>
                </div>
            [% END -%]

            <div id="content-container">
                <div id="security-container">
                    <div id="security-sub-container">
                        <div id="login-sub-header">
                            <img src="[% app_image %]" alt="logo" class="main-logo" />
                        </div>
                        <div id="security-sub">
                            <div class="login-rt">
                                <div class="form">

templates/token_denied.tmpl

The system accesses this template whenever the server responds with a Token Denied error.

Template variables

Variable Type Description
dest_uri string The URL to load after a user authenticates. This URL does not contain the security token.
error_msg string The error message to display.
form_ref hash A hash of the form variables to pass with the request. The system sends this hash to the location that the redirect_uri variable specifies.
parameterized_form hash A hash of form variables that the user provided as a URL query string.
theme string The theme to load.
user string The username to authenticate.

Default template example

[%

    #----------------------------------------------------------------------
    # Arguments received by this template:
    # This list may not be exhaustive, and other parameters may be added or available.
    #
    # goto_uri - The uri that the user requested
    # user - Username requesting access
    # app_name - What application is loading this interface (cpaneld, whostmgrd, webmaild)
    # theme - The current cPanel theme that the user is using
    # parameterized_form - A dump of the postdata that is uri encoded

%]
[% WRAPPER 'templates/_error_wrapper' -%]

[% PROCESS "templates/external_auth_header.tmpl" %]

    <!-- Do not remove msg_code as it is needed for automated testing - msg_code:[invalid_token]  -->
    <h3>[% locale.maketext('Invalid Security Token') %]</h3>
    <p>[% locale.maketext('The requested [output,acronym,URL,Uniform Resource Locator] does not contain your session's correct security token.') %]</p>
    <p>[% locale.maketext('You may have reached this error by copying and pasting a URL from a different cPanel, WHM, or Webmail session into your browser's address bar. To resolve this situation, please take one of the following steps:') %]</p>
    <ul class="options">
        <li>[% locale.maketext('[output,url,_1,Go back one page,_2,_3] and reload the URL, making sure that the [output,class,/cpsess ... /,_4] section of the URL remains the same.','javascript:history.back()','class','page-link','code') %]</li>
        <li>[% locale.maketext('Re-enter your account's password below. This will assign your session a new security token. This new token will prevent you from using other pages of this application that may be open in other tabs.') %]</li>
    </ul>
    <div id="token-forms">
        <div class="pagevars">
            <h3>[% locale.maketext('Request information') %]</h3>
            <p>
                [% dest_html = goto_uri.html() -%]
                [% locale.maketext('Requested page: [_1]', dest_html) %]
            </p>
            [% IF form_ref.keys.size -%]
                <table class="formtbl" cellspacing="6">
                    <tr>
                        <th>[% locale.maketext('Parameter name') %]</th>
                        <th>[% locale.maketext('Parameter value') %]</th>
                    </tr>
                    [% FOR pair = form_ref -%]
                    <tr><td>[% pair.key.html() %]</td><td>[% pair.value.html() %]</td></tr>
                    [% END -%]
                </table>
            [% END -%]
        </div>

        <div id="login-container">
          <div id="login-sub-container">
            <form id="badtokenloginform" action="/login" method="POST">
                <input type="hidden" id="url_fragment_input" name="url_fragment" value="" />
                <input type="hidden" name="user" value="[% user.html() %]" />
                <input type="hidden" name="token_denied" value="1" />
                <input type="hidden" name="parameterized_form" value="[% parameterized_form.html() %]" />
                <input type="hidden" name="goto_uri" value="[% goto_uri.html() %]" />
                <input type="hidden" name="theme" value="[% theme.html() %]" />
                <p>[% locale.maketext('Username: [_1]', user).html() %]</p>
                <div class="control_container">
                    <div class="group">
                    <div class="controls">
                        <div class="input-field-login icon password-container">
                            <input name="pass" id="pass" placeholder="[% IF app_name=="webmaild" %][% locale.maketext('Enter your email password.') %][% ELSE %][% locale.maketext('Enter your account password.') %][% END %]" class="std_textbox" type="password" autofocus required>
                        </div>
                    </div>
                    </div>
                    <div class="group">
                    <div class="controls">
                        <div class="login-btn" id="proceed_btn_container">
                            <button type="submit" id="token-submit">[% locale.maketext('Proceed with the Current Request') %]</button>
                        </div>
                    </div>
                    </div>
                </div>
            </form>

            [% PROCESS "templates/external_auth.tmpl" %]

            <form id="badtokenlogoutform"  action="/logout" target="_top">
                <div class="control_container">
                    <div class="controls">
                        <div class="login-btn" id="logout_btn_container">
                            <button type="submit" id="logout-btn">[% locale.maketext('Log Out') %]</button>
                        </div>
                    </div>
                </div>
            </form>
          </div>
        </div>
    </div>

    <script>
        try { document.getElementById("pass").focus(); } catch(e) {}
	document.getElementById("url_fragment_input").value = location.hash;
    </script>
[% END %]