vercel / ai-chatbot

A full-featured, hackable Next.js AI chatbot built by Vercel
https://chat.vercel.ai
Other
6.09k stars 1.88k forks source link

Can't get next-auth email provider to work with nodemailer #128

Closed newme616 closed 9 months ago

newme616 commented 1 year ago

Nodemailer seems to be not compatible with edge?

I get this error if I try to implement Email Provider in auth.ts.

Error:

Server Error
Error: The edge runtime does not support Node.js 'stream' module.
Learn More: https://nextjs.org/docs/messages/node-module-in-edge-runtime

This error happened while generating the page. Any console logs will be displayed in the terminal window.

Call Stack
<unknown>
webpack-internal:///(middleware)/./node_modules/.pnpm/next@13.4.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/esm/server/web/globals.js (33)
Object.get
webpack-internal:///(middleware)/./node_modules/.pnpm/next@13.4.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/esm/server/web/globals.js (33:19)
eval
webpack-internal:///(middleware)/./node_modules/.pnpm/nodemailer@6.9.4/node_modules/nodemailer/lib/base64/index.js (43:27)
(middleware)/./node_modules/.pnpm/nodemailer@6.9.4/node_modules/nodemailer/lib/base64/index.js
file:///Users/matthiasneumayer/Developer/DiamondHandsAI/vercel-ai/.next/server/middleware.js (701:1)
__webpack_require__
file:///Users/matthiasneumayer/Developer/DiamondHandsAI/vercel-ai/.next/server/edge-runtime-webpack.js (37:33)
fn
file:///Users/matthiasneumayer/Developer/DiamondHandsAI/vercel-ai/.next/server/edge-runtime-webpack.js (280:21)
eval
webpack-internal:///(middleware)/./node_modules/.pnpm/nodemailer@6.9.4/node_modules/nodemailer/lib/mime-funcs/index.js (3:16)
(middleware)/./node_modules/.pnpm/nodemailer@6.9.4/node_modules/nodemailer/lib/mime-funcs/index.js
file:///Users/matthiasneumayer/Developer/DiamondHandsAI/vercel-ai/.next/server/middleware.js (822:1)
__webpack_require__
file:///Users/matthiasneumayer/Developer/DiamondHandsAI/vercel-ai/.next/server/edge-runtime-webpack.js (37:33)
fn
file:///Users/matthiasneumayer/Developer/DiamondHandsAI/vercel-ai/.next/server/edge-runtime-webpack.js (280:21)
eval
webpack-internal:///(middleware)/./node_modules/.pnpm/nodemailer@6.9.4/node_modules/nodemailer/lib/mime-node/index.js (8:19)

Code:

import NextAuth, { type DefaultSession } from 'next-auth'
import GitHub from 'next-auth/providers/github'
import EmailProvider from 'next-auth/providers/email'

declare module 'next-auth' {
  interface Session {
    user: {
      /** The user's id. */
      id: string
    } & DefaultSession['user']
  }
}

export const {
  handlers: { GET, POST },
  auth,
  CSRF_experimental // will be removed in future
} = NextAuth({
  providers: [
    GitHub,
    // see https://next-auth.js.org/providers/email
    EmailProvider({
      server: process.env.EMAIL_SERVER,
      from: process.env.EMAIL_FROM
    })
  ],
  callbacks: {
    jwt({ token, profile }) {
      if (profile) {
        token.id = profile.id
        token.image = profile.picture
      }
      return token
    },
    authorized({ auth }) {
      return !!auth?.user // this ensures there is a logged in user for -every- request
    }
  },
  pages: {
    signIn: '/sign-in' // overrides the next-auth default signin page https://authjs.dev/guides/basics/pages
  }
})

package.json

{
  "name": "project-1",
  "version": "0.0.2",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint",
    "lint:fix": "next lint --fix",
    "preview": "next build && next start",
    "type-check": "tsc --noEmit",
    "format:write": "prettier --write \"{app,lib,components}/**/*.{ts,tsx,mdx}\" --cache",
    "format:check": "prettier --check \"{app,lib,components}**/*.{ts,tsx,mdx}\" --cache"
  },
  "dependencies": {
    "@radix-ui/react-alert-dialog": "^1.0.4",
    "@radix-ui/react-dialog": "^1.0.4",
    "@radix-ui/react-dropdown-menu": "^2.0.5",
    "@radix-ui/react-label": "^2.0.2",
    "@radix-ui/react-select": "^1.2.2",
    "@radix-ui/react-separator": "^1.0.3",
    "@radix-ui/react-slot": "^1.0.2",
    "@radix-ui/react-switch": "^1.0.3",
    "@radix-ui/react-tooltip": "^1.0.6",
    "@vercel/analytics": "^1.0.0",
    "@vercel/kv": "^0.2.1",
    "@vercel/og": "^0.5.7",
    "ai": "^2.1.21",
    "axios": "^1.4.0",
    "class-variance-authority": "^0.4.0",
    "clsx": "^1.2.1",
    "date-fns": "^2.30.0",
    "focus-trap-react": "^10.1.1",
    "langchain": "^0.0.110",
    "nanoid": "^4.0.2",
    "next": "13.4.7",
    "next-auth": "0.0.0-manual.83c4ebd1",
    "next-themes": "^0.2.1",
    "nodemailer": "^6.9.4",
    "openai": "3.3.0",
    "openai-edge": "^1.2.0",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-hot-toast": "^2.4.1",
    "react-intersection-observer": "^9.4.4",
    "react-markdown": "^8.0.7",
    "react-syntax-highlighter": "^15.5.0",
    "react-textarea-autosize": "^8.4.1",
    "remark-gfm": "^3.0.1",
    "remark-math": "^5.1.1"
  },
  "devDependencies": {
    "@tailwindcss/typography": "^0.5.9",
    "@types/node": "^17.0.45",
    "@types/react": "^18.2.15",
    "@types/react-dom": "^18.2.7",
    "@types/react-syntax-highlighter": "^15.5.7",
    "@typescript-eslint/parser": "^5.62.0",
    "autoprefixer": "^10.4.14",
    "eslint": "^8.45.0",
    "eslint-config-next": "13.4.7-canary.1",
    "eslint-config-prettier": "^8.8.0",
    "eslint-plugin-tailwindcss": "^3.13.0",
    "postcss": "^8.4.26",
    "prettier": "^2.8.8",
    "tailwind-merge": "^1.14.0",
    "tailwindcss": "^3.3.3",
    "tailwindcss-animate": "^1.0.6",
    "typescript": "^5.1.6"
  },
  "pnpm": {
    "overrides": {
      "oidc-token-hash": "5.0.1"
    }
  },
  "packageManager": "pnpm@8.6.3"
}
0xHorace commented 1 year ago

I've also been having next-auth issues and just made #133 documenting mine, maybe ours are similar?

amplicity commented 1 year ago

I have the same issue. I don't think EmailProvider supports edge, which makes this implementation challenging because tmk, middleware.ts must be run in edge.

An example using EmailProvider in this repo would be great to see.

mundia416 commented 10 months ago

Facing the exact same issue using "next-auth": "5.0.0-beta.3"

 ⨯ ./node_modules/nodemailer/lib/base64/index.js:3:18
Module not found: Can't resolve 'stream'

https://nextjs.org/docs/messages/module-not-found

Import trace for requested module:
./node_modules/nodemailer/lib/mime-node/index.js
./node_modules/nodemailer/lib/mail-composer/index.js
./node_modules/nodemailer/lib/mailer/index.js
./node_modules/nodemailer/lib/nodemailer.js
./node_modules/@auth/core/providers/email.js
./node_modules/next-auth/providers/email.js

is there a fix for this?

amplicity commented 10 months ago

@mundia416 see https://github.com/vercel-labs/ai-chatbot/issues/133 for hack-around solution. Not ideal, but I believe you can get it to work by using the mentioned manual next-auth release.

maddo7 commented 10 months ago

Does email work at all with this? When I add import EmailProvider from "next-auth/providers/email"; to auth.ts and

 EmailProvider({
      server: process.env.EMAIL_SERVER,
      from: process.env.EMAIL_FROM
    }),

To the providers, I get

Type 'EmailConfig' is not assignable to type 'Provider'.
  Type 'EmailConfig' is not assignable to type 'EmailConfig & InternalProviderOptions'.
    Type 'EmailConfig' is not assignable to type 'InternalProviderOptions'.
      Types of property 'options' are incompatible.
        Type 'EmailUserConfig' is not assignable to type 'Record<string, unknown>'.
          Index signature for type 'string' is missing in type 'EmailUserConfig'.
huotarih commented 10 months ago

Ran into this issue too. What a shame.

leerob commented 9 months ago

Let's continue this conversation on the NextAuth.js repo – this template won't be adding nodemailer, and sounds like a more general question around integrating those two together. Thank you.

jasny commented 9 months ago

@maddo7 It seems like a typing issue only, so you can force the typing.

 EmailProvider({
      server: process.env.EMAIL_SERVER,
      from: process.env.EMAIL_FROM
    }) as EmailConfig & { options: Record<string, unknown> },
jasny commented 9 months ago

As a (temporary) solution, you can render everything server side instead of on edge.


@leerob Can you link to the topic on the nextauth.js repo where this is discussed?

lexsemenenko commented 9 months ago

Same issue here. Did anybody solve it with nodemailer?

Server Error Error: The edge runtime does not support Node.js 'stream' module.

pixelcatgg commented 9 months ago

For what its worth I made it work by implementing an HTTP based email provider: https://next-auth.js.org/tutorials/securing-pages-and-api-routes

my providers:

  providers: [
    Discord,
    Google({
      clientId: env.AUTH_GOOGLE_CLIENT_ID,
      clientSecret: env.AUTH_GOOGLE_CLIENT_SECRET,
    }),
    Facebook({
      clientId: env.AUTH_FACEBOOK_CLIENT_ID,
      clientSecret: env.AUTH_FACEBOOK_CLIENT_SECRET,
    }),
    {
      id: "sendgrid",
      type: "email",
           async sendVerificationRequest({identifier: email, url}) {
// your code here to send the email
      },
    },
  ],

Then the middleware worked

fcanmekikoglu commented 8 months ago

As a (temporary) solution, you can render everything server side instead of on edge.

  • Remove middleware.ts.
  • Find and remove the following line in all files in the app directory:
    export const runtime = 'edge'

@leerob Can you link to the topic on the nextauth.js repo where this is discussed?

how would you protect routes if there is no middleware provided

raming commented 8 months ago

I fixed this by having two auth configurations, one for auth-client and another for auth-server. The configurations that are critical to the server, like EmailProvider, are put into auth-server. which makes sense; those details are sensitive and should not be exposed to the client. You need to then go to all pages (like the api folder, etc.) that need server-side auth verification and point to auth-server. In my case both auth-server and auth-client look the same except the EmailProvider and possibly other configurations.

tomatac commented 6 months ago

For what its worth I made it work by implementing an HTTP based email provider: https://next-auth.js.org/tutorials/securing-pages-and-api-routes

my providers:

  providers: [
    Discord,
    Google({
      clientId: env.AUTH_GOOGLE_CLIENT_ID,
      clientSecret: env.AUTH_GOOGLE_CLIENT_SECRET,
    }),
    Facebook({
      clientId: env.AUTH_FACEBOOK_CLIENT_ID,
      clientSecret: env.AUTH_FACEBOOK_CLIENT_SECRET,
    }),
    {
      id: "sendgrid",
      type: "email",
           async sendVerificationRequest({identifier: email, url}) {
// your code here to send the email
      },
    },
  ],

Then the middleware worked

pixelcatgg, did you end up making it work with an HTTP based email provider? I get Type '"email"' is not assignable to type '"credentials" | "oidc" | "oauth"'.ts(2322)