diff --git a/patches/protonmail/common-3.patch b/patches/protonmail/common-3.patch deleted file mode 100644 index f94eb0c2a..000000000 --- a/patches/protonmail/common-3.patch +++ /dev/null @@ -1,127 +0,0 @@ -diff --git a/packages/pack/scripts/validate.sh b/packages/pack/scripts/validate.sh -index 1a2ea64..bae388c 100755 ---- a/packages/pack/scripts/validate.sh -+++ b/packages/pack/scripts/validate.sh -@@ -58,7 +58,7 @@ function main { - fi; - - if [ "$hasSourceMap" -eq 0 ]; then -- hasError=true; -+ #hasError=true; - echo "[error] no SourceMaps found inside the directory: $OUTPUT_DIR"; - fi; - -diff --git a/packages/pack/bin/protonPack.js b/packages/pack/bin/protonPack.js -index 55715b89d..c87879ad4 100755 ---- a/packages/pack/bin/protonPack.js -+++ b/packages/pack/bin/protonPack.js -@@ -81,7 +81,7 @@ addGlobalOptions(program.command('build').description('create an optimized produ - const outputPath = path.resolve('./dist'); - await commandWithLog(`rm -rf ${outputPath}`); - await commandWithLog( -- `${require.resolve('webpack-cli/bin/cli.js')} --progress --output-path=${outputPath} ${webpackArgs}`, -+ `${require.resolve('webpack-cli/bin/cli.js')} --output-path=${outputPath} ${webpackArgs}`, - { - stdio: 'inherit', - } - -diff --git a/packages/pack/webpack/css.loader.js b/packages/pack/webpack/css.loader.js -index c50ab972c..a505eb314 100644 ---- a/packages/pack/webpack/css.loader.js -+++ b/packages/pack/webpack/css.loader.js -@@ -44,11 +44,13 @@ module.exports = ({ browserslist }) => { - }, - { - loader: require.resolve('resolve-url-loader'), -+ options: {sourceMap: false}, - }, - { - loader: require.resolve('sass-loader'), - options: { - additionalData: PREPEND_SASS, -+ sourceMap: true, // to please "resolve-url-loader" - }, - }, - ].filter(Boolean); - - -diff --git a/packages/shared/lib/helpers/browser.ts b/packages/shared/lib/helpers/browser.ts -index 9aaa78a28..f3d24b47c 100644 ---- a/packages/shared/lib/helpers/browser.ts -+++ b/packages/shared/lib/helpers/browser.ts -@@ -1,6 +1,21 @@ - import UAParser from 'ua-parser-js'; - - const uaParser = new UAParser(); -+{ -+ const platform = String(navigator.platform); -+ const userAgents = { -+ linux: "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36", -+ windows: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36", -+ macos: "Mozilla/5.0 (Macintosh; Intel Mac OS X 13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36" -+ } as const; -+ uaParser.setUA( -+ platform.startsWith("Linux") -+ ? userAgents.linux -+ : platform.startsWith("Win") -+ ? userAgents.windows -+ : userAgents.macos -+ ); -+} - const ua = uaParser.getResult(); - - export const hasModulesSupport = () => { -@@ -89,20 +104,10 @@ export const requireDirectAction = () => isSafari() || isFirefox() || isEdge(); - * @links { https://mathiasbynens.github.io/rel-noopener/} - */ - export const openNewTab = (url: string) => { -- if (isIE11()) { -- const otherWindow = window.open(); -- if (!otherWindow) { -- return; -- } -- otherWindow.opener = null; -- otherWindow.location.href = url; -- return; -- } -- const anchor = document.createElement('a'); -- -- anchor.setAttribute('rel', 'noreferrer nofollow noopener'); -- anchor.setAttribute('target', '_blank'); -- anchor.href = url; -- -- return anchor.click(); -+ window.dispatchEvent( -+ new CustomEvent( -+ "electron-mail:packages/shared/lib/helpers/browser.ts:openNewTab", -+ {detail: {url}}, -+ ), -+ ); - }; - -diff --git a/packages/components/components/link/SettingsLink.tsx b/packages/components/components/link/SettingsLink.tsx -index 5081c4003..cde37c0cb 100644 ---- a/packages/components/components/link/SettingsLink.tsx -+++ b/packages/components/components/link/SettingsLink.tsx -@@ -48,7 +48,7 @@ const SettingsLink = ({ path, app, children, ...rest }: Props, ref: Ref - {children} - -diff --git a/packages/components/helpers/earlyAccessDesynchronization.ts b/packages/components/helpers/earlyAccessDesynchronization.ts -index 36bd0c712..c2fb3681c 100644 ---- a/packages/components/helpers/earlyAccessDesynchronization.ts -+++ b/packages/components/helpers/earlyAccessDesynchronization.ts -@@ -42,6 +42,7 @@ export const handleEarlyAccessDesynchronization = ({ - earlyAccessScope: Feature | undefined; - appName: APP_NAMES; - }) => { -+ return; - if (doesNotSupportEarlyAccessVersion()) { - return; - } diff --git a/patches/protonmail/constants-8.patch b/patches/protonmail/constants-8.patch deleted file mode 100644 index 67a6cd5b5..000000000 --- a/patches/protonmail/constants-8.patch +++ /dev/null @@ -1,24 +0,0 @@ -diff --git a/packages/shared/lib/constants.ts b/packages/shared/lib/constants.ts -index d035e6c88..96af3775b 100644 ---- a/packages/shared/lib/constants.ts -+++ b/packages/shared/lib/constants.ts -@@ -69,7 +69,7 @@ interface AppConfiguration { - - export const APPS_CONFIGURATION: { [key in APP_NAMES]: AppConfiguration } = { - [APPS.PROTONACCOUNT]: { -- publicPath: '', -+ publicPath: '/account', - subdomain: 'account', - name: 'Proton Account', - bareName: 'Account', -@@ -141,8 +141,8 @@ export const APPS_CONFIGURATION: { [key in APP_NAMES]: AppConfiguration } = { - settingsSlug: '', - }, - [APPS.PROTONVPN_SETTINGS]: { -- publicPath: '', -- subdomain: '', -+ publicPath: 'account/vpn', -+ subdomain: 'account', - name: VPN_APP_NAME, - bareName: VPN_SHORT_APP_NAME, - clientID: 'web-vpn-settings', diff --git a/patches/protonmail/drop-circular-dependency-2.patch b/patches/protonmail/drop-circular-dependency-2.patch new file mode 100644 index 000000000..72c8f682b --- /dev/null +++ b/patches/protonmail/drop-circular-dependency-2.patch @@ -0,0 +1,44 @@ +diff --git a/packages/components/hooks/usePendingUserInvitations.ts b/packages/components/hooks/usePendingUserInvitations.ts +index d61e10f07..6cc0d2097 100644 +--- a/packages/components/hooks/usePendingUserInvitations.ts ++++ b/packages/components/hooks/usePendingUserInvitations.ts +@@ -1,7 +1,7 @@ + import { useCallback } from 'react'; + + import { PendingInvitation as PendingUserInvitation } from '@proton/shared/lib/interfaces'; +-import { UserInvitationModel } from '@proton/shared/lib/models'; ++import { UserInvitationModelKey } from '@proton/shared/lib/models/userInvitationModel.key'; + import { fetchPendingUserInvitations } from '@proton/shared/lib/models/userInvitationModelApi'; + + import useApi from './useApi'; +@@ -13,7 +13,7 @@ const usePendingUserInvitations = (): [PendingUserInvitation[] | undefined, bool + const cache = useCache(); + + const miss = useCallback(() => fetchPendingUserInvitations(api), [api]); +- return useCachedModelResult(cache, UserInvitationModel.key, miss); ++ return useCachedModelResult(cache, UserInvitationModelKey, miss); + }; + + export default usePendingUserInvitations; +diff --git a/packages/shared/lib/models/userInvitationModel.js b/packages/shared/lib/models/userInvitationModel.js +index ec3e45c0e..c8b5672ed 100644 +--- a/packages/shared/lib/models/userInvitationModel.js ++++ b/packages/shared/lib/models/userInvitationModel.js +@@ -1,8 +1,9 @@ + import updateCollection from '../helpers/updateCollection'; + import { fetchPendingUserInvitations } from './userInvitationModelApi'; ++import { UserInvitationModelKey as key } from './userInvitationModel.key'; + + export const UserInvitationModel = { +- key: 'UserInvitations', ++ key, + get: fetchPendingUserInvitations, + update: (model, events) => updateCollection({ model, events, itemKey: 'UserInvitation' }), + }; +diff --git a/packages/shared/lib/models/userInvitationModel.key.js b/packages/shared/lib/models/userInvitationModel.key.js +new file mode 100644 +index 000000000..c07ff03fa +--- /dev/null ++++ b/packages/shared/lib/models/userInvitationModel.key.js +@@ -0,0 +1 @@ ++export const UserInvitationModelKey = 'UserInvitations'; diff --git a/patches/protonmail/drop-circular-dependency.patch b/patches/protonmail/drop-circular-dependency.patch new file mode 100644 index 000000000..4f983178c --- /dev/null +++ b/patches/protonmail/drop-circular-dependency.patch @@ -0,0 +1,49 @@ +diff --git a/packages/components/hooks/usePendingUserInvitations.ts b/packages/components/hooks/usePendingUserInvitations.ts +index 6044196e1..b35ae94f5 100644 +--- a/packages/components/hooks/usePendingUserInvitations.ts ++++ b/packages/components/hooks/usePendingUserInvitations.ts +@@ -2,11 +2,11 @@ import { useCallback } from 'react'; + + import { getInvitations } from '@proton/shared/lib/api/user'; + import { Api, PendingInvitation as PendingUserInvitation } from '@proton/shared/lib/interfaces'; +-import { UserInvitationModel } from '@proton/shared/lib/models'; + + import useApi from './useApi'; + import useCache from './useCache'; + import useCachedModelResult from './useCachedModelResult'; ++import { UserInvitationModelKey } from '@proton/shared/lib/models/userInvitationModel.key'; + + export const fetchPendingUserInvitations = (api: Api) => + api<{ UserInvitations: PendingUserInvitation[] }>(getInvitations()).then(({ UserInvitations }) => { +@@ -18,7 +18,7 @@ const usePendingUserInvitations = (): [PendingUserInvitation[] | undefined, bool + const cache = useCache(); + + const miss = useCallback(() => fetchPendingUserInvitations(api), [api]); +- return useCachedModelResult(cache, UserInvitationModel.key, miss); ++ return useCachedModelResult(cache, UserInvitationModelKey, miss); + }; + + export default usePendingUserInvitations; +diff --git a/packages/shared/lib/models/userInvitationModel.js b/packages/shared/lib/models/userInvitationModel.js +index 1fa9690b7..a9035e06d 100644 +--- a/packages/shared/lib/models/userInvitationModel.js ++++ b/packages/shared/lib/models/userInvitationModel.js +@@ -1,9 +1,10 @@ + import { fetchPendingUserInvitations } from '@proton/components/hooks/usePendingUserInvitations'; + + import updateCollection from '../helpers/updateCollection'; ++import { UserInvitationModelKey as key } from './userInvitationModel.key'; + + export const UserInvitationModel = { +- key: 'UserInvitations', ++ key, + get: fetchPendingUserInvitations, + update: (model, events) => updateCollection({ model, events, itemKey: 'UserInvitation' }), + }; +diff --git a/packages/shared/lib/models/userInvitationModel.key.js b/packages/shared/lib/models/userInvitationModel.key.js +new file mode 100644 +index 000000000..c07ff03fa +--- /dev/null ++++ b/packages/shared/lib/models/userInvitationModel.key.js +@@ -0,0 +1 @@ ++export const UserInvitationModelKey = 'UserInvitations'; diff --git a/patches/protonmail/meta.json b/patches/protonmail/meta.json index cec869c1e..fdc76b60c 100644 --- a/patches/protonmail/meta.json +++ b/patches/protonmail/meta.json @@ -1,9 +1,10 @@ { "proton-mail": [ - "common-3.patch", - "url-3.patch", - "constants-8.patch", - "sentry-11.patch", + "common-4.patch", + "drop-circular-dependency.patch", + "url-4.patch", + "constants-10.patch", + "sentry-12.patch", "pack-api-arg-4.patch", "pack-webpack-6.patch", "session-storage-5.patch", @@ -12,9 +13,10 @@ "proton-mail.patch" ], "proton-account": [ - "common-3.patch", + "common-4.patch", + "drop-circular-dependency-2.patch", "url-4.patch", - "constants-8.patch", + "constants-10.patch", "sentry-12.patch", "pack-api-arg-4.patch", "pack-webpack-6.patch", @@ -24,10 +26,11 @@ "proton-account.patch" ], "proton-calendar": [ - "common-3.patch", - "url-3.patch", + "common-4.patch", + "drop-circular-dependency.patch", + "url-4.patch", "constants-10.patch", - "sentry-11.patch", + "sentry-12.patch", "pack-api-arg-4.patch", "pack-webpack-6.patch", "session-storage-5.patch", @@ -35,7 +38,8 @@ "embedded-verification-3.patch" ], "proton-drive": [ - "common-3.patch", + "common-4.patch", + "drop-circular-dependency.patch", "url-4.patch", "constants-10.patch", "sentry-12.patch", @@ -48,6 +52,7 @@ ], "proton-vpn-settings": [ "common-4.patch", + "drop-circular-dependency-2.patch", "url-4.patch", "constants-10.patch", "sentry-12.patch", diff --git a/patches/protonmail/proton-mail.patch b/patches/protonmail/proton-mail.patch index 8ff043e33..310b683c8 100644 --- a/patches/protonmail/proton-mail.patch +++ b/patches/protonmail/proton-mail.patch @@ -14,56 +14,18 @@ index 519a50349..819bdb911 100644 + } }); -diff --git a/packages/components/containers/login/MinimalLoginContainer.tsx b/packages/components/containers/login/MinimalLoginContainer.tsx -index 6fef05c..1719cc8 100644 ---- a/packages/components/containers/login/MinimalLoginContainer.tsx -+++ b/packages/components/containers/login/MinimalLoginContainer.tsx -@@ -25,6 +25,8 @@ import AbuseModal from './AbuseModal'; - import { AuthActionResponse, AuthCacheResult, AuthStep } from './interface'; - import { handleLogin, handleTotp, handleUnlock } from './loginActions'; - -+const ELECTRON_MAIL_FORM_STYLE = { padding: '0.8rem' } as const; -+ - const UnlockForm = ({ - onSubmit, - cancelButton, -@@ -43,6 +45,7 @@ const UnlockForm = ({ - withLoading(onSubmit(keyPassword)).catch(noop); - }} - method="post" -+ style={ELECTRON_MAIL_FORM_STYLE} - > - -
-@@ -87,6 +90,7 @@ const TOTPForm = ({ - withLoading(onSubmit(totp)).catch(noop); - }} - method="post" -+ style={ELECTRON_MAIL_FORM_STYLE} - > - -
-@@ -165,6 +169,7 @@ const LoginForm = ({ - withLoading(run()).catch(noop); - }} - method="post" -+ style={ELECTRON_MAIL_FORM_STYLE} - > - {hasChallenge && ( - {showToolbar && ( - + { - const { isDBLimited, dropdownOpened } = getESDBStatus(); +@@ -11,10 +11,7 @@ import { + useMailSettings, + usePopperAnchor, + useToggle, +- useUser, + } from '@proton/components'; +-import { isMobile } from '@proton/shared/lib/helpers/browser'; +-import { isPaid } from '@proton/shared/lib/user/helpers'; + + import { ADVANCED_SEARCH_OVERLAY_CLOSE_EVENT } from '../../../constants'; + import { useEncryptedSearchContext } from '../../../containers/EncryptedSearchProvider'; +@@ -40,7 +37,6 @@ const MailSearch = ({ breakpoints, labelID, location }: Props) => { + const { anchorRef, isOpen, open, close } = usePopperAnchor(); + const searchParams = extractSearchParameters(location); + const [searchInputValue, setSearchInputValue] = useState(searchParams.keyword || ''); +- const [user] = useUser(); + const [, loadingMailSettings] = useMailSettings(); + const [, loadingLabels] = useLabels(); + const [, loadingFolders] = useFolders(); +@@ -49,7 +45,7 @@ const MailSearch = ({ breakpoints, labelID, location }: Props) => { + const { dropdownOpened } = getESDBStatus(); const esState = useEncryptedSearchToggleState(isOpen); - const showEncryptedSearch = !isMobile() && !!isPaid(user); @@ -381,11 +362,11 @@ index d1cb165a1..904bd2364 100644 const { state: showMore, toggle: toggleShowMore } = useToggle(false); diff --git a/packages/encrypted-search/lib/constants.ts b/packages/encrypted-search/lib/constants.ts -index 1b28a2765..ee7c59df8 100644 +index ebdf5ee22..28adf6c62 100644 --- a/packages/encrypted-search/lib/constants.ts +++ b/packages/encrypted-search/lib/constants.ts -@@ -67,7 +67,7 @@ export const defaultESStatus = { - isBuilding: false, +@@ -131,7 +131,7 @@ export const defaultESStatus = { + isEnablingContentSearch: false, isDBLimited: false, esEnabled: false, - esSupported: true, @@ -393,26 +374,3 @@ index 1b28a2765..ee7c59df8 100644 isRefreshing: false, isSearchPartial: false, isSearching: false, - -diff --git a/packages/encrypted-search/lib/esHelpers/esUtils.ts b/packages/encrypted-search/lib/esHelpers/esUtils.ts -index 2bb63cf10..c1440e969 100644 ---- a/packages/encrypted-search/lib/esHelpers/esUtils.ts -+++ b/packages/encrypted-search/lib/esHelpers/esUtils.ts -@@ -296,15 +296,7 @@ export const updateSizeIDB = (userID: string, addend: number) => { - * Check whether ES can be used not just because the index key exists in localStorage - * but also because IDB is not corrupt, i.e. the object store exists - */ --export const canUseES = async (userID: string, storeName: string) => { -- if (!indexKeyExists(userID)) { -- return false; -- } -- const esDB = await openESDB(userID); -- const isIntact = esDB.objectStoreNames.contains(storeName); -- esDB.close(); -- return isIntact; --}; -+export const canUseES = async (userID: string, storeName: string) => false; - - /** - * Request storage persistence to prevent the ES database from being evicted - diff --git a/patches/protonmail/sentry-11.patch b/patches/protonmail/sentry-11.patch deleted file mode 100644 index d3de6c78f..000000000 --- a/patches/protonmail/sentry-11.patch +++ /dev/null @@ -1,188 +0,0 @@ -diff --git a/packages/shared/lib/helpers/sentry.ts b/packages/shared/lib/helpers/sentry.ts -index 69e21214b..6d6a3fb2a 100644 ---- a/packages/shared/lib/helpers/sentry.ts -+++ b/packages/shared/lib/helpers/sentry.ts -@@ -1,14 +1,9 @@ - import { - captureException, -- configureScope, -- init, -- makeFetchTransport, - captureMessage as sentryCaptureMessage, - } from '@sentry/browser'; --import { BrowserTransportOptions } from '@sentry/browser/types/transports/types'; - - import { VPN_HOSTNAME } from '../constants'; --import { ApiError } from '../fetch/ApiError'; - import { getUIDHeaders } from '../fetch/headers'; - import { ProtonConfig } from '../interfaces'; - -@@ -61,21 +56,6 @@ export const getContentTypeHeaders = (input: RequestInfo | URL): HeadersInit => - return {}; - }; - --const sentryFetch = (input: RequestInfo | URL, init?: RequestInit) => { -- return globalThis.fetch(input, { -- ...init, -- headers: { -- ...init?.headers, -- ...getContentTypeHeaders(input), -- ...context.authHeaders, -- }, -- }); --}; -- --const makeProtonFetchTransport = (options: BrowserTransportOptions) => { -- return makeFetchTransport(options, sentryFetch); --}; -- - const isLocalhost = (host: string) => host.startsWith('localhost'); - const isProduction = (host: string) => host.endsWith('.proton.me') || host === VPN_HOSTNAME; - -@@ -94,143 +74,10 @@ function main({ - sessionTracking = false, - sentryConfig = getDefaultSentryConfig(config), - ignore = ({ host }) => isLocalhost(host), --}: SentryOptions) { -- const { SENTRY_DSN, APP_VERSION } = config; -- const { host, release, environment } = sentryConfig; -- -- // No need to configure it if we don't load the DSN -- if (!SENTRY_DSN || ignore(sentryConfig)) { -- return; -- } -+}: SentryOptions) {} - -- setUID(uid); -- -- // Assumes SENTRY_DSN is: https://111b3eeaaec34cae8e812df705690a36@sentry/11 -- // To get https://111b3eeaaec34cae8e812df705690a36@protonmail.com/api/core/v4/reports/sentry/11 -- const dsn = SENTRY_DSN.replace('sentry', `${host}/api/core/v4/reports/sentry`); -- -- init({ -- dsn, -- release, -- environment, -- normalizeDepth: 5, -- transport: makeProtonFetchTransport, -- autoSessionTracking: sessionTracking, -- // Disable client reports. Client reports are used by sentry to retry events that failed to send on visibility change. -- // Unfortunately Sentry does not use the custom transport for those, and thus fails to add the headers the API requires. -- sendClientReports: false, -- beforeSend(event, hint) { -- const error = hint?.originalException; -- const stack = typeof error === 'string' ? error : error?.stack; -- // Filter out broken ferdi errors -- if (stack && stack.match(/ferdi|franz/i)) { -- return null; -- } -- -- // Not interested in uncaught API errors -- if (error instanceof ApiError) { -- return null; -- } -- -- if (!context.enabled) { -- return null; -- } -- -- // Remove the hash from the request URL and navigation breadcrumbs to avoid -- // leaking the search parameters of encrypted searches -- if (event.request && event.request.url) { -- [event.request.url] = event.request.url.split('#'); -- } -- if (event.breadcrumbs) { -- event.breadcrumbs = event.breadcrumbs.map((breadcrumb) => { -- if (breadcrumb.category === 'navigation' && breadcrumb.data) { -- [breadcrumb.data.from] = breadcrumb.data.from.split('#'); -- [breadcrumb.data.to] = breadcrumb.data.to.split('#'); -- } -- return breadcrumb; -- }); -- } -- -- return event; -- }, -- // Some ignoreErrors and denyUrls are taken from this gist: https://gist.github.com/Chocksy/e9b2cdd4afc2aadc7989762c4b8b495a -- // This gist is suggested in the Sentry documentation: https://docs.sentry.io/clients/javascript/tips/#decluttering-sentry -- ignoreErrors: [ -- // Ignore random plugins/extensions -- 'top.GLOBALS', -- 'canvas.contentDocument', -- 'MyApp_RemoveAllHighlights', -- 'atomicFindClose', -- // See http://toolbar.conduit.com/Developer/HtmlAndGadget/Methods/JSInjection.aspx -- 'conduitPage', -- // https://bugzilla.mozilla.org/show_bug.cgi?id=1678243 -- 'XDR encoding failure', -- 'Request timed out', -- 'No network connection', -- 'Failed to fetch', -- 'NetworkError when attempting to fetch resource.', -- 'webkitExitFullScreen', // Bug in Firefox for iOS. -- 'InactiveSession', -- 'UnhandledRejection', // Happens too often in extensions and we have lints for that, so should be safe to ignore. -- /chrome-extension/, -- /moz-extension/, -- 'TransferCancel', // User action to interrupt upload or download in Drive. -- 'UploadConflictError', // User uploading the same file again in Drive. -- 'UploadUserError', // Upload error on user's side in Drive. -- 'ValidationError', // Validation error on user's side in Drive. -- 'ChunkLoadError', // WebPack loading source code. -- /ResizeObserver loop/, // Chromium bug https://stackoverflow.com/questions/49384120/resizeobserver-loop-limit-exceeded -- // See: http://blog.errorception.com/2012/03/tale-of-unfindable-js-error.html -- 'originalCreateNotification', -- 'http://tt.epicplay.com', -- "Can't find variable: ZiteReader", -- 'jigsaw is not defined', -- 'ComboSearch is not defined', -- 'http://loading.retry.widdit.com/', -- // Facebook borked -- 'fb_xd_fragment', -- // ISP "optimizing" proxy - `Cache-Control: no-transform` seems to reduce this. (thanks @acdha) -- // See http://stackoverflow.com/questions/4113268/how-to-stop-javascript-injection-from-vodafone-proxy -- 'bmi_SafeAddOnload', -- 'EBCallBackMessageReceived', -- // Avast extension error -- '_avast_submit', -- ], -- denyUrls: [ -- // Google Adsense -- /pagead\/js/i, -- // Facebook flakiness -- /graph\.facebook\.com/i, -- // Facebook blocked -- /connect\.facebook\.net\/en_US\/all\.js/i, -- // Woopra flakiness -- /eatdifferent\.com\.woopra-ns\.com/i, -- /static\.woopra\.com\/js\/woopra\.js/i, -- // Chrome extensions -- /extensions\//i, -- /^chrome:\/\//i, -- // Other plugins -- /127\.0\.0\.1:4001\/isrunning/i, // Cacaoweb -- /webappstoolbarba\.texthelp\.com\//i, -- /metrics\.itunes\.apple\.com\.edgesuite\.net\//i, -- ], -- }); -- -- configureScope((scope) => { -- scope.setTag('appVersion', APP_VERSION); -- }); --} -- --export const traceError = (...args: Parameters) => { -- if (!isLocalhost(window.location.host)) { -- captureException(...args); -- } --}; -+export const traceError = (...args: Parameters) => console.error(...args); - --export const captureMessage = (...args: Parameters) => { -- if (!isLocalhost(window.location.host)) { -- sentryCaptureMessage(...args); -- } --}; -+export const captureMessage = (...args: Parameters) => console.log(...args); - - export default main; diff --git a/patches/protonmail/url-3.patch b/patches/protonmail/url-3.patch deleted file mode 100644 index e325e8d10..000000000 --- a/patches/protonmail/url-3.patch +++ /dev/null @@ -1,103 +0,0 @@ -diff --git a/packages/shared/lib/helpers/url.ts b/packages/shared/lib/helpers/url.ts -index 11cd310f6..8019c07f5 100644 ---- a/packages/shared/lib/helpers/url.ts -+++ b/packages/shared/lib/helpers/url.ts -@@ -175,48 +175,16 @@ export const getSecondLevelDomain = (hostname: string) => { - return hostname.slice(hostname.indexOf('.') + 1); - }; - --export const getRelativeApiHostname = (hostname: string) => { -- const idx = hostname.indexOf('.'); -- const first = hostname.slice(0, idx); -- const second = hostname.slice(idx + 1); -- return `${first}-api.${second}`; --}; -- - export const getIsDohDomain = (origin: string) => { - return DOH_DOMAINS.some((dohDomain) => origin.endsWith(dohDomain)); - }; - - export const getApiSubdomainUrl = (pathname: string) => { -- const url = new URL('/', window.location.origin); -- if (url.hostname === 'localhost' || getIsDohDomain(url.origin)) { -- url.pathname = `/api${pathname}`; -- return url; -- } -- url.hostname = getRelativeApiHostname(url.hostname); -+ const url = new URL('/', '___ELECTRON_MAIL_PROTON_API_ENTRY_URL_PLACEHOLDER___'); - url.pathname = pathname; - return url; - }; - --export const getAppUrlFromApiUrl = (apiUrl: string, appName: APP_NAMES) => { -- const { subdomain } = APPS_CONFIGURATION[appName]; -- const url = new URL(apiUrl); -- const { hostname } = url; -- const index = hostname.indexOf('.'); -- const tail = hostname.slice(index + 1); -- url.pathname = ''; -- url.hostname = `${subdomain}.${tail}`; -- return url; --}; -- --export const getAppUrlRelativeToOrigin = (origin: string, appName: APP_NAMES) => { -- const { subdomain } = APPS_CONFIGURATION[appName]; -- const url = new URL(origin); -- const segments = url.host.split('.'); -- segments[0] = subdomain; -- url.hostname = segments.join('.'); -- return url; --}; -- - let cache = ''; - export const getStaticURL = (path: string) => { - if (window.location.hostname === 'localhost' || getIsDohDomain(window.location.origin)) { - -diff --git a/packages/shared/lib/fetch/helpers.ts b/packages/shared/lib/fetch/helpers.ts -index f0b3e2e31..90995e1fc 100644 ---- a/packages/shared/lib/fetch/helpers.ts -+++ b/packages/shared/lib/fetch/helpers.ts -@@ -10,6 +10,7 @@ const appendQueryParams = (url: URL, params: { [key: string]: any }) => { - }); - }; - -+/* */ - export const createUrl = (urlString: string, params: { [key: string]: any } = {}) => { - let url: URL; - if (typeof window !== 'undefined') { -@@ -20,6 +21,7 @@ export const createUrl = (urlString: string, params: { [key: string]: any } = {} - appendQueryParams(url, params); - return url; - }; -+/* */ - - export const checkStatus = (response: Response, config: any) => { - const { status } = response; - -diff --git a/applications/mail/src/app/helpers/message/messageImages.ts b/applications/mail/src/app/helpers/message/messageImages.ts -index effa61709..2d54ff153 100644 ---- a/applications/mail/src/app/helpers/message/messageImages.ts -+++ b/applications/mail/src/app/helpers/message/messageImages.ts -@@ -194,7 +194,7 @@ export const replaceProxyWithOriginalURLAttributes = (message: MessageState, doc - - export const forgeImageURL = (url: string, uid: string) => { - const config = getImage(url, 0, uid); -- const prefixedUrl = `api/${config.url}`; // api/ is required to set the AUTH cookie -+ const prefixedUrl = `___ELECTRON_MAIL_PROTON_API_ENTRY_URL_PLACEHOLDER___/${config.url}`; - const urlToLoad = createUrl(prefixedUrl, config.params); - return urlToLoad.toString(); - }; - -diff --git a/packages/components/containers/contacts/helpers/senderImage.ts b/packages/components/containers/contacts/helpers/senderImage.ts -index 24578bbc0..6b38625e0 100644 ---- a/packages/components/containers/contacts/helpers/senderImage.ts -+++ b/packages/components/containers/contacts/helpers/senderImage.ts -@@ -58,7 +58,7 @@ export const getSenderImageUrl = ( - mode?: SenderImageMode - ) => { - const config = getLogo(emailAddress, size, bimiSelector, mode, UID); -- const prefixedUrl = `api/${config.url}`; // api/ is required to set the AUTH cookie -+ const prefixedUrl = `___ELECTRON_MAIL_PROTON_API_ENTRY_URL_PLACEHOLDER___/${config.url}`; - const url = createUrl(prefixedUrl, config.params); - return url.toString(); - }; diff --git a/src/electron-main/util/proton-url.ts b/src/electron-main/util/proton-url.ts index c9badc308..76149fddc 100644 --- a/src/electron-main/util/proton-url.ts +++ b/src/electron-main/util/proton-url.ts @@ -31,7 +31,7 @@ export const protonApiUrlsUtil = { // https://github.com/vladimiry/ElectronMail/issues/490#issuecomment-1046883249 patchCaptchaResponseHeaders(urlPathname: string, responseHeaders: Record): boolean { - if (!`${urlPathname}/`.includes("/captcha/")) { + if (!["/captcha/", "/challenge/"].some((value) => `${urlPathname}/`.includes(value))) { return false; } @@ -49,13 +49,10 @@ export const protonApiUrlsUtil = { }, // https://github.com/vladimiry/ElectronMail/issues/522#issuecomment-1156989727 - patchAuthHeaders(urlPathname: string, requestHeaders: Record): boolean { + patchAuthRequestHeaders(urlPathname: string, requestHeaders: Record): boolean { if ( - !`${urlPathname}/`.startsWith("/auth/") - && - !`${urlPathname}/`.startsWith("/api/auth/") - && - !`${urlPathname}/`.startsWith("/core/auth/")) { + !["/auth/", "/core/v4/auth/"].some((value) => `${urlPathname}/`.startsWith(value)) + ) { return false; } @@ -72,7 +69,7 @@ export const protonApiUrlsUtil = { return true; }, - patchMailApiHeaders(urlPathname: string, requestHeaders: Record): boolean { + patchMailApiRequestHeaders(urlPathname: string, requestHeaders: Record): boolean { if (!urlPathname.includes("/mail/v4/messages/")) { return false; } diff --git a/src/electron-main/web-request/index.ts b/src/electron-main/web-request/index.ts index 4c8d0ede0..c48130d2f 100644 --- a/src/electron-main/web-request/index.ts +++ b/src/electron-main/web-request/index.ts @@ -265,8 +265,8 @@ export function initWebRequestListenersByAccount( requestHeaders[headerName] = getUserAgentByAccount({customUserAgent}); } - protonApiUrlsUtil.patchAuthHeaders(String(url?.pathname), requestHeaders); - protonApiUrlsUtil.patchMailApiHeaders(String(url?.pathname), requestHeaders); + protonApiUrlsUtil.patchAuthRequestHeaders(String(url?.pathname), requestHeaders); + protonApiUrlsUtil.patchMailApiRequestHeaders(String(url?.pathname), requestHeaders); callback({requestHeaders}); }, diff --git a/src/electron-preload/webview/primary/api/index.ts b/src/electron-preload/webview/primary/api/index.ts index 9f1ff01d4..3c3e53fa1 100644 --- a/src/electron-preload/webview/primary/api/index.ts +++ b/src/electron-preload/webview/primary/api/index.ts @@ -188,7 +188,7 @@ export function registerApi(providerApi: ProviderApi): void { const elements = await resolveDomElements( { - username: () => document.querySelector("form[name=loginForm] #login"), + username: () => document.querySelector("form[name=loginForm] #username"), }, logger, ); @@ -234,7 +234,7 @@ export function registerApi(providerApi: ProviderApi): void { logger.info(); const resolveElementsConfig = { - input: () => document.querySelector("form[name=totpForm] #twoFa"), + input: () => document.querySelector("form[name=totpForm] #totp"), button: () => document.querySelector("form[name=totpForm] [type=submit]"), }; const elements = await resolveDomElements(resolveElementsConfig, logger); @@ -269,7 +269,7 @@ export function registerApi(providerApi: ProviderApi): void { const elements = await resolveDomElements( { - mailboxPassword: () => document.querySelector("form[name=unlockForm] #password"), + mailboxPassword: () => document.querySelector("form[name=unlockForm] #mailboxPassword"), submit: () => document.querySelector("form[name=unlockForm] [type=submit]"), }, logger, diff --git a/src/shared/const/proton-apps.ts b/src/shared/const/proton-apps.ts index fc9239c26..e27c6359a 100644 --- a/src/shared/const/proton-apps.ts +++ b/src/shared/const/proton-apps.ts @@ -23,7 +23,7 @@ export const PROVIDER_REPO_MAP = { basePath: "", apiSubdomain: "mail-api", repoRelativeDistDir: "./dist", - tag: "proton-mail@5.0.19.5", + tag: "proton-mail@5.0.22.7", protonPack: { webpackIndexEntryItems: [ // immediate @@ -49,14 +49,14 @@ export const PROVIDER_REPO_MAP = { basePath: "account", apiSubdomain: "account-api", repoRelativeDistDir: "./dist", - tag: "proton-account@5.0.22.2", + tag: "proton-account@5.0.31.3", protonPack: {} }, [PROVIDER_APP_NAMES[2]]: { basePath: "calendar", apiSubdomain: "calendar-api", repoRelativeDistDir: "./dist", - tag: "proton-calendar@5.0.9.4", + tag: "proton-calendar@5.0.10.15", protonPack: { webpackIndexEntryItems: [ // immediate @@ -69,14 +69,14 @@ export const PROVIDER_REPO_MAP = { basePath: "drive", apiSubdomain: "drive-api", repoRelativeDistDir: "./dist", - tag: "proton-drive@5.0.12.2", + tag: "proton-drive@5.0.13.8", protonPack: {}, }, [PROVIDER_APP_NAMES[4]]: { basePath: "account/vpn", apiSubdomain: "account-api", repoRelativeDistDir: "./dist", - tag: "proton-vpn-settings@5.0.20.1", + tag: "proton-vpn-settings@5.0.30.2", protonPack: {}, }, } as const;