reset-password not working with email link

Hi, For some reason, my reset password email is not working - I have this code:
import { resend } from "../mail";
import { EmailTemplate } from "@daveyplate/better-auth-ui/server";

...
sendResetPassword: async ({ user, url }) => {
const name = user.name || user.email.split("@")[0];
console.log("url", url);
await resend.emails.send({
from: "redacted",
to: user.email,
subject: "Reset your password",
react: EmailTemplate({
action: "Reset Password",
content: await ResetPasswordEmailTemplate({ name }),
heading: "Reset your password",
siteName: "redacted",
baseUrl: "redacted",
url,
}),
});
},
},
import { resend } from "../mail";
import { EmailTemplate } from "@daveyplate/better-auth-ui/server";

...
sendResetPassword: async ({ user, url }) => {
const name = user.name || user.email.split("@")[0];
console.log("url", url);
await resend.emails.send({
from: "redacted",
to: user.email,
subject: "Reset your password",
react: EmailTemplate({
action: "Reset Password",
content: await ResetPasswordEmailTemplate({ name }),
heading: "Reset your password",
siteName: "redacted",
baseUrl: "redacted",
url,
}),
});
},
},
in the email link I see http://localhost:8080/api/auth/reset-password/redacted_token?callbackURL=/reset-password but when i click the button I get a 404 and no redirect to the frontend. I did the same for email verification and that works fine
error: NOT_FOUND
status: 404,
code: "NOT_FOUND"

at NotFoundError (/Users/kevin/code/src/github/efnf/market/node_modules/elysia/src/error.ts:77:3)
error: NOT_FOUND
status: 404,
code: "NOT_FOUND"

at NotFoundError (/Users/kevin/code/src/github/efnf/market/node_modules/elysia/src/error.ts:77:3)
Interestingly enough I can hit the endpoint directly through the openapi spec. I am using this guide: https://better-auth-ui.com/components/email-template Am I missing something?
Better Auth UI
Better Auth UI
UI components for the most comprehensive authentication library for TypeScript.
No description
25 Replies
KiNFiSH
KiNFiSH3w ago
Are you using Elysia ?
bxr
bxrOP2w ago
yeah Bump @daveycodez have you come across this issue with tanstack start?
daveycodez
daveycodez2w ago
Hey does the route /auth/reset-password work for you? This might be a bug in Better Auth UI @bxr can you try updating better-auth-ui to v1.3.19
bxr
bxrOP2w ago
it returns invalid reset password link
bxr
bxrOP2w ago
but from the email it just says 404 the backend maybe having an issue idk the link http://localhost:8080/api/auth/reset-password/FmliNO7lmtwHS45DaxMurWMh?callbackURL=/reset-password not sure if the callback url should be different, verifying sends this link
http://localhost:8080/api/auth/verify-email?token=eyJhbGciOiJIUzI1NiJ9.eyJlbWFpbCI6Im1vay5rZXZpbjExQGdtYWlsLmNvbSIsImlhdCI6MTc0Mzg2NTc1MywiZXhwIjoxNzQzODY5MzUzfQ.V_otPyaepXdTLDTJWdoe3BA_CuA5Q2rQVJzCMtWNqSU&callbackURL=http://localhost:3000
http://localhost:8080/api/auth/verify-email?token=eyJhbGciOiJIUzI1NiJ9.eyJlbWFpbCI6Im1vay5rZXZpbjExQGdtYWlsLmNvbSIsImlhdCI6MTc0Mzg2NTc1MywiZXhwIjoxNzQzODY5MzUzfQ.V_otPyaepXdTLDTJWdoe3BA_CuA5Q2rQVJzCMtWNqSU&callbackURL=http://localhost:3000
and this callback is the frontend url
daveycodez
daveycodez2w ago
Your callback URL should be like this http://localhost:8080/api/auth/reset-password/FmliNO7lmtwHS45DaxMurWMh?callbackURL=/auth/reset-password Assuming you followed the guide and have your auth paths at /auth/sign-in etc Please update to latest better-auth-ui version pnpm install @daveyplate/better-auth-ui@latest
bxr
bxrOP2w ago
oh that's my bad, i had my routes in a _auth route so /_auth doesn't get appended i'll fix thanks
daveycodez
daveycodez2w ago
It's okay to do that but you have to set basePath on AuthUIProvider if you change it from /auth But that explains your 404 If you want domain.com/sign-in that is totally fine, just set basePath to "/" <AuthUIProvider basePath="/" >
bxr
bxrOP2w ago
still doesn't work. I think the 404 is coming from the backend service I had "" instead of "/" but still doesn't work
daveycodez
daveycodez2w ago
Did you install the latest build
bxr
bxrOP2w ago
Yeah my web app has 1.3.19
daveycodez
daveycodez2w ago
So is your sign-in /auth/sign-in ? or /sign-in ?
bxr
bxrOP2w ago
/sign-in so the link in the email's callback url is callbackurl=/reset-password
http://localhost:8080/api/auth/reset-password/sDFccxmjade4gpWTG0XnClyw?callbackURL=/reset-password
http://localhost:8080/api/auth/reset-password/sDFccxmjade4gpWTG0XnClyw?callbackURL=/reset-password
if i change it to
http://localhost:8080/api/auth/reset-password/sDFccxmjade4gpWTG0XnClyw?callbackURL=http://localhost:3000/reset-password
http://localhost:8080/api/auth/reset-password/sDFccxmjade4gpWTG0XnClyw?callbackURL=http://localhost:3000/reset-password
it works so, is there a way to adjust that? I guess I could adjust this url in the backend auth here, doesn't seem the cleanest way though
sendResetPassword: async ({ user, url }) => {
const name = user.name || user.email.split("@")[0];
console.log(url);
await resend.emails.send({
from: "eFNF <redacted>",
to: user.email,
subject: "Reset your password",
react: EmailTemplate({
action: "Reset Password",
content: await ResetPasswordEmailTemplate({ name }),
heading: "Reset your password",
siteName: "eFNF",
baseUrl: "redacted",
url,
}),
});
sendResetPassword: async ({ user, url }) => {
const name = user.name || user.email.split("@")[0];
console.log(url);
await resend.emails.send({
from: "eFNF <redacted>",
to: user.email,
subject: "Reset your password",
react: EmailTemplate({
action: "Reset Password",
content: await ResetPasswordEmailTemplate({ name }),
heading: "Reset your password",
siteName: "eFNF",
baseUrl: "redacted",
url,
}),
});
daveycodez
daveycodez2w ago
Ohh you have separate domains I can make a fix for you where you pass baseURL to AuthUIProvider Then you can pass localhost:3000 there and it'll use that for callBackURL Your bug is that http://localhost:8080/api/auth/reset-password/sDFccxmjade4gpWTG0XnClyw?callbackURL=/reset-password is sending you to :8080 instead of :3000 on the redirect
bxr
bxrOP2w ago
Yep correct, it's two different services. a separate backend from the frontend - i was surprised because verify email redirects to my frontend app with no issues yeah correct if you see the callback url from verify email:
http://localhost:8080/api/auth/verify-email?token=eyJhbGciOiJIUzI1NiJ9.eyJlbWFpbCI6Im1vay5rZXZpbjExQGdtYWlsLmNvbSIsImlhdCI6MTc0Mzg2NjMzMiwiZXhwIjoxNzQzODY5OTMyfQ.wrAguBEXowjsvwF28LVXStnFlv1NfNlfdpgMas66i4s&callbackURL=http://localhost:3000
http://localhost:8080/api/auth/verify-email?token=eyJhbGciOiJIUzI1NiJ9.eyJlbWFpbCI6Im1vay5rZXZpbjExQGdtYWlsLmNvbSIsImlhdCI6MTc0Mzg2NjMzMiwiZXhwIjoxNzQzODY5OTMyfQ.wrAguBEXowjsvwF28LVXStnFlv1NfNlfdpgMas66i4s&callbackURL=http://localhost:3000
its callback url is the other domain so not sure why that's different between both
daveycodez
daveycodez2w ago
It's because of how Better Auth UI works It passes relative URL to callbackURL. I can fix this by allowing you to pass baseURL prop. Do you have a process.env you use for current URL? Thanks for reporting this btw, totally flew under my radar I could just append window.location.origin To the beginning of callbackURL
bxr
bxrOP2w ago
I don't but I'm actually planning on that since some of my pages are ssr and wondle isn't available
daveycodez
daveycodez2w ago
I'll brainstorm a solution and I'll have a fix for you either later tonight or tomorrow Try basePath
<AuthUIProvider
basePath={`http://localhost:3000/auth`}
>
<AuthUIProvider
basePath={`http://localhost:3000/auth`}
>
If this works I'll update the docs with notes on this for multi-domain setups You'll need something like this. lib/utils.ts
export const baseURL = process.env.NODE_ENV === "production" ? "https://domain.com" : "http://localhost:3000"
export const baseURL = process.env.NODE_ENV === "production" ? "https://domain.com" : "http://localhost:3000"
then you can do
basePath={`${baseURL}/auth`}
basePath={`${baseURL}/auth`}
Or load it from .env variable If you're using http://localhost:3000/sign-in without /auth prefix route, then you can just do basePath={baseURL} in that case which would resolve to be basePath="http://localhost:3000" in dev for example
bxr
bxrOP2w ago
I see, this seemed to work for the email - but now after clicking the "send reset link" button from the forgot-password page, it redirects me here:
http://localhost:3000/forgot-password/http:/localhost:3000/sign-in
http://localhost:3000/forgot-password/http:/localhost:3000/sign-in
my basepath:
basePath="http://localhost:3000"
basePath="http://localhost:3000"
daveycodez
daveycodez2w ago
Darn okay so it creates another issue due to navigate prepending the base url on TanStack. It was working on Next so I’ll come up with something else
bxr
bxrOP2w ago
okay thanks! no worries, i can handle this issue on the backend for now - NBD
daveycodez
daveycodez2w ago
Hey try callbackURL So set basePath back to "/" then in your AuthCard this time, there is a callbackURL prop Not in the provider, on the auth page that renders AuthCard Set callbackURL to http://localhost:3000/callback wait actually one sec Yea this should do it oh wait actually hold on let me test it first There's some confusion because forgetPassword() accepts redirectTo but that gets changed to callbackURL Whereas something like signIn.magicLink() accepts callbackURL directly I'm assuming you're having issues with magic link as well? Yea so callbackURL there won't solve it I'm just going to add baseURL prop to authuiprovider I'll release the update in like an hr @bxr Okay I just released v1.3.21 which supports baseURL prop for AuthUIProvider For your use case do basePath="/" and baseURL="http://localhost:3000" make sure you also add http://localhost:3000 to your trustedOrigins
bxr
bxrOP2w ago
awesome, that worked 🙏 idk how to review better-auth besides providing a github star. But the support here is unmatched!
daveycodez
daveycodez2w ago
Heh I'm not technically a better-auth maintainer, my packages are third party But thanks 😄
bxr
bxrOP2w ago
INSANE welp kudos man!!

Did you find this page helpful?