Next.js Discord

Discord Forum

Prisma

Unanswered
Southeastern blueberry bee posted this in #help-forum
Open in Discord
Southeastern blueberry beeOP
How can I connect my next.js project to a prisma database

411 Replies

Southeastern blueberry beeOP
i dont want to get information, setinformation in the datbase with an api as that can be seen in the network tab on the "use client"
Can i go straight from
client -> database without there being any security concerns?
i know abt server -> database
but what abyt client
you should do client -> nextjs -> database
Southeastern blueberry beeOP
Yreds
how can I do that?
wait
could i do
"use client"
...
async function getInfo() {
  "use server"

  get info?
}
?
yeah using server action in client component is good
but you have to create the action in a seperate file with 'use server' on top
Southeastern blueberry beeOP
yh
then import the action in the client component file
Southeastern blueberry beeOP
i have done
/api/getinfo/route.ts
before
where it gets the data
however
what do you mean?
Southeastern blueberry beeOP
so
in the page.tsx file
it does
await axios.get('/api/getinfo/`)
thats an api as the network tab shows the request and hackers casn abuse that and add or get info from my db
that's why your site should be run on https
Southeastern blueberry beeOP
it is
then it should be fine?
Southeastern blueberry beeOP
why?
why would that change if it were http?
https encrypt the traffic
Southeastern blueberry beeOP
so
does that mean
they cant see the network?
they can
they can see the encrpted data
Southeastern blueberry beeOP
what does it encrypt?
Southeastern blueberry beeOP
`right
i see that
so say i have /api/add/route.ts
which adds a number to my database
yes it is totally fine
Southeastern blueberry beeOP
and the number added is the number in the body number
so
body: {
  number: 1
}
@Ray Click to see attachment
it will become something like this in the network
if your site is running on https
Southeastern blueberry beeOP
but why can i read this then?
and even the headres
@Southeastern blueberry bee Click to see attachment
yes because the browser is the one who send the request
Southeastern blueberry beeOP
the client?
client mean browser?
Southeastern blueberry beeOP
by browser do you mean the client?
you can try login in other site
you can see that payload too
Southeastern blueberry beeOP
yes
im making a registration thing
so the database has to check if the username is already taken
so i want to get in the db and see if the username is available
what is the issue you have?
Southeastern blueberry beeOP
ok
right
one second
ikll send the code i have
ok
Southeastern blueberry beeOP
thats my
app/register/page.tsx
when
register()
is run how do i check in my prisma db if the username is taken
you should have a route handler for registration?
you can check if the username exist in the data. return an error if it does
Southeastern blueberry beeOP
right
but
route handler or server action
Southeastern blueberry beeOP
for when im adding the verificationCode to the database
how do i do that?
it should only send after the user begin added to database
Southeastern blueberry beeOP
i know
but how?
because
i cant add to the database via
axios.post('/api/addVerificationCode', {
   'code': 1,
   'email': '...'
})
because a hacker can see that in the network tab and spam it and full my db with codes
you don't need separate endpoint for that
Southeastern blueberry beeOP
so how do i add to the database
so no one can spam it lol
Southeastern blueberry beeOP
yes
thats what ive been trying to get out of this whole chat
how do i add to db without an endpoint
and straight from file
hold on
Southeastern blueberry beeOP
👍
@Southeastern blueberry bee 👍
// action.ts

"use server";

export async function registration({
  username,
  password,
}: {
  username: string;
  password: string;
}) {
  const exist = await prisma.user.findUnique({ where: { username } });
  if (exist) {
    return {
      error: "Username already exists",
    };
  }

  try {
    const passwordHash = hash(password);
    const user = await prisma.user.create({
      data: { username, password: passwordHash },
    });

    await setVerificationCode(user);
  } catch (error) {
    console.log(error);
    return {
      error: "unexpected error",
    };
  }
}
Southeastern blueberry beeOP
where would action.ts be?
its up to you
Southeastern blueberry beeOP
but
anywhere but not in server component or client component
Southeastern blueberry beeOP
how would i access that
froim my app/register/page.tsx
@Southeastern blueberry bee Click to see attachment
Southeastern blueberry beeOP
^
import it
import { registration} from 'action.ts'
Southeastern blueberry beeOP
right
so
can i do
app/database/registration.ts
sure
Eastern Carpenter bee
test
Southeastern blueberry beeOP
or
app/database/addVerificationCode.ts
hm ok
like this?
"use server";

import { PrismaClient } from "@prisma/client";

const prisma = new PrismaClient

export async function registration({
  username,
  password,
}: {
  username: string;
  password: string;
}) {
  const exist = await prisma.user.findUnique({ where: { username } });
  if (exist) {
    return {
      error: "Username already exists",
    };
  }

  try {
    const passwordHash = hash(password);
    const user = await prisma.user.create({
      data: { username, password: passwordHash },
    });

    await setVerificationCode(user);
  } catch (error) {
    console.log(error);
    return {
      error: "unexpected error",
    };
  }
}
yes you always import your hash function
i dont know what you use
Southeastern blueberry beeOP
ok
one second
like this? @Ray
"use server";

import { PrismaClient } from "@prisma/client";

const prisma = new PrismaClient()

export async function addVerificationCode({
  code,
  email,
}: {
  code: string;
  email: string;
}) {

  try {

    const user = await prisma.registrationCodes.create({
      data: { code: code, email: email }
    });

  } catch (error) {

    console.log(error);
    return {
      error: "unexpected error",
    };

  }
}
yes
Southeastern blueberry beeOP
so thats adding
registration and addVerificationCode both are server action which can be defined in same file but its up to you
Southeastern blueberry beeOP
so in my app/register/page.tsx i do
import { addVerificationCode } from '../database/addVerificationCode'

addVerificationCode('the code', 'the email')
yes
Southeastern blueberry beeOP
Right
so thats adding
now getting
i can do
Tonkinese
:yo:
Exploring Server Actions? 😄
Southeastern blueberry beeOP
// app/database/getVerificationCode.ts

"use server";
import { PrismaClient } from "@prisma/client";

const prisma = new PrismaClient()

export async function getVerificationCode({
  email,
}: {
  email: string;
}) {

  try {

    const user = await prisma.registrationCodes.findUnique({
      where: { email: email }
    });

    return user

  } catch (error) {

    return { error: "Error" };

  }
}


// app/register/page.tsx
"use client"
import { getVerificationCode } from '../components/getVerificationCode'

const data = getVerificationCode('code')
?
@Ray
@Ray turn the page to server component by removing `'use client'` then you can do `const data = await getVerificationCode('code')`
Southeastern blueberry beeOP
app/register/page.tsx
must be clioent
Southeastern blueberry beeOP
move what
and import it from server component
@Southeastern blueberry bee Click to see attachment
Southeastern blueberry beeOP
i need to getVerificationCode in this file
@Southeastern blueberry bee move what
// app/register/page.tsx

import Client from "./client"

export default function Page() {
  const data = await getVerificationCode('code')

  return <Client data={data} />
}

// app/register/client.tsx
'use client'

export default function Client({data}) {
  ....
}
it is recommended to let the page component as server component
Southeastern blueberry beeOP
@Ray
you have allowImportingTsExtensions in tsconfig.json?
Southeastern blueberry beeOP
nope
cheers
and
// app/database/setVerificationCode.ts
"use server"
import { PrismaClient } from "@prisma/client"

const prisma = new PrismaClient()

export async function setVerificationCodeInDB({ code, email }: { code: string; email: string; }) {

    try {

        const user = await prisma.registrationCodes.create({
            data: {
                email: email,
                code: code
            }
        })

        return {
            Statement: 'Success'
        }

    } catch(error) {

        return {
            Error: error
        }

    }

}
@Southeastern blueberry bee Click to see attachment
import { setVerficationCodeInDB} from '../database/setVerificationCode'
Southeastern blueberry beeOP
right
@Southeastern blueberry bee Click to see attachment
setVerificationCodeInDB({ code, email:mail })
Southeastern blueberry beeOP
show the code you have now
Southeastern blueberry beeOP
// app/database/setVerificationCode.ts

"use server"
import { PrismaClient } from "@prisma/client"

const prisma = new PrismaClient()

export async function setVerificationCodeInDB({ code, email }: { code: string; email: string; }) {

    try {

        const user = await prisma.registrationCodes.create({
            data: {
                email: email,
                code: code
            }
        })

        return {
            Statement: 'Success'
        }

    } catch(error) {

        return {
            Error: error
        }

    }

}
nothing was added to db
show the code on the page
where you call setVerificationCodeInDB
Southeastern blueberry beeOP
alr
await setVerificationCodeInDB({ code, email:mail })
Southeastern blueberry beeOP
ah ok
i see why ur doing that
it worked!
ok
perfect
wait
why am i even doing all this
the veri code is already in verificationCode
actually
i can use this for the accounts
@Southeastern blueberry bee why am i even doing all this
lol good question, i dont know
Southeastern blueberry beeOP
@Ray
how can i install nodemailer to use in my page.tsx?
npm install nodemailer --save
Southeastern blueberry beeOP
i did that
but im doing
import { nodemailer } from 'nodemailer'
and you should use it in server action or route handler
Southeastern blueberry beeOP
and it aint working
import nodemailer from 'nodemailer'
Southeastern blueberry beeOP
i did that too
const transporter = nodemailer.createTransport({
  host: "smtp.ethereal.email",
  port: 587,
  secure: false, // `true` for port 465, `false` for all other ports
  auth: {
    user: "maddison53@ethereal.email",
    pass: "jn7jnAPss4f63QBp6D",
  },
});

await transporter.sendMail({
    from: '"Maddison Foo Koch 👻" <maddison53@ethereal.email>', // sender address
    to: "bar@example.com, baz@example.com", // list of receivers
    subject: "Hello ✔", // Subject line
    text: "Hello world?", // plain text body
    html: "<b>Hello world?</b>", // html body
  });
Southeastern blueberry beeOP
i know howm to use nodemailer
i just cant import it
npm install @types/nodemailer --save-dev
Southeastern blueberry beeOP
fixed it
sop
cheers
soi
so
for the router handler
server use
could i do the same thing i did when i was setting verification code
?
yes
Southeastern blueberry beeOP
alr
Southeastern blueberry beeOP
wait
@Ray
i have
// app/register/page.tsx
"use client"
import { sendMail } from '../functions/sendMail.ts'

sendMail({ code, email: mail })
it says the code and stuff in network tab
which removes the purpose of verification
only you can see it
Southeastern blueberry beeOP
yes i get the email
wdym
@Southeastern blueberry bee Click to see attachment
only you can see the payload
Southeastern blueberry beeOP
me?
the one who send the request
Southeastern blueberry beeOP
ytes
but then if someone who doesnt own the email creates an account with that email
they just find the code sent in the network tab?
how?
Southeastern blueberry beeOP
cause its in the payload
how they can access that guy browser?
Southeastern blueberry beeOP
dev tools?
lol
can i access your browser and check your history?
Southeastern blueberry beeOP
no
ur not getting what im saying
ok
so how can other guy does?
Southeastern blueberry beeOP
so
Say me is a a hacker
I put some random persons email in the email input box
and press sign up
the verification code is sent to the random persons email
but the code is in the hackers payload request
and they can see the code withoutr access to the email
that's why you need to check if the email is already been used
and send the code after the user is created
Southeastern blueberry beeOP
no
?
not in a separate action
Southeastern blueberry beeOP
that wont fix anythjing
im verifying email with a code
when the code is sent to their emnaoil
u can just see the code in the network tab
then the email should contain a link
Southeastern blueberry beeOP
the link will still be in the payload tab
and he user press the link and your server handle the verfication
it doesn't matter
Southeastern blueberry beeOP
it does
ok
you refresh the page
Southeastern blueberry beeOP
cause a hacker can just see the payload?
you refresh the page
and can you check the previous payload
Southeastern blueberry beeOP
i dont think you are understanding me
I don't think you understand me either lol
Southeastern blueberry beeOP
probably not if u understand me
ill do something that may help u
as I said early, if your site is running on https
it should be encrypted on the network
also, the code should be invalid after the verification
it doesn't matter if someone have it or not
Southeastern blueberry beeOP
@Ray
how does the hacker get the code if the email is sent victim?
Southeastern blueberry beeOP
because the code is in the network tab when the email is sent to the victim
it should be in network tab when you doing the verfication with the code
Southeastern blueberry beeOP
// sendMail.ts
"use server"
import nodemailer from 'nodemailer'

export async function sendMail({ code, email }: { code: string, email: string }) {

    const transporter = nodemailer.createTransport({
        service: 'gmail',
        auth: {
            user: '..',
            pass: '..'
        }
    })

    const options = {
        from: '',
        to: email,
        subject: `Verification Code -`
,
        text: `Hello,\n\nPlease enter this verification code into the input box:\n${code}\n\nIf you have not tried to create a code, you may ignore this email.`
    }

    await transporter.sendMail(options).catch(() => {})



}
Southeastern blueberry beeOP
yes
so am i
you are sending it on the page
Southeastern blueberry beeOP
but how am i going to know the verification code in page.tsx
if i create the code in the sendMail.ts
how do you generate the code
wait
why you need to know the code in page.tsx?
Southeastern blueberry beeOP
@Ray why you need to know the code in page.tsx?
Southeastern blueberry beeOP
because they input ythe verification code in there
the code should be saved in db
and handle in server action
Southeastern blueberry beeOP
oh ok
i gtg tho now
gotta celeb new years
cya
ill be back in some time
ty
:thinq:
@Southeastern blueberry bee because they input ythe verification code in there
if you just store the code in state, how are you gonna verfiy it if the user refresh the page?
why would they refersh?
how about page crash then
Southeastern blueberry beeOP
well
how about power off by accident?
you can't control it
Southeastern blueberry beeOP
they will have to verify again
but if i add the code to the db
they can still see me adding to db
you should do that on server side
Southeastern blueberry beeOP
i am
but whne i do
...(code, email)
no you are generating the code on the page
Southeastern blueberry beeOP
thats logged in network
and sending it to server
Southeastern blueberry beeOP
OHHHHHHH
IO
GET YOU
I GET WHAT U MEAN NOW
Southeastern blueberry beeOP
but
so
your doing sendMail(email)
which is sending the code in email
and
then when they press confirm on the verification code page
it gets the code from db and matches it to the input
@Southeastern blueberry bee your doing sendMail(email)
it is just an example, i dont have your code
Southeastern blueberry beeOP
i know
you could just call generateCode inside the sendMail function
Southeastern blueberry beeOP
i will
or generate the code in registration
then save it to db and send the email
Southeastern blueberry beeOP
but when i get the code from the db
hgm
ok ok
i can do the first bit
one second
you just query the user by email
Southeastern blueberry beeOP
yh
and check the user.code and input.code is equal
remove the code from database after verfication
Southeastern blueberry beeOP
ofc
and you could also add a boolean column to the user, eg isVerified
Southeastern blueberry beeOP
which would serve what purpose?
only verified user are able to login or other stuff
it is up to you
Southeastern blueberry beeOP
yh but
whne i do
import { sendMail } from '../functions/sendMail'

sendMail('email')
and thats logged in network tab
can hacker not span that
spam
it won't if you are not calling it on the page
Southeastern blueberry beeOP
so i cant edo
?
Southeastern blueberry beeOP
in like an app like insomnia?
to spam it
lol
you try
Southeastern blueberry beeOP
is there any way i can imporve the speed of this?
so the page loads quicker
Southeastern blueberry beeOP
@Ray
your page load slow?
Southeastern blueberry beeOP
yh
it takes 10 seconds
like 99% of time
it is localhost tho
is that reason?
??????
the variables are right
@Southeastern blueberry bee it takes 10 seconds
try it in production build, if it still take 10 sec, it should be something wrong with your query
@Southeastern blueberry bee Click to see attachment
email already exists in db
Southeastern blueberry beeOP
wdym
oh
ur right
but why does it error?
you set it unique
Southeastern blueberry beeOP
i did npx prisma migrate dev --name init
@id is unique
you can't have duplicate id
Southeastern blueberry beeOP
i thought id meant primary key
there must be id
so it would be better put it in code @id?
primary key is unique
Southeastern blueberry beeOP
lmao
oh
@Ray how do i get from the db again?
what do you mean?
Southeastern blueberry beeOP
how do i get the code from database with email
i dont know how does your schema look like
Southeastern blueberry beeOP
no
from page.tsx
to the getCode.ts
why you need it on the page?
Southeastern blueberry beeOP
cause thats where the user writes the code they received
so they write the code
and you verify it with server action
on the server side
Southeastern blueberry beeOP
one sexc
if you send the code to page, they will see it
Southeastern blueberry beeOP
something like this?
@Ray
change 3 to 2
these two should be on server too
Southeastern blueberry beeOP
is this bit right then
yes
Southeastern blueberry beeOP
right