diff --git a/VERSIONS_DEV/169475 b/VERSIONS_DEV/169475
new file mode 100644
index 0000000000000000000000000000000000000000..803a9fbaeeba17392c114b54d7c7a8602fda2306
--- /dev/null
+++ b/VERSIONS_DEV/169475
@@ -0,0 +1 @@
+ - fonctionnalité #169475 : Administration : Une page peut maintenant servir d'écran de connexion.
\ No newline at end of file
diff --git a/application/modules/admin/controllers/ProfilController.php b/application/modules/admin/controllers/ProfilController.php
index ecf2f12c8f10645128083f3c8a17b562977f4a74..53f71672cf90367a6eb168e67774b691ee62372c 100644
--- a/application/modules/admin/controllers/ProfilController.php
+++ b/application/modules/admin/controllers/ProfilController.php
@@ -282,6 +282,7 @@ class Admin_ProfilController extends ZendAfi_Controller_Action {
 
     $profil->setLibelle($this->_getParam('libelle', $profil->getLibelle()));
     $profil->setRewriteUrl($this->_getParam('rewrite_url'));
+    $profil->setIntent($this->_getParam('intent'));
 
     if (Class_AdminVar::isIndexablePagesEnabled()) {
       $profil
@@ -395,6 +396,8 @@ class Admin_ProfilController extends ZendAfi_Controller_Action {
     if ( ! $this->_request->isPost() )
       return;
 
+    $this->_profil->setIntent($this->_getParam('intent', ''));
+
     if( ! $this->view->form->isValidModelAndArray($this->_profil,
                                                   $this->_request->getPost()))
       return;
diff --git a/application/modules/admin/views/scripts/profil/_page_row.phtml b/application/modules/admin/views/scripts/profil/_page_row.phtml
index ef943da35747fbdea8f650cb5ccd7445885e173f..de18cab85af5ff464b4058ef0d01bebe55106476 100644
--- a/application/modules/admin/views/scripts/profil/_page_row.phtml
+++ b/application/modules/admin/views/scripts/profil/_page_row.phtml
@@ -20,7 +20,11 @@ $url_delete_profil = $this->url(['module' => 'admin',
 
   <div>
     <a href="<?php echo $url_edit_profil ?>" title="Modifier la page">
-      <?php echo $this->libelle . $this->tag('sub', ' #' . $this->profil->getId(), ['style' => 'color: #999']); ?>
+      <?php
+      echo $this->libelle
+  . $this->tag('sub', ' #' . $this->profil->getId(), ['style' => 'color: #999; margin-right: 5px;'])
+. ($this->profil->hasIntent() ? $this->renderIcon('class fa fa-user-circle-o') : '');
+      ?>
     </a>
   </div>
 
diff --git a/application/modules/opac/controllers/AbonneController.php b/application/modules/opac/controllers/AbonneController.php
index bfc8a5bdf8de27d0c7ce1cae1b2350731e2eb7b6..e3355f28f21c59b340ce0cfdf74478dcdddc509e 100644
--- a/application/modules/opac/controllers/AbonneController.php
+++ b/application/modules/opac/controllers/AbonneController.php
@@ -33,7 +33,6 @@ class AbonneController extends ZendAfi_Controller_Action {
 
   public function init()  {
     parent::init();
-
     if ('authenticate' == $this->getRequest()->getActionName())
       return;
 
@@ -55,6 +54,9 @@ class AbonneController extends ZendAfi_Controller_Action {
   public function preDispatch() {
     parent::preDispatch();
 
+    if ( ! $this->_checkLogged(['authenticate']))
+      return $this->_forwardToLogin($this->view->url(), $this->_getReferer()?? $this->view->url(), false);
+
     if ($this->_isMultimediaHoldAction()
         && !Class_AdminVar::isMultimediaEnabled()) {
       $this->_helper->notify($this->_('AFI-Multimédia n\'est pas activé'));
diff --git a/application/modules/opac/controllers/AuthController.php b/application/modules/opac/controllers/AuthController.php
index 62f7a840e60a5131b8b0cbd3954a0b2c8e6b7694..7392c334e45d4afad94993b6b60944e322d25ea6 100644
--- a/application/modules/opac/controllers/AuthController.php
+++ b/application/modules/opac/controllers/AuthController.php
@@ -157,22 +157,18 @@ class AuthController extends ZendAfi_Controller_Action {
 
 
   public function loginAction() {
-
     $preferences = Class_Template::current()
       ->filterNotNamespaced($this->_loginPrefFromWidgetOrModule());
 
-    $redirect = $this->_processRedirect($this->_getParam('redirect',
-                                                         Class_Url::relative(['module' => 'opac',
-                                                                              'action' => 'index',
-                                                                              'controller' => 'index'])));
+    $redirect =
+      $this->_processRedirect($this->_redirectUrl());
 
     $strategy = Class_Auth_Strategy::newFor($this);
+
     $strategy->setDefaultUrl($redirect);
+
     $strategy
-      ->onLoginSuccess(function($user)
-                       {
-                         $user->registerNotificationsOn($this->getHelper('notify')->bePopup());
-                       });
+      ->onLoginSuccess($this->_onLoginSucessCallback($strategy));
 
     $service = $this->_getParam('service', '');
     $cas = $this->_getParam('cas');
@@ -203,9 +199,13 @@ class AuthController extends ZendAfi_Controller_Action {
 
 
   protected function _processRedirect($redirect_candidate = ""){
+    $default = Class_Url::relative(['module' => 'opac',
+                                    'action' => 'index',
+                                    'controller' => 'index']);
+
     $redirect_candidate = $redirect_candidate
       ? $redirect_candidate
-      : $this->_getParam('redirect','/opac');
+      : $this->_getParam('redirect', $default);
 
     if (Class_Url::isABokehUrl($redirect_candidate))
       return $redirect_candidate;
@@ -314,22 +314,39 @@ class AuthController extends ZendAfi_Controller_Action {
       ? $target->getUrl()
       : $referer;
 
+    if ($redirect = $this->_getParam('redirect_url', $this->_getParam('redirect')))
+      $url = $redirect;
+
+    if ( $redirect_url = Zend_Registry::get('session')->redirect_url){
+      Zend_Registry::get('session')->redirect_url = null;
+      $url = $redirect_url;
+    }
+
     $strategy = Class_Auth_Strategy::newFor($this);
     $strategy->setDefaultUrl($url);
+
     $on_fail = function() use($strategy, $referer) {
       $strategy->setRedirectUrl($referer);
     };
+
     if ($target)
       $strategy->onLoginFail($on_fail);
 
-    $on_success = function($user) {
-      $user->registerNotificationsOn($this->getHelper('notify')->bePopup());
-    };
-    $strategy->onLoginSuccess($on_success);
+    $strategy->onLoginSuccess($this->_onLoginSucessCallback($strategy));
     $strategy->processLogin();
   }
 
 
+  protected function _onLoginSucessCallback (Class_Auth_Strategy $strategy) :Closure {
+    return
+      function(Class_Users $user) use ($strategy) {
+        $user->registerNotificationsOn($this->getHelper('notify')->bePopup());
+        if ($popup_url = $this->_afterLoginUrl())
+          $strategy->setPopupRedirect($popup_url . '/render/popup');
+      };
+  }
+
+
   public function logoutAction()  {
     Class_Auth_Strategy::newFor($this)->logout();
   }
@@ -681,4 +698,18 @@ class AuthController extends ZendAfi_Controller_Action {
 
     $this->_redirectToUrlOrReferer($this->_getParam('redirect', '/opac/index/index'));
   }
+
+
+  protected function _redirectUrl() : string {
+    return ($redirect_url = Zend_Registry::get('session')->redirect_url)
+      ? $redirect_url
+      : (string) $this->_getParam('redirect_url', $this->_getParam('redirect'));
+  }
+
+
+  protected function _afterLoginUrl() : string {
+    return ($after_login_do = Zend_Registry::get('session')->after_login_do)
+      ? $after_login_do
+      : (string) $this->_getParam('after_login_do', '');
+  }
 }
diff --git a/application/modules/opac/controllers/BibNumeriqueController.php b/application/modules/opac/controllers/BibNumeriqueController.php
index 0178da8c1f15934e7b01df3afde4e792cc2abf45..c223490b2b87aa51ce578e32ceac750dc7eb5f4f 100644
--- a/application/modules/opac/controllers/BibNumeriqueController.php
+++ b/application/modules/opac/controllers/BibNumeriqueController.php
@@ -253,27 +253,12 @@ class BibNumeriqueController extends ZendAfi_Controller_Action {
   }
 
 
-  protected function _redirectToLogin() {
-    if ($this->_user)
-      return false;
-
-    $this->_forward('login', 'auth', 'opac', ['redirect' => $this->view->absoluteUrl()]);
-    return true;
-  }
-
-
-  protected function _redirectToPopupLogin($url) {
-    if ($this->_user)
-      return false;
-
-    $this->_forward('popup-login', 'auth', 'opac', ['redirect' => $url]);
-    return true;
-  }
-
-
   protected function _userShouldBeRedirect() {
-    if ($this->_redirectToPopupLogin($this->view->url()))
+    if (!$this->_user){
+      $this->getResponse()->setHeader('Location', $this->view->url());
+      $this->_forwardToLogin('', $this->view->url());
       return true;
+    }
 
     if (!$this->_user->hasRightAccessDilicom())
       return $this->_ajaxRedirectToNotice();
@@ -316,8 +301,8 @@ class BibNumeriqueController extends ZendAfi_Controller_Action {
 
 
   public function loanBookAction() {
-    if ($this->_redirectToLogin())
-      return;
+    if (!$this->_user)
+      return $this->_forwardToLogin('', $this->view->absoluteUrl());
 
     if (!$this->_user->hasRightAccessDilicom())
       return $this->_redirectToReferer();
@@ -411,7 +396,8 @@ class BibNumeriqueController extends ZendAfi_Controller_Action {
                           function($url)
                           {
                             $this->view->download_url = $url;
-                            $this->renderPopupResult($this->_('Téléchargement'), $this->view->render('bib-numerique/download-book.phtml'));
+                            $this->renderPopupResult($this->_('Téléchargement'),
+                                                     $this->view->render('bib-numerique/download-book.phtml'));
                           });
   }
 
@@ -454,8 +440,8 @@ class BibNumeriqueController extends ZendAfi_Controller_Action {
 
 
   public function consultBookAction() {
-    if ($this->_redirectToLogin())
-      return;
+    if (!$this->_user)
+      return $this->_forwardToLogin('', $this->view->url());
 
     if (!$this->_user->hasRightAccessDilicom())
       return $this->_redirectToReferer();
diff --git a/application/modules/opac/controllers/BookmarkedSearchesController.php b/application/modules/opac/controllers/BookmarkedSearchesController.php
index 500fb9fd1a812ea59c285416e7b5920864f4f9d6..f95ac7156f74c53bf4f1019e6240d659db48c708 100644
--- a/application/modules/opac/controllers/BookmarkedSearchesController.php
+++ b/application/modules/opac/controllers/BookmarkedSearchesController.php
@@ -22,6 +22,12 @@
 
 class BookmarkedSearchesController extends ZendAfi_Controller_Action {
 
+  public function preDispatch(){
+    parent::preDispatch();
+    if ( ! $this->_checkLogged([]))
+      return $this->_forwardToLogin($this->view->url(), '', false);
+  }
+
   public function getPlugins() : array {
     return [ZendAfi_Controller_Plugin_ResourceDefinition_BookmarkedSearches::class,
             ZendAfi_Controller_Plugin_Manager_BookmarkedSearches::class];
diff --git a/application/modules/opac/controllers/DriveCheckoutController.php b/application/modules/opac/controllers/DriveCheckoutController.php
index 3088d7be848511c26c5615387b2289fdf2d5c722..4bc046697773358eef400c894ba16e0eee2c6b19 100644
--- a/application/modules/opac/controllers/DriveCheckoutController.php
+++ b/application/modules/opac/controllers/DriveCheckoutController.php
@@ -29,10 +29,16 @@ class DriveCheckoutController extends ZendAfi_Controller_Action {
   }
 
 
-  public function planAction() {
+  public function preDispatch()  {
     if (!$this->_isActive())
       return;
 
+    if(!Class_Users::getIdentity())
+      return $this->_forwardToLogin($this->view->url(), '', false);
+  }
+
+
+  public function planAction() {
     $plan = new Class_DriveCheckout_Plan($this->_request->getParams(), $this->_user);
 
     if (!$plan->isValid()) {
@@ -63,9 +69,6 @@ class DriveCheckoutController extends ZendAfi_Controller_Action {
 
 
   public function deleteAction() {
-    if (!$this->_isActive())
-      return;
-
     $this->getHelper('ViewRenderer')->setNoRender();
     $message = $this->_('Impossible de supprimer un retrait inconnu.');
     if ($checkout = Class_DriveCheckout::findFor($this->_getParam('id'), $this->_user)) {
@@ -82,9 +85,6 @@ class DriveCheckoutController extends ZendAfi_Controller_Action {
 
 
   public function icalAction() {
-    if (!$this->_isActive())
-      return;
-
     if (!$checkout = Class_DriveCheckout::findFor($this->_getParam('id'), $this->_user)) {
       $this->getHelper('ViewRenderer')->setNoRender();
       $this->_helper->notify($this->_('Impossible d\'importer un retrait inconnu.'));
diff --git a/application/modules/opac/controllers/IndexController.php b/application/modules/opac/controllers/IndexController.php
index 9584617c3d44f772a50524e9e86fd4386898049f..98f6955861ca639e8a9496b0c1bef2b6752cd84b 100644
--- a/application/modules/opac/controllers/IndexController.php
+++ b/application/modules/opac/controllers/IndexController.php
@@ -38,6 +38,13 @@ class IndexController extends ZendAfi_Controller_Action {
                                             ['profil' => Class_Profil::getCurrentProfil()]);
       };
 
+
+    if ($redirect = $this->_getParam('redirect_url'))
+      Zend_Registry::get('session')->redirect_url = $redirect;
+
+    if ($after_login_do = $this->_getParam('after_login_do'))
+      Zend_Registry::get('session')->after_login_do = $after_login_do;
+
     if(array_keys($this->getRequest()->getParams()) == ['controller', 'action', 'module', 'current_module', 'q']) {
       $this->_redirect('recherche?'.http_build_query(['q' => $this->_getParam('q')]));
     }
diff --git a/application/modules/opac/controllers/NoticeajaxController.php b/application/modules/opac/controllers/NoticeajaxController.php
index 4104fa7ba88f09ba61d8fd791e8a20b599736799..816a84ad3b97adaa67b664fb1dc41b310d58c104 100644
--- a/application/modules/opac/controllers/NoticeajaxController.php
+++ b/application/modules/opac/controllers/NoticeajaxController.php
@@ -364,17 +364,16 @@ class NoticeAjaxController extends ZendAfi_Controller_Action {
 
   public function addAvisAction() {
     if (!$user = Class_Users::getIdentity())
-      return $this->_forward('login', 'auth', 'opac', ['redirect' => $this->_request->REQUEST_URI]);
+      return $this->_forwardToLogin($this->view->url(),'',false);
 
     $this->_forward('avis', 'abonne', 'opac');
   }
 
 
   public function addTagAction() {
-    if (!$user = Class_Users::getIdentity()) {
-      $this->_forward('popup-login', 'auth', 'opac', ['redirect' => $this->view->url()]);
-      return;
-    }
+    if (!$user = Class_Users::getIdentity())
+      return $this->_forwardToLogin($this->view->url());
+
 
     $this->_forward('tagnotice', 'abonne', 'opac');
   }
diff --git a/application/modules/opac/controllers/PanierController.php b/application/modules/opac/controllers/PanierController.php
index ee3db0c5a8f9cc83ba4452336a68e8b82b86819b..5119137c6a369e0cea04a1ef75347c2ce855c70b 100644
--- a/application/modules/opac/controllers/PanierController.php
+++ b/application/modules/opac/controllers/PanierController.php
@@ -24,13 +24,12 @@ class PanierController extends ZendAfi_Controller_Action {
 
   public function preDispatch()  {
     parent::preDispatch();
-    $this->_user = Class_Users::getIdentity();
+
+    if (!$this->_user = Class_Users::getIdentity())
+      return $this->_forwardToLogin($this->view->url(),'',('add-record-ajax' == $this->_getParam('action')));
 
     if('add-record-ajax' == $this->_getParam('action'))
       return;
-
-    if (!$this->_user)
-      $this->_forward('login', 'auth', 'opac', ['redirect' => $this->_request->REQUEST_URI]);
   }
 
 
@@ -210,9 +209,6 @@ class PanierController extends ZendAfi_Controller_Action {
   public function addSelectionAction() {
     $this->view->titre = $this->_('Mettre la sélection dans un panier');
 
-    if(!$this->_user)
-      return $this->_forward('popup-login', 'auth', 'opac', ['redirect' => $this->view->url()]);
-
     $this->view->panier = $panier = $this->_user->getPanierCourant();
 
     if (!$this->_request->isPost())
@@ -234,9 +230,6 @@ class PanierController extends ZendAfi_Controller_Action {
   public function addRecordAjaxAction() {
     $this->view->titre = $popup_title = $this->_('Ajouter un document dans un panier');
 
-    if(!$this->_user)
-      return $this->_forward('popup-login', 'auth', 'opac', ['redirect' => $this->view->url()]);
-
     if(!$this->view->notice = $notice = Class_Notice::find($this->_getParam('id_notice')))
       return $this->renderPopupResult($popup_title,
                                       $this->_('Veuillez choisir une notice'));
diff --git a/application/modules/opac/controllers/RechercheController.php b/application/modules/opac/controllers/RechercheController.php
index 92120cdb78b79b98a2b0566aad1daab4cf58b0d9..9a4342e66ffb8d40bbcbe72c16f948a626c62547 100644
--- a/application/modules/opac/controllers/RechercheController.php
+++ b/application/modules/opac/controllers/RechercheController.php
@@ -389,6 +389,9 @@ class RechercheController extends ZendAfi_Controller_Action {
 
 
   public function reservationAction() {
+    if (!$this->userConnected())
+      return;
+
     if ((!$library = Class_Bib::find((int)$this->_getParam('id_bib')))
         || !$record = Class_Notice::find((int)$this->_getParam('id_notice'))) {
       $this->_redirectToIndex();
@@ -681,7 +684,7 @@ class RechercheController extends ZendAfi_Controller_Action {
 
   protected function userConnected() {
     if (!$user = Class_Users::getIdentity()) {
-      $this->_forward('popup-login', 'auth', 'opac', ['redirect' => $this->view->url()]);
+      $this->_forwardToLogin($this->view->url(), '');
       return false;
     }
     return $user;
@@ -850,6 +853,9 @@ class RechercheController extends ZendAfi_Controller_Action {
 
 
   public function reserverAction() {
+    if (!$this->userConnected())
+      return;
+
     $this->view->titre = $this->_('Réserver un document');
 
     if ( ! $record = Class_Notice::find($this->_getParam('record_id', 0)))
diff --git a/application/modules/opac/controllers/RecordController.php b/application/modules/opac/controllers/RecordController.php
index ccb19decf7855cd34b1dd4106ed8c8b25e293be6..f3352fae4908300bd882145915a5f84529abb9d1 100644
--- a/application/modules/opac/controllers/RecordController.php
+++ b/application/modules/opac/controllers/RecordController.php
@@ -24,7 +24,6 @@ class RecordController extends ZendAfi_Controller_Action {
 
   public function preDispatch() {
     parent::preDispatch();
-
     if (!$this->view->record = Class_Notice::find($this->_getParam('id'))) {
       $this->_helper->notify($this->_('Impossible d\'afficher les données. Le document est introuvable'));
       $this->_redirectToIndex();
diff --git a/application/modules/opac/views/scripts/auth/newsletter-register.phtml b/application/modules/opac/views/scripts/auth/newsletter-register.phtml
index 42f2cdf89bafde9d49fecb42403918de93c1bd14..5b5423e2077d897d375711644839df5cd6c9bae0 100644
--- a/application/modules/opac/views/scripts/auth/newsletter-register.phtml
+++ b/application/modules/opac/views/scripts/auth/newsletter-register.phtml
@@ -3,9 +3,6 @@ $this->openBoite($this->titre);
 echo $this->form;
 echo $this->error ? $this->renderError($this->error) : '';
 echo $this->tag('br','');
-echo $this->tagAnchor($this->url(['controller' => 'auth',
-                                  'action' => 'ajax-login']),
-                      $this->_('J\'ai déjà un compte.'),
-                      ['data-popup' => 'true']);
+echo $this->getConnectionUrl($this->_('J\'ai déjà un compte.'));
 echo $this->closeBoite();
 ?>
diff --git a/cosmogramme/sql/patch/patch_450.php b/cosmogramme/sql/patch/patch_450.php
new file mode 100644
index 0000000000000000000000000000000000000000..b56ab0b4214bc53f4b9ee2141026259a892dce04
--- /dev/null
+++ b/cosmogramme/sql/patch/patch_450.php
@@ -0,0 +1,10 @@
+<?php
+$adapter = Zend_Db_Table_Abstract::getDefaultAdapter();
+
+try {
+  $adapter->query(
+                  'ALTER TABLE `bib_admin_profil` '
+                  . 'ADD COLUMN `intent` varchar(255) default "",'
+                  . 'ADD KEY `intent` (`intent`)'
+  );
+} catch(Exception $e) {}
diff --git a/library/Class/AdminVar/GoogleTagManager.php b/library/Class/AdminVar/GoogleTagManager.php
index 5d0314bc825d33663bae9ba1a148cbbdea6db4d1..62a2eaebd75829dab1a3c78c90a98cb8ad198d4a 100644
--- a/library/Class/AdminVar/GoogleTagManager.php
+++ b/library/Class/AdminVar/GoogleTagManager.php
@@ -27,7 +27,7 @@ class Class_AdminVar_GoogleTagManager {
 
 
   public function getGoogleTagId() {
-    return trim(Class_AdminVar::get('GOOGLE_TAG_MANAGER_ID'));
+    return trim((string) Class_AdminVar::get('GOOGLE_TAG_MANAGER_ID'));
   }
 
 
@@ -50,4 +50,4 @@ class Class_AdminVar_GoogleTagManager {
       return '';
     return $this->manageCookies()->gTagsFrame($this->getGoogleTagId());
   }
-}
\ No newline at end of file
+}
diff --git a/library/Class/Auth/IdentityProvider.php b/library/Class/Auth/IdentityProvider.php
index 713cc2c36c4ee5d1687296e1189e457484e8615d..acc0ff33b4a731fe2d4e75fd7bcbf448c3957848 100644
--- a/library/Class/Auth/IdentityProvider.php
+++ b/library/Class/Auth/IdentityProvider.php
@@ -59,7 +59,7 @@ class Class_Auth_IdentityProviderLogged extends Class_Auth_Logged {
         && ($message = $provider->getLastMessage()))
       $this->controller->notify($message);
 
-    $this->redirect_url = ($url = $provider->loginSuccessRedirectUrl())
+   $this->redirect_url = ($url = $provider->loginSuccessRedirectUrl())
         ? $url
         : $this->default_url;
 
@@ -162,6 +162,7 @@ class Class_Auth_IdentityProviderNotLogged extends Class_Auth_NotLogged {
 
 
   protected function _redirectToProviderSuccessOrDefaultUrl($provider) {
+    $this->_doOnLoginSuccess();
     return $this->setRedirectUrl(($url = $provider->loginSuccessRedirectUrl())
                                  ? $url
                                  : $this->default_url);
diff --git a/library/Class/Auth/Strategy.php b/library/Class/Auth/Strategy.php
index 7b7612c3cde8baa5054b037974fa809b65c4a035..33e65629d614dfef278ed848f70b701262ff4996 100644
--- a/library/Class/Auth/Strategy.php
+++ b/library/Class/Auth/Strategy.php
@@ -31,6 +31,7 @@ abstract class Class_Auth_Strategy {
     $disable_redirect = false,
     $on_login_success_callback,
     $on_login_fail_callback,
+    $_popup_redirect,
     $_cas_ticket = null;
 
   /**
@@ -111,12 +112,18 @@ abstract class Class_Auth_Strategy {
   }
 
 
-  public function setRedirectUrl($url) {
+  public function setRedirectUrl(string $url) :self {
     $this->redirect_url = $url;
     return $this;
   }
 
 
+  public function setPopupRedirect(string $url) :self {
+    $this->_popup_redirect = $url;
+    return $this;
+  }
+
+
   public function getMessage($view) {
     return '';
   }
@@ -170,6 +177,9 @@ abstract class Class_Auth_Strategy {
 
 
   protected function _handleRedirect() {
+    if ($this->_popup_redirect)
+      $this->controller->renderPopup($this->_popup_redirect, $this->redirect_url);
+
     if ($this->shouldRedirect())
       $this->controller->redirect($this->redirect_url);
 
diff --git a/library/Class/DigitalResource/AlbumViewHelper.php b/library/Class/DigitalResource/AlbumViewHelper.php
index 673a4d8ec2a371ef186e022f29a43eaa3e5e0e90..87f1c7ede059377d8746539dcaf0623365e7da5c 100644
--- a/library/Class/DigitalResource/AlbumViewHelper.php
+++ b/library/Class/DigitalResource/AlbumViewHelper.php
@@ -23,6 +23,8 @@
 class Class_DigitalResource_AlbumViewHelper extends ZendAfi_View_Helper_BaseHelper {
   protected $_config;
 
+  use Trait_AuthenticationProfile, Trait_Translator;
+
   public function __construct($config) {
     parent::__construct();
     $this->_config = $config;
@@ -37,7 +39,7 @@ class Class_DigitalResource_AlbumViewHelper extends ZendAfi_View_Helper_BaseHelp
 
 
   protected function _getViewLink(Class_Album $album) : string{
-    if (Class_Users::getIdentity() && ! $this->hasRightAccesRessourcesNumeriques(Class_Users::getIdentity()))
+    if (($user = Class_Users::getIdentity()) && ! $this->hasRightAccesRessourcesNumeriques($user))
       return $this->view->tag('p', $this->_getTextInvalidSubscription());
 
     return $this->view->tagAnchor($this->_getAlbumSsoUrl($album),
diff --git a/library/Class/DigitalResource/Controller.php b/library/Class/DigitalResource/Controller.php
index ae3749841427742bc5100130f7f630149c4268ab..1d3779c64ccc157e2342a34a809f05dfa6dc9924 100644
--- a/library/Class/DigitalResource/Controller.php
+++ b/library/Class/DigitalResource/Controller.php
@@ -19,6 +19,7 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
  */
 class Class_DigitalResource_Controller extends ZendAfi_Controller_Action {
+
   protected $_config;
 
 
@@ -81,6 +82,11 @@ class Class_DigitalResource_Controller extends ZendAfi_Controller_Action {
     if($message)
       $this->_helper->notify($message);
 
+    if ($this->_withAuthenticateProfileDo('',
+                                          $url,
+                                          fn($authenticate_url) => $this->_redirect($authenticate_url) ?? true))
+      return;
+
     $login_url = Class_Url::absolute(['module' => 'opac',
                                       'controller' => 'auth',
                                       'action' => 'login'],
diff --git a/library/Class/FileManager.php b/library/Class/FileManager.php
index 5ebd92e6d360f1a81e886d2e34b74ff971591a0b..bf2efd52bc5245f403ba37eea09979fa1f54f709 100644
--- a/library/Class/FileManager.php
+++ b/library/Class/FileManager.php
@@ -589,7 +589,7 @@ class Class_FileManager extends Class_Entity {
 
 
   public function getRelativeUrl() : string {
-    return Class_Url::relative($this->getPath(), null, true);
+    return Class_Url::relative($this->getPath());
   }
 
 
@@ -633,4 +633,4 @@ class Class_FileManager extends Class_Entity {
   public function readfile() {
     return static::getFileSystem()->readfile($this->getRealpath());
   }
-}
\ No newline at end of file
+}
diff --git a/library/Class/IdentityProvider.php b/library/Class/IdentityProvider.php
index 1cca3a614052f52f1768cdd21c4b336273cd7473..6f355e17c67706a76d957806cfc4a38938a4c97e 100644
--- a/library/Class/IdentityProvider.php
+++ b/library/Class/IdentityProvider.php
@@ -299,6 +299,9 @@ class Class_IdentityProvider extends Storm_Model_Abstract{
         && Class_Users::getIdentity()->isInvite())
       return $this->_getPreregistrationUrl();
 
+    if (Zend_Registry::get('session')->redirect_url)
+      return Zend_Registry::get('session')->redirect_url;
+
     if ($profil = Class_Profil::find($this->getProfilRedirect()))
       return $profil->getUrl();
 
diff --git a/library/Class/Profil.php b/library/Class/Profil.php
index 2f9a0c6ba69d09078f38fdf7f8cf5dc7fdf3195c..54a6a22832efcff2248c867ee06c58895900e1c8 100644
--- a/library/Class/Profil.php
+++ b/library/Class/Profil.php
@@ -180,6 +180,7 @@ class Class_Profil extends Storm_Model_Abstract {
   const DIV_BANNIERE = 4;
   const DIV_FLOTANTTE = 5;
   const DIV_FOOTER = 6;
+  const INTENT_AUTHENTICATION = 'authentication';
   const MOBILE_CSS = 'mobile';
   const SHOW_ITEM_ANNEX = 1;
   const SHOW_ITEM_LIBRARY = 1;
@@ -411,6 +412,7 @@ class Class_Profil extends Storm_Model_Abstract {
          'header_social_network' => false,
          'division_three_always_visible' => false,
          'rewrite_url' => '',
+         'intent' => '',
          'responsive' => false,
          'template' => '',
          'indexable' => 0,
@@ -450,6 +452,7 @@ class Class_Profil extends Storm_Model_Abstract {
                                  'indexable',
                                  'commentaire',
                                  'ref_tags',
+                                 'intent',
                                  'id_notice'];
     self::$FORWARDED_ATTRIBUTES = array_diff($all_attributes,
                                              $not_forwarded_attributes);
@@ -1547,7 +1550,10 @@ class Class_Profil extends Storm_Model_Abstract {
     $validator = new ZendAfi_Validate_ProfilRewriteUrl();
     $validator->isValid($this);
 
-    foreach($validator->getMessages() as $message)
+    $intent_validator = new ZendAfi_Validate_ProfileIntent;
+    $intent_validator->isValid($this);
+
+    foreach($intent_validator->getMessages() + $validator->getMessages() as $message)
       $this->check(false, $message);
 
     return $this;
@@ -2584,4 +2590,32 @@ class Class_Profil extends Storm_Model_Abstract {
     $this->_attributes['commentaire'] = '';
     return $this;
   }
+
+
+  public function getAuthenticate() : ? Class_Profil {
+    $profiles = $this->getLoader()->findAllBy(['intent' => 'authentication']);
+
+    $profiles = array_filter($profiles, fn($profile) => $this->_isMyAuthenticate($profile));
+
+    return ($profile = reset($profiles))
+      ? $profile
+      : null;
+  }
+
+
+  protected function _isMyAuthenticate(Class_Profil $profil) : bool {
+    if ( $profil->getId() == $this->getId())
+      return true;
+
+    if ($profil->getParentId() == $this->getParentId())
+      return true;
+
+    if ($profil->getParentId() == $this->getId())
+      return true;
+
+    if ($profil->getId() == $this->getParentId())
+      return true;
+
+    return false;
+  }
 }
diff --git a/library/Class/RemoteClient.php b/library/Class/RemoteClient.php
index baeb6e851a562088ee6222b433139fc201383270..3275126497b44bd18b822c271c486b9d8baf441d 100644
--- a/library/Class/RemoteClient.php
+++ b/library/Class/RemoteClient.php
@@ -30,15 +30,14 @@ class Class_RemoteClient {
   public function getIpAddress() {
     $keys = ['HTTP_X_FORWARDED_FOR', 'HTTP_CLIENT_IP', 'REMOTE_ADDR'];
     foreach($keys as $key)
-      if ($ip = $this->_extractIp($this->_request->getServer($key)))
+      if ($ip = $this->_extractIp((string) $this->_request->getServer($key)))
         return $ip;
   }
 
-  protected function _extractIp($str) {
-    if (!$ips = array_filter(explode(',', $str)))
-      return null;
-    return trim($ips[0]);
+
+  protected function _extractIp(string $str) : string {
+    return ($ips = array_filter(explode(',', $str)))
+      ? trim($ips[0])
+      : '';
   }
 }
-
-?>
\ No newline at end of file
diff --git a/library/Class/Systeme/ModulesMenu/SSOAbstract.php b/library/Class/Systeme/ModulesMenu/SSOAbstract.php
index d05d145a39509421e57161f17644c7084f0e3550..0d4524bfbcdd84f787694cd9545c74ce2db2ee4e 100644
--- a/library/Class/Systeme/ModulesMenu/SSOAbstract.php
+++ b/library/Class/Systeme/ModulesMenu/SSOAbstract.php
@@ -20,6 +20,10 @@
  */
 
 class Class_Systeme_ModulesMenu_SSOAbstract extends Class_Systeme_ModulesMenu_Null {
+
+  use Trait_AuthenticationProfile;
+
+
   protected $_login_redirect_url = null;
 
 
@@ -36,6 +40,8 @@ class Class_Systeme_ModulesMenu_SSOAbstract extends Class_Systeme_ModulesMenu_Nu
 
   public function loginUrl() {
     $this->setMessage($this->_('Vous devez vous connecter avec un abonnement valide pour profiter de la ressource.'));
+    if ( $url = $this->_authenticateProfileUrl('', $this->_login_redirect_url))
+      return $url;
 
     return Class_Url::absolute(['module' => 'opac',
                                 'controller' => 'auth',
@@ -59,4 +65,4 @@ class Class_Systeme_ModulesMenu_SSOAbstract extends Class_Systeme_ModulesMenu_Nu
   public function urlForUser($user) {
     return '';
   }
-}
\ No newline at end of file
+}
diff --git a/library/Class/TableDescription/AdminVar.php b/library/Class/TableDescription/AdminVar.php
index 9fcad5b14e9e0a23f71196baa76ac90a74417c57..74225bf22392e9e3a91895b4551fbf61e2e52b78 100644
--- a/library/Class/TableDescription/AdminVar.php
+++ b/library/Class/TableDescription/AdminVar.php
@@ -32,7 +32,7 @@ class Class_TableDescription_AdminVar extends Class_TableDescription {
                                         'action' => 'adminvaredit',
                                         'cle' => $model->getClef()],
                               'icon' => 'edit',
-                              'anchorOptions' => ['data-popup' => true],
+                              'anchorOptions' => ['data-popup' => 'true'],
                               'label' => $this->_('Modifier "%s"', $model->getClef())]]));
 
     $this
diff --git a/library/Trait/AuthenticationProfile.php b/library/Trait/AuthenticationProfile.php
new file mode 100644
index 0000000000000000000000000000000000000000..87c85fa33cb8fe33fd0f9c3d630cf627196a9a90
--- /dev/null
+++ b/library/Trait/AuthenticationProfile.php
@@ -0,0 +1,94 @@
+<?php
+/**
+ * Copyright (c) 2012-2015, Agence Française Informatique (AFI). All rights reserved.
+ *
+ * BOKEH is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by
+ * the Free Software Foundation.
+ *
+ * There are special exceptions to the terms and conditions of the AGPL as it
+ * is applied to this software (see README file).
+ *
+ * BOKEH 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 AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * along with BOKEH; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
+ */
+
+
+trait Trait_AuthenticationProfile {
+  protected string $_after_login_do ='';
+  protected string $_redirect_url ='';
+  protected ?Class_Profil $_profile = null;
+
+
+  public function setAuthenticateParams(string $redirect_url ='', string $after_login_do ='') :void {
+    $this->_redirect_url = $redirect_url;
+    $this->_after_login_do = $after_login_do;
+  }
+
+  public function _authenticateProfile() : ?Class_Profil {
+    if ( $this->_profile)
+      return $this->_profile;
+
+    if (Class_Users::getIdentity())
+      return null;
+
+    if ( ! $profile = Class_Profil::getCurrentProfil())
+      return null;
+
+    return $this->_profile = $profile->getAuthenticate();
+  }
+
+
+  protected function _authenticateProfileUrl(string $after_login_do = '', string $redirect_url = '') : string {
+    if ( ! $profile = $this->_authenticateProfile())
+      return '';
+
+    $params=['module' => 'opac',
+             'controller' => 'index',
+             'action' => 'index',
+             'id_profil' => $profile->getId()
+    ];
+
+    if ($redirect_url || $redirect_url = $this->_getReferer())
+      $params['redirect_url'] = $redirect_url;
+
+    if ($after_login_do)
+      $params['after_login_do'] = $after_login_do;
+
+    return Class_Url::relative($params,
+                               null,
+                               true);
+  }
+
+
+  protected function _withAuthenticateProfileDo(string $after_login_do,
+                                                string $redirect_url,
+                                                Closure $callback) {
+    return ($url = $this->_authenticateProfileUrl($after_login_do, $redirect_url))
+      ? $callback($url)
+      : null;
+  }
+
+
+  public function _getReferer() :string {
+    return (isset($_SERVER['HTTP_REFERER']))
+      ? $_SERVER['HTTP_REFERER']
+    : $this->view->url();
+  }
+
+
+  public function getRedirectUrl() :?string {
+    return $this->_redirect_url;
+  }
+
+
+  public function getAfterLoginDo() :?string {
+    return $this->_after_login_do;
+  }
+}
diff --git a/library/ZendAfi/Controller/Action.php b/library/ZendAfi/Controller/Action.php
index 86ff6206201ac2697ad9036b288afba69205924a..e2b8631457940dcbc7e8f06250a6f8e4b2d09263 100644
--- a/library/ZendAfi/Controller/Action.php
+++ b/library/ZendAfi/Controller/Action.php
@@ -20,7 +20,7 @@
  */
 
 class ZendAfi_Controller_Action extends Zend_Controller_Action {
-  use Trait_Translator, Trait_InspectorGadget;
+  use Trait_Translator, Trait_InspectorGadget, Trait_AuthenticationProfile;
 
   protected
     $_definitions,
@@ -145,6 +145,7 @@ class ZendAfi_Controller_Action extends Zend_Controller_Action {
 
   public function preDispatch() {
     parent::preDispatch();
+
     $this->view->plugins = $this->_getActionPlugins();
 
     if ($this->isPopupRequest())
@@ -192,6 +193,36 @@ class ZendAfi_Controller_Action extends Zend_Controller_Action {
   }
 
 
+  protected function _forwardToLogin(string $after_login_do, string $redirect_url='', bool $popup = true){
+    if ($authenticate_url = $this->_authenticateProfileUrl($after_login_do, $redirect_url))
+      return $this->_redirect($authenticate_url);
+
+    $action = ($popup ||$this->isPopupRequest())
+      ? 'popup-login'
+      : 'login';
+
+    $redirect = $this->_getRedirectFrom($after_login_do, $redirect_url);
+
+    return $this->_forward($action
+                           , 'auth'
+                           , 'opac'
+                           , ['redirect' => $redirect]);
+  }
+
+
+  protected function _getRedirectFrom(string $after_login_do, string $redirect_url = ''): string {
+    if ($redirect_url && $after_login_do
+        && ($redirect_url != $after_login_do)
+        && ($redirect_url != '/'))
+      return $after_login_do . '?redirect_url='. urlencode($redirect_url);
+
+    if ($after_login_do)
+      return $after_login_do;
+
+    return $redirect_url;
+  }
+
+
   protected function _javascriptRedirectToReferrer($message = null) {
     $this->_popupJavascriptRedirectTo('', $message);
   }
@@ -475,4 +506,11 @@ class ZendAfi_Controller_Action extends Zend_Controller_Action {
 
     return $this;
   }
+
+
+  protected function _checkLogged(array $actions) :bool{
+    if (in_array($this->getRequest()->getActionName(), $actions))
+      return true;
+    return (null !== Class_Users::getIdentity());
+  }
 }
diff --git a/library/ZendAfi/Controller/Action/Helper/FlashMessenger.php b/library/ZendAfi/Controller/Action/Helper/FlashMessenger.php
index 795018a1c4be29c5149e074db362bcebff42cbd2..72fc42180462ede969ea3adbde39eea77f868043 100644
--- a/library/ZendAfi/Controller/Action/Helper/FlashMessenger.php
+++ b/library/ZendAfi/Controller/Action/Helper/FlashMessenger.php
@@ -42,6 +42,12 @@ class ZendAfi_Controller_Action_Helper_FlashMessenger extends Zend_Controller_Ac
   }
 
 
+  public function addPopup(string $url) : self {
+    $this->addMessage([static::POPUP => ['url' => $url . '/render/popup']]);
+    return $this;
+  }
+
+
   public function isNotification($message) {
     return $this->isType($message, static::NOTIFICATION);
   }
diff --git a/library/ZendAfi/Controller/Action/Helper/View.php b/library/ZendAfi/Controller/Action/Helper/View.php
index 7fe2a0b0701f978a59c282f7188f913df4168888..9324269ca238cf87e42e25ee85e2324af1296641 100644
--- a/library/ZendAfi/Controller/Action/Helper/View.php
+++ b/library/ZendAfi/Controller/Action/Helper/View.php
@@ -20,7 +20,7 @@
  */
 
 class ZendAfi_Controller_Action_Helper_View extends Zend_View {
-  use Trait_Translator;
+  use Trait_Translator, Trait_AuthenticationProfile;
 
   protected static $instance;
 
@@ -266,17 +266,34 @@ class ZendAfi_Controller_Action_Helper_View extends Zend_View {
   }
 
 
-  public function bePopup() {
+  public function bePopup() :self {
     $this->_is_popup = true;
     return $this;
   }
 
 
+  public function bePage() :self {
+    $this->_is_popup = false;
+    return $this;
+  }
+
+
   public function isPopup() {
     return $this->_is_popup;
   }
 
 
+  public function getConnectionUrl(string $label) : string {
+    if ($url = $this->_authenticateProfileUrl($this->url(), $_SERVER['HTTP_REFERER'] ?? ''))
+      return $this->tagAnchor($url, $label);
+
+    return $this->tagAnchor($this->url(['controller' => 'auth',
+                                        'action' => 'ajax-login']),
+                            $label,
+                            ['data-popup' => 'true']);
+  }
+
+
   /**
    * create and return view helper without using Zend_View_Abstract local cache
    */
diff --git a/library/ZendAfi/Controller/Action/Helper/ViewRenderer.php b/library/ZendAfi/Controller/Action/Helper/ViewRenderer.php
index 465c6187b7ef519a5e9feebbd132879c16fcbd7f..7c5bd8c7dce680cb470fa8783d4ec37cdc30a9ea 100644
--- a/library/ZendAfi/Controller/Action/Helper/ViewRenderer.php
+++ b/library/ZendAfi/Controller/Action/Helper/ViewRenderer.php
@@ -111,7 +111,7 @@ class ZendAfi_Controller_Action_Helper_ViewRenderer extends Zend_Controller_Acti
   }
 
 
-  public function beRenderPopup() {
+  public function beRenderPopup() :self {
     $this->_render_popup = true;
     $this->view->bePopup();
     $this->setLayoutScript('popup.phtml');
@@ -124,6 +124,14 @@ class ZendAfi_Controller_Action_Helper_ViewRenderer extends Zend_Controller_Acti
   }
 
 
+  public function beRenderPage() :self {
+    $this->_render_popup = false;
+    $this->_render_ajax = false;
+    $this->view->bePage();
+    return $this;
+  }
+
+
   public function beRenderIframe() {
     $this->setLayoutScript('iframe.phtml');
 
@@ -149,6 +157,13 @@ class ZendAfi_Controller_Action_Helper_ViewRenderer extends Zend_Controller_Acti
   public function renderScript($script, $name = null) {
     $this->view->actionScript = $script;
     $layoutScript = $this->getLayoutScript();
+    if ($this->view->_authenticateProfile()
+        && (($redirect_url = $this->_actionController->getRequest()->getParam('redirect_url',''))
+            || ($after_login_do = $this->_actionController->getRequest()->getParam('after_login_do','')))){
+      $this->view->setAuthenticateParams($redirect_url,
+                                         $after_login_do
+                                         ?? $this->_actionController->getRequest()->getParam('after_login_do',''));
+    }
     $layoutContent = $this->view->render($layoutScript);
     $this->getResponse()->appendBody($layoutContent, $this->getResponseSegment());
     $this->setNoRender();
diff --git a/library/ZendAfi/Controller/Plugin/AdminAuth.php b/library/ZendAfi/Controller/Plugin/AdminAuth.php
index adbec4d2b1685d6db26b28210475211ac29f71bd..ae2b374408ce750e36495890d49a806c0e3486ed 100644
--- a/library/ZendAfi/Controller/Plugin/AdminAuth.php
+++ b/library/ZendAfi/Controller/Plugin/AdminAuth.php
@@ -63,33 +63,13 @@ class ZendAfi_Controller_Plugin_AdminAuth extends Zend_Controller_Plugin_Abstrac
       $action = 'sitedown';
     }
 
-    if ((!$user = Class_Users::getIdentity())
-        && $action !== "authenticate"
-        && in_array($controller, ["abonne", 'bookmarked-searches', 'drive-checkout'])) {
-      $request->setParam('redirect', $this->_getRedirect($request, $action));
-      $controller = 'auth';
-      $action = ($request->getParam('render') == 'popup') ? 'popup-login' : 'login';
-    }
 
-    // Parametres du controller
     $request->setModuleName($module);
     $request->setControllerName($controller);
     $request->setActionName($action);
   }
 
 
-  protected function _getRedirect($request, $action) {
-    $redirect = Class_Url::absolute();
-    if ($action != 'inscrire-session')
-      return $redirect;
-
-    if (! $referer = $request->getServer('HTTP_REFERER'))
-      return $redirect;
-
-    return $redirect.'?redirect_url='.urlencode($referer);
-  }
-
-
   protected function _handleAdmin($request) {
     Zend_Controller_Front::getInstance()
       ->getPlugin(Zend_Controller_Plugin_ErrorHandler::class)
diff --git a/library/ZendAfi/Controller/Plugin/Manager/AbonneSessionActivity.php b/library/ZendAfi/Controller/Plugin/Manager/AbonneSessionActivity.php
index 8349451f35a943c389e4fee0a15df20a03fc4ffc..4e33fe54b1a837bbe6801462babfec30d30a0f77 100644
--- a/library/ZendAfi/Controller/Plugin/Manager/AbonneSessionActivity.php
+++ b/library/ZendAfi/Controller/Plugin/Manager/AbonneSessionActivity.php
@@ -24,6 +24,12 @@
 class ZendAfi_Controller_Plugin_Manager_AbonneSessionActivity
   extends ZendAfi_Controller_Plugin_Manager_SessionActivityInscriptionBasic {
 
+  public function predDispatch(){
+    parent:preDispatch();
+    if ( ! $this->_checkLogged(['authenticate']))
+      return $this->_forwardToLogin($this->view->url(), $this->_getReferer()?? $this->view->url());
+  }
+
   public function init() {
     parent::init();
     $this->_validators[] = '_sessionInscriptionNotClosed';
diff --git a/library/ZendAfi/Controller/Plugin/Popup.php b/library/ZendAfi/Controller/Plugin/Popup.php
index 69c1bcf67d6adc8f8a3b234b3d887fa421ef07cd..615fcdfa843a1bbe7769d3a4a3abb2285f607115 100644
--- a/library/ZendAfi/Controller/Plugin/Popup.php
+++ b/library/ZendAfi/Controller/Plugin/Popup.php
@@ -16,17 +16,14 @@
  *
  * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
  * along with BOKEH; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA 
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
  */
 
 class ZendAfi_Controller_Plugin_Popup extends Zend_Controller_Plugin_Abstract {
   function preDispatch(Zend_Controller_Request_Abstract $request) {
     $messenger = new ZendAfi_Controller_Action_Helper_FlashMessenger();
     $popups = $messenger->getPopups();
-    foreach($popups as $popup) {
+    foreach($popups as $popup)
       Class_ScriptLoader::getInstance()->addJQueryReady('opacDialogFromUrl("'.$popup['popup']['url'].'");');
-    }
   }
 }
-
-?>
\ No newline at end of file
diff --git a/library/ZendAfi/Validate/ProfileIntent.php b/library/ZendAfi/Validate/ProfileIntent.php
new file mode 100644
index 0000000000000000000000000000000000000000..fc6a52085e39f824eb3be9c53a221c27d5e93795
--- /dev/null
+++ b/library/ZendAfi/Validate/ProfileIntent.php
@@ -0,0 +1,72 @@
+<?php
+/**
+ * Copyright (c) 2012-2022, Agence Française Informatique (AFI). All rights reserved.
+ *
+ * BOKEH is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by
+ * the Free Software Foundation.
+ *
+ * There are special exceptions to the terms and conditions of the AGPL as it
+ * is applied to this software (see README file).
+ *
+ * BOKEH 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 AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * along with BOKEH; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
+ */
+
+
+class ZendAfi_Validate_ProfileIntent extends Zend_Validate_Abstract {
+
+  use Trait_Translator;
+
+  const
+    INTENT_ALREADY_SET = 'intentSet';
+
+  protected $_messageTemplates = [];
+
+
+  public function isValid($profile) {
+    if( ! $profile instanceof Class_Profil) {
+      $intent = $profile;
+      $profile = Class_Profil::getCurrentProfil()->setIntent($intent);
+    }
+
+    if ( ! $intent = $profile->getIntent())
+      return true;
+
+    $this->_setValue($intent);
+
+    return $this->_checkProfilesWithSameIntent($profile);
+  }
+
+
+  protected function _checkProfilesWithSameIntent(Class_Profil $profile) : bool {
+    $parent = $profile->getParentProfil();
+
+    if ( $parent && Class_Profil::INTENT_AUTHENTICATION == $parent->getIntent())
+      return $this->_fail($parent);
+
+    if ($other = Class_Profil::findFirstBy(['intent' => $this->_value,
+                                            'parent_id' => $parent ? $parent->getId() : $profile->getId()]))
+      return ($other->getId() == $profile->getId()) || $this->_fail($other);
+
+    return true;
+  }
+
+
+  protected function _fail(Class_Profil $profile) : bool {
+    $this->_messageTemplates =
+      [static::INTENT_ALREADY_SET =>
+       $this->_('La page %s (id %s) a déjà défini la page d\'authentification',
+                $profile->getLibelle(),
+                $profile->getId())];
+
+    $this->_error(static::INTENT_ALREADY_SET);
+    return false;
+  }
+}
diff --git a/library/ZendAfi/View/Helper/Admin/RenderTestMyOpac.php b/library/ZendAfi/View/Helper/Admin/RenderTestMyOpac.php
index 3b579881635b31e0fd7e1b69d734595fc83f57d5..e763b186b8ff3a167d2355794ca6b459c8773c84 100644
--- a/library/ZendAfi/View/Helper/Admin/RenderTestMyOpac.php
+++ b/library/ZendAfi/View/Helper/Admin/RenderTestMyOpac.php
@@ -211,7 +211,7 @@ class ZendAfi_View_Helper_Admin_RenderTestMyOpac extends ZendAfi_View_Helper_Bas
 
   protected function _renderUrl($instance) {
     $url = is_array($instance->getUrl())
-      ? Class_Url::relative($instance->getUrl(), null, true)
+      ? Class_Url::relative($instance->getUrl())
       : $instance->getUrl();
 
     $url_prod = str_replace('http:', 'https:', Class_Url::absolute($instance->getUrl(), null, true));
diff --git a/library/ZendAfi/View/Helper/Avis.php b/library/ZendAfi/View/Helper/Avis.php
index 67cc5ddcfc506388dd0dd154a757a0dc1d122aa4..44bf6aab83d2b14bbc99164ab82c839f22205cbb 100644
--- a/library/ZendAfi/View/Helper/Avis.php
+++ b/library/ZendAfi/View/Helper/Avis.php
@@ -274,7 +274,9 @@ class ZendAfi_View_Helper_Avis extends ZendAfi_View_Helper_BaseHelper {
                                                              'active_tab' => $this->_active_tab,
                                                              'page' => $this->_page]),
                                      $this->view->boutonIco('type=' .$action),
-                                     ['data-popup' => 'true']);
+                                     ['data-popup' => $this->_shouldConnectWithProfil()
+                                      ? 'false'
+                                      : 'true']);
       $html_actions .= $this->_tag('span', $link, ['rel' => $action]);
     }
 
diff --git a/library/ZendAfi/View/Helper/BaseHelper.php b/library/ZendAfi/View/Helper/BaseHelper.php
index 66998522554a5f2e1db07f057af21c0992dc4b72..e92e4027d72be9240a20b5a75b813c5f9238df78 100644
--- a/library/ZendAfi/View/Helper/BaseHelper.php
+++ b/library/ZendAfi/View/Helper/BaseHelper.php
@@ -108,6 +108,15 @@ class ZendAfi_View_Helper_BaseHelper extends Zend_View_Helper_HtmlElement {
   }
 
 
+  protected function _shouldConnectWithProfil() : ?Class_Profil {
+    if (Class_Users::getIdentity())
+      return null;
+    return ($profil = Class_Profil::getCurrentProfil()->getAuthenticate())
+      ? $profil
+      : null;
+  }
+
+
   protected function _templateIco(string $key, string $category = '', array $attribs = []) : string {
     return $this->view->templateIco($key, $category, $attribs);
   }
diff --git a/library/ZendAfi/View/Helper/Notice/ExemplairesTable.php b/library/ZendAfi/View/Helper/Notice/ExemplairesTable.php
index cf8ba58958253fae64ed4b3cf03a09af4e76cac4..b52ae29e4ea57233b6df1fa5c790777d6695f7ca 100644
--- a/library/ZendAfi/View/Helper/Notice/ExemplairesTable.php
+++ b/library/ZendAfi/View/Helper/Notice/ExemplairesTable.php
@@ -340,7 +340,7 @@ class ZendAfi_View_Helper_Notice_Exemplaires_Plan extends ZendAfi_View_Helper_No
                                                     'action' => 'mapview',
                                                     'id_bib' => $exemplaire->getIdBib()], null, true),
                                   $this->_getPicto(),
-                                  ['data-popup' => true]);
+                                  ['data-popup' => 'true']);
   }
 
 
diff --git a/library/ZendAfi/View/Helper/Notice/ReservationLink.php b/library/ZendAfi/View/Helper/Notice/ReservationLink.php
index 679bde35e4f6127553c0da2a25ce929b8f2ebfac..2eb82a6659428fce09950908b046bcb7ad5f9df7 100644
--- a/library/ZendAfi/View/Helper/Notice/ReservationLink.php
+++ b/library/ZendAfi/View/Helper/Notice/ReservationLink.php
@@ -42,7 +42,9 @@ class ZendAfi_View_Helper_Notice_ReservationLink extends ZendAfi_View_Helper_Bas
 
     $attributes = ['href' => $url];
     if ($ex->hasSIGBComm())
-      $attributes['data-popup'] = 'true';
+      $attributes['data-popup'] = Class_Profil::getCurrentProfil()->getAuthenticate()
+        ? 'false'
+        : 'true';
 
     return $this->_renderCellWith($this->_tag('a',
                                               $this->_getHoldImage(),
@@ -72,4 +74,4 @@ class ZendAfi_View_Helper_Notice_ReservationLink extends ZendAfi_View_Helper_Bas
   }
 }
 
-?>
\ No newline at end of file
+?>
diff --git a/library/ZendAfi/View/Helper/Panier/Edit.php b/library/ZendAfi/View/Helper/Panier/Edit.php
index 0cddf9e06c119a2cd6c4c69e13db444b873d8dea..3887bc1171790cd7a086c91b214830225498caa2 100644
--- a/library/ZendAfi/View/Helper/Panier/Edit.php
+++ b/library/ZendAfi/View/Helper/Panier/Edit.php
@@ -61,7 +61,9 @@ class ZendAfi_View_Helper_Panier_Edit extends ZendAfi_View_Helper_BaseHelper {
                                    'controller' => 'panier',
                                    'action' => 'edit'],
                                   $this->view->_('Modifier le panier %s', $this->_panier_courant->getLibelle()),
-                                  ['data-popup' => 'true']);
+                                  ['data-popup' => $this->_shouldConnectWithProfil()
+                                   ? 'false'
+                                   : 'true']);
 
     $domaine_select = '';
     if(Class_Users::getIdentity()->canAccessBackend())
@@ -99,4 +101,4 @@ class ZendAfi_View_Helper_Panier_Edit extends ZendAfi_View_Helper_BaseHelper {
                                   ['onclick' => "$(this).prev().toggle();return false;",
                                    'title' => $this->view->_('Modifier le panier')]);
   }
-}
\ No newline at end of file
+}
diff --git a/library/ZendAfi/View/Helper/Paniers.php b/library/ZendAfi/View/Helper/Paniers.php
index 51279904a70887888db840e8c8f410baa7b20e73..c35cf9d1aebe43efbc7c2f8eb6cce97f6e1c6056 100644
--- a/library/ZendAfi/View/Helper/Paniers.php
+++ b/library/ZendAfi/View/Helper/Paniers.php
@@ -69,4 +69,4 @@ class ZendAfi_View_Helper_Paniers extends ZendAfi_View_Helper_BaseHelper {
 
     return implode($html);
   }
-}
\ No newline at end of file
+}
diff --git a/library/ZendAfi/View/Helper/RenderRecord.php b/library/ZendAfi/View/Helper/RenderRecord.php
index 4e5476e1abb5883b14fad5f99ffd9239a67be92c..b47a09fdd0c0795b35d65690cd9751e9a6a06f91 100644
--- a/library/ZendAfi/View/Helper/RenderRecord.php
+++ b/library/ZendAfi/View/Helper/RenderRecord.php
@@ -182,4 +182,4 @@ class ZendAfi_View_Helper_RenderRecord extends ZendAfi_View_Helper_BaseHelper {
                                    implode($html)),
                        ['class' => 'view_notice type_doc_' . $this->notice->getTypeDoc()]);
   }
-}
\ No newline at end of file
+}
diff --git a/library/ZendAfi/View/Helper/TagDilicomWidget.php b/library/ZendAfi/View/Helper/TagDilicomWidget.php
index 2e03e75590417ba4c34ca7f6a0c5808c4c780692..fcb794ac84bddadf1f1444323954cd9b828d7865 100644
--- a/library/ZendAfi/View/Helper/TagDilicomWidget.php
+++ b/library/ZendAfi/View/Helper/TagDilicomWidget.php
@@ -78,7 +78,9 @@ class ZendAfi_View_Helper_TagDilicomWidget extends ZendAfi_View_Helper_BaseHelpe
                            'action' => $this->_getConsultBookAction(),
                            'id' => $this->_album->getId()],
                           $this->_('Consulter le livre en ligne (depuis la médiathèque)'),
-                          ['data-popup' => 'true',
+                          ['data-popup' => $this->_shouldConnectWithProfil()
+                           ? 'false'
+                           : 'true',
                            'data-disabled' => 1]);
   }
 
@@ -127,7 +129,9 @@ class ZendAfi_View_Helper_TagDilicomWidget extends ZendAfi_View_Helper_BaseHelpe
                                       'action' => $this->_getLoanBookAction(),
                                       'id' => $this->_album->getId()],
                                      $this->_('Emprunter le livre au format EPUB'),
-                                     ['data-popup' => 'true',
+                                     ['data-popup' => $this->_shouldConnectWithProfil()
+                                      ? 'false'
+                                      : 'true',
                                       'data-disabled' => true]);
 
     if (!$this->_user)
@@ -162,4 +166,4 @@ class ZendAfi_View_Helper_TagDilicomWidget extends ZendAfi_View_Helper_BaseHelpe
                                               $attribs),
                        ['class' => 'dilicom-action']);
   }
-}
\ No newline at end of file
+}
diff --git a/library/ZendAfi/View/Helper/TagSelectRecord.php b/library/ZendAfi/View/Helper/TagSelectRecord.php
index 290f90d1cdabbff672c23ea664234a51e820ebf3..7337ef67550b7aaebf832f05b837b31d36d0fedf 100644
--- a/library/ZendAfi/View/Helper/TagSelectRecord.php
+++ b/library/ZendAfi/View/Helper/TagSelectRecord.php
@@ -21,6 +21,8 @@
 
 
 class ZendAfi_View_Helper_TagSelectRecord extends ZendAfi_View_Helper_BaseHelper {
+  use Trait_AuthenticationProfile;
+
   public function tagSelectRecord($record) {
     $url = Class_url::relative(['module' => 'opac',
                                 'controller' => 'records',
@@ -129,14 +131,13 @@ class ZendAfi_View_Helper_TagSelectRecord extends ZendAfi_View_Helper_BaseHelper
 
 
   protected function _addSelectionToCartLink() {
-    $url_add = Class_Url::relative(['controller' => 'panier',
-                                    'action' => 'add-selection']);
-
-
     return $this->_tag('a',
                        $this->_('Mettre dans un panier'),
-                       ['href' => $url_add,
-                        'data-popup' => 'true',
+                       ['href' => Class_Url::relative(['controller' => 'panier',
+                                                       'action' => 'add-selection']),
+                        'data-popup' => $this->_authenticateProfile()
+                        ? 'false'
+                        : 'true',
                         'title' => $this->_('Ajouter toutes les notices de la sélection à un panier')
                        ]);
   }
diff --git a/library/digital_resources/ArteVod/tests/ArteVodHelperTest.php b/library/digital_resources/ArteVod/tests/ArteVodHelperTest.php
index b76f86119aa6b70ba56fdd7d3cf83cd97fded61c..f20b9a43ad8d11d003f4572f416edebb584a9d55 100644
--- a/library/digital_resources/ArteVod/tests/ArteVodHelperTest.php
+++ b/library/digital_resources/ArteVod/tests/ArteVodHelperTest.php
@@ -21,7 +21,7 @@
 
 
 
-class ArteVodHelperTest extends ViewHelperTestCase {
+abstract class ArteVodHelperTestCase extends ViewHelperTestCase {
   public function setUp() {
     parent::setUp();
 
@@ -31,25 +31,13 @@ class ArteVodHelperTest extends ViewHelperTestCase {
     $this->group_multimedia = $this->fixture(Class_UserGroup::class,
                                              ['id' => 20,
                                               'libelle' => 'Multimedia']);
-    $this->fixture('Class_Permission',
+    $this->_connection();
+
+    $this->fixture(Class_Permission::class,
                    ['id' => 1,
                     'code' => 'ArteVod'])
          ->permitTo($this->group_multimedia,  new Class_Entity());
 
-    $this->_james_bond = Class_Users::newInstanceWithId(45)
-      ->setIdabon(45)
-      ->setPrenom('James')
-      ->setNom('Bond')
-      ->setMail('jbond@007.fr')
-      ->setUserGroups([]);
-
-    $user = $this->fixture('Class_Users',
-                           ['id' => 5,
-                            'login' => 'super_admin',
-                            'password' => 'super',
-                            'role_level' => ZendAfi_Acl_AdminControllerRoles::SUPER_ADMIN]);
-
-    ZendAfi_Auth::getInstance()->logUser($this->_james_bond);
     $this->_album = Class_Album::newInstanceWithId(102)
       ->setTitre('Mulholland drive')
       ->setTypeDocId('ArteVod')
@@ -74,6 +62,33 @@ class ArteVodHelperTest extends ViewHelperTestCase {
     $this->_helper->setView($view);
   }
 
+  protected function _connection(){
+  }
+}
+
+
+
+class ArteVodHelperTest extends ArteVodHelperTestCase {
+  protected $_james_bond;
+
+  protected function _connection(){
+    $this->_james_bond = Class_Users::newInstanceWithId(45)
+      ->setIdabon(45)
+      ->setPrenom('James')
+      ->setNom('Bond')
+      ->setMail('jbond@007.fr')
+      ->setUserGroups([]);
+
+    $user = $this->fixture(Class_Users::class,
+                           ['id' => 5,
+                            'login' => 'super_admin',
+                            'password' => 'super',
+                            'role_level' => ZendAfi_Acl_AdminControllerRoles::SUPER_ADMIN]);
+
+    ZendAfi_Auth::getInstance()->logUser($this->_james_bond);
+  }
+
+
   /** @test */
   public function withCurrentUserAbonneSigbShouldDisplayLinkFullPlay() {
     $this->_james_bond
@@ -159,3 +174,19 @@ class ArteVodHelperTest extends ViewHelperTestCase {
                                       '//a', 'Visionner le film');
   }
 }
+
+
+
+
+class ArteVodHelperWithoutUserTest extends ArteVodHelperTestCase {
+  protected function _connection(){
+    ZendAfi_Auth::getInstance()->clearIdentity();
+  }
+
+  /** @test */
+  public function linkToConnectionShouldBeDisplayed() {
+    $this->assertXPathContentContains($this->_helper->album($this->_album),
+                                      '//a[contains(@href,"/modules/arte-vod/album_id/102")]',
+                                      Class_CharSet::fromISOtoUTF8('Visionner le film dans son intégralité'));
+  }
+}
diff --git a/library/templates/Chili/Library/Wrapper/Record.php b/library/templates/Chili/Library/Wrapper/Record.php
index 5583ca30669e5db68d1df83950933ee7a9f6f30c..2e62e637293588df06df941d00576f2999b9d75d 100644
--- a/library/templates/Chili/Library/Wrapper/Record.php
+++ b/library/templates/Chili/Library/Wrapper/Record.php
@@ -58,7 +58,7 @@ class Chili_Library_Wrapper_Record extends Intonation_Library_View_Wrapper_Recor
   }
 
 
-  protected function _addHoldLink($actions) {
+  protected function _addHoldLink(array $actions) :array{
     $actions [] = (new Intonation_Library_Record($this->_model))
       ->getFirstItemHoldLink($this->_view);
 
diff --git a/library/templates/Chili/View/RenderRecord/RenderItems.php b/library/templates/Chili/View/RenderRecord/RenderItems.php
index 6b577d758f9e9c6d7acfeb245e7a87f8c0472c8e..c13d8552c9a06d4f11edbda88a994298a45bee17 100644
--- a/library/templates/Chili/View/RenderRecord/RenderItems.php
+++ b/library/templates/Chili/View/RenderRecord/RenderItems.php
@@ -21,6 +21,7 @@
 
 
 class Chili_View_RenderRecord_RenderItems extends Intonation_View_RenderRecord_RenderItems {
+  use Trait_AuthenticationProfile;
   protected function _hookForMoreHtml($items) {
     if ( ! $first_item = $this->_getFirstHoldableItem($items))
       return $this->_noHoldableItem();
@@ -28,20 +29,25 @@ class Chili_View_RenderRecord_RenderItems extends Intonation_View_RenderRecord_R
     if ( ! $record = $first_item->getNotice())
       return $this->_noHoldableItem();
 
-    $hold = (new Intonation_Library_Link)
-      ->setUrl($first_item->getHoldLink())
-      ->setText($this->_('Réserver'))
-      ->setImage(Class_Template::current()->getIco($this->view, 'hold', 'library'))
-      ->setTitle($this->_('Réserver le document %s',
-                          $record->getTitreEtSousTitre(' ')))
-      ->setPopup(true);
+    $link = $this->_holdLink($record, $first_item);
 
     return $this->view->div(['class' => 'items_hold_link'],
-                            $this->view->tagAction($hold));
+                            $this->view->tagAction($link));
 
   }
 
 
+  protected function _holdLink(Class_Notice $record, Class_Exemplaire $first_item): Intonation_Library_Link {
+      return (new Intonation_Library_Link)
+        ->setUrl($first_item->getHoldLink())
+        ->setText($this->_('Réserver'))
+        ->setImage(Class_Template::current()->getIco($this->view, 'hold', 'library'))
+        ->setTitle($this->_('Réserver le document %s',
+                            $record->getTitreEtSousTitre(' ')))
+        ->setPopup(true);
+    }
+
+
   protected function _noHoldableItem() {
     return $this->view->div(['class' => 'items_hold_link no_holdable_item'],
                             $this->_('Réservation impossible, pas d\'exemplaire réservable'));
diff --git a/library/templates/Intonation/Library/FormCustomizer/ProfilePage.php b/library/templates/Intonation/Library/FormCustomizer/ProfilePage.php
index 8b5ad42ca177f027e7ceb65b0563e9dd39d25e32..2428efa2b434e9ca2ad16e05e38ce2241b6a56a2 100644
--- a/library/templates/Intonation/Library/FormCustomizer/ProfilePage.php
+++ b/library/templates/Intonation/Library/FormCustomizer/ProfilePage.php
@@ -23,9 +23,16 @@
 class Intonation_Library_FormCustomizer_ProfilePage extends Intonation_Library_FormCustomizer_Abstract {
 
   public function getForm() {
+    $this->_form->addElement('select',
+                             'intent',
+                             ['label' => $this->_('Action de la page'),
+                              'validators' => [new ZendAfi_Validate_ProfileIntent],
+                              'multioptions' => ['' => '',
+                                                 Class_Profil::INTENT_AUTHENTICATION => $this->_('page d\'authentification')]]);
+    $this->_form->addToHeadGroup(['intent']);
     $display_settings_group = $this->_form->getDisplayGroup('display_group');
     $display_settings_group->clearElements();
     $this->_form->removeDisplayGroup('display_group');
     return $this->_form;
   }
-}
\ No newline at end of file
+}
diff --git a/library/templates/Intonation/Library/FormCustomizer/UserSettings.php b/library/templates/Intonation/Library/FormCustomizer/UserSettings.php
index d9b24ebe33e4aae1413dd34066e0028ecf0d77c8..5a34690e9808981202c74206e6ae7754539f9ecb 100644
--- a/library/templates/Intonation/Library/FormCustomizer/UserSettings.php
+++ b/library/templates/Intonation/Library/FormCustomizer/UserSettings.php
@@ -77,7 +77,7 @@ class Intonation_Library_FormCustomizer_UserSettings extends Intonation_Library_
                    'user_image_selector',
                    ['value' => ['controller' => 'abonne',
                                 'action' => 'change-image'],
-                    'data-popup' => 1,
+                    'data-popup' => "true",
                     'label' => $this->_('Changer l\'image de profil')])
 
       ->addDisplayGroup(['user_image_selector'],
diff --git a/library/templates/Intonation/Library/Link.php b/library/templates/Intonation/Library/Link.php
index 197d99c4010e3a1c2d64a52fd0acc3ee3b2c9db8..6883dee39c6b83e13b27b34c4baa1f3063dbb36a 100644
--- a/library/templates/Intonation/Library/Link.php
+++ b/library/templates/Intonation/Library/Link.php
@@ -101,7 +101,7 @@ class Intonation_Library_Link extends Class_Button {
 
 
   public function getScreenReaderText() {
-    return strip_tags($this->_screen_reader_text);
+    return strip_tags((string) $this->_screen_reader_text);
   }
 
 }
diff --git a/library/templates/Intonation/Library/Record.php b/library/templates/Intonation/Library/Record.php
index a4ac4d1321669116a993ab69f3f624c9c713d27a..8be0bc7232598b8191c5887639fe3a8c0cd5fc8e 100644
--- a/library/templates/Intonation/Library/Record.php
+++ b/library/templates/Intonation/Library/Record.php
@@ -22,7 +22,7 @@
 
 class Intonation_Library_Record {
 
-  use Trait_Translator;
+  use Trait_Translator, Trait_AuthenticationProfile;
 
   protected static
     $_items_by_records = [],
diff --git a/library/templates/Intonation/Library/Selection.php b/library/templates/Intonation/Library/Selection.php
index df6184058e40c88a0cbb4d5b807bb839f6caba52..92ade1565bcf384407c105f88722c3d23444fa72 100644
--- a/library/templates/Intonation/Library/Selection.php
+++ b/library/templates/Intonation/Library/Selection.php
@@ -21,7 +21,7 @@
 
 
 class Intonation_Library_Selection {
-  use Trait_Translator;
+  use Trait_Translator, Trait_AuthenticationProfile;
 
   protected static $_selections_cache = [];
 
@@ -88,14 +88,12 @@ class Intonation_Library_Selection {
 
 
   public function getAction() : Intonation_Library_Link {
-    $url = $this->getView()->url($this->_getUrlForContext(), null, true);
+    $url = Class_Url::relative($this->_getUrlForContext());
 
     $js =
       sprintf("event.preventDefault(); event.stopPropagation(); var url = $(this).attr('href'); var anchors = $('a[href=\'' + url + '\']'); $.ajax({type: 'GET', url: '%s', success: function(data) {anchors.replaceWith(data.anchor);}});",
                   $url);
 
-    $popup = Class_Users::getIdentity() ? false : 'true';
-
     return (new Intonation_Library_Link)
       ->setUrl($url)
       ->setAttribs(Class_Users::getIdentity() ? ['onclick' => $js] : [])
@@ -105,7 +103,7 @@ class Intonation_Library_Selection {
       ->setClass($this->getClass())
       ->setTitle($this->_getTitleForContext(false))
       ->setScreenReaderText($this->_getTitleForContext())
-      ->setPopup($popup);
+      ->setPopup((null === $this->_authenticateProfile()));
   }
 
 
diff --git a/library/templates/Intonation/Library/View/Wrapper/Abstract.php b/library/templates/Intonation/Library/View/Wrapper/Abstract.php
index a3c0e407a6fae1cd616ff20d10eef392b8d46edf..b9074dd4c566e907f5015aa294bd34f45b7a64da 100644
--- a/library/templates/Intonation/Library/View/Wrapper/Abstract.php
+++ b/library/templates/Intonation/Library/View/Wrapper/Abstract.php
@@ -22,7 +22,7 @@
 
 abstract class Intonation_Library_View_Wrapper_Abstract {
 
-  use Trait_Translator, Trait_TemplateAware;
+  use Trait_Translator, Trait_TemplateAware, Trait_AuthenticationProfile;
 
   protected
     $_view,
diff --git a/library/templates/Intonation/Library/View/Wrapper/ItemWithoutSIGB.php b/library/templates/Intonation/Library/View/Wrapper/ItemWithoutSIGB.php
index 2896fa354f4fee32fbdd46dcfd405446659a6175..0bc91e9cbccc2a6b230cb218ffdde2d71dde8cb5 100644
--- a/library/templates/Intonation/Library/View/Wrapper/ItemWithoutSIGB.php
+++ b/library/templates/Intonation/Library/View/Wrapper/ItemWithoutSIGB.php
@@ -64,7 +64,7 @@ class Intonation_Library_View_Wrapper_ItemWithoutSIGB extends Intonation_Library
             ->setText($text)
             ->setImage($this->getSecondaryIco())
             ->setTitle($title)
-            ->setPopup(true)];
+            ->setPopup((null === $this->_authenticateProfile()))];
   }
 
 }
diff --git a/library/templates/Intonation/Library/View/Wrapper/Record.php b/library/templates/Intonation/Library/View/Wrapper/Record.php
index 6d39c821e310ce996aabc8e1bcad7e8022d2278f..88dc175ddad287ff9a8ac119eeaa5a9dea755cf5 100644
--- a/library/templates/Intonation/Library/View/Wrapper/Record.php
+++ b/library/templates/Intonation/Library/View/Wrapper/Record.php
@@ -571,22 +571,23 @@ class Intonation_Library_View_Wrapper_Record
       return $actions;
     }
 
-    $actions = $this->_addHoldLink($actions);
-
-    return $actions;
+    return $this->_addHoldLink($actions);
   }
 
 
-  protected function _addHoldLink($actions) {
+  protected function _addHoldLink(array $actions) : array {
+    $url = $this->_view->url(['controller' => 'recherche',
+                              'action' => 'reserver',
+                              'record_id' => $this->_model->getId()],
+                             null, true);
+
     $actions [] = (new Intonation_Library_Link)
-      ->setUrl($this->_view->url(['controller' => 'recherche',
-                                  'action' => 'reserver',
-                                  'record_id' => $this->_model->getId()]))
+      ->setUrl($url)
       ->setImage($this->getIco('hold', 'library'))
       ->setText($this->_('Réserver'))
       ->setTitle($this->_('Réserver le document %s', $this->getMainTitleAsText()))
       ->setClass('hold_record doctype_id_' . $this->getDocType())
-      ->setPopup(true);
+      ->setPopup((null === $this->_authenticateProfile()));
 
     return $actions;
   }
@@ -636,7 +637,7 @@ class Intonation_Library_View_Wrapper_Record
       ->setScreenReaderText($this->_('%s dans une sélection', $this->_model->getTitrePrincipal(' ')))
       ->setTitle($this->_('Ajouter %s dans une sélection', $this->_model->getTitrePrincipal(' ')))
       ->setClass('add_record_to_selection')
-      ->setPopup('true');
+      ->setPopup((null === $this->_authenticateProfile()));
   }
 
 
diff --git a/library/templates/Intonation/Library/View/Wrapper/Review.php b/library/templates/Intonation/Library/View/Wrapper/Review.php
index 1a31077a6b27e5e5517b3c6c36eaad67a15244bc..7c29d8e70e519aa37ce1dafda048f695fa484ec5 100644
--- a/library/templates/Intonation/Library/View/Wrapper/Review.php
+++ b/library/templates/Intonation/Library/View/Wrapper/Review.php
@@ -190,7 +190,7 @@ class Intonation_Library_View_Wrapper_Review extends Intonation_Library_View_Wra
       ->setImage($this->getIco('edit', 'utils'))
       ->setText($this->_('Modifier'))
       ->setTitle($this->_('Modifier l\'avis %s', $this->_model->getEntete()))
-      ->setPopup(true);
+      ->setPopup((null === $this->_authenticateProfile()));
 
     $actions [] = (new Intonation_Library_Link)
       ->setUrl($this->_view->url(['controller' => 'abonne',
@@ -200,7 +200,7 @@ class Intonation_Library_View_Wrapper_Review extends Intonation_Library_View_Wra
       ->setText($this->_('Supprimer'))
       ->setTitle($this->_('Supprimer l\'avis %s', $this->_model->getEntete()))
       ->setClass('text-danger')
-      ->setPopup(true);
+      ->setPopup((null === $this->_authenticateProfile()));
 
     return $actions;
   }
diff --git a/library/templates/Intonation/Library/View/Wrapper/ReviewInRecord.php b/library/templates/Intonation/Library/View/Wrapper/ReviewInRecord.php
index 8d222648a4cfa4f7317bce8a1b5c1537844a560f..b1b82aaf4d3994bf70fc57015d84e86bbff0c398 100644
--- a/library/templates/Intonation/Library/View/Wrapper/ReviewInRecord.php
+++ b/library/templates/Intonation/Library/View/Wrapper/ReviewInRecord.php
@@ -45,7 +45,7 @@ class Intonation_Library_View_Wrapper_ReviewInRecord extends Intonation_Library_
       ->setImage($this->getIco('read-review', 'library'))
       ->setText($this->_('Lire l\'avis'))
       ->setTitle($this->_getMainLinkTitle())
-      ->setPopup(true);
+      ->setPopup((null === $this->_authenticateProfile()));
   }
 
 
@@ -70,4 +70,4 @@ class Intonation_Library_View_Wrapper_ReviewInRecord extends Intonation_Library_
   public function getActions() {
     return $this->_belongsToCurrentUserActions([]);
   }
-}
\ No newline at end of file
+}
diff --git a/library/templates/Intonation/Library/View/Wrapper/Search.php b/library/templates/Intonation/Library/View/Wrapper/Search.php
index ceec19ee46da2af9d04a47fc42ee48a4e8b2bf12..86fae95a75d40b0a2ae4432f2961a4e285144fd8 100644
--- a/library/templates/Intonation/Library/View/Wrapper/Search.php
+++ b/library/templates/Intonation/Library/View/Wrapper/Search.php
@@ -121,12 +121,14 @@ class Intonation_Library_View_Wrapper_Search
   public function getActions() {
     $id = $this->_model->getExistingIdFor(Class_Users::getIdentity());
     $can_follow = !$id;
+    $url = $this->_view->url(array_merge($this->_model->getCriteriasUrl(),
+                                         ['controller' => 'bookmarked-searches',
+                                          'action' => $can_follow ? 'add' : 'delete',
+                                          'label' => $this->getMainTitleAsText(),
+                                          'id' => $id]));
+
     return [(new Intonation_Library_Link)
-            ->setUrl($this->_view->url(array_merge($this->_model->getCriteriasUrl(),
-                                                   ['controller' => 'bookmarked-searches',
-                                                    'action' => $can_follow ? 'add' : 'delete',
-                                                    'label' => $this->getMainTitleAsText(),
-                                                    'id' => $id])))
+            ->setUrl($url)
             ->setImage($this->getIco($can_follow ? 'no-selection' : 'selection',
                                      'library'))
             ->setText($can_follow ? $this->_('Suivre') : $this->_('Ne plus suivre'))
@@ -135,20 +137,24 @@ class Intonation_Library_View_Wrapper_Search
                        : $this->_('Ne plus suivre cette recherche.'))
             ->alwaysDisplayText()
             ->setScreenReaderText($this->_model->getLabel())
-            ->setPopup(true)];
+            ->setPopup((null === $this->_authenticateProfile()))];
   }
 
 
   public function getMoreActions() {
-    $actions = [(new Intonation_Library_Link)
-                ->setUrl($this->_view->url(['controller' => 'abonne',
-                                            'action' => 'suggestion-achat-add']))
+    $url = $this->_view->url(['controller' => 'abonne',
+                              'action' => 'suggestion-achat-add']);
+
+    $action_link = (new Intonation_Library_Link)
+                ->setUrl($url)
                 ->setImage($this->getIco('suggest', 'library'))
                 ->setText($this->_('Suggérer un achat'))
                 ->setTitle($this->_('Envoyer une demande d\'achat de document'))
                 ->setAriaLabel($this->_('Envoyer une demande d\'achat de document dans un nouvel onglet'))
                 ->setAttrib('target', '_blank')
-                ->alwaysDisplayText()
+                ->alwaysDisplayText();
+
+    $actions = [$action_link
                 ,
                 (new Intonation_Library_Link)
                 ->setUrl($this->_view->url(['controller' => 'recherche',
diff --git a/library/templates/Intonation/Library/View/Wrapper/Selection.php b/library/templates/Intonation/Library/View/Wrapper/Selection.php
index b443192c0d275e0fdfb17bcdb5227b98c009567d..a938c06b04520b146f0e94aa76f881bdfd97f062 100644
--- a/library/templates/Intonation/Library/View/Wrapper/Selection.php
+++ b/library/templates/Intonation/Library/View/Wrapper/Selection.php
@@ -199,7 +199,7 @@ class Intonation_Library_View_Wrapper_Selection extends Intonation_Library_View_
         ->setText($this->_('Exporter'))
         ->setTitle($this->_('Exporter la sélection %s', $this->_model->getLibelle()))
         ->setScreenReaderText($this->_('la sélection %s', $this->_model->getLibelle()))
-        ->setPopup(true);
+        ->setPopup((null === $this->_authenticateProfile()));
 
     if ( ! $this->_model->canBeEditedByMe())
       return $actions;
@@ -227,7 +227,7 @@ class Intonation_Library_View_Wrapper_Selection extends Intonation_Library_View_
       ->setText($this->_('Renommer'))
       ->setTitle($this->_('Renommer la sélection %s', $this->_model->getLibelle()))
       ->setAriaLabel($this->_('Renommer la sélection %s', $this->_model->getLibelle()))
-      ->setPopup('true');
+      ->setPopup((null === $this->_authenticateProfile()));
 
     $actions[] = (new Intonation_Library_Link)
       ->setUrl($this->_view->url(['controller' => 'panier',
@@ -237,7 +237,7 @@ class Intonation_Library_View_Wrapper_Selection extends Intonation_Library_View_
       ->setText($this->_('Domaines liés'))
       ->setTitle($this->_('Lier la sélection %s à un domaine', $this->_model->getLibelle()))
       ->setAriaLabel($this->_('Lier la sélection %s à un domaine', $this->_model->getLibelle()))
-      ->setPopup('true');
+      ->setPopup((null === $this->_authenticateProfile()));
 
     $actions[] = (new Intonation_Library_Link)
       ->setUrl($this->_view->url(['controller' => 'abonne',
@@ -248,7 +248,7 @@ class Intonation_Library_View_Wrapper_Selection extends Intonation_Library_View_
       ->setTitle($this->_('Supprimer la sélection %s', $this->_model->getLibelle()))
       ->setAriaLabel($this->_('Supprimer la sélection %s', $this->_model->getLibelle()))
       ->setClass('text-danger')
-      ->setPopup('true');
+      ->setPopup((null === $this->_authenticateProfile()));
 
     return $actions;
   }
diff --git a/library/templates/Intonation/Library/Widget/Login/Definition.php b/library/templates/Intonation/Library/Widget/Login/Definition.php
index ef5000d7b73e67eda28df2fe548ce90236e41a28..34242d1db06a749e5822caf4e827e17c66e3bb42 100644
--- a/library/templates/Intonation/Library/Widget/Login/Definition.php
+++ b/library/templates/Intonation/Library/Widget/Login/Definition.php
@@ -28,7 +28,7 @@ class Intonation_Library_Widget_Login_Definition extends Class_Systeme_ModulesAc
 
   public function __construct() {
     parent::__construct();
-    $this->_view_helper = 'Intonation_Library_Widget_Login_View';
+    $this->_view_helper = Intonation_Library_Widget_Login_View::class;
     $this->_defaultValues = array_merge($this->_defaultValues,
                                         ['titre_connecte' => '',
                                          'identifiant' => $this->_('Identifiant'),
diff --git a/library/templates/Intonation/Library/Widget/Login/RenderAbstract.php b/library/templates/Intonation/Library/Widget/Login/RenderAbstract.php
index 948b0a1d4dc4543416c801bb81befa2cb8fc4e69..834c18ad1df2f684d79ec24cd6ce032ee3095555 100644
--- a/library/templates/Intonation/Library/Widget/Login/RenderAbstract.php
+++ b/library/templates/Intonation/Library/Widget/Login/RenderAbstract.php
@@ -72,11 +72,15 @@ abstract class Intonation_Library_Widget_Login_RenderAbstract {
         $options [Storm_Inflector::underscorize($key)] = $value;
     $form = ZendAfi_Form_Login::newWithOptions(['data' => $options]);
 
+    $action_params = ['controller' => 'auth',
+                      'action' => 'login'];
+
+    if (!$this->_view->getRedirectUrl() && !$this->_view->getAfterLoginDo())
+      $action_params['redirect'] = $this->_redirectUrl($options);
+
     $action = $this->_settings->getClearAction()
       ? ''
-      : $this->_view->url(['controller' => 'auth',
-                           'action' => 'login',
-                           'redirect' => $this->_redirectUrl($options)]);
+      : $this->_view->url($action_params);
     $form
       ->setAction($action);
 
diff --git a/library/templates/Intonation/View/RenderRecord/RenderReviews.php b/library/templates/Intonation/View/RenderRecord/RenderReviews.php
index c682c716dd6136b45e906e743bcdb85c356bc002..ae1b6d9f3842938c8dbb2f25979d073750b89d28 100644
--- a/library/templates/Intonation/View/RenderRecord/RenderReviews.php
+++ b/library/templates/Intonation/View/RenderRecord/RenderReviews.php
@@ -24,6 +24,7 @@ class Intonation_View_RenderRecord_RenderReviews extends ZendAfi_View_Helper_Bas
 
   protected $_record;
 
+  use Trait_AuthenticationProfile;
 
   public function RenderRecord_RenderReviews($record) {
     $this->_record = $record;
@@ -117,13 +118,7 @@ class Intonation_View_RenderRecord_RenderReviews extends ZendAfi_View_Helper_Bas
 
   protected function _mine() {
     if (!$me = Class_Users::getIdentity())
-      return $this->view->tagAction((new Intonation_Library_Link)
-                                    ->setUrl($this->view->url(['controller' => 'auth',
-                                                               'action' => 'popup-login']))
-                                    ->setImage($this->view->templateIco('login', 'utils'))
-                                    ->setText($this->_('Se connecter'))
-                                    ->setTitle($this->_('Connectez vous pour donner un avis'))
-                                    ->setPopup(true));
+      return $this->_getTagConnectionUrl();
 
     if ($me->getFirstAvisByIdNotice($this->_record->getId())
         || (!$me->isBibliothecaire() && Class_AdminVar::isLibrarianReviewsOnly()))
@@ -138,4 +133,20 @@ class Intonation_View_RenderRecord_RenderReviews extends ZendAfi_View_Helper_Bas
                                 $this->_div(['class' => 'card-body'],
                                             $this->view->reviewForm($new_review))));
   }
+
+
+  protected function _getTagConnectionUrl() :string {
+    $url =  $this->view->url(['controller' => 'auth',
+                              'action' => 'popup-login']);
+
+    if ($profile = $this->_authenticateProfile())
+      $url = $this->_authenticateProfileUrl('', $this->view->url());
+
+    return $this->view->tagAction((new Intonation_Library_Link)
+                                  ->setUrl($url)
+                                  ->setImage($this->view->templateIco('login', 'utils'))
+                                  ->setText($this->_('Se connecter'))
+                                  ->setTitle($this->_('Connectez vous pour donner un avis'))
+                                  ->setPopup((null === $profile)));
+  }
 }
diff --git a/library/templates/Intonation/View/Search/Preferences.php b/library/templates/Intonation/View/Search/Preferences.php
index 74202a60a7cb7a9c4a6baa7562ab717360737056..375a2ab16917dfef88402bd95f09cfc512d98ae0 100644
--- a/library/templates/Intonation/View/Search/Preferences.php
+++ b/library/templates/Intonation/View/Search/Preferences.php
@@ -21,6 +21,7 @@
 
 
 class Intonation_View_Search_Preferences extends ZendAfi_View_Helper_Bookmarks {
+  use Trait_AuthenticationProfile;
   public function search_Preferences($search) {
     return $this->bookmarks($search);
   }
@@ -52,15 +53,17 @@ class Intonation_View_Search_Preferences extends ZendAfi_View_Helper_Bookmarks {
 
 
   protected function _renderEditMySettingsLink() {
+    $url =  $this->view->url(['module' => 'opac',
+                              'controller' => 'abonne' ,
+                              'action' => 'configurations'],
+                             null,
+                             true);
+
     return $this->_tagAnchor(
-                             $this->view->url(['module' => 'opac',
-                                               'controller' => 'abonne' ,
-                                               'action' => 'configurations'],
-                                              null,
-                                              true),
+                             $url,
                              $this->view->templateIco('settings', 'library',['title' => $this->_('Modifier mes préférences dans une boîte de dialogue')] ),
                              ['class' => 'bookmarks_edit ml-2',
-                              'data-popup' => 'true',
+                              'data-popup' => (null === $this->_authenticateProfile()),
                               'aria-label' => $this->_('Configuration de mes préférences de recherche')]);
   }
 
diff --git a/library/templates/Intonation/View/Search/Result.php b/library/templates/Intonation/View/Search/Result.php
index c6857024f80c484c8701fe6bcbc7fa7d1665ee29..d766a5b3a6a687e38bc81c3728f98627373d5750 100644
--- a/library/templates/Intonation/View/Search/Result.php
+++ b/library/templates/Intonation/View/Search/Result.php
@@ -204,7 +204,7 @@ class Intonation_View_Search_Result extends ZendAfi_View_Helper_BaseHelper {
     $tools ['result_follow_search'] =
       $this->view->tagAction($search_wrapper
                              ->getActions()[0]
-                             ->setAttribs(['data-popup' => true,
+                             ->setAttribs(['data-popup' => (null === $this->_shouldConnectWithProfil()),
                                            'class' => 'btn btn-sm btn-primary text-white']));
 
     $tools ['result_more_actions'] = $search_wrapper->getMoreActions();
diff --git a/tests/application/modules/opac/controllers/AbonneControllerFicheTest.php b/tests/application/modules/opac/controllers/AbonneControllerFicheTest.php
index f4388fc5adf100f88c29b81cd84ea2d07166b154..a45a6bdd009a092f451f98578e92eb503a9cc6b8 100644
--- a/tests/application/modules/opac/controllers/AbonneControllerFicheTest.php
+++ b/tests/application/modules/opac/controllers/AbonneControllerFicheTest.php
@@ -159,7 +159,7 @@ class AbonneControllerFicheNobodyLoggedTest extends AbstractAbonneControllerFich
   public function setUp() {
     parent::setUp();
     ZendAfi_Auth::getInstance()->clearIdentity();
-    $this->dispatch('/abonne/fiche', true);
+    $this->dispatch('/abonne/fiche');
   }
 
 
@@ -176,7 +176,7 @@ class AbonneControllerFicheNobodyLoggedTest extends AbstractAbonneControllerFich
 
   /** @test */
   public function hiddenInputRedirectShouldContainsAbonneFiche() {
-    $this->assertXPath('//input[@name="redirect"][@value="http://localhost' . BASE_URL . '/abonne/fiche"]');
+    $this->assertXPath('//input[@name="redirect"][@value="/abonne/fiche"]');
   }
 
 }
@@ -188,7 +188,7 @@ class AbonneControllerFicheAsAdminDisableSuggestAndBookmarkableLibrariesTest ext
     parent::setUp();
     Class_AdminVar::set('DISABLE_SUGGESTIONS', 1);
     Class_AdminVar::set('ENABLE_BOOKMARKABLE_LIBRARIES', 0);
-    $this->dispatch('/abonne/fiche', true);
+    $this->dispatch('/abonne/fiche');
   }
 
 
@@ -232,7 +232,7 @@ class AbonneControllerFicheWithIdentityProvidersEnabledTest extends AbstractAbon
 class AbonneControllerFicheActionWithLoggedUserTest extends AbstractAbonneControllerFicheTest {
   public function setUp() {
     parent::setUp();
-    $this->dispatch('/abonne/fiche', true);
+    $this->dispatch('/abonne/fiche');
   }
 
 
@@ -329,7 +329,7 @@ class AbonneControllerFicheActionLoggedGuestWithPnbHoldsTest
                               'hold_date' => '2022-06-07 20:10:00',
                               'expiration_date' => '2022-06-15 20:10:00']);
 
-    $this->dispatch('/abonne/fiche', true);
+    $this->dispatch('/abonne/fiche');
   }
 
 
diff --git a/tests/application/modules/opac/controllers/NoticeAjaxControllerItemsTest.php b/tests/application/modules/opac/controllers/NoticeAjaxControllerItemsTest.php
index 19a914015ad032dc17930058b1939b4912b68d5a..1f3b578fce157f2a78b512f0f9a3fc5180123800 100644
--- a/tests/application/modules/opac/controllers/NoticeAjaxControllerItemsTest.php
+++ b/tests/application/modules/opac/controllers/NoticeAjaxControllerItemsTest.php
@@ -226,7 +226,7 @@ class NoticeAjaxControllerItemsWithoutOrderTest
 
   /** @test */
   public function linkToMapviewShouldBePresent() {
-    $this->assertXPath('//td//a[contains(@href, "/bib/mapview/id_bib/3")][@data-popup="1"]');
+    $this->assertXPath('//td//a[contains(@href, "/bib/mapview/id_bib/3")][@data-popup="true"]');
   }
 }
 
diff --git a/tests/application/modules/opac/controllers/PanierControllerTest.php b/tests/application/modules/opac/controllers/PanierControllerTest.php
index 2eb70254ec1efc9c738f83d09886e58c738493d9..7ec88bbc5f86cd03418f6ea55db76d0da65eca9d 100644
--- a/tests/application/modules/opac/controllers/PanierControllerTest.php
+++ b/tests/application/modules/opac/controllers/PanierControllerTest.php
@@ -818,13 +818,13 @@ class PanierControllerNotLoggedTest extends PanierControllerTestCase {
 
   /** @test */
   public function responseShouldRenderLoginForm() {
-    $this->assertXPath('//input[@name="username"]', $this->_response->getBody());
+    $this->assertXPath('//input[@name="username"]');
   }
 
 
   /** @test */
   public function hiddenInputShouldContainsRedirectUrl() {
-    $this->assertXPath('//input[@type="hidden"][@name="redirect"][contains(@value, "/panier/index")]');
+    $this->assertXPath('//input[@type="hidden"][@name="redirect"][contains(@value, "/panier")]');
   }
 }
 
diff --git a/tests/db/UpgradeDBTest.php b/tests/db/UpgradeDBTest.php
index 6a3ddd35a171046273b1df2f544aa7481c3557d6..a3bafdf347af474983c2eb258a0bffdcd7dc3a3d 100644
--- a/tests/db/UpgradeDBTest.php
+++ b/tests/db/UpgradeDBTest.php
@@ -5207,3 +5207,21 @@ class UpgradeDB_449_Test extends UpgradeDBTestCase {
     $this->assertFieldType('codif_genre', 'code_alpha', 'varchar(255)');
   }
 }
+
+
+
+
+class UpgradeDB_450_Test extends UpgradeDBTestCase {
+
+  public function prepare() {
+    try {
+      $this->query("ALTER TABLE bib_admin_profil DROP intent");
+    } catch(Exception $e) {}
+  }
+
+
+  /** @test */
+  public function bibAdminProfilIntentColumnshouldExist() {
+    $this->assertFieldType('bib_admin_profil','intent', 'varchar(255)');
+  }
+}
diff --git a/tests/scenarios/Activities/AbonneControllerActivitiesTest.php b/tests/scenarios/Activities/AbonneControllerActivitiesTest.php
index 1b9070cd63fb1b658be317fd7d56b9e2ddb4061d..a262a430f766594775f35987a9a9d84102c06bd5 100644
--- a/tests/scenarios/Activities/AbonneControllerActivitiesTest.php
+++ b/tests/scenarios/Activities/AbonneControllerActivitiesTest.php
@@ -1136,6 +1136,9 @@ class AbonneControllerActivitiesInscritSessionWithoutRightSuivreActivityTest ext
 
 class AbonneControllerActivitiesInscriptionNotLoggedTest
   extends AbstractAbonneControllerActivitiesTestCase {
+  protected
+    $_json,
+    $_xpath;
 
   public function setUp() {
     parent::setUp();
diff --git a/tests/scenarios/AuthenticationIntentTest.php b/tests/scenarios/AuthenticationIntentTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..7512041b4a0b93a5ab39da5a795a2817a5e0cab7
--- /dev/null
+++ b/tests/scenarios/AuthenticationIntentTest.php
@@ -0,0 +1,791 @@
+<?php
+/**
+ * Copyright (c) 2012-2022, Agence Française Informatique (AFI). All rights reserved.
+ *
+ * BOKEH is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by
+ * the Free Software Foundation.
+ *
+ * There are special exceptions to the terms and conditions of the AGPL as it
+ * is applied to this software (see README file).
+ *
+ * BOKEH 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 AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * along with BOKEH; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
+ */
+
+
+abstract class AuthenticationIntentWithoutLoginWidgetTestCase extends AbstractControllerTestCase {
+  protected string $_url_tested;
+  public function setUp() {
+    parent::setUp();
+
+    ZendAfi_Auth::getInstance()->clearIdentity();
+
+    $this->_buildTemplateProfil(['id' => 1]);
+
+    $profile = $this->_buildTemplateProfil(['id' => 3,
+                                            'libelle' => 'Authentication Page',
+                                            'parent_id' => 1,
+                                            'intent' => 'authentication']);
+
+    $profile_patcher = (new Class_Template_ProfilePatcher(null))
+      ->setProfile($profile);
+
+    $profile_patcher
+      ->addWidget(Intonation_Library_Widget_Login_Definition::CODE,
+                  Class_Profil::DIV_MAIN);
+
+    $this->fixture(Class_Notice::class,
+                   ['id' => 2]);
+
+    $this->fixture(Class_Exemplaire::class,
+                   ['id' => 1,
+                    'id_notice' => 2,
+                    'id_origine' => '12',
+                    'code_barres' => '1249036',
+                    'id_int_bib' => 1,
+                    'id_bib' => 1]);
+
+    $this->fixture(Class_IntBib::class,
+                   ['id' => 1,
+                    'label' => 'majolieville',
+                    'comm_sigb' => Class_IntBib::COM_KOHA,
+                    'comm_params' => ['url_serveur' => 'https://monsuperkoha.org']]);
+
+    $this->fixture(Class_Bib::class,
+                   ['id' => 1,
+                    'libelle' => 'Montmin']);
+
+    $this->fixture(Class_Newsletter::class,
+                   ['id' => 35,
+                    'titre' => 'Jeunesse',
+                    'mail_subject' => 'Jeunesse'
+                   ]);
+
+    $this->fixture(Class_Notice::class,
+                   ['id' => 123,
+                    'titre' => 'Le parfum de la dame en noir',
+                    'type_doc' => Class_TypeDoc::LIVRE
+                   ]);
+
+    $this->fixture(Class_Exemplaire::class,
+                   ['id' => 1234,
+                    'id_int_bib' => 1,
+                    'id_bib' => 1,
+                    'notice_id' => 123,
+                    'cote' => 'BAC123',
+                    'code_barres' => '1234'
+                   ]);
+  }
+}
+
+
+
+
+class AuthenticationIntentWithoutLoginViewAlbumTest
+  extends AuthenticationIntentWithoutLoginWidgetTestCase{
+
+
+  public function setUp() {
+    parent::setUp();
+
+    $this->fixture(Class_Album::class,
+                   ['id' => 4,
+                    'notice_id' => 3,
+                    'type_doc_id' => 'ArteVod',
+                    'titre' => 'Seventh Son of a Seventh Son',
+                    'status' => Class_Album::STATUS_VALIDATED]);
+
+    $this->fixture(Class_Exemplaire::class,
+                   ['id' => 15,
+                    'notice' => $this->fixture(Class_Notice::class,
+                                               ['id' => 3,
+                                                'titre' => 'Un titre',
+                                                'type_doc' => 'ArteVod']),
+                    'id_origine' => 4,
+                    'code_barres' => '786876786']);
+
+    $this->fixture(Class_AlbumRessource::class,
+                   ['id' => 1,
+                    'id_album' => 4,
+                    'titre' => 'Moonchild',
+                    'url' => 'http://mabib.net/bib-numerique/notice/ido/1']);
+
+    $this->dispatch('/noticeajax/resources/id/3');
+  }
+
+
+  /** @test */
+  public function albumShouldContainAuthenticationLink() {
+    $this->assertXPathContentContains('//a[contains(@href,"/modules/arte-vod/album_id/4")][@target = "_blank"]',
+                                      utf8_encode('Visionner le film dans son intégralité'));
+  }
+}
+
+
+
+
+class AuthenticationIntentWithoutLoginRecordReviewsClefTest extends AuthenticationIntentWithoutLoginWidgetTestCase{
+  public function setUp() {
+    parent::setUp();
+    $this->dispatch('record/reviews/clef/qsdfqsdf/id/2');
+  }
+
+
+  /** @test */
+  public function seConnecterLinkShouldBeProfileIdThree() {
+    $this->assertXPathContentContains('//div//a[@href="/index/index/id_profil/3/redirect_url/'.urlencode('/record/reviews/clef/qsdfqsdf/id/2').'"]',
+                                      'Se connecter');
+  }
+}
+
+
+
+
+class AuthenticationIntentWithoutLoginRecord2LinksTest extends AuthenticationIntentWithoutLoginWidgetTestCase {
+  public function setUp() {
+    parent::setUp();
+
+    $this->fixture(Class_Notice::class,
+                   ['id' => 2,
+                    'clef_oeuvre' => 'PSYKO',
+                    'titre_principal' => 'Psyko'
+                   ]);
+
+    $this->dispatch('recherche/viewnotice/id/2');
+  }
+
+
+  /** @test */
+  public function mesPreferesLinkShouldBeIndexIndexIdProfile() {
+    $this->assertXPathContentContains('//a[contains(@href,"/abonne/ajouter-le-document-a-la-selection/selection_label/Mes+pr%C3%A9f%C3%A9r%C3%A9s/image/like/revert-image/dislike/record_id/2/ajax/")]',
+                                      'Mes préférés');
+  }
+
+
+  /** @test */
+  public function dejaLuLinkShouldBeIndexIndexIdProfile() {
+    $this->assertXPathContentContains('//a[contains(@href,"/abonne/ajouter-le-document-a-la-selection/")]',
+                                      'Déjà lu');
+  }
+
+
+  /** @test */
+  public function seConnecterAvisLinkShouldBeindex() {
+    $this->assertXPathContentContains('//a[contains(@href,"/index/index/id_profil/3/redirect_url/'.urlencode('/recherche/viewnotice/id/2').'")][@title="Connectez vous pour donner un avis"]',"Se connecter");
+  }
+}
+
+
+
+
+class AuthenticationIntentWithoutLoginRechercheSimpleLinksTest extends AuthenticationIntentWithoutLoginWidgetTestCase {
+  public function setUp() {
+    parent::setUp();
+
+    $this->fixture(Class_Notice::class,
+                   ['id' => 2,
+                    'clef_oeuvre' => 'PSYKO',
+                    'titre_principal' => 'Psyko'
+                   ]);
+    $sql = $this->mock()
+                ->whenCalled('fetchAll')
+                ->answers([[2, '']]);
+
+    Zend_Registry::set('sql', $sql);
+
+    Class_AdminVar::set('ENABLE_SEARCH_MULTIPLE_RECORD_SELECTION', 1);
+    Zend_Registry::get('session')->search_record_selection = [2];
+
+    $this->dispatch('recherche/simple/expressionRecherche/Psyko');
+  }
+
+
+  /** @test */
+  public function suivreLinkShouldBeBookmarkedSearchesAdd() {
+    $this->assertXPathContentContains('//a[contains(@href,"/bookmarked-searches/add/expressionRecherche/Psyko/label/R%C3%A9sultat+pour+Psyko+")]',
+                                      "Suivre");
+  }
+
+
+  /** @test */
+  public function addPanierLinkShouldBePanierAddSelection() {
+    $this->assertXPathContentContains('//div[@class="record-selection"]//a[contains(@href,"/panier/add-selection")][@title="Ajouter toutes les notices de la sélection à un panier"]',
+                                      "Mettre dans un panier");
+  }
+}
+
+
+
+
+abstract class AuthenticationIntentWithoutLoginDispatchTestCase extends AuthenticationIntentWithoutLoginWidgetTestCase {
+  protected string $_url_tested;
+  public function setUp() {
+    parent::setUp();
+    $this->_setReferer() ;
+    $this->dispatch($this->_url_tested);
+  }
+
+
+  public function tearDown(){
+    $_SERVER['HTTP_REFERER'] = null;
+    parent::tearDown();
+  }
+
+
+  protected function _setReferer(){
+    $_SERVER['HTTP_REFERER'] = '/recherche/viewnotice/id/12';
+  }
+
+
+  /** @test */
+  public function pageShouldRedirectToAuthenticationPage() {
+    $this->assertRedirectTo('/index/index/id_profil/3/redirect_url/'
+                            .urlencode($_SERVER['HTTP_REFERER'])
+                            .'/after_login_do/'
+                            .urlencode($this->_url_tested));
+  }
+}
+
+
+
+
+
+class AuthenticationIntentWithoutLoginNoticeAjaxAddAvisTest extends AuthenticationIntentWithoutLoginDispatchTestCase{
+  protected string $_url_tested =  '/noticeajax/add-avis/id/2';
+}
+
+
+
+
+class AuthenticationIntentWithoutLoginNoticeAjaxAddTagTest extends AuthenticationIntentWithoutLoginDispatchTestCase{
+  protected string $_url_tested =  '/noticeajax/add-tag/id/2';
+}
+
+
+
+
+class AuthenticationIntentWithoutLoginRechercheConsultationPickupAjaxTest extends AuthenticationIntentWithoutLoginDispatchTestCase{
+  protected string $_url_tested =  '/recherche/consultation-pickup-ajax/id/2';
+}
+
+
+
+
+class AuthenticationIntentWithoutLoginPanierAddSelectionTest extends AuthenticationIntentWithoutLoginDispatchTestCase{
+  protected string $_url_tested =  '/panier/add-selection/id/2';
+}
+
+
+
+
+class AuthenticationIntentWithoutLoginPanierAddRecordAjaxTest extends AuthenticationIntentWithoutLoginDispatchTestCase{
+  protected string $_url_tested =  '/panier/add-record-ajax/id/2';
+}
+
+
+
+
+class AuthenticationIntentRechercheReserverRedirectToLoginTest extends AuthenticationIntentWithoutLoginDispatchTestCase{
+  protected string $_url_tested = '/recherche/reservation/id_int_bib/1/id_bib/1/id_notice/123/cote/BAC123';
+
+  protected string $_referer = '/record/items/123';
+}
+
+
+
+
+class AuthenticationIntentDispatchAbonneInscrireSessionTest extends AuthenticationIntentWithoutLoginDispatchTestCase {
+  protected string $_url_tested = '/abonne/inscrire-session/id/1';
+}
+
+
+
+
+
+class AuthenticationIntentDispatchAbonneSuggestionAchatAddTest extends AuthenticationIntentWithoutLoginDispatchTestCase {
+  protected string $_url_tested = '/abonne/suggestion-achat-add/id/1';
+}
+
+
+
+
+class AuthenticationIntentDispatchAbonneFicheId1AddTest extends AuthenticationIntentWithoutLoginDispatchTestCase {
+  protected string $_url_tested = '/abonne/fiche/id/1';
+}
+
+
+
+
+class AuthenticationIntentDispatchAbonneConfigurationsAddTest extends AuthenticationIntentWithoutLoginDispatchTestCase {
+  protected string $_url_tested = '/abonne/configurations';
+}
+
+
+
+
+class AuthenticationIntentDispatchBookmarkedSearchesTest extends AuthenticationIntentWithoutLoginDispatchTestCase {
+  protected string $_url_tested = '/bookmarked-searches/add/label/qsdf/id/1';
+}
+
+
+
+
+abstract class AuthenticationIntentWithoutLoginBibNumeriqueDispatchTestCase extends AuthenticationIntentWithoutLoginWidgetTestCase {
+  protected string $_url_tested;
+  public function setUp() {
+    parent::setUp();
+    $this->dispatch($this->_url_tested);
+  }
+
+
+  /** @test */
+  public function pageShouldRedirectToAuthenticationPage() {
+    $this->assertRedirectTo('/index/index/id_profil/3/redirect_url/'
+                            .urlencode($this->_url_tested));
+  }
+}
+
+
+
+
+class AuthenticationIntentBibNumeriqueControllerConsultBookOpenAjaxTest extends AuthenticationIntentWithoutLoginBibNumeriqueDispatchTestCase{
+  protected string $_url_tested =  '/bib-numerique/consult-book-open-ajax/id/2';
+}
+
+
+
+
+class AuthenticationIntentBibNumeriqueControllerConsultBookAjaxTest extends AuthenticationIntentWithoutLoginBibNumeriqueDispatchTestCase{
+  protected string $_url_tested =  '/bib-numerique/consult-book-ajax/id/2';
+}
+
+
+
+
+class AuthenticationIntentBibNumeriqueControllerConsultBookTest extends AuthenticationIntentWithoutLoginBibNumeriqueDispatchTestCase{
+  protected string $_url_tested =  '/bib-numerique/consult-book/id/2';
+}
+
+
+
+
+class AuthenticationIntentBibNumeriqueControllerLoanBookAjaxTest extends AuthenticationIntentWithoutLoginBibNumeriqueDispatchTestCase{
+  protected string $_url_tested =  '/bib-numerique/loan-book-ajax/id/2';
+}
+
+
+
+
+class AuthenticationIntentBibNumeriqueControllerDownloadBookAjaxTest extends AuthenticationIntentWithoutLoginBibNumeriqueDispatchTestCase{
+  protected string $_url_tested =  '/bib-numerique/download-loan-book-ajax/id/2';
+}
+
+
+
+
+class AuthenticationIntentDispatchWithAfterLoginRedirectAndConnectionWithUserTest extends AbstractControllerTestCase {
+  public function setUp() {
+    parent::setUp();
+
+    $this->_buildTemplateProfil(['id' => 1,
+                                 'libelle' => 'accueil']);
+
+    $this->_buildTemplateProfil(['id' => 3,
+                                 'libelle' => 'auth',
+                                 'parent_id' => 1,
+                                 'intent' => 'authentication']);
+    $this->fixture(Class_Users::class,
+                   ['id' => 36,
+                    'login' => 'pourlecoup',
+                    'password' => 'puocelruop']);
+
+
+    $authenticated = false;
+    Zend_Registry::get('session')->redirect_url = "/recherche/viewnotice/id/2";
+    ZendAfi_Auth::setInstance($this->mock()
+                              ->whenCalled('getIdentity')
+                              ->willDo(
+                                       function() use(&$authenticated) {
+                                         if (!$authenticated)
+                                           return null;
+
+                                         $identity = new StdClass();
+                                         $identity->ID_USER = 36;
+                                         return $identity;
+                                       })
+                              ->whenCalled('authenticateLoginPassword')
+                              ->with('pourlecoup', 'puocelruop')
+                              ->willDo(
+                                       function() use(&$authenticated) {
+                                         return $authenticated = true;
+                                       })
+                              ->whenCalled('authenticateLoginPassword')
+                              ->with('pourlecoup', 'peza')
+                              ->willDo(
+                                       function() use(&$authenticated) {
+                                         return $authenticated = false;
+                                       }));
+
+  }
+
+  public function tearDown() {
+    ZendAfi_Auth::setInstance(null);
+    parent::tearDown();
+  }
+
+
+  public function authenticationMethod(){
+    return [['boite-login'],
+            ['login']
+    ];
+  }
+
+
+  /** @test
+   *  @dataProvider authenticationMethod
+   */
+  public function boiteLoginConnectWithAfterLoginSuccessRedirectShouldForwardToOpacViewnotice($auth_method) {
+    $this->postDispatch('opac/auth/'.$auth_method.'/id_profil/3',
+                        ['username' => 'pourlecoup',
+                         'password' => 'puocelruop']);
+
+    $this->assertRedirectTo('/recherche/viewnotice/id/2');
+  }
+
+
+
+  /** @test
+   */
+  public function loginConnectWithAfterLoginErrorRedirectShouldForwardToOpacViewnotice() {
+    $this->postDispatch('opac/auth/login/id_profil/3',
+                        ['username' => 'pourlecoup',
+                         'password' => 'peza']);
+
+    $this->assertRedirectTo('/recherche/viewnotice/id/2');
+  }
+}
+
+
+
+class AuthenticationIntentAfterLoginRedirectTest extends AuthenticationIntentWithoutLoginWidgetTestCase {
+  public function setUp() {
+    parent::setUp();
+
+    (new ZendAfi_Controller_Action_Helper_FlashMessenger)
+        ->addPopup('/recherche/reserver/record_id/2');
+    ZendAfi_Controller_Action_Helper_FlashMessenger::reset();
+    $this->dispatch('/record/items/clef/qsdfqsdf/id/2');
+  }
+
+
+  /** @test */
+  public function pageShouldContainsScriptOpacDialogWithRechercheReserverId2() {
+    $this->assertXPathContentContains('//script', 'opacDialogFromUrl("/recherche/reserver/record_id/2/render/popup");});');
+  }
+
+
+  /** @test */
+  public function sessionShouldNotContainsFlashMessengerPopupRechercheReserver() {
+    $this->assertNotFlashMessengerPopup();
+  }
+}
+
+
+
+
+
+class AuthenticationIntentPostLoginTest extends AuthenticationIntentWithoutLoginWidgetTestCase {
+  public function setUp() {
+    parent::setUp();
+
+    $this->fixture(Class_Users::class,
+                   ['id' => 879,
+                    'login' => 'Thomas',
+                    'password' => 'go']);
+
+    $this->postDispatch('/auth/login/redirect_url/'
+                        . urlencode('/recherche/viewnotice/id/2')
+                        . '/after_login_do/'
+                        . urlencode('/recherche/reserver/record_id/2'),
+                        ['username' => 'Thomas',
+                         'password' => 'go']);
+  }
+
+
+  /** @test */
+  public function shouldRedirectToRechercheViewnoticeIdTwo() {
+    $this->assertRedirectTo('/recherche/viewnotice/id/2');
+  }
+
+
+  /** @test */
+  public function sessionShouldNotContainsFlashMessengerPopupRechercheReserver() {
+    $this->assertFlashMessengerContainsPopup('/recherche/reserver/record_id/2/render/popup');
+  }
+}
+
+
+
+
+class AuthenticationIntentConnexionProfilWithRedirectTest
+  extends AuthenticationIntentWithoutLoginWidgetTestCase {
+
+  public function setUp() {
+    parent::setUp();
+    $this->dispatch('/index/index/id_profil/3/redirect_url/'
+                    . urlencode('/recherche/viewnotice/id/2')
+                    . '/after_login_do/'
+                    . urlencode('/recherche/reserver/id/2'));
+  }
+
+
+  /** @test */
+  public function boiteLoginFormActionShouldContainsRedirectUrlToRechercheViewNoticeAndAfterLogin() {
+    $this->assertXPath('//form[contains(@action, "/auth/login/id_profil/3'
+                       . '/redirect_url/'
+                       . urlencode('/recherche/viewnotice/id/2')
+                       . '/after_login_do/'
+                       . urlencode('/recherche/reserver/id/2')
+                       .'")]');
+  }
+
+
+  /** @test */
+  public function boiteLoginFormActionShouldNotContainsSimpleRedirect() {
+    $this->assertNotXPath('//form[contains(@action, "/redirect/")]');
+  }
+
+
+  /** @test */
+  public function afterLoginDoRechercheReserverShouldBeSavedInSession() {
+    $this->assertEquals('/recherche/reserver/id/2', Zend_Registry::get('session')->after_login_do);
+  }
+
+
+  /** @test */
+  public function redircetUrlRechercheViewnoticeShouldBeSavedInSession() {
+    $this->assertEquals('/recherche/viewnotice/id/2', Zend_Registry::get('session')->redirect_url);
+  }
+}
+
+
+
+
+abstract class AuthenticationIntentLoginWithIdentityProviderTestCase extends AuthenticationIntentWithoutLoginWidgetTestCase {
+  protected $_provider;
+
+  public function setUp() {
+    parent::setUp();
+
+    Class_AdminVar::set('ENABLE_IDENTITY_PROVIDERS', 1);
+
+    ZendAfi_Auth::getInstance()->clearIdentity();
+
+    $user = $this->fixture(Class_Users::class,
+                   ['id' => 98134,
+                    'login' => 'mysuperid',
+                    'nom' => 'James',
+                    'prenom' => 'P.D.',
+                    'password' => '1234',
+                    'civilite' => "1",
+                    'date_naissance' => '2022-12-08']);
+
+    $this->_provider =
+      $this->fixture(Class_IdentityProvider::class,
+                     ['id' => 1,
+                      'label' => 'Médiathèque Deauville',
+                      'type' => 'cas3',
+                      'config' => json_encode
+                      (['url' => 'http://moncompte.server.com/cas-server-v3/',
+                        'auto_create_users' => 1,
+                        'associate_on_login' => 1,
+                        'mapping'  =>
+                        ['nom'  => 'lastname',
+                         'prenom'  => 'firstname',
+                         'mail'  => 'mail',
+                         'id_site' => 'site_code']])]);
+
+    $this->fixture(Class_User_Identity::class,
+                   ['id' => 789,
+                    'user_id' => 98134,
+                    'provider_id' => 1,
+                    'identifier' => 'mysuperid']);
+
+    $response = $this->mock()
+                     ->whenCalled('isError')->answers(false)
+
+                     ->whenCalled('getBody')
+                     ->answers(file_get_contents(__DIR__.'/IdentityProvider/cas3ticket.xml'));
+
+    Class_WebService_Cas3::setWebClient($this->mock()
+                                        ->whenCalled('getResponse')
+                                        ->answers($response));
+
+    Zend_Registry::get('session')->after_login_do = '/recherche/reserver/id/2';
+    Zend_Registry::get('session')->redirect_url = '/recherche/viewnotice/id/2';
+  }
+}
+
+
+
+
+class AuthenticationIntentLoginWithIdentityProviderTest extends AuthenticationIntentLoginWithIdentityProviderTestCase {
+  public function setUp() {
+    parent::setUp();
+
+    $this->dispatch('/auth/login/provider/1?ticket=testticket&redirect=');
+  }
+
+
+  /** @test */
+  public function jamesShouldBeLogged() {
+    $this->assertNotNull(Class_Users::getIdentity());
+  }
+
+
+  /**
+   * @test
+   * @depends jamesShouldBeLogged
+   */
+  public function shouldRedirectToRechercheViewnoticeIdTwo() {
+    $this->assertRedirectTo('/recherche/viewnotice/id/2');
+  }
+
+
+
+  /**
+   * @test
+   * @depends jamesShouldBeLogged
+   */
+  public function sessionShouldNotContainsFlashMessengerPopupRechercheReserver() {
+    $this->assertFlashMessengerContainsPopup('/recherche/reserver/id/2/render/popup');
+ }
+}
+
+
+
+
+class AuthenticationIntentLoginWithIdentityProviderWithRedirectProfileTest extends AuthenticationIntentLoginWithIdentityProviderTestCase {
+  protected $_provider;
+
+  public function setUp() {
+    parent::setUp();
+    $this->fixture(class_Profil::class,
+                   ['id' => 5,
+                    'label' => 'Mon Profil test'
+                   ]);
+
+    $this->_provider->setProfilRedirect(5)->save();
+
+    $this->dispatch('/auth/login/provider/1?ticket=testticket&redirect=');
+  }
+
+
+  /** @test */
+  public function jamesShouldBeLogged() {
+    $this->assertNotNull(Class_Users::getIdentity());
+  }
+
+
+  /**
+   * @test
+   */
+  public function shouldRedirectToRechercheViewnoticeIdTwo() {
+    $this->assertRedirectTo('/recherche/viewnotice/id/2');
+  }
+
+
+
+  /**
+   * @test
+   */
+  public function sessionShouldNotContainsFlashMessengerPopupRechercheReserver() {
+    $this->assertFlashMessengerContainsPopup('/recherche/reserver/id/2/render/popup');
+ }
+}
+
+
+
+
+
+class AuthenticationIntentModulePlanetNemoNotLoggedTest
+  extends AuthenticationIntentWithoutLoginWidgetTestCase {
+
+  public function setUp() {
+    parent::setUp();
+    RessourcesNumeriquesFixtures::activatePlanetNemo();
+    $this->dispatch('/opac/modules/planetnemo');
+  }
+
+
+  /** @test */
+  public function bodyShouldContainsScriptToRedirectToIndexIndexIdProfil3AndRedirectParamToModulesPlanetNemo() {
+    $this->assertXPathContentContains('//script',
+                                      '/index/index/id_profil/3/redirect_url/');
+    $this->assertXPathContentContains('//script',
+                                      '%2Fmodules%2Fplanetnemo');
+  }
+}
+
+
+
+
+
+class AuthenticationIntentModulesArteVodNotLoggedTest extends AuthenticationIntentWithoutLoginWidgetTestCase {
+
+  public function setUp() {
+    parent::setUp();
+    Class_AdminVar::set('ArteVod_SSO_KEY', '123');
+    Class_AdminVar::set('ArteVod_LOGIN', '123');
+
+    $this->dispatch('/opac/modules/arte-vod');
+  }
+
+
+  /** @test */
+  public function shouldRedirectToIndexIndexIdProfil3AndRedirectUrlParamToModulesArteVod() {
+    $this->assertRedirectTo('/index/index/id_profil/3/redirect_url/'.urlencode('http://localhost'. BASE_URL . '/modules/arte-vod'));
+  }
+}
+
+
+
+
+class AuthenticationIntentDispatchAuthSubscribeNewsletterTest extends AuthenticationIntentWithoutLoginWidgetTestCase {
+  public function setUp() {
+    parent::setUp();
+    $this->fixture(Class_Newsletter::class,
+                   ['id' => 35,
+                    'titre' => 'Jeunesse',
+                    'mail_subject' => 'Jeunesse'
+                   ]);
+    $_SERVER['HTTP_REFERER'] = 'http://localhost/vos-acces';
+
+    $this->dispatch('/auth/newsletter-register/id/35');
+  }
+
+
+  public function tearDown(){
+    $_SERVER['HTTP_REFERER']='';
+    parent::tearDown();
+  }
+
+
+  /** @test */
+  public function linkDejaUnCompteShouldBeAuthenticationProfil() {
+    $this->assertXPathContentContains('//a[@href="/index/index/id_profil/3/redirect_url/'
+                                      . urlencode($_SERVER['HTTP_REFERER'])
+                                      . '/after_login_do/'
+                                      . urlencode('/auth/newsletter-register/id/35')
+                                      .'"]'
+                                      , "J'ai déjà un compte"
+    );
+  }
+}
diff --git a/tests/scenarios/DriveCheckOut/DriveCheckoutAdminControllerTest.php b/tests/scenarios/DriveCheckOut/DriveCheckoutAdminControllerTest.php
index 786e3b17a7d0224a6d45295cff65aa772475c5e6..96f2ccda3c4c2fb312120a1cea925282992d2593 100644
--- a/tests/scenarios/DriveCheckOut/DriveCheckoutAdminControllerTest.php
+++ b/tests/scenarios/DriveCheckOut/DriveCheckoutAdminControllerTest.php
@@ -31,6 +31,7 @@ abstract class DriveCheckOutAdminControllerTestCase extends Admin_AbstractContro
     $timesource = new TimeSourceForTest('2020-05-12 10:00:00');
     Admin_DriveCheckoutController::setTimeSource($timesource);
     Class_DriveCheckout_Plan::setTimeSource($timesource);
+    Class_DriveCheckout::setTimeSource($timesource);
     Class_Bib_DriveOpening_Period::setTimeSource($timesource);
 
     Class_AdminVar::set('ENABLE_DRIVE_CHECKOUT', 1);
@@ -178,6 +179,7 @@ abstract class DriveCheckOutAdminControllerTestCase extends Admin_AbstractContro
   public function tearDown() {
     Admin_DriveCheckoutController::setTimeSource(null);
     Class_DriveCheckout_Plan::setTimeSource(null);
+    Class_DriveCheckout::setTimeSource(null);
     Class_Bib_DriveOpening_Period::setTimeSource(null);
     parent::tearDown();
   }
diff --git a/tests/scenarios/PnbDilicom/PnbDilicomDisplayTest.php b/tests/scenarios/PnbDilicom/PnbDilicomDisplayTest.php
index 686b67a3ae3a99a43bddc7005bec40302b0f7bc5..956c7d3500e6ff7d375fb356b02de2d0fcec88df 100644
--- a/tests/scenarios/PnbDilicom/PnbDilicomDisplayTest.php
+++ b/tests/scenarios/PnbDilicom/PnbDilicomDisplayTest.php
@@ -636,7 +636,11 @@ class PnbDilicomDisplayBibNumeriqueControllerAjaxPopupBookActionTest extends Pnb
   public function downloadLinkWithNoConnectedUserShouldRenderLoginPopup() {
     ZendAfi_Auth::getInstance()->clearIdentity();
     $this->postDispatch('bib-numerique/download-loan-book-ajax/id/3', [],true);
-    $this->assertContains('"title":"Authentification"', $this->_response->getBody());
+    $json = json_decode($this->_response->getBody());
+    $local_xpath = new Storm_Test_XPath;
+    $local_xpath->assertXPath($json->content, '//form//input[@name="username"]');
+    $local_xpath->assertXPathContentContains($json->content, '//input[@type="hidden"][@name="redirect"]//@value', '/bib-numerique/download-loan-book-ajax/id/3', $json->content);
+    $this->assertHeaderContains('Location','/bib-numerique/download-loan-book-ajax/id/3');
   }
 }
 
diff --git a/tests/scenarios/PortalBorrowers/PortalBorrowersBatchTest.php b/tests/scenarios/PortalBorrowers/PortalBorrowersBatchTest.php
index cffb11360e326a50169b6f2ad1a0547cbc3ba49d..706cb6950d5b70d86b74649ff97ffb3eae30944d 100644
--- a/tests/scenarios/PortalBorrowers/PortalBorrowersBatchTest.php
+++ b/tests/scenarios/PortalBorrowers/PortalBorrowersBatchTest.php
@@ -152,6 +152,7 @@ class PortalBorrowersBatchEnabledRunTest extends PortalBorrowersActivatedTestCas
 
   public function tearDown() {
     $this->_fixtures->tearDown();
+    parent::tearDown();
   }
 
 
@@ -486,6 +487,7 @@ class PortalBorrowersBatchEnabledRunWithEmptyCSVTest extends PortalBorrowersActi
 
   public function tearDown() {
     $this->_fixtures->tearDown();
+    parent::tearDown();
   }
 
 
diff --git a/tests/scenarios/Templates/TemplatesAdminProfileTest.php b/tests/scenarios/Templates/TemplatesAdminProfileTest.php
index 1da443d7e582e88a8260e3b341d64234b93a4261..5c011f20a476932bcf05b6604e2e3f76d90eb76d 100644
--- a/tests/scenarios/Templates/TemplatesAdminProfileTest.php
+++ b/tests/scenarios/Templates/TemplatesAdminProfileTest.php
@@ -20,8 +20,7 @@
  */
 
 
-class TemplatesDispatchEditProfileTest extends Admin_AbstractControllerTestCase {
-  protected $_storm_default_to_volatile;
+class TemplatesAdminProfileDispatchEditProfileTest extends Admin_AbstractControllerTestCase {
 
   public function setUp() {
     parent::setUp();
@@ -72,7 +71,6 @@ class TemplatesDispatchEditProfileTest extends Admin_AbstractControllerTestCase
 
 
 class TemplatesAdminProfilePostEditTest extends Admin_AbstractControllerTestCase {
-  protected $_storm_default_to_volatile = true;
 
   public function setUp() {
     parent::setUp();
@@ -139,3 +137,314 @@ class TemplatesAdminProfileProprietesTest extends Admin_AbstractControllerTestCa
                                       'des documents de type article de périodique');
   }
 }
+
+
+
+
+
+class TemplatesAdminProfileDispatchAccueilTest extends Admin_AbstractControllerTestCase {
+
+  public function setUp() {
+    parent::setUp();
+    $this->_buildTemplateProfil(['id' => 1,
+                                 'libelle' => 'portail']);
+    $this->dispatch('/admin/profil/accueil/id_profil/1');
+  }
+
+
+  /** @test */
+  public function formShouldContainsSelectIntent() {
+    $this->assertXPath('//form//select[@name="intent"]');
+  }
+
+
+  /** @test */
+  public function formIntentShouldContainsEmptyOption() {
+    $this->assertXPath('//form//select[@name="intent"]/option[@value=""][@label=""]');
+  }
+
+
+  /** @test */
+  public function formIntentShouldContainsAuthActionOption() {
+    $this->assertXPath('//form//select[@name="intent"]/option[@value="' . Class_Profil::INTENT_AUTHENTICATION . '"][@label="page d\'authentification"]');
+  }
+}
+
+
+
+
+class TemplatesAdminProfilePostDispatchAccueilTest extends Admin_AbstractControllerTestCase {
+
+  public function setUp() {
+    parent::setUp();
+    $this->_buildTemplateProfil(['id' => 1,
+                                 'libelle' => 'portail',
+                                 'intent' => '']);
+
+    $this->postDispatch('/admin/profil/accueil/id_profil/1',
+                        ['libelle' => 'portail',
+                         'intent' => Class_Profil::INTENT_AUTHENTICATION]);
+  }
+
+
+  /** @test */
+  public function responseShouldRedirectToProfilAccueilProfileOne() {
+    $this->assertRedirectTo('/admin/profil/accueil/id_profil/1');
+  }
+
+
+  /** @test */
+  public function pageOneIntentShouldBeOne() {
+    $this->assertEquals(Class_Profil::INTENT_AUTHENTICATION, Class_Profil::find(1)->getIntent());
+  }
+}
+
+
+
+
+class TemplatesAdminProfilePostDispatchAccueilFromPageTest extends Admin_AbstractControllerTestCase {
+
+  public function setUp() {
+    parent::setUp();
+    $this->_buildTemplateProfil(['id' => 1,
+                                 'libelle' => 'portail',
+                                 'intent' => '']);
+
+    $this->_buildTemplateProfil(['id' => 2,
+                                 'libelle' => 'auth',
+                                 'parent_id' => 1,
+                                 'intent' => '']);
+
+    $this->postDispatch('/admin/profil/accueil/id_profil/2',
+                        ['libelle' => 'auth',
+                         'intent' => Class_Profil::INTENT_AUTHENTICATION]);
+  }
+
+
+  /** @test */
+  public function responseShouldRedirectToProfilAccueilProfileTwo() {
+    $this->assertRedirectTo('/admin/profil/accueil/id_profil/2');
+  }
+
+
+  /** @test */
+  public function pageOneIntentShouldBeEmpty() {
+    $this->assertEquals('', Class_Profil::find(1)->getIntent());
+  }
+
+
+  /** @test */
+  public function pageTwoIntentShouldBeAuthentication() {
+    $this->assertEquals(Class_Profil::INTENT_AUTHENTICATION, Class_Profil::find(2)->getIntent());
+  }
+}
+
+
+
+
+class TemplatesAdminProfilePostDispatchEditProfilIntentPageTest extends Admin_AbstractControllerTestCase {
+
+  public function setUp() {
+    parent::setUp();
+    $this->_buildTemplateProfil(['id' => 2,
+                                 'libelle' => 'auth',
+                                 'parent_id' => 1,
+                                 'intent' => Class_Profil::INTENT_AUTHENTICATION]);
+
+    $this->postDispatch('/admin/profil/accueil/id_profil/2',
+                        ['libelle' => 'auth',
+                         'intent' => Class_Profil::INTENT_AUTHENTICATION,
+                         'division2' => 'LOGIN-10'
+                        ]);
+  }
+
+
+  /** @test */
+  public function responseShouldRedirectToProfilAccueilProfileTwo() {
+    $this->assertRedirectTo('/admin/profil/accueil/id_profil/2');
+  }
+
+
+  /** @test */
+  public function pagTwoIntentShouldBeClassProfilIntent() {
+    $this->assertEquals(Class_Profil::INTENT_AUTHENTICATION, Class_Profil::find(2)->getIntent());
+  }
+
+
+  /** @test */
+  public function pageTwoIntentShouldBeAuthentication() {
+    $profil = Class_Profil::find(2);
+    $this->assertEquals(["10" => ['division' => '2',
+                                  'type_module' => 'LOGIN',
+                                  'preferences'=> ['id_module' => 10]],
+                         ], Class_Profil::find(2)->getCfgAccueilParam('modules'));
+  }
+}
+
+
+
+
+class TemplatesAdminProfilePostDispatchAccueilWithErrorTest extends Admin_AbstractControllerTestCase {
+
+  public function setUp() {
+    parent::setUp();
+    $this->_buildTemplateProfil(['id' => 1,
+                                 'libelle' => 'portail',
+                                 'intent' => '']);
+
+    $this->_buildTemplateProfil(['id' => 2,
+                                 'libelle' => 'auth',
+                                 'parent_id' => 1,
+                                 'intent' => 'authentication']);
+
+    $this->postDispatch('/admin/profil/accueil/id_profil/1',
+                        ['libelle' => 'portail',
+                         'intent' => 'authentication']);
+  }
+
+
+  /** @test */
+  public function formShouldContainsAuthenticationAlreadySetByProfileAuth() {
+    $this->assertXPathContentContains('//ul[@class="errors"]/li', 'La page auth (id 2) a déjà défini la page d\'authentification');
+  }
+}
+
+
+
+
+
+class TemplatesAdminProfilePostDispatchAccueilIntentOnProfileTest extends Admin_AbstractControllerTestCase {
+
+  public function setUp() {
+    parent::setUp();
+    $this->_buildTemplateProfil(['id' => 1,
+                                 'libelle' => 'portail',
+                                 'intent' => 'authentication']);
+
+    $this->_buildTemplateProfil(['id' => 2,
+                                 'libelle' => 'auth',
+                                 'intent' => '']);
+
+    $this->postDispatch('/admin/profil/accueil/id_profil/2',
+                        ['libelle' => 'auth',
+                         'intent' => 'authentication']);
+  }
+
+
+  /** @test */
+  public function responseShouldRedirectToProfilAccueilProfileTwo() {
+    $this->assertRedirectTo('/admin/profil/accueil/id_profil/2');
+  }
+
+
+  /** @test */
+  public function profileTwoIntentShouldBeAuthentication() {
+    Class_Profil::clearCache();
+    $this->assertEquals('authentication', Class_Profil::find(2)->getIntent());
+  }
+}
+
+
+
+
+class TemplatesAdminProfilePostDispatchAccueilWithParentIntentTest extends Admin_AbstractControllerTestCase {
+
+  public function setUp() {
+    parent::setUp();
+    $this->_buildTemplateProfil(['id' => 1,
+                                 'libelle' => 'portail',
+                                 'intent' => 'authentication']);
+
+    $this->_buildTemplateProfil(['id' => 2,
+                                 'libelle' => 'auth',
+                                 'parent_id' => 1,
+                                 'intent' => '']);
+
+    $this->postDispatch('/admin/profil/accueil/id_profil/2',
+                        ['libelle' => 'auth',
+                         'intent' => 'authentication']);
+  }
+
+
+  /** @test */
+  public function formShouldContainsAuthenticationAlreadySetByProfileAuth() {
+    $this->assertXPathContentContains('//ul[@class="errors"]/li', 'La page portail (id 1) a déjà défini la page d\'authentification');
+  }
+}
+
+
+
+
+class TemplatesAdminProfilePostDispatchAccueilWithMultipleChildrenAndParentsIntentTest extends Admin_AbstractControllerTestCase {
+
+  public function setUp() {
+    parent::setUp();
+    $this->_buildTemplateProfil(['id' => 1,
+                                 'libelle' => 'portail',
+                                 'intent' => '']);
+
+    $this->_buildTemplateProfil(['id' => 2,
+                                 'libelle' => 'auth',
+                                 'parent_id' => 1,
+                                 'intent' => 'authentication']);
+
+    $this->_buildTemplateProfil(['id' => 3,
+                                 'libelle' => 'portail jeunesse',
+                                 'intent' => '']);
+
+    $this->_buildTemplateProfil(['id' => 4,
+                                 'libelle' => 'auth',
+                                 'parent_id' => 3,
+                                 'intent' => '']);
+
+    $this->postDispatch('/admin/profil/accueil/id_profil/4',
+                        ['libelle' => 'auth',
+                         'intent' => 'authentication']);
+  }
+
+
+  /** @test */
+  public function responseShouldRedirectToProfilAccueilProfileFour() {
+    $this->assertRedirectTo('/admin/profil/accueil/id_profil/4');
+  }
+
+
+  /** @test */
+  public function profileFourIntentShouldBeAuthentication() {
+    Class_Profil::clearCache();
+    $this->assertEquals('authentication', Class_Profil::find(4)->getIntent());
+  }
+}
+
+
+
+
+class TemplatesAdminProfileDispatchIndexWithIntentTest extends Admin_AbstractControllerTestCase {
+
+  public function setUp() {
+    parent::setUp();
+    $this->_buildTemplateProfil(['id' => 1,
+                                 'libelle' => 'portail',
+                                 'id_site' => 1,
+                                 'intent' => 'authentication']);
+
+    $this->_buildTemplateProfil(['id' => 2,
+                                 'libelle' => 'portail',
+                                 'id_site' => 1,
+                                 'intent' => '']);
+
+    $this->dispatch('/admin/profil');
+  }
+
+
+  /** @test */
+  public function tableShouldContainsPortailWithAuthenticationIco() {
+    $this->assertXPath('//ul/li/div/a[@href="/admin/profil/accueil/id_profil/1"][contains(text(),"Accueil")]/i[@class="fa fa-user-circle-o"]');
+  }
+
+
+  /** @test */
+  public function tableShouldContainsOnlyOneAuthenticationIco() {
+    $this->assertXPathCount('//i[@class="fa fa-user-circle-o"]', 1);
+  }
+}
diff --git a/tests/scenarios/Templates/TemplatesSearchTest.php b/tests/scenarios/Templates/TemplatesSearchTest.php
index edd3c1b1ca16320c6311ca9485cec3a69399229b..fae2a58909379406aca26b6120d98f603786b984 100644
--- a/tests/scenarios/Templates/TemplatesSearchTest.php
+++ b/tests/scenarios/Templates/TemplatesSearchTest.php
@@ -768,7 +768,6 @@ class TemplatesSearchReservationPickupAjaxTest extends TemplatesSearchWithItemsL
                                  ['tri' => Class_CriteresRecherche::SORT_NOVELTY_DESC,
                                   'IntonationFormStyle' => 'toggle'])
       ->assertSave();
-
     $this->dispatch('/recherche/reservation-pickup-ajax/id/34/id_notice/34/id_int_bib/2/id_bib/23');
 
     $this->_xpath = new Storm_Test_XPath();
@@ -784,7 +783,8 @@ class TemplatesSearchReservationPickupAjaxTest extends TemplatesSearchWithItemsL
 
   /** @test */
   public function loginFormShouldNotBeDropdown() {
-    $this->_xpath->assertNotXPath($this->_html, '//div[@class="dropdown"]');
+    $this->_xpath->assertNotXPath($this->_html,
+                                  '//div[@class="dropdown"]');
   }
 
 }