* chore: update project dependencies and documentation for Next.js 16 - Upgraded Next.js from version 15 to 16 across various documentation files and components. - Updated references to Next.js 16 in AGENTS.md and CLAUDE.md for consistency. - Incremented application version to 2.21.0 in package.json. - Refactored identity setup components to improve user experience and added confirmation dialogs for authentication methods. - Enhanced invitation flow with new logic for handling user redirection and token generation. * refactor: streamline invitation flow in e2e tests - Simplified the invitation flow test by using a predefined email instead of generating a random one. - Removed unnecessary steps such as clearing cookies and reloading the page before user sign-up. - Enhanced clarity by eliminating commented-out code related to identity verification and user membership checks. * refactor: improve code readability in IdentitiesPage and UpdatePasswordForm components - Enhanced formatting of JSX elements in IdentitiesPage and UpdatePasswordForm for better readability. - Adjusted indentation and line breaks to maintain consistent coding style across components. * refactor: enhance LinkAccountsList component with user redirection logic - Updated the LinkAccountsList component to include a redirectToPath option in the useLinkIdentityWithProvider hook for improved user experience. - Removed redundant user hook declaration to streamline the code structure. * refactor: update account setup logic in JoinTeamAccountPage - Introduced a check for email-only authentication support to streamline account setup requirements. - Adjusted the conditions for determining if a new account should set up additional authentication methods, enhancing user experience for new users.
126 lines
3.6 KiB
TypeScript
126 lines
3.6 KiB
TypeScript
import { Metadata } from 'next';
|
|
|
|
import { redirect } from 'next/navigation';
|
|
|
|
import { AuthLayoutShell } from '@kit/auth/shared';
|
|
import { requireUser } from '@kit/supabase/require-user';
|
|
import { getSupabaseServerClient } from '@kit/supabase/server-client';
|
|
import { Heading } from '@kit/ui/heading';
|
|
import { Trans } from '@kit/ui/trans';
|
|
|
|
import { AppLogo } from '~/components/app-logo';
|
|
import authConfig from '~/config/auth.config';
|
|
import pathsConfig from '~/config/paths.config';
|
|
import { createI18nServerInstance } from '~/lib/i18n/i18n.server';
|
|
import { withI18n } from '~/lib/i18n/with-i18n';
|
|
|
|
import { IdentitiesStepWrapper } from './_components/identities-step-wrapper';
|
|
|
|
export const meta = async (): Promise<Metadata> => {
|
|
const i18n = await createI18nServerInstance();
|
|
|
|
return {
|
|
title: i18n.t('auth:setupAccount'),
|
|
};
|
|
};
|
|
|
|
type IdentitiesPageProps = {
|
|
searchParams: Promise<{ next?: string }>;
|
|
};
|
|
|
|
/**
|
|
* @name IdentitiesPage
|
|
* @description Displays linked accounts and available authentication methods.
|
|
*/
|
|
async function IdentitiesPage(props: IdentitiesPageProps) {
|
|
const {
|
|
nextPath,
|
|
showPasswordOption,
|
|
showEmailOption,
|
|
oAuthProviders,
|
|
enableIdentityLinking,
|
|
requiresConfirmation,
|
|
} = await fetchData(props);
|
|
|
|
return (
|
|
<AuthLayoutShell
|
|
Logo={AppLogo}
|
|
contentClassName="max-w-md overflow-y-hidden"
|
|
>
|
|
<div
|
|
className={
|
|
'flex max-h-[70vh] w-full flex-col items-center space-y-6 overflow-y-auto'
|
|
}
|
|
>
|
|
<div className={'flex flex-col items-center gap-1'}>
|
|
<Heading
|
|
level={4}
|
|
className="text-center"
|
|
data-test="identities-page-heading"
|
|
>
|
|
<Trans i18nKey={'auth:linkAccountToSignIn'} />
|
|
</Heading>
|
|
|
|
<Heading
|
|
level={6}
|
|
className={'text-muted-foreground text-center text-sm'}
|
|
data-test="identities-page-description"
|
|
>
|
|
<Trans i18nKey={'auth:linkAccountToSignInDescription'} />
|
|
</Heading>
|
|
</div>
|
|
|
|
<IdentitiesStepWrapper
|
|
nextPath={nextPath}
|
|
showPasswordOption={showPasswordOption}
|
|
showEmailOption={showEmailOption}
|
|
oAuthProviders={oAuthProviders}
|
|
enableIdentityLinking={enableIdentityLinking}
|
|
requiresConfirmation={requiresConfirmation}
|
|
/>
|
|
</div>
|
|
</AuthLayoutShell>
|
|
);
|
|
}
|
|
|
|
export default withI18n(IdentitiesPage);
|
|
|
|
async function fetchData(props: IdentitiesPageProps) {
|
|
const searchParams = await props.searchParams;
|
|
const client = getSupabaseServerClient();
|
|
const auth = await requireUser(client);
|
|
|
|
// If not authenticated, redirect to sign in
|
|
if (!auth.data) {
|
|
throw redirect(pathsConfig.auth.signIn);
|
|
}
|
|
|
|
// Get the next path from URL params (where to redirect after setup)
|
|
const nextPath = searchParams.next || pathsConfig.app.home;
|
|
|
|
// Available auth methods to add
|
|
const showPasswordOption = authConfig.providers.password;
|
|
|
|
// Show email option if password, magic link, or OTP is enabled
|
|
const showEmailOption =
|
|
authConfig.providers.password ||
|
|
authConfig.providers.magicLink ||
|
|
authConfig.providers.otp;
|
|
|
|
const oAuthProviders = authConfig.providers.oAuth;
|
|
const enableIdentityLinking = authConfig.enableIdentityLinking;
|
|
|
|
// Only require confirmation if password or oauth providers are enabled
|
|
const requiresConfirmation =
|
|
authConfig.providers.password || oAuthProviders.length > 0;
|
|
|
|
return {
|
|
nextPath,
|
|
showPasswordOption,
|
|
showEmailOption,
|
|
oAuthProviders,
|
|
enableIdentityLinking,
|
|
requiresConfirmation,
|
|
};
|
|
}
|