Skip to content

Commit

Permalink
feat(core): avoid popup window being blocked (#6451)
Browse files Browse the repository at this point in the history
  • Loading branch information
forehalo authored Apr 3, 2024
1 parent 3e9e2ce commit 6fa4b7d
Show file tree
Hide file tree
Showing 14 changed files with 78 additions and 28 deletions.
3 changes: 2 additions & 1 deletion packages/frontend/core/src/commands/affine-help.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { registerAffineCommand } from '@toeverything/infra';
import type { createStore } from 'jotai';

import { openSettingModalAtom } from '../atoms';
import { popupWindow } from '../utils';

export function registerAffineHelpCommands({
t,
Expand All @@ -20,7 +21,7 @@ export function registerAffineHelpCommands({
icon: <NewIcon />,
label: t['com.affine.cmdk.affine.whats-new'](),
run() {
window.open(runtimeConfig.changelogUrl, '_blank');
popupWindow(runtimeConfig.changelogUrl);
},
})
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Loading } from '@affine/component/ui/loading';
import { AffineShapeIcon } from '@affine/core/components/page-list';
import { useCredentialsRequirement } from '@affine/core/hooks/affine/use-server-config';
import { useAsyncCallback } from '@affine/core/hooks/affine-async-hooks';
import { popupWindow } from '@affine/core/utils';
import { SubscriptionPlan, type SubscriptionRecurring } from '@affine/graphql';
import {
changePasswordMutation,
Expand Down Expand Up @@ -48,7 +49,7 @@ const usePaymentRedirect = () => {
successCallbackLink: null,
},
});
window.open(checkoutUrl, '_self', 'norefferer');
popupWindow(checkoutUrl);
}, [recurring, plan, coupon, idempotencyKey, checkoutSubscription]);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { useCallback } from 'react';

import { useAppSettingHelper } from '../../../../../hooks/affine/use-app-setting-helper';
import { appIconMap, appNames } from '../../../../../pages/open-app';
import { mixpanel } from '../../../../../utils';
import { mixpanel, popupWindow } from '../../../../../utils';
import { relatedLinks } from './config';
import * as styles from './style.css';
import { UpdateCheckSection } from './update-check-section';
Expand Down Expand Up @@ -99,7 +99,7 @@ export const AboutAffine = () => {
desc={t['com.affine.aboutAFFiNE.changelog.description']()}
style={{ cursor: 'pointer' }}
onClick={() => {
window.open(runtimeConfig.changelogUrl, '_blank');
popupWindow(runtimeConfig.changelogUrl);
}}
>
<ArrowRightSmallIcon />
Expand Down Expand Up @@ -143,7 +143,7 @@ export const AboutAffine = () => {
<div
className={styles.communityItem}
onClick={() => {
window.open(link, '_blank');
popupWindow(link);
}}
key={title}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import { useMutation } from '../../../../../hooks/use-mutation';
import { useQuery } from '../../../../../hooks/use-query';
import type { SubscriptionMutator } from '../../../../../hooks/use-subscription';
import { useUserSubscription } from '../../../../../hooks/use-subscription';
import { mixpanel } from '../../../../../utils';
import { mixpanel, popupWindow } from '../../../../../utils';
import { SWRErrorBoundary } from '../../../../pure/swr-error-bundary';
import { CancelAction, ResumeAction } from '../plans/actions';
import * as styles from './style.css';
Expand Down Expand Up @@ -262,7 +262,7 @@ const PaymentMethodUpdater = () => {
const update = useAsyncCallback(async () => {
await trigger(null, {
onSuccess: data => {
window.open(data.createCustomerPortal, '_blank', 'noopener noreferrer');
popupWindow(data.createCustomerPortal);
},
});
}, [trigger]);
Expand Down Expand Up @@ -361,7 +361,7 @@ const InvoiceLine = ({

const open = useCallback(() => {
if (invoice.link) {
window.open(invoice.link, '_blank', 'noopener noreferrer');
popupWindow(invoice.link);
}
}, [invoice.link]);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Button } from '@affine/component';
import { useAsyncCallback } from '@affine/core/hooks/affine-async-hooks';
import { useMutation } from '@affine/core/hooks/use-mutation';
import { popupWindow } from '@affine/core/utils';
import { createCheckoutSessionMutation } from '@affine/graphql';
import { nanoid } from 'nanoid';
import { useCallback, useEffect, useMemo, useRef } from 'react';
Expand Down Expand Up @@ -51,11 +52,7 @@ export const AISubscribe = ({
},
{
onSuccess: data => {
const newTab = window.open(
data.createCheckoutSession,
'_blank',
'noopener noreferrer'
);
const newTab = popupWindow(data.createCheckoutSession);
if (newTab) {
newTabRef.current = newTab;
newTab.addEventListener('close', onClose);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import type {
Subscription,
SubscriptionMutator,
} from '@affine/core/hooks/use-subscription';
import { popupWindow } from '@affine/core/utils';
import type { SubscriptionRecurring } from '@affine/graphql';
import {
createCheckoutSessionMutation,
Expand Down Expand Up @@ -309,13 +310,7 @@ const Upgrade = ({
},
{
onSuccess: data => {
// FIXME: safari prevents from opening new tab by window api
// TODO(@xp): what if electron?
const newTab = window.open(
data.createCheckoutSession,
'_blank',
'noopener noreferrer'
);
const newTab = popupWindow(data.createCheckoutSession);

if (newTab) {
newTabRef.current = newTab;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Tooltip } from '@affine/component';
import { popupWindow } from '@affine/core/utils';
import { Unreachable } from '@affine/env/constant';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { CloseIcon, NewIcon, ResetIcon } from '@blocksuite/icons';
Expand Down Expand Up @@ -181,13 +182,12 @@ export function AppUpdaterButton({
onDownloadUpdate();
}
} else {
window.open(
`https://github.com/toeverything/AFFiNE/releases/tag/v${updateAvailable.version}`,
'_blank'
popupWindow(
`https://github.com/toeverything/AFFiNE/releases/tag/v${updateAvailable.version}`
);
}
} else if (changelogUnread) {
window.open(runtimeConfig.changelogUrl, '_blank');
popupWindow(runtimeConfig.changelogUrl);
onOpenChangelog();
} else {
throw new Unreachable();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Tooltip } from '@affine/component/ui/tooltip';
import { popupWindow } from '@affine/core/utils';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { CloseIcon, NewIcon } from '@blocksuite/icons';
import { Doc, useLiveData, useServiceOptional } from '@toeverything/infra';
Expand Down Expand Up @@ -70,7 +71,7 @@ export const HelpIsland = () => {
<StyledIconWrapper
data-testid="right-bottom-change-log-icon"
onClick={() => {
window.open(runtimeConfig.changelogUrl, '_blank');
popupWindow(runtimeConfig.changelogUrl);
}}
>
<NewIcon />
Expand Down
4 changes: 2 additions & 2 deletions packages/frontend/core/src/hooks/use-app-updater.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { atomWithObservable, atomWithStorage } from 'jotai/utils';
import { useCallback, useState } from 'react';
import { Observable } from 'rxjs';

import { mixpanel } from '../utils';
import { mixpanel, popupWindow } from '../utils';
import { useAsyncCallback } from './affine-async-hooks';

function rpcToObservable<
Expand Down Expand Up @@ -191,7 +191,7 @@ export const useAppUpdater = () => {
mixpanel.track('Button', {
resolve: 'OpenChangelog',
});
window.open(runtimeConfig.changelogUrl, '_blank');
popupWindow(runtimeConfig.changelogUrl);
await setChangelogUnread(true);
}, [setChangelogUnread]);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useAppSettingHelper } from '@affine/core/hooks/affine/use-app-setting-helper';
import { popupWindow } from '@affine/core/utils';
import { useLiveData, useService } from '@toeverything/infra';
import type { To } from 'history';
import { useCallback } from 'react';
Expand Down Expand Up @@ -32,7 +33,7 @@ export const WorkbenchLink = ({
typeof to === 'string'
? to
: `${to.pathname}${to.search}${to.hash}`;
window.open(basename + href, '_blank');
popupWindow(basename + href);
}
} else {
workbench.open(to);
Expand Down
43 changes: 43 additions & 0 deletions packages/frontend/core/src/pages/redirect.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { type LoaderFunction, Navigate, useLoaderData } from 'react-router-dom';

const trustedDomain = [
'stripe.com',
'github.com',
'twitter.com',
'discord.gg',
'youtube.com',
't.me',
'reddit.com',
];

export const loader: LoaderFunction = async ({ request }) => {
const url = new URL(request.url);
const searchParams = url.searchParams;
const redirectUri = searchParams.get('redirect_uri');

if (!redirectUri) {
return { allow: false };
}

const target = new URL(redirectUri);

if (
trustedDomain.some(domain =>
new RegExp(`.?${domain}$`).test(target.hostname)
)
) {
location.href = redirectUri;
}

return { allow: true };
};

export const Component = () => {
const { allow } = useLoaderData() as { allow: boolean };

if (allow) {
return null;
}

return <Navigate to="/404" />;
};
4 changes: 4 additions & 0 deletions packages/frontend/core/src/router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,10 @@ export const topLevelRoutes = [
path: '/onboarding',
lazy: () => import('./pages/onboarding'),
},
{
path: '/redirect-proxy',
lazy: () => import('./pages/redirect'),
},
{
path: '*',
lazy: () => import('./pages/404'),
Expand Down
1 change: 1 addition & 0 deletions packages/frontend/core/src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@ export * from './create-emotion-cache';
export * from './fractional-indexing';
export * from './intl-formatter';
export * from './mixpanel';
export * from './popup';
export * from './string2color';
export * from './toast';
6 changes: 6 additions & 0 deletions packages/frontend/core/src/utils/popup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export function popupWindow(target: string) {
const url = new URL(runtimeConfig.serverUrlPrefix + '/redirect-proxy');
url.searchParams.set('redirect_uri', target);

return window.open(url, '_blank', `noreferrer noopener`);
}

0 comments on commit 6fa4b7d

Please sign in to comment.