diff --git a/apps/builder/src/features/auth/components/SignInForm.tsx b/apps/builder/src/features/auth/components/SignInForm.tsx
index a922a730d..1e4e5e7c9 100644
--- a/apps/builder/src/features/auth/components/SignInForm.tsx
+++ b/apps/builder/src/features/auth/components/SignInForm.tsx
@@ -6,7 +6,10 @@ import {
HStack,
Text,
Spinner,
- Tooltip,
+ Alert,
+ Flex,
+ AlertIcon,
+ SlideFade,
} from '@chakra-ui/react'
import React, { ChangeEvent, FormEvent, useEffect } from 'react'
import { useState } from 'react'
@@ -78,11 +81,6 @@ export const SignInForm = ({
})
} else {
setIsMagicLinkSent(true)
- showToast({
- status: 'success',
- title: 'Success!',
- description: 'Check your inbox to sign in',
- })
}
setAuthLoading(false)
}
@@ -103,40 +101,54 @@ export const SignInForm = ({
)
return (
-
- {providers?.email && (
+ {!isMagicLinkSent && (
<>
- Or with your email
-
-
-
-
-
-
+
+ {providers?.email && (
+ <>
+ Or with your email
+
+
+
+
+ >
+ )}
>
)}
{router.query.error && (
)}
+
+
+
+
+
+
+
+ A magic link email was sent. 🪄
+
+ Make sure to check your SPAM folder.
+
+
+
+
+
)
}
diff --git a/apps/builder/src/pages/api/auth/[...nextauth].ts b/apps/builder/src/pages/api/auth/[...nextauth].ts
index 3fbad4675..a75b0d18e 100644
--- a/apps/builder/src/pages/api/auth/[...nextauth].ts
+++ b/apps/builder/src/pages/api/auth/[...nextauth].ts
@@ -13,6 +13,7 @@ import { User } from 'db'
import { env, getAtPath, isDefined, isNotEmpty } from 'utils'
import { mockedUser } from '@/features/auth'
import { getNewUserInvitations } from '@/features/auth/api'
+import { sendVerificationRequest } from './sendVerificationRequest'
const providers: Provider[] = []
@@ -42,6 +43,7 @@ if (isNotEmpty(env('SMTP_FROM')) && process.env.SMTP_AUTH_DISABLED !== 'true')
},
},
from: env('SMTP_FROM'),
+ sendVerificationRequest,
})
)
diff --git a/apps/builder/src/pages/api/auth/sendVerificationRequest.ts b/apps/builder/src/pages/api/auth/sendVerificationRequest.ts
new file mode 100644
index 000000000..50b04fb05
--- /dev/null
+++ b/apps/builder/src/pages/api/auth/sendVerificationRequest.ts
@@ -0,0 +1,16 @@
+import { EmailConfig } from 'next-auth/providers/email'
+import { sendMagicLinkEmail } from 'emails'
+
+type Props = {
+ identifier: string
+ url: string
+ provider: Partial>
+}
+
+export const sendVerificationRequest = async ({ identifier, url }: Props) => {
+ try {
+ await sendMagicLinkEmail({ url, to: identifier })
+ } catch (err) {
+ throw new Error(`Email(s) could not be sent`)
+ }
+}
diff --git a/packages/emails/src/components/Button.tsx b/packages/emails/src/components/Button.tsx
index cbf5e9beb..91a84e8a3 100644
--- a/packages/emails/src/components/Button.tsx
+++ b/packages/emails/src/components/Button.tsx
@@ -1,14 +1,14 @@
import React from 'react'
-import { MjmlButton } from '@faire/mjml-react'
+import { IMjmlButtonProps, MjmlButton } from '@faire/mjml-react'
import { blue, grayLight } from '../theme'
import { leadingTight, textBase, borderBase } from '../theme'
type ButtonProps = {
link: string
children: React.ReactNode
-}
+} & IMjmlButtonProps
-export const Button = ({ link, children }: ButtonProps) => (
+export const Button = ({ link, children, ...props }: ButtonProps) => (
(
backgroundColor={blue}
color={grayLight}
borderRadius={borderBase}
+ {...props}
>
{children}
diff --git a/packages/emails/src/emails/MagicLinkEmail.tsx b/packages/emails/src/emails/MagicLinkEmail.tsx
new file mode 100644
index 000000000..9c5ec7e59
--- /dev/null
+++ b/packages/emails/src/emails/MagicLinkEmail.tsx
@@ -0,0 +1,55 @@
+import React, { ComponentProps } from 'react'
+import {
+ Mjml,
+ MjmlBody,
+ MjmlSection,
+ MjmlColumn,
+ MjmlSpacer,
+} from '@faire/mjml-react'
+import { render } from '@faire/mjml-react/utils/render'
+import { HeroImage, Text, Button, Head } from '../components'
+import { SendMailOptions } from 'nodemailer'
+import { sendEmail } from '../sendEmail'
+
+type Props = {
+ url: string
+}
+
+export const MagicLinkEmail = ({ url }: Props) => (
+
+
+
+
+
+
+
+
+
+
+ Here is your magic link 👇
+
+
+
+ If you didn't request this, please ignore this email.
+
+
+ Best,
+
- Typebot Team.
+
+
+
+
+
+)
+
+export const sendMagicLinkEmail = ({
+ to,
+ ...props
+}: Pick & ComponentProps) =>
+ sendEmail({
+ to,
+ subject: 'Sign in to Typebot',
+ html: render().html,
+ })
diff --git a/packages/emails/src/emails/index.ts b/packages/emails/src/emails/index.ts
index 3400aba2b..b2a863cb8 100644
--- a/packages/emails/src/emails/index.ts
+++ b/packages/emails/src/emails/index.ts
@@ -5,3 +5,4 @@ export * from './GuestInvitationEmail'
export * from './ReachedChatsLimitEmail'
export * from './ReachedStorageLimitEmail'
export * from './WorkspaceMemberInvitationEmail'
+export * from './MagicLinkEmail'
diff --git a/packages/emails/src/preview.tsx b/packages/emails/src/preview.tsx
index 23bf19fbf..a09126107 100644
--- a/packages/emails/src/preview.tsx
+++ b/packages/emails/src/preview.tsx
@@ -10,6 +10,7 @@ import {
ReachedStorageLimitEmail,
WorkspaceMemberInvitation,
} from './emails'
+import { MagicLinkEmail } from './emails/MagicLinkEmail'
const createDistFolder = () => {
const dist = path.resolve(__dirname, 'dist')
@@ -91,6 +92,10 @@ const createHtmlFile = () => {
/>
).html
)
+ fs.writeFileSync(
+ path.resolve(__dirname, 'dist', 'magicLink.html'),
+ render().html
+ )
}
createDistFolder()