From e6bf381e2fa3f0c10c629b841956503808c20244 Mon Sep 17 00:00:00 2001 From: Zai Shi Date: Fri, 6 Jun 2025 04:36:46 +0200 Subject: [PATCH] Disable OAuth in iframe (#701) ---- > [!IMPORTANT] > Disable OAuth in iframes using `useInIframe` hook and update `SimpleTooltip` to support conditional disabling. > > - **Behavior**: > - Disable OAuth buttons in iframes by using `useInIframe` hook in `oauth-button.tsx`. > - Show tooltip "OAuth is disabled in iFrame" when OAuth buttons are disabled. > - **Components**: > - Add `useInIframe` hook in `use-in-iframe.tsx` to detect iframe context. > - Remove `IframePreventer` component and its usage in `stack-handler.tsx`. > - Update `SimpleTooltip` in `simple-tooltip.tsx` to accept `disabled` prop to conditionally disable tooltips. > - **Misc**: > - Remove unused `useTranslation` import in `auth-page.tsx`. > > This description was created by [Ellipsis](https://www.ellipsis.dev?ref=stack-auth%2Fstack-auth&utm_source=github&utm_medium=referral) for 35793e8055b8358abf300bcfed399151d499b8ec. You can [customize](https://app.ellipsis.dev/stack-auth/settings/summaries) this summary. It will automatically update as commits are pushed. --------- Co-authored-by: Konsti Wohlwend --- .../src/components/simple-tooltip.tsx | 3 +- .../src/components-page/auth-page.tsx | 2 - .../src/components-page/stack-handler.tsx | 11 +---- .../template/src/components/oauth-button.tsx | 47 +++++++++++-------- ...iframe-preventer.tsx => use-in-iframe.tsx} | 10 +--- 5 files changed, 34 insertions(+), 39 deletions(-) rename packages/template/src/components/{iframe-preventer.tsx => use-in-iframe.tsx} (50%) diff --git a/packages/stack-ui/src/components/simple-tooltip.tsx b/packages/stack-ui/src/components/simple-tooltip.tsx index b603e9228..4be4389cf 100644 --- a/packages/stack-ui/src/components/simple-tooltip.tsx +++ b/packages/stack-ui/src/components/simple-tooltip.tsx @@ -7,6 +7,7 @@ export function SimpleTooltip(props: { type?: 'info' | 'warning', inline?: boolean, className?: string, + disabled?: boolean, }) { const iconClassName = cn("w-4 h-4 text-zinc-500", props.inline && "inline"); const icon = props.type === 'warning' ? @@ -21,7 +22,7 @@ export function SimpleTooltip(props: { return ( - + {props.inline ? ( diff --git a/packages/template/src/components-page/auth-page.tsx b/packages/template/src/components-page/auth-page.tsx index 88683f697..74c83b99f 100644 --- a/packages/template/src/components-page/auth-page.tsx +++ b/packages/template/src/components-page/auth-page.tsx @@ -42,8 +42,6 @@ export function AuthPage(props: Props) { } function Fallback(props: Props) { - const { t } = useTranslation(); - return (
diff --git a/packages/template/src/components-page/stack-handler.tsx b/packages/template/src/components-page/stack-handler.tsx index 44e92168d..86ccbb7d6 100644 --- a/packages/template/src/components-page/stack-handler.tsx +++ b/packages/template/src/components-page/stack-handler.tsx @@ -4,7 +4,6 @@ import { getRelativePart } from "@stackframe/stack-shared/dist/utils/urls"; import { RedirectType, notFound, redirect } from 'next/navigation'; // THIS_LINE_PLATFORM next import { useMemo } from 'react'; import { SignIn, SignUp, StackServerApp } from ".."; -import { IframePreventer } from "../components/iframe-preventer"; import { MessageCard } from "../components/message-cards/message-card"; import { HandlerUrls, StackClientApp } from "../lib/stack-app"; import { AccountSettings } from "./account-settings"; @@ -249,9 +248,7 @@ async function NextStackHandler(props: BaseHandle {next15DeprecationWarning}. This warning will not be shown in production. )} - - {result} - + {result} ; } @@ -317,11 +314,7 @@ function ReactStackHandler(props: BaseHandlerProp return null; } - return ( - - {result} - - ); + return result; } // END_PLATFORM diff --git a/packages/template/src/components/oauth-button.tsx b/packages/template/src/components/oauth-button.tsx index 8743e73aa..52bde4147 100644 --- a/packages/template/src/components/oauth-button.tsx +++ b/packages/template/src/components/oauth-button.tsx @@ -1,10 +1,11 @@ 'use client'; -import { BrandIcons, Button } from '@stackframe/stack-ui'; +import { BrandIcons, Button, SimpleTooltip } from '@stackframe/stack-ui'; import Color from 'color'; import { useEffect, useId, useState } from 'react'; import { useStackApp } from '..'; import { useTranslation } from '../lib/translations'; +import { useInIframe } from './use-in-iframe'; const iconSize = 22; @@ -27,6 +28,7 @@ export function OAuthButton({ const { t } = useTranslation(); const stackApp = useStackApp(); const styleId = useId().replaceAll(':', '-'); + const isIframe = useInIframe(); const [lastUsed, setLastUsed] = useState(null); useEffect(() => { @@ -167,28 +169,35 @@ export function OAuthButton({ return ( <> - + } + +
+ + ); } diff --git a/packages/template/src/components/iframe-preventer.tsx b/packages/template/src/components/use-in-iframe.tsx similarity index 50% rename from packages/template/src/components/iframe-preventer.tsx rename to packages/template/src/components/use-in-iframe.tsx index 3704582e4..41129c3c6 100644 --- a/packages/template/src/components/iframe-preventer.tsx +++ b/packages/template/src/components/use-in-iframe.tsx @@ -1,9 +1,7 @@ 'use client'; import { useEffect, useState } from "react"; -export function IframePreventer({ children }: { - children: React.ReactNode, -}) { +export function useInIframe() { const [isIframe, setIsIframe] = useState(false); useEffect(() => { if (window.self !== window.top) { @@ -11,9 +9,5 @@ export function IframePreventer({ children }: { } }, []); - if (isIframe) { - return
Stack Auth components may not run in an {'<'}iframe{'>'}.
; - } - - return children; + return isIframe; }