Glen Kurio
Glen Kurio
Explore posts from servers
BABetter Auth
Created by RiLeX98 on 4/16/2025 in #help
How to set CallbackURL in emailVerification
Otherwise callback in signUp/In.email is used to redirect user after successful email verification
3 replies
BABetter Auth
Created by RiLeX98 on 4/16/2025 in #help
How to set CallbackURL in emailVerification
You can specify the callback URL only when triggering sendVerificationEmail manually:
await authClient.sendVerificationEmail({
callbackURL: "/" // The redirect URL after verification
})
await authClient.sendVerificationEmail({
callbackURL: "/" // The redirect URL after verification
})
https://www.better-auth.com/docs/concepts/email#3-manually
3 replies
BABetter Auth
Created by Glen Kurio on 4/14/2025 in #help
Avatar Upload Issue: Session Cookie Size and Upload Timing
Yes, and if sign up fails - we'll have orphaned images in storage.
5 replies
BABetter Auth
Created by maito on 4/13/2025 in #help
Handling error of forgetPassword call
only in local dev though . It is a bit strange as it returns 204 in my case in prod but triggers onError callback. Does anyone knows why ?
8 replies
BABetter Auth
Created by maito on 4/13/2025 in #help
Handling error of forgetPassword call
I can throw custom error in hook:
if (ctx.path === "/forget-password") {
const validationResult = forgotPasswordSchema.safeParse(ctx.body);

if (!validationResult.success) {
console.log(validationResult.error.errors);
throw new APIError("BAD_REQUEST", {
message: validationResult.error.errors[0]?.message,
});
}

const dbUser = await db
.select()
.from(user)
.where(eq(user.email, ctx.body.email))
.then((r) => r[0]);

if (!dbUser) {
throw new APIError("NOT_FOUND", {
message: "Provided email is not registered",
});
}
}
if (ctx.path === "/forget-password") {
const validationResult = forgotPasswordSchema.safeParse(ctx.body);

if (!validationResult.success) {
console.log(validationResult.error.errors);
throw new APIError("BAD_REQUEST", {
message: validationResult.error.errors[0]?.message,
});
}

const dbUser = await db
.select()
.from(user)
.where(eq(user.email, ctx.body.email))
.then((r) => r[0]);

if (!dbUser) {
throw new APIError("NOT_FOUND", {
message: "Provided email is not registered",
});
}
}
And handle it on the client:
onError: async (ctx) => {
if (ctx.error.status === 429) {
toast(
<div className="flex flex-shrink-0 items-start gap-2 p-0">
<IconExclamationCircle className="h-full w-5 text-amber-500" />
<div className="flex flex-col gap-1">
<h6 className="text-sm">Too many Requests.</h6>
<p className="text-xs">
Please try again in couple minutes or contact support.
</p>
</div>
</div>,
{},
);
} else {
toast.error(ctx.error.message);
}
},
onError: async (ctx) => {
if (ctx.error.status === 429) {
toast(
<div className="flex flex-shrink-0 items-start gap-2 p-0">
<IconExclamationCircle className="h-full w-5 text-amber-500" />
<div className="flex flex-col gap-1">
<h6 className="text-sm">Too many Requests.</h6>
<p className="text-xs">
Please try again in couple minutes or contact support.
</p>
</div>
</div>,
{},
);
} else {
toast.error(ctx.error.message);
}
},
It displays the text of my error on the client in the toast
8 replies
BABetter Auth
Created by maito on 4/13/2025 in #help
Handling error of forgetPassword call
Rate limit is not applied to /forget-password path for some reason. Despite I have this custom rule: "/forget-password": { window: 300, max: 1, }, I can send as many 'forget password emails' as I want as long as I provide existing email
8 replies
BABetter Auth
Created by maito on 4/13/2025 in #help
Handling error of forgetPassword call
onError: (error) => {
toast.error(error.error.message);
},
onError: (error) => {
toast.error(error.error.message);
},
Has to be:
ts
onError: (ctx) => {
toast.error(ctx.error.message);
},
ts
onError: (ctx) => {
toast.error(ctx.error.message);
},
8 replies
BABetter Auth
Created by SxYxuse on 3/18/2025 in #help
Use auth on client or server (NEXTJS)
I believe this rate limit "bug" I described is already known, this is from docs: Server-side requests made using auth.api aren't affected by rate limiting. Rate limits only apply to client-initiated requests. When I call sign-in it calls send-verification-email from the server thats why send-verification's rate limit is not applied ?
13 replies
BABetter Auth
Created by SxYxuse on 3/18/2025 in #help
Use auth on client or server (NEXTJS)
Thank you. Somehow I missed this part , my bad 🤦‍♂️
13 replies
BABetter Auth
Created by SxYxuse on 3/18/2025 in #help
Use auth on client or server (NEXTJS)
I setup the sign-in with
requireEmailVerification: true
requireEmailVerification: true
and custom rate-limit
rateLimit: {
enabled: true,
customRules: {
"/sign-in/email": {
window: 120,
max: 5,
},
"/send-verification-email": {
window: 600,
max: 2,
},
}
rateLimit: {
enabled: true,
customRules: {
"/sign-in/email": {
window: 120,
max: 5,
},
"/send-verification-email": {
window: 600,
max: 2,
},
}
So when user signs-in it sends the verification email if user's email is not verified. So despite send-verification-email rate limit is much stricter it uses the sing-in/email rate limit and sends 5 emails in 120 s instead of 2 in 600s in my example. So send-verification-email ratelimit is only applied when this endpoint is called directly
13 replies
BABetter Auth
Created by SxYxuse on 3/18/2025 in #help
Use auth on client or server (NEXTJS)
I cannot do that in auth config:
export const auth = betterAuth({
database: drizzleAdapter(db, {
provider: "pg",
}),

emailAndPassword: {
enabled: true,
async sendResetPassword({ user, url, token }, request) {
console.log("Email being sent with url: ", url);
console.log("Email being sent to Email : ", user.email);
await sendForgotPassword(url, "[email protected]");
},

},
}
export const auth = betterAuth({
database: drizzleAdapter(db, {
provider: "pg",
}),

emailAndPassword: {
enabled: true,
async sendResetPassword({ user, url, token }, request) {
console.log("Email being sent with url: ", url);
console.log("Email being sent to Email : ", user.email);
await sendForgotPassword(url, "[email protected]");
},

},
}
Where shoul I do server-side stuff ?
13 replies
BABetter Auth
Created by SxYxuse on 3/18/2025 in #help
Use auth on client or server (NEXTJS)
How do I do server side validation of provided info during user sign-up/sign-in using authClient? How do I check for email being disposable? How do I set rate limits of my own (better-auth ones have bugs); How do I check if user is not trying to submit any harmful for db data bypassing the client validation ? Am I not understanding the design of better-auth properly? Could you clarify on these my concerns, please?
13 replies
BABetter Auth
Created by Glen Kurio on 4/10/2025 in #help
Server side validation
I have this in my action:
"use server";

import { validatedAction } from "@/lib/action-helpers";
import { auth } from "@/lib/auth";
import { signInSchema } from "@/lib/types";
import { headers } from "next/headers";
import { redirect } from "next/navigation";

export const loginEmail = validatedAction(signInSchema, async (data) => {
const { email, password } = data;

await auth.api.signInEmail({
body: { email, password },
});

redirect("/dashboard");
});
"use server";

import { validatedAction } from "@/lib/action-helpers";
import { auth } from "@/lib/auth";
import { signInSchema } from "@/lib/types";
import { headers } from "next/headers";
import { redirect } from "next/navigation";

export const loginEmail = validatedAction(signInSchema, async (data) => {
const { email, password } = data;

await auth.api.signInEmail({
body: { email, password },
});

redirect("/dashboard");
});
How do I handle all those errors it may return 429, 401, 403? auth.api.signInEmail does not return them. this is what it returns (assigned to 'result' variable)
const result: {
redirect: boolean;
token: string;
url: string | undefined;
user: {
id: string;
email: string;
name: string;
image: string | null | undefined;
emailVerified: boolean;
createdAt: Date;
updatedAt: Date;
};
}
const result: {
redirect: boolean;
token: string;
url: string | undefined;
user: {
id: string;
email: string;
name: string;
image: string | null | undefined;
emailVerified: boolean;
createdAt: Date;
updatedAt: Date;
};
}
18 replies
BABetter Auth
Created by Glen Kurio on 4/10/2025 in #help
Server side validation
Ok, but could you give me an example of how does it look in the code? Or is it somewhere in the docs ? Because I'm not following, sorry
18 replies
BABetter Auth
Created by Perchun_Pak on 4/6/2025 in #help
how to return more data from `/get-session`
If I'm not mistaken you don't need to create a custom plugin, all you need to do is to extend session with CustomSession built-in plugin:
import { customSession } from "better-auth/plugins";

export const auth = betterAuth({
plugins: [
customSession(async ({ user, session }) => {
const roles = findUserRoles(session.session.userId);
return {
roles,
user: {
...user,
newField: "newField",
},
session
};
}),
],
});
import { customSession } from "better-auth/plugins";

export const auth = betterAuth({
plugins: [
customSession(async ({ user, session }) => {
const roles = findUserRoles(session.session.userId);
return {
roles,
user: {
...user,
newField: "newField",
},
session
};
}),
],
});
Docs link to this: https://www.better-auth.com/docs/concepts/session-management#customizing-session-response
4 replies