';
+ if ($facturestatic->fk_project > 0) {
+ $project->fetch($facturestatic->fk_project);
+ print $project->getNomUrl(1);
+ }
// $filename = dol_sanitizeFileName($objp->ref);
// $filedir = $conf->facture->multidir_output[$objp->entity].'/'.dol_sanitizeFileName($objp->ref);
// $urlsource = '/compta/facture/card.php?id='.$objp->cid;
diff --git a/htdocs/compta/prelevement/class/bonprelevement.class.php b/htdocs/compta/prelevement/class/bonprelevement.class.php
index 9f60156c6a8..e8770f12f0e 100644
--- a/htdocs/compta/prelevement/class/bonprelevement.class.php
+++ b/htdocs/compta/prelevement/class/bonprelevement.class.php
@@ -2211,13 +2211,13 @@ class BonPrelevement extends CommonObject
$XML_DEBITOR .= ' false' . $CrLf;
$XML_DEBITOR .= ' ' . $CrLf;
$XML_DEBITOR .= ' ' . $CrLf;
+ $XML_DEBITOR .= ' ' . $CrLf;
+ $XML_DEBITOR .= ' ' . $CrLf;
if (getDolGlobalInt('WITHDRAWAL_WITHOUT_BIC')==0) {
- $XML_DEBITOR .= ' ' . $CrLf;
- $XML_DEBITOR .= ' ' . $CrLf;
$XML_DEBITOR .= ' ' . $row_bic . '' . $CrLf;
- $XML_DEBITOR .= ' ' . $CrLf;
- $XML_DEBITOR .= ' ' . $CrLf;
}
+ $XML_DEBITOR .= ' ' . $CrLf;
+ $XML_DEBITOR .= ' ' . $CrLf;
$XML_DEBITOR .= ' ' . $CrLf;
$XML_DEBITOR .= ' ' . dolEscapeXML(strtoupper(dol_string_nospecial(dol_string_unaccent($row_nom), ' '))) . '' . $CrLf;
$XML_DEBITOR .= ' ' . $CrLf;
diff --git a/htdocs/core/boxes/box_factures_imp.php b/htdocs/core/boxes/box_factures_imp.php
index 4c7473046d5..86e9b986a31 100644
--- a/htdocs/core/boxes/box_factures_imp.php
+++ b/htdocs/core/boxes/box_factures_imp.php
@@ -139,10 +139,9 @@ class box_factures_imp extends ModeleBoxes
while ($line < min($num, $this->max)) {
$objp = $this->db->fetch_object($result);
- $datelimite = $this->db->jdate($objp->datelimite);
$date = $this->db->jdate($objp->date);
$datem = $this->db->jdate($objp->tms);
- $datelimit = $this->db->jdate(datelimite);
+ $datelimit = $this->db->jdate($objp->datelimite);
$facturestatic->id = $objp->facid;
$facturestatic->ref = $objp->ref;
@@ -182,7 +181,7 @@ class box_factures_imp extends ModeleBoxes
$late = '';
if ($facturestatic->hasDelay()) {
// @phan-suppress-next-line PhanPluginPrintfVariableFormatString
- $late = img_warning(sprintf($l_due_date, dol_print_date($datelimite, 'day', 'tzuserrel')));
+ $late = img_warning(sprintf($l_due_date, dol_print_date($datelimit, 'day', 'tzuserrel')));
}
$this->info_box_contents[$line][] = array(
@@ -204,8 +203,8 @@ class box_factures_imp extends ModeleBoxes
);
$this->info_box_contents[$line][] = array(
- 'td' => 'class="center nowraponall" title="'.dol_escape_htmltag($langs->trans("DateDue").': '.dol_print_date($datelimite, 'day', 'tzuserrel')).'"',
- 'text' => dol_print_date($datelimite, 'day', 'tzuserrel'),
+ 'td' => 'class="center nowraponall" title="'.dol_escape_htmltag($langs->trans("DateDue").': '.dol_print_date($datelimit, 'day', 'tzuserrel')).'"',
+ 'text' => dol_print_date($datelimit, 'day', 'tzuserrel'),
);
$this->info_box_contents[$line][] = array(
diff --git a/htdocs/core/lib/openid_connect.lib.php b/htdocs/core/lib/openid_connect.lib.php
new file mode 100644
index 00000000000..21cf8ef30cc
--- /dev/null
+++ b/htdocs/core/lib/openid_connect.lib.php
@@ -0,0 +1,76 @@
+
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+/**
+ * \file htdocs/admin/openid_connect.php
+ * \ingroup openid_connect
+ * \brief Functions for the module openid_connect
+ */
+
+/**
+ * Prepare array with list of tabs
+ *
+ * @return array Array of tabs to show
+ */
+function openid_connect_prepare_head()
+{
+ global $langs, $conf, $user;
+ $h = 0;
+ $head = array();
+
+ $head[$h][0] = dol_buildpath("/admin/openid_connect.php", 1);
+ $head[$h][1] = $langs->trans("Parameters");
+ $head[$h][2] = 'settings';
+ $h++;
+
+ complete_head_from_modules($conf, $langs, null, $head, $h, 'openid_connect_admin');
+
+ return $head;
+}
+
+
+/**
+ * return the current state
+ *
+ * @return string String containing the state
+ */
+function openid_connect_get_state()
+{
+ return hash('sha256', session_id());
+}
+
+
+/**
+ * return the redirect url
+ *
+ * @return string Redirect url
+ */
+function openid_connect_get_redirect_url()
+{
+ return DOL_MAIN_URL_ROOT . '/core/modules/openid_connect/callback.php';
+}
+
+
+/**
+ * Return authentication url
+ *
+ * @return string Authentication url
+ */
+function openid_connect_get_url()
+{
+ return getDolGlobalString('MAIN_AUTHENTICATION_OIDC_AUTHORIZE_URL') . '?client_id=' . getDolGlobalString('MAIN_AUTHENTICATION_OIDC_CLIENT_ID') . '&redirect_uri=' . openid_connect_get_redirect_url() . '&scope=' . getDolGlobalString('MAIN_AUTHENTICATION_OIDC_SCOPES') . '&response_type=code&state=' . openid_connect_get_state();
+}
diff --git a/htdocs/core/login/functions_openid_connect.php b/htdocs/core/login/functions_openid_connect.php
index 81b829b1890..82689da653c 100644
--- a/htdocs/core/login/functions_openid_connect.php
+++ b/htdocs/core/login/functions_openid_connect.php
@@ -27,6 +27,7 @@
*/
include_once DOL_DOCUMENT_ROOT.'/core/lib/geturl.lib.php';
+include_once DOL_DOCUMENT_ROOT.'/core/lib/openid_connect.lib.php';
/**
* Check validity of user/password/entity
@@ -41,6 +42,12 @@ function check_user_password_openid_connect($usertotest, $passwordtotest, $entit
{
global $db;
+ if (getDolGlobalInt('MAIN_MODULE_OPENIDCONNECT', 0) <= 0) {
+ $_SESSION["dol_loginmesg"] = "OpenID Connect is disabled";
+ dol_syslog("functions_openid_connect::check_user_password_openid_connect Module disabled");
+ return false;
+ }
+
// Force master entity in transversal mode
$entity = $entitytotest;
if (isModEnabled('multicompany') && getDolGlobalString('MULTICOMPANY_TRANSVERSE_MODE')) {
@@ -72,7 +79,7 @@ function check_user_password_openid_connect($usertotest, $passwordtotest, $entit
$state = GETPOST('state', 'aZ09');
dol_syslog('functions_openid_connect::check_user_password_openid_connect code='.$auth_code.' state='.$state);
- if ($state !== hash('sha256', session_id())) {
+ if ($state !== openid_connect_get_state()) {
// State does not match
$_SESSION["dol_loginmesg"] = "Error in OAuth 2.0 flow (state does not match)";
dol_syslog("functions_openid_connect::check_user_password_openid_connect::state does not match", LOG_ERR);
@@ -85,7 +92,7 @@ function check_user_password_openid_connect($usertotest, $passwordtotest, $entit
'client_id' => getDolGlobalString('MAIN_AUTHENTICATION_OIDC_CLIENT_ID'),
'client_secret' => getDolGlobalString('MAIN_AUTHENTICATION_OIDC_CLIENT_SECRET'),
'code' => $auth_code,
- 'redirect_uri' => getDolGlobalString('MAIN_AUTHENTICATION_OIDC_REDIRECT_URL')
+ 'redirect_uri' => openid_connect_get_redirect_url()
];
$token_response = getURLContent(getDolGlobalString('MAIN_AUTHENTICATION_OIDC_TOKEN_URL'), 'POST', http_build_query($auth_param), 1, array(), array('https'), 2);
diff --git a/htdocs/core/modules/modOpenIDConnect.class.php b/htdocs/core/modules/modOpenIDConnect.class.php
new file mode 100644
index 00000000000..d8166c46ec0
--- /dev/null
+++ b/htdocs/core/modules/modOpenIDConnect.class.php
@@ -0,0 +1,113 @@
+
+ * Copyright (C) 2015 Frederic France
+ * Copyright (C) 2023 Maximilien Rozniecki
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+/** \defgroup openid_connect Module OpenID Connect
+ * \brief Module for activation of OpenID Connect authentication method
+ */
+
+/**
+ * \file htdocs/core/modules/modOpenIDConnect.class.php
+ * \ingroup openid_connect
+ * \brief Description and activation file for the module OpenID Connect
+ */
+include_once DOL_DOCUMENT_ROOT.'/core/modules/DolibarrModules.class.php';
+
+
+
+/**
+ * Class to describe and activate module OpenID Connect
+ */
+class modOpenIDConnect extends DolibarrModules
+{
+ /**
+ * Constructor
+ *
+ * @param DoliDB $db Database handler
+ */
+ public function __construct($db)
+ {
+ $this->db = $db;
+ $this->numero = 69000; // ToDo
+ // Family can be 'crm','financial','hr','projects','products','ecm','technic','other'
+ // It is used to group modules in module setup page
+ $this->family = "interface";
+ $this->module_position = '32';
+ // Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module)
+ $this->name = preg_replace('/^mod/i', '', get_class($this));
+ // Module description, used if translation string 'ModuleXXXDesc' not found (where XXX is value of numeric property 'numero' of module)
+ $this->description = "Enable OpenID Connect authentication";
+ // Possible values for version are: 'development', 'experimental', 'dolibarr' or 'dolibarr_deprecated' or version
+ $this->version = 'dolibarr';
+ $this->const_name = 'MAIN_MODULE_'.strtoupper($this->name);
+ // Name of image file used for this module.
+ // If file is in theme/yourtheme/img directory under name object_pictovalue.png, use this->picto='pictovalue'
+ // If file is in module/img directory under name object_pictovalue.png, use this->picto='pictovalue@module'
+ $this->picto = 'technic';
+
+ // Data directories to create when module is enabled.
+ $this->dirs = array();
+
+ // Config pages
+ $this->config_page_url = array("openid_connect.php");
+
+ // Dependencies
+ $this->hidden = false; // A condition to hide module
+ $this->depends = array(); // List of module class names as string that must be enabled if this module is enabled
+ $this->requiredby = array(); // List of module ids to disable if this one is disabled
+ $this->conflictwith = array(); // List of module class names as string this module is in conflict with
+ $this->phpmin = array(7, 0); // Minimum version of PHP required by module // Minimum version of PHP required by module
+ $this->need_dolibarr_version = array(3, 7, -2); // Minimum version of Dolibarr required by module
+ $this->conflictwith = array();
+ $this->langfiles = array("openid_connect");
+
+ // Constants
+ $this->const = array();
+
+ // Boxes
+ $this->boxes = array();
+
+ // Permissions
+ $this->rights = array();
+ $this->rights_class = 'openid_connect';
+
+ // List of menus to add
+ $this->menu = array();
+ }
+
+
+ /**
+ * Function called when module is enabled.
+ * The init function add constants, boxes, permissions and menus (defined in constructor) into Dolibarr database.
+ * It also creates data directories
+ *
+ * @param string $options Options when enabling module ('', 'noboxes')
+ * @return int 1 if OK, 0 if KO
+ */
+ public function init($options = '')
+ {
+ global $conf;
+
+ // Clean before activation
+ $this->remove($options);
+
+ $sql = array();
+
+ return $this->_init($sql, $options);
+ }
+}
diff --git a/htdocs/core/modules/openid_connect/callback.php b/htdocs/core/modules/openid_connect/callback.php
new file mode 100644
index 00000000000..9fd4ffde67d
--- /dev/null
+++ b/htdocs/core/modules/openid_connect/callback.php
@@ -0,0 +1,72 @@
+top_htmlhead
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+/**
+ * \file htdocs/core/modules/openid_connect/public/callback.php
+ * \ingroup openid_connect
+ * \brief OpenID Connect: Authorization Code flow authentication
+ */
+
+
+
+define('NOLOGIN', '1');
+if (!defined('NOTOKENRENEWAL')) {
+ define('NOTOKENRENEWAL', '1');
+}
+
+require '../../../main.inc.php';
+require_once DOL_DOCUMENT_ROOT.'/core/lib/functions.lib.php';
+
+// Javascript code on logon page only to detect user tz, dst_observed, dst_first, dst_second
+$arrayofjs = array(
+ '/includes/jstz/jstz.min.js'.(empty($conf->dol_use_jmobile) ? '' : '?version='.urlencode(DOL_VERSION)),
+ '/core/js/dst.js'.(empty($conf->dol_use_jmobile) ? '' : '?version='.urlencode(DOL_VERSION))
+);
+
+top_htmlhead('', '', 0, 0, $arrayofjs);
+
+$prefix = dol_getprefix('');
+$rollback_url = $_COOKIE["DOL_rollback_url_$prefix"];
+if (empty($rollback_url) || $rollback_url === '/') {
+ $action = $dolibarr_main_url_root . '/index.php?mainmenu=home&leftmenu=';
+} else {
+ $action = $rollback_url;
+ setcookie('DOL_rollback_url_' . dol_getprefix(''), "", time() + 1, '/');
+}
+?>
+
+
+
diff --git a/htdocs/core/modules/societe/mod_codeclient_elephant.php b/htdocs/core/modules/societe/mod_codeclient_elephant.php
index c30145891ed..5101606ea32 100644
--- a/htdocs/core/modules/societe/mod_codeclient_elephant.php
+++ b/htdocs/core/modules/societe/mod_codeclient_elephant.php
@@ -5,7 +5,8 @@
* Copyright (C) 2011 Juanjo Menent
* Copyright (C) 2013-2018 Philippe Grand
* Copyright (C) 2020-2024 Frédéric France
- * Copyright (C) 2024 MDW
+ * Copyright (C) 2024 MDW
+ * Copyright (C) 2024 Eric Seigne
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -93,6 +94,8 @@ class mod_codeclient_elephant extends ModeleThirdPartyCode
$texte .= '';
$texte .= '';
$texte .= '';
+ $texte .= '';
+ $texte .= '';
$texte .= '
- Example on third party created on 2023-01-31:
GenericMaskCodes4c=Example on product created on 2023-01-31:
GenericMaskCodes5=ABC{yy}{mm}-{000000} will give ABC2301-000099 {0000+100@1}-ZZZ/{dd}/XXX will give 0199-ZZZ/31/XXX IN{yy}{mm}-{0000}-{t} will give IN2301-0099-A if the type of company is 'Responsable Inscripto' with code for type that is 'A_RI'
GenericNumRefModelDesc=Returns a customizable number according to a defined mask.
+DateStartThatModel=Disable use of this numbering rule for all thirdparties created before
+DateStartThatModelHelp=You can disable elephant numbering rule for thirdparties created before a date (imported by a migration from another software using a different rule for example). Let that field empty to have the rule applied on all thirdparties.
ServerAvailableOnIPOrPort=Server is available at address %s on port %s
ServerNotAvailableOnIPOrPort=Server is not available at address %s on port %s
DoTestServerAvailability=Test server connectivity
@@ -2511,5 +2513,26 @@ SendToUrl=Send to Url
WebsiteTemplateWasCopied=The website template(s) "%s" provided by this module has been saved into the directory of website templates (/doctemplates/websites) and is ready to be imported as a new web site.
EnabledByDefaultAtInstall=Enabled by default at install
VulnerableToRCEAttack=You are vulnerable to RCE attacks by using the custom dol_json_decode function
+OpenIDconnectSetup=Configuration of the OpenID Connect module
+MainAuthenticationOidcClientIdName=Client ID
+MainAuthenticationOidcClientIdDesc=OpenID Connect Client ID
+MainAuthenticationOidcClientSecretName=Client secret
+MainAuthenticationOidcClientSecretDesc=OpenID Connect Client Secret
+MainAuthenticationOidcScopesName=Scopes
+MainAuthenticationOidcScopesDesc=OpenID scopes to allow access to user information
+MainAuthenticationOidcAuthorizeUrlName=Authorize URL
+MainAuthenticationOidcAuthorizeUrlDesc=(example: https://example.com/oauth2/authorize)
+MainAuthenticationOidcTokenUrlName=Token URL
+MainAuthenticationOidcTokenUrlDesc=(example: https://example.com/oauth2/token)
+MainAuthenticationOidcUserinfoUrlName=User info URL
+MainAuthenticationOidcUserinfoUrlDesc=(example: https://example.com/oauth2/userinfo)
+MainAuthenticationOidcLogoutUrlName=Logout URL
+MainAuthenticationOidcLogoutUrlDesc=(example: https://example.com/oauth2/logout)
+MainAuthenticationOidcRedirectUrlName=Redirect URL
+MainAuthenticationOidcRedirectUrlDesc=Redirect URL to authorize on the OpenID provider side
+MainAuthenticationOidcLogoutRedirectUrlName=Dolibarr logout URL
+MainAuthenticationOidcLogoutRedirectUrlDesc=Dolibarr logout URL to authorize on the OpenID provider side
+MainAuthenticationOidcLoginClaimName=Login claim
+MainAuthenticationOidcLoginClaimDesc=OpenID Connect claim matching the Dolibarr user login. If not set or empty, defaults to email
BlackListWords=Black list of words
AddBlackList=Add to black list
diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php
index 474d0406d5d..d2aa8f02026 100644
--- a/htdocs/main.inc.php
+++ b/htdocs/main.inc.php
@@ -887,7 +887,7 @@ if (!defined('NOLOGIN')) {
if (GETPOST("username", "alpha", $allowedmethodtopostusername)) { // For posting the login form
$goontestloop = true;
}
- if (GETPOST('openid_mode', 'alpha', 1)) { // For openid_connect ?
+ if (GETPOST('openid_mode', 'alpha')) { // For openid_connect ?
$goontestloop = true;
}
if (GETPOST('beforeoauthloginredirect') || GETPOST('afteroauthloginreturn')) { // For oauth login
diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php
index bd8f34d5639..2f61557ff5c 100644
--- a/htdocs/theme/eldy/global.inc.php
+++ b/htdocs/theme/eldy/global.inc.php
@@ -6488,6 +6488,7 @@ div#ecm-layout-center {
max-width: 1024px;
padding-left: 10px !important;
padding-right: 10px !important;
+ padding-top: 10px !important;
word-wrap: break-word;
}
.jnotify-container .jnotify-notification .jnotify-message {
@@ -6502,10 +6503,11 @@ div#ecm-layout-center {
/* use or not ? */
div.jnotify-background {
opacity : 0.95 !important;
- -webkit-box-shadow: 2px 2px 4px #888 !important;
- box-shadow: 2px 2px 4px #888 !important;
+ -webkit-box-shadow: 2px 2px 4px #8888 !important;
+ box-shadow: 2px 2px 4px #8888 !important;
}
+
/* ============================================================================== */
/* blockUI */
/* ============================================================================== */
diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php
index 4b0130eefa4..11e68f6c7c8 100644
--- a/htdocs/theme/md/style.css.php
+++ b/htdocs/theme/md/style.css.php
@@ -6465,6 +6465,7 @@ div#ecm-layout-center {
max-width: 1024px;
padding-left: 10px !important;
padding-right: 10px !important;
+ padding-top: 10px !important;
word-wrap: break-word;
}
.jnotify-container .jnotify-notification .jnotify-message {
@@ -6479,10 +6480,11 @@ div#ecm-layout-center {
/* use or not ? */
div.jnotify-background {
opacity : 0.95 !important;
- -webkit-box-shadow: 2px 2px 4px #888 !important;
- box-shadow: 2px 2px 4px #888 !important;
+ -webkit-box-shadow: 2px 2px 4px #8888 !important;
+ box-shadow: 2px 2px 4px #8888 !important;
}
+
/* ============================================================================== */
/* blockUI */
/* ============================================================================== */
diff --git a/htdocs/user/logout.php b/htdocs/user/logout.php
index be39b2fda02..4103a7ee648 100644
--- a/htdocs/user/logout.php
+++ b/htdocs/user/logout.php
@@ -99,6 +99,15 @@ if (GETPOST('dol_use_jmobile')) {
$url .= (preg_match('/\?/', $url) ? '&' : '?').'dol_use_jmobile=1';
}
+// Logout openid_connect sessions using OIDC logout URL if defined
+if (getDolGlobalInt('MAIN_MODULE_OPENIDCONNECT', 0) > 0 && !empty($_SESSION['OPENID_CONNECT']) && getDolGlobalString("MAIN_AUTHENTICATION_OIDC_LOGOUT_URL")) {
+ // We need the full URL
+ if (strpos($url, '/') === 0) {
+ $url = DOL_MAIN_URL_ROOT . $url;
+ }
+ $url = getDolGlobalString('MAIN_AUTHENTICATION_OIDC_LOGOUT_URL') . '?client_id=' . getDolGlobalString('MAIN_AUTHENTICATION_OIDC_CLIENT_ID') . '&returnTo=' . urlencode($url);
+}
+
// Destroy session
dol_syslog("End of session ".session_id());
if (session_status() === PHP_SESSION_ACTIVE) {
diff --git a/htdocs/zapier/admin/about.php b/htdocs/zapier/admin/about.php
index 9b143c7acdb..88fae5a0a12 100644
--- a/htdocs/zapier/admin/about.php
+++ b/htdocs/zapier/admin/about.php
@@ -71,7 +71,7 @@ $form = new Form($db);
$page_name = "ZapierForDolibarrSetup";
$help_url = 'EN:Module_Zapier';
-llxHeader('', $langs->trans($page_name), $help_url);
+llxHeader('', $langs->trans($page_name), $help_url, '', 0, 0, '', '', '', 'mod-zapier page-admin_about');
// Subheader
$linkback = ''.$langs->trans("BackToModuleList").'';
diff --git a/htdocs/zapier/admin/setup.php b/htdocs/zapier/admin/setup.php
index 6ae23e3dc21..9e5ce8ab950 100644
--- a/htdocs/zapier/admin/setup.php
+++ b/htdocs/zapier/admin/setup.php
@@ -66,7 +66,7 @@ include DOL_DOCUMENT_ROOT . '/core/actions_setmoduleoptions.inc.php';
$page_name = 'ZapierForDolibarrSetup';
$help_url = 'EN:Module_Zapier';
-llxHeader('', $langs->trans($page_name), $help_url);
+llxHeader('', $langs->trans($page_name), $help_url, '', 0, 0, '', '', '', 'mod-zapier page-admin_setup');
// Subheader
$linkback = '' . $langs->trans("BackToModuleList") . '';