3 * create_portallogin.php
6 * @link http://www.open-emr.org
7 * @author Eldho Chacko <eldho@zhservices.com>
8 * @author Jacob T Paul <jacob@zhservices.com>
9 * @author Paul Simon <paul@zhservices.com>
10 * @author Brady Miller <brady.g.miller@gmail.com>
11 * @copyright Copyright (c) 2011 Z&H Consultancy Services Private Limited <sam@zhservices.com>
12 * @copyright Copyright (c) 2018-2019 Brady Miller <brady.g.miller@gmail.com>
13 * @license https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3
17 require_once("../../globals.php");
19 use OpenEMR\Common\Csrf\CsrfUtils
;
20 use OpenEMR\Common\Utils\RandomGenUtils
;
21 use OpenEMR\Core\Header
;
23 // Collect portalsite parameter (either off for offsite or on for onsite); only allow off or on
24 $portalsite = isset($_GET['portalsite']) ?
$_GET['portalsite'] : $portalsite = "off";
25 if ($portalsite != "off" && $portalsite != "on") {
28 $trustedEmail = sqlQuery("SELECT email_direct FROM `patient_data` WHERE `pid`=?", array($pid));
29 $row = sqlQuery("SELECT pd.*,pao.portal_username,pao.portal_pwd,pao.portal_pwd_status FROM patient_data AS pd LEFT OUTER JOIN patient_access_" . escape_identifier($portalsite, array("on","off"), true) . "site AS pao ON pd.pid=pao.pid WHERE pd.pid=?", array($pid));
31 function validEmail($email)
33 if (preg_match("/^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$/i", $email)) {
40 function messageCreate($uname, $pass, $site)
44 $message = xlt("Patient Portal Web Address") . ":<br>";
46 if ($GLOBALS['portal_onsite_two_enable']) {
47 $message .= "<a href='" . attr($GLOBALS['portal_onsite_two_address']) . "'>" .
48 text($GLOBALS['portal_onsite_two_address']) . "</a><br>";
52 } else { // $site == "off"
53 $offsite_portal_patient_link = $GLOBALS['portal_offsite_address_patient_link'] ?
$GLOBALS['portal_offsite_address_patient_link'] : "https://mydocsportal.com";
54 $message .= "<a href='" . attr($offsite_portal_patient_link) . "'>" .
55 text($offsite_portal_patient_link) . "</a><br><br>";
56 $message .= xlt("Provider Id") . ": " .
57 text($GLOBALS['portal_offsite_providerid']) . "<br><br>";
60 if ($GLOBALS['enforce_signin_email']) {
61 $sub = xlt("Login Trusted Email") . ":" .
62 (!empty(trim($trustedEmail['email_direct'])) ?
text(trim($trustedEmail['email_direct'])) : xlt("Is Required. Contact Provider."));
65 $message .= xlt("User Name") . ": " .
66 text($uname) . "<br><br>" .
67 xlt("Password") . ": " .
68 text($pass) . "<br><br>" . $sub;
72 function emailLogin($patient_id, $message)
74 $patientData = sqlQuery("SELECT * FROM `patient_data` WHERE `pid`=?", array($patient_id));
75 if ($patientData['hipaa_allowemail'] != "YES" ||
empty($patientData['email']) ||
empty($GLOBALS['patient_reminder_sender_email'])) {
79 if (!(validEmail($patientData['email']))) {
83 if (!(validEmail($GLOBALS['patient_reminder_sender_email']))) {
87 $mail = new MyMailer();
88 $pt_name=$patientData['fname'].' '.$patientData['lname'];
89 $pt_email=$patientData['email'];
90 $email_subject=xl('Access Your Patient Portal');
91 $email_sender=$GLOBALS['patient_reminder_sender_email'];
92 $mail->AddReplyTo($email_sender, $email_sender);
93 $mail->SetFrom($email_sender, $email_sender);
94 $mail->AddAddress($pt_email, $pt_name);
95 $mail->Subject
= $email_subject;
96 $mail->MsgHTML("<html><body><div class='wrapper'>".$message."</div></body></html>");
98 $mail->AltBody
= $message;
103 $email_status = $mail->ErrorInfo
;
104 error_log("EMAIL ERROR: " . errorLogEscape($email_status), 0);
109 function displayLogin($patient_id, $message, $emailFlag)
111 $patientData = sqlQuery("SELECT * FROM `patient_data` WHERE `pid`=?", array($patient_id));
113 $message = "<br><br>" .
114 xlt("Email was sent to following address") . ": " .
115 text($patientData['email']) . "<br><br>" .
119 echo "<html><body onload='top.printLogPrint(window);'>" . $message . "</body></html>";
122 if (isset($_POST['form_save']) && $_POST['form_save']=='SUBMIT') {
123 if (!CsrfUtils
::verifyCsrfToken($_POST["csrf_token_form"])) {
124 CsrfUtils
::csrfNotVerified();
127 require_once("$srcdir/authentication/common_operations.php");
129 $clear_pass=$_POST['pwd'];
131 $res = sqlStatement("SELECT * FROM patient_access_" . escape_identifier($portalsite, array("on","off"), true) . "site WHERE pid=?", array($pid));
132 $query_parameters=array($_POST['uname'],$_POST['uname']);
134 if ($portalsite=='on') {
135 // For onsite portal create a blowfish based hash and salt.
136 $new_salt = oemr_password_salt();
137 $salt_clause = ",portal_salt=? ";
138 array_push($query_parameters, oemr_password_hash($clear_pass, $new_salt), $new_salt);
140 // For offsite portal still create and SHA1 hashed password
141 // When offsite portal is updated to handle blowfish, then both portals can use the same execution path.
142 array_push($query_parameters, SHA1($clear_pass));
145 array_push($query_parameters, $pid);
146 if (sqlNumRows($res)) {
147 sqlStatementNoLog("UPDATE patient_access_" . escape_identifier($portalsite, array("on","off"), true) . "site SET portal_username=?,portal_login_username=?,portal_pwd=?,portal_pwd_status=0 " . $salt_clause . " WHERE pid=?", $query_parameters);
149 sqlStatementNoLog("INSERT INTO patient_access_" . escape_identifier($portalsite, array("on","off"), true) . "site SET portal_username=?,portal_login_username=?,portal_pwd=?,portal_pwd_status=0" . $salt_clause . " ,pid=?", $query_parameters);
152 // Create the message
153 $message = messageCreate($_POST['uname'], $clear_pass, $portalsite);
154 // Email and display/print the message
155 if (emailLogin($pid, $message)) {
157 displayLogin($pid, $message, true);
160 displayLogin($pid, $message, false);
168 <?php Header
::setupHeader(['no_bootstrap', 'no_fontawesome', 'no_textformat', 'no_dialog', 'opener']); ?
>
170 <script type
="text/javascript">
172 // get a public key to encrypt the password info and send
173 document
.getElementById('form_save').value
='SUBMIT';
174 document
.forms
[0].submit();
178 <body
class="body_top">
179 <form name
="portallogin" action
="" method
="POST">
180 <input type
="hidden" name
="csrf_token_form" value
="<?php echo attr(CsrfUtils::collectCsrfToken()); ?>" />
182 <table align
="center" style
="margin-top:10px">
184 <th colspan
="5" align
="center"><?php
echo text(xl("Generate Username And Password For")." ".$row['fname']);?
></th
>
187 if ($portalsite == 'off') {
190 <td
><?php
echo text(xl('Provider Id').':');?
></td
>
191 <td
><span
><?php
echo text($GLOBALS['portal_offsite_providerid']);?
></span
></td
>
197 <td
><strong
><?php
echo text(xl('User Name').':');?
></strong
></td
>
198 <td
><input type
="text" name
="uname" value
="<?php echo ($row['portal_username']) ? attr($row['portal_username']) : attr($row['fname'].$row['id']); ?>" size
="10" readonly
></td
>
201 <td
><strong
><?php
echo text(xl('Password').':');?
></strong
></td
>
203 $pwd = RandomGenUtils
::generatePortalPassword();
205 <td
><input type
="text" name
="pwd" id
="pwd" value
="<?php echo attr($pwd); ?>" size
="14"/></td
>
206 <td
><a href
="#" class="css_button" onclick
="top.restoreSession(); javascript:document.location.reload()"><span
><?php
echo xlt('Change'); ?
></span
></a
></td
>
208 <?php
if ($GLOBALS['enforce_signin_email']) { ?
>
210 <td
><strong
><?php
echo xlt("Login Trusted Email") . ":" ?
></strong
></td
>
211 <td
><?php
echo (!empty(trim($trustedEmail['email_direct'])) ?
text(trim($trustedEmail['email_direct'])) : xlt("Is Required. Please Add in Contacts.")) ?
></td
>
214 <tr align
="center"><td
> 
;</td
><td
><hr
></td
></tr
>
217 <td
><input type
="hidden" name
="form_save" id
="form_save"></td
>
218 <td colspan
="5" align
="center">
219 <a href
="#" class="css_button" onclick
="return transmit()"><span
><?php
echo xlt('Save');?
></span
></a
>
220 <input type
="hidden" name
="form_cancel" id
="form_cancel">
221 <a href
="#" class="css_button" onclick
="top.restoreSession(); dlgclose();"><span
><?php
echo xlt('Cancel');?
></span
></a
>