Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
newme616 opened this issue Aug 8, 2023 · 14 comments
Closed

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

newme616 opened this issue Aug 8, 2023 · 14 comments

Comments

@newme616
Copy link

newme616 commented Aug 8, 2023

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/[email protected][email protected][email protected]/node_modules/next/dist/esm/server/web/globals.js (33)
Object.get
webpack-internal:///(middleware)/./node_modules/.pnpm/[email protected][email protected][email protected]/node_modules/next/dist/esm/server/web/globals.js (33:19)
eval
webpack-internal:///(middleware)/./node_modules/.pnpm/[email protected]/node_modules/nodemailer/lib/base64/index.js (43:27)
(middleware)/./node_modules/.pnpm/[email protected]/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/[email protected]/node_modules/nodemailer/lib/mime-funcs/index.js (3:16)
(middleware)/./node_modules/.pnpm/[email protected]/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/[email protected]/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": "[email protected]"
}
@0xHorace
Copy link

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

@amplicity
Copy link

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
Copy link

mundia416 commented Nov 1, 2023

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
Copy link

@mundia416 see #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
Copy link

maddo7 commented Nov 10, 2023

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
Copy link

Ran into this issue too. What a shame.

@leerob
Copy link
Member

leerob commented Nov 27, 2023

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.

@leerob leerob closed this as completed Nov 27, 2023
@jasny
Copy link

jasny commented Nov 29, 2023

@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
Copy link

jasny commented Dec 1, 2023

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?

@lexsemenenko
Copy link

Same issue here. Did anybody solve it with nodemailer?

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

@pixelcatgg
Copy link

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
Copy link

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
Copy link

raming commented Jan 16, 2024

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
Copy link

tomatac commented Feb 24, 2024

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)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests