don't send a verification email during sign in if no match (#1999)

* don't send verification email on signin if there's no matching user, update email.js message

* conditional magic code message; signup/signin button

* unnecessary useCallback

* switch to cookie parsing lib

---------

Co-authored-by: Keyan <34140557+huumn@users.noreply.github.com>
This commit is contained in:
soxa 2025-03-20 21:32:31 +01:00 committed by GitHub
parent a669ec832b
commit dbbd9477fd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 23 additions and 8 deletions

View File

@ -223,7 +223,7 @@ async function nostrEventAuth (event) {
}
/** @type {import('next-auth/providers').Provider[]} */
const getProviders = res => [
const getProviders = (req, res) => [
CredentialsProvider({
id: 'lightning',
name: 'Lightning',
@ -275,14 +275,14 @@ const getProviders = res => [
from: process.env.LOGIN_EMAIL_FROM,
maxAge: 5 * 60, // expires in 5 minutes
generateVerificationToken: generateRandomString,
sendVerificationRequest
sendVerificationRequest: (...args) => sendVerificationRequest(...args, req)
})
]
/** @returns {import('next-auth').AuthOptions} */
export const getAuthOptions = (req, res) => ({
callbacks: getCallbacks(req, res),
providers: getProviders(res),
providers: getProviders(req, res),
adapter: {
...PrismaAdapter(prisma),
createUser: data => {
@ -421,7 +421,7 @@ async function sendVerificationRequest ({
url,
token,
provider
}) {
}, req) {
let user = await prisma.user.findUnique({
where: {
// Look for the user by hashed email
@ -443,6 +443,11 @@ async function sendVerificationRequest ({
const site = new URL(url).host
// if we're trying to sign in but no user was found, resolve the promise
if (req.cookies.signin && !user) {
return resolve()
}
nodemailer.createTransport(server).sendMail(
{
to: email,

View File

@ -1,4 +1,5 @@
import Image from 'react-bootstrap/Image'
import * as cookie from 'cookie'
import { StaticLayout } from '@/components/layout'
import { getGetServerSideProps } from '@/api/ssrApollo'
import { useRouter } from 'next/router'
@ -12,8 +13,10 @@ export const getServerSideProps = getGetServerSideProps({ query: null })
export default function Email () {
const router = useRouter()
const [callback, setCallback] = useState(null) // callback.email, callback.callbackUrl
const [signin, setSignin] = useState(false)
useEffect(() => {
setSignin(!!cookie.parse(document.cookie).signin)
setCallback(JSON.parse(window.sessionStorage.getItem('callback')))
}, [])
@ -27,6 +30,13 @@ export default function Email () {
router.push(url)
}, [callback, router])
const buildMessage = () => {
const email = callback?.email || 'your email address'
return signin
? `if there's a match, a magic code will be sent to ${email}`
: `a magic code has been sent to ${email}`
}
return (
<StaticLayout>
<div className='p-4 text-center'>
@ -35,14 +45,14 @@ export default function Email () {
<Image className='rounded-1 shadow-sm' width='640' height='302' src={`${process.env.NEXT_PUBLIC_ASSET_PREFIX}/cowboy-saloon.gif`} fluid />
</video>
<h2 className='pt-4'>Check your email</h2>
<h4 className='text-muted pt-2 pb-4'>a magic code has been sent to {callback ? callback.email : 'your email address'}</h4>
<MagicCodeForm onSubmit={(token) => pushCallback(token)} disabled={!callback} />
<h4 className='text-muted pt-2 pb-4'>{buildMessage()}</h4>
<MagicCodeForm onSubmit={(token) => pushCallback(token)} disabled={!callback} signin={signin} />
</div>
</StaticLayout>
)
}
export const MagicCodeForm = ({ onSubmit, disabled }) => {
export const MagicCodeForm = ({ onSubmit, disabled, signin }) => {
return (
<Form
initial={{
@ -64,7 +74,7 @@ export const MagicCodeForm = ({ onSubmit, disabled }) => {
hideError // hide error message on every input, allow custom error message
disabled={disabled} // disable the form if no callback is provided
/>
<SubmitButton variant='primary' className='px-4' disabled={disabled}>login</SubmitButton>
<SubmitButton variant='primary' className='px-4' disabled={disabled}>{signin ? 'login' : 'signup'}</SubmitButton>
</Form>
)
}