Next.js Discord

Discord Forum

Email confirmation link

Unanswered
Asian black bear posted this in #help-forum
Open in Discord
Asian black bearOP
so i want to know if user came to page /confirmed using email link or just typing it by himself, can i do it?

115 Replies

Asian black bearOP
Basically, when user registers on website it sends him a confirmation link which redirects to /confirmed page, but i wanna check if use came from the email or just typed this page
So they cant just do ...com/confirmed
ping just in case @Anay-208 | Ping in replies
In email message, you can perhaps add some query like ?utm_source=email, I believe there is no specific way to verify it
Asian black bearOP
Yes
If you're sending magic links, you're supposed to include tokens in the link you sent them so you can actually verify the request is authorized
Asian black bearOP
Yes there is magic link
I see you are new at Auth. I highly recommend you to use something like better-auth or authjs
Asian black bearOP
Can i connect those to supabase?
yes
supabase is just postgres, so yes
recommend better-auth: https://www.better-auth.com/
Asian black bearOP
Ok ill try it out
And let you know
Asian black bearOP
Btw does better auth have password hashing?
yes, it automatically does that
@Anay-208 | Ping in replies yes, it automatically does that
Asian black bearOP
another question, im trying to setup sign-up, does it send an email after i submit it?
@Asian black bear another question, im trying to setup sign-up, does it send an email after i submit it?
if you've enabled magic Link, you've to create a send verification link function
@Anay-208 | Ping in replies if you've enabled magic Link, you've to create a send verification link function
Asian black bearOP
do i need to give name when registering a user?
You can enable it if needed
IIRC its not necessary
Asian black bearOP
Argument of type '{ email: string; password: string; }' is not assignable to parameter of type 'Prettify<{ email: string; name: string; password: string; image?: string | undefined; callbackURL?: string | undefined; fetchOptions?: { method?: string | undefined; headers?: (HeadersInit & (HeadersInit | CommonHeaders)) | undefined; ... 33 more ...; disableValidation?: boolean | undefined; } | undefined; }>'.

how do i disable it then
Asian black bearOP
@Anay-208 | Ping in replies
Can you share your code + config
@Anay-208 | Ping in replies Can you share your code + config
Asian black bearOP
auth or authClient?
both
Asian black bearOP
import { betterAuth } from "better-auth";
import { Pool } from "pg";

export const auth = betterAuth({
    database: new Pool({
        connectionString: process.env.DATABASE_URL,
    }),
    secret: process.env.BETTER_AUTH_SECRET,
    emailAndPassword: { enabled: true },
    
});
import { createAuthClient } from "better-auth/react";

export const authClient = createAuthClient({
    baseURL: process.env.BETTER_AUTH_URL,
});

export const { signUp, signIn, signOut, useSession } = authClient;
Ah it seems to be required for emailAndPassword
for magic link it doesn't seem to be required
youc an just put this as empty string if it works or "NA"
Asian black bearOP
ok
@Anay-208 | Ping in replies youc an just put this as empty string if it works or `"NA"`
Asian black bearOP
can i send magic link from onSuccess or it has to be in setup?
import { signUp } from "./auth-client";

export async function register(email: string, password: string) {
    const { data, error } = await signUp.email({
        email,
        password,
        name: "",
    }, {
        onSuccess: (ctx) => {}
    })
}
Refer to this docs for magic links: https://www.better-auth.com/docs/plugins/magic-link
Asian black bearOP
that means no ig
@Anay-208 | Ping in replies Refer to this docs for magic links: https://www.better-auth.com/docs/plugins/magic-link
Asian black bearOP
and should i sign in/up through client or server, what would be better
client
@Anay-208 | Ping in replies client
Asian black bearOP
so another question, is magic link the think that allows you to login or it confirms your registration like on supabase auth
I haven't used supabase auth so idk
@Anay-208 | Ping in replies I haven't used supabase auth so idk
Asian black bearOP
i want it to be like confirm your email by clicking link below
Asian black bearOP
ok im trying to catch error "Sign-up for existing email" because it sends it into server console
and i need to show it to user
@Asian black bear ok im trying to catch error "Sign-up for existing email" because it sends it into server console
I don't think there should be any difference for signing up, can you send screenshot
@Anay-208 | Ping in replies I don't think there should be any difference for signing up, can you send screenshot
Asian black bearOP
ok uhm for some reason its not sending it anymore, but i get "{status: 404, statusText: 'Not Found'}" as response in client console
Asian black bearOP
for some reason its trying to fetch route that doesnt exist
POST /api/auth/sign-up/email 404 in 106ms
try restarting dev server once, and make sure you've added auth routes
@Anay-208 | Ping in replies try restarting dev server once, and make sure you've added auth routes
Asian black bearOP
But why do i need them when i register on client
The client needs to connect to the server which connects to the database
@Anay-208 | Ping in replies The client needs to connect to the server which connects to the database
Asian black bearOP
then what do i need in the route
what typeof code
import { authClient } from "./auth-client";

export async function register(email: string, password: string) {
    const { data, error } = await authClient.signUp.email({
        email,
        password,
        name: "",
    });

    return { data, error };
}
cuz my register function already does this
@Anay-208 | Ping in replies Please refer to better-auth guides on implementation
Asian black bearOP
There is nothing about register function
https://www.better-auth.com/docs/plugins/magic-link

there is different code depending on whether you are executing it on client or server
and authClient is supposed to be used on client
@Anay-208 | Ping in replies and `authClient` is supposed to be used on client
Asian black bearOP
But the function by itself is used on client
Or do i add 'use client' there
Asian black bearOP
well ig i fixed that
ill let know if i have any more issues
Asian black bearOP
@Anay-208 | Ping in replies where can i find all error codes
What error you get?
@Anay-208 | Ping in replies What error you get?
Asian black bearOP
None, im just trying to prevent invalid emails for example
invalid emails?
@Anay-208 | Ping in replies invalid emails?
Asian black bearOP
like if user typed 123@gmail.jdsjjs
if the email is invalid then no one will get the link so no one can verify the email, that's about it
you don't need to manually detect invalid emails
you just need to send the email and see if the user manages to verify their emails, if not you can suspend their account or otherwise restrict the account until they provide a valid email that they can verify
Asian black bearOP
Oh i see
Forgot i can do it that way
Asian black bearOP
@Anay-208 | Ping in replies how can i check if user exists in the database?
is there a function in better-auth or i have to do it myself
I guess you’ll have to directly query the database
Asian black bearOP
how do i access the Pool from auth then
this pool
export const auth = betterAuth({
    database: new Pool({
        connectionString: process.env.DATABASE_URL,
    }),
Asian black bearOP
nvm i fixed it
Asian black bearOP
@Anay-208 | Ping in replies where do i change callback url in verification process?
i could only find it here
await authClient.sendVerificationEmail({
    email: "user@email.com",
    callbackURL: "/" // The redirect URL after verification
})
Asian black bearOP
not really
can you do it from here
sendVerificationEmail: async ({ user, url, token }) => {
            const res = await fetch("http://localhost:3000/api/email/send", {
                method: "POST",
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({
                    to: user.email,
                    url,
                }),
            });

            if (!res.ok) {
                console.error(await res.text());
            }
        },
i dont wanna manually call it
why are you creating a api route for it?
This way, any client could send an email
just move the code in /api/email/send/route.ts to this function
Asian black bearOP
ok
but can i change callback url through this
@Anay-208 | Ping in replies Isn't this working for you?
Asian black bearOP
im not using it
im using the other method
@Asian black bear im using the other method
Can you specify the method
It'll just cause additional function calls increasing costs
And a security vulnerability that it is being exposed to the client side, so anyone can send the email
and you've to also send the token to verify it
@Anay-208 | Ping in replies Why are you using this method
Asian black bearOP
no i changed the email sending, i just have this function sendVerificationEmail in auth instead of calling it manually
Asian black bearOP
import { betterAuth } from "better-auth";
import { transporter } from "./email";
import { Pool } from "pg";

const pool = new Pool({
    connectionString: process.env.DATABASE_URL,
})

export const auth = betterAuth({
    database: pool,
    secret: process.env.BETTER_AUTH_SECRET,
    emailAndPassword: {
        enabled: true,
        autoSignIn: false,
        requireEmailVerification: true,
    },
    emailVerification: {
        sendOnSignUp: true,
        sendOnSignIn: false,
        autoSignInAfterVerification: true,
        sendVerificationEmail: async ({ user, url, token }) => {
             try {
                const info = await transporter.sendMail({
                    from: '"Test App" <my email i wont leak@gmail.com>',
                    to: user.email,
                    subject: 'Test',
                    text: "tester",
                    html: `<p>Cool URL: ${url}</p>`,
                });
                
                console.log("✅ Email sent:", info.messageId);
            } catch (err) {
                console.error(err);
            }
        },
    }
});
Asian black bearOP
but i dont need after
Umm, verification is required to actually verify the user email
I highly recommend you to watch a in depth video about Auth and its flow, and using better-auth
@Anay-208 | Ping in replies Umm, verification is required to actually verify the user email
Asian black bearOP
But is there no like redirect link
in the sendVerificationEmail function, better-auth provides a argument url
Oh you don't need a callback url
Asian black bearOP
@Anay-208 | Ping in replies hello, how can i get users id stored in my database when they sign in into the system?
@Asian black bear <@755810867878297610> hello, how can i get users id stored in my database when they sign in into the system?
Cape lion
you should start reading through the better auth docs. it’s all explained in there.
Asian black bearOP
i found it