'."\n";
print '';
- print '| '.$langs->trans($key[0]).' | ';
+ print '';
+ print img_picto('', $supportedoauth2array[$keyforsupportedoauth2array]['picto'], 'class="pictofixedwidth"');
+ print $langs->trans($keyforsupportedoauth2array);
+ print ' | ';
print ' | ';
print ' | ';
print "
\n";
@@ -244,7 +259,7 @@ if ($mode == 'setup' && $user->admin) {
//var_dump($key);
print $langs->trans("OAuthIDSecret").'';
print '';
- print $langs->trans("SeePreviousTab");
+ print ''.$langs->trans("SeePreviousTab").'';
print ' | ';
print '';
print ' | ';
@@ -259,7 +274,7 @@ if ($mode == 'setup' && $user->admin) {
if (is_object($tokenobj)) {
print $langs->trans("HasAccessToken");
} else {
- print $langs->trans("NoAccessToken");
+ print ''.$langs->trans("NoAccessToken").'';
}
print '';
print '';
@@ -346,7 +361,7 @@ if ($mode == 'setup' && $user->admin) {
if ($mode == 'test' && $user->admin) {
print $langs->trans('PrintTestDesc'.$driver)."
\n";
- print '';
+ print ' ';
print ' ';
if (!empty($driver)) {
require_once DOL_DOCUMENT_ROOT.'/core/modules/printing/'.$driver.'.modules.php';
diff --git a/htdocs/comm/mailing/card.php b/htdocs/comm/mailing/card.php
index 7f2410da136..79faf4b2cd2 100644
--- a/htdocs/comm/mailing/card.php
+++ b/htdocs/comm/mailing/card.php
@@ -493,9 +493,9 @@ if (empty($reshook)) {
if ($action == 'add') {
$mesgs = array();
- $object->email_from = (string) GETPOST("from", "none"); // Must allow 'name '
- $object->email_replyto = (string) GETPOST("replyto", "none"); // Must allow 'name '
- $object->email_errorsto = (string) GETPOST("errorsto", "none"); // Must allow 'name '
+ $object->email_from = (string) GETPOST("from", 'alphawithlgt'); // Must allow 'name '
+ $object->email_replyto = (string) GETPOST("replyto", 'alphawithlgt'); // Must allow 'name '
+ $object->email_errorsto = (string) GETPOST("errorsto", 'alphawithlgt'); // Must allow 'name '
$object->title = (string) GETPOST("title");
$object->sujet = (string) GETPOST("sujet");
$object->body = (string) GETPOST("bodyemail", 'restricthtml');
@@ -531,11 +531,11 @@ if (empty($reshook)) {
if ($action == 'settitle') {
$object->title = trim(GETPOST('title', 'alpha'));
} elseif ($action == 'setemail_from') {
- $object->email_from = trim(GETPOST('email_from', 'none')); // Must allow 'name '
+ $object->email_from = trim(GETPOST('email_from', 'alphawithlgt')); // Must allow 'name '
} elseif ($action == 'setemail_replyto') {
- $object->email_replyto = trim(GETPOST('email_replyto', 'none')); // Must allow 'name '
+ $object->email_replyto = trim(GETPOST('email_replyto', 'alphawithlgt')); // Must allow 'name '
} elseif ($action == 'setemail_errorsto') {
- $object->email_errorsto = trim(GETPOST('email_errorsto', 'none')); // Must allow 'name '
+ $object->email_errorsto = trim(GETPOST('email_errorsto', 'alphawithlgt')); // Must allow 'name '
} elseif ($action == 'settitle' && empty($object->title)) {
$mesg = $langs->trans("ErrorFieldRequired", $langs->transnoentities("MailTitle"));
} elseif ($action == 'setfrom' && empty($object->email_from)) {
diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php
index 74d08ddef2a..63fee0085bb 100644
--- a/htdocs/compta/facture/class/facture.class.php
+++ b/htdocs/compta/facture/class/facture.class.php
@@ -527,9 +527,9 @@ class Facture extends CommonInvoice
// Fields coming from GUI (priority on template). TODO Value of template should be used as default value on GUI so we can use here always value from GUI
$this->fk_project = GETPOST('projectid', 'int') > 0 ? ((int) GETPOST('projectid', 'int')) : $_facrec->fk_project;
- $this->note_public = GETPOST('note_public', 'none') ? GETPOST('note_public', 'restricthtml') : $_facrec->note_public;
- $this->note_private = GETPOST('note_private', 'none') ? GETPOST('note_private', 'restricthtml') : $_facrec->note_private;
- $this->model_pdf = GETPOST('model', 'alpha') ? GETPOST('model', 'alpha') : $_facrec->model_pdf;
+ $this->note_public = GETPOSTISSET('note_public') ? GETPOST('note_public', 'restricthtml') : $_facrec->note_public;
+ $this->note_private = GETPOSTISSET('note_private') ? GETPOST('note_private', 'restricthtml') : $_facrec->note_private;
+ $this->model_pdf = GETPOSTISSET('model') ? GETPOST('model', 'alpha') : $_facrec->model_pdf;
$this->cond_reglement_id = GETPOST('cond_reglement_id', 'int') > 0 ? ((int) GETPOST('cond_reglement_id', 'int')) : $_facrec->cond_reglement_id;
$this->mode_reglement_id = GETPOST('mode_reglement_id', 'int') > 0 ? ((int) GETPOST('mode_reglement_id', 'int')) : $_facrec->mode_reglement_id;
$this->fk_account = GETPOST('fk_account') > 0 ? ((int) GETPOST('fk_account')) : $_facrec->fk_account;
diff --git a/htdocs/compta/tva/card.php b/htdocs/compta/tva/card.php
index 530d18d17f9..317838009c7 100644
--- a/htdocs/compta/tva/card.php
+++ b/htdocs/compta/tva/card.php
@@ -196,7 +196,8 @@ if ($action == 'add' && !$cancel) {
}
$object->amount = $amount;
$object->label = GETPOST("label", 'alpha');
- $object->note = GETPOST("note", 'none');
+ $object->note = GETPOST("note", 'restricthtml');
+ $object->note_private = GETPOST("note", 'restricthtml');
if (empty($object->datep)) {
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("DatePayment")), null, 'errors');
@@ -236,7 +237,7 @@ if ($action == 'add' && !$cancel) {
$paiement->amounts = array($object->id=>$amount); // Tableau de montant
$paiement->paiementtype = GETPOST("type_payment", 'alphanohtml');
$paiement->num_payment = GETPOST("num_payment", 'alphanohtml');
- $paiement->note = GETPOST("note", 'none');
+ $paiement->note = GETPOST("note", 'restricthtml');
if (!$error) {
$paymentid = $paiement->create($user, (int) GETPOST('closepaidtva'));
diff --git a/htdocs/core/class/CSMSFile.class.php b/htdocs/core/class/CSMSFile.class.php
index 8d5bcf7dc50..3f082ba6d53 100644
--- a/htdocs/core/class/CSMSFile.class.php
+++ b/htdocs/core/class/CSMSFile.class.php
@@ -29,8 +29,9 @@
/**
* Class to send SMS
- * Usage: $smsfile = new CSMSFile($subject,$sendto,$replyto,$message,$filepath,$mimetype,$filename,$cc,$ccc,$deliveryreceipt,$msgishtml,$errors_to);
- * $smsfile->sendfile();
+ * Usage: $smsfile = new CSMSFile($subject,$sendto,$replyto,$message,$filepath,$mimetype,$filename,$cc,$ccc,$deliveryreceipt,$msgishtml,$errors_to);
+ * $smsfile->socid=...; $smsfile->contact_id=...; $smsfile->member_id=...; $smsfile->fk_project=...;
+ * $smsfile->sendfile();
*/
class CSMSFile
{
@@ -48,7 +49,8 @@ class CSMSFile
public $nostop;
public $socid;
- public $contactid;
+ public $contact_id;
+ public $member_id;
public $fk_project;
@@ -135,6 +137,7 @@ class CSMSFile
$sms->socid = $this->socid;
$sms->contact_id = $this->contact_id;
+ $sms->member_id = $this->member_id;
$sms->project = $this->fk_project;
$res = $sms->SmsSend();
@@ -167,6 +170,7 @@ class CSMSFile
$sms->socid = $this->socid;
$sms->contact_id = $this->contact_id;
+ $sms->member_id = $this->member_id;
$sms->fk_project = $this->fk_project;
$res = $sms->SmsSend();
diff --git a/htdocs/core/class/html.formadmin.class.php b/htdocs/core/class/html.formadmin.class.php
index 3240d64c893..99ce3bb0201 100644
--- a/htdocs/core/class/html.formadmin.class.php
+++ b/htdocs/core/class/html.formadmin.class.php
@@ -73,15 +73,19 @@ class FormAdmin
$langs_available = $langs->get_available_languages(DOL_DOCUMENT_ROOT, 12, 0, $mainlangonly);
- // If the language to select is not inside the list of available language and empty value is not available, we must find
- // an alternative as the language code to pre-select (to avoid to have first element in list pre-selected).
- if ($selected && !array_key_exists($selected, $langs_available) && empty($showempty)) {
- $tmparray = explode('_', $selected);
- if (!empty($tmparray[1])) {
- $selected = getLanguageCodeFromCountryCode($tmparray[1]);
- }
- if (empty($selected)) {
- $selected = $langs->defaultlang;
+ // If empty value is not allowed and the language to select is not inside the list of available language and we must find
+ // an alternative of the language code to pre-select (to avoid to have first element in list pre-selected).
+ if ($selected && empty($showempty)) {
+ if (!is_array($selected) && !array_key_exists($selected, $langs_available)) {
+ $tmparray = explode('_', $selected);
+ if (!empty($tmparray[1])) {
+ $selected = getLanguageCodeFromCountryCode($tmparray[1]);
+ }
+ if (empty($selected)) {
+ $selected = $langs->defaultlang;
+ }
+ } else {
+ // If the preselected value is an array, we do not try to find alternative to preselect
}
}
diff --git a/htdocs/core/customreports.php b/htdocs/core/customreports.php
index e380dea8403..fafd1c015e8 100644
--- a/htdocs/core/customreports.php
+++ b/htdocs/core/customreports.php
@@ -56,7 +56,7 @@ if (!defined('USE_CUSTOM_REPORT_AS_INCLUDE')) {
}
$search_yaxis = GETPOST('search_yaxis', 'array');
- $search_graph = GETPOST('search_graph', 'none');
+ $search_graph = GETPOST('search_graph', 'restricthtml');
// Load variable for pagination
$limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit;
diff --git a/htdocs/core/db/DoliDB.class.php b/htdocs/core/db/DoliDB.class.php
index fdbb755637a..4476228d509 100644
--- a/htdocs/core/db/DoliDB.class.php
+++ b/htdocs/core/db/DoliDB.class.php
@@ -70,6 +70,18 @@ abstract class DoliDB implements Database
/** @var string */
public $error;
+
+
+ /**
+ * Return the DB prefix
+ *
+ * @return string The DB prefix
+ */
+ public function prefix()
+ {
+ return (empty($this->prefix_db) ? MAIN_DB_PREFIX : $this->prefix_db);
+ }
+
/**
* Format a SQL IF
*
diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php
index 28a20ad6b09..ce8e02e9cee 100644
--- a/htdocs/core/lib/functions.lib.php
+++ b/htdocs/core/lib/functions.lib.php
@@ -641,7 +641,7 @@ function GETPOST($paramname, $check = 'alphanohtml', $method = 0, $filter = null
}
// Check rule
- if (preg_match('/^array/', $check)) { // If 'array' or 'array:restricthtml' or 'array:aZ09'
+ if (preg_match('/^array/', $check)) { // If 'array' or 'array:restricthtml' or 'array:aZ09' or 'array:intcomma'
if (!is_array($out) || empty($out)) {
$out = array();
} else {
@@ -1897,7 +1897,7 @@ function dol_banner_tab($object, $paramid, $morehtml = '', $shownav = 1, $fieldi
if ($object->element == 'product') {
$width = 80;
- $cssclass = 'photoref';
+ $cssclass = 'photowithmargin photoref';
$showimage = $object->is_photo_available($conf->product->multidir_output[$entity]);
$maxvisiblephotos = (isset($conf->global->PRODUCT_MAX_VISIBLE_PHOTO) ? $conf->global->PRODUCT_MAX_VISIBLE_PHOTO : 5);
if ($conf->browser->layout == 'phone') {
@@ -3658,7 +3658,7 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $
'paiment', 'paragraph', 'play', 'pdf', 'phone', 'phoning', 'phoning_mobile', 'phoning_fax', 'playdisabled', 'previous', 'poll', 'pos', 'printer', 'product', 'propal', 'puce',
'stock', 'resize', 'service', 'stats', 'trip',
'security', 'setup', 'share-alt', 'sign-out', 'split', 'stripe', 'stripe-s', 'switch_off', 'switch_on', 'switch_on_red', 'tools', 'unlink', 'uparrow', 'user', 'vcard', 'wrench',
- 'github', 'jabber', 'skype', 'twitter', 'facebook', 'linkedin', 'instagram', 'snapchat', 'youtube', 'google-plus-g', 'whatsapp',
+ 'github', 'google', 'jabber', 'skype', 'twitter', 'facebook', 'linkedin', 'instagram', 'snapchat', 'youtube', 'google-plus-g', 'whatsapp',
'chevron-left', 'chevron-right', 'chevron-down', 'chevron-top', 'commercial', 'companies',
'generic', 'home', 'hrm', 'members', 'products', 'invoicing',
'partnership', 'payment', 'payment_vat', 'pencil-ruler', 'preview', 'project', 'projectpub', 'projecttask', 'question', 'refresh', 'region',
@@ -3678,7 +3678,7 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $
if (in_array($pictowithouttext, array('card', 'bell', 'clock', 'establishment', 'generic', 'minus-square', 'object_generic', 'pdf', 'plus-square', 'timespent', 'note', 'off', 'on', 'object_bookmark', 'bookmark', 'vcard'))) {
$fa = 'far';
}
- if (in_array($pictowithouttext, array('black-tie', 'github', 'skype', 'twitter', 'facebook', 'linkedin', 'instagram', 'snapchat', 'stripe', 'stripe-s', 'youtube', 'google-plus-g', 'whatsapp'))) {
+ if (in_array($pictowithouttext, array('black-tie', 'github', 'google', 'skype', 'twitter', 'facebook', 'linkedin', 'instagram', 'snapchat', 'stripe', 'stripe-s', 'youtube', 'google-plus-g', 'whatsapp'))) {
$fa = 'fab';
}
diff --git a/htdocs/core/lib/geturl.lib.php b/htdocs/core/lib/geturl.lib.php
index be7e1ffa80b..50ae7c33561 100644
--- a/htdocs/core/lib/geturl.lib.php
+++ b/htdocs/core/lib/geturl.lib.php
@@ -214,11 +214,14 @@ function getURLContent($url, $postorget = 'GET', $param = '', $followlocation =
}
}
- // Common check (local and external)
- if (in_array($iptocheck, array('100.100.100.200'))) {
- $info['http_code'] = 400;
- $info['content'] = 'Error bad hostname IP (Used by Alibaba metadata). Must be an external URL.';
- break;
+ // Common check on ip (local and external)
+ $arrayofmetadataserver = array('100.100.100.200' => 'Alibaba', '192.0.0.192'=> 'Oracle', '192.80.8.124'=>'Packet');
+ foreach ($arrayofmetadataserver as $ipofmetadataserver => $nameofmetadataserver) {
+ if ($iptocheck == $ipofmetadataserver) {
+ $info['http_code'] = 400;
+ $info['content'] = 'Error bad hostname IP (Used by '.$nameofmetadataserver.' metadata server). This IP is forbidden.';
+ break 2; // exit the foreach and the do...
+ }
}
// Set CURLOPT_CONNECT_TO so curl will not try another resolution that may give a different result. Possible only on PHP v7+
diff --git a/htdocs/core/lib/oauth.lib.php b/htdocs/core/lib/oauth.lib.php
index 48356868143..ab1b5a217b8 100644
--- a/htdocs/core/lib/oauth.lib.php
+++ b/htdocs/core/lib/oauth.lib.php
@@ -25,13 +25,13 @@
// Supported OAUTH (a provider is supported when a file xxx_oauthcallback.php is available into htdocs/core/modules/oauth)
$supportedoauth2array = array(
- 'OAUTH_GOOGLE_NAME'=>'google',
+ 'OAUTH_GOOGLE_NAME'=>array('callbackfile' => 'google', 'picto' => 'google', 'urlforapp' => 'OAUTH_GOOGLE_DESC', 'name'=>'Google'),
);
-if ($conf->global->MAIN_FEATURES_LEVEL >= 2) {
- $supportedoauth2array['OAUTH_STRIPE_TEST_NAME'] = 'stripetest';
- $supportedoauth2array['OAUTH_STRIPE_LIVE_NAME'] = 'stripelive';
+if (!empty($conf->stripe->enabled)) {
+ $supportedoauth2array['OAUTH_STRIPE_TEST_NAME'] = array('callbackfile' => 'stripetest', 'picto' => 'stripe', 'urlforapp' => '', 'name'=>'StripeTest');
+ $supportedoauth2array['OAUTH_STRIPE_LIVE_NAME'] = array('callbackfile' => 'stripelive', 'picto' => 'stripe', 'urlforapp' => '', 'name'=>'StripeLive');
}
-$supportedoauth2array['OAUTH_GITHUB_NAME'] = 'github';
+$supportedoauth2array['OAUTH_GITHUB_NAME'] = array('callbackfile' => 'github', 'picto' => 'github', 'urlforapp' => 'OAUTH_GITHUB_DESC', 'name'=>'GitHub');
diff --git a/htdocs/core/modules/modPrinting.class.php b/htdocs/core/modules/modPrinting.class.php
index 4c104b30ecf..c9e99b3d933 100644
--- a/htdocs/core/modules/modPrinting.class.php
+++ b/htdocs/core/modules/modPrinting.class.php
@@ -34,7 +34,6 @@ include_once DOL_DOCUMENT_ROOT.'/core/modules/DolibarrModules.class.php';
*/
class modPrinting extends DolibarrModules
{
-
/**
* Constructor
*
diff --git a/htdocs/core/modules/oauth/google_oauthcallback.php b/htdocs/core/modules/oauth/google_oauthcallback.php
index 4f9fded878f..9fbc38ef156 100644
--- a/htdocs/core/modules/oauth/google_oauthcallback.php
+++ b/htdocs/core/modules/oauth/google_oauthcallback.php
@@ -16,6 +16,9 @@
* along with this program. If not, see .
*/
+// This page should make the process to login and get token as described here:
+// https://developers.google.com/identity/protocols/oauth2/openid-connect#server-flow
+
/**
* \file htdocs/core/modules/oauth/google_oauthcallback.php
* \ingroup oauth
@@ -70,9 +73,13 @@ $credentials = new Credentials(
$currentUri->getAbsoluteUri()
);
+$state = GETPOST('state');
+
$requestedpermissionsarray = array();
-if (GETPOST('state')) {
- $requestedpermissionsarray = explode(',', GETPOST('state')); // Example: 'userinfo_email,userinfo_profile,cloud_print'. 'state' parameter is standard to store a hash value and can be used to retrieve some parameters back
+if ($state) {
+ // 'state' parameter is standard to store a hash value and can be used to retrieve some parameters back
+ $statewithscopeonly = preg_replace('/\-.*$/', '', $state);
+ $requestedpermissionsarray = explode(',', $statewithscopeonly); // Example: 'userinfo_email,userinfo_profile,openid,email,profile,cloud_print'.
}
if ($action != 'delete' && empty($requestedpermissionsarray)) {
print 'Error, parameter state is not defined';
@@ -80,6 +87,8 @@ if ($action != 'delete' && empty($requestedpermissionsarray)) {
}
//var_dump($requestedpermissionsarray);exit;
+
+
// Instantiate the Api service using the credentials, http client and storage mechanism for the token
// $requestedpermissionsarray contains list of scopes.
// Conversion into URL is done by Reflection on constant with name SCOPE_scope_in_uppercase
@@ -89,7 +98,6 @@ $apiService = $serviceFactory->createService('Google', $credentials, $storage, $
// also note that a refresh token is sent only after a prompt
$apiService->setAccessType('offline');
-$apiService->setApprouvalPrompt('force');
$langs->load("oauth");
@@ -108,48 +116,86 @@ if ($action == 'delete') {
exit();
}
-if (!empty($_GET['code'])) { // We are coming from oauth provider page
+if (GETPOST('code')) { // We are coming from oauth provider page.
dol_syslog("We are coming from the oauth provider page");
- //llxHeader('',$langs->trans("OAuthSetup"));
- //$linkback=''.$langs->trans("BackToModuleList").'';
- //print load_fiche_titre($langs->trans("OAuthSetup"),$linkback,'title_setup');
+ // We must validate that the $state is the same than the one into $_SESSION['oauthstateanticsrf'], return error if not.
+ if (isset($_SESSION['oauthstateanticsrf']) && $state != $_SESSION['oauthstateanticsrf']) {
+ print 'Value for state = '.dol_escape_htmltag($state).' differs from value in $_SESSION["oauthstateanticsrf"]. Code is refused.';
+ unset($_SESSION['oauthstateanticsrf']);
+ } else {
+ // This was a callback request from service, get the token
+ try {
+ //var_dump($_GET['code']);
+ //var_dump($state);
+ //var_dump($apiService); // OAuth\OAuth2\Service\Google
- //print dol_get_fiche_head();
- // retrieve the CSRF state parameter
- $state = isset($_GET['state']) ? $_GET['state'] : null;
- //print '';
+ // This request the token
+ // Result is stored into object managed by class DoliStorage into includes/OAuth/Common/Storage/DoliStorage.php, so into table llx_oauth_token
+ $token = $apiService->requestAccessToken(GETPOST('code'), $state);
- // This was a callback request from service, get the token
- try {
- //var_dump($_GET['code']);
- //var_dump($state);
- //var_dump($apiService); // OAuth\OAuth2\Service\Google
+ // Note: The extraparams has the 'id_token' than contains a lot of information about the user.
+ $extraparams = $token->getExtraParams();
+ $jwt = explode('.', $extraparams['id_token']);
- $token = $apiService->requestAccessToken($_GET['code'], $state);
+ // Extract the middle part, base64 decode, then json_decode it
+ if (!empty($jwt[1])) {
+ $userinfo = json_decode(base64_decode($jwt[1]), true);
- setEventMessages($langs->trans('NewTokenStored'), null, 'mesgs'); // Stored into object managed by class DoliStorage so into table oauth_token
+ // TODO
+ // We should make the 5 steps of validation of id_token
+ // Verify that the ID token is properly signed by the issuer. Google-issued tokens are signed using one of the certificates found at the URI specified in the jwks_uri metadata value of the Discovery document.
+ // Verify that the value of the iss claim in the ID token is equal to https://accounts.google.com or accounts.google.com.
+ // Verify that the value of the aud claim in the ID token is equal to your app's client ID.
+ // Verify that the expiry time (exp claim) of the ID token has not passed.
+ // If you specified a hd parameter value in the request, verify that the ID token has a hd claim that matches an accepted G Suite hosted domain.
- $backtourl = $_SESSION["backtourlsavedbeforeoauthjump"];
- unset($_SESSION["backtourlsavedbeforeoauthjump"]);
+ /*
+ $useremailuniq = $userinfo['sub'];
+ $useremail = $userinfo['email'];
+ $useremailverified = $userinfo['email_verified'];
+ $username = $userinfo['name'];
+ $userfamilyname = $userinfo['family_name'];
+ $usergivenname = $userinfo['given_name'];
+ $hd = $userinfo['hd'];
+ */
+ }
- header('Location: '.$backtourl);
- exit();
- } catch (Exception $e) {
- print $e->getMessage();
+ setEventMessages($langs->trans('NewTokenStored'), null, 'mesgs');
+
+ $backtourl = $_SESSION["backtourlsavedbeforeoauthjump"];
+ unset($_SESSION["backtourlsavedbeforeoauthjump"]);
+
+ header('Location: '.$backtourl);
+ exit();
+ } catch (Exception $e) {
+ print $e->getMessage();
+ }
}
-} else // If entry on page with no parameter, we arrive here
-{
+} else {
+ // If we enter this page without 'code' parameter, we arrive here. this is the case when we want to get the redirect
+ // to the OAuth provider login page
$_SESSION["backtourlsavedbeforeoauthjump"] = $backtourl;
+ if (!preg_match('/^forlogin/', $state)) {
+ $apiService->setApprouvalPrompt('force');
+ }
+
// This may create record into oauth_state before the header redirect.
// Creation of record with state in this tables depend on the Provider used (see its constructor).
- if (GETPOST('state')) {
- $url = $apiService->getAuthorizationUri(array('state'=>GETPOST('state')));
+ if ($state) {
+ $url = $apiService->getAuthorizationUri(array('state' => $state));
} else {
$url = $apiService->getAuthorizationUri(); // Parameter state will be randomly generated
}
+ // Add more param
+ $url .= '&nonce='.bin2hex(random_bytes(64/8));
+ // TODO Add param hd and/or login_hint
+ if (!preg_match('/^forlogin/', $state)) {
+ //$url .= 'hd=xxx';
+ }
+
// we go on oauth provider authorization page
header('Location: '.$url);
exit();
@@ -160,6 +206,6 @@ if (!empty($_GET['code'])) { // We are coming from oauth provider page
* View
*/
-// No view at all, just actions
+// No view at all, just actions, so we never reach this line.
$db->close();
diff --git a/htdocs/core/tpl/admin_extrafields_add.tpl.php b/htdocs/core/tpl/admin_extrafields_add.tpl.php
index d9c0f650395..9b46fba6c67 100644
--- a/htdocs/core/tpl/admin_extrafields_add.tpl.php
+++ b/htdocs/core/tpl/admin_extrafields_add.tpl.php
@@ -185,7 +185,7 @@ $listofexamplesforlink = 'Societe:societe/class/societe.class.php Contact:con
textwithpicto($langs->trans("ComputedFormula"), $langs->trans("ComputedFormulaDesc")).$form->textwithpicto($langs->trans("Computedpersistent"), $langs->trans("ComputedpersistentDesc"), 1, 'warning'); ?> |
- |
+ |
diff --git a/htdocs/core/tpl/login.tpl.php b/htdocs/core/tpl/login.tpl.php
index 338d2bd1a19..d7e9bda13dd 100644
--- a/htdocs/core/tpl/login.tpl.php
+++ b/htdocs/core/tpl/login.tpl.php
@@ -33,6 +33,8 @@ if (empty($conf) || !is_object($conf)) {
require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
+
+
header('Cache-Control: Public, must-revalidate');
header("Content-type: text/html; charset=".$conf->file->character_set_client);
@@ -316,6 +318,32 @@ if (isset($conf->file->main_authentication) && preg_match('/openid/', $conf->fil
echo '';
}
+if (isset($conf->file->main_authentication) && preg_match('/google/', $conf->file->main_authentication)) {
+ $langs->load("users");
+
+ global $dolibarr_main_url_root;
+
+ // Define $urlwithroot
+ $urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root));
+ $urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file
+ //$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current
+
+ echo ' ';
+ echo '';
+
+ //$shortscope = 'userinfo_email,userinfo_profile';
+ $shortscope = 'openid,email,profile'; // For openid connect
+
+ $oauthstateanticsrf = bin2hex(random_bytes(128/8));
+ $_SESSION['oauthstateanticsrf'] = $shortscope.'-'.$oauthstateanticsrf;
+ $urltorenew = $urlwithroot.'/core/modules/oauth/google_oauthcallback.php?shortscope='.$shortscope.'&state=forlogin-'.$shortscope.'-'.$oauthstateanticsrf;
+
+ $url = $urltorenew;
+
+ print img_picto('', 'google', 'class="pictofixedwidth"').' '.$langs->trans("LoginWith", "Google").'';
+
+ echo ' ';
+}
?>
diff --git a/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php b/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php
index d441d364f4b..2ff5d3f9c43 100644
--- a/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php
+++ b/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php
@@ -66,7 +66,7 @@ class InterfaceActionsAuto extends DolibarrTriggers
* $object->elementtype (->element of object to link action to)
* $object->module (if defined, elementtype in llx_actioncomm will be elementtype@module)
*
- * @param string $action Event action code ('CONTRACT_MODIFY', 'RECRUITMENTCANDIDATURE_MODIFIY', ...)
+ * @param string $action Event action code ('CONTRACT_MODIFY', 'RECRUITMENTCANDIDATURE_MODIFIY', or example by external module: 'SENTBYSMS'...)
* @param Object $object Object
* @param User $user Object user
* @param Translate $langs Object langs
@@ -88,6 +88,7 @@ class InterfaceActionsAuto extends DolibarrTriggers
//var_dump($action.' - '.$conf->global->$key);exit;
// Do not log events not enabled for this action
+ // GUI allow to set this option only if entry exists into table llx_c_action_trigger
if (empty($conf->global->$key)) {
return 0;
}
@@ -887,8 +888,9 @@ class InterfaceActionsAuto extends DolibarrTriggers
} else {
// TODO Merge all previous cases into this generic one
// $action = BILL_DELETE, TICKET_CREATE, TICKET_MODIFY, TICKET_DELETE, CONTACT_SENTBYMAIL, RECRUITMENTCANDIDATURE_MODIFY, ...
+ // Can also be a value defined by an external module like SENTBYSMS, COMPANY_SENTBYSMS, MEMBER_SENTBYSMS, ...
// Note: We are here only if $conf->global->MAIN_AGENDA_ACTIONAUTO_action is on (tested at begining of this function).
- // Note that these key can be set in agenda setup, only if defined into c_action_trigger
+ // Note that these key can be set in agenda setup, only if defined into llx_c_action_trigger
// Load translation files required by the page
if (empty($object->actionmsg2)) {
$langs->loadLangs(array("agenda", "other"));
diff --git a/htdocs/eventorganization/conferenceorboothattendee_note.php b/htdocs/eventorganization/conferenceorboothattendee_note.php
index 19d413daaa0..b8fb87d39fa 100644
--- a/htdocs/eventorganization/conferenceorboothattendee_note.php
+++ b/htdocs/eventorganization/conferenceorboothattendee_note.php
@@ -39,7 +39,6 @@
//if (! defined("MAIN_LANG_DEFAULT")) define('MAIN_LANG_DEFAULT', 'auto'); // Force lang to a particular value
//if (! defined("MAIN_AUTHENTICATION_MODE")) define('MAIN_AUTHENTICATION_MODE', 'aloginmodule'); // Force authentication handler
//if (! defined("NOREDIRECTBYMAINTOLOGIN")) define('NOREDIRECTBYMAINTOLOGIN', 1); // The main.inc.php does not make a redirect if not logged, instead show simple error message
-//if (! defined("FORCECSP")) define('FORCECSP', 'none'); // Disable all Content Security Policies
//if (! defined('CSRFCHECK_WITH_TOKEN')) define('CSRFCHECK_WITH_TOKEN', '1'); // Force use of CSRF protection with tokens even for GET
//if (! defined('NOBROWSERNOTIF')) define('NOBROWSERNOTIF', '1'); // Disable browser notification
diff --git a/htdocs/externalsite/admin/index.php b/htdocs/externalsite/admin/index.php
index ba23b88e68e..0b55a297be9 100644
--- a/htdocs/externalsite/admin/index.php
+++ b/htdocs/externalsite/admin/index.php
@@ -57,7 +57,7 @@ if ($action == 'update') {
$label = GETPOST('EXTERNALSITE_LABEL', 'alphanohtml');
// exturl can be an url or a HTML string
- $exturl = GETPOST('EXTERNALSITE_URL', 'none');
+ $exturl = GETPOST('EXTERNALSITE_URL', 'restricthtml');
$exturl = dol_string_onlythesehtmltags($exturl, 1, 1, 0, 1);
$exturl = dol_string_onlythesehtmlattributes($exturl);
@@ -110,7 +110,7 @@ print '';
print '| '.$langs->trans("ExternalSiteURL")." | ";
print ' | |