Problems related to TypeScript in a callback session

I am currently working on enhancing the API response by adding the unique identifier (id) property during the login process. I followed the recommendation to use callbacks from a discussion on Stack Overflow (Get User ID from session in next-auth client), but encountered an error that seems to be related to TypeScript according to this GitHub thread (https://github.com/nextauthjs/next-auth/issues/7132). How can I address this issue? I want to get the id in my response and manipulate it later. Here is the current API response structure:

https://i.stack.imgur.com/uXICV.png

Error Found:

https://i.stack.imgur.com/iJxnB.png

The error seems to originate within the callback function:

callbacks: {
      session: async ({ session, token }) => {
        if (session?.user) {
          session.user.id = token.sub;
        }
        return session;
      },
      jwt: async ({ user, token }) => {
        if (user) {
          token.sub = user.id;
        }
        return token;
      },
  },

Next Auth Configuration File:

export const authOptions: NextAuthOptions = {
  adapter: PrismaAdapter(prisma as any),
  providers:[
    GoogleProvider({
      clientId: process.env.GOOGLE_CLIENT_ID!,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
    }),
    CredentialProvider({
      name: "credentials",
      credentials: {
        name: {label: "Name", type: "text", placeholder: "John Due"},
        email: {label: "Email", type: "text", placeholder: "jsmith"},
        password: {label: "Password", type: "password", placeholder: "password"},
      },
      async authorize(credentials, req): Promise<any>{
        console.log("Authorize method", credentials)
        
        if(!credentials?.email || !credentials?.password) throw new Error("Login data required")
        const user = await prisma.user.findUnique({
          where:{
            email: credentials?.email
          }
        })
        if(!user || !user.hashedPassword) {
          throw new Error("User not registered")
        }

        const matchPassword = await bcrypt.compare(credentials.password, user.hashedPassword);
        if(!matchPassword)
         throw new Error("Incorrect password")

        return user
      }
    })
  ],
  session: {
    strategy: "jwt",
    maxAge: 60 * 60,
  },
  jwt: { encode, decode },
  secret: process.env.NEXTAUTH_SECRET,
  callbacks: {
      session: async ({ session, token }) => {
        if (session?.user) {
          session.user.id = token.sub;
        }
        return session;
      },
      jwt: async ({ user, token }) => {
        if (user) {
          token.sub = user.id;
        }
        return token;
      },
  },
  debug: process.env.NODE_ENV === "development",
  pages: {
    signIn: "/dashboard"
  }
}
  • I went through the documentation of Next Auth, but couldn't find relevant details for this specific task.

Answer №1

You may be encountering a typescript error due to the fact that `session.user` does not inherently include a `userId`. To address this, consider extending the Session and JWT types in a custom next-auth declaration file (next-auth.d.ts):

import { EnumRole } from "@prisma/client"
import NextAuth, { DefaultSession } from "next-auth"
import { JWT } from "next-auth/jwt"
import { Provider } from "next-auth/providers"

declare module "next-auth" {
  interface Session extends DefaultSession {
    user: {
      id: string;
    } & DefaultSession["user"]
  }
}

declare module "next-auth/jwt" {
    interface JWT {
      sub: string;
    }
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Child component experiencing issues with Materialize Pagination and Sorting functionalities not functioning

New to materialize pagination and currently working on the hierarchy below: app modules > list > list.component app.component Implemented a sample code example in app.component which worked perfectly. However, encountered issues when trying to imp ...

Exporting components as the default from Next.js leads to a forced page refresh whenever there is a change

One issue I encountered involved having an index.tsx file containing all the shared UI components. When I exported the Footer and imported it into my shared Layout.tsx, which is utilized across all pages, the browser would refresh the page every time a cha ...

Unable to get the Angular Formly select option to bind

I'm currently working on binding formly select type options with the following code: fieldGroup: [ { key: 'TimeOffTypeID', type: 'select', className: 'flex-40 padding-10', templateOptions ...

Every time I click on a single button, all the text inputs get updated simultaneously

One issue I encountered is with a component featuring increment and decrement buttons. These buttons are meant to interact with specific products, yet when clicked, all text inputs update simultaneously instead of just the intended one. COMPONENT HTML: &l ...

Creating a grid UI in AngularJS using Typescript: utilizing functions as column values

I am working on an AngularJS app that includes the following UI grid: this.resultGrid = { enableRowSelection: true, enableRowHeaderSelection: false, enableHorizontalScrollbar: 0, enableSorting: true, columnDefs: [ { name: &apos ...

Is there a way to transfer data from a custom hook to a component seamlessly?

I am facing an issue with a custom hook that passes parameter data along with fetched data to the Settings component. Inside Settings, I have a hook called setData11 in useEffect and I am trying to set the data passed from useTable but encountering an er ...

Passing an ID via Link to retrieve data with getServerSideProps in Next.js

I have several alert components. From each of these components, I aim to pass the itm._id and receive it in [itm].jsx within the same folder. In [itm].jsx, I intend to utilize it in the getServerSideProps function for fetching data. Below is a snippet fro ...

Failed to establish RBAC with GoogleProvider

I am currently working on developing an application using NextJs with NextAuth. My goal is to implement GoogleProvider and have two distinct roles within the application, labeled as 'A' and 'B". As part of the user signup process, I wou ...

Retrieve an instance of the property class within a property decorator

I'm attempting to create a decorator called @Prop that will assist me in adjusting attributes for custom elements. This is the desired code: class MyCustomClass extends HtmlElement { get content() { return this.getAttribute('content&apo ...

Issue with NgFor nested component not refreshing after @Input modification

When populating a component called ContactUpdatableItem within a NgFor, the code looks like this: <section class="plContactCreation-listItem" *ngFor="let contact of contacts$ | async; index as idx" > <contact-updatable-item [c ...

The attribute 'body' cannot be found in the specified 'Request' type

Why does the req variable of type Request not show intellisense for the property body? Could this be related to typings? import { Request, Response } from 'express' import { ok, bad } from './responses' export const signIn: async (req ...

Updating User Roles with Prisma in Next JS

I am currently in the process of working with Next.js and Prisma as I develop an application for managing city councils. The purpose of this app is to allow the admin to create users, assign roles to them, and manage these roles for the city council employ ...

Using an image as a button in Vue.js: A step-by-step guide

I'm currently working on creating a login button within a single-file-component using Vue.js in my Rails application with a Vue.js front-end. The purpose of this button is to redirect users to an external login page when clicked. I am wondering how I ...

The Firebase application named `[DEFAULT]` has already been created with conflicting options or configurations

I am currently working on a project using NextJS, NextAuth, and Firebase. During the implementation of NextAuth, I came across this error message: Error - FirebaseError: Firebase: Firebase App named '[DEFAULT]' already exists with different op ...

Angular Project: Exploring Classes and Interfaces with and without the Export Keyword

Currently, I am delving into the world of Angular. I have taken up a video course and also referred to a PDF book, but I find myself perplexed when it comes to understanding the usage of the "export" keyword... The PDF course focuses on Angular 5 and util ...

utilizing adaptive image sizing in next.js with tailwindcss

Lately, I've noticed a lot of changes in the way next.js handles image sizing across different versions. Currently, I'm on version "next": "13.4.4", and I'm looking to create responsive images that take up 20% of the scre ...

Tips for retrieving items from <ng-template>:

When the loader is set to false, I am trying to access an element by ID that is located inside the <ng-template>. In the subscribe function, after the loader changes to false and my content is rendered, I attempt to access the 'gif-html' el ...

Setting up a Typescript class for seamless use in both Browser and Node applications

I developed a web app consisting of two separate projects, each housed in different folders with their own set of unique files. The client component is built using Angular 2 (RC-4) with SystemJS Typescript 1.8.10 (as per instructions found here). The serv ...

Limiting the Size of Highcharts Maps with maxWidth or maxHeight

My attempt to adjust the maxWidth of my world map using highcharts isn't altering its size. I have experimented with the following: responsive: { rules: [{ condition: { maxWidth: 500 }, ... As recomme ...

Unlocking the power of canonical URLs in Next.js with Automatic Static Optimization enabled

I am currently developing an SEO component that requires a canonical URL. Is there a way to obtain the URL of a static page in Next.js when Automatic Static Optimization is enabled? ...