File tree Expand file tree Collapse file tree
src/frontend/src/features/auth Expand file tree Collapse file tree Original file line number Diff line number Diff line change 11import { fetchApi } from '@/api/fetchApi'
22import { setAccessToken } from '@/stores/accessToken'
3- import { consumeTransitCodeFromFragment } from '../utils/transitCode'
3+ import {
4+ consumeTransitCodeFromFragment ,
5+ isEmbedded ,
6+ } from '../utils/transitCode'
47
58type ApiAccessToken = {
69 access_token : string
@@ -28,6 +31,11 @@ const runInitialization = async (): Promise<void> => {
2831 return
2932 }
3033
34+ if ( ! isEmbedded ( ) ) {
35+ console . warn ( 'Transit code ignored outside an embedded context' )
36+ return
37+ }
38+
3139 try {
3240 const { access_token } = await exchangeAccessToken ( code )
3341 setAccessToken ( access_token )
Original file line number Diff line number Diff line change @@ -23,9 +23,13 @@ export const TransitCodeGate = ({
2323} ) => {
2424 const hash = useHash ( )
2525
26- // Latch the decision on the initial hash: the bootstrap scrubs the
27- // fragment as soon as it starts, and the gate must not flip back to the
28- // fast path while the exchange is still in flight.
26+ // Note: the exchange only happens in an embedding context. This check lives
27+ // in initializeAccessTokenFromFragment, the single funnel for all bootstrap paths.
28+ // The gate still mounts top-level to scrub the fragment, but bootstrap then resolves
29+ // immediately without exchanging.
30+ //
31+ // Latch the decision on the initial hash: bootstrap scrubs it immediately, and the
32+ // gate must not switch back to the fast path while the exchange is in flight.
2933 const [ needsExchange ] = useState ( ( ) => hasTransitCodeInFragment ( hash ) )
3034
3135 if ( ! needsExchange ) {
Original file line number Diff line number Diff line change 11const TRANSIT_CODE_FRAGMENT_PARAM = 'transit_code'
22
3+ /**
4+ * Whether the app is rendered inside an embedding context (iframe).
5+ *
6+ * Comparing window references never throws, even when the parent is
7+ * cross-origin. Defaults to false outside a browser environment.
8+ */
9+ export const isEmbedded = ( ) : boolean => {
10+ if ( typeof window === 'undefined' ) {
11+ return false
12+ }
13+ return window . self !== window . top
14+ }
15+
316/**
417 * Whether a URL fragment carries a transit code. Pure check, does not
518 * consume anything.
You can’t perform that action at this time.
0 commit comments