chore: update ci and dev environments to use mariadb 11.4 (#7545)
[openemr.git] / interface / login / login.php
blob150bba3b8215aa6bd2edb5127f210469b17e2648
1 <?php
3 /**
4 * Login screen.
6 * @package OpenEMR
7 * @link http://www.open-emr.org
8 * @author Rod Roark <rod@sunsetsystems.com>
9 * @author Brady Miller <brady.g.miller@gmail.com>
10 * @author Kevin Yeh <kevin.y@integralemr.com>
11 * @author Scott Wakefield <scott.wakefield@gmail.com>
12 * @author ViCarePlus <visolve_emr@visolve.com>
13 * @author Julia Longtin <julialongtin@diasp.org>
14 * @author cfapress
15 * @author markleeds
16 * @author Tyler Wrenn <tyler@tylerwrenn.com>
17 * @author Ken Chapple <ken@mi-squared.com>
18 * @author Daniel Pflieger <daniel@mi-squared.com> <daniel@growlingflea.com>
19 * @author Robert Down <robertdown@live.com>
20 * @copyright Copyright (c) 2019 Brady Miller <brady.g.miller@gmail.com>
21 * @copyright Copyright (c) 2020 Tyler Wrenn <tyler@tylerwrenn.com>
22 * @copyright Copyright (c) 2021 Ken Chapple <ken@mi-squared.com>
23 * @copyright Copyright (c) 2021 Daniel Pflieger <daniel@mi-squared.com> <daniel@growlingflea.com>
24 * @copyright Copyright (c) 2021-2023 Robert Down <robertdown@live.com>
25 * @license https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3
28 // prevent UI redressing
29 Header("X-Frame-Options: DENY");
30 Header("Content-Security-Policy: frame-ancestors 'none'");
32 use OpenEMR\Common\Twig\TwigContainer;
33 use OpenEMR\Events\Core\TemplatePageEvent;
34 use OpenEMR\Services\FacilityService;
35 use OpenEMR\Services\LogoService;
36 use Symfony\Component\EventDispatcher\EventDispatcher;
37 use Twig\Error\LoaderError;
38 use Twig\Error\RuntimeError;
39 use Twig\Error\SyntaxError;
41 $ignoreAuth = true;
42 // Set $sessionAllowWrite to true to prevent session concurrency issues during authorization related code
43 $sessionAllowWrite = true;
44 require_once("../globals.php");
46 $twig = new TwigContainer(null, $GLOBALS["kernel"]);
47 $t = $twig->getTwig();
49 $logoService = new LogoService();
50 $primaryLogo = $logoService->getLogo("core/login/primary");
51 $secondaryLogo = $logoService->getLogo("core/login/secondary");
52 $smallLogoOne = $logoService->getLogo("core/login/small_logo_1");
53 $smallLogoTwo = $logoService->getLogo("core/login/small_logo_2");
55 $layout = $GLOBALS['login_page_layout'];
57 // mdsupport - Add 'App' functionality for user interfaces without standard menu and frames
58 // If this script is called with app parameter, validate it without showing other apps.
60 // Build a list of valid entries
61 // Original merge v5.0.1
62 $emr_app = array();
63 $sql = "SELECT option_id, title,is_default FROM list_options WHERE list_id=? and activity=1 ORDER BY seq, option_id";
64 $rs = sqlStatement($sql, ['apps']);
65 if (sqlNumRows($rs)) {
66 while ($app = sqlFetchArray($rs)) {
67 $app_req = explode('?', trim($app['title']));
68 if (! file_exists('../' . $app_req[0])) {
69 continue;
72 $emr_app [trim($app ['option_id'])] = trim($app ['title']);
73 if ($app ['is_default']) {
74 $emr_app_def = $app ['option_id'];
79 $div_app = '';
80 if (count($emr_app)) {
81 // Standard app must exist
82 $std_app = 'main/main_screen.php';
83 if (!in_array($std_app, $emr_app)) {
84 $emr_app['*OpenEMR'] = $std_app;
87 if (isset($_REQUEST['app']) && $emr_app[$_REQUEST['app']]) {
88 $div_app = sprintf('<input type="hidden" name="appChoice" value="%s">', attr($_REQUEST['app']));
89 } else {
90 $opt_htm = '';
91 foreach ($emr_app as $opt_disp => $opt_value) {
92 $opt_htm .= sprintf(
93 '<option value="%s" %s>%s</option>\n',
94 attr($opt_disp),
95 ($opt_disp == ($emr_app_def ?? '') ? 'selected="selected"' : ''),
96 text(xl_list_label($opt_disp))
100 $div_app = sprintf(
102 <div id="divApp" class="form-group row">
103 <label for="appChoice" class="col-form-label col-sm-4">%s:</label>
104 <div class="col">
105 <select class="form-control" id="selApp" name="appChoice" size="1">%s</select>
106 </div>
107 </div>',
108 xlt('App'),
109 $opt_htm
115 function getDefaultLanguage(): array
117 $sql = "SELECT * FROM lang_languages where lang_description = ?";
118 $res = sqlStatement($sql, [$GLOBALS['language_default']]);
119 $langs = [];
121 while ($row = sqlFetchArray($res)) {
122 $langs[] = $row;
125 $id = 1;
126 $desc = "English";
128 if (count($langs) == 1) {
129 $id = $langs[0]["lang_id"];
130 $desc = $langs[0]["lang_description"];
133 return ["id" => $id, "language" => $desc];
136 function getLanguagesList(): array
138 $mainLangID = empty($_SESSION['language_choice']) ? '1' : $_SESSION['language_choice'];
139 $sql = "SELECT ll.lang_id, IF(LENGTH(ld.definition), ld.definition, ll.lang_description) AS trans_lang_description, ll.lang_description
140 FROM lang_languages AS ll
141 LEFT JOIN lang_constants AS lc ON lc.constant_name = ll.lang_description
142 LEFT JOIN lang_definitions AS ld ON ld.cons_id = lc.cons_id AND ld.lang_id = ?
143 ORDER BY IF(LENGTH(ld.definition),ld.definition,ll.lang_description), ll.lang_id";
144 $res = sqlStatement($sql, [$mainLangID]);
145 $langList = [];
147 while ($row = sqlFetchArray($res)) {
148 if (!$GLOBALS['allow_debug_language'] && $row['lang_description'] == 'dummy') {
149 continue; // skip the dummy language
152 if ($GLOBALS['language_menu_showall']) {
153 $langList[] = $row;
154 } else {
155 if (in_array($row['lang_description'], $GLOBALS['language_menu_show'])) {
156 $langList[] = $row;
161 return $langList;
164 $facilities = [];
165 $facilitySelected = false;
166 if ($GLOBALS['login_into_facility']) {
167 $facilityService = new FacilityService();
168 $facilities = $facilityService->getAllFacility();
169 $facilitySelected = ($GLOBALS['set_facility_cookie'] && isset($_COOKIE['pc_facility'])) ? $_COOKIE['pc_facility'] : null;
172 $defaultLanguage = getDefaultLanguage();
173 $languageList = getLanguagesList();
174 $_SESSION['language_choice'] = $defaultLanguage['id'];
176 $relogin = (isset($_SESSION['relogin']) && ($_SESSION['relogin'] == 1)) ? true : false;
177 if ($relogin) {
178 unset($_SESSION["relogin"]);
181 $t1 = $GLOBALS['tiny_logo_1'];
182 $t2 = $GLOBALS['tiny_logo_2'];
183 $displaySmallLogo = false;
184 if ($t1 && !$t2) {
185 $displaySmallLogo = 1;
186 } if ($t2 && !$t1) {
187 $displaySmallLogo = 2;
188 } if ($t1 && $t2) {
189 $displaySmallLogo = 3;
192 $regTranslations = json_encode(array(
193 'title' => xla('OpenEMR Product Registration'),
194 'pleaseProvideValidEmail' => xla('Please provide a valid email address'),
195 'success' => xla('Success'),
196 'registeredSuccess' => xla('Your installation of OpenEMR has been registered'),
197 'submit' => xla('Submit'),
198 'noThanks' => xla('No Thanks'),
199 'registeredEmail' => xla('Registered email'),
200 'registeredId' => xla('Registered id'),
201 'genericError' => xla('Error. Try again later'),
202 'closeTooltip' => ''
205 $cookie = '';
206 if (session_name()) {
207 $sid = urlencode(session_id());
208 $sname = urlencode(session_name());
209 $scparams = session_get_cookie_params();
210 $domain = $scparams['domain'];
211 $path = $scparams['path'];
212 $oldDate = gmdate('Y', strtotime("-1 years"));
213 $expires = gmdate(DATE_RFC1123, $oldDate);
214 $sameSite = empty($scparams['samesite']) ? '' : $scparams['samesite'];
215 $cookie = "{$sname}={$sid}; path={$path}; domain={$domain}; expires={$expires}";
217 if ($sameSite) {
218 $cookie .= "; SameSite={$sameSite}";
221 $cookie = json_encode($cookie);
224 $viewArgs = [
225 'title' => $openemr_name,
226 'displayLanguage' => $GLOBALS["language_menu_login"] && (count($languageList) != 1),
227 'defaultLangID' => $defaultLanguage['id'],
228 'defaultLangName' => $defaultLanguage['language'],
229 'languageList' => $languageList,
230 'relogin' => $relogin,
231 'loginFail' => isset($_SESSION["loginfailure"]) && $_SESSION["loginfailure"] == 1,
232 'displayFacilities' => (bool)$GLOBALS["login_into_facility"],
233 'facilityList' => $facilities,
234 'facilitySelected' => $facilitySelected,
235 'displayGoogleSignin' => !empty($GLOBALS['google_signin_enabled']) && !empty($GLOBALS['google_signin_client_id']),
236 'googleSigninClientID' => $GLOBALS['google_signin_client_id'],
237 'displaySmallLogo' => $displaySmallLogo,
238 'smallLogoOne' => $smallLogoOne,
239 'smallLogoTwo' => $smallLogoTwo,
240 'showTitleOnLogin' => $GLOBALS['show_label_login'],
241 'displayTagline' => $GLOBALS['show_tagline_on_login'],
242 'tagline' => $GLOBALS['login_tagline_text'],
243 'displayAck' => $GLOBALS['display_acknowledgements_on_login'],
244 'hasSession' => (bool)session_name(),
245 'cookieText' => $cookie,
246 'regTranslations' => $regTranslations,
247 'regConstants' => json_encode(['webroot' => $GLOBALS['webroot']]),
248 'siteID' => $_SESSION['site_id'],
249 'showLabels' => $GLOBALS['show_labels_on_login_form'],
250 'displayPrimaryLogo' => $GLOBALS['show_primary_logo'],
251 'primaryLogo' => $primaryLogo,
252 'primaryLogoWidth' => $GLOBALS['primary_logo_width'],
253 'logoPosition' => $GLOBALS['logo_position'],
254 'secondaryLogoWidth' => $GLOBALS['secondary_logo_width'],
255 'displaySecondaryLogo' => $GLOBALS['extra_logo_login'],
256 'secondaryLogo' => $secondaryLogo,
257 'secondaryLogoPosition' => $GLOBALS['secondary_logo_position'],
261 * @var EventDispatcher;
263 $ed = $GLOBALS['kernel']->getEventDispatcher();
265 $templatePageEvent = new TemplatePageEvent('login/login.php', [], $layout, $viewArgs);
266 $event = $ed->dispatch($templatePageEvent, TemplatePageEvent::RENDER_EVENT);
268 try {
269 echo $t->render($event->getTwigTemplate(), $event->getTwigVariables());
270 } catch (LoaderError | RuntimeError | SyntaxError $e) {
271 echo "<p style='font-size:24px; color: red;'>" . text($e->getMessage()) . '</p>';