diff options
author | André Oliveira <37463445+SpecialAro@users.noreply.github.com> | 2024-01-26 02:06:35 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-26 02:06:35 +0000 |
commit | 711181751f0a5ee183b74514a621e4aaa6da3dd7 (patch) | |
tree | 202718df2046fb92761abc3379ae48f35774a92c /src | |
parent | 6.7.1-nightly.10 [skip ci] (diff) | |
download | ferdium-app-711181751f0a5ee183b74514a621e4aaa6da3dd7.tar.gz ferdium-app-711181751f0a5ee183b74514a621e4aaa6da3dd7.tar.zst ferdium-app-711181751f0a5ee183b74514a621e4aaa6da3dd7.zip |
feat: self signed certificates bypass (#1545)
* feat: self signed certificates bypass
* fix lint and vscode setting
* Fix some mistakes and comments
* forgot this one [skip ci]
Diffstat (limited to 'src')
-rw-r--r-- | src/@types/stores.types.ts | 1 | ||||
-rw-r--r-- | src/components/settings/settings/EditSettingsForm.tsx | 61 | ||||
-rw-r--r-- | src/config.ts | 1 | ||||
-rw-r--r-- | src/containers/settings/EditSettingsScreen.tsx | 16 | ||||
-rw-r--r-- | src/environment-remote.ts | 4 | ||||
-rw-r--r-- | src/helpers/certs-helpers.ts | 25 | ||||
-rw-r--r-- | src/i18n/locales/en-US.json | 6 | ||||
-rw-r--r-- | src/index.ts | 39 |
8 files changed, 150 insertions, 3 deletions
diff --git a/src/@types/stores.types.ts b/src/@types/stores.types.ts index d036f8ee1..c0670ee87 100644 --- a/src/@types/stores.types.ts +++ b/src/@types/stores.types.ts | |||
@@ -92,6 +92,7 @@ export interface AppStore extends TypedStore { | |||
92 | darkMode: boolean; | 92 | darkMode: boolean; |
93 | enableSpellchecking: boolean; | 93 | enableSpellchecking: boolean; |
94 | enableTranslator: boolean; | 94 | enableTranslator: boolean; |
95 | useSelfSignedCertificates: boolean; | ||
95 | fetchDataInterval: 4; | 96 | fetchDataInterval: 4; |
96 | get(key: string): any; | 97 | get(key: string): any; |
97 | getAppCacheSizeRequest: () => void; | 98 | getAppCacheSizeRequest: () => void; |
diff --git a/src/components/settings/settings/EditSettingsForm.tsx b/src/components/settings/settings/EditSettingsForm.tsx index 70887af0f..226dbac76 100644 --- a/src/components/settings/settings/EditSettingsForm.tsx +++ b/src/components/settings/settings/EditSettingsForm.tsx | |||
@@ -15,6 +15,7 @@ import Infobox from '../../ui/Infobox'; | |||
15 | import { H1, H2, H3, H5 } from '../../ui/headline'; | 15 | import { H1, H2, H3, H5 } from '../../ui/headline'; |
16 | import { | 16 | import { |
17 | ferdiumVersion, | 17 | ferdiumVersion, |
18 | userDataCertsPath, | ||
18 | userDataPath, | 19 | userDataPath, |
19 | userDataRecipesPath, | 20 | userDataRecipesPath, |
20 | } from '../../../environment-remote'; | 21 | } from '../../../environment-remote'; |
@@ -262,6 +263,20 @@ const messages = defineMessages({ | |||
262 | id: 'settings.app.form.splitColumns', | 263 | id: 'settings.app.form.splitColumns', |
263 | defaultMessage: 'Number of columns', | 264 | defaultMessage: 'Number of columns', |
264 | }, | 265 | }, |
266 | warningSelfSignedCertificates: { | ||
267 | id: 'settings.app.warningSelfSignedCertificates', | ||
268 | defaultMessage: | ||
269 | 'WARNING: Only enable this feature if you know what you are doing. Enabling this is a security risk and should only be used for testing purposes.', | ||
270 | }, | ||
271 | infoOpenCertificatesFolder: { | ||
272 | id: 'settings.app.infoOpenCertificatesFolder', | ||
273 | defaultMessage: | ||
274 | 'To install a certificate, click the button below to open the certificates folder and copy it into the folder. After that you can refresh the service (CTRL/CMD + R). To remove/uninstall, simply delete the certificate file and restart Ferdium.', | ||
275 | }, | ||
276 | buttonOpenFerdiumCertsFolder: { | ||
277 | id: 'settings.app.buttonOpenFerdiumCertsFolder', | ||
278 | defaultMessage: 'Open certificates folder', | ||
279 | }, | ||
265 | }); | 280 | }); |
266 | 281 | ||
267 | const Hr = (): ReactElement => ( | 282 | const Hr = (): ReactElement => ( |
@@ -387,8 +402,12 @@ class EditSettingsForm extends Component<IProps, IState> { | |||
387 | updateButtonLabelMessage = messages.updateStatusAvailable; | 402 | updateButtonLabelMessage = messages.updateStatusAvailable; |
388 | } | 403 | } |
389 | 404 | ||
390 | const { lockingFeatureEnabled, scheduledDNDEnabled, reloadAfterResume } = | 405 | const { |
391 | window['ferdium'].stores.settings.all.app; | 406 | lockingFeatureEnabled, |
407 | scheduledDNDEnabled, | ||
408 | reloadAfterResume, | ||
409 | useSelfSignedCertificates, | ||
410 | } = window['ferdium'].stores.settings.all.app; | ||
392 | 411 | ||
393 | let cacheSize; | 412 | let cacheSize; |
394 | let notCleared; | 413 | let notCleared; |
@@ -411,6 +430,7 @@ class EditSettingsForm extends Component<IProps, IState> { | |||
411 | 430 | ||
412 | const profileFolder = userDataPath(); | 431 | const profileFolder = userDataPath(); |
413 | const recipeFolder = userDataRecipesPath(); | 432 | const recipeFolder = userDataRecipesPath(); |
433 | const certsFolder = userDataCertsPath(); | ||
414 | 434 | ||
415 | return ( | 435 | return ( |
416 | <div className="settings__main"> | 436 | <div className="settings__main"> |
@@ -947,6 +967,43 @@ class EditSettingsForm extends Component<IProps, IState> { | |||
947 | {intl.formatMessage(messages.appRestartRequired)} | 967 | {intl.formatMessage(messages.appRestartRequired)} |
948 | </p> | 968 | </p> |
949 | 969 | ||
970 | <Toggle {...form.$('useSelfSignedCertificates').bind()} /> | ||
971 | |||
972 | {useSelfSignedCertificates && ( | ||
973 | <div className="settings__settings-group"> | ||
974 | <p | ||
975 | style={{ | ||
976 | padding: '0rem 0rem 1rem 0rem', | ||
977 | textAlign: 'justify', | ||
978 | fontSize: '1.1rem', | ||
979 | }} | ||
980 | > | ||
981 | {intl.formatMessage(messages.infoOpenCertificatesFolder)} | ||
982 | </p> | ||
983 | <div className="settings__open-settings-cache-container"> | ||
984 | <Button | ||
985 | buttonType="secondary" | ||
986 | label={intl.formatMessage( | ||
987 | messages.buttonOpenFerdiumCertsFolder, | ||
988 | )} | ||
989 | className="settings__open-settings-file-button" | ||
990 | onClick={() => openPath(certsFolder)} | ||
991 | /> | ||
992 | </div> | ||
993 | </div> | ||
994 | )} | ||
995 | |||
996 | <p | ||
997 | className="settings__help" | ||
998 | style={{ | ||
999 | padding: useSelfSignedCertificates | ||
1000 | ? '1rem 0rem 0rem 0rem' | ||
1001 | : undefined, | ||
1002 | }} | ||
1003 | > | ||
1004 | {intl.formatMessage(messages.warningSelfSignedCertificates)} | ||
1005 | </p> | ||
1006 | |||
950 | <Hr /> | 1007 | <Hr /> |
951 | 1008 | ||
952 | <Input | 1009 | <Input |
diff --git a/src/config.ts b/src/config.ts index fd1b1cced..73ea25343 100644 --- a/src/config.ts +++ b/src/config.ts | |||
@@ -424,6 +424,7 @@ export const DEFAULT_APP_SETTINGS = { | |||
424 | customTodoServer: '', | 424 | customTodoServer: '', |
425 | locale: 'en-US', | 425 | locale: 'en-US', |
426 | keepAllWorkspacesLoaded: false, | 426 | keepAllWorkspacesLoaded: false, |
427 | useSelfSignedCertificates: false, | ||
427 | }; | 428 | }; |
428 | 429 | ||
429 | export const DEFAULT_SERVICE_SETTINGS = { | 430 | export const DEFAULT_SERVICE_SETTINGS = { |
diff --git a/src/containers/settings/EditSettingsScreen.tsx b/src/containers/settings/EditSettingsScreen.tsx index 8190bef3e..528b1410b 100644 --- a/src/containers/settings/EditSettingsScreen.tsx +++ b/src/containers/settings/EditSettingsScreen.tsx | |||
@@ -295,6 +295,10 @@ const messages = defineMessages({ | |||
295 | id: 'settings.app.form.enableTranslator', | 295 | id: 'settings.app.form.enableTranslator', |
296 | defaultMessage: 'Enable Translator', | 296 | defaultMessage: 'Enable Translator', |
297 | }, | 297 | }, |
298 | useSelfSignedCertificates: { | ||
299 | id: 'settings.app.form.useSelfSignedCertificates', | ||
300 | defaultMessage: 'Enable self-signed certificates', | ||
301 | }, | ||
298 | enableGPUAcceleration: { | 302 | enableGPUAcceleration: { |
299 | id: 'settings.app.form.enableGPUAcceleration', | 303 | id: 'settings.app.form.enableGPUAcceleration', |
300 | defaultMessage: 'Enable GPU Acceleration', | 304 | defaultMessage: 'Enable GPU Acceleration', |
@@ -439,6 +443,9 @@ class EditSettingsScreen extends Component< | |||
439 | showDragArea: Boolean(settingsData.showDragArea), | 443 | showDragArea: Boolean(settingsData.showDragArea), |
440 | enableSpellchecking: Boolean(settingsData.enableSpellchecking), | 444 | enableSpellchecking: Boolean(settingsData.enableSpellchecking), |
441 | enableTranslator: Boolean(settingsData.enableTranslator), | 445 | enableTranslator: Boolean(settingsData.enableTranslator), |
446 | useSelfSignedCertificates: Boolean( | ||
447 | settingsData.useSelfSignedCertificates, | ||
448 | ), | ||
442 | spellcheckerLanguage: settingsData.spellcheckerLanguage, | 449 | spellcheckerLanguage: settingsData.spellcheckerLanguage, |
443 | userAgentPref: settingsData.userAgentPref, | 450 | userAgentPref: settingsData.userAgentPref, |
444 | beta: Boolean(settingsData.beta), // we need this info in the main process as well | 451 | beta: Boolean(settingsData.beta), // we need this info in the main process as well |
@@ -906,6 +913,15 @@ class EditSettingsScreen extends Component< | |||
906 | default: DEFAULT_APP_SETTINGS.enableTranslator, | 913 | default: DEFAULT_APP_SETTINGS.enableTranslator, |
907 | type: 'checkbox', | 914 | type: 'checkbox', |
908 | }, | 915 | }, |
916 | useSelfSignedCertificates: { | ||
917 | label: intl.formatMessage(messages.useSelfSignedCertificates), | ||
918 | value: ifUndefined<boolean>( | ||
919 | settings.all.app.useSelfSignedCertificates, | ||
920 | DEFAULT_APP_SETTINGS.useSelfSignedCertificates, | ||
921 | ), | ||
922 | default: DEFAULT_APP_SETTINGS.useSelfSignedCertificates, | ||
923 | type: 'checkbox', | ||
924 | }, | ||
909 | spellcheckerLanguage: { | 925 | spellcheckerLanguage: { |
910 | label: intl.formatMessage(globalMessages.spellcheckerLanguage), | 926 | label: intl.formatMessage(globalMessages.spellcheckerLanguage), |
911 | value: ifUndefined<string>( | 927 | value: ifUndefined<string>( |
diff --git a/src/environment-remote.ts b/src/environment-remote.ts index 7662d69a0..346a75e97 100644 --- a/src/environment-remote.ts +++ b/src/environment-remote.ts | |||
@@ -48,6 +48,10 @@ export function userDataRecipesPath(...segments: string[]): string { | |||
48 | return userDataPath('recipes', ...[segments].flat()); | 48 | return userDataPath('recipes', ...[segments].flat()); |
49 | } | 49 | } |
50 | 50 | ||
51 | export function userDataCertsPath(...segments: string[]): string { | ||
52 | return userDataPath('certs', ...[segments].flat()); | ||
53 | } | ||
54 | |||
51 | const useLocalAPI = process.env.USE_LOCAL_API; | 55 | const useLocalAPI = process.env.USE_LOCAL_API; |
52 | export const useLiveAPI = process.env.USE_LIVE_API; | 56 | export const useLiveAPI = process.env.USE_LIVE_API; |
53 | 57 | ||
diff --git a/src/helpers/certs-helpers.ts b/src/helpers/certs-helpers.ts new file mode 100644 index 000000000..a81e7e365 --- /dev/null +++ b/src/helpers/certs-helpers.ts | |||
@@ -0,0 +1,25 @@ | |||
1 | import { readdirSync, readFileSync, ensureDirSync } from 'fs-extra'; | ||
2 | import { join } from 'node:path'; | ||
3 | import { userDataCertsPath } from '../environment-remote'; | ||
4 | |||
5 | export function removeNewLines(string: string) { | ||
6 | return string.replaceAll(/\r?\n|\r/g, ''); | ||
7 | } | ||
8 | |||
9 | export function readCerts() { | ||
10 | const certsFolder = userDataCertsPath(); | ||
11 | |||
12 | ensureDirSync(certsFolder); | ||
13 | |||
14 | const certs: string[] = []; | ||
15 | |||
16 | for (const file of readdirSync(certsFolder)) { | ||
17 | const cert = readFileSync(join(certsFolder, file), { | ||
18 | encoding: 'utf8', | ||
19 | flag: 'r', | ||
20 | }); | ||
21 | certs.push(removeNewLines(cert)); | ||
22 | } | ||
23 | |||
24 | return certs; | ||
25 | } | ||
diff --git a/src/i18n/locales/en-US.json b/src/i18n/locales/en-US.json index eb8053fec..d2856e87a 100644 --- a/src/i18n/locales/en-US.json +++ b/src/i18n/locales/en-US.json | |||
@@ -188,6 +188,7 @@ | |||
188 | "settings.account.yourLicense": "Your Ferdium License:", | 188 | "settings.account.yourLicense": "Your Ferdium License:", |
189 | "settings.app.accentColorInfo": "Write your color choice in a CSS-compatible format. (Default: {defaultAccentColor} or clear the input field)", | 189 | "settings.app.accentColorInfo": "Write your color choice in a CSS-compatible format. (Default: {defaultAccentColor} or clear the input field)", |
190 | "settings.app.buttonInstallUpdate": "Restart & install update", | 190 | "settings.app.buttonInstallUpdate": "Restart & install update", |
191 | "settings.app.buttonOpenFerdiumCertsFolder": "Open certificates folder", | ||
191 | "settings.app.buttonOpenFerdiumProfileFolder": "Open Profile folder", | 192 | "settings.app.buttonOpenFerdiumProfileFolder": "Open Profile folder", |
192 | "settings.app.buttonOpenFerdiumServiceRecipesFolder": "Open Service Recipes folder", | 193 | "settings.app.buttonOpenFerdiumServiceRecipesFolder": "Open Service Recipes folder", |
193 | "settings.app.buttonOpenImportExport": "Import / Export", | 194 | "settings.app.buttonOpenImportExport": "Import / Export", |
@@ -262,6 +263,7 @@ | |||
262 | "settings.app.form.universalDarkMode": "Enable universal Dark Mode", | 263 | "settings.app.form.universalDarkMode": "Enable universal Dark Mode", |
263 | "settings.app.form.useGrayscaleServices": "Use grayscale services", | 264 | "settings.app.form.useGrayscaleServices": "Use grayscale services", |
264 | "settings.app.form.useHorizontalStyle": "Use horizontal style", | 265 | "settings.app.form.useHorizontalStyle": "Use horizontal style", |
266 | "settings.app.form.useSelfSignedCertificates": "Enable self-signed certificates", | ||
265 | "settings.app.form.useTouchIdToUnlock": "Allow using TouchID to unlock Ferdium", | 267 | "settings.app.form.useTouchIdToUnlock": "Allow using TouchID to unlock Ferdium", |
266 | "settings.app.form.wakeUpHibernationSplay": "Splay hibernate/wake cycles to reduce load", | 268 | "settings.app.form.wakeUpHibernationSplay": "Splay hibernate/wake cycles to reduce load", |
267 | "settings.app.form.wakeUpHibernationStrategy": "Hibernation strategy after automatic wake up", | 269 | "settings.app.form.wakeUpHibernationStrategy": "Hibernation strategy after automatic wake up", |
@@ -276,6 +278,7 @@ | |||
276 | "settings.app.headlineUpdates": "Updates", | 278 | "settings.app.headlineUpdates": "Updates", |
277 | "settings.app.hibernateInfo": "By default, Ferdium will keep all your services open and loaded in the background so they are ready when you want to use them. Service Hibernation will unload your services after a specified amount. This is useful to save RAM or keeping services from slowing down your computer.", | 279 | "settings.app.hibernateInfo": "By default, Ferdium will keep all your services open and loaded in the background so they are ready when you want to use them. Service Hibernation will unload your services after a specified amount. This is useful to save RAM or keeping services from slowing down your computer.", |
278 | "settings.app.inactivityLockInfo": "Minutes of inactivity, after which Ferdium should automatically lock. Use 0 to disable", | 280 | "settings.app.inactivityLockInfo": "Minutes of inactivity, after which Ferdium should automatically lock. Use 0 to disable", |
281 | "settings.app.infoOpenCertificatesFolder": "To install a certificate, click the button below to open the certificates folder and copy it into the folder. After that you can refresh the service (CTRL/CMD + R). To remove/uninstall, simply delete the certificate file and restart Ferdium.", | ||
279 | "settings.app.lockInfo": "Password Lock allows you to keep your messages protected.\nUsing Password Lock, you will be prompted to enter your password everytime you start Ferdium or lock Ferdium yourself using the lock symbol in the bottom left corner or the shortcut {lockShortcut}.", | 282 | "settings.app.lockInfo": "Password Lock allows you to keep your messages protected.\nUsing Password Lock, you will be prompted to enter your password everytime you start Ferdium or lock Ferdium yourself using the lock symbol in the bottom left corner or the shortcut {lockShortcut}.", |
280 | "settings.app.lockedPassword": "Password", | 283 | "settings.app.lockedPassword": "Password", |
281 | "settings.app.lockedPasswordInfo": "Please make sure to set a password you'll remember.\nIf you loose this password, you will have to reinstall Ferdium.", | 284 | "settings.app.lockedPasswordInfo": "Please make sure to set a password you'll remember.\nIf you loose this password, you will have to reinstall Ferdium.", |
@@ -306,6 +309,7 @@ | |||
306 | "settings.app.updateStatusAvailable": "Update available, downloading...", | 309 | "settings.app.updateStatusAvailable": "Update available, downloading...", |
307 | "settings.app.updateStatusSearching": "Searching for updates...", | 310 | "settings.app.updateStatusSearching": "Searching for updates...", |
308 | "settings.app.updateStatusUpToDate": "You are using the latest version of Ferdium", | 311 | "settings.app.updateStatusUpToDate": "You are using the latest version of Ferdium", |
312 | "settings.app.warningSelfSignedCertificates": "WARNING: Only enable this feature if you know what you are doing. Enabling this is a security risk and should only be used for testing purposes.", | ||
309 | "settings.invite.headline": "Invite Friends", | 313 | "settings.invite.headline": "Invite Friends", |
310 | "settings.navigation.account": "Account", | 314 | "settings.navigation.account": "Account", |
311 | "settings.navigation.availableServices": "Available services", | 315 | "settings.navigation.availableServices": "Available services", |
@@ -495,4 +499,4 @@ | |||
495 | "workspaceDrawer.workspaceFeatureInfo": "<p>Ferdium Workspaces let you focus on what’s important right now. Set up different sets of services and easily switch between them at any time.</p><p>You decide which services you need when and where, so we can help you stay on top of your game - or easily switch off from work whenever you want.</p>", | 499 | "workspaceDrawer.workspaceFeatureInfo": "<p>Ferdium Workspaces let you focus on what’s important right now. Set up different sets of services and easily switch between them at any time.</p><p>You decide which services you need when and where, so we can help you stay on top of your game - or easily switch off from work whenever you want.</p>", |
496 | "workspaceDrawer.workspacesSettingsTooltip": "Edit workspaces settings", | 500 | "workspaceDrawer.workspacesSettingsTooltip": "Edit workspaces settings", |
497 | "workspaces.switchingIndicator.switchingTo": "Switching to" | 501 | "workspaces.switchingIndicator.switchingTo": "Switching to" |
498 | } \ No newline at end of file | 502 | } |
diff --git a/src/index.ts b/src/index.ts index e466b4ab1..8419d5cf9 100644 --- a/src/index.ts +++ b/src/index.ts | |||
@@ -50,6 +50,7 @@ import { openExternalUrl } from './helpers/url-helpers'; | |||
50 | import userAgent from './helpers/userAgent-helpers'; | 50 | import userAgent from './helpers/userAgent-helpers'; |
51 | import { translateTo } from './helpers/translation-helpers'; | 51 | import { translateTo } from './helpers/translation-helpers'; |
52 | import { darkThemeGrayDarkest } from './themes/legacy'; | 52 | import { darkThemeGrayDarkest } from './themes/legacy'; |
53 | import { readCerts, removeNewLines } from './helpers/certs-helpers'; | ||
53 | 54 | ||
54 | const debug = require('./preload-safe-debug')('Ferdium:App'); | 55 | const debug = require('./preload-safe-debug')('Ferdium:App'); |
55 | 56 | ||
@@ -752,3 +753,41 @@ app.on('will-finish-launching', () => { | |||
752 | }); | 753 | }); |
753 | }); | 754 | }); |
754 | }); | 755 | }); |
756 | |||
757 | app.on( | ||
758 | 'certificate-error', | ||
759 | (event, _webContents, _url, _error, certificate, callback) => { | ||
760 | // On certificate error we disable default behaviour (stop loading the page) | ||
761 | // and we then say "it is all fine - true" to the callback | ||
762 | event.preventDefault(); | ||
763 | |||
764 | const useSelfSignedCertificates = | ||
765 | retrieveSettingValue( | ||
766 | 'useSelfSignedCertificates', | ||
767 | DEFAULT_APP_SETTINGS.useSelfSignedCertificates, | ||
768 | ) === true; | ||
769 | |||
770 | // Check if the certificate is trusted | ||
771 | if (!useSelfSignedCertificates) { | ||
772 | callback(false); | ||
773 | return; | ||
774 | } | ||
775 | |||
776 | const trustedCerts = readCerts(); | ||
777 | if (!trustedCerts) { | ||
778 | callback(false); | ||
779 | return; | ||
780 | } | ||
781 | |||
782 | const isTrustedCert = trustedCerts.includes( | ||
783 | removeNewLines(certificate.data), | ||
784 | ); | ||
785 | |||
786 | if (isTrustedCert) { | ||
787 | callback(true); | ||
788 | return; | ||
789 | } | ||
790 | |||
791 | callback(false); | ||
792 | }, | ||
793 | ); | ||