Fixed sign in with an invite token when user is signed out

This commit is contained in:
giancarlo
2024-06-07 01:23:16 +07:00
parent 6ec939469b
commit 2e7e289495
7 changed files with 7639 additions and 9323 deletions

View File

@@ -10,6 +10,12 @@ import pathsConfig from '~/config/paths.config';
import { createI18nServerInstance } from '~/lib/i18n/i18n.server'; import { createI18nServerInstance } from '~/lib/i18n/i18n.server';
import { withI18n } from '~/lib/i18n/with-i18n'; import { withI18n } from '~/lib/i18n/with-i18n';
interface SignInPageProps {
searchParams: {
invite_token?: string;
};
}
export const generateMetadata = async () => { export const generateMetadata = async () => {
const i18n = await createI18nServerInstance(); const i18n = await createI18nServerInstance();
@@ -21,20 +27,31 @@ export const generateMetadata = async () => {
const paths = { const paths = {
callback: pathsConfig.auth.callback, callback: pathsConfig.auth.callback,
home: pathsConfig.app.home, home: pathsConfig.app.home,
joinTeam: pathsConfig.app.joinTeam,
}; };
function SignInPage() { function SignInPage({ searchParams }: SignInPageProps) {
const inviteToken = searchParams.invite_token;
const signUpPath =
pathsConfig.auth.signUp +
(inviteToken ? `?invite_token=${inviteToken}` : '');
return ( return (
<> <>
<Heading level={4}> <Heading level={4}>
<Trans i18nKey={'auth:signInHeading'} /> <Trans i18nKey={'auth:signInHeading'} />
</Heading> </Heading>
<SignInMethodsContainer paths={paths} providers={authConfig.providers} /> <SignInMethodsContainer
inviteToken={inviteToken}
paths={paths}
providers={authConfig.providers}
/>
<div className={'flex justify-center'}> <div className={'flex justify-center'}>
<Button asChild variant={'link'} size={'sm'}> <Button asChild variant={'link'} size={'sm'}>
<Link href={pathsConfig.auth.signUp}> <Link href={signUpPath}>
<Trans i18nKey={'auth:doNotHaveAccountYet'} /> <Trans i18nKey={'auth:doNotHaveAccountYet'} />
</Link> </Link>
</Button> </Button>

View File

@@ -32,6 +32,10 @@ const paths = {
function SignUpPage({ searchParams }: Props) { function SignUpPage({ searchParams }: Props) {
const inviteToken = searchParams.invite_token; const inviteToken = searchParams.invite_token;
const signInPath =
pathsConfig.auth.signIn +
(inviteToken ? `?invite_token=${inviteToken}` : '');
return ( return (
<> <>
<Heading level={4}> <Heading level={4}>
@@ -46,7 +50,7 @@ function SignUpPage({ searchParams }: Props) {
<div className={'justify-centers flex'}> <div className={'justify-centers flex'}>
<Button asChild variant={'link'} size={'sm'}> <Button asChild variant={'link'} size={'sm'}>
<Link href={pathsConfig.auth.signIn}> <Link href={signInPath}>
<Trans i18nKey={'auth:alreadyHaveAnAccount'} /> <Trans i18nKey={'auth:alreadyHaveAnAccount'} />
</Link> </Link>
</Button> </Button>

View File

@@ -42,7 +42,7 @@
"cross-env": "^7.0.3", "cross-env": "^7.0.3",
"pnpm": "^9.2.0", "pnpm": "^9.2.0",
"prettier": "^3.3.1", "prettier": "^3.3.1",
"turbo": "^2.0.1", "turbo": "2.0.2-canary.2",
"typescript": "^5.4.5", "typescript": "^5.4.5",
"yarn": "^1.22.22" "yarn": "^1.22.22"
}, },

View File

@@ -14,6 +14,7 @@ import { AuthProviderButton } from './auth-provider-button';
export function OauthProviders(props: { export function OauthProviders(props: {
inviteToken?: string; inviteToken?: string;
shouldCreateUser: boolean;
enabledProviders: Provider[]; enabledProviders: Provider[];
paths: { paths: {
@@ -85,6 +86,7 @@ export function OauthProviders(props: {
const credentials = { const credentials = {
provider, provider,
options: { options: {
shouldCreateUser: props.shouldCreateUser,
redirectTo, redirectTo,
...scopesOpts, ...scopesOpts,
}, },

View File

@@ -13,9 +13,12 @@ import { OauthProviders } from './oauth-providers';
import { PasswordSignInContainer } from './password-sign-in-container'; import { PasswordSignInContainer } from './password-sign-in-container';
export function SignInMethodsContainer(props: { export function SignInMethodsContainer(props: {
inviteToken?: string;
paths: { paths: {
callback: string; callback: string;
home: string; home: string;
joinTeam: string;
}; };
providers: { providers: {
@@ -32,7 +35,17 @@ export function SignInMethodsContainer(props: {
: ''; : '';
const onSignIn = () => { const onSignIn = () => {
router.replace(nextPath); if (props.inviteToken) {
const searchParams = new URLSearchParams({
invite_token: props.inviteToken,
});
const joinTeamPath = props.paths.joinTeam + '?' + searchParams.toString();
router.replace(joinTeamPath);
} else {
router.replace(nextPath);
}
}; };
return ( return (
@@ -42,7 +55,10 @@ export function SignInMethodsContainer(props: {
</If> </If>
<If condition={props.providers.magicLink}> <If condition={props.providers.magicLink}>
<MagicLinkAuthContainer redirectUrl={redirectUrl} /> <MagicLinkAuthContainer
inviteToken={props.inviteToken}
redirectUrl={redirectUrl}
/>
</If> </If>
<If condition={props.providers.oAuth.length}> <If condition={props.providers.oAuth.length}>
@@ -50,6 +66,8 @@ export function SignInMethodsContainer(props: {
<OauthProviders <OauthProviders
enabledProviders={props.providers.oAuth} enabledProviders={props.providers.oAuth}
inviteToken={props.inviteToken}
shouldCreateUser={false}
paths={{ paths={{
callback: props.paths.callback, callback: props.paths.callback,
returnPath: props.paths.home, returnPath: props.paths.home,

View File

@@ -51,6 +51,7 @@ export function SignUpMethodsContainer(props: {
<OauthProviders <OauthProviders
enabledProviders={props.providers.oAuth} enabledProviders={props.providers.oAuth}
inviteToken={props.inviteToken} inviteToken={props.inviteToken}
shouldCreateUser={true}
paths={{ paths={{
callback: props.paths.callback, callback: props.paths.callback,
returnPath: props.paths.appHome, returnPath: props.paths.appHome,

16906
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff