Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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