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 * @author Tyler Wrenn <tyler@tylerwrenn.com>
12 * @copyright Copyright (c) 2011 Cassian LUP <cassi.lup@gmail.com>
13 * @copyright Copyright (c) 2016-2022 Jerry Padgett <sjpadgett@gmail.com>
14 * @copyright Copyright (c) 2019 Brady Miller <brady.g.miller@gmail.com>
15 * @copyright Copyright (c) 2020 Tyler Wrenn <tyler@tylerwrenn.com>
16 * @license https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3
19 //setting the session & other config options
21 // Will start the (patient) portal OpenEMR session/cookie.
22 require_once __DIR__
. "/../src/Common/Session/SessionUtil.php";
23 OpenEMR\Common\Session\SessionUtil
::portalSessionStart();
25 //don't require standard openemr authorization in globals.php
26 $ignoreAuth_onsite_portal = true;
29 require_once '../interface/globals.php';
30 require_once __DIR__
. "/lib/appsql.class.php";
31 $logit = new ApplicationTable();
33 use OpenEMR\Common\Crypto\CryptoGen
;
34 use OpenEMR\Common\Csrf\CsrfUtils
;
35 use OpenEMR\Common\Logging\EventAuditLogger
;
36 use OpenEMR\Common\Logging\SystemLogger
;
37 use OpenEMR\Core\Header
;
39 //For redirect if the site on session does not match
40 $landingpage = "index.php?site=" . urlencode($_SESSION['site_id']);
42 //exit if portal is turned off
43 if (!(isset($GLOBALS['portal_onsite_two_enable'])) ||
!($GLOBALS['portal_onsite_two_enable'])) {
44 echo xlt('Patient Portal is turned off');
47 $auth['portal_pwd'] = '';
48 if (isset($_GET['woops'])) {
49 unset($_GET['woops']);
50 unset($_SESSION['password_update']);
53 if (!empty($_GET['forward_email_verify'])) {
54 if (empty($GLOBALS['portal_onsite_two_register']) ||
empty($GLOBALS['google_recaptcha_site_key']) ||
empty($GLOBALS['google_recaptcha_secret_key'])) {
55 (new SystemLogger())->debug("registration not supported, so stopped attempt to use forward_email_verify token");
56 OpenEMR\Common\Session\SessionUtil
::portalSessionCookieDestroy();
57 header('Location: ' . $landingpage . '&w&u');
61 $crypto = new CryptoGen();
62 if (!$crypto->cryptCheckStandard($_GET['forward_email_verify'])) {
63 (new SystemLogger())->debug("illegal token, so stopped attempt to use forward_email_verify token");
64 OpenEMR\Common\Session\SessionUtil
::portalSessionCookieDestroy();
65 header('Location: ' . $landingpage . '&w&u');
69 $token_one_time = $crypto->decryptStandard($_GET['forward_email_verify'], null, 'drive', 6);
70 if (empty($token_one_time)) {
71 (new SystemLogger())->debug("unable to decrypt token, so stopped attempt to use forward_email_verify token");
72 OpenEMR\Common\Session\SessionUtil
::portalSessionCookieDestroy();
73 header('Location: ' . $landingpage . '&w&u');
77 $sqlResource = sqlStatementNoLog("SELECT `id`, `token_onetime`, `fname`, `mname`, `lname`, `dob`, `email`, `language` FROM `verify_email` WHERE `active` = 1 AND `token_onetime` LIKE BINARY ?", [$token_one_time . '%']);
78 if (sqlNumRows($sqlResource) > 1) {
79 (new SystemLogger())->debug("active token (" . $token_one_time . ") found more than once, so stopped attempt to use forward_email_verify token");
80 EventAuditLogger
::instance()->newEvent('patient-reg-email-verify', '', '', 0, "active token (" . $token_one_time . ") found more than once, so stopped attempt to use forward_email_verify token");
81 OpenEMR\Common\Session\SessionUtil
::portalSessionCookieDestroy();
82 header('Location: ' . $landingpage . '&w&u');
85 if (!sqlNumRows($sqlResource)) {
86 (new SystemLogger())->debug("active token (" . $token_one_time . ") not found, so stopped attempt to use forward_email_verify token");
87 EventAuditLogger
::instance()->newEvent('patient-reg-email-verify', '', '', 0, "active token (" . $token_one_time . ") not found, so stopped attempt to use forward_email_verify token");
88 OpenEMR\Common\Session\SessionUtil
::portalSessionCookieDestroy();
89 header('Location: ' . $landingpage . '&w&u');
92 $sqlVerify = sqlFetchArray($sqlResource);
93 if (empty($sqlVerify['id']) ||
empty($sqlVerify['token_onetime'])) {
94 (new SystemLogger())->debug("active token (" . $token_one_time . ") not properly set up, so stopped attempt to use forward_email_verify token");
95 EventAuditLogger
::instance()->newEvent('patient-reg-email-verify', '', '', 0, "active token (" . $token_one_time . ") not properly set up, so stopped attempt to use forward_email_verify token");
96 OpenEMR\Common\Session\SessionUtil
::portalSessionCookieDestroy();
97 header('Location: ' . $landingpage . '&w&u');
100 // have "used" token, so now make it inactive
101 sqlStatementNoLog("UPDATE `verify_email` SET `active` = 0 WHERE `id` = ?", [$sqlVerify['id']]);
103 $validateTime = hex2bin(str_replace($token_one_time, '', $sqlVerify['token_onetime']));
104 if ($validateTime <= time()) {
105 (new SystemLogger())->debug("active token (" . $token_one_time . ") has expired, so stopped attempt to use forward_email_verify token");
106 EventAuditLogger
::instance()->newEvent('patient-reg-email-verify', '', '', 0, "active token (" . $token_one_time . ") has expired, so stopped attempt to use forward_email_verify token");
107 OpenEMR\Common\Session\SessionUtil
::portalSessionCookieDestroy();
108 die(xlt("Your email verification link has expired. Reset and try again."));
111 if (!empty($sqlVerify['fname']) && !empty($sqlVerify['lname']) && !empty($sqlVerify['dob']) && !empty($sqlVerify['email']) && !empty($sqlVerify['language'])) {
112 // token has passed and have all needed data
113 $fnameRegistration = $sqlVerify['fname'];
114 $_SESSION['fnameRegistration'] = $fnameRegistration;
115 $mnameRegistration = $sqlVerify['mname'] ??
'';
116 $_SESSION['mnameRegistration'] = $mnameRegistration;
117 $lnameRegistration = $sqlVerify['lname'];
118 $_SESSION['lnameRegistration'] = $lnameRegistration;
119 $dobRegistration = $sqlVerify['dob'];
120 $_SESSION['dobRegistration'] = $dobRegistration;
121 $emailRegistration = $sqlVerify['email'];
122 $_SESSION['emailRegistration'] = $emailRegistration;
123 $languageRegistration = $sqlVerify['language'];
124 $_SESSION['language_choice'] = (int)($languageRegistration ??
1);
125 $portalRegistrationAuthorization = true;
126 $_SESSION['token_id_holder'] = $sqlVerify['id'];
127 (new SystemLogger())->debug("token worked for forward_email_verify token, now on to registration");
128 EventAuditLogger
::instance()->newEvent('patient-reg-email-verify', '', '', 1, "token (" . $token_one_time . ") was successful for forward_email_verify token");
129 require_once(__DIR__
. "/account/register.php");
132 (new SystemLogger())->debug("active token (" . $token_one_time . ") did not have all required data, so stopped attempt to use forward_email_verify token");
133 EventAuditLogger
::instance()->newEvent('patient-reg-email-verify', '', '', 0, "active token (" . $token_one_time . ") did not have all required data, so stopped attempt to use forward_email_verify token");
134 OpenEMR\Common\Session\SessionUtil
::portalSessionCookieDestroy();
135 header('Location: ' . $landingpage . '&w&u');
138 } else if (isset($_GET['forward'])) {
139 if ((empty($GLOBALS['portal_two_pass_reset']) && empty($GLOBALS['portal_onsite_two_register'])) ||
empty($GLOBALS['google_recaptcha_site_key']) ||
empty($GLOBALS['google_recaptcha_secret_key'])) {
140 (new SystemLogger())->debug("reset password and registration not supported, so stopped attempt to use forward token");
141 OpenEMR\Common\Session\SessionUtil
::portalSessionCookieDestroy();
142 header('Location: ' . $landingpage . '&w&u');
146 if (strlen($_GET['forward']) >= 64) {
147 $crypto = new CryptoGen();
148 if ($crypto->cryptCheckStandard($_GET['forward'])) {
149 $one_time = $crypto->decryptStandard($_GET['forward'], null, 'drive', 6);
150 if (!empty($one_time)) {
151 $auth = sqlQueryNoLog("Select * From patient_access_onsite Where portal_onetime Like BINARY ?", array($one_time . '%'));
155 if ($auth === false) {
156 error_log("PORTAL ERROR: " . errorLogEscape('One time reset:' . $_GET['forward']), 0);
157 $logit->portalLog('login attempt', '', ($_GET['forward'] . ':invalid one time'), '', '0');
158 OpenEMR\Common\Session\SessionUtil
::portalSessionCookieDestroy();
159 header('Location: ' . $landingpage . '&w&u');
162 $parse = str_replace($one_time, '', $auth['portal_onetime']);
163 $validate = hex2bin(substr($parse, 6));
164 if ($validate <= time()) {
165 error_log("PORTAL ERROR: " . errorLogEscape('One time reset link expired. Dying.'), 0);
166 $logit->portalLog('password reset attempt', '', ($_POST['uname'] . ':link expired'), '', '0');
167 OpenEMR\Common\Session\SessionUtil
::portalSessionCookieDestroy();
168 die(xlt("Your one time credential reset link has expired. Reset and try again.") . "time:$validate time:" . time());
170 $_SESSION['pin'] = substr($parse, 0, 6);
171 $_SESSION['forward'] = $auth['portal_onetime'];
172 $_SESSION['portal_username'] = $auth['portal_username'];
173 $_SESSION['portal_login_username'] = $auth['portal_login_username'];
174 $_SESSION['password_update'] = 2;
175 $_SESSION['onetime'] = $auth['portal_pwd'];
178 // security measure -- will check on next page.
179 $_SESSION['itsme'] = 1;
183 // Deal with language selection
185 // collect default language id (skip this if this is a password update or reset)
186 if (!(isset($_SESSION['password_update']) ||
(!empty($GLOBALS['portal_two_pass_reset']) && !empty($GLOBALS['google_recaptcha_site_key']) && !empty($GLOBALS['google_recaptcha_secret_key']) && isset($_GET['requestNew'])))) {
187 $res2 = sqlStatement("select * from lang_languages where lang_description = ?", array($GLOBALS['language_default']));
188 for ($iter = 0; $row = sqlFetchArray($res2); $iter++
) {
189 $result2[$iter] = $row;
192 if (count($result2) == 1) {
193 $defaultLangID = $result2[0]["lang_id"];
194 $defaultLangName = $result2[0]["lang_description"];
196 //default to english if any problems
198 $defaultLangName = "English";
201 // set session variable to default so login information appears in default language
202 $_SESSION['language_choice'] = $defaultLangID;
203 // collect languages if showing language menu
204 if ($GLOBALS['language_menu_login']) {
205 // sorting order of language titles depends on language translation options.
206 $mainLangID = empty($_SESSION['language_choice']) ?
'1' : $_SESSION['language_choice'];
207 // Use and sort by the translated language name.
208 $sql = "SELECT ll.lang_id, " .
209 "IF(LENGTH(ld.definition),ld.definition,ll.lang_description) AS trans_lang_description, " .
210 "ll.lang_description " .
211 "FROM lang_languages AS ll " .
212 "LEFT JOIN lang_constants AS lc ON lc.constant_name = ll.lang_description " .
213 "LEFT JOIN lang_definitions AS ld ON ld.cons_id = lc.cons_id AND " .
215 "ORDER BY IF(LENGTH(ld.definition),ld.definition,ll.lang_description), ll.lang_id";
216 $res3 = SqlStatement($sql, array($mainLangID));
217 for ($iter = 0; $row = sqlFetchArray($res3); $iter++
) {
218 $result3[$iter] = $row;
220 if (count($result3) == 1) {
221 //default to english if only return one language
222 $hiddenLanguageField = "<input type='hidden' name='languageChoice' value='1' />\n";
225 $hiddenLanguageField = "<input type='hidden' name='languageChoice' value='" . attr($defaultLangID) . "' />\n";
232 <title
><?php
echo xlt('Patient Portal Login'); ?
></title
>
234 Header
::setupHeader(['no_main-theme', 'datetime-picker', 'patientportal-style', 'patientportal-base', 'patientportal-register']);
237 function checkUserName() {
238 let vacct
= document
.getElementById('uname').value
;
239 let vsuname
= document
.getElementById('login_uname').value
;
240 if (vsuname
.length
< 12) {
241 alert(<?php
echo xlj('User Name must be at least 12 characters!'); ?
>);
245 'action': 'userIsUnique',
247 'loginUname': vsuname
251 url
: './account/account.php',
253 }).done(function (rtn
) {
257 alert(<?php
echo xlj('Log In Name is unavailable. Try again!'); ?
>);
264 alert(<?php
echo xlj('Field(s) are missing!'); ?
>);
270 function validate() {
273 if (document
.getElementById('uname').value
== "") {
274 $
('#uname').addClass('is-invalid');
277 if (document
.getElementById('pass').value
== "") {
278 $
('#pass').addClass('is-invalid');
284 function process_new_pass() {
285 if (!(validate_new_pass())) {
286 alert(<?php
echo xlj('Field(s) are missing!'); ?
>);
289 if (document
.getElementById('pass_new').value
!= document
.getElementById('pass_new_confirm').value
) {
290 alert(<?php
echo xlj('The new password fields are not the same.'); ?
>);
293 if (document
.getElementById('pass').value
== document
.getElementById('pass_new').value
) {
294 alert(<?php
echo xlj('The new password can not be the same as the current password.'); ?
>);
299 function validate_new_pass() {
301 if (document
.getElementById('uname').value
== "") {
302 $
('#uname').addClass('is-invalid');
305 if (document
.getElementById('pass').value
== "") {
306 $
('#pass').addClass('is-invalid');
309 if (document
.getElementById('pass_new').value
== "") {
310 $
('#pass_new').addClass('is-invalid');
313 if (document
.getElementById('pass_new_confirm').value
== "") {
314 $
('#pass_new_confirm').addClass('is-invalid');
321 <?php
if (!empty($GLOBALS['portal_two_pass_reset']) && !empty($GLOBALS['google_recaptcha_site_key']) && !empty($GLOBALS['google_recaptcha_secret_key']) && isset($_GET['requestNew'])) { ?
>
322 <script src
="https://www.google.com/recaptcha/api.js" async defer
></script
>
324 function enableVerifyBtn(){
325 document
.getElementById("submitRequest").disabled
= false;
328 <?php
// add csrf mechanism for the password reset ui
329 CsrfUtils
::setupCsrfKey();
334 <body
class="login container mt-2">
335 <div id
="wrapper" class="container-fluid text-center">
336 <?php
if (isset($_SESSION['password_update']) ||
isset($_GET['password_update'])) {
337 $_SESSION['password_update'] = 1;
339 <h2
class="title"><?php
echo xlt('Please Enter New Credentials'); ?
></h2
>
340 <form
class="form pb-5" action
="get_patient_info.php" method
="POST" onsubmit
="return process_new_pass()">
341 <input style
="display: none" type
="text" name
="dummyuname" />
342 <input style
="display: none" type
="password" name
="dummypass" />
343 <div
class="form-row my-3">
344 <label
class="col-md-2 col-form-label" for="uname"><?php
echo xlt('Account Name'); ?
></label
>
346 <input
class="form-control" name
="uname" id
="uname" type
="text" readonly autocomplete
="none" value
="<?php echo attr($_SESSION['portal_username']); ?>" />
349 <div
class="form-row my-3">
350 <label
class="col-md-2 col-form-label" for="login_uname"><?php
echo xlt('Use Username'); ?
></label
>
352 <input
class="form-control" name
="login_uname" id
="login_uname" type
="text" autofocus autocomplete
="none" title
="<?php echo xla('Please enter a username of 12 to 80 characters. Recommended to include symbols and numbers but not required.'); ?>" placeholder
="<?php echo xla('Must be 12 to 80 characters'); ?>" pattern
=".{12,80}" value
="<?php echo attr($_SESSION['portal_login_username']); ?>" onblur
="checkUserName()" />
355 <div
class="form-row my-3">
356 <label
class="col-md-2 col-form-label" for="pass"><?php
echo !$_SESSION['onetime'] ?
xlt('Current Password') : ''; ?
></label
>
358 <input
class="form-control" name
="pass" id
="pass" <?php
echo $_SESSION['onetime'] ?
'type="hidden" ' : 'type="password" '; ?
> autocomplete
="none" value
="<?php echo attr($_SESSION['onetime']);
359 $_SESSION['password_update'] = $_SESSION['onetime'] ? 2 : 1;
360 unset($_SESSION['onetime']); ?>" required
/>
363 <?php
if ($_SESSION['pin']) { ?
>
364 <div
class="form-row my-3">
365 <label
class="col-md-2 col-form-label" for="token_pin"><?php
echo xlt('One Time PIN'); ?
></label
>
367 <input
class="form-control" name
="token_pin" id
="token_pin" type
="password" autocomplete
="none" value
="" required pattern
=".{6,20}" />
371 <div
class="form-row my-3">
372 <label
class="col-md-2 col-form-label" for="pass_new"><?php
echo xlt('New Password'); ?
></label
>
374 <input
class="form-control" name
="pass_new" id
="pass_new" type
="password" required placeholder
="<?php echo xla('Min length is 8 with upper,lowercase,numbers mix'); ?>" pattern
="(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}" />
377 <div
class="form-row my-3">
378 <label
class="col-md-2 col-form-label" for="pass_new_confirm"><?php
echo xlt('Confirm New Password'); ?
></label
>
380 <input
class="form-control" name
="pass_new_confirm" id
="pass_new_confirm" type
="password" required pattern
="(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}" />
383 <?php
if ($GLOBALS['enforce_signin_email']) { ?
>
384 <div
class="form-row my-3">
385 <label
class="col-md-2 col-form-label" for="passaddon"><?php
echo xlt('Confirm Email Address'); ?
></label
>
387 <input
class="form-control" name
="passaddon" id
="passaddon" required placeholder
="<?php echo xla('Current on record trusted email'); ?>" type
="email" autocomplete
="none" value
="" />
391 <input
class="btn btn-secondary float-left" type
="button" onclick
="document.location.replace('./index.php?woops=1&site=<?php echo attr_url($_SESSION['site_id']); ?>');" value
="<?php echo xla('Cancel'); ?>" />
392 <input
class="btn btn-primary float-right" type
="submit" value
="<?php echo xla('Log In'); ?>" />
394 <?php
} elseif (!empty($GLOBALS['portal_two_pass_reset']) && !empty($GLOBALS['google_recaptcha_site_key']) && !empty($GLOBALS['google_recaptcha_secret_key']) && isset($_GET['requestNew'])) { ?
>
395 <form id
="resetPass" action
="#" method
="post">
396 <input type
='hidden' id
='csrf_token_form' name
='csrf_token_form' value
='<?php echo attr(CsrfUtils::collectCsrfToken('passwordResetCsrf
')); ?>' />
397 <div
class="text-center">
399 <legend
class='bg-primary text-white pt-2 py-1'><h3
><?php
echo xlt('Patient Credentials Reset') ?
></h3
></legend
>
400 <div
class="jumbotron jumbotron-fluid px-5 py-3">
401 <div
class="form-row my-3">
402 <label
class="col-md-2 col-form-label" for="fname"><?php
echo xlt('First Name') ?
></label
>
404 <input type
="text" class="form-control" id
="fname" required placeholder
="<?php echo xla('First Name'); ?>" />
407 <div
class="form-row my-3">
408 <label
class="col-md-2 col-form-label" for="lname"><?php
echo xlt('Last Name') ?
></label
>
410 <input type
="text" class="form-control" id
="lname" required placeholder
="<?php echo xla('Last Name'); ?>" />
413 <div
class="form-row my-3">
414 <label
class="col-md-2 col-form-label" for="dob"><?php
echo xlt('Birth Date') ?
></label
>
416 <input id
="dob" type
="text" required
class="form-control datepicker" placeholder
="<?php echo xla('YYYY-MM-DD'); ?>" />
419 <div
class="form-row my-3">
420 <label
class="col-md-2 col-form-label" for="emailInput"><?php
echo xlt('Enter E-Mail Address') ?
></label
>
422 <input id
="emailInput" type
="email" class="form-control" required placeholder
="<?php echo xla('Current trusted email address on record.'); ?>" maxlength
="100" />
426 <div
class="form-group">
427 <div
class="d-flex justify-content-center">
428 <div
class="g-recaptcha" data
-sitekey
="<?php echo attr($GLOBALS['google_recaptcha_site_key']); ?>" data
-callback
="enableVerifyBtn"></div
>
431 <input
class="btn btn-secondary float-left" type
="button" onclick
="document.location.replace('./index.php?woops=1&site=<?php echo attr_url($_SESSION['site_id']); ?>');" value
="<?php echo xla('Cancel'); ?>" />
432 <button id
="submitRequest" class="btn btn-primary nextBtn float-right" type
="submit" disabled
="disabled"><?php
echo xlt('Verify') ?
></button
>
437 ?
> <!-- Main logon
-->
438 <img
class="img-responsive center-block login-image" src
='<?php echo $GLOBALS['images_static_relative
']; ?>/login-logo.png' />
439 <form
class="text-center" action
="get_patient_info.php" method
="POST" onsubmit
="return process()">
441 <legend
class="bg-primary text-white pt-2 py-1"><h3
><?php
echo xlt('Patient Portal Login'); ?
></h3
></legend
>
442 <div
class="jumbotron jumbotron-fluid px-5 py-3">
443 <div
class="form-row my-3">
444 <label
class="col-md-2 col-form-label" for="uname"><?php
echo xlt('Username') ?
></label
>
446 <input type
="text" class="form-control" name
="uname" id
="uname" autocomplete
="none" required
/>
449 <div
class="form-row mt-3">
450 <label
class="col-md-2 col-form-label" for="pass"><?php
echo xlt('Password') ?
></label
>
452 <input
class="form-control" name
="pass" id
="pass" type
="password" required autocomplete
="none" />
455 <?php
if ($GLOBALS['enforce_signin_email']) { ?
>
456 <div
class="form-row mt-3">
457 <label
class="col-md-2 col-form-label" for="passaddon"><?php
echo xlt('E-Mail Address') ?
></label
>
459 <input
class="form-control" name
="passaddon" id
="passaddon" type
="email" autocomplete
="none" />
463 <?php
if ($GLOBALS['language_menu_login']) { ?
>
464 <?php
if (count($result3) != 1) { ?
>
465 <div
class="form-group mt-1">
466 <label
class="col-form-label-sm" for="selLanguage"><?php
echo xlt('Language'); ?
></label
>
467 <select
class="form-control form-control-sm" id
="selLanguage" name
="languageChoice">
469 echo "<option selected='selected' value='" . attr($defaultLangID) . "'>" .
470 text(xl('Default') . " - " . xl($defaultLangName)) . "</option>\n";
471 foreach ($result3 as $iter) {
472 if ($GLOBALS['language_menu_showall']) {
473 if (!$GLOBALS['allow_debug_language'] && $iter['lang_description'] == 'dummy') {
474 continue; // skip the dummy language
476 echo "<option value='" . attr($iter['lang_id']) . "'>" .
477 text($iter['trans_lang_description']) . "</option>\n";
479 if (in_array($iter['lang_description'], $GLOBALS['language_menu_show'])) {
480 if (!$GLOBALS['allow_debug_language'] && $iter['lang_description'] == 'dummy') {
481 continue; // skip the dummy language
483 echo "<option value='" . attr($iter['lang_id']) . "'>" .
484 text($iter['trans_lang_description']) . "</option>\n";
496 <?php
if (!empty($GLOBALS['portal_onsite_two_register']) && !empty($GLOBALS['google_recaptcha_site_key']) && !empty($GLOBALS['google_recaptcha_secret_key'])) { ?
>
497 <button
class="btn btn-secondary float-left" onclick
="location.replace('./account/verify.php?site=<?php echo attr_url($_SESSION['site_id']); ?>')"><?php
echo xlt('Register'); ?
></button
>
499 <?php
if (!empty($GLOBALS['portal_two_pass_reset']) && !empty($GLOBALS['google_recaptcha_site_key']) && !empty($GLOBALS['google_recaptcha_secret_key']) && isset($_GET['w']) && (isset($_GET['u']) ||
isset($_GET['p']))) { ?
>
500 <button
class="btn btn-danger ml-2" onclick
="location.replace('./index.php?requestNew=1&site=<?php echo attr_url($_SESSION['site_id']); ?>')"><?php
echo xlt('Reset Credentials'); ?
></button
>
502 <button
class="btn btn-success float-right" type
="submit"><?php
echo xlt('Log In'); ?
></button
>
506 <?php
if (!(empty($hiddenLanguageField))) {
507 echo $hiddenLanguageField;
510 </div
><!-- div wrapper
-->
511 <?php
} ?
> <!-- logon wrapper
-->
513 <div id
="alertStore" class="d-none">
514 <div
class="h6 alert alert-warning alert-dismissible fade show my-1 py-1" role
="alert">
515 <button type
="button" class="close my-1 py-0" data
-dismiss
="alert" aria
-label
="Close">
516 <span aria
-hidden
="true">×
;</span
>
523 var webroot_url
= <?php
echo js_escape($GLOBALS['web_root']) ?
>;
525 function restoreSession() {
526 //dummy functions so the dlgopen function will work in the patient portal
533 <?php
// if something went wrong
534 if (!empty($GLOBALS['portal_two_pass_reset']) && !empty($GLOBALS['google_recaptcha_site_key']) && !empty($GLOBALS['google_recaptcha_secret_key']) && isset($_GET['requestNew'])) {
535 $_SESSION['register'] = true;
536 $_SESSION['authUser'] = 'portal-user';
537 $_SESSION['pid'] = true;
539 $
('.datepicker').datetimepicker({
540 <?php
$datetimepicker_timepicker = false; ?
>
541 <?php
$datetimepicker_showseconds = false; ?
>
542 <?php
$datetimepicker_formatInput = false; ?
>
543 <?php
require $GLOBALS['srcdir'] . '/js/xl/jquery-datetimepicker-2-5-4.js.php'; ?
>
545 $
(document
.body
).on('hidden.bs.modal', function () {
546 callServer('cleanup');
548 $
("#resetPass").on('submit', function (e
) {
550 callServer('reset_password');
554 <?php
if (isset($_GET['w'])) { ?
>
555 // mdsupport - Would be good to include some clue about what went wrong!
556 bsAlert(<?php
echo xlj('Something went wrong. Please try again.'); ?
>);
558 <?php
// if successfully logged out
559 if (isset($_GET['logout'])) { ?
>
560 bsAlert(<?php
echo xlj('You have been successfully logged out.'); ?
>);
566 function callServer(action
) {
568 if (action
=== 'reset_password') {
571 'dob': $
("#dob").val(),
572 'last': $
("#lname").val(),
573 'first': $
("#fname").val(),
574 'email': $
("#emailInput").val(),
575 'g-recaptcha-response': grecaptcha
.getResponse(),
576 'csrf_token_form': $
("#csrf_token_form").val()
579 if (action
=== 'cleanup') {
586 url
: './account/account.php',
588 }).done(function (rtn
) {
589 if (action
=== "cleanup") {
590 window
.location
.href
= "./index.php?site=" +
<?php
echo js_url($_SESSION['site_id']); ?
>; // Goto landing page.
591 } else if (action
=== "reset_password") {
592 if (JSON
.parse(rtn
) === 1) {
593 dialog
.alert(<?php
echo xlj("Check your email inbox (and possibly your spam folder) for further instructions to reset your password. If you have not received an email, then recommend contacting the clinic.") ?
>);
596 dialog
.alert(<?php
echo xlj("Something went wrong. Recommend contacting the clinic.") ?
>);
600 }).fail(function (err
) {
601 var message
= <?php
echo xlj('Something went wrong.') ?
>;
606 function bsAlert(msg
) {
607 let divAlert
= document
.getElementById("alertStore").querySelector("div.alert").cloneNode(true);
608 document
.querySelector("form").prepend(divAlert
);
609 let strongMsg
= document
.createElement("strong");
610 strongMsg
.innerHTML
= msg
;
611 divAlert
.prepend(strongMsg
);
613 document
.querySelector("div.alert").remove();