How to add link existing user account with google Oauth account with next-auth?

Viewed 871

Struggling to find a way to link an existing user with google oAuth using next-auth, here is my situation.

The flow is a bit odd for my case I believe; A user has the option to create a "Project" before registering. Basically they create a project and when they are ready they can "save the project". This will create a "Project" in my Mongo database as well as a user (without a password, this step is necessary to allow us to create generate a lead to sales with their information). Then once they have saved the project it takes them to a register modal where they can sign in using credentials or google Oauth.

So the issues it I am getting this error "OAuthAccountNotLinked" because the user email already exists in Mongo, I need the user to be unchanged because it is connected to the project they have already created. Therefore, when they use Google oAuth to sign in I need to link them with the user that's already been created.

I haven't found any good solutions to my issue at this, I'm relatively new to next-auth so any advice helps!!

Here is my next-auth file, not sure it will help much but let me know what might and I'll update.

const options = {
    providers: [
        Providers.Credentials({
            name: 'Custom Provider',
            credentials: {
                username: { label: 'Email', type: 'text', placeholder: 'username' },
                password: { label: 'Password', type: 'password', placeholder: 'password' }
            },
            async authorize(credentials) {
                try {
                    const res = await fetch(
                        `${
                            process.env.NODE_ENV === 'development'
                                ? process.env.NEXTAUTH_URL
                                : process.env.NEXTAUTH_URL_2
                        }/api/auth/signin`,
                        {
                            method: 'POST',
                            body: JSON.stringify(credentials)
                        }
                    );
                    const { user, error } = await res.json();
                    if (user) {
                        return Promise.resolve(user);
                    }
                    return Promise.reject(new Error(error));
                } catch (error) {
                    return undefined;
                }
            }
        }),
        Providers.Google({
            clientId: process.env.GOOGLE_ID,
            clientSecret: process.env.GOOGLE_SECRET
        })
    ],
    pages: {
        error: '/auth/error'
    },
    database: {
        type: 'mongodb',
        url: process.env.DATABASE_URL,
        ssl: true,
        // replicaSet: 'Cluster0-shard-0',
        authSource: 'admin',
        retryWrites: true,
        synchronize: true
    },
    secret: process.env.SECRET,
    session: { jwt: true, maxAge: 30 * 24 * 60 * 60 }, // 30 days
    jwt: { secret: process.env.JWT_SECRET },
    callbacks: {
        signIn: async (user, account, profile) => {
            return Promise.resolve(true);
        },
        redirect: async (url, baseUrl) => {
            if (url.startsWith(baseUrl)) {
                return Promise.resolve(url);
            }
            return Promise.resolve(baseUrl);
        },
        async session(session, token) {
            if (token.user) {
                session.user = token.user;
            }

            return session;
        },
        async jwt(token, user, account, profile, isNewUser) {
            if (user) {
                token.user = { _id: user._id, email: user.email, status: user.status, provider: 'credentials' };
            }
            if (account?.provider === 'google') {
                token.user = { _id: user.id, email: user.email, status: 'client', provider: 'google' };
            }

            return token;
        }
    },
    debug: false
};

export default (req, res) => NextAuth(req, res, options);

0 Answers
Related