4 * Copyright (C) 2016-2017 Jerry Padgett <sjpadgett@gmail.com>
5 * Copyright (C) 2011 Cassian LUP <cassi.lup@gmail.com>
7 * LICENSE: This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU Affero General Public License as
9 * published by the Free Software Foundation, either version 3 of the
10 * License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Affero General Public License for more details.
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 * @author Jerry Padgett <sjpadgett@gmail.com>
22 * @author Cassian LUP <cassi.lup@gmail.com>
23 * @link http://www.open-emr.org
26 //setting the session & other config options
29 //don't require standard openemr authorization in globals.php
32 //For redirect if the site on session does not match
33 $landingpage = "index.php?site=".$_GET['site'];
36 require_once('../interface/globals.php');
38 use OpenEMR\Core\Header
;
40 ini_set("error_log", E_ERROR || ~E_NOTICE
);
41 //exit if portal is turned off
42 if (!(isset($GLOBALS['portal_onsite_two_enable'])) ||
!($GLOBALS['portal_onsite_two_enable'])) {
43 echo htmlspecialchars(xl('Patient Portal is turned off'), ENT_NOQUOTES
);
47 // security measure -- will check on next page.
48 $_SESSION['itsme'] = 1;
52 // Deal with language selection
54 // collect default language id (skip this if this is a password update)
55 if (!(isset($_SESSION['password_update']) ||
isset($_GET['requestNew']))) {
56 $res2 = sqlStatement("select * from lang_languages where lang_description = ?", array($GLOBALS['language_default']));
57 for ($iter = 0; $row = sqlFetchArray($res2); $iter++
) {
58 $result2[$iter] = $row;
61 if (count($result2) == 1) {
62 $defaultLangID = $result2[0]{"lang_id"};
63 $defaultLangName = $result2[0]{"lang_description"};
65 //default to english if any problems
67 $defaultLangName = "English";
70 // set session variable to default so login information appears in default language
71 $_SESSION['language_choice'] = $defaultLangID;
72 // collect languages if showing language menu
73 if ($GLOBALS['language_menu_login']) {
74 // sorting order of language titles depends on language translation options.
75 $mainLangID = empty($_SESSION['language_choice']) ?
'1' : $_SESSION['language_choice'];
76 if ($mainLangID == '1' && !empty($GLOBALS['skip_english_translation'])) {
77 $sql = "SELECT * FROM lang_languages ORDER BY lang_description, lang_id";
78 $res3=SqlStatement($sql);
80 // Use and sort by the translated language name.
81 $sql = "SELECT ll.lang_id, " .
82 "IF(LENGTH(ld.definition),ld.definition,ll.lang_description) AS trans_lang_description, " .
83 "ll.lang_description " .
84 "FROM lang_languages AS ll " .
85 "LEFT JOIN lang_constants AS lc ON lc.constant_name = ll.lang_description " .
86 "LEFT JOIN lang_definitions AS ld ON ld.cons_id = lc.cons_id AND " .
88 "ORDER BY IF(LENGTH(ld.definition),ld.definition,ll.lang_description), ll.lang_id";
89 $res3=SqlStatement($sql, array($mainLangID));
91 for ($iter = 0; $row = sqlFetchArray($res3); $iter++
) {
92 $result3[$iter] = $row;
94 if (count($result3) == 1) {
95 //default to english if only return one language
96 $hiddenLanguageField = "<input type='hidden' name='languageChoice' value='1' />\n";
99 $hiddenLanguageField = "<input type='hidden' name='languageChoice' value='".htmlspecialchars($defaultLangID, ENT_QUOTES
)."' />\n";
106 <title
><?php
echo xlt('Patient Portal Login'); ?
></title
>
108 $css = $GLOBALS['css_header'];
109 $GLOBALS['css_header'] = "";
110 Header
::setupHeader(['datetime-picker']);
111 //$GLOBALS['css_header'] = $css;
113 <script type
="text/javascript" src
="<?php echo $GLOBALS['assets_static_relative']; ?>/jquery.gritter-1-7-4/js/jquery.gritter.min.js"></script
>
114 <link rel
="stylesheet" type
="text/css" href
="<?php echo $GLOBALS['assets_static_relative']; ?>/jquery.gritter-1-7-4/css/jquery.gritter.css" />
115 <script type
="text/javascript" src
="<?php echo $GLOBALS['assets_static_relative']; ?>/emodal-1-2-65/dist/eModal.js"></script
>
116 <link rel
="stylesheet" type
="text/css" href
="assets/css/base.css?v=<?php echo $v_js_includes; ?>" />
117 <link rel
="stylesheet" type
="text/css" href
="assets/css/register.css?v=<?php echo $v_js_includes; ?>" />
118 <script type
="text/javascript">
121 alert ('<?php echo addslashes(xl('Field(s
) are missing
!')); ?>');
125 function validate() {
127 if (document
.getElementById('uname').value
== "") {
128 document
.getElementById('uname').style
.border
= "1px solid red";
131 if (document
.getElementById('pass').value
== "") {
132 document
.getElementById('pass').style
.border
= "1px solid red";
137 function process_new_pass() {
138 if (!(validate_new_pass())) {
139 alert ('<?php echo addslashes(xl('Field(s
) are missing
!')); ?>');
142 if (document
.getElementById('pass_new').value
!= document
.getElementById('pass_new_confirm').value
) {
143 alert ('<?php echo addslashes(xl('The
new password fields are not the same
.')); ?>');
146 if (document
.getElementById('pass').value
== document
.getElementById('pass_new').value
) {
147 alert ('<?php echo addslashes(xl('The
new password can not be the same
as the current password
.')); ?>');
152 function validate_new_pass() {
154 if (document
.getElementById('uname').value
== "") {
155 document
.getElementById('uname').style
.border
= "1px solid red";
158 if (document
.getElementById('pass').value
== "") {
159 document
.getElementById('pass').style
.border
= "1px solid red";
162 if (document
.getElementById('pass_new').value
== "") {
163 document
.getElementById('pass_new').style
.border
= "1px solid red";
166 if (document
.getElementById('pass_new_confirm').value
== "") {
167 document
.getElementById('pass_new_confirm').style
.border
= "1px solid red";
174 <body
class="skin-blue">
176 <div
class="container text-center">
177 <?php
if (isset($_SESSION['password_update']) ||
isset($_GET['password_update'])) {
178 $_SESSION['password_update']=1;
180 <div id
="wrapper" class="centerwrapper" style
="text-align:center;">
181 <h2
class="title"><?php
echo xlt('Please Enter a New Password'); ?
></h2
>
182 <form action
="get_patient_info.php" method
="POST" onsubmit
="return process_new_pass()" >
183 <table style
="width:100%">
185 <td
class="algnRight"><?php
echo xlt('User Name'); ?
></td
>
186 <td
><input name
="uname" id
="uname" type
="text" autocomplete
="off" value
="<?php echo attr($_SESSION['portal_username']); ?>"/></td
>
189 <td
class="algnRight"><?php
echo xlt('Current Password');?
></td
>
191 <input name
="pass" id
="pass" type
="password" autocomplete
="off" value
="" />
195 <td
class="algnRight"><?php
echo xlt('New Password');?
></td
>
197 <input name
="pass_new" id
="pass_new" type
="password" />
201 <td
class="algnRight"><?php
echo xlt('Confirm New Password');?
></td
>
203 <input name
="pass_new_confirm" id
="pass_new_confirm" type
="password" />
207 <td
class="algnRight"><?php
echo xlt('Confirm Email Address');?
></td
>
209 <input name
="passaddon" id
="passaddon" placeholder
="<?php echo xla('Your on file email address'); ?>" type
="email" autocomplete
="off" value
="" />
213 <td colspan
=2><br
><input
class="pull-right" type
="submit" value
="<?php echo xla('Log In');?>" /></td
>
217 <div
class="copyright"><?php
echo xlt('Powered by');?
> OpenEMR
</div
>
219 <?php
} elseif (isset($_GET['requestNew'])) { ?
>
220 <div id
="wrapper" class="centerwrapper" style
="text-align:center;" >
221 <form
class="form-inline" id
="resetPass" action
="" method
="" >
223 <div
class="col-sm-10 col-md-offset-1 text-center">
225 <legend
class='bg-primary'><h3
><?php
echo xlt('Patient Credentials Reset') ?
></h3
></legend
>
228 <div
class="form-group inline">
229 <label
class="control-label" for="fname"><?php
echo xlt('First')?
></label
>
230 <div
class="controls inline-inputs">
231 <input type
="text" class="form-control" id
="fname" required placeholder
="<?php echo xla('First Name'); ?>">
234 <div
class="form-group inline">
235 <label
class="control-label" for="lname"><?php
echo xlt('Last Name')?
></label
>
236 <div
class="controls inline-inputs">
237 <input type
="text" class="form-control" id
="lname" required placeholder
="<?php echo xla('Enter Last'); ?>">
240 <div
class="form-group inline">
241 <label
class="control-label" for="dob"><?php
echo xlt('Birth Date')?
></label
>
242 <div
class="controls inline-inputs">
243 <div
class="input-group">
244 <input id
="dob" type
="text" required
class="form-control datepicker" placeholder
="<?php echo xla('YYYY-MM-DD'); ?>" />
249 <div
class="col-sm-12 form-group">
250 <label
class="control-label" for="emailInput"><?php
echo xlt('Enter E-Mail Address')?
></label
>
251 <div
class="controls inline-inputs">
252 <input id
="emailInput" type
="email" class="form-control" style
="width: 100%" required
253 placeholder
="<?php echo xla('Must be current email address on file.'); ?>" maxlength
="100">
258 <button id
="submitRequest" class="btn btn-primary nextBtn btn-sm pull-right" type
="button"><?php
echo xlt('Verify') ?
></button
>
265 ?
> <!-- Main logon
-->
266 <div id
="wrapper" class="row centerwrapper text-center">
267 <img style
="width:65%" src
='<?php echo $GLOBALS['images_static_relative
']; ?>/login-logo.png'/>
268 <form
class="form-inline text-center" action
="get_patient_info.php" method
="POST" onsubmit
="return process()">
270 <div
class="col-sm-12 text-center">
272 <legend
class="bg-primary"><h3
><?php
echo xlt('Patient Portal Login'); ?
></h3
></legend
>
275 <div
class="col-sm-12">
276 <div
class="form-group inline">
277 <label
class="control-label" for="uname"><?php
echo xlt('Username')?
></label
>
278 <div
class="controls inline-inputs">
279 <input type
="text" class="form-control" name
="uname" id
="uname" type
="text" autocomplete
="on" required
>
282 <div
class="form-group inline">
283 <label
class="control-label" for="pass"><?php
echo xlt('Password')?
></label
>
284 <div
class="controls inline-inputs">
285 <input
class="form-control" name
="pass" id
="pass" type
="password" required autocomplete
="on">
291 <div
class="col-sm-12 form-group">
292 <label
class="control-label" for="passaddon"><?php
echo xlt('E-Mail Address')?
></label
>
293 <div
class="controls inline-inputs">
294 <input
class="form-control" style
="width: 100%" name
="passaddon" id
="passaddon" placeholder
="<?php echo xla('on file email'); ?>" type
="email" autocomplete
="on" />
298 <?php
if ($GLOBALS['language_menu_login']) { ?
>
299 <?php
if (count($result3) != 1) { ?
>
300 <div
class="form-group row">
301 <label
for="selLanguage"><?php
echo xlt('Language'); ?
></label
>
302 <select
class="form-control" id
="selLanguage" name
="languageChoice">
304 echo "<option selected='selected' value='" . htmlspecialchars($defaultLangID, ENT_QUOTES
) . "'>" .
305 htmlspecialchars(xl('Default') . " - " . xl($defaultLangName), ENT_NOQUOTES
) . "</option>\n";
306 foreach ($result3 as $iter) {
307 if ($GLOBALS['language_menu_showall']) {
308 if (! $GLOBALS['allow_debug_language'] && $iter['lang_description'] == 'dummy') {
309 continue; // skip the dummy language
311 echo "<option value='" . htmlspecialchars($iter['lang_id'], ENT_QUOTES
) . "'>" .
312 htmlspecialchars($iter['trans_lang_description'], ENT_NOQUOTES
) . "</option>\n";
314 if (in_array($iter['lang_description'], $GLOBALS['language_menu_show'])) {
315 if (! $GLOBALS['allow_debug_language'] && $iter['lang_description'] == 'dummy') {
316 continue; // skip the dummy language
318 echo "<option value='" . htmlspecialchars($iter['lang_id'], ENT_QUOTES
) . "'>" .
319 htmlspecialchars($iter['trans_lang_description'], ENT_NOQUOTES
) . "</option>\n";
328 <div
class="col-sm-12 col-md-12">
329 <?php
if ($GLOBALS['portal_onsite_two_register']) { ?
>
330 <button
class="btn btn-default pull-left" onclick
="location.replace('./account/register.php')"><?php
echo xlt('Register');?
></button
>
332 <?php
if ($GLOBALS['portal_two_pass_reset'] && isset($_GET['w']) && (isset($_GET['u']) ||
isset($_GET['p']))) { ?
>
333 <button
class="btn btn-danger" onclick
="location.replace('./index.php?requestNew=1')" style
="margin-left:10px"><?php
echo xlt('Reset Credentials');?
></button
>
335 <button
class="btn btn-success pull-right" type
="submit" ><?php
echo xlt('Log In');?
></button
>
340 <?php
if (!(empty($hiddenLanguageField))) {
341 echo $hiddenLanguageField; } ?
>
343 </div
><!-- div wrapper
-->
344 <?php
} ?
> <!-- logon wrapper
-->
345 </div
><!-- container
-->
347 <script type
="text/javascript">
348 $
(document
).ready(function() {
350 <?php
// if something went wrong
351 if (isset($_GET['requestNew'])) {
352 $_SESSION['patient_portal_onsite_two'] = true;
353 $_SESSION['authUser'] = 'portal-user';
354 $_SESSION['pid'] = true;
356 $
('.datepicker').datetimepicker({
357 <?php
$datetimepicker_timepicker = false; ?
>
358 <?php
$datetimepicker_showseconds = false; ?
>
359 <?php
$datetimepicker_formatInput = false; ?
>
360 <?php
require($GLOBALS['srcdir'] . '/js/xl/jquery-datetimepicker-2-5-4.js.php'); ?
>
362 $
(document
.body
).on('hidden.bs.modal', function () {
363 callServer('cleanup');
365 $
("#submitRequest").click(function () {
366 callServer('is_new', '');
369 <?php
if (isset($_GET['w'])) { ?
>
370 var unique_id
= $
.gritter
.add({
371 title
: '<span class="red"><?php echo xlt('Oops
!');?></span>',
372 text
: '<?php echo xlt('Something went wrong
. Please
try again
.'); ?>',
375 class_name
: 'my-nonsticky-class'
378 <?php
// if successfully logged out
379 if (isset($_GET['logout'])) { ?
>
380 var unique_id
= $
.gritter
.add({
381 title
: '<span class="green"><?php echo xlt('Success
');?></span>',
382 text
: '<?php echo xlt('You have been successfully logged out
.');?>',
385 class_name
: 'my-nonsticky-class'
392 $("#emailInput").val("me@me.com");
393 $("#fname").val("Jerry");
394 $("#lname").val("Padgett");
395 $("#dob").val("1919-03-03"); */
397 function callServer(action
, value
, value2
, last
, first
) {
401 'dob' : $
("#dob").val(),
402 'last' : $
("#lname").val(),
403 'first' : $
("#fname").val(),
404 'email' : $
("#emailInput").val()
406 if (action
== 'do_signup') {
412 else if (action
== 'notify_admin') {
419 else if (action
== 'cleanup') {
426 url
: './account/account.php',
428 }).done(function (rtn
) {
429 if (action
== "cleanup") {
430 window
.location
.href
= "./index.php" // Goto landing page.
432 else if (action
== "is_new") {
433 if (parseInt(rtn
) > 0) {
434 var yes
= confirm('<?php echo xls("Account is validated. Send new credentials?") ?>');
436 callServer('cleanup');
438 callServer('do_signup', parseInt(rtn
));
441 // After error alert app exit to landing page.
442 var message
= "<?php echo xls('Unable to find your records. Be sure to use your correct Dob, First and Last name and Email of record. If you have opted out of email with none on file then leave blank.'); ?>";
443 eModal
.alert(message
);
446 else if (action
== 'do_signup') {
448 var message
= "<?php echo xlt('Unable to either create credentials or send email.'); ?>";
452 //alert(rtn); // sync alert.. rtn holds username and password for testing.
453 var message
= "<?php echo xls(" Your
new credentials have been sent
. Check your email inbox
and also possibly your spam folder
. Once you log into your patient portal feel free to make an appointment
or send us a secure message
. We look forward to seeing you soon
."); ?>"
454 eModal
.alert(message
); // This is an async call. The modal close event exits us to portal landing page after cleanup.
456 }).fail(function (err
) {
457 var message
= "<?php echo xls('Something went wrong.') ?>";