From d4ddfd9292fcf5cb7973edfebd4dcd20f71a176d Mon Sep 17 00:00:00 2001 From: Stephen Nielson Date: Thu, 9 Feb 2023 14:44:08 -0500 Subject: [PATCH] Fixes #6190 Portal Login Redirect (#6191) * Fixes #6190 Portal Login Redirect This change allows the portal page to redirect to another page other than the SPA home.php file once a user has authenticated. In this initial release we only allow this to go to a module page that exists in the OpenEMR directory. As needed we can open this up to other areas of the application. The redirect param is retained across password changes and the mfa auth that is handled in the portal/index.php. I modified the verify_sessions so that the landingpage param can be updated so the script can be used inside of other pages we want to be protected by the portal session (such as inside a module). * Switch to !empty instead of isset * Portal Login change input type text to be hidden Change the redirect input type from text to be hidden. * Fix the encodeUri and handle reset password Need to pass the redirectUrl for the reset password if the recaptcha is enabled. Also fix the encodeUri escaping on the js. * Fix style problems. --- portal/get_patient_info.php | 17 +++++++++++++++++ portal/index.php | 30 ++++++++++++++++++++++++++---- portal/verify_session.php | 6 +++++- 3 files changed, 48 insertions(+), 5 deletions(-) diff --git a/portal/get_patient_info.php b/portal/get_patient_info.php index e4871c7ee..87d635c80 100644 --- a/portal/get_patient_info.php +++ b/portal/get_patient_info.php @@ -27,6 +27,11 @@ session_regenerate_id(true); $landingpage = "index.php?site=" . urlencode($_SESSION['site_id'] ?? ($_GET['site'] ?? 'default')); // +if (!empty($_REQUEST['redirect'])) { + // let's add the redirect back in case there are any errors or other problems. + $landingpage .= "&redirect=" . urlencode($_REQUEST['redirect']); +} + // checking whether the request comes from index.php if (!isset($_SESSION['itsme'])) { OpenEMR\Common\Session\SessionUtil::portalSessionCookieDestroy(); @@ -279,6 +284,18 @@ if ($userData = sqlQuery($sql, array($auth['pid']))) { // if query gets executed header('Location: ' . $landingpage . '&w'); exit(); } + +// now that we are authorized, we need to check for the redirect, sanitize it (or eliminate it if we can't), and then redirect + +if (!empty($_REQUEST['redirect'])) { + // for now we are only going to allow redirects to locations in the module directories, we can open this up more + // in future requests once we consider the threat vectors + $safeRedirect = \OpenEMR\Core\ModulesApplication::filterSafeLocalModuleFiles([$_REQUEST['redirect']]); + if (!empty($safeRedirect)) { + header('Location: ' . $safeRedirect[0]); + exit(); + } +} header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); header("Cache-Control: no-cache"); header("Pragma: no-cache"); diff --git a/portal/index.php b/portal/index.php index 9baa1ba0b..f5e697d15 100644 --- a/portal/index.php +++ b/portal/index.php @@ -46,6 +46,11 @@ $landingpage = "index.php?site=" . urlencode($_SESSION['site_id']); $logoService = new LogoService(); $logoSrc = $logoService->getLogo("portal/login/primary"); +// allow both get and post redirect params here... everything will be sanitized in get_patient_info.php before we +// actually do anything with the redirect +// this value should already be url encoded. +$redirectUrl = $_REQUEST['redirect'] ?? ''; + //exit if portal is turned off if (!(isset($GLOBALS['portal_onsite_two_enable'])) || !($GLOBALS['portal_onsite_two_enable'])) { echo xlt('Patient Portal is turned off'); @@ -347,6 +352,9 @@ if (!(isset($_SESSION['password_update']) || (!empty($GLOBALS['portal_two_pass_r
+ + +
@@ -395,12 +403,16 @@ if (!(isset($_SESSION['password_update']) || (!empty($GLOBALS['portal_two_pass_r
- +
' /> + + +

@@ -435,7 +447,8 @@ if (!(isset($_SESSION['password_update']) || (!empty($GLOBALS['portal_two_pass_r
- + @@ -444,6 +457,9 @@ if (!(isset($_SESSION['password_update']) || (!empty($GLOBALS['portal_two_pass_r ?> + + +

@@ -504,7 +520,8 @@ if (!(isset($_SESSION['password_update']) || (!empty($GLOBALS['portal_two_pass_r - +
@@ -594,7 +611,12 @@ if (!(isset($_SESSION['password_update']) || (!empty($GLOBALS['portal_two_pass_r data: data }).done(function (rtn) { if (action === "cleanup") { - window.location.href = "./index.php?site=" + ; // Goto landing page. + let url = "./index.php?site=" + ; // Goto landing page. + let redirectUrl = $("#redirect").val(); + if (redirectUrl) { + url += "&redirect=" + encodeURIComponent(redirectUrl); + } + window.location.href = url; } else if (action === "reset_password") { if (JSON.parse(rtn) === 1) { dialog.alert(); diff --git a/portal/verify_session.php b/portal/verify_session.php index 5492b54a0..9c3507a6d 100644 --- a/portal/verify_session.php +++ b/portal/verify_session.php @@ -26,7 +26,11 @@ require_once(__DIR__ . "/../src/Common/Session/SessionUtil.php"); OpenEMR\Common\Session\SessionUtil::portalSessionStart(); //landing page definition -- where to go if something goes wrong -$landingpage = "index.php?site=" . urlencode($_SESSION['site_id'] ?? null); +// if this script is included somewhere else we want to support them changing up the landingpage url such as adding +// parameters, or even setting what the landing page should be for the portal verify session. +if (!isset($landingpage)) { + $landingpage = "index.php?site=" . urlencode($_SESSION['site_id'] ?? null); +} // // kick out if patient not authenticated -- 2.11.4.GIT