updates to make oauth2/api compatible with php8 (#4069)
[openemr.git] / portal / get_patient_info.php
blobb809f2733a33a5adcff8182f278e05eeedad3382
1 <?php
3 /**
4 * portal/get_patient_info.php
6 * @package OpenEMR
7 * @link https://www.open-emr.org
8 * @author Cassian LUP <cassi.lup@gmail.com>
9 * @author Jerry Padgett <sjpadgett@gmail.com>
10 * @author Brady Miller <brady.g.miller@gmail.com>
11 * @copyright Copyright (c) 2011 Cassian LUP <cassi.lup@gmail.com>
12 * @copyright Copyright (c) 2016-2017 Jerry Padgett <sjpadgett@gmail.com>
13 * @copyright Copyright (c) 2019 Brady Miller <brady.g.miller@gmail.com>
14 * @license https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3
17 // starting the PHP session
18 // Will start the (patient) portal OpenEMR session/cookie.
19 require_once(dirname(__FILE__) . "/../src/Common/Session/SessionUtil.php");
20 OpenEMR\Common\Session\SessionUtil::portalSessionStart();
22 // regenerating the session id to avoid session fixation attacks
23 session_regenerate_id(true);
26 // landing page definition -- where to go if something goes wrong
27 $landingpage = "index.php?site=" . urlencode($_SESSION['site_id']);
30 // checking whether the request comes from index.php
31 if (!isset($_SESSION['itsme'])) {
32 OpenEMR\Common\Session\SessionUtil::portalSessionCookieDestroy();
33 header('Location: ' . $landingpage . '&w');
34 exit();
37 // some validation
38 if (!isset($_POST['uname']) || empty($_POST['uname'])) {
39 OpenEMR\Common\Session\SessionUtil::portalSessionCookieDestroy();
40 header('Location: ' . $landingpage . '&w&c');
41 exit();
44 if (!isset($_POST['pass']) || empty($_POST['pass'])) {
45 OpenEMR\Common\Session\SessionUtil::portalSessionCookieDestroy();
46 header('Location: ' . $landingpage . '&w&c');
47 exit();
50 // set the language
51 if (!empty($_POST['languageChoice'])) {
52 $_SESSION['language_choice'] = (int)$_POST['languageChoice'];
53 } elseif (empty($_SESSION['language_choice'])) {
54 // just in case both are empty, then use english
55 $_SESSION['language_choice'] = 1;
56 } else {
57 // keep the current session language token
60 // Settings that will override globals.php
61 $ignoreAuth_onsite_portal = true;
64 // Authentication
65 require_once('../interface/globals.php');
66 require_once(dirname(__FILE__) . "/lib/appsql.class.php");
67 require_once("$srcdir/user.inc");
69 use OpenEMR\Common\Auth\AuthHash;
70 use OpenEMR\Common\Csrf\CsrfUtils;
72 $logit = new ApplicationTable();
73 $password_update = isset($_SESSION['password_update']) ? $_SESSION['password_update'] : 0;
74 unset($_SESSION['password_update']);
76 $authorizedPortal = false; // flag
77 DEFINE("TBL_PAT_ACC_ON", "patient_access_onsite");
78 DEFINE("COL_ID", "id");
79 DEFINE("COL_PID", "pid");
80 DEFINE("COL_POR_PWD", "portal_pwd");
81 DEFINE("COL_POR_USER", "portal_username");
82 DEFINE("COL_POR_LOGINUSER", "portal_login_username");
83 DEFINE("COL_POR_PWD_STAT", "portal_pwd_status");
84 DEFINE("COL_POR_ONETIME", "portal_onetime");
86 // 2 is flag for one time credential reset else 1 = normal reset.
87 // one time reset requires a PIN where normal uses a new temp pass sent to user.
88 if ($password_update === 2 && !empty($_SESSION['pin'])) {
89 $sql = "SELECT " . implode(",", array(
90 COL_ID, COL_PID, COL_POR_PWD, COL_POR_USER, COL_POR_LOGINUSER, COL_POR_PWD_STAT, COL_POR_ONETIME)) . " FROM " . TBL_PAT_ACC_ON .
91 " WHERE BINARY " . COL_POR_ONETIME . "= ?";
92 $auth = privQuery($sql, array($_SESSION['forward']));
93 if ($auth !== false) {
94 // remove the token from database
95 privStatement("UPDATE " . TBL_PAT_ACC_ON . " SET " . COL_POR_ONETIME . "=NULL WHERE BINARY " . COL_POR_ONETIME . " = ?", [$auth['portal_onetime']]);
96 // validation
97 $validate = substr($auth[COL_POR_ONETIME], 32, 6);
98 if (!empty($validate) && !empty($_POST['token_pin'])) {
99 if ($_SESSION['pin'] !== $_POST['token_pin']) {
100 $auth = false;
101 } elseif ($validate !== $_POST['token_pin']) {
102 $auth = false;
104 } else {
105 $auth = false;
107 unset($_SESSION['forward']);
108 unset($_SESSION['pin']);
109 unset($_POST['token_pin']);
111 } else {
112 // normal login
113 $sql = "SELECT " . implode(",", array(
114 COL_ID, COL_PID, COL_POR_PWD, COL_POR_USER, COL_POR_LOGINUSER, COL_POR_PWD_STAT)) . " FROM " . TBL_PAT_ACC_ON .
115 " WHERE " . COL_POR_LOGINUSER . "= ?";
116 if ($password_update === 1) {
117 $sql = "SELECT " . implode(",", array(
118 COL_ID, COL_PID, COL_POR_PWD, COL_POR_USER, COL_POR_LOGINUSER, COL_POR_PWD_STAT)) . " FROM " . TBL_PAT_ACC_ON .
119 " WHERE " . COL_POR_USER . "= ?";
122 $auth = privQuery($sql, array($_POST['uname']));
124 if ($auth === false) {
125 $logit->portalLog('login attempt', '', ($_POST['uname'] . ':invalid username'), '', '0');
126 OpenEMR\Common\Session\SessionUtil::portalSessionCookieDestroy();
127 header('Location: ' . $landingpage . '&w&u');
128 exit();
131 if ($password_update === 2) {
132 if ($_POST['pass'] != $auth[COL_POR_PWD]) {
133 $logit->portalLog('login attempt', '', ($_POST['uname'] . ':invalid password'), '', '0');
134 OpenEMR\Common\Session\SessionUtil::portalSessionCookieDestroy();
135 header('Location: ' . $landingpage . '&w&p');
136 exit();
138 } else {
139 if (AuthHash::passwordVerify($_POST['pass'], $auth[COL_POR_PWD])) {
140 $authHashPortal = new AuthHash('auth');
141 if ($authHashPortal->passwordNeedsRehash($auth[COL_POR_PWD])) {
142 // If so, create a new hash, and replace the old one (this will ensure always using most modern hashing)
143 $reHash = $authHashPortal->passwordHash($_POST['pass']);
144 if (empty($reHash)) {
145 // Something is seriously wrong
146 error_log('OpenEMR Error : OpenEMR is not working because unable to create a hash.');
147 die("OpenEMR Error : OpenEMR is not working because unable to create a hash.");
149 privStatement(
150 "UPDATE " . TBL_PAT_ACC_ON . " SET " . COL_POR_PWD . " = ? WHERE " . COL_ID . " = ?",
152 $reHash,
153 $auth[COL_ID]
157 } else {
158 $logit->portalLog('login attempt', '', ($_POST['uname'] . ':invalid password'), '', '0');
159 OpenEMR\Common\Session\SessionUtil::portalSessionCookieDestroy();
160 header('Location: ' . $landingpage . '&w&p');
161 exit();
167 $_SESSION['portal_username'] = $auth[COL_POR_USER];
168 $_SESSION['portal_login_username'] = $auth[COL_POR_LOGINUSER];
170 $sql = "SELECT * FROM `patient_data` WHERE `pid` = ?";
172 if ($userData = sqlQuery($sql, array($auth['pid']))) { // if query gets executed
173 if (empty($userData)) {
174 $logit->portalLog('login attempt', '', ($_POST['uname'] . ':not active patient'), '', '0');
175 OpenEMR\Common\Session\SessionUtil::portalSessionCookieDestroy();
176 header('Location: ' . $landingpage . '&w');
177 exit();
180 if ($userData['email'] != $_POST['passaddon'] && $GLOBALS['enforce_signin_email']) {
181 $logit->portalLog('login attempt', '', ($_POST['uname'] . ':invalid email'), '', '0');
182 OpenEMR\Common\Session\SessionUtil::portalSessionCookieDestroy();
183 header('Location: ' . $landingpage . '&w');
184 exit();
187 if ($userData['allow_patient_portal'] != "YES") {
188 // Patient has not authorized portal, so escape
189 $logit->portalLog('login attempt', '', ($_POST['uname'] . ':allow portal turned off'), '', '0');
190 OpenEMR\Common\Session\SessionUtil::portalSessionCookieDestroy();
191 header('Location: ' . $landingpage . '&w');
192 exit();
195 if ($auth['pid'] != $userData['pid']) {
196 // Not sure if this is even possible, but should escape if this happens
197 OpenEMR\Common\Session\SessionUtil::portalSessionCookieDestroy();
198 header('Location: ' . $landingpage . '&w');
199 exit();
202 if ($password_update) {
203 $code_new = $_POST['pass_new'];
204 $code_new_confirm = $_POST['pass_new_confirm'];
205 if (!(empty($_POST['pass_new'])) && !(empty($_POST['pass_new_confirm'])) && ($code_new == $code_new_confirm)) {
206 $new_hash = (new AuthHash('auth'))->passwordHash($code_new);
207 if (empty($new_hash)) {
208 // Something is seriously wrong
209 error_log('OpenEMR Error : OpenEMR is not working because unable to create a hash.');
210 die("OpenEMR Error : OpenEMR is not working because unable to create a hash.");
212 // Update the password and continue (patient is authorized)
213 privStatement(
214 "UPDATE " . TBL_PAT_ACC_ON . " SET " . COL_POR_LOGINUSER . "=?," . COL_POR_PWD . "=?," . COL_POR_PWD_STAT . "=1 WHERE id=?",
215 array(
216 $_POST['login_uname'],
217 $new_hash,
218 $auth['id']
221 $authorizedPortal = true;
222 $logit->portalLog('password update', $auth['pid'], ($_POST['login_uname'] . ': ' . $_SESSION['ptName'] . ':success'));
226 if ($auth['portal_pwd_status'] == 0) {
227 if (!$authorizedPortal) {
228 // Need to enter a new password in the index.php script
229 $_SESSION['password_update'] = 1;
230 header('Location: ' . $landingpage);
231 exit();
235 if ($auth['portal_pwd_status'] == 1) {
236 // continue (patient is authorized)
237 $authorizedPortal = true;
240 if ($authorizedPortal) {
241 // patient is authorized (prepare the session variables)
242 unset($_SESSION['password_update']); // just being safe
243 unset($_SESSION['itsme']); // just being safe
244 $_SESSION['pid'] = $auth['pid'];
245 $_SESSION['patient_portal_onsite_two'] = 1;
247 $tmp = getUserIDInfo($userData['providerID']);
248 $_SESSION['providerName'] = $tmp['fname'] . ' ' . $tmp['lname'];
249 $_SESSION['providerUName'] = $tmp['username'];
250 $_SESSION['sessionUser'] = '-patient-'; // $_POST['uname'];
251 $_SESSION['providerId'] = $userData['providerID'] ? $userData['providerID'] : 'undefined';
252 $_SESSION['ptName'] = $userData['fname'] . ' ' . $userData['lname'];
253 // never set authUserID though authUser is used for ACL!
254 $_SESSION['authUser'] = 'portal-user';
255 // Set up the csrf private_key (for the paient portal)
256 // Note this key always remains private and never leaves server session. It is used to create
257 // the csrf tokens.
258 CsrfUtils::setupCsrfKey();
260 $logit->portalLog('login', $_SESSION['pid'], ($_SESSION['portal_username'] . ': ' . $_SESSION['ptName'] . ':success'));
261 } else {
262 $logit->portalLog('login', '', ($_POST['uname'] . ':not authorized'), '', '0');
263 OpenEMR\Common\Session\SessionUtil::portalSessionCookieDestroy();
264 header('Location: ' . $landingpage . '&w');
265 exit();
267 } else { // problem with query
268 OpenEMR\Common\Session\SessionUtil::portalSessionCookieDestroy();
269 header('Location: ' . $landingpage . '&w');
270 exit();
272 header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
273 header("Cache-Control: no-cache");
274 header("Pragma: no-cache");
275 header('Location: ./home.php');
276 exit();