Prevent new account creation on login (#1976)
* Prevent account creation if we're not signin up * remove cookie once logged in, 24 hours expiry, comment * adjust error messages * check signin instead of signup * appendHeader to avoid overwrites, fix typo, use NodeNextRequest to handle cookies * expire cookie if signup
This commit is contained in:
parent
4f17615291
commit
71caa6d0fe
@ -1,7 +1,7 @@
|
||||
import { signIn } from 'next-auth/react'
|
||||
import styles from './login.module.css'
|
||||
import { Form, Input, SubmitButton } from '@/components/form'
|
||||
import { useState } from 'react'
|
||||
import { useState, useEffect } from 'react'
|
||||
import Alert from 'react-bootstrap/Alert'
|
||||
import { useRouter } from 'next/router'
|
||||
import { LightningAuthWithExplainer } from './lightning-auth'
|
||||
@ -42,10 +42,10 @@ const authErrorMessages = {
|
||||
OAuthCallback: 'Error handling OAuth response. Try again or choose a different method.',
|
||||
OAuthCreateAccount: 'Could not create OAuth account. Try again or choose a different method.',
|
||||
EmailCreateAccount: 'Could not create Email account. Try again or choose a different method.',
|
||||
Callback: 'Try again or choose a different method.',
|
||||
Callback: 'Could not authenticate. Try again or choose a different method.',
|
||||
OAuthAccountNotLinked: 'This auth method is linked to another account. To link to this account first unlink the other account.',
|
||||
EmailSignin: 'Failed to send email. Make sure you entered your email address correctly.',
|
||||
CredentialsSignin: 'Auth failed. Try again or choose a different method.',
|
||||
CredentialsSignin: 'Could not authenticate. Try again or choose a different method.',
|
||||
default: 'Auth failed. Try again or choose a different method.'
|
||||
}
|
||||
|
||||
@ -53,10 +53,23 @@ export function authErrorMessage (error) {
|
||||
return error && (authErrorMessages[error] ?? authErrorMessages.default)
|
||||
}
|
||||
|
||||
export default function Login ({ providers, callbackUrl, multiAuth, error, text, Header, Footer }) {
|
||||
export default function Login ({ providers, callbackUrl, multiAuth, error, text, Header, Footer, signin }) {
|
||||
const [errorMessage, setErrorMessage] = useState(authErrorMessage(error))
|
||||
const router = useRouter()
|
||||
|
||||
// signup/signin awareness cookie
|
||||
useEffect(() => {
|
||||
const cookieOptions = [
|
||||
`signin=${!!signin}`,
|
||||
'path=/',
|
||||
'max-age=' + (signin ? 60 * 60 * 24 : 0), // 24 hours if signin is true, expire the cookie otherwise
|
||||
'SameSite=Lax',
|
||||
process.env.NODE_ENV === 'production' ? 'Secure' : ''
|
||||
].filter(Boolean).join(';')
|
||||
|
||||
document.cookie = cookieOptions
|
||||
}, [signin])
|
||||
|
||||
if (router.query.type === 'lightning') {
|
||||
return <LightningAuthWithExplainer callbackUrl={callbackUrl} text={text} multiAuth={multiAuth} />
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ import { hashEmail } from '@/lib/crypto'
|
||||
import * as cookie from 'cookie'
|
||||
import { multiAuthMiddleware } from '@/pages/api/graphql'
|
||||
import { BECH32_CHARSET } from '@/lib/constants'
|
||||
import { NodeNextRequest } from 'next/dist/server/base-http/node'
|
||||
|
||||
/**
|
||||
* Stores userIds in user table
|
||||
@ -94,6 +95,8 @@ function getCallbacks (req, res) {
|
||||
*/
|
||||
async jwt ({ token, user, account, profile, isNewUser }) {
|
||||
if (user) {
|
||||
// reset signup cookie if any
|
||||
res.appendHeader('Set-Cookie', cookie.serialize('signin', '', { path: '/', expires: 0, maxAge: 0 }))
|
||||
// token won't have an id on it for new logins, we add it
|
||||
// note: token is what's kept in the jwt
|
||||
token.id = Number(user.id)
|
||||
@ -205,7 +208,8 @@ async function pubkeyAuth (credentials, req, res, pubkeyColumnName) {
|
||||
if (token?.id && !multiAuth) {
|
||||
user = await prisma.user.update({ where: { id: token.id }, data: { [pubkeyColumnName]: pubkey } })
|
||||
} else {
|
||||
// we're not logged in: create new user with that pubkey
|
||||
// create a new user only if we're trying to sign up
|
||||
if (new NodeNextRequest(req).cookies.signin) return null
|
||||
user = await prisma.user.create({ data: { name: pubkey.slice(0, 10), [pubkeyColumnName]: pubkey } })
|
||||
}
|
||||
}
|
||||
@ -314,6 +318,7 @@ export const getAuthOptions = (req, res) => ({
|
||||
adapter: {
|
||||
...PrismaAdapter(prisma),
|
||||
createUser: data => {
|
||||
if (req.cookies.signin) return null
|
||||
// replace email with email hash in new user payload
|
||||
if (data.email) {
|
||||
const { email } = data
|
||||
|
@ -81,6 +81,7 @@ export default function LoginPage (props) {
|
||||
<Login
|
||||
Footer={() => <LoginFooter callbackUrl={props.callbackUrl} />}
|
||||
Header={() => <LoginHeader />}
|
||||
signin
|
||||
{...props}
|
||||
/>
|
||||
</StaticLayout>
|
||||
|
Loading…
x
Reference in New Issue
Block a user