Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions packages/shared/src/features/onboarding/shared/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,5 @@ export function shouldRedirectAuth(): boolean {

return brokenWebviewPatterns.some((pattern) => pattern.test(ua));
}

export const AUTH_REDIRECT_KEY = 'auth_redirect';
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { ReactElement } from 'react';
import React, { useEffect, useMemo, useRef } from 'react';
import React, { useCallback, useEffect, useMemo, useRef } from 'react';
import { useRouter } from 'next/router';
import classNames from 'classnames';
import {
Expand Down Expand Up @@ -29,7 +29,11 @@ import { broadcastChannel } from '../../../lib/constants';
import Logo, { LogoPosition } from '../../../components/Logo';
import type { LoggedUser } from '../../../lib/user';
import { FunnelStepTransitionType } from '../types/funnel';
import { sanitizeMessage, shouldRedirectAuth } from '../shared';
import {
AUTH_REDIRECT_KEY,
sanitizeMessage,
shouldRedirectAuth,
} from '../shared';
import type { FunnelStepSignup } from '../types/funnel';
import { useConsentCookie } from '../../../hooks/useCookieConsent';
import { GdprConsentKey } from '../../../hooks/useCookieBanner';
Expand All @@ -50,15 +54,9 @@ const useRegistrationListeners = (
const { logEvent } = useLogContext();
const router = useRouter();

const onProviderMessage = async (e: MessageEvent) => {
const isEventSupported = supportedEvents.includes(e.data?.eventKey);

if (!isEventSupported) {
return undefined;
}

if (e.data?.flow) {
const connected = await getKratosFlow(AuthFlow.Registration, e.data.flow);
const handleExistingFlow = useCallback(
async (flow: string) => {
const connected = await getKratosFlow(AuthFlow.Registration, flow);

logEvent({
event_name: AuthEventNames.RegistrationError,
Expand All @@ -78,6 +76,19 @@ const useRegistrationListeners = (
}

return displayToast(`${labels.auth.error.generic} Code: ${code}`);
},
[displayToast, logEvent],
);

const onProviderMessage = async (e: MessageEvent) => {
const isEventSupported = supportedEvents.includes(e.data?.eventKey);

if (!isEventSupported) {
return undefined;
}

if (e.data?.flow) {
return handleExistingFlow(e.data.flow);
}

const bootResponse = await refetchBoot();
Expand All @@ -100,6 +111,23 @@ const useRegistrationListeners = (
useEventListener(broadcastChannel, 'message', onProviderMessage);

useEventListener(globalThis, 'message', onProviderMessage);

useEffect(() => {
if (!router?.isReady || !router?.query?.flow) {
return;
}

const flowFn = async () => {
await handleExistingFlow(router.query.flow as string);
const url = new URL(window.location.href);
const fullPath = url.origin + url.pathname;
const { flow, ...rest } = router.query;
const params = new URLSearchParams(rest as Record<string, string>);
router.replace(`${fullPath}?${params}`);
};

flowFn();
}, [handleExistingFlow, router]);
};

function InnerFunnelRegistration({
Expand All @@ -123,6 +151,7 @@ function InnerFunnelRegistration({
},
onRedirect: (redirect) => {
if (shouldRedirect) {
window.sessionStorage.setItem(AUTH_REDIRECT_KEY, window.location.href);
window.location.href = redirect;
} else {
windowPopup.current.location.href = redirect;
Expand All @@ -142,6 +171,14 @@ function InnerFunnelRegistration({

const sanitizedHeading = useMemo(() => sanitizeMessage(headline), [headline]);

useEffect(() => {
if (typeof window === 'undefined' || !shouldRedirect) {
return;
}

window.sessionStorage.removeItem(AUTH_REDIRECT_KEY);
Copy link
Copy Markdown
Contributor Author

@sshanzel sshanzel Apr 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to ensure the storage is clean until interaction starts.

}, [shouldRedirect]);

return (
<div className="relative flex w-full flex-1 flex-col items-center justify-center overflow-hidden">
<div className="absolute inset-0">
Expand Down
24 changes: 24 additions & 0 deletions packages/webapp/pages/callback.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ import { AuthEvent } from '@dailydotdev/shared/src/lib/kratos';
import type { ReactElement } from 'react';
import { useContext, useEffect } from 'react';
import LogContext from '@dailydotdev/shared/src/contexts/LogContext';
import {
AUTH_REDIRECT_KEY,
shouldRedirectAuth,
} from '@dailydotdev/shared/src/features/onboarding/shared';

const checkShouldSendBroadcast = () => {
const ua = navigator.userAgent;
Expand All @@ -17,6 +21,21 @@ const checkShouldSendBroadcast = () => {
return conditions.some(Boolean);
};

const handleRedirectAuth = (params: URLSearchParams) => {
const href = window.sessionStorage.getItem(AUTH_REDIRECT_KEY);

if (href) {
const [redirect, hrefParams] = href.split('?');
const redirectParams = new URLSearchParams(hrefParams);

Object.entries(redirectParams).forEach(([key, value]) =>
params.set(key, value),
);

window.location.replace(`${redirect}?${params}`);
}
};

function CallbackPage(): ReactElement {
const { logEvent } = useContext(LogContext);
useEffect(() => {
Expand All @@ -36,6 +55,11 @@ function CallbackPage(): ReactElement {
return;
}

if (shouldRedirectAuth()) {
handleRedirectAuth(urlSearchParams);
return;
}

if (checkShouldSendBroadcast()) {
broadcastMessage({ ...params, eventKey });
} else {
Expand Down