MoralisWeb3 / Moralis-JS-SDK

Moralis Official Javascript SDK
https://docs.moralis.io
Other
368 stars 257 forks source link

Adding extra data field to Next Auth session object #940

Closed script8888 closed 1 year ago

script8888 commented 1 year ago

New Bug Report

Checklist

Issue Description

I am using Next Js and vercel In the old implementation of next-auth with Moralis as a provider, moralis v2.6.5, for auth with phantom wallet, I was able to add an extra data field called role to the session object. But with the new implementation here, https://docs.moralis.io/authentication-api/how-to-sign-in-with-solana-phantom-wallet, the same trick doesn't seem to work.

Steps + code to reproduce

Old implementation Which runs a request to /api/auth/request-message.js

import Moralis from "moralis";

//session expires in 7 days from now
const TIME = new Date();
const FUTURE = new Date(
  TIME.getFullYear(),
  TIME.getMonth(),
  TIME.getDate() + 1,
  TIME.getHours(),
  TIME.getMinutes(),
  TIME.getSeconds(),
  TIME.getMilliseconds()
);

const EXPIRATION_TIME = FUTURE.toISOString();
const NOT_BEFORE = TIME.toISOString();

const DOMAIN = process.env.APP_DOMAIN;
const STATEMENT = "welcome. sign this to confirm your identity, anon";
const URI = process.env.NEXTAUTH_URL || "http://localhost:3000";
const TIMEOUT = 30;

export default async function handler(req, res) {
  const { address, chain, network } = req.body;

  await Moralis.start({ apiKey: process.env.MORALIS_API });

  try {
    const message = await Moralis.Auth.requestMessage({
      address: address,
      solNetwork: chain,
      network: network,
      domain: DOMAIN,
      statement: STATEMENT,
      uri: URI,
      expirationTime: EXPIRATION_TIME,
      timeout: TIMEOUT,
      notBefore: NOT_BEFORE,
    });
    res.status(200).json(message);
  } catch (error) {
    res.status(400).json({ error });
  }
}

and from there the [...next-auth].js

import Moralis from "moralis";
import NextAuth from "next-auth";
import CredentialsProvider from "next-auth/providers/credentials";

export default NextAuth({
  session: {
    strategy: "jwt",
  },
  secret: process.env.NEXTAUTH_SECRET,
  //adding user info to the user session object
  callbacks: {
    async session({ token, session, user }) {
      session.expires = token.user.expirationTime;
      session.user = token.user;
      if (user?.role) session.user.role = user.role;
      return session;
    },
    async jwt({ token, user }) {
      user && (token.user = user);
      if (user?.role) token.role = user.role;

      return token;
    },
  },

  providers: [
    CredentialsProvider({
      name: "MoralisAuth",
      credentials: {
        message: {
          label: "Message",
          type: "text",
          placeholder: "0x0",
        },
        signature: {
          label: "Signature",
          type: "text",
          placeholder: "0x0",
        },
        role: {
          label: "Role",
          type: "text",
          placeholder: "0x0",
        },
      },
      async authorize(credentials) {
        try {
          await db.connect();
          const { message, signature, role } = credentials;
          await Moralis.start({ apiKey: process.env.MORALIS_API });

          const { address, network, profileId, expirationTime } = (
            await Moralis.Auth.verify({
              message,
              signature,
              network: "solana",
            })
          ).raw;

          const user = {
            address,
            network,
            profileId,
            expirationTime,
            signature,
            role,
          };

          return user;
        } catch (e) {
          console.error(e);
          return null;
        }
      },
    }),
  ],
});

and this is how I pass it in the signIn function on the frontend

//Code to get wallet details and sign message and signature
 await signIn("credentials", {
        message,
        signature,
        role,
        redirect: false,
      });

Actual Outcome

I encountered a TypeError: Converting circular structure to JSON from Moralis.Auth.requestMessage when using the Moralis library in production mode. My role data field was added to the session object as expected, but my env variables were accurate and the issue persisted. I sought help on the Discord and was recommended to try a new implementation.

Expected Outcome

I expected the new implementation with "@moralisweb3/next" to be able to accept extra data field in the session object

Environment

dev and production

Server

Client

Logs

For the old implementation which had aTypeError: Converting circular structure to JSON --> starting at object with constructor "ClientRequest", this is the log from vercel function logs

2023-01-04T09:10:55.467Z    4385a57f-162e-43ea-80a0-6cad52c1af3e    ERROR   TypeError: Converting circular structure to JSON
    --> starting at object with constructor 'ClientRequest'
    |     property 'socket' -> object with constructor 'TLSSocket'
    --- property '_httpMessage' closes the circle
    at JSON.stringify (<anonymous>)
    at sendJson (/var/task/node_modules/next/dist/server/api-utils/node.js:197:19)
    at apiRes.json (/var/task/node_modules/next/dist/server/api-utils/node.js:351:31)
    at handler (/var/task/.next/server/pages/api/auth/request-message.js:63:21)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async Object.apiResolver (/var/task/node_modules/next/dist/server/api-utils/node.js:367:9)
    at async NextNodeServer.runApi (/var/task/node_modules/next/dist/server/next-server.js:474:9)
    at async Object.fn (/var/task/node_modules/next/dist/server/next-server.js:736:37)
    at async Router.execute (/var/task/node_modules/next/dist/server/router.js:252:36)
    at async NextNodeServer.run (/var/task/node_modules/next/dist/server/base-server.js:384:29)
2023-01-04T09:10:55.468Z    4385a57f-162e-43ea-80a0-6cad52c1af3e    ERROR   TypeError: Converting circular structure to JSON
    --> starting at object with constructor 'ClientRequest'
    |     property 'socket' -> object with constructor 'TLSSocket'
    --- property '_httpMessage' closes the circle
    at JSON.stringify (<anonymous>)
    at sendJson (/var/task/node_modules/next/dist/server/api-utils/node.js:197:19)
    at apiRes.json (/var/task/node_modules/next/dist/server/api-utils/node.js:351:31)
    at handler (/var/task/.next/server/pages/api/auth/request-message.js:63:21)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async Object.apiResolver (/var/task/node_modules/next/dist/server/api-utils/node.js:367:9)
    at async NextNodeServer.runApi (/var/task/node_modules/next/dist/server/next-server.js:474:9)
    at async Object.fn (/var/task/node_modules/next/dist/server/next-server.js:736:37)
    at async Router.execute (/var/task/node_modules/next/dist/server/router.js:252:36)
    at async NextNodeServer.run (/var/task/node_modules/next/dist/server/base-server.js:384:29)
RequestId: 4385a57f-162e-43ea-80a0-6cad52c1af3e Error: Runtime exited with error: exit status 1
Runtime.ExitError
b4rtaz commented 1 year ago

We will add an extra parameter (payload) in the next version.

b4rtaz commented 1 year ago

@script8888 Please check the 2.11.1 version. You may look at this example.

Y0moo commented 1 year ago

Hey @script8888! As I can see the feature from @b4rtaz should solve your problem. The only thing I wanted to ask: Why do you set such sensitive information as "Role" from the client side?

script8888 commented 1 year ago

Im not using it to set the role I just need it for redirecting users

Y0moo commented 1 year ago

Hey @script8888! Is your problem resolved? Can we close the issue?

script8888 commented 1 year ago

Yes

On Wed, 1 Feb 2023 at 14:24, Dmitry Kapeliushnyi @.***> wrote:

Hey @script8888 https://github.com/script8888! Is your problem resolved? Can we close the issue?

— Reply to this email directly, view it on GitHub https://github.com/MoralisWeb3/Moralis-JS-SDK/issues/940#issuecomment-1412054859, or unsubscribe https://github.com/notifications/unsubscribe-auth/AMNJSERAWYHETCGUDGVCYJDWVJPZ7ANCNFSM6AAAAAATQR4WW4 . You are receiving this because you were mentioned.Message ID: @.***>