diff --git a/README.txt b/README.txt index aaf2336..ff45060 100644 --- a/README.txt +++ b/README.txt @@ -37,8 +37,8 @@ https://www.drupal.org/project/issues/tfa_basic * tfa_basic_cookie_name Cookie name of TFA trusted browser cookie. Default is "TB". - * tfa_basic_cookie_domain - Cookie domain for TFA trusted browser cookie. + * tfa_basic_cookie_domains + Cookie domains for TFA trusted browser cookie. * tfa_basic_trust_cookie_expiration How long before TFA cookies expire. Default is 30 days. diff --git a/includes/tfa_trusted_browser.inc b/includes/tfa_trusted_browser.inc index d9d5e60..002debc 100644 --- a/includes/tfa_trusted_browser.inc +++ b/includes/tfa_trusted_browser.inc @@ -20,9 +20,9 @@ class TfaTrustedBrowser extends TfaBasePlugin implements TfaLoginPluginInterface protected $cookieName; /** - * @var string + * @var array */ - protected $domain; + protected $domains; /** * @var string @@ -31,8 +31,9 @@ class TfaTrustedBrowser extends TfaBasePlugin implements TfaLoginPluginInterface public function __construct(array $context) { parent::__construct($context); + global $cookie_domain; $this->cookieName = variable_get('tfa_basic_cookie_name', 'TB'); - $this->domain = variable_get('tfa_basic_cookie_domain', ''); + $this->domains = explode(',',variable_get('tfa_basic_cookie_domains', $cookie_domain)); // Expiration defaults to 30 days. $this->expiration = variable_get('tfa_basic_trust_cookie_expiration', 3600 * 24 * 30); } @@ -101,6 +102,19 @@ class TfaTrustedBrowser extends TfaBasePlugin implements TfaLoginPluginInterface * @param string $name */ protected function setTrusted($value, $name = '') { + if (!in_array($_SERVER['HTTP_HOST'], $this->domains)) { + watchdog( + 'TFA', + t( + 'Browser is not added as trusted browser because current domain is not set as !link', + ['!link' => l('trusted domain', 'admin/config/people/tfa')] + ), + [], + WATCHDOG_ALERT + ); + return; + } + // Store id for account. $record = array( 'uid' => $this->context['uid'], @@ -113,7 +127,7 @@ class TfaTrustedBrowser extends TfaBasePlugin implements TfaLoginPluginInterface // Issue cookie with ID. $cookie_secure = ini_get('session.cookie_secure'); $expiration = REQUEST_TIME + $this->expiration; - setcookie($this->cookieName, $value, $expiration, '/', $this->domain, (empty($cookie_secure) ? FALSE : TRUE), TRUE); + setcookie($this->cookieName, $value, $expiration, '/', $_SERVER['HTTP_HOST'], (empty($cookie_secure) ? FALSE : TRUE), TRUE); $name = empty($name) ? $this->getAgent() : $name; watchdog('tfa_basic', 'Set trusted browser for user UID !uid, browser @name', array('@name' => $name, '!uid' => $this->context['uid']), WATCHDOG_INFO); } diff --git a/tfa_basic.module b/tfa_basic.module index 3d3ba0f..db20284 100644 --- a/tfa_basic.module +++ b/tfa_basic.module @@ -545,17 +545,59 @@ function tfa_basic_form_tfa_admin_settings_alter(&$form, &$form_state, $form_id) ); // Add cookie domain field to TFA admin settings. - $form['tfa_basic_cookie_domain'] = array( - '#type' => 'textfield', - '#title' => t('Cookie domain'), - '#default_value' => variable_get('tfa_basic_cookie_domain', $cookie_domain), - '#description' => t('Domain to set for the trusted browser TFA cookie.'), - '#states' => array( - 'visible' => array( - ':input[name="tfa_login[tfa_basic_trusted_browser]"]' => array('checked' => TRUE) - ) - ), - ); + // Multiple domains are possible + $form['#tree'] = TRUE; + if (empty($form_state['amount_cookie_domains'])) { + $form_state['amount_cookie_domains'] = variable_get('tfa_basic_cookie_domain_amount',1); + } + + $form['cookie_domains'] = [ + '#type' => 'fieldset', + '#title' => t('Cookie domains'), + '#description' => t('Allowed domains to set for the trusted browser TFA cookie.'), + '#attributes' => ['id' => 'cookies-domains-wrapper'], + '#states' => [ + 'visible' => [ + ':input[name="tfa_login[tfa_basic_trusted_browser]"]' => ['checked' => TRUE], + ], + ], + ]; + + $cookie_domains = explode(',',variable_get('tfa_basic_cookie_domains',$cookie_domain)); + for ($i = 0; $i < $form_state['amount_cookie_domains']; $i++) { + $form['cookie_domains']['tfa_basic_cookie_domain'][$i] = [ + '#type' => 'textfield', + '#title' => t('Cookie domain'), + '#default_value' => $cookie_domains[$i], + ]; + } + + $form['cookie_domains']['add_cookie_domain'] = [ + '#type' => 'submit', + '#value' => t('Add cookie domain'), + '#submit' => [ + 'tfa_basic_add_cookie_domain', + ], + '#ajax' => [ + 'callback' => 'tfa_basic_cookie_domain_callback', + 'wrapper' => 'cookies-domains-wrapper', + ], + ]; + + if ($form_state['amount_cookie_domains'] > 1) { + $form['cookie_domains']['remove_cookie_domain'] = [ + '#type' => 'submit', + '#value' => t('Remove cookie domain'), + '#submit' => [ + 'tfa_basic_remove_cookie_domain', + ], + '#ajax' => [ + 'callback' => 'tfa_basic_cookie_domain_callback', + 'wrapper' => 'cookies-domains-wrapper', + ], + ]; + } + // Add Twilio configuration if Twilio PHP library is available. if (module_exists('libraries') && $library = libraries_load('twilio') && !empty($library['loaded'])) { $twilio_available = TRUE; @@ -664,6 +706,42 @@ function tfa_basic_form_tfa_admin_settings_alter(&$form, &$form_state, $form_id) $form['#submit'][] = 'tfa_basic_form_submit'; } +/** + * Add one more cookie domain option + * + * @param $form + * @param $form_state + */ +function tfa_basic_add_cookie_domain($form, &$form_state){ + $form_state['amount_cookie_domains']++; + $form_state['rebuild'] = TRUE; +} + +/** + * Remove cookie domain option + * + * @param $form + * @param $form_state + */ +function tfa_basic_remove_cookie_domain($form, &$form_state){ + if ($form_state['amount_cookie_domains'] > 1) { + $form_state['amount_cookie_domains']--; + } + $form_state['rebuild'] = TRUE; +} + +/** + * Cookie domain ajax callback + * + * @param $form + * @param $form_state + * + * @return mixed + */ +function tfa_basic_cookie_domain_callback($form, $form_state){ + return $form['cookie_domains']; +} + /** * Validation for TFA admin settings alter. */ @@ -677,7 +755,7 @@ function tfa_basic_form_validate($form, &$form_state) { } } - if (!empty($login) && in_array('tfa_basic_trusted_browser', $login) && empty($values['tfa_basic_cookie_domain'])) { + if (!empty($login) && in_array('tfa_basic_trusted_browser', $login) && empty($values['cookie_domains']['tfa_basic_cookie_domain'])) { form_set_error('tfa_basic_cookie_domain', t('Cookie domain is required if Trusted Browser plugin is enabled.')); } } @@ -708,8 +786,9 @@ function tfa_basic_form_validate($form, &$form_state) { * Submit for TFA admin settings alter. */ function tfa_basic_form_submit($form, &$form_state) { - if (!empty($form_state['values']['tfa_basic_cookie_domain'])) { - variable_set('tfa_basic_cookie_domain', $form_state['values']['tfa_basic_cookie_domain']); + if (!empty($form_state['values']['cookie_domains']['tfa_basic_cookie_domain'])) { + variable_set('tfa_basic_cookie_domains', implode(',',$form_state['values']['cookie_domains']['tfa_basic_cookie_domain'])); + variable_set('tfa_basic_cookie_domain_amount',count($form_state['values']['cookie_domains']['tfa_basic_cookie_domain'])); } if (!empty($form_state['values']['tfa_basic_twilio_account_sid'])) { variable_set('tfa_basic_twilio_account_sid', $form_state['values']['tfa_basic_twilio_account_sid']);