| 1: | <?php |
| 2: | use Symfony\Component\Yaml\Yaml; |
| 3: | |
| 4: | |
| 5: | |
| 6: | |
| 7: | |
| 8: | |
| 9: | |
| 10: | |
| 11: | if (!defined('DEBUG_MODE')) { die(); } |
| 12: | |
| 13: | require_once APP_PATH.'modules/nux/functions.php'; |
| 14: | require_once APP_PATH.'modules/nux/services.php'; |
| 15: | require_once APP_PATH.'modules/profiles/hm-profiles.php'; |
| 16: | require_once APP_PATH.'modules/profiles/functions.php'; |
| 17: | |
| 18: | |
| 19: | |
| 20: | |
| 21: | class Hm_Handler_nux_dev_news extends Hm_Handler_Module { |
| 22: | public function process() { |
| 23: | if (!DEBUG_MODE) { |
| 24: | return; |
| 25: | } |
| 26: | $cache = $this->cache->get('nux_dev_news', array()); |
| 27: | if ($cache) { |
| 28: | $this->out('nux_dev_news', $cache); |
| 29: | return; |
| 30: | } |
| 31: | $res = array(); |
| 32: | $ch = Hm_Functions::c_init(); |
| 33: | if ($ch) { |
| 34: | Hm_Functions::c_setopt($ch, CURLOPT_URL, 'https://api.github.com/repos/cypht-org/cypht/commits'); |
| 35: | Hm_Functions::c_setopt($ch, CURLOPT_RETURNTRANSFER, 1); |
| 36: | Hm_Functions::c_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5); |
| 37: | Hm_Functions::c_setopt($ch, CURLOPT_USERAGENT, $this->request->server["HTTP_USER_AGENT"]); |
| 38: | $curl_result = Hm_Functions::c_exec($ch); |
| 39: | if (trim($curl_result)) { |
| 40: | if (mb_strstr($curl_result, 'API rate limit exceeded')) { |
| 41: | return; |
| 42: | } |
| 43: | $json_commits = json_decode($curl_result); |
| 44: | foreach($json_commits as $c) { |
| 45: | $msg = trim($c->commit->message); |
| 46: | $res[] = array( |
| 47: | 'hash' => $c->sha, |
| 48: | 'shash' => mb_substr($c->sha, 0, 8), |
| 49: | 'name' => $c->commit->author->name, |
| 50: | 'age' => date('D, M d', strtotime($c->commit->author->date)), |
| 51: | 'note' => (mb_strlen($msg) > 80 ? mb_substr($msg, 0, 80) . "..." : $msg) |
| 52: | ); |
| 53: | } |
| 54: | } |
| 55: | } |
| 56: | $this->cache->set('nux_dev_news', $res); |
| 57: | $this->out('nux_dev_news', $res); |
| 58: | } |
| 59: | } |
| 60: | |
| 61: | |
| 62: | |
| 63: | |
| 64: | class Hm_Handler_nux_homepage_data extends Hm_Handler_Module { |
| 65: | public function process() { |
| 66: | |
| 67: | $imap_servers = NULL; |
| 68: | $jmap_servers = NULL; |
| 69: | $ews_servers = NULL; |
| 70: | $smtp_servers = NULL; |
| 71: | $feed_servers = NULL; |
| 72: | $profiles = NULL; |
| 73: | |
| 74: | $modules = $this->config->get_modules(); |
| 75: | |
| 76: | if (data_source_available($modules, 'imap')) { |
| 77: | $servers = Hm_IMAP_List::dump(false); |
| 78: | $imap_servers = count(array_filter($servers, function($server) { return empty($server['type']) || $server['type'] === 'imap'; })); |
| 79: | $jmap_servers = count(array_filter($servers, function($server) { return @$server['type'] === 'jmap'; })); |
| 80: | $ews_servers = count(array_filter($servers, function($server) { return @$server['type'] === 'ews'; })); |
| 81: | } |
| 82: | if (data_source_available($modules, 'feeds')) { |
| 83: | $feed_servers = count(Hm_Feed_List::dump(false)); |
| 84: | } |
| 85: | if (data_source_available($modules, 'smtp')) { |
| 86: | $servers = Hm_SMTP_List::dump(false); |
| 87: | $smtp_servers = count(array_filter($servers, function($server) { return empty($server['type']) || $server['type'] === 'smtp'; })); |
| 88: | } |
| 89: | if (data_source_available($modules, 'profiles')) { |
| 90: | Hm_Profiles::init($this); |
| 91: | $profiles = Hm_Profiles::count(); |
| 92: | } |
| 93: | |
| 94: | $this->out('nux_server_setup', array( |
| 95: | 'imap' => $imap_servers, |
| 96: | 'jmap' => $jmap_servers, |
| 97: | 'ews' => $ews_servers, |
| 98: | 'feeds' => $feed_servers, |
| 99: | 'smtp' => $smtp_servers, |
| 100: | 'profiles' => $profiles |
| 101: | )); |
| 102: | $this->out('tzone', $this->user_config->get('timezone_setting')); |
| 103: | } |
| 104: | } |
| 105: | |
| 106: | |
| 107: | |
| 108: | class Hm_Handler_process_oauth2_authorization extends Hm_Handler_Module { |
| 109: | public function process() { |
| 110: | if (array_key_exists('state', $this->request->get) && $this->request->get['state'] == 'nux_authorization') { |
| 111: | if (array_key_exists('code', $this->request->get)) { |
| 112: | $details = $this->session->get('nux_add_service_details'); |
| 113: | $oauth2 = new Hm_Oauth2($details['client_id'], $details['client_secret'], $details['redirect_uri']); |
| 114: | $result = $oauth2->request_token($details['token_uri'], $this->request->get['code']); |
| 115: | if (!empty($result) && array_key_exists('access_token', $result)) { |
| 116: | Hm_IMAP_List::add(array( |
| 117: | 'name' => $details['name'], |
| 118: | 'server' => $details['server'], |
| 119: | 'port' => $details['port'], |
| 120: | 'tls' => $details['tls'], |
| 121: | 'user' => $details['email'], |
| 122: | 'pass' => $result['access_token'], |
| 123: | 'expiration' => strtotime(sprintf("+%d seconds", $result['expires_in'])), |
| 124: | 'refresh_token' => $result['refresh_token'], |
| 125: | 'auth' => 'xoauth2', |
| 126: | 'type' => $details['type'] |
| 127: | )); |
| 128: | if (isset($details['smtp'])) { |
| 129: | Hm_SMTP_List::add(array( |
| 130: | 'name' => $details['name'], |
| 131: | 'server' => $details['smtp']['server'], |
| 132: | 'port' => $details['smtp']['port'], |
| 133: | 'tls' => $details['smtp']['tls'], |
| 134: | 'auth' => 'xoauth2', |
| 135: | 'user' => $details['email'], |
| 136: | 'pass' => $result['access_token'], |
| 137: | 'expiration' => strtotime(sprintf("+%d seconds", $result['expires_in'])), |
| 138: | 'refresh_token' => $result['refresh_token'], |
| 139: | 'type' => 'smtp' |
| 140: | )); |
| 141: | $this->session->record_unsaved('SMTP server added'); |
| 142: | } |
| 143: | Hm_Msgs::add("E-mail account successfully added, To preserve these settings after logout, please go to <a class='alert-link' href='/?page=save'>Save Settings</a>."); |
| 144: | Hm_IMAP_List::clean_up(); |
| 145: | $this->session->del('nux_add_service_details'); |
| 146: | $this->session->record_unsaved('IMAP server added'); |
| 147: | $this->session->secure_cookie($this->request, 'hm_reload_folders', '1'); |
| 148: | $this->session->close_early(); |
| 149: | } |
| 150: | else { |
| 151: | Hm_Msgs::add('An Error Occurred', 'danger'); |
| 152: | } |
| 153: | } |
| 154: | elseif (array_key_exists('error', $this->request->get)) { |
| 155: | Hm_Msgs::add(ucwords(str_replace('_', ' ', $this->request->get['error'])), 'danger'); |
| 156: | } |
| 157: | else { |
| 158: | Hm_Msgs::add('An Error Occurred', 'danger'); |
| 159: | } |
| 160: | $this->save_hm_msgs(); |
| 161: | Hm_Dispatch::page_redirect('?page=servers'); |
| 162: | } |
| 163: | } |
| 164: | } |
| 165: | |
| 166: | |
| 167: | |
| 168: | |
| 169: | class Hm_Handler_process_nux_add_service extends Hm_Handler_Module { |
| 170: | public function process() { |
| 171: | list($success, $form) = $this->process_form(array('nux_pass', 'nux_service', 'nux_email', 'nux_name')); |
| 172: | if ($success) { |
| 173: | if (Nux_Quick_Services::exists($form['nux_service'])) { |
| 174: | $details = Nux_Quick_Services::details($form['nux_service']); |
| 175: | $details['name'] = $form['nux_name']; |
| 176: | if ($form['nux_service'] == 'all-inkl') { |
| 177: | $details['server'] = $this->request->post['nux_all_inkl_login'].$details['server']; |
| 178: | $details['smtp']['server'] = $this->request->post['nux_all_inkl_login'].$details['smtp']['server'] ; |
| 179: | } |
| 180: | $imap_list = array( |
| 181: | 'name' => $details['name'], |
| 182: | 'server' => $details['server'], |
| 183: | 'port' => $details['port'], |
| 184: | 'tls' => $details['tls'], |
| 185: | 'user' => $form['nux_email'], |
| 186: | 'pass' => $form['nux_pass'], |
| 187: | 'type' => $details['type'] |
| 188: | ); |
| 189: | if ($details['sieve'] && $this->module_is_supported('sievefilters') && $this->user_config->get('enable_sieve_filter_setting', DEFAULT_ENABLE_SIEVE_FILTER)) { |
| 190: | $imap_list['sieve_config_host'] = $details['sieve']['host'].':'.$details['sieve']['port']; |
| 191: | $imap_list['sieve_tls'] = $details['sieve']['tls']; |
| 192: | } |
| 193: | $new_id = Hm_IMAP_List::add($imap_list); |
| 194: | if (! can_save_last_added_server('Hm_IMAP_List', $form['nux_email'])) { |
| 195: | return; |
| 196: | } |
| 197: | $mailbox = Hm_IMAP_List::connect($new_id, false); |
| 198: | if ($mailbox && $mailbox->authed()) { |
| 199: | if (isset($details['smtp'])) { |
| 200: | Hm_SMTP_List::add(array( |
| 201: | 'name' => $details['name'], |
| 202: | 'server' => $details['smtp']['server'], |
| 203: | 'port' => $details['smtp']['port'], |
| 204: | 'tls' => $details['smtp']['tls'], |
| 205: | 'user' => $form['nux_email'], |
| 206: | 'pass' => $form['nux_pass'], |
| 207: | 'type' => 'smtp' |
| 208: | )); |
| 209: | if (can_save_last_added_server('Hm_SMTP_List', $form['nux_email'])) { |
| 210: | $this->session->record_unsaved('SMTP server added'); |
| 211: | } |
| 212: | } |
| 213: | Hm_IMAP_List::clean_up(); |
| 214: | $this->session->record_unsaved('IMAP server added'); |
| 215: | $this->session->record_unsaved('SMTP server added'); |
| 216: | $this->session->secure_cookie($this->request, 'hm_reload_folders', '1'); |
| 217: | Hm_Msgs::add("E-mail account successfully added, To preserve these settings after logout, please go to <a class='alert-link' href='/?page=save'>Save Settings</a>."); |
| 218: | $this->session->close_early(); |
| 219: | $this->out('nux_account_added', true); |
| 220: | if ($this->module_is_supported('imap_folders')) { |
| 221: | $this->out('nux_server_id', $new_id); |
| 222: | $this->out('nux_service_name', $form['nux_service']); |
| 223: | } |
| 224: | } |
| 225: | else { |
| 226: | Hm_IMAP_List::del($new_id); |
| 227: | Hm_Msgs::add('Authentication failed', 'danger'); |
| 228: | } |
| 229: | } |
| 230: | } |
| 231: | } |
| 232: | } |
| 233: | |
| 234: | |
| 235: | |
| 236: | |
| 237: | class Hm_Handler_setup_nux extends Hm_Handler_Module { |
| 238: | public function process() { |
| 239: | Nux_Quick_Services::oauth2_setup($this->config); |
| 240: | } |
| 241: | } |
| 242: | |
| 243: | |
| 244: | |
| 245: | |
| 246: | class Hm_Handler_process_nux_service extends Hm_Handler_Module { |
| 247: | public function process() { |
| 248: | list($success, $form) = $this->process_form(array('nux_service', 'nux_email')); |
| 249: | if ($success) { |
| 250: | if (Nux_Quick_Services::exists($form['nux_service'])) { |
| 251: | $details = Nux_Quick_Services::details($form['nux_service']); |
| 252: | $details['id'] = $form['nux_service']; |
| 253: | $details['email'] = $form['nux_email']; |
| 254: | if (array_key_exists('nux_account_name', $this->request->post) && trim($this->request->post['nux_account_name'])) { |
| 255: | $details['name'] = $this->request->post['nux_account_name']; |
| 256: | } |
| 257: | $this->out('nux_add_service_details', $details); |
| 258: | $this->session->set('nux_add_service_details', $details); |
| 259: | } |
| 260: | } |
| 261: | } |
| 262: | } |
| 263: | |
| 264: | |
| 265: | |
| 266: | |
| 267: | class Hm_Handler_get_nux_service_details extends Hm_Handler_Module { |
| 268: | public function process() { |
| 269: | list($success, $form) = $this->process_form(array('nux_service')); |
| 270: | if ($success) { |
| 271: | if (Nux_Quick_Services::exists($form['nux_service'])) { |
| 272: | $details = Nux_Quick_Services::details($form['nux_service']); |
| 273: | |
| 274: | $this->out('nux_add_service_details', $details); |
| 275: | $this->session->set('nux_add_service_details', $details); |
| 276: | } |
| 277: | } |
| 278: | } |
| 279: | } |
| 280: | |
| 281: | |
| 282: | |
| 283: | |
| 284: | class Hm_Handler_process_import_accouts_servers extends Hm_Handler_Module |
| 285: | { |
| 286: | public function process() |
| 287: | { |
| 288: | list($success, $form) = $this->process_form(array('accounts_source')); |
| 289: | |
| 290: | if ($success) { |
| 291: | if (! check_file_upload($this->request, 'accounts_sample')) { |
| 292: | Hm_Msgs::add('Error while uploading accounts sample', 'danger'); |
| 293: | return; |
| 294: | } |
| 295: | try { |
| 296: | $extension = pathinfo($this->request->files['accounts_sample']['name'], PATHINFO_EXTENSION); |
| 297: | if (in_array(strtolower($extension), ['yaml', 'yml'])) { |
| 298: | $servers = Yaml::parseFile($this->request->files['accounts_sample']['tmp_name']); |
| 299: | } elseif (in_array($this->request->files['accounts_sample']['type'], ['text/csv', 'text/plain'])) { |
| 300: | $servers = []; |
| 301: | $server_data = parse_csv_with_headers($this->request->files['accounts_sample']['tmp_name']); |
| 302: | |
| 303: | |
| 304: | foreach ($server_data as $server_row) { |
| 305: | $data = []; |
| 306: | $server_name = $server_row['server_name']; |
| 307: | unset($server_row['server_name']); |
| 308: | foreach ($server_row as $key => $value) { |
| 309: | if (strpos($key, '_') !== false) { |
| 310: | list($prefix, $suffix) = explode('_', $key, 2); |
| 311: | $data[$prefix][$suffix] = $value; |
| 312: | } else { |
| 313: | $data[$key] = $value; |
| 314: | } |
| 315: | } |
| 316: | $servers[$server_name] = $data; |
| 317: | } |
| 318: | } |
| 319: | } catch (\Exception $e) { |
| 320: | Hm_Msgs::add($e->getMessage(), 'danger'); |
| 321: | return; |
| 322: | } |
| 323: | if(empty($servers)) { |
| 324: | Hm_Msgs::add('Imported file is empty', 'warning'); |
| 325: | return; |
| 326: | } |
| 327: | $errors = []; |
| 328: | $successes = []; |
| 329: | foreach ($servers as $server_name => $server) { |
| 330: | $jmap_server_id = $imap_server_id = $smtp_server_id = null; |
| 331: | if (! empty($server['jmap']['server'])) { |
| 332: | if (! $this->module_is_supported('jmap')) { |
| 333: | $errors[] = 'JMAP module is not enabled'; |
| 334: | } else { |
| 335: | $jmap_server_id = connect_to_imap_server( |
| 336: | $server['jmap']['server'], |
| 337: | $server_name, |
| 338: | null, |
| 339: | $server['username'], |
| 340: | $server['password'], |
| 341: | false, |
| 342: | null, |
| 343: | false, |
| 344: | 'jmap', |
| 345: | $this, |
| 346: | $server['jmap']['hide_from_combined_view'], |
| 347: | false, |
| 348: | $server['sieve']['tls'], |
| 349: | false |
| 350: | ); |
| 351: | if (! $jmap_server_id) { |
| 352: | $errors[] = "Failed to save server $server_name: JMAP problem"; |
| 353: | continue; |
| 354: | } |
| 355: | } |
| 356: | } elseif (! empty($server['imap']['server'])) { |
| 357: | if (! $this->module_is_supported('imap')) { |
| 358: | $errors[] = 'IMAP module is not enabled'; |
| 359: | } else { |
| 360: | $imap_server_id = connect_to_imap_server( |
| 361: | $server['imap']['server'], |
| 362: | $server_name, |
| 363: | $server['imap']['port'], |
| 364: | $server['username'], |
| 365: | $server['password'], |
| 366: | $server['imap']['tls'], |
| 367: | $server['sieve']['host'].':'.($server['sieve']['port'] ?? 4190), |
| 368: | ! empty($server['sieve']['host']), |
| 369: | 'imap', |
| 370: | $this, |
| 371: | $server['imap']['hide_from_combined_view'], |
| 372: | false, |
| 373: | $server['sieve']['tls'], |
| 374: | false |
| 375: | ); |
| 376: | if (! $imap_server_id) { |
| 377: | $errors[] = "Failed to save server $server_name: IMAP problem"; |
| 378: | continue; |
| 379: | } |
| 380: | } |
| 381: | } |
| 382: | if (! empty($server['smtp']['server'])) { |
| 383: | if (!$this->module_is_supported('smtp')) { |
| 384: | $errors[] = 'SMTP module is not enabled'; |
| 385: | } else { |
| 386: | $smtp_server_id = connect_to_smtp_server( |
| 387: | $server['smtp']['server'], |
| 388: | $server_name, |
| 389: | $server['smtp']['port'], |
| 390: | $server['username'], |
| 391: | $server['password'], |
| 392: | $server['smtp']['tls'], |
| 393: | $server['type'], |
| 394: | false |
| 395: | ); |
| 396: | if (! $smtp_server_id) { |
| 397: | $errors[] = "Failed to save server $server_name: SMTP problem"; |
| 398: | if ($jmap_server_id) { |
| 399: | Hm_IMAP_List::del($jmap_server_id); |
| 400: | } elseif ($imap_server_id) { |
| 401: | Hm_IMAP_List::del($imap_server_id); |
| 402: | } |
| 403: | continue; |
| 404: | } |
| 405: | } |
| 406: | } |
| 407: | if(! empty($server['profile']['reply_to']) && ($imap_server_id || $jmap_server_id) && $smtp_server_id) { |
| 408: | if (!$this->module_is_supported('profiles')) { |
| 409: | $errors[] = 'Profiles module is not enabled'; |
| 410: | continue; |
| 411: | } |
| 412: | |
| 413: | Hm_Profiles::init($this); |
| 414: | |
| 415: | add_profile( |
| 416: | $server_name, |
| 417: | $server['profile']['signature'], |
| 418: | $server['profile']['reply_to'], |
| 419: | $server['profile']['is_default'], |
| 420: | $server['username'], |
| 421: | ($server['jmap']['server'] ?? $server['imap']['server']), |
| 422: | $server['username'], |
| 423: | $smtp_server_id, |
| 424: | ($jmap_server_id ?? $imap_server_id), |
| 425: | $this |
| 426: | ); |
| 427: | } |
| 428: | $successes[] = $server_name; |
| 429: | } |
| 430: | foreach (array_unique($errors) as $error) { |
| 431: | Hm_Msgs::add("$error", 'danger'); |
| 432: | } |
| 433: | foreach ($successes as $success) { |
| 434: | Hm_Msgs::add("Server $success imported successfully, To preserve these settings after logout, please go to <a href='/?save'>/?save</a>."); |
| 435: | } |
| 436: | } |
| 437: | } |
| 438: | } |
| 439: | |
| 440: | |
| 441: | |
| 442: | |
| 443: | |
| 444: | class Hm_Output_quick_add_dialog extends Hm_Output_Module { |
| 445: | protected function output() { |
| 446: | if ($this->get('single_server_mode')) { |
| 447: | return ''; |
| 448: | } |
| 449: | return '<div class="quick_add_section">'. |
| 450: | '<div class="nux_step_one px-4 pt-">'. |
| 451: | '<p class="py-3">'.$this->trans('Quickly add an account from popular E-mail providers. To manually configure an account, use the IMAP/SMTP sections below.').'</p>'. |
| 452: | '<div class="row"><div class="col col-lg-4"><div class="form-floating mb-3">'. |
| 453: | ' <select id="service_select" name="service_select" class="form-select">'. |
| 454: | '<option value="">'.$this->trans('Select an E-mail provider').'</option>'. |
| 455: | Nux_Quick_Services::option_list(false, $this).'</select>'. |
| 456: | '<label for="service_select">'.$this->trans('Select an E-mail provider').'</label></div>'. |
| 457: | |
| 458: | '<div class="form-floating mb-3">'. |
| 459: | '<input type="email" id="nux_username" class="form-control nux_username" placeholder="'.$this->trans('Your E-mail address').'">'. |
| 460: | '<label for="nux_username">'.$this->trans('Username').'</label></div>'. |
| 461: | |
| 462: | '<div class="form-floating mb-3">'. |
| 463: | '<input type="text" id="nux_account_name" class="form-control nux_account_name" placeholder="'.$this->trans('Account Name [optional]').'">'. |
| 464: | '<label for="nux_account_name">'.$this->trans('Account name').'</label></div>'. |
| 465: | |
| 466: | '<input type="button" class="nux_next_button btn btn-primary btn-md px-5" value="'.$this->trans('Next').'">'. |
| 467: | '</div></div></div><div class="nux_step_two px-4 pt-3"></div></div>'; |
| 468: | } |
| 469: | } |
| 470: | |
| 471: | |
| 472: | |
| 473: | |
| 474: | class Hm_Output_quick_add_multiple_dialog extends Hm_Output_Module { |
| 475: | protected function output() { |
| 476: | if ($this->get('single_server_mode')) { |
| 477: | return ''; |
| 478: | } |
| 479: | $notice = $this->trans('Please ensure your YAML or CSV file follows the correct format'); |
| 480: | $yaml_file_sample_path = ASSETS_PATH . 'data/server_accounts_sample.yaml'; |
| 481: | $csv_file_sample_path = ASSETS_PATH . 'data/server_accounts_sample.csv'; |
| 482: | |
| 483: | return '<div class="quick_add_multiple_section">' . |
| 484: | '<div class="row"><div class="col col-lg-6"><div class="form-floating mb-3">' . |
| 485: | '<form class="quick_add_multiple_server_form" action="?page=servers" method="POST" enctype="multipart/form-data">' . |
| 486: | '<p class="mt-2">' . $notice . '</p>' . |
| 487: | '<div class="server_form"><br />' . |
| 488: | '<div class="row">' . |
| 489: | '<div class="col-md-6">' . |
| 490: | '<div><a href="' . $yaml_file_sample_path . '" download data-external="true">' . $this->trans('Download a sample yaml file') . '</a></div>' . |
| 491: | '</div>' . |
| 492: | '<div class="col-md-6">' . |
| 493: | '<div><a href="' . $csv_file_sample_path . '" download data-external="true">' . $this->trans('Download a sample csv file') . '</a></div><br />' . |
| 494: | '</div>' . |
| 495: | '</div>' . |
| 496: | '<input type="hidden" name="hm_page_key" value="' . $this->html_safe(Hm_Request_Key::generate()) . '" />' . |
| 497: | '<input type="hidden" name="accounts_source" value="yaml" />' . |
| 498: | '<label class="screen_reader" for="accounts_sample">' . $this->trans('Yaml or csv File') . '</label>' . |
| 499: | '<input class="form-control" id="accounts_sample" type="file" name="accounts_sample" accept=".yaml,.csv"/> <br />' . |
| 500: | '<input class="btn btn-primary add_multiple_server_submit" type="submit" name="import_contact" id="import_contact" value="' . $this->trans('Add') . '" /> <input type="reset" class="btn btn-secondary reset_add_multiple_server" value="' . |
| 501: | $this->trans('Cancel') . '" /></div></form></div></div></div></div></div>'; |
| 502: | } |
| 503: | } |
| 504: | |
| 505: | |
| 506: | |
| 507: | |
| 508: | class Hm_Output_filter_service_select extends Hm_Output_Module { |
| 509: | protected function output() { |
| 510: | $details = $this->get('nux_add_service_details', array()); |
| 511: | if (!empty($details)) { |
| 512: | if (array_key_exists('auth', $details) && $details['auth'] == 'oauth2') { |
| 513: | $this->out('nux_service_step_two', oauth2_form($details, $this)); |
| 514: | } |
| 515: | else { |
| 516: | $this->out('nux_service_step_two', credentials_form($details, $this)); |
| 517: | } |
| 518: | } |
| 519: | } |
| 520: | } |
| 521: | |
| 522: | |
| 523: | |
| 524: | |
| 525: | class Hm_Output_service_details extends Hm_Output_Module { |
| 526: | protected function output() { |
| 527: | $details = $this->get('nux_add_service_details', array()); |
| 528: | $this->out('service_details', json_encode($details)); |
| 529: | } |
| 530: | } |
| 531: | |
| 532: | |
| 533: | |
| 534: | |
| 535: | class Hm_Output_nux_dev_news extends Hm_Output_Module { |
| 536: | protected function output() { |
| 537: | if (!$this->get('nux_dev_news')) { |
| 538: | return ''; |
| 539: | } |
| 540: | $res = '<div class="nux_dev_news mt-3 col-12"><div class="card"><div class="card-body"><div class="card_title"><h4>'.$this->trans('Development Updates').'</h4></div><div class="table-responsive"><table class="table table-bordered">'; |
| 541: | foreach ($this->get('nux_dev_news', array()) as $vals) { |
| 542: | $res .= sprintf('<tr><td><a href="https://github.com/cypht-org/cypht/commit/%s" target="_blank" rel="noopener">%s</a>'. |
| 543: | '</td><td class="msg_date">%s</td><td>%s</td><td>%s</td></tr>', |
| 544: | $this->html_safe($vals['hash']), |
| 545: | $this->html_safe($vals['shash']), |
| 546: | $this->html_safe($vals['name']), |
| 547: | $this->html_safe($vals['age']), |
| 548: | $this->html_safe($vals['note']) |
| 549: | ); |
| 550: | } |
| 551: | $res .= '</table></div></div></div></div>'; |
| 552: | return $res; |
| 553: | } |
| 554: | } |
| 555: | |
| 556: | |
| 557: | |
| 558: | |
| 559: | class Hm_Output_nux_help extends Hm_Output_Module { |
| 560: | protected function output() { |
| 561: | return '<div class="nux_help mt-3 col-lg-6 col-md-12 col-sm-12"><div class="card"><div class="card-body"><div class="card_title"><h4>'.$this->trans('Help').'</h4></div>'. |
| 562: | $this->trans('Cypht is a webmail aggregator client. You can use it to access your E-mail accounts from any server or service that offers any of the main protocols: IMAP/SMTP, Exchange Web Services (EWS) or the newest protocol: JMAP (RFC8621).').' '. |
| 563: | '</div></div></div>'; |
| 564: | } |
| 565: | } |
| 566: | |
| 567: | |
| 568: | |
| 569: | |
| 570: | class Hm_Output_start_welcome_dialog extends Hm_Output_Module { |
| 571: | protected function output() { |
| 572: | if ($this->get('single_server_mode')) { |
| 573: | return ''; |
| 574: | } |
| 575: | $res = '<div class="nux_welcome mt-3 col-lg-6 col-md-5 col-sm-12"><div class="card"><div class="card-body"><div class="card-title"><h4>'.$this->trans('Welcome to Cypht').'</h4></div>'; |
| 576: | $res .= '<div class="mb-3"><p>'.$this->trans('Add a popular E-mail source quickly and easily').'</p>'; |
| 577: | $res .= '<a class="mt-3 btn btn-light" href="?page=servers#quick_add_section"><i class="bi bi-person-plus me-3"></i>'.$this->trans('Add an E-mail Account').'</a>'; |
| 578: | $res .= '</div>'; |
| 579: | return $res; |
| 580: | } |
| 581: | } |
| 582: | |
| 583: | |
| 584: | |
| 585: | |
| 586: | class Hm_Output_end_welcome_dialog extends Hm_Output_Module { |
| 587: | protected function output() { |
| 588: | if ($this->get('single_server_mode')) { |
| 589: | return ''; |
| 590: | } |
| 591: | $server_data = $this->get('nux_server_setup', array()); |
| 592: | $tz = $this->get('tzone'); |
| 593: | $protos = array('imap', 'jmap', 'ews', 'smtp', 'feeds', 'profiles'); |
| 594: | |
| 595: | |
| 596: | $res = '<ul class="mt-4">'; |
| 597: | |
| 598: | foreach ($protos as $proto) { |
| 599: | $proto_dsp = $proto; |
| 600: | if ($proto == 'feeds') { |
| 601: | $proto_dsp = 'RSS/ATOM'; |
| 602: | } |
| 603: | $res .= '<li class="nux_'.$proto.' mt-3">'; |
| 604: | |
| 605: | |
| 606: | if ($proto == 'profiles') { |
| 607: | if ($server_data[$proto] === 0) { |
| 608: | $res .= sprintf($this->trans('You don\'t have any profile(s)')); |
| 609: | $res .= sprintf(' <a href="?page=profiles">%s</a>', $proto, $this->trans('Add')); |
| 610: | } |
| 611: | if ($server_data[$proto] > 0) { |
| 612: | $res .= sprintf($this->trans('You have %s profile(s)'), $server_data[$proto]); |
| 613: | $res .= sprintf(' <a href="?page=profiles">%s</a>', $this->trans('Manage')); |
| 614: | } |
| 615: | $res .= '</li>'; |
| 616: | continue; |
| 617: | } |
| 618: | |
| 619: | $section = in_array($proto, ['imap', 'smtp']) ? 'server_config' : $proto; |
| 620: | if ($server_data[$proto] === NULL) { |
| 621: | $res .= sprintf($this->trans('%s services are not enabled for this site. Sorry about that!'), mb_strtoupper($proto_dsp)); |
| 622: | } |
| 623: | elseif ($server_data[$proto] === 0) { |
| 624: | $res .= sprintf($this->trans('You don\'t have any %s sources'), mb_strtoupper($proto_dsp)); |
| 625: | $res .= sprintf(' <a href="?page=servers#%s_section">%s</a>', $section, $this->trans('Add')); |
| 626: | } |
| 627: | else { |
| 628: | if ($server_data[$proto] > 1) { |
| 629: | $res .= sprintf($this->trans('You have %d %s sources'), $server_data[$proto], mb_strtoupper($proto_dsp)); |
| 630: | } |
| 631: | else { |
| 632: | $res .= sprintf($this->trans('You have %d %s source'), $server_data[$proto], mb_strtoupper($proto_dsp)); |
| 633: | } |
| 634: | $res .= sprintf(' <a href="?page=servers#%s_section">%s</a>', $section, $this->trans('Manage')); |
| 635: | } |
| 636: | $res .= '</li>'; |
| 637: | } |
| 638: | $res .= '</ul>'; |
| 639: | $res .= '<div class="nux_tz">'; |
| 640: | if (!$tz) { |
| 641: | $res .= $this->trans('Your timezone is NOT set'); |
| 642: | } |
| 643: | else { |
| 644: | $res .= sprintf($this->trans('Your timezone is set to %s'), $this->html_safe($tz)); |
| 645: | } |
| 646: | $res .= ' <a href="?page=settings#general_setting">'.$this->trans('Update').'</a></div></div></div></div>'; |
| 647: | return $res; |
| 648: | } |
| 649: | } |
| 650: | |
| 651: | |
| 652: | |
| 653: | |
| 654: | class Hm_Output_nux_message_list_notice extends Hm_Output_Module { |
| 655: | protected function output() { |
| 656: | $msg = '<div class="nux_empty_combined_view">'; |
| 657: | $msg .= $this->trans('You don\'t have any data sources assigned to this page.'); |
| 658: | $msg .= '<br /><a href="?page=servers">'.$this->trans('Add some').'</a>'; |
| 659: | $msg .= '</div>'; |
| 660: | return $msg; |
| 661: | } |
| 662: | } |
| 663: | |
| 664: | |
| 665: | |
| 666: | |
| 667: | class Hm_Output_quick_add_section extends Hm_Output_Module { |
| 668: | protected function output() { |
| 669: | if ($this->get('single_server_mode')) { |
| 670: | return ''; |
| 671: | } |
| 672: | return '<div class="nux_add_account"><div data-target=".quick_add_section" class="server_section border-bottom cursor-pointer px-1 py-3 pe-auto"><a href="#" class="pe-auto">'. |
| 673: | '<i class="bi bi-check-circle-fill me-3"></i>'. |
| 674: | '<b>'.$this->trans('Add an E-mail Account').'</b></a></div>'; |
| 675: | } |
| 676: | } |
| 677: | |
| 678: | |
| 679: | |
| 680: | class Hm_Output_quick_add_multiple_section extends Hm_Output_Module { |
| 681: | protected function output() { |
| 682: | if ($this->get('single_server_mode')) { |
| 683: | return ''; |
| 684: | } |
| 685: | return '<div data-target=".quick_add_multiple_section" class="server_section border-bottom cursor-pointer px-1 py-3 pe-auto"><a href="#" class="pe-auto">' . |
| 686: | '<i class="bi bi-filetype-yml me-3"></i>' . |
| 687: | '<b>' . $this->trans('Bulk-import accounts using yaml or csv template') . '</b></a></div>'; |
| 688: | } |
| 689: | } |
| 690: | |
| 691: | |
| 692: | |
| 693: | |
| 694: | class Nux_Quick_Services { |
| 695: | |
| 696: | static private $services = array(); |
| 697: | static private $oauth2 = array(); |
| 698: | |
| 699: | static public function add($id, $details) { |
| 700: | self::$services[$id] = $details; |
| 701: | } |
| 702: | static public function oauth2_setup($config) { |
| 703: | $services = array_keys(config('oauth2')); |
| 704: | foreach ($services as $service) { |
| 705: | $vals = $config->get($service, []); |
| 706: | if (!empty($vals)) { |
| 707: | self::$services[$service]['auth'] = 'oauth2'; |
| 708: | self::$services[$service]['client_id'] = $vals['client_id']; |
| 709: | self::$services[$service]['client_secret'] = $vals['client_secret']; |
| 710: | self::$services[$service]['redirect_uri'] = $vals['client_uri']; |
| 711: | self::$services[$service]['auth_uri'] = $vals['auth_uri']; |
| 712: | self::$services[$service]['token_uri'] = $vals['token_uri']; |
| 713: | self::$services[$service]['refresh_uri'] = $vals['refresh_uri']; |
| 714: | } |
| 715: | } |
| 716: | self::$oauth2 = config('oauth2'); |
| 717: | } |
| 718: | |
| 719: | static public function option_list($current, $mod) { |
| 720: | $res = ''; |
| 721: | uasort(self::$services, function($a, $b) { return strcasecmp($a['name'], $b['name']); }); |
| 722: | foreach(self::$services as $id => $details) { |
| 723: | $res .= '<option value="'.$mod->html_safe($id).'"'; |
| 724: | if ($id == $current) { |
| 725: | $res .= ' selected="selected"'; |
| 726: | } |
| 727: | $res .= '>'.$mod->trans($details['name']); |
| 728: | $res .= '</option>'; |
| 729: | } |
| 730: | return $res; |
| 731: | } |
| 732: | |
| 733: | static public function exists($id) { |
| 734: | return array_key_exists($id, self::$services); |
| 735: | } |
| 736: | |
| 737: | static public function details($id) { |
| 738: | if (array_key_exists($id, self::$services)) { |
| 739: | return self::$services[$id]; |
| 740: | } |
| 741: | return array(); |
| 742: | } |
| 743: | |
| 744: | static public function get() { |
| 745: | return self::$services; |
| 746: | } |
| 747: | } |
| 748: | |