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
@@ -28,13 +28,11 @@ import { useLastAuthMethod } from '../hooks/use-last-auth-method';
|
||||
import { TermsAndConditionsFormField } from './terms-and-conditions-form-field';
|
||||
|
||||
export function MagicLinkAuthContainer({
|
||||
inviteToken,
|
||||
redirectUrl,
|
||||
shouldCreateUser,
|
||||
defaultValues,
|
||||
displayTermsCheckbox,
|
||||
}: {
|
||||
inviteToken?: string;
|
||||
redirectUrl: string;
|
||||
shouldCreateUser: boolean;
|
||||
displayTermsCheckbox?: boolean;
|
||||
@@ -63,10 +61,6 @@ export function MagicLinkAuthContainer({
|
||||
const onSubmit = ({ email }: { email: string }) => {
|
||||
const url = new URL(redirectUrl);
|
||||
|
||||
if (inviteToken) {
|
||||
url.searchParams.set('invite_token', inviteToken);
|
||||
}
|
||||
|
||||
const emailRedirectTo = url.href;
|
||||
|
||||
const promise = async () => {
|
||||
|
||||
@@ -32,7 +32,6 @@ const OAUTH_SCOPES: Partial<Record<Provider, string>> = {
|
||||
};
|
||||
|
||||
export const OauthProviders: React.FC<{
|
||||
inviteToken?: string;
|
||||
shouldCreateUser: boolean;
|
||||
enabledProviders: Provider[];
|
||||
queryParams?: Record<string, string>;
|
||||
@@ -86,10 +85,6 @@ export const OauthProviders: React.FC<{
|
||||
queryParams.set('next', props.paths.returnPath);
|
||||
}
|
||||
|
||||
if (props.inviteToken) {
|
||||
queryParams.set('invite_token', props.inviteToken);
|
||||
}
|
||||
|
||||
const redirectPath = [
|
||||
props.paths.callback,
|
||||
queryParams.toString(),
|
||||
|
||||
@@ -36,7 +36,6 @@ const OtpSchema = z.object({ token: z.string().min(6).max(6) });
|
||||
|
||||
type OtpSignInContainerProps = {
|
||||
shouldCreateUser: boolean;
|
||||
inviteToken?: string;
|
||||
};
|
||||
|
||||
export function OtpSignInContainer(props: OtpSignInContainerProps) {
|
||||
@@ -80,19 +79,9 @@ export function OtpSignInContainer(props: OtpSignInContainerProps) {
|
||||
recordAuthMethod('otp', { email });
|
||||
|
||||
// on sign ups we redirect to the app home
|
||||
const inviteToken = props.inviteToken;
|
||||
const next = params.get('next') ?? '/home';
|
||||
|
||||
if (inviteToken) {
|
||||
const params = new URLSearchParams({
|
||||
invite_token: inviteToken,
|
||||
next,
|
||||
});
|
||||
|
||||
router.replace(`/join?${params.toString()}`);
|
||||
} else {
|
||||
router.replace(next);
|
||||
}
|
||||
router.replace(next);
|
||||
};
|
||||
|
||||
if (isEmailStep) {
|
||||
|
||||
@@ -18,8 +18,6 @@ import { OtpSignInContainer } from './otp-sign-in-container';
|
||||
import { PasswordSignInContainer } from './password-sign-in-container';
|
||||
|
||||
export function SignInMethodsContainer(props: {
|
||||
inviteToken?: string;
|
||||
|
||||
paths: {
|
||||
callback: string;
|
||||
joinTeam: string;
|
||||
@@ -40,22 +38,10 @@ export function SignInMethodsContainer(props: {
|
||||
: '';
|
||||
|
||||
const onSignIn = useCallback(() => {
|
||||
// if the user has an invite token, we should join the team
|
||||
if (props.inviteToken) {
|
||||
const searchParams = new URLSearchParams({
|
||||
invite_token: props.inviteToken,
|
||||
});
|
||||
const returnPath = props.paths.returnPath || '/home';
|
||||
|
||||
const joinTeamPath = props.paths.joinTeam + '?' + searchParams.toString();
|
||||
|
||||
router.replace(joinTeamPath);
|
||||
} else {
|
||||
const returnPath = props.paths.returnPath || '/home';
|
||||
|
||||
// otherwise, we should redirect to the return path
|
||||
router.replace(returnPath);
|
||||
}
|
||||
}, [props.inviteToken, props.paths.joinTeam, props.paths.returnPath, router]);
|
||||
router.replace(returnPath);
|
||||
}, [props.paths.returnPath, router]);
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -67,17 +53,13 @@ export function SignInMethodsContainer(props: {
|
||||
|
||||
<If condition={props.providers.magicLink}>
|
||||
<MagicLinkAuthContainer
|
||||
inviteToken={props.inviteToken}
|
||||
redirectUrl={redirectUrl}
|
||||
shouldCreateUser={false}
|
||||
/>
|
||||
</If>
|
||||
|
||||
<If condition={props.providers.otp}>
|
||||
<OtpSignInContainer
|
||||
inviteToken={props.inviteToken}
|
||||
shouldCreateUser={false}
|
||||
/>
|
||||
<OtpSignInContainer shouldCreateUser={false} />
|
||||
</If>
|
||||
|
||||
<If condition={props.providers.oAuth.length}>
|
||||
@@ -95,7 +77,6 @@ export function SignInMethodsContainer(props: {
|
||||
|
||||
<OauthProviders
|
||||
enabledProviders={props.providers.oAuth}
|
||||
inviteToken={props.inviteToken}
|
||||
shouldCreateUser={false}
|
||||
paths={{
|
||||
callback: props.paths.callback,
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
import type { Provider } from '@supabase/supabase-js';
|
||||
|
||||
import { isBrowser } from '@kit/shared/utils';
|
||||
import { Alert, AlertDescription, AlertTitle } from '@kit/ui/alert';
|
||||
import { If } from '@kit/ui/if';
|
||||
import { Separator } from '@kit/ui/separator';
|
||||
import { Trans } from '@kit/ui/trans';
|
||||
@@ -28,7 +27,6 @@ export function SignUpMethodsContainer(props: {
|
||||
};
|
||||
|
||||
displayTermsCheckbox?: boolean;
|
||||
inviteToken?: string;
|
||||
}) {
|
||||
const redirectUrl = getCallbackUrl(props);
|
||||
const defaultValues = getDefaultValues();
|
||||
@@ -38,10 +36,6 @@ export function SignUpMethodsContainer(props: {
|
||||
{/* Show hint if user might already have an account */}
|
||||
<ExistingAccountHint />
|
||||
|
||||
<If condition={props.inviteToken}>
|
||||
<InviteAlert />
|
||||
</If>
|
||||
|
||||
<If condition={props.providers.password}>
|
||||
<EmailPasswordSignUpContainer
|
||||
emailRedirectTo={redirectUrl}
|
||||
@@ -51,15 +45,11 @@ export function SignUpMethodsContainer(props: {
|
||||
</If>
|
||||
|
||||
<If condition={props.providers.otp}>
|
||||
<OtpSignInContainer
|
||||
inviteToken={props.inviteToken}
|
||||
shouldCreateUser={true}
|
||||
/>
|
||||
<OtpSignInContainer shouldCreateUser={true} />
|
||||
</If>
|
||||
|
||||
<If condition={props.providers.magicLink}>
|
||||
<MagicLinkAuthContainer
|
||||
inviteToken={props.inviteToken}
|
||||
redirectUrl={redirectUrl}
|
||||
shouldCreateUser={true}
|
||||
defaultValues={defaultValues}
|
||||
@@ -82,7 +72,6 @@ export function SignUpMethodsContainer(props: {
|
||||
|
||||
<OauthProviders
|
||||
enabledProviders={props.providers.oAuth}
|
||||
inviteToken={props.inviteToken}
|
||||
shouldCreateUser={true}
|
||||
paths={{
|
||||
callback: props.paths.callback,
|
||||
@@ -99,8 +88,6 @@ function getCallbackUrl(props: {
|
||||
callback: string;
|
||||
appHome: string;
|
||||
};
|
||||
|
||||
inviteToken?: string;
|
||||
}) {
|
||||
if (!isBrowser()) {
|
||||
return '';
|
||||
@@ -110,10 +97,6 @@ function getCallbackUrl(props: {
|
||||
const origin = window.location.origin;
|
||||
const url = new URL(redirectPath, origin);
|
||||
|
||||
if (props.inviteToken) {
|
||||
url.searchParams.set('invite_token', props.inviteToken);
|
||||
}
|
||||
|
||||
const searchParams = new URLSearchParams(window.location.search);
|
||||
const next = searchParams.get('next');
|
||||
|
||||
@@ -130,27 +113,8 @@ function getDefaultValues() {
|
||||
}
|
||||
|
||||
const searchParams = new URLSearchParams(window.location.search);
|
||||
const inviteToken = searchParams.get('invite_token');
|
||||
|
||||
if (!inviteToken) {
|
||||
return { email: '' };
|
||||
}
|
||||
|
||||
return {
|
||||
email: searchParams.get('email') ?? '',
|
||||
};
|
||||
}
|
||||
|
||||
function InviteAlert() {
|
||||
return (
|
||||
<Alert variant={'info'}>
|
||||
<AlertTitle>
|
||||
<Trans i18nKey={'auth:inviteAlertHeading'} />
|
||||
</AlertTitle>
|
||||
|
||||
<AlertDescription>
|
||||
<Trans i18nKey={'auth:inviteAlertBody'} />
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user