1 | <?php |
||
2 | |||
3 | /** |
||
4 | * This is the entry point for every request that should return HTML |
||
5 | * (one exception is that it also returns translated text for javascript). |
||
6 | */ |
||
7 | |||
8 | // Bootstrap the script |
||
9 | require_once 'server/includes/bootstrap.php'; |
||
10 | |||
11 | /* |
||
12 | * Get the favicon either from theme or use the default. |
||
13 | * |
||
14 | * @param string theme the users theme |
||
15 | * @return string favicon |
||
16 | */ |
||
17 | function getFavicon($theme) { |
||
18 | $favicon = Theming::getFavicon($theme); |
||
19 | |||
20 | if (!isset($favicon) || $favicon === false) { |
||
21 | $favicon = 'client/resources/images/favicon.ico?kv2.2.0'; |
||
22 | } |
||
23 | |||
24 | return $favicon; |
||
25 | } |
||
26 | |||
27 | // If the user wants to logout (and is not using single-signon) |
||
28 | // then destroy the session and redirect to this page, so the login page |
||
29 | // will be shown |
||
30 | |||
31 | if (isset($_GET['logout'])) { |
||
32 | if (isset($_SESSION['_keycloak_auth'])) { |
||
33 | $keycloak_auth = $_SESSION['_keycloak_auth']->logout(); |
||
34 | header("Location:" . $keycloak_auth . ""); |
||
35 | } |
||
36 | else { |
||
37 | // GET variable user will be set when the user was logged out because of session timeout |
||
38 | // or because he logged out in another window. |
||
39 | $username = sanitizeGetValue('user', '', USERNAME_REGEX); |
||
40 | $location = rtrim(dirname((string) $_SERVER['PHP_SELF']), '/') . '/'; |
||
41 | header('Location: ' . $location . ($username ? '?user=' . rawurlencode((string) $username) : ''), true, 303); |
||
42 | } |
||
43 | $webappSession->destroy(); |
||
44 | |||
45 | exit; |
||
46 | } |
||
47 | |||
48 | // Check if an action GET-parameter was sent with the request. |
||
49 | // This parameter is set when the webapp was opened by clicking on |
||
50 | // a mailto: link in the browser. |
||
51 | // If so, we will store it in the session, so we can use it later. |
||
52 | if (isset($_GET['action']) && !empty($_GET['action'])) { |
||
53 | storeURLDataToSession(); |
||
54 | } |
||
55 | |||
56 | // Check if the continue parameter was set. This will be set e.g. when someone |
||
57 | // uses the grommunio Web to login to another application with OpenID Connect. |
||
58 | if (isset($_GET['continue']) && !empty($_GET['continue']) && !isset($_GET['wacontinue'])) { |
||
59 | $_SESSION['continue'] = $_GET['continue']; |
||
60 | } |
||
61 | |||
62 | // Try to authenticate the user |
||
63 | WebAppAuthentication::authenticate(); |
||
64 | |||
65 | $webappTitle = defined('WEBAPP_TITLE') && WEBAPP_TITLE ? WEBAPP_TITLE : 'grommunio Web'; |
||
66 | if (isset($_COOKIE['webapp_title'])) { |
||
67 | $webappTitle .= " – " . $_COOKIE['webapp_title']; |
||
68 | } |
||
69 | |||
70 | // If we could not authenticate the user, we will show the login page |
||
71 | if (!WebAppAuthentication::isAuthenticated()) { |
||
72 | // Get language from the cookie, or from the language that is set by the admin |
||
73 | $Language = new Language(); |
||
74 | $lang = $_COOKIE['lang'] ?? LANG; |
||
75 | $lang = $Language->resolveLanguage($lang); |
||
76 | $Language->setLanguage($lang); |
||
77 | |||
78 | // If GET parameter 'load' is defined, we defer handling to the load.php script |
||
79 | if (isset($_GET['load']) && $_GET['load'] !== 'logon') { |
||
80 | include BASE_PATH . 'server/includes/load.php'; |
||
81 | |||
82 | exit; |
||
83 | } |
||
84 | |||
85 | // Set some template variables for the login page |
||
86 | $version = 'grommunio Web ' . trim(file_get_contents('version')); |
||
87 | $user = sanitizeGetValue('user', '', USERNAME_REGEX); |
||
88 | |||
89 | $url = '?logon'; |
||
90 | |||
91 | if (isset($_GET["logout"]) && $_GET["logout"] == "auto") { |
||
92 | $error = _("You have been automatically logged out"); |
||
93 | } |
||
94 | else { |
||
95 | $error = WebAppAuthentication::getErrorMessage(); |
||
96 | if (empty($error) && useSecureCookies() && getRequestProtocol() == 'http') { |
||
97 | header("HTTP/1.0 400 Bad Request"); |
||
98 | include BASE_PATH . 'server/includes/templates/BadRequest.php'; |
||
99 | error_log("Rejected insecure request as configuration for 'SECURE_COOKIES' is true."); |
||
100 | |||
101 | exit; |
||
102 | } |
||
103 | } |
||
104 | |||
105 | // If a username was passed as GET parameter we will prefill the username input |
||
106 | // of the login form with it. |
||
107 | $user = isset($_GET['user']) ? htmlentities((string) $_GET['user']) : ''; |
||
108 | |||
109 | // Lets add a header when login failed (DeskApp needs it to identify failed login attempts) |
||
110 | if (WebAppAuthentication::getErrorCode() !== NOERROR) { |
||
111 | header("X-grommunio-Hresult: " . get_mapi_error_name(WebAppAuthentication::getErrorCode())); |
||
112 | } |
||
113 | |||
114 | // Set a template variable for the favicon of the login, welcome, and webclient page |
||
115 | $theme = Theming::getActiveTheme(); |
||
116 | $favicon = getFavicon(Theming::getActiveTheme()); |
||
117 | include BASE_PATH . 'server/includes/templates/login.php'; |
||
118 | |||
119 | exit; |
||
120 | } |
||
121 | |||
122 | // The user is authenticated! Let's get ready to start the webapp. |
||
123 | // If the user just logged in or if url data was stored in the session, |
||
124 | // we will redirect to make sure that a browser refresh will not post |
||
125 | // the credentials again, and that the url data is taken away from the |
||
126 | // url in the address bar (so a browser refresh will not pass them again) |
||
127 | if (isset($_GET['code']) || (WebAppAuthentication::isUsingLoginForm() || isset($_GET['action']) && !empty($_GET['action']))) { |
||
128 | $location = rtrim(dirname((string) $_SERVER['PHP_SELF']), '/') . '/'; |
||
129 | header('Location: ' . $location, true, 303); |
||
130 | |||
131 | exit; |
||
132 | } |
||
133 | |||
134 | // TODO: we could replace all references to $GLOBALS['mapisession'] |
||
135 | // with WebAppAuthentication::getMAPISession(), that way we would |
||
136 | // lose at least one GLOBAL (because globals suck) |
||
137 | $GLOBALS['mapisession'] = WebAppAuthentication::getMAPISession(); |
||
138 | |||
139 | // check if it's DB or LDAP for the password plugin |
||
140 | $result = @json_decode(@file_get_contents(ADMIN_API_STATUS_ENDPOINT, false), true); |
||
0 ignored issues
–
show
Bug
introduced
by
![]() |
|||
141 | if (isset($result['ldap']) && $result['ldap']) { |
||
142 | $GLOBALS['usersinldap'] = true; |
||
143 | } |
||
144 | |||
145 | // Instantiate Plugin Manager and init the plugins (btw: globals suck) |
||
146 | $GLOBALS['PluginManager'] = new PluginManager(ENABLE_PLUGINS); |
||
147 | $GLOBALS['PluginManager']->detectPlugins(DISABLED_PLUGINS_LIST); |
||
148 | |||
149 | // Initialize plugins and prevent any output which might be written as |
||
150 | // plugins might be uncleanly output white-space and other stuff. We must |
||
151 | // not allow this here as it can destroy the response data. |
||
152 | ob_start(); |
||
153 | $GLOBALS['PluginManager']->initPlugins(DEBUG_LOADER); |
||
154 | ob_end_clean(); |
||
155 | |||
156 | // Create globals settings object (btw: globals suck) |
||
157 | $GLOBALS["settings"] = new Settings(); |
||
158 | |||
159 | // Create global operations object |
||
160 | $GLOBALS["operations"] = new Operations(); |
||
161 | |||
162 | // If webapp feature is not enabled for the user, |
||
163 | // we will show the login page with appropriated error message. |
||
164 | if ($GLOBALS['mapisession']->isWebappDisableAsFeature()) { |
||
165 | header("X-grommunio-Hresult: " . get_mapi_error_name(ecLoginPerm)); |
||
166 | |||
167 | $error = _("Sorry, access to grommunio Web is not available with this user account. Please contact your system administrator."); |
||
168 | // Set some template variables for the login page |
||
169 | $user = sanitizeGetValue('user', '', USERNAME_REGEX); |
||
170 | |||
171 | $url = '?logon'; |
||
172 | // Set a template variable for the favicon of the login, welcome, and webclient page |
||
173 | $theme = Theming::getActiveTheme(); |
||
174 | $favicon = getFavicon(Theming::getActiveTheme()); |
||
175 | $webappSession->destroy(); |
||
176 | // Include the login template |
||
177 | include BASE_PATH . 'server/includes/templates/login.php'; |
||
178 | |||
179 | exit; |
||
180 | } |
||
181 | |||
182 | $Language = new Language(); |
||
183 | |||
184 | // Set session settings (language & style) |
||
185 | foreach ($GLOBALS["settings"]->getSessionSettings($Language) as $key => $value) { |
||
186 | $_SESSION[$key] = $value; |
||
187 | } |
||
188 | |||
189 | // Get language from the request, or the session, or the user settings, or the config |
||
190 | if (isset($_REQUEST["language"]) && $Language->is_language($_REQUEST["language"])) { |
||
191 | $lang = $_REQUEST["language"]; |
||
192 | $GLOBALS["settings"]->set("zarafa/v1/main/language", $lang); |
||
193 | } |
||
194 | elseif (isset($_SESSION["lang"])) { |
||
195 | $lang = $_SESSION["lang"]; |
||
196 | $GLOBALS["settings"]->set("zarafa/v1/main/language", $lang); |
||
197 | } |
||
198 | else { |
||
199 | $lang = $GLOBALS["settings"]->get("zarafa/v1/main/language"); |
||
200 | if (empty($lang)) { |
||
201 | $lang = LANG; |
||
202 | $GLOBALS["settings"]->set("zarafa/v1/main/language", $lang); |
||
203 | } |
||
204 | } |
||
205 | |||
206 | $Language->setLanguage($lang); |
||
207 | setcookie('lang', (string) $lang, [ |
||
208 | 'expires' => time() + 31536000, |
||
209 | 'path' => '/', |
||
210 | 'domain' => '', |
||
211 | 'secure' => true, |
||
212 | 'httponly' => true, |
||
213 | 'samesite' => 'Strict', |
||
214 | ]); |
||
215 | |||
216 | // add extra header |
||
217 | header("X-grommunio: " . trim(file_get_contents('version'))); |
||
218 | |||
219 | // Set a template variable for the favicon of the login, welcome, and webclient page |
||
220 | $theme = Theming::getActiveTheme(); |
||
221 | $favicon = getFavicon(Theming::getActiveTheme()); |
||
222 | $hideFavorites = $GLOBALS["settings"]->get("zarafa/v1/contexts/hierarchy/hide_favorites") ? 'hideFavorites' : ''; |
||
223 | $scrollFavorites = $GLOBALS["settings"]->get("zarafa/v1/contexts/hierarchy/scroll_favorites") ? 'scrollFavorites' : ''; |
||
224 | $unreadBorders = $GLOBALS["settings"]->get("zarafa/v1/main/unread_borders") === false ? '' : 'k-unreadborders'; |
||
225 | |||
226 | // If GET parameter 'load' is defined, we defer handling to the load.php script |
||
227 | if (isset($_GET['load'])) { |
||
228 | include BASE_PATH . 'server/includes/load.php'; |
||
229 | |||
230 | exit; |
||
231 | } |
||
232 | |||
233 | if (ENABLE_WELCOME_SCREEN && $GLOBALS["settings"]->get("zarafa/v1/main/show_welcome") !== false) { |
||
234 | // These hooks are defined twice (also when there is a "load" argument supplied) |
||
235 | $GLOBALS['PluginManager']->triggerHook("server.index.load.welcome.before"); |
||
236 | include BASE_PATH . 'server/includes/templates/welcome.php'; |
||
237 | $GLOBALS['PluginManager']->triggerHook("server.index.load.welcome.after"); |
||
238 | } |
||
239 | else { |
||
240 | // Set the show_welcome to false, so that when the admin is changing the |
||
241 | // ENABLE_WELCOME_SCREEN option to false after some time, the users who are already |
||
242 | // using grommunio Web are not bothered with the Welcome Screen. |
||
243 | $GLOBALS["settings"]->set("zarafa/v1/main/show_welcome", false); |
||
244 | |||
245 | // Clean up old state files in tmp/session/ |
||
246 | $state = new State("index"); |
||
247 | $state->clean(); |
||
248 | |||
249 | // Clean up old attachments in tmp/attachments/ |
||
250 | $state = new AttachmentState(); |
||
251 | $state->clean(); |
||
252 | |||
253 | // Fetch the hierarchy state cache for unread counters notifications for subfolders |
||
254 | $counterState = new State('counters_sessiondata'); |
||
255 | $counterState->open(); |
||
256 | $counterState->write("sessionData", updateHierarchyCounters()); |
||
257 | $counterState->close(); |
||
258 | |||
259 | // clean search folders |
||
260 | cleanSearchFolders(); |
||
261 | |||
262 | // These hooks are defined twice (also when there is a "load" argument supplied) |
||
263 | $GLOBALS['PluginManager']->triggerHook("server.index.load.main.before"); |
||
264 | |||
265 | // Include webclient |
||
266 | include BASE_PATH . 'server/includes/templates/webclient.php'; |
||
267 | $GLOBALS['PluginManager']->triggerHook("server.index.load.main.after"); |
||
268 | } |
||
269 |