2.18.0: New Invitation flow, refactored Database Webhooks, new ShadCN UI Components (#384)

* Streamlined invitations flow
* Removed web hooks in favor of handling logic directly in server actions
* Added new Shadcn UI Components
This commit is contained in:
Giancarlo Buomprisco
2025-10-05 17:54:16 +08:00
committed by GitHub
parent 195cf41680
commit 2e20d3e76f
60 changed files with 3760 additions and 1009 deletions

View File

@@ -65,7 +65,13 @@ async function DocumentationPage({ params }: DocumentationPageProps) {
<section
className={'flex flex-col gap-y-1 border-b border-dashed pb-4'}
>
<h1 className={'text-foreground text-3xl'}>{page.title}</h1>
<h1
className={
'text-foreground text-3xl font-semibold tracking-tighter'
}
>
{page.title}
</h1>
<h2 className={'text-secondary-foreground/80 text-lg'}>
{description}

View File

@@ -26,11 +26,7 @@ export const generateMetadata = async () => {
};
async function SignInPage({ searchParams }: SignInPageProps) {
const { invite_token: inviteToken, next } = await searchParams;
const signUpPath =
pathsConfig.auth.signUp +
(inviteToken ? `?invite_token=${inviteToken}` : '');
const { next } = await searchParams;
const paths = {
callback: pathsConfig.auth.callback,
@@ -50,15 +46,11 @@ async function SignInPage({ searchParams }: SignInPageProps) {
</p>
</div>
<SignInMethodsContainer
inviteToken={inviteToken}
paths={paths}
providers={authConfig.providers}
/>
<SignInMethodsContainer paths={paths} providers={authConfig.providers} />
<div className={'flex justify-center'}>
<Button asChild variant={'link'} size={'sm'}>
<Link href={signUpPath} prefetch={true}>
<Link href={pathsConfig.auth.signUp} prefetch={true}>
<Trans i18nKey={'auth:doNotHaveAccountYet'} />
</Link>
</Button>

View File

@@ -18,24 +18,12 @@ export const generateMetadata = async () => {
};
};
interface Props {
searchParams: Promise<{
invite_token?: string;
}>;
}
const paths = {
callback: pathsConfig.auth.callback,
appHome: pathsConfig.app.home,
};
async function SignUpPage({ searchParams }: Props) {
const inviteToken = (await searchParams).invite_token;
const signInPath =
pathsConfig.auth.signIn +
(inviteToken ? `?invite_token=${inviteToken}` : '');
async function SignUpPage() {
return (
<>
<div className={'flex flex-col items-center gap-1'}>
@@ -51,13 +39,12 @@ async function SignUpPage({ searchParams }: Props) {
<SignUpMethodsContainer
providers={authConfig.providers}
displayTermsCheckbox={authConfig.displayTermsCheckbox}
inviteToken={inviteToken}
paths={paths}
/>
<div className={'flex justify-center'}>
<Button asChild variant={'link'} size={'sm'}>
<Link href={signInPath} prefetch={true}>
<Link href={pathsConfig.auth.signIn} prefetch={true}>
<Trans i18nKey={'auth:alreadyHaveAnAccount'} />
</Link>
</Button>

View File

@@ -56,12 +56,12 @@ async function JoinTeamAccountPage(props: JoinTeamAccountPageProps) {
const verifyMfaUrl = `${pathsConfig.auth.verifyMfa}?${urlParams.toString()}`;
// if the user needs to verify MFA, redirect them to the MFA verification page
// if the user needs to verify MFA
// redirect them to the MFA verification page
redirect(verifyMfaUrl);
} else {
const urlParams = new URLSearchParams({
invite_token: token,
email: searchParams.email ?? '',
});
const nextUrl = `${pathsConfig.auth.signUp}?${urlParams.toString()}`;
@@ -78,8 +78,10 @@ async function JoinTeamAccountPage(props: JoinTeamAccountPageProps) {
// the user is logged in, we can now check if the token is valid
const invitation = await api.getInvitation(adminClient, token);
// the invitation is not found or expired
if (!invitation) {
// the invitation is not found or expired or the email is not the same as the user's email
const isInvitationValid = invitation?.email === auth.data.email;
if (!isInvitationValid) {
return (
<AuthLayoutShell Logo={AppLogo}>
<InviteNotFoundOrExpired />