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:
committed by
GitHub
parent
195cf41680
commit
2e20d3e76f
@@ -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}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 />
|
||||
|
||||
@@ -135,5 +135,6 @@
|
||||
"accountUnlinked": "Account successfully unlinked",
|
||||
"linkEmailPassword": "Email & Password",
|
||||
"linkEmailPasswordDescription": "Add an email and password to your account for additional sign-in options",
|
||||
"noAccountsAvailable": "No additional accounts available to link"
|
||||
"noAccountsAvailable": "No additional accounts available to link",
|
||||
"linkAccountDescription": "Link account to sign in with {{provider}}"
|
||||
}
|
||||
|
||||
@@ -5,19 +5,6 @@
|
||||
-- In production, you should manually create webhooks in the Supabase dashboard (or create a migration to do so).
|
||||
-- We don't do it because you'll need to manually add your webhook URL and secret key.
|
||||
|
||||
-- this webhook will be triggered after deleting an account
|
||||
create trigger "accounts_teardown"
|
||||
after delete
|
||||
on "public"."accounts"
|
||||
for each row
|
||||
execute function "supabase_functions"."http_request"(
|
||||
'http://host.docker.internal:3000/api/db/webhook',
|
||||
'POST',
|
||||
'{"Content-Type":"application/json", "X-Supabase-Event-Signature":"WEBHOOKSECRET"}',
|
||||
'{}',
|
||||
'5000'
|
||||
);
|
||||
|
||||
-- this webhook will be triggered after a delete on the subscriptions table
|
||||
-- which should happen when a user deletes their account (and all their subscriptions)
|
||||
create trigger "subscriptions_delete"
|
||||
@@ -32,21 +19,6 @@ execute function "supabase_functions"."http_request"(
|
||||
'5000'
|
||||
);
|
||||
|
||||
-- this webhook will be triggered after every insert on the invitations table
|
||||
-- which should happen when a user invites someone to their account
|
||||
create trigger "invitations_insert"
|
||||
after insert
|
||||
on "public"."invitations"
|
||||
for each row
|
||||
execute function "supabase_functions"."http_request"(
|
||||
'http://host.docker.internal:3000/api/db/webhook',
|
||||
'POST',
|
||||
'{"Content-Type":"application/json", "X-Supabase-Event-Signature":"WEBHOOKSECRET"}',
|
||||
'{}',
|
||||
'5000'
|
||||
);
|
||||
|
||||
|
||||
-- DATA SEED
|
||||
-- This is a data dump for testing purposes. It should be used to seed the database with data for testing.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user