next-auth

Im working on auth in this next app using next auth with google and credentials providers, and custom sign in and register page . I definitely don't knw if I'm doing it in the right safest way to prevent my data from attackers. I made only the
play
play
route redirect u to the login page when u're not logged in i'll do the same for the rest of the pages later except blogs, home, sign in routes Also the dashboard route will be protected route with user based auth
For now i wanna knw if my method is correct or not and what the things that i missed or did wrong. This is the github repo pls feel free to check it out : https://github.com/CLOG9/PuzChess/tree/main
GitHub
GitHub - CLOG9/PuzChess: a new chess puzzles platform made with nex...
a new chess puzzles platform made with next js. Contribute to CLOG9/PuzChess development by creating an account on GitHub.
261 Replies
Lumberjack
Lumberjack17mo ago
@smolcheeld
KP
KP17mo ago
you on app dir or pages dir ?
Lumberjack
Lumberjack17mo ago
App Check the repo
KP
KP17mo ago
u can write a middleware to do it as well. this way isnt too bad tho i have done this way personally a few times as well in the form of making a HOC that redirects to other pages this is the better way to do it tho. google around for some examples for this
Lumberjack
Lumberjack17mo ago
I saw how to make middleware Just two lines of code and u did it
KP
KP17mo ago
yea do that then, its a safer option than HOC
Lumberjack
Lumberjack17mo ago
Really?
KP
KP17mo ago
yes
Lumberjack
Lumberjack17mo ago
I thought the HOC is safer
KP
KP17mo ago
btw u will still have to check if user is auth to make typescript happy for either way
Lumberjack
Lumberjack17mo ago
Wdym
KP
KP17mo ago
next auths useSession hook that returns data it wont know if ur middleware has checked for it or not i believe so ts will show data returned by useSession as session | null
Lumberjack
Lumberjack17mo ago
Aaaah okay i got it So i don't need getServerSession? For the admin panel
KP
KP17mo ago
yea its not needed thats one of the advantages of middleware, u dont need to make HOCs for diff scenarios
Lumberjack
Lumberjack17mo ago
Or just i have to make special key in the .env file for the admin user? Yeh i'll use middleware then
KP
KP17mo ago
write the middleware. for each page thats for authed users only, do an if(status === "unauthenticated") redirect or do something uhm u shld assume anything on the client can be hacked and so rely on making ur serverside apis secure this way even if they hack the js and get to the admin page, all the fetch requests wont respond anythin coz u auth on the server
Lumberjack
Lumberjack17mo ago
Do u have any real projects have this type of middleware?
KP
KP17mo ago
not on the app dir
Lumberjack
Lumberjack17mo ago
Aah okay
KP
KP17mo ago
search it up, u shld easily find multiple examples for this
Lumberjack
Lumberjack17mo ago
Nd in my repo i did right or? For sure so just changing to middleware and make sure the admin route is safer Im bit confused in the second one
KP
KP17mo ago
wdym by second one where are u makin requests ? i dont see any server code here
Lumberjack
Lumberjack17mo ago
I didn't make the api yet I'll put the code in the api route
KP
KP17mo ago
basically what i meant by making it safe on server side is like on the api u do: if(!authed || !isAdmin) throw unauthrozied
Lumberjack
Lumberjack17mo ago
Ooooooooh 🤦‍♂️🤦‍♂️🤦‍♂️🤦‍♂️ Silly me So i have to check in both client and server sides
KP
KP17mo ago
yes always do validations on both the client and server. and always on server at the very least never do client side only
Lumberjack
Lumberjack17mo ago
I got it now, but how the server or the API will get the
authed
authed
and
isAdmin
isAdmin
props? Just passing them through the headers with axios or any lib?
KP
KP17mo ago
uhm u get the session on the server from next auth
Lumberjack
Lumberjack17mo ago
🤦‍♂️🤦‍♂️🤦‍♂️🤦‍♂️🤦‍♂️🤦‍♂️
KP
KP17mo ago
and have a property on the session called role or wotever
Lumberjack
Lumberjack17mo ago
I can pass the data from session🤦‍♂️ Thanks bro im stupid today idk what happend to me lol
armanda 🇮🇩
armanda 🇮🇩17mo ago
hi, i have similar question but im using pages route. do i need to use getServerSideProps on protected page to check the session?
Lumberjack
Lumberjack17mo ago
@smolcheeld u here ? anyway i tried to make this in middleware but its making weird behaivor
Lumberjack
Lumberjack17mo ago
Lumberjack
Lumberjack17mo ago
when i load the page nd make a session(sign in ) it renders the other routes but when i navigate between them it gets frozen until i open the route in other tab. and even if im logged in it requires me to re-log when i try to navigate to those routes also i can access the routes from the URL so actually it still not protected
KP
KP17mo ago
hmm thats weird. i havent used next auth with app dir so cant help u much there sorry not necessarily. u can check if user is authed via middleware, in getserversideprops or inside the pages render function. all 3 options have diff user exps
Lumberjack
Lumberjack17mo ago
is there any other suggestions
KP
KP17mo ago
check out shadcn's taxonomy repo. that has a nextauth middleware example iirc
KP
KP17mo ago
GitHub
GitHub - shadcn/taxonomy: An open source application built using th...
An open source application built using the new router, server components and everything new in Next.js 13. - GitHub - shadcn/taxonomy: An open source application built using the new router, server ...
Lumberjack
Lumberjack17mo ago
@smolcheeld hey, i fixed the issues. I just changed the middleware file to the src dir and it worked totally fine lol, anyway now im going to make user authorization and register using mysql but do u suggest using raw SQL or using drizzle? I remember that u said use prizma latter in other projects to learn SQL well. but what about now?
KP
KP17mo ago
use drizzle coz it makes workin with ts easier and safer
Lumberjack
Lumberjack17mo ago
i heared that i cant use drizzle with next auth ?
KP
KP17mo ago
havent tried it with next auth, but i dont see why u shldnt try askin in drizzles discord or searching for examples
Lumberjack
Lumberjack17mo ago
check this
KP
KP17mo ago
ah the adapter is a WIP
KP
KP17mo ago
welp, u can try to follow and clone this https://github.com/nextauthjs/next-auth/pull/7165 and ask in their discord for help when u get stuck
GitHub
[WIP] feat(adapters): add Drizzle adapter by anthonyshew · Pull Req...
☕️ Reasoning Introducing a drizzle-orm adapter! With drizzle's increasing popularity, it's no surprise that there's a discussion for an adapter. This PR adds it. 🧢 Checklist Documenta...
KP
KP17mo ago
or use clerk or something else 🤷‍♂️
Lumberjack
Lumberjack17mo ago
i think i'll use prizma instead and use cleark with drizzle in the next project
KP
KP17mo ago
fair enough
Lumberjack
Lumberjack17mo ago
thanks tho and sorry for annoying u
KP
KP17mo ago
nah its all good
Lumberjack
Lumberjack17mo ago
@smolcheeld u here? I don't understand smthng, i saw a prizma t3 boilerplate nd it has session, verification token models I don't understand why wee beed them . I mean yes u need to check session but doesn't nextauth do that for me? Or its just ob the client side ?
KP
KP17mo ago
@CLOG read the next auth docs adapters section The tldr is u need to store info somewhere - jwt or db, when u store on db u need to make some tables and shit first And so for prisma the schema needs to look like that which the t3 boilerplate gives u
Lumberjack
Lumberjack17mo ago
To make things clear: nextauth create a jwt for me or should i generate one?
KP
KP17mo ago
Nah u dont need to do anything Just follow the prisma setup for next auth and thats it
Lumberjack
Lumberjack17mo ago
What user based role Aah okay
KP
KP17mo ago
Wdym ? Are u askin how to add role based auth ?
Lumberjack
Lumberjack17mo ago
Well what will happen if i don't store the session on the db?
KP
KP17mo ago
I havent tested this in next auth but with most auth solutions what happens is when u login and close the tab, next time u open the site again u will have to login again
Lumberjack
Lumberjack17mo ago
Oh i miss spell it, what about user based role should i make a different jwt for it?
KP
KP17mo ago
But if u store sessions,u wont have to login until the sess expires Nah just add the role field to the session Thats what i did for impl role based auth and it works well
Lumberjack
Lumberjack17mo ago
And check it on the server
KP
KP17mo ago
Yep For promotion to admin, i made a route that can only be navigated by typing it in And u have to give a server secret to chck if u are admin Then if its correct the persons role gets promoted For simple setups this works well eno
Lumberjack
Lumberjack17mo ago
I think i should make a jwt only if im making reset password feature Is that server secret a jwt or just an openssl key?
KP
KP17mo ago
Openssl key I think u are mistaking the purpose of jwt U dont need a jwt for this either tbh
Lumberjack
Lumberjack17mo ago
I didn't understand how the client would have that key How
KP
KP17mo ago
Well if its only gonna be for u and a circle of ppl u personally trust, u manually generate a key and add it to env vars and check against that Otherwise wot u wanna do is have a table wit a single entry in which u store the key but everytime its used it gets rolled over. This way there is no risk of ppl using old keys to make their friends admin without u knowing
Lumberjack
Lumberjack17mo ago
So that server secret must be typed in the url?
KP
KP17mo ago
For this u generate a random crypto secure hash and store it on the users table. U send them an email with that hash in the route param and when they open that url u compare the hashes Not necessarily. Totally upto u how and where u check it If u wanna send links that ppl judt click and its done then do it that way
Lumberjack
Lumberjack17mo ago
Or just make a login page I think i understand a bit
KP
KP17mo ago
Its not conceptually complicated tbh. The email part can be a bit of a pain to setup tho
Lumberjack
Lumberjack17mo ago
And that crypto should be regenerated every time the specified user try to reset his password
KP
KP17mo ago
Yes. In case if ppls email gets leaked u dont want ppl with old links resetting Also u wanna store the key as hashed not in plain form, basically the same way we store passwords in db using bcrypt or some other algo The reason u wanna hash is, if ur db gets leaked somehow, anyone can reset anyones password if its not hashed
Lumberjack
Lumberjack17mo ago
Oh that's why then ...
KP
KP17mo ago
Yea this is also why some companies dont let u see ur api keys more than once btw
Lumberjack
Lumberjack17mo ago
I understand now but the only thing that i don't knw why i need it is why should store the session in the db If its already known by the auth provider
KP
KP17mo ago
u own ur auth with next auth u arent checking against their server
Lumberjack
Lumberjack17mo ago
I checked the next auth adapters section and its only showing how to make the model and add the prizma adapter to the options, is that it? Or should make api endpoints and POST the data?
KP
KP17mo ago
u need to make a catch all api route atleast for pages dir not sure about app dir, search around or look for examples
Lumberjack
Lumberjack17mo ago
Sure
Lumberjack
Lumberjack17mo ago
@smolcheeld why im getting this
KP
KP17mo ago
is this local or on planetscale ?
Lumberjack
Lumberjack17mo ago
planetscale
KP
KP17mo ago
read the Making schema changes with db push part
Lumberjack
Lumberjack17mo ago
relationMode = "prisma" lol, thanks budd i don't know how i would make this app without your help
KP
KP17mo ago
:D
Lumberjack
Lumberjack17mo ago
I think i miss spelled it but u got me anyway lol
KP
KP17mo ago
xD
Lumberjack
Lumberjack17mo ago
@smolcheeld i made this api route i still didn't add zod validation to it but i want to make an API key to it
const API_KEY: string = process.env.DATA_API_KEY as string;

export async function POST(request: Request, response: Response) {
const { username, email, chessElo } = await request.json();

if (!username || !email)
return NextResponse.json({ message: "Missing required data" });

const res = await createUser(username, email, chessElo);

console.log(request.headers.get("authorization"));

return NextResponse.json(response);
}
const API_KEY: string = process.env.DATA_API_KEY as string;

export async function POST(request: Request, response: Response) {
const { username, email, chessElo } = await request.json();

if (!username || !email)
return NextResponse.json({ message: "Missing required data" });

const res = await createUser(username, email, chessElo);

console.log(request.headers.get("authorization"));

return NextResponse.json(response);
}
and thats the create user function
import prisma from "@/server/db/seed";
export const createUser = async (
username: string,

email: string,
chessElo?: number,
role?: "roles" | undefined,

badge?: "budges" | undefined
) => {
const user = await prisma.user.create({
data: <userType>{
username,
email,
chessElo,
role,

badge,
},
});
return user;
};
import prisma from "@/server/db/seed";
export const createUser = async (
username: string,

email: string,
chessElo?: number,
role?: "roles" | undefined,

badge?: "budges" | undefined
) => {
const user = await prisma.user.create({
data: <userType>{
username,
email,
chessElo,
role,

badge,
},
});
return user;
};
KP
KP17mo ago
so what u tryin to do here
Lumberjack
Lumberjack17mo ago
Well i have two problems first i want to make a secret key to the header of this api to protect it Also idk if should i make zod validation before or after encrypting the data
KP
KP17mo ago
why are u doin this ? either i dont fully understand what u are doin or u are doin something wrong is this related to role based auth where u are tryin to promote the user to admin ?
Lumberjack
Lumberjack17mo ago
I wanna make a GET method that fetchs all the users in the db but i don't want anyone to have the ability to fetch it except the admin(because i need all the uses to appear in the dashboard)
KP
KP17mo ago
ah so u dont need to do this all u do is check if the user is admin inside the route i mean in the api request
Lumberjack
Lumberjack17mo ago
Aaaa okay pretty simple then What about the zod question?
KP
KP17mo ago
i dont think u need to encrypt anythin
Lumberjack
Lumberjack17mo ago
Really? Why I mean everyone highly suggest to do sort of bcrypt or something like that
KP
KP17mo ago
wait what specifically are u tryin to encrypt here
Lumberjack
Lumberjack17mo ago
Passwords and emails
KP
KP17mo ago
u dont need to encrypt emails only encrypt things that need to stay hidden coz with any secure crypto algo like bcrypt its one way only e.g. if u do myemail@com -> somehash, u cant do somehash -> myemail@com
Lumberjack
Lumberjack17mo ago
Okay so encrypting passwords
KP
KP17mo ago
yes encrypt passwords and the reset hash only
Lumberjack
Lumberjack17mo ago
Oh one way then
KP
KP17mo ago
also fyi, u cant decrypt somethin after u have encrypted it but u can compare them yes, once its done, no matter what u wont get the original string
Lumberjack
Lumberjack17mo ago
Well when i add new user to the db should encrypt first then do zod validation or the opposite?
KP
KP17mo ago
so this what u wanna do -> get post request -> validate stuff with zod -> bcrypt hash password -> save everything to db
Lumberjack
Lumberjack17mo ago
a POST yes
KP
KP17mo ago
and if u are doin email resets, generate a random 32 digit key similar to what openssl command gives u, bcrypt hash that and store in the db
Lumberjack
Lumberjack17mo ago
I don't understand
KP
KP17mo ago
also there is no point encrypting after validation coz u wont be saving the user coz the data is invalid xD
Lumberjack
Lumberjack17mo ago
Ps: I realized that im talking with u more than my mom lol, u're a life saver buddy
KP
KP17mo ago
lmao
Lumberjack
Lumberjack17mo ago
I think the point of encryption is protecting the database
KP
KP17mo ago
uh basically u generate a random string, hash that and save it in ur db, when the user requests email reset, u send that in the email and u compare hashes to verify if the request made is legit yes but ur idea of encryption is wrong. u dont encrypt the entire db, u encrypt certain fields of tables and u only do the encryption once before entering/updating that item/row
Lumberjack
Lumberjack17mo ago
Should it be in one of the users table columns or just a temporary key?
KP
KP17mo ago
put it inside the users table col
Lumberjack
Lumberjack17mo ago
If im wrong what is the right method
KP
KP17mo ago
this
Lumberjack
Lumberjack17mo ago
No problem then, i think it would be the same for password reset too?
KP
KP17mo ago
yep
Lumberjack
Lumberjack17mo ago
That's great no need for jwt then
KP
KP17mo ago
also if u are confused about encryption. we dont encrypt the db because like i said its a one way process for good algos so we cant use the data coz it gets converted to meaningless hashes
Lumberjack
Lumberjack17mo ago
I got it i just want to implement the best practices Just two more questions pls🙂
KP
KP17mo ago
yea what i said is compliant with them go ahead, i will prob answer in a bit, got food to take
Lumberjack
Lumberjack17mo ago
First is that the right method to make an api? (The code i sent) Enjoy Second if im not going to use any sort of jwt, when should i use them ? And third (yes i knw i said two sorry ) i did session storage in the db but only for the OAuth, what about the credentials login ?
KP
KP17mo ago
the logic is right but i am not sure if thats how next auth expects u to do it. i havent implemented email and password login on next itself. with nextauth i use social passwords and magic link. if i do email pass its when i have another backend.
Lumberjack
Lumberjack17mo ago
Oh okay i see, i'll search for nextauth method then
KP
KP17mo ago
the jwt is a loaded question, u shld honestly just google it. as for the creds provider question idk tbh
Lumberjack
Lumberjack17mo ago
Okay, thank u bro i really appreciate ur help I think its out of context but how u guys knw that huge stuff of backed functionality and best practices? Is there a specific source or path should i take to get that knowledge cuz the most thing i hate is when i don't knw that something exists even if i don't knw how to use it
KP
KP17mo ago
Watch a basic tutorial and build stuff But dont get trapped in tutorials. Watch the tut to only learn the foundational pieces
Lumberjack
Lumberjack17mo ago
I do this since 3 years but the how u guys (lets say u in this example) know some things that aren't available in the tuts. e.g. u said use middleware instead of the server session or sometimes i read the chat in the tech discussion room and i wounder how u get this info
KP
KP17mo ago
a lot of those things are - we did something, searched how others are doing it and found better ways ^ do the above. doesnt matter in what order and u will learn stuff since u dont know a lot, google even the obvious stuff. i am not a backend guy, i am a frontend one but even then i google stuff i already know just to see if there isnt a better way
Lumberjack
Lumberjack17mo ago
U're correct, now i knw that using middleware in protecting routes is the great solution now and i didn't knw that before. What about blogs, articles which ones u suggest to read
KP
KP17mo ago
for blogs - tkdodo's for react query stuff, read brendanovich's form blog post for specific stuff just read whatever article coz u cant really tell if its gonna be good or not for backend, i highly encourage writing an auth from scratch, dont have to connect it to a frontend or anything. just make like a simple express app, that has a login and register page and u can sign in
Lumberjack
Lumberjack17mo ago
Awesome! But sometimes i don't get certain type of answers to my questions by search, for example: what are the optimal use cases for middleware.
KP
KP17mo ago
well for questions like these, first understand the meaning of it, see a few examples and that shld be eno to extrapolate use cases for it
Lumberjack
Lumberjack17mo ago
In this project, i mada auth and role based and actually i learned a lot of stuff and every day i feel my app is getting more secure but still didn't reach the point that i can handle all the app problems The meaning of middleware?
KP
KP17mo ago
yes if u know how stuff works on a fundamental level u can come up with use cases urself for e.g. if u validate only in a client react comp, its gonna be less secure than doin it thru middleware because the first option is clientside and the second u are checkin on ur server
Lumberjack
Lumberjack17mo ago
Well i guess it comes before the api so any data that needs a specific thing before it gets to the endpoint, it should come across the middleware. And that's another question why should i check in the middleware and not in the api route lol
KP
KP17mo ago
convenience
Lumberjack
Lumberjack17mo ago
Either im dumb or just i miss something
KP
KP17mo ago
middlewares also let u reuse code u just need to sit down and make a backend side app tbh, or u could break down the taxonomy next js github repo i sent u
Lumberjack
Lumberjack17mo ago
Hmmm i definitely have to do it, well based on ur info, i have to make the zod validation and the encryption in the middleware?
KP
KP17mo ago
u dont need to do the validation in the middleware or the encryption
Lumberjack
Lumberjack17mo ago
Why
KP
KP17mo ago
middleware = reusable logic u want to do before ur api route so it works really well when u want to do the same thing everytime but things like validation which in one route u validate diff fields and in the other diff its not as easy to setup to make it worth it. esp with typescript and there is no reason to do encryption outside ur api route
Lumberjack
Lumberjack17mo ago
Oooh like protecting routes
KP
KP17mo ago
yea coz with protecting u will always only check if loggedin, thats it
Lumberjack
Lumberjack17mo ago
Cuz the data should be sent encrypted? I got it, but is there another use cases for middleware?
KP
KP17mo ago
yea but think what u are goin to do after encrypting the password, add it to the db. so this is why u shld do it in the api route because this is the core purpose of ur api route not really. just reusable code. most middlewares u see will check for auth, do cors stuff, session management stuff, etc. stuff thats common to all/multiple routes u can make validation middlewares and such but getting types to work with them is hard so ppl usually dont bother
Lumberjack
Lumberjack17mo ago
To send and encrypt the data? I think the easiest solution is doing it in the api route
KP
KP17mo ago
yes it is no its to add the user to the db. encrypting the password before u do that is just a step. to make it simpler think about this, are u going to ever reuse encrypting ur password in a route other than create user and change password ? prob not so it makes no sense to create a middleware for it
Lumberjack
Lumberjack17mo ago
Well a question came to me, basically in my app when someone register the data went to the api route and it calls the prisma function to store the data, so i wondered why do i even need the api route (i know api routes are important ) i just can call the prisma function directly Finally i got the middleware use case
KP
KP17mo ago
coz u connect to ur db by a connection url that shld be kept secret if u make direct requests on the client, anyone can find out ur connection url from the browser and can write stuff directly to ur db
Lumberjack
Lumberjack17mo ago
U mean The url is connected with prisma client?
KP
KP17mo ago
yes ur planetscale db url and secrets next js separates public env vars (available on client and server) and private ones (only available on server)
Lumberjack
Lumberjack17mo ago
Hmmm i got it now, what about the api route i see some ppl make a type of url in the api itself Lemme send an example
KP
KP17mo ago
wdym i dont understand what u mean by this
Lumberjack
Lumberjack17mo ago
I'll show u an example
Lumberjack
Lumberjack17mo ago
Lumberjack
Lumberjack17mo ago
Why he used the jsonplaceholder api?
KP
KP17mo ago
to get dummy data ? like what are u really askin with this question
Lumberjack
Lumberjack17mo ago
My question is should the api's have a type of urls inside or just he did that to simulate fetching from database
KP
KP17mo ago
u can fetch inside api routes and he also did it to simulate fetching from db u can do this but dont fetch ur own server's other route, re use functions instead
Lumberjack
Lumberjack17mo ago
I got it now, i guess i'll work on the form validation and the credentials login now. Also i did some search about if nextauth is okay with my method of making the api and i found out that nextauth doesn't have an adapter for credentials so either hard code it or just use OAuth.
KP
KP17mo ago
there is a credentials provider but u have to do a lot of implementation urself
Lumberjack
Lumberjack17mo ago
Yes i used it but im talking about the prisma adapter it doesn't work for the credentials provider so idk i think i'll hard code a prisma function that stores a session in the users table
KP
KP17mo ago
u can implement it with prisma sure the creds provider is not a plug and play option. if u see the docs they even mention why
Lumberjack
Lumberjack17mo ago
What about this? Does it help or just send the session directly to the db
callbacks: {
async jwt({ token, user }) {
if (user) {
token.accessToken = user.jwt
}

return token
},
async session({ session, token, user }) {
session.accessToken = token.accessToken
return session
}
}
callbacks: {
async jwt({ token, user }) {
if (user) {
token.accessToken = user.jwt
}

return token
},
async session({ session, token, user }) {
session.accessToken = token.accessToken
return session
}
}
KP
KP17mo ago
Just refer the docs for this. But seems fine to me
Lumberjack
Lumberjack17mo ago
So no need for db? Or i have to store the jwt in the db too
KP
KP17mo ago
no just look at a tutorial or example its a lot to explain
Lumberjack
Lumberjack17mo ago
"next/server";
import { form } from "@/schemas/forms";
const bcrypt = require("bcrypt");

export async function POST(request: Request, response: Response) {
const { username, password, email, confirmPassword } = await request.json();

if (!username || !email || !password) {
return NextResponse.json(
{ message: "Missing required data" },
{ status: 400 }
);
}

try {
const parsedData = await form.parse({
username,
password,
email,
confirmPassword,
});
await bcrypt.hash(parsedData.password, 10, (err: string, hash: string) => {
try {
createUser(
parsedData.username as string,
hash as string,
parsedData.email as string
);
} catch (error) {
throw error;
}
});

return NextResponse.json(parsedData);
} catch (error: unknown) {
console.log(error);
const castedError = error as {
issues?: Array<{ message: string; code: string }>;
};
const errorMessage = castedError.issues?.[0]?.message || error;

return NextResponse.json({ message: errorMessage }, { status: 400 });
}
}
"next/server";
import { form } from "@/schemas/forms";
const bcrypt = require("bcrypt");

export async function POST(request: Request, response: Response) {
const { username, password, email, confirmPassword } = await request.json();

if (!username || !email || !password) {
return NextResponse.json(
{ message: "Missing required data" },
{ status: 400 }
);
}

try {
const parsedData = await form.parse({
username,
password,
email,
confirmPassword,
});
await bcrypt.hash(parsedData.password, 10, (err: string, hash: string) => {
try {
createUser(
parsedData.username as string,
hash as string,
parsedData.email as string
);
} catch (error) {
throw error;
}
});

return NextResponse.json(parsedData);
} catch (error: unknown) {
console.log(error);
const castedError = error as {
issues?: Array<{ message: string; code: string }>;
};
const errorMessage = castedError.issues?.[0]?.message || error;

return NextResponse.json({ message: errorMessage }, { status: 400 });
}
}
what do u think
KP
KP17mo ago
seems fine this is cursed tho
catch (error) {
throw error;
}
catch (error) {
throw error;
}
Lumberjack
Lumberjack17mo ago
well im having a bug, lemme show u first i made a user in the db with a unique username, its created and returns 201 status. when i recreate another one with the same username it should returns an error with a message but instead of that its not creating the recreated user but returning 201 status and logging this in the console - error unhandledRejection: { source: 'server' } when i removed the hashing method everything worked fine but i need to hash the password. i fixed it!
Lumberjack
Lumberjack17mo ago
i made some changes and i dont knw if im doing it right thats the repo pls if u dont mind check it https://github.com/CLOG9/PuzChess
GitHub
GitHub - CLOG9/PuzChess: a new chess puzzles platform made with nex...
a new chess puzzles platform made with next js. Contribute to CLOG9/PuzChess development by creating an account on GitHub.
Lumberjack
Lumberjack17mo ago
@smolcheeld u here?
KP
KP17mo ago
not home today, will check tmrw when i am back
Lumberjack
Lumberjack17mo ago
Oh sorry, have fun
KP
KP17mo ago
nah its ok :D
Lumberjack
Lumberjack17mo ago
@smolcheeld u here?
KP
KP17mo ago
Ye
Lumberjack
Lumberjack17mo ago
first hooe your doing well. im having a problem with middleware even if im logged in its asking me to re sign in and it keeps doing that thats the next auth page :
export const options: NextAuthOptions = {
secret: process.env.JWT_SECRET,
session: {
strategy: "jwt",
maxAge: 3600 * 6,
},
callbacks: {



jwt: async ({ token, account, user }) => {
user && (token.user = user);
console.log(token);
return token;
},
session: async ({ session, token }) => {
if (token && token.user) {
session.user = token.user as any;
}
return session;
},
},
adapter: PrismaAdapter(prisma) as Adapter,
pages: {
signIn: "/auth/signin",
},
providers: [
GoogleProvider({
// profile(profile: GoogleProfile) {
// return {
// ...profile,
// role: profile.role ?? "BASIC",
// id: profile.id,
// };
// },
clientId: process.env.GOOGLE_CLIENT_ID as string,
clientSecret: process.env.GOOGLE_CLIENT_SECRET as string,
}),
CredentialsProvider({
name: "Credentials",
credentials: {
username: {
type: "text",
},
password: {
type: "password",
},
},
async authorize(credentials) {
const user = await getUser(credentials?.username as string);
if (user === null) {
//no user
throw Error("user or password not valid");
}
const ismatch = await bcrypt.compare(
credentials?.password,
user?.password
);
console.log(ismatch);
if (ismatch) {
return {
id: user.id,
role: user.role,
name: user.name,
email: user.email,
chessElo: user.chessElo,
badge: user.badge,
image: user.image,
};
} else {
// invalid pass
throw Error("user or password not valid");
}
},
}),
],
};
export const options: NextAuthOptions = {
secret: process.env.JWT_SECRET,
session: {
strategy: "jwt",
maxAge: 3600 * 6,
},
callbacks: {



jwt: async ({ token, account, user }) => {
user && (token.user = user);
console.log(token);
return token;
},
session: async ({ session, token }) => {
if (token && token.user) {
session.user = token.user as any;
}
return session;
},
},
adapter: PrismaAdapter(prisma) as Adapter,
pages: {
signIn: "/auth/signin",
},
providers: [
GoogleProvider({
// profile(profile: GoogleProfile) {
// return {
// ...profile,
// role: profile.role ?? "BASIC",
// id: profile.id,
// };
// },
clientId: process.env.GOOGLE_CLIENT_ID as string,
clientSecret: process.env.GOOGLE_CLIENT_SECRET as string,
}),
CredentialsProvider({
name: "Credentials",
credentials: {
username: {
type: "text",
},
password: {
type: "password",
},
},
async authorize(credentials) {
const user = await getUser(credentials?.username as string);
if (user === null) {
//no user
throw Error("user or password not valid");
}
const ismatch = await bcrypt.compare(
credentials?.password,
user?.password
);
console.log(ismatch);
if (ismatch) {
return {
id: user.id,
role: user.role,
name: user.name,
email: user.email,
chessElo: user.chessElo,
badge: user.badge,
image: user.image,
};
} else {
// invalid pass
throw Error("user or password not valid");
}
},
}),
],
};
and thats the middlare
export { default } from "next-auth/middleware"

export const config = { matcher: ["/dashboard"] }
export { default } from "next-auth/middleware"

export const config = { matcher: ["/dashboard"] }
so when i navigate to the dashboard route it requiring me to sign in even if im already signed in
KP
KP17mo ago
GitHub
taxonomy/middleware.ts at main · shadcn/taxonomy
An open source application built using the new router, server components and everything new in Next.js 13. - taxonomy/middleware.ts at main · shadcn/taxonomy
KP
KP17mo ago
also i am doing great, hope u are too :D
Lumberjack
Lumberjack17mo ago
trust me, im not lol
KP
KP17mo ago
lmfao take a look at that link, that shld work for u
Lumberjack
Lumberjack17mo ago
hmmm i didnt get the most of it can you explain?
KP
KP17mo ago
basically u need to make a list of pages that shld be only accessible to signed in users and then in the cb u check if they are authed or not and redirect them just copy paste his code and replace your routes and stuff and thats it pretty much
Lumberjack
Lumberjack17mo ago
i think its causing infinte redirects?
KP
KP17mo ago
what is causing infinite redirects ?
KP
KP17mo ago
his code shld def work coz https://tx.shadcn.com/ works
Taxonomy
Taxonomy
An open source application built using the new router, server components and everything new in Next.js 13.
Lumberjack
Lumberjack17mo ago
i'll check the options i won't se credentials provider ever again if im going to use it ill use it with clerk idk its a hell @smolcheeld if u don't mind i'll sent u the repo and check it
Lumberjack
Lumberjack17mo ago
GitHub
GitHub - CLOG9/PuzChess: a new chess puzzles platform made with nex...
a new chess puzzles platform made with next js. Contribute to CLOG9/PuzChess development by creating an account on GitHub.
KP
KP17mo ago
most things seem fine here yep thats why i dont personally use it either. they intentionally dont help u out with to discourage it. sadly if thats what u need then its gonna be hard
Lumberjack
Lumberjack17mo ago
I can give u the secrets and try it by urself The sad thing is clients still ask for them to be in the design
KP
KP17mo ago
is this ur own side project or for a client if its for clients u shld really just use clerk or some other auth service
Lumberjack
Lumberjack17mo ago
Its a side project Im trying to learn auth
KP
KP17mo ago
welp i dont have personal exp implementing cred provider so cant help u there
Lumberjack
Lumberjack17mo ago
I think i'll switch to email provider theb Then
Endgame1013
Endgame101317mo ago
Exactly why I haven’t been using next-auth for credential auth lmao
Lumberjack
Lumberjack16mo ago
Believe me when i say this project gave me trauma Hey, i used getServerSession instead of middleware cause it didn't help, now the problem is the session only return 3 values instead of the full data i tried to edit it in the callback Like this :
session.user = user
return session
session.user = user
return session
But when i check it in the server component it doesn't work @smolcheeld
KP
KP16mo ago
U need to add ,user in the jwt cb and in the session cb acc to the docs
KP
KP16mo ago
Callbacks | NextAuth.js
Callbacks are asynchronous functions you can use to control what happens when an action is performed.
Lumberjack
Lumberjack16mo ago
i think that is available only for jwt strategy right? or both jwt and db sessions?
KP
KP16mo ago
Not sure, check the docs
Lumberjack
Lumberjack16mo ago
@smolcheeld should make friendship table relationship one to many or many to many?
KP
KP16mo ago
many to many coz if i am friends with X, he is also friends with me xd
Lumberjack
Lumberjack16mo ago
something like that?
model User {
id String @id @default(cuid())
role roles @default(BASIC)
name String @unique
chessElo Int?
badge budges @default(ROCKIE)
email String? @unique
emailVerified DateTime?
image String?
followedBy Follows[] @relation("following")
following Follows[] @relation("follower")
accounts Account[]
sessions Session[]
}

model Follows {
follower User @relation("follower", fields: [followerId], references: [id])
followerId String
following User @relation("following", fields: [followingId], references: [id])
followingId String

@@id([followerId, followingId])
}
model User {
id String @id @default(cuid())
role roles @default(BASIC)
name String @unique
chessElo Int?
badge budges @default(ROCKIE)
email String? @unique
emailVerified DateTime?
image String?
followedBy Follows[] @relation("following")
following Follows[] @relation("follower")
accounts Account[]
sessions Session[]
}

model Follows {
follower User @relation("follower", fields: [followerId], references: [id])
followerId String
following User @relation("following", fields: [followingId], references: [id])
followingId String

@@id([followerId, followingId])
}
KP
KP16mo ago
Prisma
Many-to-many relations
How to define and work with many-to-many relations in Prisma.
KP
KP16mo ago
Read the implicit section
Coded_58
Coded_5816mo ago
sorry for diverting the conversation a bit, but i saw the heading was about next-auth and i needed to understand smthing.... So i've an application (pretty big) with multiple users and their roles and access level (thank goodness for the new next.js route grouping) i was able to group different UI for different users now i'm implementing next-auth credentials providers and i will like to redirect different users based on their roles to their specific route group i created a role-checking server component that run on the server and checks your session from next-auth, it then directs the user to their route... i really am beating myself if this is the best implementation for this use case or theres another way to run a function on next-auth sign-in handler @smolcheeld please help, thanks
Lumberjack
Lumberjack16mo ago
The thing that i learned from next auth is don't use their credentials provider. Use clerk or smthng else. What is the session strategy?
Coded_58
Coded_5816mo ago
its a seperate frontend from the backend... i only work on the frontend so i dont have much of an option... the backend developers control the authetication database just get the session from next-auth on the server and run some checks before routing users to specific route... that's what i want to know if that is a good strategy or there's a better way of implementing role-based-acces control on the overall application what i did in the middleware was check for each path if the user is authenticated and authorized to vie that route
Lumberjack
Lumberjack16mo ago
So used the middleware here? I guess u can do that, either all in one place ur Middleware or in each router if its a server component
Coded_58
Coded_5816mo ago
yeah. the main question is how to route users after they sign-in with next-auth sign-in function... is it okay that i have a special route page for checking their roles or is there a better way to go about it
Lumberjack
Lumberjack16mo ago
In the callbacks set the paths based on their role After u get the session, check the role then redirect them based on that Or use middleware either Just make the checking in both client and server side More important in server
Coded_58
Coded_5816mo ago
yeah every authenticated is being done on the server... thanks one more thing.... what i actually need is like a guide, i feel i'm doing it right but also need opionion from other devs... lets say after i created different route-groups for different users, inside each route there's also a very granular access level, lets say for example i defined a sidebar that holds 7 different link menus, the head or let's say admin of that particular route give access and authorization to different users the admin goes to the settings page, choose a particular user and gives them access to some part of the sidebar menu that basically means every menu on the sidebar must go thru an authorization check. what i implemented was each sidebar menu gets the user details from the database and check if they are authorized to view that page or not please is there a better way to go about it cuz that basically mean each sub page of each menu will also go thru that check... sorry for the long a** message desperately need some clarity
Lumberjack
Lumberjack16mo ago
So u're checking in every single route?
KP
KP16mo ago
U can try middlewares for this Ur current approach isnt bad either. Middleware is a more "clean" way to do it
Lumberjack
Lumberjack16mo ago
U used tauri before right?
KP
KP16mo ago
a bit yea
Coded_58
Coded_5816mo ago
yeah exactly... how can i go about it correctly sending the next-auth callback to the middleware or?? a bit confused
Lumberjack
Lumberjack16mo ago
Since i used database session as my strategy i used server components to check the user roles So make sure u use them U check the role in the middleware and redirect the user based on that
Coded_58
Coded_5816mo ago
thanks
Lumberjack
Lumberjack16mo ago
U still can use middleware tho
Coded_58
Coded_5816mo ago
ohh yeah, already implemented that... just extra checks and making sure the frontend authentication is perfect
Lumberjack
Lumberjack16mo ago
Im looking to make a feature that allows me to use an external printer Make sure to query that via an api
KP
KP16mo ago
u just check it in the middleware. look at this for e.g. https://github.com/shadcn/taxonomy/blob/main/middleware.ts
GitHub
taxonomy/middleware.ts at main · shadcn/taxonomy
An open source application built using the new router, server components and everything new in Next.js 13. - shadcn/taxonomy
KP
KP16mo ago
interesting. would suggest u check the stuff it supports first tho coz when i tried it i found very often i need x but tauri doesnt have it and electron does
Lumberjack
Lumberjack16mo ago
I see, electron is cursed tho but it is what it is
KP
KP16mo ago
using a cursed thing is better than somethin that literally doesnt do what u want tho 🤷‍♂️
Lumberjack
Lumberjack16mo ago
Even if the performance is the tradeoff?
KP
KP16mo ago
yea. somethin workin will nearly always be better than nothin at all.
Coded_58
Coded_5816mo ago
🙌 few minutes into the repo and i have already refactored a bit🫡
KP
KP16mo ago
yea its a great resource fr. have fun with ur learning :D
Lumberjack
Lumberjack16mo ago
GitHub
[feat] Provide print API · Issue #4917 · tauri-apps/tauri
Describe the problem Tauri lacks a print API and this make it very difficult for electron based apps that perform lots of work with printers to migrate to Tauri, there are many use cases Unable to ...
Lumberjack
Lumberjack16mo ago
i think electron is the way for this project
KP
KP16mo ago
yea tauri has lot of shit electron doesnt deranged
Lumberjack
Lumberjack16mo ago
electron is slow poohheh
KP
KP16mo ago
vs code and discord are electron it will be fine for ur usecase unless ram is ur issue
Lumberjack
Lumberjack16mo ago
basically im making a store management app. user receipt, stock and revenue,etc.. but i want to make it with complex ui (shadows, animations )
KP
KP16mo ago
electron shld be fine for this
Lumberjack
Lumberjack16mo ago
am i able to use react stuff with it? like framer motion, tailwind?
KP
KP16mo ago
u can use any framework u want with it
Lumberjack
Lumberjack16mo ago
theowat
Sturlen
Sturlen16mo ago
I'd be careful with animations for such a system. I've made similar industrial applications and there is nothing more annoying to a worker putting in a hundred orders per day, than long-winded or flashy animations
KP
KP16mo ago
yes although idk why u would want next with it
Lumberjack
Lumberjack16mo ago
the animations im trying to make just the page transitions, pop out , fades in/out spinners how would i handle the backend (works local)?
KP
KP16mo ago
oh i thought this purely a clientside thing yea t3 shld be pretty good for this or next app dir if uwant that
Lumberjack
Lumberjack16mo ago
im going to use sqlite for the records trpc sounds pretty handy for this project
Coded_58
Coded_5816mo ago
please how can i solve this error, i cant seem to use the apostrophe
Coded_58
Coded_5816mo ago
i just started using typescript
KP
KP16mo ago
You can write it as {`Text with apostraphe here } any type of string declaration works in there not just
Coded_58
Coded_5816mo ago
but thats just plain text, i wasnt even evaluating an expression... what about if my database returns an apostraphe??
KP
KP16mo ago
vars dont have this problem. the problem here is a js syntax problem nothin else.
Coded_58
Coded_5816mo ago
alright... thank you
dingo
dingo16mo ago
Yes, except you mean a hash 🙂
KP
KP16mo ago
yea i meant hashes
Want results from more Discord servers?
Add your server