1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package davmail;
20
21 import davmail.ui.tray.DavGatewayTray;
22 import org.apache.log4j.ConsoleAppender;
23 import org.apache.log4j.FileAppender;
24 import org.apache.log4j.Level;
25 import org.apache.log4j.Logger;
26 import org.apache.log4j.PatternLayout;
27 import org.apache.log4j.RollingFileAppender;
28
29 import java.io.BufferedReader;
30 import java.io.BufferedWriter;
31 import java.io.File;
32 import java.io.FileInputStream;
33 import java.io.FileOutputStream;
34 import java.io.IOException;
35 import java.io.InputStream;
36 import java.io.InputStreamReader;
37 import java.io.OutputStreamWriter;
38 import java.nio.charset.StandardCharsets;
39 import java.nio.file.Files;
40 import java.nio.file.Path;
41 import java.nio.file.Paths;
42 import java.nio.file.attribute.FileAttribute;
43 import java.nio.file.attribute.PosixFilePermissions;
44 import java.util.ArrayList;
45 import java.util.Enumeration;
46 import java.util.Iterator;
47 import java.util.Map;
48 import java.util.Properties;
49 import java.util.TreeSet;
50
51 import static org.apache.http.util.TextUtils.isEmpty;
52
53
54
55
56
57
58 public final class Settings {
59
60 private static final Logger LOGGER = Logger.getLogger(Settings.class);
61
62 public static final String OUTLOOK_URL = "https://outlook.office365.com";
63 public static final String O365_URL = OUTLOOK_URL + "/EWS/Exchange.asmx";
64
65 public static final String GRAPH_URL = "https://graph.microsoft.com";
66
67 public static final String O365_LOGIN_URL = "https://login.microsoftonline.com";
68
69 public static final String O365 = "O365";
70 public static final String O365_MODERN = "O365Modern";
71 public static final String O365_INTERACTIVE = "O365Interactive";
72 public static final String O365_MANUAL = "O365Manual";
73 public static final String WEBDAV = "WebDav";
74 public static final String EWS = "EWS";
75 public static final String AUTO = "Auto";
76
77 public static final String EDGE_USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36 Edg/90.0.818.49";
78
79 private Settings() {
80 }
81
82 private static final Properties SETTINGS_PROPERTIES = new Properties() {
83 @Override
84 public synchronized Enumeration<Object> keys() {
85 Enumeration<Object> keysEnumeration = super.keys();
86 TreeSet<String> sortedKeySet = new TreeSet<>();
87 while (keysEnumeration.hasMoreElements()) {
88 sortedKeySet.add((String) keysEnumeration.nextElement());
89 }
90 final Iterator<String> sortedKeysIterator = sortedKeySet.iterator();
91 return new Enumeration<Object>() {
92
93 public boolean hasMoreElements() {
94 return sortedKeysIterator.hasNext();
95 }
96
97 public Object nextElement() {
98 return sortedKeysIterator.next();
99 }
100 };
101 }
102
103 };
104 private static String configFilePath;
105 private static boolean isFirstStart;
106
107
108
109
110
111
112 public static synchronized void setConfigFilePath(String path) {
113 configFilePath = path;
114 }
115
116
117
118
119
120
121 public static synchronized boolean isFirstStart() {
122 return isFirstStart;
123 }
124
125
126
127
128
129
130
131 public static synchronized void load(InputStream inputStream) throws IOException {
132 SETTINGS_PROPERTIES.load(inputStream);
133 updateLoggingConfig();
134 }
135
136
137
138
139 public static synchronized void load() {
140 try {
141 if (configFilePath == null) {
142
143 configFilePath = System.getProperty("user.home") + "/.davmail.properties";
144 }
145 File configFile = new File(configFilePath);
146 if (configFile.exists()) {
147 try (FileInputStream fileInputStream = new FileInputStream(configFile)) {
148 load(fileInputStream);
149 }
150 } else {
151 isFirstStart = true;
152
153
154 setDefaultSettings();
155 save();
156 }
157 } catch (IOException e) {
158 DavGatewayTray.error(new BundleMessage("LOG_UNABLE_TO_LOAD_SETTINGS"), e);
159 }
160 updateLoggingConfig();
161 }
162
163
164
165
166
167 public static void setDefaultSettings() {
168 SETTINGS_PROPERTIES.put("davmail.mode", O365_INTERACTIVE);
169 SETTINGS_PROPERTIES.put("davmail.url", getO365Url());
170 SETTINGS_PROPERTIES.put("davmail.popPort", "1110");
171 SETTINGS_PROPERTIES.put("davmail.imapPort", "1143");
172 SETTINGS_PROPERTIES.put("davmail.smtpPort", "1025");
173 SETTINGS_PROPERTIES.put("davmail.caldavPort", "1080");
174 SETTINGS_PROPERTIES.put("davmail.ldapPort", "1389");
175 SETTINGS_PROPERTIES.put("davmail.clientSoTimeout", "");
176 SETTINGS_PROPERTIES.put("davmail.keepDelay", "30");
177 SETTINGS_PROPERTIES.put("davmail.sentKeepDelay", "0");
178 SETTINGS_PROPERTIES.put("davmail.caldavPastDelay", "0");
179 SETTINGS_PROPERTIES.put("davmail.caldavAutoSchedule", Boolean.TRUE.toString());
180 SETTINGS_PROPERTIES.put("davmail.imapIdleDelay", "");
181 SETTINGS_PROPERTIES.put("davmail.folderSizeLimit", "");
182 SETTINGS_PROPERTIES.put("davmail.enableKeepAlive", Boolean.FALSE.toString());
183 SETTINGS_PROPERTIES.put("davmail.allowRemote", Boolean.FALSE.toString());
184 SETTINGS_PROPERTIES.put("davmail.bindAddress", "");
185 SETTINGS_PROPERTIES.put("davmail.useSystemProxies", Boolean.FALSE.toString());
186 SETTINGS_PROPERTIES.put("davmail.enableProxy", Boolean.FALSE.toString());
187 SETTINGS_PROPERTIES.put("davmail.enableKerberos", "false");
188 SETTINGS_PROPERTIES.put("davmail.disableUpdateCheck", "false");
189 SETTINGS_PROPERTIES.put("davmail.proxyHost", "");
190 SETTINGS_PROPERTIES.put("davmail.proxyPort", "");
191 SETTINGS_PROPERTIES.put("davmail.proxyUser", "");
192 SETTINGS_PROPERTIES.put("davmail.proxyPassword", "");
193 SETTINGS_PROPERTIES.put("davmail.noProxyFor", "");
194 SETTINGS_PROPERTIES.put("davmail.server", Boolean.FALSE.toString());
195 SETTINGS_PROPERTIES.put("davmail.server.certificate.hash", "");
196 SETTINGS_PROPERTIES.put("davmail.caldavAlarmSound", "");
197 SETTINGS_PROPERTIES.put("davmail.carddavReadPhoto", Boolean.TRUE.toString());
198 SETTINGS_PROPERTIES.put("davmail.forceActiveSyncUpdate", Boolean.FALSE.toString());
199 SETTINGS_PROPERTIES.put("davmail.showStartupBanner", Boolean.TRUE.toString());
200 SETTINGS_PROPERTIES.put("davmail.disableGuiNotifications", Boolean.FALSE.toString());
201 SETTINGS_PROPERTIES.put("davmail.disableTrayActivitySwitch", Boolean.FALSE.toString());
202 SETTINGS_PROPERTIES.put("davmail.imapAutoExpunge", Boolean.TRUE.toString());
203 SETTINGS_PROPERTIES.put("davmail.imapAlwaysApproxMsgSize", Boolean.FALSE.toString());
204 SETTINGS_PROPERTIES.put("davmail.popMarkReadOnRetr", Boolean.FALSE.toString());
205 SETTINGS_PROPERTIES.put("davmail.smtpSaveInSent", Boolean.TRUE.toString());
206 SETTINGS_PROPERTIES.put("davmail.ssl.keystoreType", "");
207 SETTINGS_PROPERTIES.put("davmail.ssl.keystoreFile", "");
208 SETTINGS_PROPERTIES.put("davmail.ssl.keystorePass", "");
209 SETTINGS_PROPERTIES.put("davmail.ssl.keyPass", "");
210 if (isWindows()) {
211
212 SETTINGS_PROPERTIES.put("davmail.ssl.clientKeystoreType", "MSCAPI");
213 } else {
214 SETTINGS_PROPERTIES.put("davmail.ssl.clientKeystoreType", "");
215 }
216 SETTINGS_PROPERTIES.put("davmail.ssl.clientKeystoreFile", "");
217 SETTINGS_PROPERTIES.put("davmail.ssl.clientKeystorePass", "");
218 SETTINGS_PROPERTIES.put("davmail.ssl.pkcs11Library", "");
219 SETTINGS_PROPERTIES.put("davmail.ssl.pkcs11Config", "");
220 SETTINGS_PROPERTIES.put("davmail.ssl.nosecurepop", Boolean.FALSE.toString());
221 SETTINGS_PROPERTIES.put("davmail.ssl.nosecureimap", Boolean.FALSE.toString());
222 SETTINGS_PROPERTIES.put("davmail.ssl.nosecuresmtp", Boolean.FALSE.toString());
223 SETTINGS_PROPERTIES.put("davmail.ssl.nosecurecaldav", Boolean.FALSE.toString());
224 SETTINGS_PROPERTIES.put("davmail.ssl.nosecureldap", Boolean.FALSE.toString());
225
226
227 SETTINGS_PROPERTIES.put("log4j.rootLogger", Level.WARN.toString());
228 SETTINGS_PROPERTIES.put("log4j.logger.davmail", Level.DEBUG.toString());
229 SETTINGS_PROPERTIES.put("log4j.logger.httpclient.wire", Level.WARN.toString());
230 SETTINGS_PROPERTIES.put("log4j.logger.httpclient", Level.WARN.toString());
231 String logFilePath = "";
232 if (isFlatpak()) {
233 logFilePath = System.getenv("XDG_DATA_HOME")+"/davmail.log";
234 }
235 SETTINGS_PROPERTIES.put("davmail.logFilePath", logFilePath);
236 }
237
238
239
240
241
242
243 public static String getLogFilePath() {
244 String logFilePath = Settings.getProperty("davmail.logFilePath");
245
246 if ((logFilePath == null || logFilePath.isEmpty())) {
247 if (Settings.getBooleanProperty("davmail.server")) {
248 logFilePath = "davmail.log";
249 } else if (System.getProperty("os.name").toLowerCase().startsWith("mac os x")) {
250
251 logFilePath = System.getProperty("user.home") + "/Library/Logs/DavMail/davmail.log";
252 } else {
253
254 logFilePath = System.getProperty("user.home") + "/davmail.log";
255 }
256 } else {
257 File logFile = new File(logFilePath);
258 if (logFile.isDirectory()) {
259 logFilePath += "/davmail.log";
260 }
261 }
262 return logFilePath;
263 }
264
265
266
267
268
269
270 public static String getLogFileDirectory() {
271 String logFilePath = getLogFilePath();
272 if (logFilePath == null || logFilePath.isEmpty()) {
273 return ".";
274 }
275 int lastSlashIndex = logFilePath.lastIndexOf('/');
276 if (lastSlashIndex == -1) {
277 lastSlashIndex = logFilePath.lastIndexOf('\\');
278 }
279 if (lastSlashIndex >= 0) {
280 return logFilePath.substring(0, lastSlashIndex);
281 } else {
282 return ".";
283 }
284 }
285
286
287
288
289 public static void updateLoggingConfig() {
290 String logFilePath = getLogFilePath();
291
292 try {
293 if (!isDocker()) {
294 if (logFilePath != null && !logFilePath.isEmpty()) {
295 File logFile = new File(logFilePath);
296
297 File logFileDir = logFile.getParentFile();
298 if (logFileDir != null && !logFileDir.exists() && (!logFileDir.mkdirs())) {
299 DavGatewayTray.error(new BundleMessage("LOG_UNABLE_TO_CREATE_LOG_FILE_DIR"));
300 throw new IOException();
301
302 }
303 } else {
304 logFilePath = "davmail.log";
305 }
306
307 synchronized (Logger.getRootLogger()) {
308
309 FileAppender fileAppender = (FileAppender) Logger.getRootLogger().getAppender("FileAppender");
310 if (fileAppender == null) {
311 String logFileSize = Settings.getProperty("davmail.logFileSize");
312 if (logFileSize == null || logFileSize.isEmpty()) {
313 logFileSize = "1MB";
314 }
315
316 if ("0".equals(logFileSize)) {
317 fileAppender = new FileAppender();
318 } else {
319 fileAppender = new RollingFileAppender();
320 ((RollingFileAppender) fileAppender).setMaxBackupIndex(2);
321 ((RollingFileAppender) fileAppender).setMaxFileSize(logFileSize);
322 }
323 fileAppender.setName("FileAppender");
324 fileAppender.setEncoding("UTF-8");
325 fileAppender.setLayout(new PatternLayout("%d{ISO8601} %-5p [%t] %c %x - %m%n"));
326 }
327 fileAppender.setFile(logFilePath, true, false, 8192);
328 Logger.getRootLogger().addAppender(fileAppender);
329 }
330 }
331
332
333 ConsoleAppender consoleAppender = (ConsoleAppender) Logger.getRootLogger().getAppender("ConsoleAppender");
334 if (consoleAppender != null) {
335 if (Settings.getBooleanProperty("davmail.server")) {
336 consoleAppender.setThreshold(Level.ALL);
337 } else {
338 consoleAppender.setThreshold(Level.INFO);
339 }
340 }
341
342 } catch (IOException e) {
343 DavGatewayTray.error(new BundleMessage("LOG_UNABLE_TO_SET_LOG_FILE_PATH"));
344 }
345
346
347 Settings.setLoggingLevel("rootLogger", Settings.getLoggingLevel("rootLogger"));
348 Settings.setLoggingLevel("davmail", Settings.getLoggingLevel("davmail"));
349
350 Settings.setLoggingLevel("org.apache.http.wire", Settings.getLoggingLevel("httpclient.wire"));
351 Settings.setLoggingLevel("org.apache.http.conn.ssl", Settings.getLoggingLevel("httpclient.wire"));
352 Settings.setLoggingLevel("org.apache.http", Settings.getLoggingLevel("httpclient"));
353 }
354
355
356
357
358 public static synchronized void save() {
359
360 if (configFilePath != null) {
361
362 Properties properties = new Properties();
363 properties.putAll(SETTINGS_PROPERTIES);
364
365 ArrayList<String> lines = new ArrayList<>();
366
367
368 Path path = Paths.get(configFilePath);
369 if (!Files.exists(path) && isUnix()) {
370 FileAttribute<?> permissions = PosixFilePermissions.asFileAttribute(PosixFilePermissions.fromString("rw-------"));
371 try {
372 Files.createFile(path, permissions);
373 } catch (IOException e) {
374 LOGGER.error(e.getMessage());
375 }
376 }
377
378 readLines(lines, properties);
379
380 try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(Files.newOutputStream(Paths.get(configFilePath)), StandardCharsets.ISO_8859_1))) {
381 for (String value : lines) {
382 writer.write(value);
383 writer.newLine();
384 }
385
386
387 Enumeration<?> propertyEnumeration = properties.propertyNames();
388 while (propertyEnumeration.hasMoreElements()) {
389 String propertyName = (String) propertyEnumeration.nextElement();
390 writer.write(propertyName + "=" + escapeValue(properties.getProperty(propertyName)));
391 writer.newLine();
392 }
393 } catch (IOException e) {
394 DavGatewayTray.error(new BundleMessage("LOG_UNABLE_TO_STORE_SETTINGS"), e);
395 }
396 }
397 updateLoggingConfig();
398 }
399
400 private static void readLines(ArrayList<String> lines, Properties properties) {
401 try {
402 File configFile = new File(configFilePath);
403 if (configFile.exists()) {
404 try (BufferedReader reader = new BufferedReader(new InputStreamReader(Files.newInputStream(configFile.toPath()), StandardCharsets.ISO_8859_1))) {
405 String line;
406 while ((line = reader.readLine()) != null) {
407 lines.add(convertLine(line, properties));
408 }
409 }
410 }
411 } catch (IOException e) {
412 DavGatewayTray.error(new BundleMessage("LOG_UNABLE_TO_LOAD_SETTINGS"), e);
413 }
414 }
415
416
417
418
419
420
421
422
423
424 private static String convertLine(String line, Properties properties) {
425 int hashIndex = line.indexOf('#');
426 int equalsIndex = line.indexOf('=');
427
428
429 if (equalsIndex >= 0 && (hashIndex < 0 || hashIndex >= equalsIndex)) {
430 String key = line.substring(0, equalsIndex);
431 String value = properties.getProperty(key);
432 if (value != null) {
433
434 line = key + "=" + escapeValue(value);
435
436 properties.remove(key);
437 }
438 }
439 return line;
440 }
441
442
443
444
445
446
447
448 private static String escapeValue(String value) {
449 StringBuilder buffer = new StringBuilder();
450 for (char c : value.toCharArray()) {
451 if (c == '\\') {
452 buffer.append('\\');
453 }
454 buffer.append(c);
455 }
456 return buffer.toString();
457 }
458
459
460
461
462
463
464
465
466 public static synchronized String getProperty(String property) {
467 String value = SETTINGS_PROPERTIES.getProperty(property);
468
469 if (value != null && value.isEmpty()) {
470 value = null;
471 }
472 return value;
473 }
474
475
476
477
478
479
480
481
482 public static synchronized String getProperty(String property, String defaultValue) {
483 String value = getProperty(property);
484 if (value == null) {
485 value = defaultValue;
486 }
487 return value;
488 }
489
490
491
492
493
494
495
496
497 public static synchronized char[] getCharArrayProperty(String property) {
498 String propertyValue = Settings.getProperty(property);
499 char[] value = null;
500 if (propertyValue != null) {
501 value = propertyValue.toCharArray();
502 }
503 return value;
504 }
505
506
507
508
509
510
511
512 public static synchronized void setProperty(String property, String value) {
513 if (value != null) {
514 SETTINGS_PROPERTIES.setProperty(property, value);
515 } else {
516 SETTINGS_PROPERTIES.setProperty(property, "");
517 }
518 }
519
520
521
522
523
524
525
526 public static synchronized int getIntProperty(String property) {
527 return getIntProperty(property, 0);
528 }
529
530
531
532
533
534
535
536
537 public static synchronized int getIntProperty(String property, int defaultValue) {
538 int value = defaultValue;
539 try {
540 String propertyValue = SETTINGS_PROPERTIES.getProperty(property);
541 if (propertyValue != null && !propertyValue.isEmpty()) {
542 value = Integer.parseInt(propertyValue);
543 }
544 } catch (NumberFormatException e) {
545 DavGatewayTray.error(new BundleMessage("LOG_INVALID_SETTING_VALUE", property), e);
546 }
547 return value;
548 }
549
550
551
552
553
554
555
556 public static synchronized boolean getBooleanProperty(String property) {
557 String propertyValue = SETTINGS_PROPERTIES.getProperty(property);
558 return Boolean.parseBoolean(propertyValue);
559 }
560
561
562
563
564
565
566
567
568 public static synchronized boolean getBooleanProperty(String property, boolean defaultValue) {
569 boolean value = defaultValue;
570 String propertyValue = SETTINGS_PROPERTIES.getProperty(property);
571 if (propertyValue != null && !propertyValue.isEmpty()) {
572 value = Boolean.parseBoolean(propertyValue);
573 }
574 return value;
575 }
576
577 public static synchronized String loadRefreshToken(String username) {
578 String tokenFilePath = Settings.getProperty("davmail.oauth.tokenFilePath");
579 if (isEmpty(tokenFilePath)) {
580 return Settings.getProperty("davmail.oauth." + username.toLowerCase() + ".refreshToken");
581 } else {
582 return loadtokenFromFile(tokenFilePath, username.toLowerCase());
583 }
584 }
585
586
587 public static synchronized void storeRefreshToken(String username, String refreshToken) {
588 String tokenFilePath = Settings.getProperty("davmail.oauth.tokenFilePath");
589 if (isEmpty(tokenFilePath)) {
590 Settings.setProperty("davmail.oauth." + username.toLowerCase() + ".refreshToken", refreshToken);
591 Settings.save();
592 } else {
593 savetokentoFile(tokenFilePath, username.toLowerCase(), refreshToken);
594 }
595 }
596
597
598
599
600
601
602
603
604 private static void savetokentoFile(String tokenFilePath, String username, String refreshToken) {
605 try {
606 checkCreateTokenFilePath(tokenFilePath);
607 Properties properties = new Properties();
608 try (FileInputStream fis = new FileInputStream(tokenFilePath)) {
609 properties.load(fis);
610 }
611 properties.setProperty(username, refreshToken);
612 try (FileOutputStream fos = new FileOutputStream(tokenFilePath)) {
613 properties.store(fos, "Oauth tokens");
614 }
615 } catch (IOException e) {
616 Logger.getLogger(Settings.class).warn(e + " " + e.getMessage());
617 }
618 }
619
620
621
622
623
624
625
626
627 private static String loadtokenFromFile(String tokenFilePath, String username) {
628 try {
629 checkCreateTokenFilePath(tokenFilePath);
630 Properties properties = new Properties();
631 try (FileInputStream fis = new FileInputStream(tokenFilePath)) {
632 properties.load(fis);
633 }
634 return properties.getProperty(username);
635 } catch (IOException e) {
636 Logger.getLogger(Settings.class).warn(e + " " + e.getMessage());
637 }
638 return null;
639 }
640
641 private static void checkCreateTokenFilePath(String tokenFilePath) throws IOException {
642 File file = new File(tokenFilePath);
643 File parentFile = file.getParentFile();
644 if (parentFile != null && (parentFile.mkdirs())) {
645 LOGGER.info("Created token file directory " + parentFile.getAbsolutePath());
646
647 }
648 if (file.createNewFile()) {
649 LOGGER.info("Created token file " + tokenFilePath);
650 }
651 }
652
653
654
655
656
657
658
659 private static String getLoggingPrefix(String category) {
660 String prefix;
661 if ("rootLogger".equals(category)) {
662 prefix = "log4j.";
663 } else {
664 prefix = "log4j.logger.";
665 }
666 return prefix;
667 }
668
669
670
671
672
673
674
675 public static synchronized Level getLoggingLevel(String category) {
676 String prefix = getLoggingPrefix(category);
677 String currentValue = SETTINGS_PROPERTIES.getProperty(prefix + category);
678
679 if (currentValue != null && !currentValue.isEmpty()) {
680 return Level.toLevel(currentValue);
681 } else if ("rootLogger".equals(category)) {
682 return Logger.getRootLogger().getLevel();
683 } else {
684 return Logger.getLogger(category).getLevel();
685 }
686 }
687
688
689
690
691
692
693
694 public static synchronized Properties getSubProperties(String scope) {
695 final String keyStart;
696 if (scope == null || scope.isEmpty()) {
697 keyStart = "";
698 } else if (scope.endsWith(".")) {
699 keyStart = scope;
700 } else {
701 keyStart = scope + '.';
702 }
703 Properties result = new Properties();
704 for (Map.Entry<Object, Object> entry : SETTINGS_PROPERTIES.entrySet()) {
705 String key = (String) entry.getKey();
706 if (key.startsWith(keyStart)) {
707 String value = (String) entry.getValue();
708 result.setProperty(key.substring(keyStart.length()), value);
709 }
710 }
711 return result;
712 }
713
714
715
716
717
718
719
720 public static synchronized void setLoggingLevel(String category, Level level) {
721 if (level != null) {
722 String prefix = getLoggingPrefix(category);
723 SETTINGS_PROPERTIES.setProperty(prefix + category, level.toString());
724 if ("rootLogger".equals(category)) {
725 Logger.getRootLogger().setLevel(level);
726 } else {
727 Logger.getLogger(category).setLevel(level);
728 }
729 }
730 }
731
732
733
734
735
736
737
738 public static synchronized void saveProperty(String property, String value) {
739 Settings.load();
740 Settings.setProperty(property, value);
741 Settings.save();
742 }
743
744
745
746
747
748
749 public static boolean isWindows() {
750 return System.getProperty("os.name").toLowerCase().startsWith("windows");
751 }
752
753
754
755
756
757
758 public static boolean isLinux() {
759 return System.getProperty("os.name").toLowerCase().startsWith("linux");
760 }
761
762 public static boolean isUnix() {
763 return isLinux() ||
764 System.getProperty("os.name").toLowerCase().startsWith("freebsd");
765 }
766
767 public static String getUserAgent() {
768 return getProperty("davmail.userAgent", Settings.EDGE_USER_AGENT);
769 }
770
771 public static String getOutlookUrl() {
772 String tld = getProperty("davmail.tld");
773 String outlookUrl = getProperty("davmail.outlookUrl");
774 if (outlookUrl != null) {
775 return outlookUrl;
776 } else if (tld == null) {
777 return OUTLOOK_URL;
778 } else {
779 return "https://outlook.office365." + tld;
780 }
781 }
782
783 public static String getO365Url() {
784 String tld = getProperty("davmail.tld");
785 String outlookUrl = getProperty("davmail.outlookUrl");
786 if (outlookUrl != null) {
787 return outlookUrl + "/EWS/Exchange.asmx";
788 } else if (tld == null) {
789 return O365_URL;
790 } else {
791 return "https://outlook.office365." + tld + "/EWS/Exchange.asmx";
792 }
793 }
794
795
796
797
798
799
800 public static String getGraphUrl() {
801 String tld = getProperty("davmail.tld");
802 String graphUrl = getProperty("davmail.graphUrl");
803 if (graphUrl != null) {
804 return graphUrl;
805 } else if (tld == null) {
806 return GRAPH_URL;
807 } else {
808 return "https://graph.microsoft." + tld;
809 }
810 }
811
812 public static String getO365LoginUrl() {
813 String tld = getProperty("davmail.tld");
814 String loginUrl = getProperty("davmail.loginUrl");
815 if (loginUrl != null) {
816 return loginUrl;
817 } else if (tld == null) {
818 return O365_LOGIN_URL;
819 } else {
820 return "https://login.microsoftonline." + tld;
821 }
822 }
823
824 public static boolean isSWTAvailable() {
825 boolean isSWTAvailable = false;
826 ClassLoader classloader = Settings.class.getClassLoader();
827 try {
828
829 classloader.loadClass("org.eclipse.swt.SWT");
830 isSWTAvailable = true;
831 } catch (Throwable e) {
832 LOGGER.info(new BundleMessage("LOG_SWT_NOT_AVAILABLE"));
833 }
834 return isSWTAvailable;
835 }
836
837 public static boolean isJFXAvailable() {
838 boolean isJFXAvailable = false;
839 try {
840 Class.forName("javafx.application.Platform");
841 isJFXAvailable = true;
842 } catch (ClassNotFoundException | NullPointerException e) {
843 LOGGER.info("JavaFX (OpenJFX) not available");
844 }
845 return isJFXAvailable;
846 }
847
848 public static boolean isDocker() {
849 boolean isDocker = new File("/.dockerenv").exists();
850 if (isDocker) {
851 LOGGER.info("Running in docker");
852 }
853 return isDocker;
854 }
855
856 public static boolean isFlatpak() {
857 boolean isFlatpak = "flatpak".equals(System.getenv("container"));
858 if (isFlatpak) {
859 LOGGER.info("Running in Flatpak");
860 }
861 return isFlatpak;
862 }
863
864
865
866
867
868 public static synchronized String getConfigFilePath() {
869 if (isFlatpak()) {
870 return System.getenv("XDG_CONFIG_HOME")+"/davmail.properties";
871 } else {
872
873 return System.getenv("DAVMAIL_PROPERTIES");
874 }
875 }
876 }