Portal credential enhancements
[openemr.git] / interface / patient_file / summary / create_portallogin.php
blob4aa150e3bfc9fb6d952b8daf2d28bfc36f8746bf
1 <?php
2 /**
3 * create_portallogin.php
5 * @package OpenEMR
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") {
26 $portalsite = "off";
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)) {
34 return true;
37 return false;
40 function messageCreate($uname, $pass, $site)
42 global $trustedEmail;
44 $message = xlt("Patient Portal Web Address") . ":<br>";
45 if ($site == "on") {
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>";
51 $message .= "<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>";
59 $sub = '';
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."));
63 $sub .= "<br><br>";
65 $message .= xlt("User Name") . ": " .
66 text($uname) . "<br><br>" .
67 xlt("Password") . ": " .
68 text($pass) . "<br><br>" . $sub;
69 return $message;
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'])) {
76 return false;
79 if (!(validEmail($patientData['email']))) {
80 return false;
83 if (!(validEmail($GLOBALS['patient_reminder_sender_email']))) {
84 return false;
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>");
97 $mail->IsHTML(true);
98 $mail->AltBody = $message;
100 if ($mail->Send()) {
101 return true;
102 } else {
103 $email_status = $mail->ErrorInfo;
104 error_log("EMAIL ERROR: " . errorLogEscape($email_status), 0);
105 return false;
109 function displayLogin($patient_id, $message, $emailFlag)
111 $patientData = sqlQuery("SELECT * FROM `patient_data` WHERE `pid`=?", array($patient_id));
112 if ($emailFlag) {
113 $message = "<br><br>" .
114 xlt("Email was sent to following address") . ": " .
115 text($patientData['email']) . "<br><br>" .
116 $message;
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']);
133 $salt_clause="";
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);
139 } else {
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);
148 } else {
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)) {
156 // email was sent
157 displayLogin($pid, $message, true);
158 } else {
159 // email wasn't sent
160 displayLogin($pid, $message, false);
163 exit;
164 } ?>
165 <html>
166 <head>
168 <?php Header::setupHeader(['no_bootstrap', 'no_fontawesome', 'no_textformat', 'no_dialog', 'opener']); ?>
170 <script type="text/javascript">
171 function transmit(){
172 // get a public key to encrypt the password info and send
173 document.getElementById('form_save').value='SUBMIT';
174 document.forms[0].submit();
176 </script>
177 </head>
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">
183 <tr class="text">
184 <th colspan="5" align="center"><?php echo text(xl("Generate Username And Password For")." ".$row['fname']);?></th>
185 </tr>
186 <?php
187 if ($portalsite == 'off') {
189 <tr class="text">
190 <td><?php echo text(xl('Provider Id').':');?></td>
191 <td><span><?php echo text($GLOBALS['portal_offsite_providerid']);?></span></td>
192 </tr>
193 <?php
196 <tr class="text">
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>
199 </tr>
200 <tr class="text">
201 <td><strong><?php echo text(xl('Password').':');?></strong></td>
202 <?php
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>
207 </tr>
208 <?php if ($GLOBALS['enforce_signin_email']) { ?>
209 <tr class="text">
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>
212 </tr>
213 <?php } ?>
214 <tr align="center"><td>&nbsp;</td><td><hr></td></tr>
216 <tr class="text">
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>
222 </td>
223 </tr>
224 </table>
225 </form>
226 </body>