1: <?php
2:
3: /**
4: * Core modules
5: * @package modules
6: * @subpackage core
7: */
8:
9: /**
10: * Check the folder list icon setting
11: * @subpackage core/handler
12: */
13: class Hm_Handler_check_folder_icon_setting extends Hm_Handler_Module {
14: /***
15: * set a flag to use folder list icons or not
16: */
17: public function process() {
18: $this->out('hide_folder_icons', $this->user_config->get('no_folder_icons_setting', DEFAULT_NO_FOLDER_ICONS));
19: }
20: }
21:
22: /**
23: * Process a password update
24: * @subpackage core/handler
25: */
26: class Hm_Handler_process_pw_update extends Hm_Handler_Module {
27: /***
28: * update a password in the session for a server
29: */
30: public function process() {
31: list($success, $form ) = $this->process_form(array('server_pw_id', 'password'));
32: $missing = $this->get('missing_pw_servers', array());
33: if (!$success) {
34: return;
35: }
36: if (!array_key_exists($form['server_pw_id'], $missing)) {
37: return;
38: }
39: $server = $missing[$form['server_pw_id']];
40: switch ($server['type']) {
41: case 'SMTP':
42: $current = Hm_SMTP_List::dump($server['id']);
43: $current['pass'] = $form['password'];
44: unset($current['nopass']);
45: Hm_SMTP_List::edit($server['id'], $current);
46: $smtp = Hm_SMTP_List::connect($server['id'], false);
47: if ($smtp->state == 'authed') {
48: Hm_Msgs::add('Password Updated');
49: $this->out('connect_status', true);
50: }
51: else {
52: unset($current['pass']);
53: Hm_SMTP_List::edit($server['id'], $current);
54: Hm_Msgs::add('Unable to authenticate to the SMTP server', 'warning');
55: $this->out('connect_status', false);
56: }
57: break;
58: case 'IMAP':
59: $current = Hm_IMAP_List::dump($server['id']);
60: $current['pass'] = $form['password'];
61: unset($current['nopass']);
62: Hm_IMAP_List::edit($server['id'], $current);
63: $mailbox = Hm_IMAP_List::connect($server['id'], false);
64: if ($mailbox && $mailbox->authed()) {
65: Hm_Msgs::add('Password Updated');
66: $this->out('connect_status', true);
67: }
68: else {
69: unset($current['pass']);
70: Hm_IMAP_List::edit($server['id'], $current);
71: Hm_Msgs::add('Unable to authenticate to the IMAP server', 'warning');
72: $this->out('connect_status', false);
73: }
74: break;
75: }
76: }
77: }
78:
79: /**
80: * Check for missing passwords to populate a home page dialog
81: * @subpackage core/handler
82: */
83: class Hm_Handler_check_missing_passwords extends Hm_Handler_Module {
84: /***
85: * pass a list of servers with missing passwords to the output modules
86: */
87: public function process() {
88: if (!$this->user_config->get('no_password_save_setting', DEFAULT_NO_PASSWORD_SAVE)) {
89: return;
90: }
91: $missing = array();
92: if ($this->module_is_supported('imap')) {
93: foreach (Hm_IMAP_List::dump() as $index => $vals) {
94: if (array_key_exists('nopass', $vals)) {
95: $vals['type'] = 'IMAP';
96: $key = 'imap_'.$index;
97: $missing[$key] = $vals;
98: }
99: }
100: }
101: if ($this->module_is_supported('smtp')) {
102: foreach (Hm_SMTP_List::dump() as $index => $vals) {
103: if (array_key_exists('nopass', $vals)) {
104: $vals['type'] = 'SMTP';
105: $key = 'smtp_'.$index;
106: $missing[$key] = $vals;
107: }
108: }
109: }
110: if (count($missing) > 0) {
111: $this->out('missing_pw_servers', $missing);
112: }
113: }
114: }
115:
116: /**
117: * Close the session before it's automatically closed at the end of page processing
118: * @subpackage core/handler
119: */
120: class Hm_Handler_close_session_early extends Hm_Handler_Module {
121: /***
122: * Uses the close_early method of the session this->session object
123: */
124: public function process() {
125: $this->session->close_early();
126: }
127: }
128:
129: /**
130: * Build a list of HTTP headers to output to the browser
131: * @subpackage core/handler
132: */
133: class Hm_Handler_http_headers extends Hm_Handler_Module {
134: /***
135: * These are pretty restrictive, but the idea is to have a secure starting point
136: */
137: public function process() {
138: $headers = array();
139: if ($this->get('language',DEFAULT_SETTING_LANGUAGE)) {
140: $headers['Content-Language'] = mb_substr($this->get('language',DEFAULT_SETTING_LANGUAGE), 0, 2);
141: }
142: if ($this->request->tls) {
143: $headers['Strict-Transport-Security'] = 'max-age=31536000';
144: }
145: $img_src = "'self'";
146: if ($this->config->get('allow_external_image_sources', false)) {
147: $img_src = '*';
148: }
149: $headers['X-Frame-Options'] = 'SAMEORIGIN';
150: $headers['X-XSS-Protection'] = '1; mode=block';
151: $headers['X-Content-Type-Options'] = 'nosniff';
152: $headers['Expires'] = gmdate('D, d M Y H:i:s \G\M\T', strtotime('-1 year'));
153: $headers['Content-Security-Policy'] = "default-src 'none'; script-src 'self' 'unsafe-inline'; " .
154: "connect-src 'self'; font-src 'self' https://fonts.gstatic.com; img-src " . $img_src . " data:; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com;";
155: if ($this->request->type == 'AJAX') {
156: $headers['Content-Type'] = 'application/json';
157: }
158: $this->out('http_headers', $headers, false);
159: if (array_key_exists('hm_reload_folders', $this->request->cookie)) {
160: $this->session->set('hm_reload_folders', $this->session->get('hm_reload_folders', 0) + 1);
161: }
162: if ($this->session->get('hm_reload_folders', false) > 2) {
163: $this->session->delete_cookie($this->request, 'hm_reload_folders');
164: $this->session->del('hm_reload_folders');
165: }
166: }
167: }
168:
169: /**
170: * Process input from the the mailto handler setting in the general settings section.
171: * @subpackage core/handler
172: */
173: class Hm_Handler_process_mailto_handler_setting extends Hm_Handler_Module {
174: /**
175: * Can be one true or false
176: */
177: public function process() {
178: function mailto_handler_callback($val) {
179: return $val;
180: }
181: process_site_setting('mailto_handler', $this, 'mailto_handler_callback', false, true);
182: }
183: }
184:
185: /**
186: * Process input from the the list style setting in the general settings section.
187: * @subpackage core/handler
188: */
189: class Hm_Handler_process_list_style_setting extends Hm_Handler_Module {
190: /**
191: * Can be one of two values, 'email_style' or 'list_style'. The default is 'email_style'.
192: */
193: public function process() {
194: function list_style_callback($val) {
195: if (in_array($val, array('email_style', 'news_style'))) {
196: return $val;
197: }
198: return DEFAULT_LIST_STYLE;
199: }
200: process_site_setting('list_style', $this, 'list_style_callback', DEFAULT_LIST_STYLE);
201: }
202: }
203:
204: /**
205: * Process input from the the start page setting in the general settings section.
206: * @subpackage core/handler
207: */
208: class Hm_Handler_process_start_page_setting extends Hm_Handler_Module {
209: /**
210: * Can be one of the values in start_page_opts()
211: */
212: public function process() {
213: function start_page_callback($val) {
214: if (in_array($val, start_page_opts(), true)) {
215: return $val;
216: }
217: return false;
218: }
219: process_site_setting('start_page', $this, 'start_page_callback',DEFAULT_START_PAGE);
220: }
221: }
222:
223: /**
224: * Check the default sort order
225: * @subpackage core/handler
226: */
227: class Hm_Handler_default_sort_order_setting extends Hm_Handler_Module {
228: /***
229: * retrieve default sort order of messages
230: */
231: public function process() {
232: $this->out('default_sort_order', $this->user_config->get('default_sort_order_setting', 'arrival'));
233: $this->out('list_sort', $this->request->get['sort'] ?? null);
234: }
235: }
236:
237: /**
238: * Process input from the the default sort order setting in the general settings section.
239: * @subpackage core/handler
240: */
241: class Hm_Handler_process_default_sort_order_setting extends Hm_Handler_Module {
242: /**
243: * Can be one of the values in start_page_opts()
244: */
245: public function process() {
246: function default_sort_order_callback($val) {
247: if (in_array($val, array_keys(default_sort_order_opts()), true)) {
248: return $val;
249: }
250: return false;
251: }
252: process_site_setting('default_sort_order', $this, 'default_sort_order_callback');
253: }
254: }
255:
256: /**
257: * Process "hide folder list icons" setting
258: * @subpackage core/handler
259: */
260: class Hm_Handler_process_hide_folder_icons extends Hm_Handler_Module {
261: /**
262: * valid values are true or false
263: */
264: public function process() {
265: function hide_folder_icons_callback($val) {
266: return $val;
267: }
268: process_site_setting('no_folder_icons', $this, 'hide_folder_icons_callback', DEFAULT_NO_FOLDER_ICONS, true);
269: }
270: }
271:
272: /**
273: * Process "show icons in message lists" setting for the message list page in the settings page
274: * @subpackage core/handler
275: */
276: class Hm_Handler_process_show_list_icons extends Hm_Handler_Module {
277: /**
278: * valid values are true or false
279: */
280: public function process() {
281: function show_list_icons_callback($val) {
282: return $val;
283: }
284: process_site_setting('show_list_icons', $this, 'show_list_icons_callback', DEFAULT_SHOW_LIST_ICONS, true);
285: }
286: }
287:
288: /**
289: * Process input from the max per source setting for the Unread page in the settings page
290: * @subpackage core/handler
291: */
292: class Hm_Handler_process_unread_source_max_setting extends Hm_Handler_Module {
293: /**
294: * Allowed values are greater than zero and less than MAX_PER_SOURCE
295: */
296: public function process() {
297: process_site_setting('unread_per_source', $this, 'max_source_setting_callback', DEFAULT_UNREAD_PER_SOURCE);
298: }
299: }
300:
301: /**
302: * Process input from the max per source setting for the All E-mail page in the settings page
303: * @subpackage core/handler
304: */
305: class Hm_Handler_process_all_email_source_max_setting extends Hm_Handler_Module {
306: /**
307: * Allowed values are greater than zero and less than MAX_PER_SOURCE
308: */
309: public function process() {
310: process_site_setting('all_email_per_source', $this, 'max_source_setting_callback', DEFAULT_ALL_EMAIL_PER_SOURCE);
311: }
312: }
313:
314: /**
315: * Process input from the no pasword between logins setting
316: * @subpackage core/handler
317: */
318: class Hm_Handler_process_no_password_setting extends Hm_Handler_Module {
319: /**
320: * Allowed vals are bool true/false
321: */
322: public function process() {
323: function no_password_callback($val) {
324: return $val;
325: }
326: process_site_setting('no_password_save', $this, 'no_password_callback', false, true);
327: }
328: }
329:
330: /**
331: * Process input from the disable delete prompts setting
332: * @subpackage core/handler
333: */
334: class Hm_Handler_process_delete_prompt_setting extends Hm_Handler_Module {
335: /**
336: * Allowed vals are bool true/false
337: */
338: public function process() {
339: function delete_disabled_callback($val) {
340: return $val;
341: }
342: process_site_setting('disable_delete_prompt', $this, 'delete_disabled_callback', DEFAULT_DISABLE_DELETE_PROMPT, true);
343: }
344: }
345:
346: /**
347: * Process input from the disable delete attachment setting
348: * @subpackage core/handler
349: */
350: class Hm_Handler_process_delete_attachment_setting extends Hm_Handler_Module {
351: /**
352: * Allowed vals are bool true/false
353: */
354: public function process() {
355: function delete_attachment_callback($val) {
356: return $val;
357: }
358: process_site_setting('allow_delete_attachment', $this, 'delete_attachment_callback', true, true);
359: }
360: }
361:
362: /**
363: * Process input from the max per source setting for the Everything page in the settings page
364: * @subpackage core/handler
365: */
366: class Hm_Handler_process_all_source_max_setting extends Hm_Handler_Module {
367: /**
368: * Allowed values are greater than zero and less than MAX_PER_SOURCE
369: */
370: public function process() {
371: process_site_setting('all_per_source', $this, 'max_source_setting_callback', DEFAULT_ALL_PER_SOURCE);
372: }
373: }
374:
375: /**
376: * Process input from the max per source setting for the Flagged page in the settings page
377: * @subpackage core/handler
378: */
379: class Hm_Handler_process_flagged_source_max_setting extends Hm_Handler_Module {
380: /**
381: * Allowed values are greater than zero and less than MAX_PER_SOURCE
382: */
383: public function process() {
384: process_site_setting('flagged_per_source', $this,'max_source_setting_callback', DEFAULT_PER_SOURCE);
385: }
386: }
387:
388: /**
389: * Process "since" setting for the Flagged page in the settings page
390: * @subpackage core/handler
391: */
392: class Hm_Handler_process_flagged_since_setting extends Hm_Handler_Module {
393: /**
394: * valid values are defined in the process_since_argument function
395: */
396: public function process() {
397: process_site_setting('flagged_since', $this, 'since_setting_callback', DEFAULT_FLAGGED_SINCE);
398: }
399: }
400:
401: /**
402: * Process input from the max per source setting for the Snoozed page in the settings page
403: * @subpackage core/handler
404: */
405: class Hm_Handler_process_snoozed_source_max_setting extends Hm_Handler_Module {
406: /**
407: * Allowed values are greater than zero and less than MAX_PER_SOURCE
408: */
409: public function process() {
410: process_site_setting('snoozed_per_source', $this, 'max_source_setting_callback', DEFAULT_SNOOZED_PER_SOURCE);
411: }
412: }
413:
414: /**
415: * Process "since" setting for the Snoozed page in the settings page
416: * @subpackage core/handler
417: */
418: class Hm_Handler_process_snoozed_since_setting extends Hm_Handler_Module {
419: /**
420: * valid values are defined in the process_since_argument function
421: */
422: public function process() {
423: process_site_setting('snoozed_since', $this, 'since_setting_callback', DEFAULT_SNOOZED_SINCE);
424: }
425: }
426:
427: /**
428: * Process the enable/disable snooze setting
429: * @subpackage core/handler
430: */
431: class Hm_Handler_process_enable_snooze_setting extends Hm_Handler_Module {
432: /**
433: * Process the enable/disable snooze setting
434: */
435: public function process() {
436: function enable_snooze_setting_callback($val) { return $val; }
437: process_site_setting('enable_snooze', $this, 'enable_snooze_setting_callback', DEFAULT_ENABLE_SNOOZE, true);
438: }
439: }
440:
441: /**
442: * Process "since" setting for the Everything page in the settings page
443: * @subpackage core/handler
444: */
445: class Hm_Handler_process_all_since_setting extends Hm_Handler_Module {
446: /**
447: * valid values are defined in the process_since_argument function
448: */
449: public function process() {
450: process_site_setting('all_since', $this, 'since_setting_callback', DEFAULT_ALL_SINCE);
451: }
452: }
453:
454: /**
455: * Process "since" setting for the All E-mail page in the settings page
456: * @subpackage core/handler
457: */
458: class Hm_Handler_process_all_email_since_setting extends Hm_Handler_Module {
459: /**
460: * valid values are defined in the process_since_argument function
461: */
462: public function process() {
463: process_site_setting('all_email_since', $this, 'since_setting_callback', DEFAULT_ALL_EMAIL_SINCE);
464: }
465: }
466:
467: /**
468: * Process "since" setting for the Unread page in the settings page
469: * @subpackage core/handler
470: */
471: class Hm_Handler_process_unread_since_setting extends Hm_Handler_Module {
472: /**
473: * valid values are defined in the process_since_argument function
474: */
475: public function process() {
476: process_site_setting('unread_since', $this, 'since_setting_callback', $this->user_config->get('default_setting_unread_since'));
477: }
478: }
479:
480: /**
481: * Process language setting from the general section of the settings page
482: * @subpackage core/handler
483: */
484: class Hm_Handler_process_language_setting extends Hm_Handler_Module {
485: /**
486: * compared against the list in modules/core/functions.php:interface_langs()
487: */
488: public function process() {
489: function language_setting_callback($val) {
490: if (array_key_exists($val, interface_langs())) {
491: return $val;
492: }
493: return DEFAULT_SETTING_LANGUAGE;
494: }
495: process_site_setting('language', $this, 'language_setting_callback',DEFAULT_SETTING_LANGUAGE);
496: }
497: }
498:
499: /**
500: * Process the timezone setting from the general section of the settings page
501: * @subpackage core/handler
502: */
503: class Hm_Handler_process_timezone_setting extends Hm_Handler_Module {
504: public function process() {
505: function timezone_setting_callback($val) {
506: if (in_array($val, timezone_identifiers_list(), true)) {
507: return $val;
508: }
509: return false;
510: }
511: process_site_setting('timezone', $this, 'timezone_setting_callback');
512: }
513: }
514:
515: /**
516: * Save user settings permanently
517: * @subpackage core/handler
518: */
519: class Hm_Handler_process_save_form extends Hm_Handler_Module {
520: /**
521: * save any changes since login to permanent storage
522: */
523: public function process() {
524: list($success, $form) = $this->process_form(array('password'));
525: if (!$success) {
526: return;
527: }
528: $save = false;
529: $logout = false;
530: if (array_key_exists('save_settings_permanently', $this->request->post)) {
531: $save = true;
532: }
533: elseif (array_key_exists('save_settings_permanently_then_logout', $this->request->post)) {
534: $save = true;
535: $logout = true;
536: }
537: if ($save) {
538: save_user_settings($this, $form, $logout);
539: }
540: }
541: }
542:
543: /**
544: * Save settings from the settings page to the session
545: * @subpackage core/handler
546: */
547: class Hm_Handler_save_user_settings extends Hm_Handler_Module {
548: /**
549: * save new site settings to the session
550: */
551: public function process() {
552: list($success, $form) = $this->process_form(array('save_settings'));
553: if (!$success) {
554: return;
555: }
556: if ($new_settings = $this->get('new_user_settings', array())) {
557: foreach ($new_settings as $name => $value) {
558: $this->user_config->set($name, $value);
559: }
560: Hm_Msgs::add('Settings updated');
561: $this->session->record_unsaved('Site settings updated');
562: $this->out('reload_folders', true, false);
563: }
564: }
565: }
566:
567: /**
568: * Do reset factory from the settings page to the session
569: * @subpackage core/handler
570: */
571: class Hm_Handler_reset_factory extends Hm_Handler_Module {
572: /**
573: * reset user config to the default
574: */
575: public function process() {
576: list($success, $form) = $this->process_form(array('reset_factory'));
577: if (!$success) {
578: return;
579: }
580: $this->user_config->reset_factory();
581: Hm_Msgs::add('Settings restored to default');
582: $this->session->record_unsaved('Site settings restored to default');
583: $this->out('reload_folders', true, false);
584: }
585: }
586:
587: /**
588: * Setup a default title
589: * @subpackage core/handler
590: */
591: class Hm_Handler_title extends Hm_Handler_Module {
592: /**
593: * output a default title based on the page URL argument
594: */
595: public function process() {
596: $this->out('title', ucfirst($this->page));
597: }
598: }
599:
600: /**
601: * Setup the current language
602: * @subpackage core/handler
603: */
604: class Hm_Handler_language extends Hm_Handler_Module {
605: /**
606: * output the user configured language or English if not set
607: */
608: public function process() {
609: $this->out('language', $this->user_config->get('language_setting', DEFAULT_SETTING_LANGUAGE));
610: }
611: }
612:
613: /**
614: * Setup the date
615: * @subpackage core/handler
616: */
617: class Hm_Handler_date extends Hm_Handler_Module {
618: /**
619: * output a simple date string
620: */
621: public function process() {
622: $this->out('date', date('G:i:s'));
623: }
624: }
625:
626: /**
627: * Check for the "stay logged in" option
628: */
629: class Hm_Handler_stay_logged_in extends Hm_Handler_Module {
630: /**
631: * If "stay logged in" is checked, set the session lifetime
632: */
633: public function process() {
634: if ($this->config->get('allow_long_session')) {
635: $this->out('allow_long_session', true);
636: }
637: $lifetime = intval($this->config->get('long_session_lifetime', 30));
638: list($success, $form) = $this->process_form(array('stay_logged_in'));
639: if ($success && $form['stay_logged_in']) {
640: $this->session->lifetime = time()+60*60*24*$lifetime;
641: }
642: }
643: }
644:
645: /**
646: * Process a potential login attempt
647: * @subpackage core/handler
648: */
649: class Hm_Handler_login extends Hm_Handler_Module {
650: /**
651: * Perform a new login if the form was submitted, otherwise check for and continue a session if it exists
652: */
653: public $validate_request = true;
654: public function process() {
655: $this->out('fancy_login_allowed', $this->config->get('fancy_login', false));
656: $this->out('is_mobile', $this->request->mobile);
657: if ($this->get('create_username', false)) {
658: return;
659: }
660: list($success, $form) = $this->process_form(array('username', 'password'));
661: if ($success) {
662: $this->session->check($this->request, rtrim($form['username']), $form['password']);
663: if (!$this->session->is_active()) {
664: Hm_Msgs::add("Invalid username or password", "warning");
665: }
666: $this->session->set('username', rtrim($form['username']));
667: if ($this->config->get('redirect_after_login')) {
668: $this->out('redirect_url', $this->config->get('redirect_after_login'));
669: }
670: }
671: else {
672: $this->session->check($this->request);
673: }
674: if ($this->session->is_active()) {
675: $this->out('changed_settings', $this->session->get('changed_settings', array()), false);
676: $this->out('username', $this->session->get('username'));
677: $this->out('is_logged', true);
678: }
679: if ($this->validate_request) {
680: Hm_Request_Key::load($this->session, $this->request, $this->session->loaded);
681: $this->validate_method($this->session, $this->request);
682: $this->process_key();
683: if (!$this->config->get('disable_origin_check', false)) {
684: $this->validate_origin($this->session, $this->request, $this->config);
685: }
686: }
687: }
688: }
689:
690: /**
691: * Setup default page data
692: * @subpackage core/handler
693: */
694: class Hm_Handler_default_page_data extends Hm_Handler_Module {
695: public function process() {
696: $this->out('data_sources', array(), false);
697: $this->out('encrypt_ajax_requests', $this->config->get('encrypt_ajax_requests', false));
698: $this->out('encrypt_local_storage', $this->config->get('encrypt_local_storage', false));
699: $this->out('default_timezone', $this->user_config->get('default_setting_timezone', 'UTC'));
700: $this->out('enabled_modules', $this->config->get_modules());
701: if (!crypt_state($this->config)) {
702: $this->out('single_server_mode', true);
703: }
704: }
705: }
706:
707: /**
708: * Load user data
709: * @subpackage core/handler
710: */
711: class Hm_Handler_load_user_data extends Hm_Handler_Module {
712: /**
713: * Load data from persistant storage on login, or from the session if already logged in
714: */
715: public function process() {
716: list($success, $form) = $this->process_form(array('username', 'password'));
717: if ($this->session->is_active()) {
718: if ($success) {
719: $this->user_config->load(rtrim($form['username']), $form['password']);
720: }
721: else {
722: $user_data = $this->session->get('user_data', array());
723: if (!empty($user_data)) {
724: $this->user_config->reload($user_data, $this->session->get('username'));
725: }
726: $pages = $this->user_config->get('saved_pages', array());
727: if (!empty($pages)) {
728: $this->session->set('saved_pages', $pages);
729: }
730: }
731: $this->out('disable_delete_prompt', $this->user_config->get('disable_delete_prompt_setting', DEFAULT_DISABLE_DELETE_PROMPT));
732: }
733: if ($this->session->loaded) {
734: $start_page = $this->user_config->get('start_page_setting');
735: if ($start_page && $start_page != 'none' && in_array($start_page, start_page_opts(), true)) {
736: $this->out('redirect_url', '?'.$start_page);
737: }
738: }
739: $this->out('mailto_handler', $this->user_config->get('mailto_handler_setting', false));
740: $this->out('warn_for_unsaved_changes', $this->user_config->get('warn_for_unsaved_changes_setting', false));
741: $this->out('no_password_save', $this->user_config->get('no_password_save_setting', DEFAULT_NO_PASSWORD_SAVE));
742: $this->out('user_settings', $this->user_config->dump(), false);
743: if (!mb_strstr($this->request->server['REQUEST_URI'], 'page=') && $this->page == 'home') {
744: $start_page = $this->user_config->get('start_page_setting', false);
745: if ($start_page && $start_page != 'none' && in_array($start_page, start_page_opts(), true)) {
746: $this->out('redirect_url', '?'.$start_page);
747: }
748: }
749: }
750: }
751:
752: /**
753: * Save user data to the session
754: * @subpackage core/handler
755: */
756: class Hm_Handler_save_user_data extends Hm_Handler_Module {
757: /**
758: * @todo rename to make it obvious this is session only
759: */
760: public function process() {
761: $user_data = $this->user_config->dump();
762: if (!empty($user_data)) {
763: $this->session->set('user_data', $user_data);
764: }
765: }
766: }
767:
768: /**
769: * Process a logout
770: * @subpackage core/handler
771: */
772: class Hm_Handler_logout extends Hm_Handler_Module {
773: /**
774: * Clean up everything on logout
775: */
776: public function process() {
777: if (array_key_exists('logout', $this->request->post) && !$this->session->loaded) {
778: $this->session->destroy($this->request);
779: Hm_Msgs::add('Session destroyed on logout', 'info');
780: }
781: elseif (array_key_exists('save_and_logout', $this->request->post)) {
782: list($success, $form) = $this->process_form(array('password'));
783: if ($success) {
784: $user = $this->session->get('username', false);
785: $path = $this->config->get('user_settings_dir', false);
786: $pages = $this->session->get('saved_pages', array());
787: if (!empty($pages)) {
788: $this->user_config->set('saved_pages', $pages);
789: }
790: if ($this->session->auth($user, $form['password'])) {
791: $pass = $form['password'];
792: }
793: else {
794: Hm_Msgs::add('Incorrect password, could not save settings to the server', 'warning');
795: $pass = false;
796: }
797: if ($user && $path && $pass) {
798: try {
799: $this->user_config->save($user, $pass);
800: $this->session->destroy($this->request);
801: Hm_Msgs::add('Saved user data on logout, Session destroyed on logout', 'info');
802: } catch (Exception $e) {
803: Hm_Msgs::add('Could not save settings: ' . $e->getMessage(), 'warning');
804: }
805: }
806: }
807: else {
808: Hm_Msgs::add('Your password is required to save your settings to the server', 'warning');
809: }
810: }
811: }
812: }
813:
814: /**
815: * Setup the message list type based on URL arguments
816: * @subpackage core/handler
817: */
818: class Hm_Handler_message_list_type extends Hm_Handler_Module {
819: /**
820: * @todo clean this up somehow
821: */
822: public function process() {
823: $uid = '';
824: $list_parent = '';
825: $list_page = 1;
826: $list_meta = true;
827: $list_path = '';
828: $mailbox_list_title = array();
829: $message_list_since = DEFAULT_SINCE;
830: $per_source_limit = DEFAULT_PER_SOURCE;
831: $no_list_headers = false;
832:
833: if (array_key_exists('list_path', $this->request->get)) {
834: $path = $this->request->get['list_path'];
835: list($list_path, $mailbox_list_title, $message_list_since, $per_source_limit) = get_message_list_settings($path, $this);
836: }
837: if (array_key_exists('list_parent', $this->request->get)) {
838: $list_parent = $this->request->get['list_parent'];
839: }
840: if (array_key_exists('list_page', $this->request->get)) {
841: $list_page = (int) $this->request->get['list_page'];
842: if ($list_page < 1) {
843: $list_page = 1;
844: }
845: }
846: else {
847: $list_page = 1;
848: }
849: if (array_key_exists('uid', $this->request->get) && preg_match("/^[0-9a-z]+$/i", $this->request->get['uid'])) {
850: $uid = $this->request->get['uid'];
851: }
852: $list_style = $this->user_config->get('list_style_setting', DEFAULT_LIST_STYLE);
853: if ($this->get('is_mobile', false)) {
854: $list_style = 'news_style';
855: }
856: if ($list_style == 'news_style') {
857: $no_list_headers = true;
858: $this->out('news_list_style', true);
859: }
860: $this->out('uid', $uid);
861: $this->out('list_path', $list_path, false);
862: $this->out('list_meta', $list_meta, false);
863: $this->out('list_parent', $list_parent, false);
864: $this->out('list_page', $list_page, false);
865: $this->out('mailbox_list_title', $mailbox_list_title, false);
866: $this->out('message_list_since', $message_list_since, false);
867: $this->out('per_source_limit', $per_source_limit, false);
868: $this->out('no_message_list_headers', $no_list_headers);
869: $this->out('msg_list_icons', $this->user_config->get('show_list_icons_setting', false));
870: $this->out('message_list_fields', array(
871: array('chkbox_col', false, false),
872: array('source_col', 'source', 'Source'),
873: array('from_col', 'from', 'From'),
874: array('subject_col', 'subject', 'Subject'),
875: array('date_col', 'msg_date', 'Date'),
876: array('icon_col', false, false)), false);
877: }
878: }
879:
880: /**
881: * Set a cookie to instruct the JS to reload the folder list
882: * @subpackage core/handler
883: */
884: class Hm_Handler_reload_folder_cookie extends Hm_Handler_Module {
885: /**
886: * This cookie will be deleted by JS
887: */
888: public function process() {
889: if ($this->get('reload_folders', false)) {
890: $this->session->secure_cookie($this->request, 'hm_reload_folders', '1');
891: $this->session->set('hm_reload_folders', 1);
892: }
893: }
894: }
895:
896: /**
897: * @subpackage core/handler
898: */
899: class Hm_Handler_reset_search extends Hm_Handler_Module {
900: public function process() {
901: $this->session->set('search_terms', '');
902: $this->session->set('search_since', DEFAULT_SEARCH_SINCE);
903: $this->session->set('search_fld', DEFAULT_SEARCH_FLD);
904: }
905: }
906:
907: /**
908: * Process search terms from a URL
909: * @subpackage core/handler
910: */
911: class Hm_Handler_process_search_terms extends Hm_Handler_Module {
912: /**
913: * validate and set search tems in the session
914: */
915: public function process() {
916: if (array_key_exists('search_terms', $this->request->get) && $this->request->get['search_terms']) {
917: $this->out('run_search', 1, false);
918: $this->session->set('search_terms', validate_search_terms($this->request->get['search_terms']));
919: }
920: if (array_key_exists('search_since', $this->request->get)) {
921: $this->session->set('search_since', process_since_argument($this->request->get['search_since'], true));
922: }
923: if (array_key_exists('search_fld', $this->request->get)) {
924: $this->session->set('search_fld', validate_search_fld($this->request->get['search_fld']));
925: }
926: $this->out('search_since', $this->session->get('search_since', DEFAULT_SEARCH_SINCE));
927: $this->out('search_terms', $this->session->get('search_terms', ''));
928: $this->out('search_fld', $this->session->get('search_fld', DEFAULT_SEARCH_FLD));
929: if ($this->session->get('search_terms')) {
930: $this->out('run_search', 1);
931: }
932: }
933: }
934:
935: /**
936: * Process input from the max per source setting for the Junk page in the settings page
937: * @subpackage core/handler
938: */
939: class Hm_Handler_process_junk_source_max_setting extends Hm_Handler_Module {
940: /**
941: * Allowed values are greater than zero and less than MAX_PER_SOURCE
942: */
943: public function process() {
944: process_site_setting('junk_per_source', $this, 'max_source_setting_callback', DEFAULT_JUNK_PER_SOURCE);
945: }
946: }
947:
948: /**
949: * Process "since" setting for the junk page in the settings page
950: * @subpackage core/handler
951: */
952: class Hm_Handler_process_junk_since_setting extends Hm_Handler_Module {
953: /**
954: * valid values are defined in the process_since_argument function
955: */
956: public function process() {
957: process_site_setting('junk_since', $this, 'since_setting_callback', DEFAULT_JUNK_SINCE);
958: }
959: }
960:
961: /**
962: * Process input from the max per source setting for the Trash page in the settings page
963: * @subpackage core/handler
964: */
965: class Hm_Handler_process_trash_source_max_setting extends Hm_Handler_Module {
966: /**
967: * Allowed values are greater than zero and less than MAX_PER_SOURCE
968: */
969: public function process() {
970: process_site_setting('trash_per_source', $this, 'max_source_setting_callback', DEFAULT_TRASH_PER_SOURCE);
971: }
972: }
973:
974: /**
975: * Process "since" setting for the trash page in the settings page
976: * @subpackage core/handler
977: */
978: class Hm_Handler_process_trash_since_setting extends Hm_Handler_Module {
979: /**
980: * valid values are defined in the process_since_argument function
981: */
982: public function process() {
983: process_site_setting('trash_since', $this, 'since_setting_callback');
984: }
985: }
986:
987: /**
988: * Process input from the max per source setting for the Draft page in the settings page
989: * @subpackage core/handler
990: */
991: class Hm_Handler_process_drafts_source_max_setting extends Hm_Handler_Module {
992: /**
993: * Allowed values are greater than zero and less than MAX_PER_SOURCE
994: */
995: public function process() {
996: process_site_setting('drafts_per_source', $this, 'max_source_setting_callback', DEFAULT_DRAFT_PER_SOURCE);
997: }
998: }
999:
1000: /**
1001: * Process "since" setting for the Drafts page in the settings page
1002: * @subpackage core/handler
1003: */
1004: class Hm_Handler_process_drafts_since_setting extends Hm_Handler_Module {
1005: /**
1006: * valid values are defined in the process_since_argument function
1007: */
1008: public function process() {
1009: process_site_setting('drafts_since', $this, 'since_setting_callback', DEFAULT_DRAFT_SINCE);
1010: }
1011: }
1012:
1013: /**
1014: * Process warn for unsaved changes in the settings page
1015: * @subpackage core/handler
1016: */
1017: class Hm_Handler_process_warn_for_unsaved_changes_setting extends Hm_Handler_Module {
1018: /**
1019: * valid values are true and false
1020: */
1021: public function process() {
1022: function warn_for_unsaved_changes_callback($val) {
1023: return $val;
1024: }
1025: process_site_setting('warn_for_unsaved_changes', $this, 'warn_for_unsaved_changes_callback', false, true);
1026: }
1027: }
1028:
1029: /**
1030: * @subpackage core/handler
1031: */
1032: class Hm_Handler_quick_servers_setup extends Hm_Handler_Module {
1033: public $smtp_server_id = null;
1034: public $imap_server_id = null;
1035: public $jmap_server_id = null;
1036:
1037: public function process() {
1038: list($success, $form) = $this->process_form(array(
1039: 'srv_setup_stepper_profile_name',
1040: 'srv_setup_stepper_email',
1041: 'srv_setup_stepper_password',
1042: 'srv_setup_stepper_provider',
1043: 'srv_setup_stepper_is_sender',
1044: 'srv_setup_stepper_is_receiver',
1045: 'srv_setup_stepper_smtp_address',
1046: 'srv_setup_stepper_smtp_port',
1047: 'srv_setup_stepper_smtp_tls',
1048: 'srv_setup_stepper_imap_address',
1049: 'srv_setup_stepper_imap_port',
1050: 'srv_setup_stepper_imap_tls',
1051: 'srv_setup_stepper_enable_sieve',
1052: 'srv_setup_stepper_create_profile',
1053: 'srv_setup_stepper_profile_is_default',
1054: 'srv_setup_stepper_profile_signature',
1055: 'srv_setup_stepper_profile_reply_to',
1056: 'srv_setup_stepper_imap_sieve_host',
1057: 'srv_setup_stepper_imap_sieve_mode_tls',
1058: 'srv_setup_stepper_only_jmap',
1059: 'srv_setup_stepper_imap_hide_from_c_page',
1060: 'srv_setup_stepper_jmap_address',
1061: 'srv_setup_stepper_imap_server_id',
1062: 'srv_setup_stepper_smtp_server_id',
1063: ));
1064: if ($success) {
1065: // Destructure form array into variables
1066: [
1067: 'srv_setup_stepper_profile_name' => $profileName,
1068: 'srv_setup_stepper_email' => $email,
1069: 'srv_setup_stepper_password' => $password,
1070: 'srv_setup_stepper_provider' => $provider,
1071: 'srv_setup_stepper_is_sender' => $isSender,
1072: 'srv_setup_stepper_is_receiver' => $isReceiver,
1073: 'srv_setup_stepper_smtp_address' => $smtpAddress,
1074: 'srv_setup_stepper_smtp_port' => $smtpPort,
1075: 'srv_setup_stepper_smtp_tls' => $smtpTls,
1076: 'srv_setup_stepper_imap_address' => $imapAddress,
1077: 'srv_setup_stepper_imap_port' => $imapPort,
1078: 'srv_setup_stepper_imap_tls' => $imapTls,
1079: 'srv_setup_stepper_enable_sieve' => $enableSieve,
1080: 'srv_setup_stepper_create_profile' => $createProfile,
1081: 'srv_setup_stepper_profile_is_default' => $profileIsDefault,
1082: 'srv_setup_stepper_profile_signature' => $profileSignature,
1083: 'srv_setup_stepper_profile_reply_to' => $profileReplyTo,
1084: 'srv_setup_stepper_imap_sieve_host' => $imapSieveHost,
1085: 'srv_setup_stepper_imap_sieve_mode_tls' => $imapSieveTls,
1086: 'srv_setup_stepper_only_jmap' => $onlyJmap,
1087: 'srv_setup_stepper_imap_hide_from_c_page' => $hideFromCombinedView,
1088: 'srv_setup_stepper_jmap_address' => $jmapAddress,
1089: 'srv_setup_stepper_imap_server_id' => $imapServerId,
1090: 'srv_setup_stepper_smtp_server_id' => $smtpServerId
1091: ] = $form;
1092:
1093: /*
1094: * Connect to SMTP server if user wants to send emails
1095: */
1096: if($isSender){
1097: if (!$this->module_is_supported('smtp')) {
1098: Hm_Msgs::add("SMTP module is not enabled",'danger');
1099: return;
1100: }
1101: $this->smtp_server_id = connect_to_smtp_server($smtpAddress, $profileName, $smtpPort, $email, $password, $smtpTls, 'smtp', $smtpServerId);
1102: if(!isset($this->smtp_server_id)){
1103: Hm_Msgs::add("Could not save server", 'danger');
1104: return;
1105: }
1106: }
1107:
1108: /*
1109: * When JMAP selected only configure JMAP
1110: */
1111: if(isset($onlyJmap) && $onlyJmap) {
1112: if (!$this->module_is_supported('jmap')) {
1113: Hm_Msgs::add("JMAP module is not enabled", "danger");
1114: return;
1115: }
1116:
1117: $this->jmap_server_id = connect_to_imap_server(
1118: $jmapAddress,
1119: $profileName,
1120: $imapPort,
1121: $email,
1122: $password,
1123: $imapTls,
1124: null,
1125: false,
1126: 'jmap',
1127: $this,
1128: $hideFromCombinedView,
1129: $imapServerId,
1130: $imapSieveTls
1131: );
1132:
1133: if(!isset($this->jmap_server_id)) {
1134: Hm_Msgs::add("Could not save JMAP server", "warning");
1135: return;
1136: };
1137:
1138: Hm_Msgs::add("JMAP Server saved");
1139: $this->out('just_saved_credentials', true);
1140: return;
1141: } else {
1142:
1143: /*
1144: * Connect to IMAP server if user wants to receive emails
1145: */
1146: if($isReceiver){
1147: if (!$this->module_is_supported('imap')) {
1148: Hm_Msgs::add("IMAP module is not enabled", "danger");
1149: return;
1150: }
1151:
1152: $this->imap_server_id = connect_to_imap_server(
1153: $imapAddress,
1154: $profileName,
1155: $imapPort,
1156: $email,
1157: $password,
1158: $imapTls,
1159: $imapSieveHost,
1160: $enableSieve,
1161: 'imap',
1162: $this,
1163: $hideFromCombinedView,
1164: $imapServerId,
1165: $imapSieveTls
1166: );
1167:
1168: if(!isset($this->imap_server_id)) {
1169: if($isSender && isset($this->smtp_server_id)){
1170: delete_smtp_server($this->smtp_server_id, $this);
1171: }
1172: Hm_Msgs::add("Could not save IMAP server", "warning");
1173: return;
1174: };
1175: }
1176:
1177: if ($this->module_is_supported('imap_folders')) {
1178: $this->out('imap_server_id', $this->imap_server_id);
1179: $this->out('imap_service_name', $provider);
1180: }
1181: $this->out('just_saved_credentials', true);
1182: Hm_Msgs::add("Server saved. To preserve these settings after logout, please go to <a class='alert-link' href='/?page=save'>Save Settings</a>.");
1183: }
1184:
1185: if ($createProfile && $this->smtp_server_id && ($this->imap_server_id || $this->jmap_server_id)) {
1186: if (!$this->module_is_supported('profiles')) {
1187: Hm_Msgs::add("Profiles module is not enabled", "danger");
1188: return;
1189: }
1190:
1191: add_profile($profileName, $profileSignature, $profileReplyTo, $profileIsDefault, $email, $imapAddress, $email, $this->smtp_server_id, $this->imap_server_id ?? $this->jmap_server_id, $this);
1192: }
1193: }
1194: }
1195: }
1196:
1197: class Hm_Handler_privacy_settings extends Hm_Handler_Module {
1198:
1199: public function process() {
1200: $settings = Hm_Output_privacy_settings::$settings;
1201: foreach ($settings as $key => $setting) {
1202: process_site_setting($key, $this, 'privacy_setting_callback');
1203: }
1204: }
1205: }
1206: