Repository: nextauthjs/next-auth Branch: main Commit: f45706836760 Files: 1094 Total size: 2.7 MB Directory structure: gitextract_vbasb9xy/ ├── .dockerignore ├── .github/ │ ├── CODEOWNERS │ ├── DISCUSSION_TEMPLATE/ │ │ ├── ideas.yml │ │ └── questions.yml │ ├── ISSUE_TEMPLATE/ │ │ ├── 1_bug_framework.yml │ │ ├── 2_bug_provider.yml │ │ ├── 3_bug_adapter.yml │ │ ├── 4_documentation.yml │ │ └── config.yml │ ├── PULL_REQUEST_TEMPLATE.md │ ├── broken-link-checker/ │ │ ├── action.yml │ │ ├── index.d.ts │ │ ├── package.json │ │ ├── src/ │ │ │ └── index.ts │ │ └── tsconfig.json │ ├── dependabot.yml │ ├── good-first-issue.md │ ├── help-needed.md │ ├── invalid-reproduction.md │ ├── pr-labeler.yml │ ├── stale.yml │ ├── sync.yml │ ├── version-pr/ │ │ ├── action.yml │ │ └── index.js │ └── workflows/ │ ├── broken-link-checker.yml │ ├── codeql-analysis.yml │ ├── pr-labeler.yml │ ├── release.yml │ ├── sync-examples.yml │ └── triage.yml ├── .gitignore ├── .nvmrc ├── .prettierignore ├── .vscode/ │ ├── extensions.json │ ├── settings.json │ └── snippets.code-snippets ├── LICENSE ├── README.md ├── apps/ │ ├── dev/ │ │ ├── express/ │ │ │ ├── .gitignore │ │ │ ├── .prettierignore │ │ │ ├── README.md │ │ │ ├── api/ │ │ │ │ └── index.js │ │ │ ├── package.json │ │ │ ├── public/ │ │ │ │ └── css/ │ │ │ │ └── style.css │ │ │ ├── src/ │ │ │ │ ├── app.ts │ │ │ │ ├── config/ │ │ │ │ │ └── auth.config.ts │ │ │ │ ├── errors.ts │ │ │ │ ├── middleware/ │ │ │ │ │ ├── auth.middleware.ts │ │ │ │ │ └── error.middleware.ts │ │ │ │ └── server.ts │ │ │ ├── tsconfig.json │ │ │ └── views/ │ │ │ ├── error.pug │ │ │ ├── index.pug │ │ │ ├── layout.pug │ │ │ └── protected.pug │ │ ├── nextjs/ │ │ │ ├── .gitignore │ │ │ ├── .vscode/ │ │ │ │ └── settings.json │ │ │ ├── README.md │ │ │ ├── app/ │ │ │ │ ├── api/ │ │ │ │ │ └── protected/ │ │ │ │ │ └── route.ts │ │ │ │ ├── auth/ │ │ │ │ │ └── [...nextauth]/ │ │ │ │ │ └── route.ts │ │ │ │ ├── client.tsx │ │ │ │ ├── dashboard/ │ │ │ │ │ └── page.tsx │ │ │ │ ├── layout.tsx │ │ │ │ ├── page.tsx │ │ │ │ └── styles.css │ │ │ ├── auth.ts │ │ │ ├── components/ │ │ │ │ ├── access-denied.tsx │ │ │ │ ├── footer.module.css │ │ │ │ ├── footer.tsx │ │ │ │ ├── header.module.css │ │ │ │ └── header.tsx │ │ │ ├── middleware.ts │ │ │ ├── next-env.d.ts │ │ │ ├── next.config.js │ │ │ ├── package.json │ │ │ ├── pages/ │ │ │ │ ├── _app.tsx │ │ │ │ ├── api/ │ │ │ │ │ └── examples/ │ │ │ │ │ ├── protected.ts │ │ │ │ │ └── session.ts │ │ │ │ ├── client.tsx │ │ │ │ ├── credentials.tsx │ │ │ │ ├── email.tsx │ │ │ │ ├── policy.tsx │ │ │ │ ├── protected-ssr.tsx │ │ │ │ ├── protected.tsx │ │ │ │ └── styles.css │ │ │ ├── prisma/ │ │ │ │ ├── migrations/ │ │ │ │ │ ├── 20231023165117_/ │ │ │ │ │ │ └── migration.sql │ │ │ │ │ ├── 20240124035029_init/ │ │ │ │ │ │ └── migration.sql │ │ │ │ │ └── migration_lock.toml │ │ │ │ └── schema.prisma │ │ │ ├── tests/ │ │ │ │ └── signin.spec.ts │ │ │ └── tsconfig.json │ │ ├── qwik/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── package.json │ │ │ ├── public/ │ │ │ │ ├── manifest.json │ │ │ │ └── robots.txt │ │ │ ├── qwik.env.d.ts │ │ │ ├── src/ │ │ │ │ ├── components/ │ │ │ │ │ └── router-head/ │ │ │ │ │ └── router-head.tsx │ │ │ │ ├── entry.dev.tsx │ │ │ │ ├── entry.preview.tsx │ │ │ │ ├── entry.ssr.tsx │ │ │ │ ├── global.css │ │ │ │ ├── root.tsx │ │ │ │ └── routes/ │ │ │ │ ├── index.tsx │ │ │ │ ├── layout.tsx │ │ │ │ ├── plugin@auth.ts │ │ │ │ └── service-worker.ts │ │ │ ├── tsconfig.json │ │ │ └── vite.config.ts │ │ └── sveltekit/ │ │ ├── .env.example │ │ ├── .eslintignore │ │ ├── .eslintrc.cjs │ │ ├── .gitignore │ │ ├── .prettierignore │ │ ├── .prettierrc │ │ ├── README.md │ │ ├── package.json │ │ ├── src/ │ │ │ ├── app.d.ts │ │ │ ├── app.html │ │ │ ├── auth.ts │ │ │ ├── components/ │ │ │ │ └── header.svelte │ │ │ ├── hooks.server.ts │ │ │ ├── routes/ │ │ │ │ ├── +layout.server.ts │ │ │ │ ├── +layout.svelte │ │ │ │ ├── +page.svelte │ │ │ │ ├── protected/ │ │ │ │ │ └── +page.svelte │ │ │ │ ├── signin/ │ │ │ │ │ └── +page.server.ts │ │ │ │ └── signout/ │ │ │ │ └── +page.server.ts │ │ │ └── style.css │ │ ├── svelte.config.js │ │ ├── tsconfig.json │ │ └── vite.config.js │ ├── examples/ │ │ ├── express/ │ │ │ ├── .eslintrc.cjs │ │ │ ├── .gitignore │ │ │ ├── .prettierignore │ │ │ ├── .prettierrc │ │ │ ├── README.md │ │ │ ├── api/ │ │ │ │ └── index.js │ │ │ ├── package.json │ │ │ ├── public/ │ │ │ │ └── css/ │ │ │ │ └── style.css │ │ │ ├── src/ │ │ │ │ ├── app.ts │ │ │ │ ├── config/ │ │ │ │ │ └── auth.config.ts │ │ │ │ ├── errors.ts │ │ │ │ ├── middleware/ │ │ │ │ │ ├── auth.middleware.ts │ │ │ │ │ └── error.middleware.ts │ │ │ │ └── server.ts │ │ │ ├── tailwind.config.js │ │ │ ├── tsconfig.json │ │ │ ├── types/ │ │ │ │ └── express/ │ │ │ │ └── index.d.ts │ │ │ ├── vercel.json │ │ │ └── views/ │ │ │ ├── error.pug │ │ │ ├── index.pug │ │ │ ├── layout.pug │ │ │ └── protected.pug │ │ ├── nextjs/ │ │ │ ├── .gitignore │ │ │ ├── Dockerfile │ │ │ ├── README.md │ │ │ ├── app/ │ │ │ │ ├── [...proxy]/ │ │ │ │ │ └── route.tsx │ │ │ │ ├── api/ │ │ │ │ │ └── protected/ │ │ │ │ │ └── route.ts │ │ │ │ ├── api-example/ │ │ │ │ │ └── page.tsx │ │ │ │ ├── auth/ │ │ │ │ │ └── [...nextauth]/ │ │ │ │ │ └── route.ts │ │ │ │ ├── client-example/ │ │ │ │ │ └── page.tsx │ │ │ │ ├── globals.css │ │ │ │ ├── layout.tsx │ │ │ │ ├── middleware-example/ │ │ │ │ │ └── page.tsx │ │ │ │ ├── page.tsx │ │ │ │ ├── policy/ │ │ │ │ │ └── page.tsx │ │ │ │ └── server-example/ │ │ │ │ └── page.tsx │ │ │ ├── auth.ts │ │ │ ├── components/ │ │ │ │ ├── auth-components.tsx │ │ │ │ ├── client-example.tsx │ │ │ │ ├── custom-link.tsx │ │ │ │ ├── footer.tsx │ │ │ │ ├── header.tsx │ │ │ │ ├── main-nav.tsx │ │ │ │ ├── session-data.tsx │ │ │ │ ├── ui/ │ │ │ │ │ ├── avatar.tsx │ │ │ │ │ ├── button.tsx │ │ │ │ │ ├── dropdown-menu.tsx │ │ │ │ │ ├── input.tsx │ │ │ │ │ └── navigation-menu.tsx │ │ │ │ └── user-button.tsx │ │ │ ├── components.json │ │ │ ├── docker-compose.yml │ │ │ ├── lib/ │ │ │ │ └── utils.ts │ │ │ ├── middleware.ts │ │ │ ├── next.config.js │ │ │ ├── package.json │ │ │ ├── postcss.config.js │ │ │ ├── tailwind.config.js │ │ │ ├── test-docker.sh │ │ │ └── tsconfig.json │ │ ├── nextjs-pages/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── app/ │ │ │ │ └── api/ │ │ │ │ └── auth/ │ │ │ │ └── [...nextauth]/ │ │ │ │ └── route.ts │ │ │ ├── auth.ts │ │ │ ├── components/ │ │ │ │ ├── auth-components.tsx │ │ │ │ ├── client-example.tsx │ │ │ │ ├── custom-link.tsx │ │ │ │ ├── footer.tsx │ │ │ │ ├── header.tsx │ │ │ │ ├── main-nav.tsx │ │ │ │ ├── session-data.tsx │ │ │ │ ├── ui/ │ │ │ │ │ ├── avatar.tsx │ │ │ │ │ ├── button.tsx │ │ │ │ │ ├── dropdown-menu.tsx │ │ │ │ │ ├── input.tsx │ │ │ │ │ └── navigation-menu.tsx │ │ │ │ └── user-button.tsx │ │ │ ├── components.json │ │ │ ├── lib/ │ │ │ │ └── utils.ts │ │ │ ├── middleware.ts │ │ │ ├── next.config.js │ │ │ ├── package.json │ │ │ ├── pages/ │ │ │ │ ├── _app.tsx │ │ │ │ ├── api/ │ │ │ │ │ └── protected.ts │ │ │ │ ├── api-example/ │ │ │ │ │ └── index.tsx │ │ │ │ ├── client-example/ │ │ │ │ │ └── index.tsx │ │ │ │ ├── globals.css │ │ │ │ ├── index.tsx │ │ │ │ ├── middleware-example/ │ │ │ │ │ └── index.tsx │ │ │ │ ├── policy/ │ │ │ │ │ └── index.tsx │ │ │ │ └── server-example/ │ │ │ │ └── index.tsx │ │ │ ├── postcss.config.js │ │ │ ├── tailwind.config.js │ │ │ └── tsconfig.json │ │ ├── qwik/ │ │ │ ├── .eslintignore │ │ │ ├── .eslintrc.cjs │ │ │ ├── .gitignore │ │ │ ├── .prettierignore │ │ │ ├── .prettierrc.js │ │ │ ├── .vscode/ │ │ │ │ ├── launch.json │ │ │ │ ├── qwik-city.code-snippets │ │ │ │ └── qwik.code-snippets │ │ │ ├── README.md │ │ │ ├── adapters/ │ │ │ │ └── vercel-edge/ │ │ │ │ └── vite.config.ts │ │ │ ├── package.json │ │ │ ├── postcss.config.cjs │ │ │ ├── public/ │ │ │ │ ├── manifest.json │ │ │ │ └── robots.txt │ │ │ ├── qwik.env.d.ts │ │ │ ├── src/ │ │ │ │ ├── components/ │ │ │ │ │ ├── avatar/ │ │ │ │ │ │ └── avatar.tsx │ │ │ │ │ ├── header/ │ │ │ │ │ │ └── header.tsx │ │ │ │ │ ├── icones/ │ │ │ │ │ │ └── qwik.tsx │ │ │ │ │ └── router-head/ │ │ │ │ │ └── router-head.tsx │ │ │ │ ├── entry.dev.tsx │ │ │ │ ├── entry.preview.tsx │ │ │ │ ├── entry.ssr.tsx │ │ │ │ ├── entry.vercel-edge.tsx │ │ │ │ ├── global.css │ │ │ │ ├── root.tsx │ │ │ │ └── routes/ │ │ │ │ ├── index.tsx │ │ │ │ ├── layout.tsx │ │ │ │ ├── plugin@auth.ts │ │ │ │ ├── protected/ │ │ │ │ │ └── index.tsx │ │ │ │ └── service-worker.ts │ │ │ ├── tailwind.config.js │ │ │ ├── tsconfig.json │ │ │ ├── vercel.json │ │ │ └── vite.config.ts │ │ ├── solid-start/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── package.json │ │ │ ├── postcss.config.cjs │ │ │ ├── src/ │ │ │ │ ├── components/ │ │ │ │ │ ├── NavBar/ │ │ │ │ │ │ ├── NavBar.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── Protected/ │ │ │ │ │ │ ├── Protected.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── entry-client.tsx │ │ │ │ ├── entry-server.tsx │ │ │ │ ├── env/ │ │ │ │ │ ├── client.ts │ │ │ │ │ ├── schema.ts │ │ │ │ │ └── server.ts │ │ │ │ ├── root.css │ │ │ │ ├── root.tsx │ │ │ │ └── routes/ │ │ │ │ ├── api/ │ │ │ │ │ └── auth/ │ │ │ │ │ └── [...solidauth].ts │ │ │ │ ├── index.tsx │ │ │ │ └── protected.tsx │ │ │ ├── tailwind.config.cjs │ │ │ ├── tsconfig.json │ │ │ └── vite.config.ts │ │ └── sveltekit/ │ │ ├── .env.example │ │ ├── .eslintignore │ │ ├── .eslintrc.cjs │ │ ├── .gitignore │ │ ├── .prettierignore │ │ ├── .prettierrc │ │ ├── README.md │ │ ├── package.json │ │ ├── src/ │ │ │ ├── app.d.ts │ │ │ ├── app.html │ │ │ ├── auth.ts │ │ │ ├── components/ │ │ │ │ ├── external-icon.svelte │ │ │ │ ├── footer.svelte │ │ │ │ └── header.svelte │ │ │ ├── hooks.server.ts │ │ │ └── routes/ │ │ │ ├── +layout.server.ts │ │ │ ├── +layout.svelte │ │ │ ├── +page.svelte │ │ │ ├── protected/ │ │ │ │ └── +page.svelte │ │ │ ├── signin/ │ │ │ │ └── +page.server.ts │ │ │ └── signout/ │ │ │ └── +page.server.ts │ │ ├── svelte.config.js │ │ ├── tsconfig.json │ │ └── vite.config.js │ ├── playgrounds/ │ │ └── README.md │ └── proxy/ │ ├── .gitignore │ ├── README.md │ ├── api/ │ │ ├── [auth].ts │ │ └── callback/ │ │ └── [auth].ts │ ├── package.json │ └── tsconfig.json ├── docs/ │ ├── .gitignore │ ├── .vscode/ │ │ └── settings.json │ ├── LICENSE │ ├── README.md │ ├── app/ │ │ └── api/ │ │ ├── cron/ │ │ │ └── route.ts │ │ └── og/ │ │ └── route.tsx │ ├── components/ │ │ ├── Accordion/ │ │ │ └── index.tsx │ │ ├── Blur/ │ │ │ └── index.tsx │ │ ├── Code/ │ │ │ └── index.tsx │ │ ├── DocSearch/ │ │ │ ├── index.tsx │ │ │ └── wrapper.tsx │ │ ├── Footer/ │ │ │ └── index.tsx │ │ ├── FrameworkLink/ │ │ │ └── index.tsx │ │ ├── Guides/ │ │ │ └── index.tsx │ │ ├── Icons/ │ │ │ ├── ArrowRight.tsx │ │ │ ├── ArrowSquareOut.tsx │ │ │ ├── Browser.tsx │ │ │ ├── CaretRight.tsx │ │ │ ├── ChatCircleText.tsx │ │ │ ├── Check.tsx │ │ │ ├── Flask.tsx │ │ │ ├── GitBranch.tsx │ │ │ ├── GithubLogo.tsx │ │ │ ├── Link.tsx │ │ │ ├── Plus.tsx │ │ │ ├── SealWarning.tsx │ │ │ ├── ShieldStar.tsx │ │ │ ├── Sparkle.tsx │ │ │ └── index.tsx │ │ ├── InkeepSearch/ │ │ │ └── index.tsx │ │ ├── Link/ │ │ │ └── index.tsx │ │ ├── ListDisclosure/ │ │ │ ├── index.tsx │ │ │ └── useListDisclosure.ts │ │ ├── LogosMarquee/ │ │ │ ├── index.tsx │ │ │ └── logo.tsx │ │ ├── OAuthProviderInstructions/ │ │ │ ├── OAuthProviderSelect.tsx │ │ │ ├── content/ │ │ │ │ ├── components/ │ │ │ │ │ ├── SetupCode.tsx │ │ │ │ │ ├── SignInCode.tsx │ │ │ │ │ ├── StepTitle.tsx │ │ │ │ │ └── TSIcon.tsx │ │ │ │ └── index.tsx │ │ │ └── index.tsx │ │ ├── RichTabs/ │ │ │ ├── index.tsx │ │ │ └── useRichTabs.ts │ │ ├── Screenshot/ │ │ │ └── index.tsx │ │ └── SearchBarProviders/ │ │ └── PreviewProviders.tsx │ ├── hooks/ │ │ └── use-select-combobox.ts │ ├── next-env.d.ts │ ├── next-sitemap.config.cjs │ ├── next.config.js │ ├── package.json │ ├── pages/ │ │ ├── 404.mdx │ │ ├── _app.tsx │ │ ├── _document.tsx │ │ ├── _meta.js │ │ ├── animated-stars.css │ │ ├── concepts/ │ │ │ ├── _meta.js │ │ │ ├── database-models.mdx │ │ │ ├── index.mdx │ │ │ ├── oauth.mdx │ │ │ └── session-strategies.mdx │ │ ├── contributors.mdx │ │ ├── data/ │ │ │ └── manifest.json │ │ ├── getting-started/ │ │ │ ├── _meta.js │ │ │ ├── adapters/ │ │ │ │ ├── _meta.js │ │ │ │ ├── azure-tables.mdx │ │ │ │ ├── d1.mdx │ │ │ │ ├── dgraph.mdx │ │ │ │ ├── drizzle.mdx │ │ │ │ ├── dynamodb.mdx │ │ │ │ ├── edgedb.mdx │ │ │ │ ├── fauna.mdx │ │ │ │ ├── firebase.mdx │ │ │ │ ├── hasura.mdx │ │ │ │ ├── kysely.mdx │ │ │ │ ├── mikro-orm.mdx │ │ │ │ ├── mongodb.mdx │ │ │ │ ├── neo4j.mdx │ │ │ │ ├── neon.mdx │ │ │ │ ├── pg.mdx │ │ │ │ ├── pouchdb.mdx │ │ │ │ ├── prisma.mdx │ │ │ │ ├── sequelize.mdx │ │ │ │ ├── supabase.mdx │ │ │ │ ├── surrealdb.mdx │ │ │ │ ├── typeorm.mdx │ │ │ │ ├── unstorage.mdx │ │ │ │ ├── upstash-redis.mdx │ │ │ │ └── xata.mdx │ │ │ ├── authentication/ │ │ │ │ ├── _meta.js │ │ │ │ ├── credentials.mdx │ │ │ │ ├── email.mdx │ │ │ │ ├── oauth.mdx │ │ │ │ └── webauthn.mdx │ │ │ ├── authentication.mdx │ │ │ ├── database.mdx │ │ │ ├── deployment.mdx │ │ │ ├── index.mdx │ │ │ ├── installation.mdx │ │ │ ├── integrations.mdx │ │ │ ├── migrate-to-better-auth.mdx │ │ │ ├── migrating-to-v5.mdx │ │ │ ├── providers/ │ │ │ │ ├── 42-school.mdx │ │ │ │ ├── apple.mdx │ │ │ │ ├── asgardeo.mdx │ │ │ │ ├── auth0.mdx │ │ │ │ ├── authentik.mdx │ │ │ │ ├── azure-ad-b2c.mdx │ │ │ │ ├── azure-ad.mdx │ │ │ │ ├── azure-devops.mdx │ │ │ │ ├── bankid-no.mdx │ │ │ │ ├── battlenet.mdx │ │ │ │ ├── beyondidentity.mdx │ │ │ │ ├── bitbucket.mdx │ │ │ │ ├── box.mdx │ │ │ │ ├── boxyhq-saml.mdx │ │ │ │ ├── bungie.mdx │ │ │ │ ├── click-up.mdx │ │ │ │ ├── cognito.mdx │ │ │ │ ├── coinbase.mdx │ │ │ │ ├── credentials.mdx │ │ │ │ ├── descope.mdx │ │ │ │ ├── discord.mdx │ │ │ │ ├── dribbble.mdx │ │ │ │ ├── dropbox.mdx │ │ │ │ ├── duende-identity-server6.mdx │ │ │ │ ├── eveonline.mdx │ │ │ │ ├── facebook.mdx │ │ │ │ ├── faceit.mdx │ │ │ │ ├── figma.mdx │ │ │ │ ├── forwardemail.mdx │ │ │ │ ├── foursquare.mdx │ │ │ │ ├── freshbooks.mdx │ │ │ │ ├── frontegg.mdx │ │ │ │ ├── fusionauth.mdx │ │ │ │ ├── github.mdx │ │ │ │ ├── gitlab.mdx │ │ │ │ ├── google.mdx │ │ │ │ ├── hubspot.mdx │ │ │ │ ├── identity-server4.mdx │ │ │ │ ├── instagram.mdx │ │ │ │ ├── kakao.mdx │ │ │ │ ├── keycloak.mdx │ │ │ │ ├── line.mdx │ │ │ │ ├── linkedin.mdx │ │ │ │ ├── logto.mdx │ │ │ │ ├── loops.mdx │ │ │ │ ├── mailchimp.mdx │ │ │ │ ├── mailgun.mdx │ │ │ │ ├── mailru.mdx │ │ │ │ ├── mastodon.mdx │ │ │ │ ├── mattermost.mdx │ │ │ │ ├── medium.mdx │ │ │ │ ├── microsoft-entra-id.mdx │ │ │ │ ├── naver.mdx │ │ │ │ ├── netlify.mdx │ │ │ │ ├── netsuite.mdx │ │ │ │ ├── nextcloud.mdx │ │ │ │ ├── nodemailer.mdx │ │ │ │ ├── notion.mdx │ │ │ │ ├── okta.mdx │ │ │ │ ├── onelogin.mdx │ │ │ │ ├── osso.mdx │ │ │ │ ├── osu.mdx │ │ │ │ ├── passage.mdx │ │ │ │ ├── passkey.mdx │ │ │ │ ├── patreon.mdx │ │ │ │ ├── pinterest.mdx │ │ │ │ ├── pipedrive.mdx │ │ │ │ ├── postmark.mdx │ │ │ │ ├── reddit.mdx │ │ │ │ ├── resend.mdx │ │ │ │ ├── sailpoint.mdx │ │ │ │ ├── salesforce.mdx │ │ │ │ ├── sendgrid.mdx │ │ │ │ ├── simplelogin.mdx │ │ │ │ ├── slack.mdx │ │ │ │ ├── spotify.mdx │ │ │ │ ├── strava.mdx │ │ │ │ ├── threads.mdx │ │ │ │ ├── tiktok.mdx │ │ │ │ ├── todoist.mdx │ │ │ │ ├── trakt.mdx │ │ │ │ ├── twitch.mdx │ │ │ │ ├── twitter.mdx │ │ │ │ ├── united-effects.mdx │ │ │ │ ├── vipps-mobilepay.mdx │ │ │ │ ├── vk.mdx │ │ │ │ ├── webex.mdx │ │ │ │ ├── wikimedia.mdx │ │ │ │ ├── wordpress.mdx │ │ │ │ ├── workos.mdx │ │ │ │ ├── yandex.mdx │ │ │ │ ├── zitadel.mdx │ │ │ │ ├── zoho.mdx │ │ │ │ └── zoom.mdx │ │ │ ├── session-management/ │ │ │ │ ├── _meta.js │ │ │ │ ├── custom-pages.mdx │ │ │ │ ├── get-session.mdx │ │ │ │ ├── login.mdx │ │ │ │ └── protecting.mdx │ │ │ └── typescript.mdx │ │ ├── global.css │ │ ├── guides/ │ │ │ ├── _meta.js │ │ │ ├── configuring-github.mdx │ │ │ ├── configuring-http-email.mdx │ │ │ ├── configuring-oauth-providers.mdx │ │ │ ├── configuring-resend.mdx │ │ │ ├── corporate-proxy.mdx │ │ │ ├── creating-a-database-adapter.mdx │ │ │ ├── creating-a-framework-integration.mdx │ │ │ ├── debugging.mdx │ │ │ ├── edge-compatibility.mdx │ │ │ ├── environment-variables.mdx │ │ │ ├── extending-the-session.mdx │ │ │ ├── integrating-third-party-backends.mdx │ │ │ ├── pages/ │ │ │ │ ├── _meta.js │ │ │ │ ├── built-in-pages.mdx │ │ │ │ ├── error.mdx │ │ │ │ ├── signin.mdx │ │ │ │ └── signout.mdx │ │ │ ├── refresh-token-rotation.mdx │ │ │ ├── restricting-user-access.mdx │ │ │ ├── role-based-access-control.mdx │ │ │ └── testing.mdx │ │ ├── index.mdx │ │ ├── reference/ │ │ │ └── _meta.js │ │ └── security.mdx │ ├── postcss.config.cjs │ ├── public/ │ │ └── .well-known/ │ │ └── security.txt │ ├── tailwind.config.js │ ├── theme.config.tsx │ ├── tsconfig.json │ ├── typedoc-nextauth.js │ ├── typedoc.config.cjs │ ├── types.d.ts │ ├── utils/ │ │ ├── types.ts │ │ ├── useCopyButton.ts │ │ └── useInkeepSettings.ts │ └── vercel.json ├── eslint.config.mjs ├── lefthook.yml ├── package.json ├── packages/ │ ├── adapter-azure-tables/ │ │ ├── README.md │ │ ├── package.json │ │ ├── src/ │ │ │ └── index.ts │ │ ├── test/ │ │ │ ├── index.test.ts │ │ │ └── test.sh │ │ ├── tsconfig.json │ │ └── typedoc.config.cjs │ ├── adapter-d1/ │ │ ├── README.md │ │ ├── package.json │ │ ├── src/ │ │ │ ├── index.ts │ │ │ ├── migrations.ts │ │ │ └── queries.ts │ │ ├── test/ │ │ │ └── index.test.ts │ │ ├── tsconfig.json │ │ └── typedoc.config.cjs │ ├── adapter-dgraph/ │ │ ├── README.md │ │ ├── package.json │ │ ├── src/ │ │ │ ├── index.ts │ │ │ └── lib/ │ │ │ ├── client.ts │ │ │ └── graphql/ │ │ │ ├── fragments.ts │ │ │ └── schema.gql │ │ ├── test/ │ │ │ ├── index.test.ts │ │ │ ├── private.key │ │ │ ├── public.key │ │ │ └── test.sh │ │ ├── tsconfig.json │ │ └── typedoc.config.cjs │ ├── adapter-drizzle/ │ │ ├── README.md │ │ ├── package.json │ │ ├── src/ │ │ │ ├── index.ts │ │ │ └── lib/ │ │ │ ├── mysql.ts │ │ │ ├── pg.ts │ │ │ ├── sqlite.ts │ │ │ └── utils.ts │ │ ├── test/ │ │ │ ├── fixtures.ts │ │ │ ├── mysql/ │ │ │ │ ├── drizzle.config.ts │ │ │ │ ├── index.test.ts │ │ │ │ ├── migrator.ts │ │ │ │ ├── schema.ts │ │ │ │ └── test.sh │ │ │ ├── mysql-multi-project-schema/ │ │ │ │ ├── drizzle.config.ts │ │ │ │ ├── index.test.ts │ │ │ │ ├── migrator.ts │ │ │ │ ├── schema.ts │ │ │ │ └── test.sh │ │ │ ├── pg/ │ │ │ │ ├── drizzle.config.ts │ │ │ │ ├── index.test.ts │ │ │ │ ├── migrator.ts │ │ │ │ ├── schema.ts │ │ │ │ └── test.sh │ │ │ ├── pg-multi-project-schema/ │ │ │ │ ├── drizzle.config.ts │ │ │ │ ├── index.test.ts │ │ │ │ ├── migrator.ts │ │ │ │ ├── schema.ts │ │ │ │ └── test.sh │ │ │ ├── sqlite/ │ │ │ │ ├── drizzle.config.ts │ │ │ │ ├── index.test.ts │ │ │ │ ├── migrator.ts │ │ │ │ ├── schema.ts │ │ │ │ └── test.sh │ │ │ └── sqlite-multi-project-schema/ │ │ │ ├── drizzle.config.ts │ │ │ ├── index.test.ts │ │ │ ├── migrator.ts │ │ │ ├── schema.ts │ │ │ └── test.sh │ │ ├── tsconfig.json │ │ └── typedoc.config.cjs │ ├── adapter-dynamodb/ │ │ ├── README.md │ │ ├── jest-dynamodb-config.cjs │ │ ├── package.json │ │ ├── src/ │ │ │ └── index.ts │ │ ├── test/ │ │ │ ├── format.test.ts │ │ │ └── index.test.ts │ │ ├── tsconfig.json │ │ └── typedoc.config.cjs │ ├── adapter-edgedb/ │ │ ├── README.md │ │ ├── package.json │ │ ├── src/ │ │ │ └── index.ts │ │ ├── test/ │ │ │ └── index.test.ts │ │ ├── tsconfig.json │ │ └── typedoc.config.cjs │ ├── adapter-fauna/ │ │ ├── .fauna-project │ │ ├── README.md │ │ ├── fauna/ │ │ │ ├── account.fsl │ │ │ ├── session.fsl │ │ │ ├── user.fsl │ │ │ └── verificationToken.fsl │ │ ├── package.json │ │ ├── src/ │ │ │ └── index.ts │ │ ├── test/ │ │ │ ├── index.test.ts │ │ │ └── test.sh │ │ ├── tsconfig.json │ │ └── typedoc.config.cjs │ ├── adapter-firebase/ │ │ ├── README.md │ │ ├── package.json │ │ ├── src/ │ │ │ └── index.ts │ │ ├── test/ │ │ │ ├── firestore.rules │ │ │ ├── index.test.ts │ │ │ └── test.sh │ │ ├── tsconfig.json │ │ ├── typedoc.config.cjs │ │ └── vitest.config.ts │ ├── adapter-hasura/ │ │ ├── README.md │ │ ├── codegen.ts │ │ ├── docker-compose.yml │ │ ├── hasura/ │ │ │ ├── config.yaml │ │ │ ├── metadata/ │ │ │ │ ├── actions.graphql │ │ │ │ ├── actions.yaml │ │ │ │ ├── allow_list.yaml │ │ │ │ ├── api_limits.yaml │ │ │ │ ├── cron_triggers.yaml │ │ │ │ ├── databases/ │ │ │ │ │ ├── databases.yaml │ │ │ │ │ └── default/ │ │ │ │ │ └── tables/ │ │ │ │ │ ├── public_accounts.yaml │ │ │ │ │ ├── public_provider_type.yaml │ │ │ │ │ ├── public_sessions.yaml │ │ │ │ │ ├── public_users.yaml │ │ │ │ │ ├── public_verification_tokens.yaml │ │ │ │ │ └── tables.yaml │ │ │ │ ├── graphql_schema_introspection.yaml │ │ │ │ ├── inherited_roles.yaml │ │ │ │ ├── network.yaml │ │ │ │ ├── query_collections.yaml │ │ │ │ ├── remote_schemas.yaml │ │ │ │ ├── rest_endpoints.yaml │ │ │ │ └── version.yaml │ │ │ └── migrations/ │ │ │ └── default/ │ │ │ └── 1666885939998_init_nextauth_models/ │ │ │ └── up.sql │ │ ├── package.json │ │ ├── schema.gql │ │ ├── src/ │ │ │ ├── index.ts │ │ │ ├── lib/ │ │ │ │ └── client.ts │ │ │ └── queries/ │ │ │ ├── account.graphql │ │ │ ├── delete.graphql │ │ │ ├── fragments.graphql │ │ │ ├── session.graphql │ │ │ ├── user.graphql │ │ │ └── verification-token.graphql │ │ ├── test/ │ │ │ ├── index.test.ts │ │ │ └── test.sh │ │ ├── tsconfig.json │ │ └── typedoc.config.cjs │ ├── adapter-kysely/ │ │ ├── README.md │ │ ├── package.json │ │ ├── src/ │ │ │ └── index.ts │ │ ├── test/ │ │ │ ├── index.test.ts │ │ │ ├── scripts/ │ │ │ │ └── mysql-init.sql │ │ │ └── test.sh │ │ ├── tsconfig.json │ │ └── typedoc.config.cjs │ ├── adapter-mikro-orm/ │ │ ├── README.md │ │ ├── package.json │ │ ├── src/ │ │ │ ├── index.ts │ │ │ └── lib/ │ │ │ └── entities.ts │ │ ├── test/ │ │ │ ├── __snapshots__/ │ │ │ │ └── schema.test.ts.snap │ │ │ ├── entities.test.ts │ │ │ └── schema.test.ts │ │ ├── tsconfig.json │ │ └── typedoc.config.cjs │ ├── adapter-mongodb/ │ │ ├── README.md │ │ ├── package.json │ │ ├── src/ │ │ │ └── index.ts │ │ ├── test/ │ │ │ ├── custom.test.ts │ │ │ ├── index.test.ts │ │ │ ├── serverless.test.ts │ │ │ └── test.sh │ │ ├── tsconfig.json │ │ └── typedoc.config.cjs │ ├── adapter-neo4j/ │ │ ├── README.md │ │ ├── package.json │ │ ├── src/ │ │ │ └── index.ts │ │ ├── test/ │ │ │ ├── index.test.ts │ │ │ ├── resources/ │ │ │ │ └── statements.ts │ │ │ └── test.sh │ │ ├── tsconfig.json │ │ └── typedoc.config.cjs │ ├── adapter-neon/ │ │ ├── README.md │ │ ├── package.json │ │ ├── schema.sql │ │ ├── src/ │ │ │ └── index.ts │ │ ├── test/ │ │ │ ├── index.test.ts │ │ │ └── test.sh │ │ ├── tsconfig.json │ │ └── typedoc.config.cjs │ ├── adapter-pg/ │ │ ├── README.md │ │ ├── package.json │ │ ├── schema.sql │ │ ├── src/ │ │ │ └── index.ts │ │ ├── test/ │ │ │ ├── index.test.ts │ │ │ └── test.sh │ │ ├── tsconfig.json │ │ └── typedoc.config.cjs │ ├── adapter-pouchdb/ │ │ ├── README.md │ │ ├── package.json │ │ ├── src/ │ │ │ └── index.ts │ │ ├── test/ │ │ │ └── index.test.ts │ │ ├── tsconfig.json │ │ └── typedoc.config.cjs │ ├── adapter-prisma/ │ │ ├── README.md │ │ ├── package.json │ │ ├── prisma/ │ │ │ ├── custom.prisma │ │ │ ├── mongodb.prisma │ │ │ └── schema.prisma │ │ ├── src/ │ │ │ └── index.ts │ │ ├── test/ │ │ │ ├── index.test.ts │ │ │ └── mongodb.test.sh │ │ ├── tsconfig.json │ │ └── typedoc.config.js │ ├── adapter-sequelize/ │ │ ├── README.md │ │ ├── package.json │ │ ├── src/ │ │ │ ├── index.ts │ │ │ └── models.ts │ │ ├── test/ │ │ │ └── index.test.ts │ │ ├── tsconfig.json │ │ └── typedoc.config.cjs │ ├── adapter-supabase/ │ │ ├── .gitignore │ │ ├── README.md │ │ ├── package.json │ │ ├── src/ │ │ │ └── index.ts │ │ ├── supabase/ │ │ │ ├── config.toml │ │ │ └── migrations/ │ │ │ ├── 20221108043803_create_next_auth_schema.sql │ │ │ └── 20221108044627_create_public_users_table.sql │ │ ├── test/ │ │ │ ├── index.test.ts │ │ │ └── test.sh │ │ ├── tsconfig.json │ │ └── typedoc.config.cjs │ ├── adapter-surrealdb/ │ │ ├── README.md │ │ ├── package.json │ │ ├── src/ │ │ │ └── index.ts │ │ ├── test/ │ │ │ ├── common.ts │ │ │ ├── index.test.ts │ │ │ └── test.sh │ │ ├── tsconfig.json │ │ └── typedoc.config.cjs │ ├── adapter-typeorm/ │ │ ├── .dockerignore │ │ ├── README.md │ │ ├── package.json │ │ ├── src/ │ │ │ ├── entities.ts │ │ │ ├── index.ts │ │ │ └── utils.ts │ │ ├── test/ │ │ │ ├── custom-entities.ts │ │ │ ├── helpers.ts │ │ │ ├── index.test.ts │ │ │ ├── mysql/ │ │ │ │ ├── index.custom.test.ts │ │ │ │ ├── index.test.ts │ │ │ │ └── test.sh │ │ │ ├── postgresql/ │ │ │ │ ├── index.custom.test.ts │ │ │ │ ├── index.test.ts │ │ │ │ └── test.sh │ │ │ └── sqlite/ │ │ │ ├── index.custom.test.ts │ │ │ ├── index.test.ts │ │ │ └── test.sh │ │ ├── tsconfig.json │ │ └── typedoc.config.cjs │ ├── adapter-unstorage/ │ │ ├── README.md │ │ ├── package.json │ │ ├── src/ │ │ │ └── index.ts │ │ ├── test/ │ │ │ ├── filesystem.test.ts │ │ │ ├── memory.test.ts │ │ │ ├── redis-json.test.ts │ │ │ ├── redis.test.ts │ │ │ └── test.sh │ │ ├── tsconfig.json │ │ └── typedoc.config.cjs │ ├── adapter-upstash-redis/ │ │ ├── README.md │ │ ├── docker-compose.yml │ │ ├── package.json │ │ ├── src/ │ │ │ └── index.ts │ │ ├── test/ │ │ │ ├── index.test.ts │ │ │ └── test.sh │ │ ├── tsconfig.json │ │ └── typedoc.config.cjs │ ├── adapter-xata/ │ │ ├── README.md │ │ ├── package.json │ │ ├── schema.json │ │ ├── src/ │ │ │ ├── index.ts │ │ │ └── xata.ts │ │ ├── test/ │ │ │ └── index.test.ts │ │ ├── tsconfig.json │ │ └── typedoc.config.cjs │ ├── core/ │ │ ├── README.md │ │ ├── package.json │ │ ├── scripts/ │ │ │ ├── generate-css.js │ │ │ └── generate-providers.js │ │ ├── src/ │ │ │ ├── adapters.ts │ │ │ ├── errors.ts │ │ │ ├── index.ts │ │ │ ├── jwt.ts │ │ │ ├── lib/ │ │ │ │ ├── actions/ │ │ │ │ │ ├── callback/ │ │ │ │ │ │ ├── handle-login.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── oauth/ │ │ │ │ │ │ ├── callback.ts │ │ │ │ │ │ ├── checks.ts │ │ │ │ │ │ └── csrf-token.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── session.ts │ │ │ │ │ ├── signin/ │ │ │ │ │ │ ├── authorization-url.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── send-token.ts │ │ │ │ │ ├── signout.ts │ │ │ │ │ └── webauthn-options.ts │ │ │ │ ├── index.ts │ │ │ │ ├── init.ts │ │ │ │ ├── pages/ │ │ │ │ │ ├── error.tsx │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── signin.tsx │ │ │ │ │ ├── signout.tsx │ │ │ │ │ ├── styles.css │ │ │ │ │ └── verify-request.tsx │ │ │ │ ├── symbols.ts │ │ │ │ ├── utils/ │ │ │ │ │ ├── actions.ts │ │ │ │ │ ├── assert.ts │ │ │ │ │ ├── callback-url.ts │ │ │ │ │ ├── cookie.ts │ │ │ │ │ ├── date.ts │ │ │ │ │ ├── email.ts │ │ │ │ │ ├── env.ts │ │ │ │ │ ├── logger.ts │ │ │ │ │ ├── merge.ts │ │ │ │ │ ├── providers.ts │ │ │ │ │ ├── session.ts │ │ │ │ │ ├── web.ts │ │ │ │ │ ├── webauthn-client.js │ │ │ │ │ └── webauthn-utils.ts │ │ │ │ └── vendored/ │ │ │ │ └── cookie.ts │ │ │ ├── providers/ │ │ │ │ ├── 42-school.ts │ │ │ │ ├── apple.ts │ │ │ │ ├── asgardeo.ts │ │ │ │ ├── atlassian.ts │ │ │ │ ├── auth0.ts │ │ │ │ ├── authentik.ts │ │ │ │ ├── azure-ad-b2c.ts │ │ │ │ ├── azure-ad.ts │ │ │ │ ├── azure-devops.ts │ │ │ │ ├── bankid-no.ts │ │ │ │ ├── battlenet.ts │ │ │ │ ├── beyondidentity.ts │ │ │ │ ├── bitbucket.ts │ │ │ │ ├── box.ts │ │ │ │ ├── boxyhq-saml.ts │ │ │ │ ├── bungie.ts │ │ │ │ ├── click-up.ts │ │ │ │ ├── cognito.ts │ │ │ │ ├── coinbase.ts │ │ │ │ ├── concept2.ts │ │ │ │ ├── credentials.ts │ │ │ │ ├── descope.ts │ │ │ │ ├── discord.ts │ │ │ │ ├── dribbble.ts │ │ │ │ ├── dropbox.ts │ │ │ │ ├── duende-identity-server6.ts │ │ │ │ ├── email.ts │ │ │ │ ├── eventbrite.ts │ │ │ │ ├── eveonline.ts │ │ │ │ ├── facebook.ts │ │ │ │ ├── faceit.ts │ │ │ │ ├── figma.ts │ │ │ │ ├── forwardemail.ts │ │ │ │ ├── foursquare.ts │ │ │ │ ├── freshbooks.ts │ │ │ │ ├── frontegg.ts │ │ │ │ ├── fusionauth.ts │ │ │ │ ├── github.ts │ │ │ │ ├── gitlab.ts │ │ │ │ ├── google.ts │ │ │ │ ├── hubspot.ts │ │ │ │ ├── huggingface.ts │ │ │ │ ├── identity-server4.ts │ │ │ │ ├── index.ts │ │ │ │ ├── instagram.ts │ │ │ │ ├── kakao.ts │ │ │ │ ├── keycloak.ts │ │ │ │ ├── kinde.ts │ │ │ │ ├── line.ts │ │ │ │ ├── linkedin.ts │ │ │ │ ├── logto.ts │ │ │ │ ├── loops.ts │ │ │ │ ├── mailchimp.ts │ │ │ │ ├── mailgun.ts │ │ │ │ ├── mailru.ts │ │ │ │ ├── mastodon.ts │ │ │ │ ├── mattermost.ts │ │ │ │ ├── medium.ts │ │ │ │ ├── microsoft-entra-id.ts │ │ │ │ ├── naver.ts │ │ │ │ ├── netlify.ts │ │ │ │ ├── netsuite.ts │ │ │ │ ├── nextcloud.ts │ │ │ │ ├── nodemailer.ts │ │ │ │ ├── notion.ts │ │ │ │ ├── oauth.ts │ │ │ │ ├── okta.ts │ │ │ │ ├── onelogin.ts │ │ │ │ ├── ory-hydra.ts │ │ │ │ ├── osso.ts │ │ │ │ ├── osu.ts │ │ │ │ ├── passage.ts │ │ │ │ ├── passkey.ts │ │ │ │ ├── patreon.ts │ │ │ │ ├── ping-id.ts │ │ │ │ ├── pinterest.ts │ │ │ │ ├── pipedrive.ts │ │ │ │ ├── postmark.ts │ │ │ │ ├── reddit.ts │ │ │ │ ├── resend.ts │ │ │ │ ├── roblox.ts │ │ │ │ ├── salesforce.ts │ │ │ │ ├── sendgrid.ts │ │ │ │ ├── simplelogin.ts │ │ │ │ ├── slack.ts │ │ │ │ ├── spotify.ts │ │ │ │ ├── strava.ts │ │ │ │ ├── threads.ts │ │ │ │ ├── tiktok.ts │ │ │ │ ├── todoist.ts │ │ │ │ ├── trakt.ts │ │ │ │ ├── twitch.ts │ │ │ │ ├── twitter.ts │ │ │ │ ├── united-effects.ts │ │ │ │ ├── vipps.ts │ │ │ │ ├── vk.ts │ │ │ │ ├── webauthn.ts │ │ │ │ ├── webex.ts │ │ │ │ ├── wechat.ts │ │ │ │ ├── wikimedia.ts │ │ │ │ ├── wordpress.ts │ │ │ │ ├── workos.ts │ │ │ │ ├── yandex.ts │ │ │ │ ├── zitadel.ts │ │ │ │ ├── zoho.ts │ │ │ │ └── zoom.ts │ │ │ ├── types.ts │ │ │ └── warnings.ts │ │ ├── test/ │ │ │ ├── actions/ │ │ │ │ ├── callback.test.ts │ │ │ │ ├── csrf.test.ts │ │ │ │ └── session.test.ts │ │ │ ├── assert-config.test.ts │ │ │ ├── authorize.test.ts │ │ │ ├── env.test.ts │ │ │ ├── fixtures/ │ │ │ │ ├── oauth-callback.ts │ │ │ │ └── pages.ts │ │ │ ├── jwt.test.ts │ │ │ ├── memory-adapter.ts │ │ │ ├── merge.test.ts │ │ │ ├── pages.test.ts │ │ │ ├── providers/ │ │ │ │ └── gitlab.test.ts │ │ │ ├── url-parsing.test.ts │ │ │ ├── utils.ts │ │ │ └── webauthn-utils.test.ts │ │ ├── tsconfig.json │ │ └── typedoc.config.cjs │ ├── frameworks-express/ │ │ ├── README.md │ │ ├── package.json │ │ ├── src/ │ │ │ ├── adapters.ts │ │ │ ├── index.ts │ │ │ └── lib/ │ │ │ ├── http-api-adapters.ts │ │ │ └── index.ts │ │ ├── test/ │ │ │ ├── http-api-adapters/ │ │ │ │ ├── request.test.ts │ │ │ │ └── response.test.ts │ │ │ ├── login.test.ts │ │ │ ├── routing.test.ts │ │ │ └── session.test.ts │ │ ├── tsconfig.json │ │ └── typedoc.config.cjs │ ├── frameworks-qwik/ │ │ ├── README.md │ │ ├── package.json │ │ ├── src/ │ │ │ ├── adapters.ts │ │ │ └── index.ts │ │ ├── tsconfig.json │ │ ├── typedoc.config.cjs │ │ └── vite.config.ts │ ├── frameworks-solid-start/ │ │ ├── .gitignore │ │ ├── README.MD │ │ ├── package.json │ │ ├── src/ │ │ │ ├── adapters.ts │ │ │ ├── client.ts │ │ │ └── index.ts │ │ ├── test/ │ │ │ └── index.test.ts │ │ ├── tsconfig.json │ │ └── typedoc.config.cjs │ ├── frameworks-sveltekit/ │ │ ├── README.md │ │ ├── package.json │ │ ├── playwright.config.ts │ │ ├── scripts/ │ │ │ └── postbuild.js │ │ ├── src/ │ │ │ └── lib/ │ │ │ ├── actions.ts │ │ │ ├── adapters.ts │ │ │ ├── client.ts │ │ │ ├── components/ │ │ │ │ ├── SignIn.svelte │ │ │ │ ├── SignOut.svelte │ │ │ │ └── index.ts │ │ │ ├── env.ts │ │ │ ├── index.ts │ │ │ ├── types.ts │ │ │ └── webauthn.ts │ │ ├── test/ │ │ │ └── index.test.ts │ │ ├── tsconfig.json │ │ └── typedoc.config.cjs │ ├── frameworks-template/ │ │ ├── README.md │ │ ├── package.json │ │ ├── src/ │ │ │ └── index.ts │ │ ├── test/ │ │ │ ├── index.test.ts │ │ │ └── test-setup.ts │ │ ├── tsconfig.json │ │ └── typedoc.config.cjs │ ├── next-auth/ │ │ ├── README.md │ │ ├── package.json │ │ ├── playwright.config.ts │ │ ├── src/ │ │ │ ├── adapters.ts │ │ │ ├── index.ts │ │ │ ├── jwt.ts │ │ │ ├── lib/ │ │ │ │ ├── actions.ts │ │ │ │ ├── client.ts │ │ │ │ ├── env.ts │ │ │ │ ├── index.ts │ │ │ │ └── types.ts │ │ │ ├── middleware.ts │ │ │ ├── next.ts │ │ │ ├── react.tsx │ │ │ └── webauthn.ts │ │ ├── test/ │ │ │ ├── actions.test.ts │ │ │ ├── e2e/ │ │ │ │ ├── fixtures/ │ │ │ │ │ ├── auth.ts │ │ │ │ │ └── webApp.ts │ │ │ │ ├── helpers/ │ │ │ │ │ └── authTest.ts │ │ │ │ ├── poms/ │ │ │ │ │ └── keycloakLoginPom.ts │ │ │ │ └── tests/ │ │ │ │ ├── api/ │ │ │ │ │ └── session.spec.ts │ │ │ │ └── providers/ │ │ │ │ ├── credentials.spec.ts │ │ │ │ └── keycloak.spec.ts │ │ │ └── env.test.ts │ │ ├── tsconfig.json │ │ └── typedoc.config.cjs │ └── utils/ │ ├── adapter.ts │ ├── package.json │ ├── scripts/ │ │ ├── providers.js │ │ └── setup-fw-integration.js │ ├── tsconfig.eslint.json │ ├── tsconfig.json │ ├── vitest-setup.ts │ └── vitest.config.ts ├── patches/ │ └── @balazsorban__monorepo-release@0.5.1.patch ├── pnpm-workspace.yaml └── turbo.json ================================================ FILE CONTENTS ================================================ ================================================ FILE: .dockerignore ================================================ # Files /**/*/.env /**/*/.env.* /**/*/README.md /**/*/.git /**/*/.github /**/*/.gitignore /**/*/.dockerignore /**/*/.turbo /**/*/npm-debug.log /**/*/Dockerfile # Directories /**/*/node_modules /**/*/test /**/*/dist # Auth.js Dirs apps/* docs/** packages/** !packages/next-auth !packages/core !packages/utils !apps/examples/nextjs-docker ================================================ FILE: .github/CODEOWNERS ================================================ # Learn how to add code owners here: # https://help.github.com/en/articles/about-code-owners * @balazsorban44 .github @ThangHuuVu @ndom91 /apps/ @ubbe-xyz @ndom91 @ThangHuuVu /docs/ @ubbe-xyz @ndom91 /packages/ @ThangHuuVu /packages/adapter-*/ @ndom91 /**/*test* @ubbe-xyz /**/*type* @ubbe-xyz ================================================ FILE: .github/DISCUSSION_TEMPLATE/ideas.yml ================================================ body: - type: textarea attributes: label: Goals description: Short list of what the feature request aims to address? value: | 1. 2. 3. validations: required: true - type: textarea attributes: label: Non-Goals description: Short list of what the feature request _does not_ aim to address? value: | 1. 2. 3. validations: required: false - type: textarea attributes: label: Background description: Discuss prior art, why do you think this feature is needed? Are there current alternatives? validations: required: true - type: textarea attributes: label: Proposal description: How should this feature be implemented? Are you interested in contributing? validations: required: true ================================================ FILE: .github/DISCUSSION_TEMPLATE/questions.yml ================================================ body: - type: textarea attributes: label: Summary description: What do you need help with? validations: required: true - type: textarea attributes: label: Additional information description: Any code snippets, error messages, or dependency details that may be related? render: js validations: required: false - type: input attributes: label: Example description: A link to a minimal reproduction is helpful for collaborative debugging! validations: required: false ================================================ FILE: .github/ISSUE_TEMPLATE/1_bug_framework.yml ================================================ name: Bug report description: Report an issue so we can improve labels: [triage, bug] body: - type: markdown attributes: value: | **NOTE:** Issues that are potentially security related should be reported to us by following the [Security guidelines](https://next-auth.js.org/security) rather than on GitHub. Thanks for taking the time to fill out this issue after reading/searching through the [documentation](https://next-auth.js.org) first! Is this your first time contributing? Check out this video: https://www.youtube.com/watch?v=cuoNzXFLitc ### Important :exclamation: _Providing incorrect/insufficient information or skipping steps to reproduce the issue *will* result in closing the issue or converting to a discussion without further explanation._ If you have a generic question specific to your project, it is best asked in Discussions under the [Questions category](https://github.com/nextauthjs/next-auth/discussions/new?category=Questions) # Let's wait with this until adoption in other frameworks. # - type: dropdown # attributes: # label: Framework # description: Which framework(s) is this issue related to? # multiple: true # options: # - "Next.js" # - "Other" - type: textarea attributes: label: Environment description: | Run this command in your project's root folder and paste the result: `npx envinfo --system --binaries --browsers --npmPackages "{next,react,next-auth,@auth/*}"` Alternatively, you can manually gather the version information from your package.json for these packages: "next", "react" and "next-auth". Please also mention your OS and Node.js version, as well as the browser you are using. value: | ``` Paste here ``` validations: required: true - type: input attributes: label: Reproduction URL description: A URL to a public github.com repository outside the next-auth org that clearly reproduces your issue. You can use our [`next-auth-example`](https://github.com/nextauthjs/next-auth-example) template repository to get started more easily validations: required: true - type: textarea attributes: label: Describe the issue description: Describe us what the issue is and what have you tried so far to fix it. Add any extra useful information in this section. Feel free to use screenshots (but prefer [code blocks](https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/creating-and-highlighting-code-blocks#syntax-highlighting) over a picture of your code) or a video explanation. validations: required: true - type: textarea attributes: label: How to reproduce description: Explain with clear steps how to reproduce the issue validations: required: true - type: textarea attributes: label: Expected behavior description: Explain what should have happened instead of what actually happened validations: required: true ================================================ FILE: .github/ISSUE_TEMPLATE/2_bug_provider.yml ================================================ name: Bug report (Provider) description: Create a provider-specific report labels: [triage, bug, providers] body: - type: markdown attributes: value: | **NOTE:** Issues that are potentially security related should be reported to us by following the [Security guidelines](https://next-auth.js.org/security) rather than on GitHub. Thanks for taking the time to fill out this [Provider](https://next-auth.js.org/providers/overview) related issue! Is this your first time contributing? Check out this video: https://www.youtube.com/watch?v=cuoNzXFLitc ### Important :exclamation: _Providing incorrect/insufficient information or skipping steps to reproduce the issue *will* result in closing the issue or converting to a discussion without further explanation._ If you have a generic question specific to your project, it is best asked in Discussions under the [Questions category](https://github.com/nextauthjs/next-auth/discussions/new?category=Questions) - type: dropdown attributes: label: Provider type description: Provider(s) this issue is related to multiple: true options: - "Credentials" - "Email" - "Custom provider" - "42 School" - "Apple" - "Asgardeo" - "Atlassian" - "Auth0" - "Authentik" - "Azure Active Directory" - "Azure Active Directory B2C" - "Azure DevOps" - "Battlenet" - "Beyond Identity" - "Bitbucket" - "Box" - "Bungie" - "ClickUp" - "Cognito" - "Concept2" - "Coinbase" - "Descope" - "Discord" - "Dribbble" - "Dropbox" - "Eventbrite" - "EVE Online" - "Facebook" - "FACEIT" - "Figma" - "Foursquare" - "Freshbooks" - "FusionAuth" - "GitHub" - "GitLab" - "Google" - "Hugging Face" - "Identity Server 4" - "Instagram" - "Kakao" - "Frontegg" - "Keycloak" - "Kinde" - "Line" - "LinkedIn" - "Logto" - "Loops" - "Mailchimp" - "Mail.ru" - "Mastodon" - "Medium" - "Microsoft Entra ID" - "Naver" - "Netlify" - "NetSuite" - "Nextcloud" - "Notion" - "Okta" - "OneLogin" - "Osso" - "Osu" - "Patreon" - "Ping Identity" - "Pipedrive" - "Reddit" - "Roblox" - "Salesforce" - "SimpleLogin" - "Slack" - "Spotify" - "Strava" - "Threads" - "Tiktok" - "Todoist" - "Trakt" - "Twitch" - "Twitter" - "Vk" - "Webex" - "Wordpress" - "WorkOS" - "Yandex" - "Zoho" - "Zoom" validations: required: true - type: textarea attributes: label: Environment description: | Run this command in your project's root folder and paste the result: `npx envinfo --system --binaries --browsers --npmPackages "{next,react,next-auth,@auth/*}"` Alternatively, you can manually gather the version information from your package.json for these packages: "next", "react" and "next-auth". Please also mention your OS and Node.js version, as well as the browser you are using. value: | ``` Paste here ``` validations: required: true - type: input attributes: label: Reproduction URL description: A URL to a public github.com repository outside the next-auth org that clearly reproduces your issue. You can use our [`next-auth-example`](https://github.com/nextauthjs/next-auth-example) template repository to get started more easily validations: required: true - type: textarea attributes: label: Describe the issue description: Describe us what the issue is and what have you tried so far to fix it. Add any extra useful information in this section. Feel free to use screenshots (but prefer [code blocks](https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/creating-and-highlighting-code-blocks#syntax-highlighting) over a picture of your code) or a video explanation. validations: required: true - type: textarea attributes: label: How to reproduce description: Explain with clear steps how to reproduce the issue validations: required: true - type: textarea attributes: label: Expected behavior description: Explain what should have happened instead of what actually happened validations: required: true ================================================ FILE: .github/ISSUE_TEMPLATE/3_bug_adapter.yml ================================================ name: Bug report (Adapter) description: Create an adapter-specific report labels: [triage, bug, adapters] body: - type: markdown attributes: value: | **NOTE:** Issues that are potentially security related should be reported to us by following the [Security guidelines](https://next-auth.js.org/security) rather than on GitHub. Thanks for taking the time to fill out this [Adapter](https://next-auth.js.org/getting-started/adapters) related issue! Is this your first time contributing? Check out this video: https://www.youtube.com/watch?v=cuoNzXFLitc ### Important :exclamation: _Providing incorrect/insufficient information or skipping steps to reproduce the issue *will* result in closing the issue or converting to a discussion without further explanation._ If you have a generic question specific to your project, it is best asked in Discussions under the [Questions category](https://github.com/nextauthjs/next-auth/discussions/new?category=Questions) - type: dropdown attributes: label: Adapter type description: Adapter(s) this issue is related to multiple: true options: - "Custom adapter" - "@auth/azure-tables-adapter" - "@auth/edgedb-adapter" - "@auth/d1-adapter" - "@auth/dgraph-adapter" - "@auth/drizzle-adapter" - "@auth/dynamodb-adapter" - "@auth/fauna-adapter" - "@auth/firebase-adapter" - "@auth/hasura-adapter" - "@auth/kysely-adapter" - "@auth/mikro-orm-adapter" - "@auth/mongodb-adapter" - "@auth/neo4j-adapter" - "@auth/pg-adapter" - "@auth/pouchdb-adapter" - "@auth/prisma-adapter" - "@auth/sequelize-adapter" - "@auth/supabase-adapter" - "@auth/surrealdb-adapter" - "@auth/typeorm-adapter" - "@auth/unstorage-adapter" - "@auth/upstash-redis-adapter" - "@auth/xata-adapter" validations: required: true - type: textarea attributes: label: Environment description: | Run this command in your project's root folder and paste the result: `npx envinfo --system --binaries --browsers --npmPackages "{next,react,next-auth,@auth/*}"` Alternatively, you can manually gather the version information from your package.json for these packages: "next", "react" and "next-auth". Please also mention your OS and Node.js version, as well as the browser you are using. value: | ``` Paste here ``` validations: required: true - type: input attributes: label: Reproduction URL description: A URL to a public github.com repository outside the next-auth org that clearly reproduces your issue. You can use our [`next-auth-example`](https://github.com/nextauthjs/next-auth-example) template repository to get started more easily validations: required: true - type: textarea attributes: label: Describe the issue description: Describe us what the issue is and what have you tried so far to fix it. Add any extra useful information in this section. Feel free to use screenshots (but prefer [code blocks](https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/creating-and-highlighting-code-blocks#syntax-highlighting) over a picture of your code) or a video explanation. validations: required: true - type: textarea attributes: label: How to reproduce description: Explain with clear steps how to reproduce the issue validations: required: true - type: textarea attributes: label: Expected behavior description: Explain what should have happened instead of what actually happened validations: required: true ================================================ FILE: .github/ISSUE_TEMPLATE/4_documentation.yml ================================================ name: "Documentation" description: Request to update or improve NextAuth.js documentation labels: ["triage", "documentation"] body: - type: textarea attributes: label: What is the improvement or update you wish to see? description: "Example: The `next-auth` docs are missing information about X." validations: required: true - type: textarea attributes: label: Is there any context that might help us understand? description: A clear description of any added context that might help us understand. validations: required: true - type: input attributes: label: Does the docs page already exist? Please link to it. description: "Example: https://next-auth.js.org/getting-started/introduction" validations: required: false ================================================ FILE: .github/ISSUE_TEMPLATE/config.yml ================================================ blank_issues_enabled: false contact_links: - name: Get help from the community (Discord) url: https://discord.authjs.dev about: Ask questions and discuss with other community members - name: Ask a question url: https://github.com/nextauthjs/next-auth/discussions/new?category=questions about: Ask questions and discuss with other community members - name: Feature request url: https://github.com/nextauthjs/next-auth/discussions/new?category=ideas about: Feature requests should be opened as discussions ================================================ FILE: .github/PULL_REQUEST_TEMPLATE.md ================================================ ## ☕️ Reasoning ## 🧢 Checklist - [ ] Documentation - [ ] Tests - [ ] Ready to be merged ## 🎫 Affected issues ## 📌 Resources - [Security guidelines](https://github.com/nextauthjs/.github/blob/main/SECURITY.md) - [Contributing guidelines](https://github.com/nextauthjs/.github/blob/main/CONTRIBUTING.md) - [Code of conduct](https://github.com/nextauthjs/.github/blob/main/CODE_OF_CONDUCT.md) - [Contributing to Open Source](https://kcd.im/pull-request) ================================================ FILE: .github/broken-link-checker/action.yml ================================================ name: "Broken Link Checker" description: "Recursively checks input URL for broken links" outputs: version: description: "Check for broken internal links" runs: using: "node20" main: "dist/index.js" ================================================ FILE: .github/broken-link-checker/index.d.ts ================================================ declare module "broken-link-checker"; ================================================ FILE: .github/broken-link-checker/package.json ================================================ { "name": "broken-link-checker", "private": true, "version": "0.2.0", "description": "Find broken links as a GitHub Action", "main": "dist/index.js", "type": "module", "scripts": { "dev": "tsx src/index.ts", "build": "npx tsup --clean --minify --format esm src/index.ts", "types": "tsc" }, "keywords": [ "typescript", "broken-link-checker", "github-action" ], "author": "ndom91 (https://ndo.dev/)", "license": "MIT", "devDependencies": { "@types/node": "^20.11.15", "tsup": "^8.0.1", "tsx": "^4.7.0", "typescript": "^5.3.3" }, "dependencies": { "@actions/core": "^1.10.1", "@actions/github": "^6.0.0", "broken-link-checker": "^0.7.8" } } ================================================ FILE: .github/broken-link-checker/src/index.ts ================================================ import blc from "broken-link-checker" import { setFailed } from "@actions/core" import * as github from "@actions/github" type TODO = any type Output = { errors: any[] links: any[] pages: any[] sites: any[] } type Comment = { id: number } type FindBotComment = { octokit: TODO owner: string repo: string prNumber: number } const COMMENT_TAG = "# Broken Link Checker" async function findBotComment({ octokit, owner, repo, prNumber, }: FindBotComment): Promise { try { const { data: comments } = await octokit.rest.issues.listComments({ owner, repo, issue_number: prNumber, }) return comments.find((c: TODO) => c.body?.includes(COMMENT_TAG)) } catch (error) { setFailed("Error finding bot comment: " + error) return undefined } } async function updateCheckStatus( brokenLinkCount: number, commentUrl?: string ): Promise { const checkName = "Broken Link Checker" const summary = `Found ${brokenLinkCount} broken links in this PR. Click details for a list.` const text = `[See the comment for details](${commentUrl})` const { context, getOctokit } = github const octokit = getOctokit(process.env.GITHUB_TOKEN!) const { owner, repo } = context.repo // Can only update status on 'pull_request' events if (context.payload.pull_request) { const pullRequest = context.payload.pull_request const sha = pullRequest?.head.sha const checkParams = { owner, repo, name: checkName, head_sha: sha, status: "completed" as const, conclusion: "failure" as const, output: { title: checkName, summary: summary, text: text, }, } try { await octokit.rest.checks.create(checkParams) } catch (error) { setFailed("Failed to create check: " + error) } } } const postComment = async ( outputMd: string, brokenLinkCount: number = 0 ): Promise => { try { const { context, getOctokit } = github const octokit = getOctokit(process.env.GITHUB_TOKEN!) const { owner, repo } = context.repo let prNumber // Handle various trigger events if (context.payload.pull_request) { // Triggered by `pull_request` prNumber = context.payload.pull_request?.number } else if (context.payload.issue) { // Triggered by `issue_comment` prNumber = context.payload?.issue?.number } if (!prNumber) { setFailed("Count not find PR Number") return "" } const botComment = await findBotComment({ octokit, owner, repo, prNumber, }) if (botComment) { console.log("Updating Comment") const { data } = await octokit.rest.issues.updateComment({ owner, repo, comment_id: botComment?.id, body: outputMd, }) return data.html_url } else if (brokenLinkCount > 0) { console.log("Creating Comment") const { data } = await octokit.rest.issues.createComment({ owner, repo, issue_number: prNumber, body: outputMd, }) return data.html_url } return "" } catch (error) { setFailed("Error commenting: " + error) return "" } } const generateOutputMd = (output: Output): string => { // Add comment header let outputMd = `${COMMENT_TAG} > **${output.links.length}** broken links found. Links organised below by source page, or page where they were found. ` // Build map of page and array of its found broken links const linksByPage = output.links.reduce((acc, link) => { if (!acc[link.base.resolved]) { acc[link.base.resolved] = [] acc[link.base.resolved].push(link) } else { acc[link.base.resolved].push(link) } return acc }, {}) // Write out markdown tables of these links Object.entries(linksByPage).forEach(([page, links], i) => { outputMd += ` ### ${i + 1}) [${new URL(page).pathname}](${page}) | Target Link | Link Text | |------|------| ` // @ts-expect-error links.forEach((link: TODO) => { outputMd += `| [${new URL(link.url.resolved).pathname}](${ link.url.resolved }) | "${link.html?.text?.trim().replaceAll("\n", "")}" | ` }) }) // If there were scrape errors, append to bottom of comment if (output.errors.length) { outputMd += ` ### Errors ` output.errors.forEach((error) => { outputMd += ` ${error} ` }) } return outputMd } // Main function that triggers link validation across .mdx files async function brokenLinkChecker(): Promise { if (!process.env.GITHUB_TOKEN) { throw new Error("GITHUB_TOKEN is required") } const siteUrl = process.env.VERCEL_PREVIEW_URL || "https://authjs-nextra-docs.vercel.app" const output: Output = { errors: [], links: [], pages: [], sites: [], } const options = { excludeExternalLinks: true, honorRobotExclusions: false, filterLevel: 0, excludedKeywords: [], } const siteChecker = new blc.SiteChecker(options, { error: (error: TODO) => { output.errors.push(error) }, link: (result: TODO) => { if (result.broken) { output.links.push(result) } }, end: async () => { if (output.links.length) { // DEBUG // console.debug(output.links) // Skip links that returned 308 const brokenLinksForAttention = output.links.filter( (link) => link.broken && !["HTTP_308"].includes(link.brokenReason) ) const outputMd = generateOutputMd({ errors: output.errors, links: brokenLinksForAttention, pages: [], sites: [], }) const commentUrl = await postComment( outputMd, brokenLinksForAttention.length ) // Update GitHub "check" status await updateCheckStatus(brokenLinksForAttention.length, commentUrl) brokenLinksForAttention.length && setFailed(`Found broken links`) } }, }) siteChecker.enqueue(siteUrl) } brokenLinkChecker() ================================================ FILE: .github/broken-link-checker/tsconfig.json ================================================ { "compilerOptions": { "noEmit": true, "target": "esnext", "moduleResolution": "node", "rootDir": "./src", "types": ["./index.d.ts", "node"], "strict": true, "noImplicitAny": true, "allowSyntheticDefaultImports": true } } ================================================ FILE: .github/dependabot.yml ================================================ # To get started with Dependabot version updates, you'll need to specify which # package ecosystems to update and where the package manifests are located. # Please see the documentation for all configuration options: # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates version: 2 updates: - package-ecosystem: "npm" # See documentation for possible values directory: "/" # Location of package manifests schedule: interval: "weekly" versioning-strategy: "increase" allow: - dependency-name: "oauth4webapi" - dependency-name: "jose" ================================================ FILE: .github/good-first-issue.md ================================================ This issue was marked with the `good first issue` label by a maintainer. This means that it is a good candidate for someone interested in contributing to the project, but does not know where to start. Have a look at the [Contributing Guide](https://github.com/nextauthjs/.github/blob/main/CONTRIBUTING.md) first. This will help you set up your development environment to get started. When you are ready, open a PR, and link back to this issue in the form of adding `Fixes #1234` to the PR description, where `1234` is the issue number. This will auto-close the issue when the PR gets merged, making it easier for us to keep track of what has been fixed. Please make sure that - if applicable - you add tests for the changes you make. If you have any questions, feel free to ask in the comments below or the PR. Generally, you don't need to `@mention` anyone directly, as we will get notified anyway and will respond as soon as we can) > [!NOTE] > There is no need to ask for permission "can I work on this?" Please, go ahead if there is no linked PR :slightly_smiling_face: ================================================ FILE: .github/help-needed.md ================================================ This issue was marked with the `help needed` label by a maintainer. The issue might require some digging, so it is recommended to have some experience with the project. Have a look at the [Contributing Guide](https://github.com/nextauthjs/.github/blob/main/CONTRIBUTING.md) first. This will help you set up your development environment to get started. When you are ready, open a PR, and link back to this issue in the form of adding `Fixes #1234` to the PR description, where `1234` is the issue number. This will auto-close the issue when the PR gets merged, making it easier for us to keep track of what has been fixed. Please make sure that - if applicable - you add tests for the changes you make. If you have any questions, feel free to ask in the comments below or the PR. Generally, you don't need to `@mention` anyone directly, as we will get notified anyway and will respond as soon as we can) > [!NOTE] > There is no need to ask for permission "can I work on this?" Please, go ahead if there is no linked PR :slightly_smiling_face: ================================================ FILE: .github/invalid-reproduction.md ================================================ We could not detect a valid reproduction link. **Make sure to follow the bug report template carefully.** ### Why was this issue closed? To be able to investigate, we need access to a reproduction to identify what triggered the issue. We need a link to a **public** GitHub repository. Example: ([NextAuth.js example repository](https://github.com/nextauthjs/next-auth-example)). The bug template that you filled out has a section called "Reproduction URL", which is where you should provide the link to the reproduction. - If you did not provide a link or the link you provided is not hosted on github.com outside of the next-auth organization, we will close the issue. - If you provide a link to a private repository, we will close the issue. - If you provide a link to a repository but not in the correct section, we will close the issue. ### What should I do? Depending on the reason the issue was closed, you can do the following: - If you did not provide a link hosted on github.com outside of the next-auth organization, please open a new issue with a link to such a reproduction. - If you provided a link to a private repository, please open a new issue with a link to a public repository. - If you provided a link to a repository but not in the correct section, please open a new issue with a link to a reproduction in the correct section. **In general, assume that we should not go through a lengthy onboarding process at your company code only to be able to verify an issue.** ### My repository is private and cannot make it public In most cases, a private repo will not be a sufficient **minimal reproduction**, as this codebase might contain a lot of unrelated parts that would make our investigation take longer. Please do **not** make it public. Instead, create a new repository using the templates above, adding the relevant code to reproduce the issue. Common things to look out for: - Remove any code that is not related to the issue. (pages, API Routes, components, etc.) - Remove any dependencies that are not related to the issue. - Remove any third-party service that would require us to sign up for an account to reproduce the issue. - Remove any environment variables that are not related to the issue. - Remove private packages that we do not have access to. - If the issue is not related to a monorepo specifically, try to reproduce the issue without a complex monorepo setup ### I did not open this issue, but it is relevant to me, what can I do to help? Anyone experiencing the same issue is welcome to provide a minimal reproduction following the above steps by opening a new issue. ### I think my reproduction is good enough, why aren't you looking into it quickly? We look into every issue and monitor open issues for new comments. However, sometimes we might miss a few due to the popularity/high traffic of the repository. We apologize, and kindly ask you to refrain from tagging core maintainers, as that will usually not result in increased priority. Upvoting issues to show your interest will help us prioritize and address them as quickly as possible. That said, every issue is important to us, and if an issue gets closed by accident, we encourage you to open a new one linking to the old issue and we will look into it. ### Useful Resources - [How to create a Minimal, Complete, and Verifiable example](https://stackoverflow.com/help/mcve) - [Bug report: Framework](https://github.com/nextauthjs/next-auth/issues/new?assignees=&labels=triage&projects=&template=1_bug_framework.yml) - [Bug report: Provider](https://github.com/nextauthjs/next-auth/issues/new?assignees=&labels=triage%2Cproviders&projects=&template=2_bug_provider.yml) - [Bug report: Adapter](https://github.com/nextauthjs/next-auth/issues/new?assignees=&labels=triage%2Cadapters&projects=&template=3_bug_adapter.yml) ================================================ FILE: .github/pr-labeler.yml ================================================ # https://github.com/actions/labeler#create-githublabeleryml adapters: ["packages/core/src/adapters.ts", "packages/adapter-*/**/*"] core: ["packages/core/src/**/*"] azure-tables: ["packages/adapter-azure-tables/**/*"] edgedb: ["packages/adapter-edgedb/**/*"] d1: ["packages/adapter-d1/**/*"] dgraph: ["packages/adapter-dgraph/**/*"] drizzle: ["packages/adapter-drizzle/**/*"] documentation: ["packages/docs/docs/**/*"] dynamodb: ["packages/adapter-dynamodb/**/*"] examples: ["apps/examples/**/*"] express: ["packages/frameworks-express/**/*"] fauna: ["packages/adapter-fauna/**/*"] firebase: ["packages/adapter-firebase/**/*"] hasura: ["packages/adapter-hasura/**/*"] frameworks: ["packages/frameworks-*/**/*"] mikro-orm: ["packages/adapter-mikro-orm/**/*"] mongodb: ["packages/adapter-mongodb/**/*"] neo4j: ["packages/adapter-neo4j/**/*"] next-auth: ["packages/next-auth/**/*"] pg: ["packages/adapter-pg/**/*"] neon: ["packages/adapter-neon/**/*"] playgrounds: ["apps/playgrounds/**/*"] pouchdb: ["packages/adapter-pouchdb/**/*"] prisma: ["packages/adapter-prisma/**/*"] kysely: ["packages/adapter-kysely/**/*"] providers: ["packages/core/src/providers/**/*"] sequelize: ["packages/adapter-sequelize/**/*"] solidjs: ["packages/frameworks-solid-start/**/*"] supabase: ["packages/adapter-supabase/**/*"] surrealdb: ["packages/adapter-surrealdb/**/*"] svelte: ["packages/frameworks-sveltekit/**/*"] test: ["**test**/*"] typeorm: ["packages/adapter-typeorm/**/*"] unstorage: ["packages/adapter-unstorage/**/*"] upstash-redis: ["packages/adapter-upstash-redis/**/*"] xata: ["packages/adapter-xata/**/*"] ================================================ FILE: .github/stale.yml ================================================ # https://github.com/probot/stale#usage daysUntilStale: 60 daysUntilClose: 7 exemptLabels: - pinned - security - priority - bug - triage - accepted staleLabel: stale only: issues markComment: > It looks like this issue did not receive any activity for 60 days. It will be closed in 7 days if no further activity occurs. If you think your issue is still relevant, commenting will keep it open. Thanks! closeComment: > To keep things tidy, we are closing this issue for now. If you think your issue is still relevant, leave a comment and we might reopen it. Thanks! ================================================ FILE: .github/sync.yml ================================================ nextauthjs/express-auth-example: - source: apps/examples/express dest: . deleteOrphaned: true - .github/FUNDING.yml - LICENSE nextauthjs/sveltekit-auth-example: - source: apps/examples/sveltekit dest: . deleteOrphaned: true - .github/FUNDING.yml - LICENSE nextauthjs/solid-start-auth-example: - source: "apps/examples/solid-start" dest: . deleteOrphaned: true - .github/FUNDING.yml - LICENSE nextauthjs/next-auth-example: - source: apps/examples/nextjs dest: . deleteOrphaned: true - .github/FUNDING.yml - LICENSE nextauthjs/next-auth-pages-example: - source: apps/examples/nextjs-pages dest: . deleteOrphaned: true - .github/FUNDING.yml - LICENSE nextauthjs/qwik-auth-example: - source: apps/examples/qwik dest: . deleteOrphaned: true - .github/FUNDING.yml - LICENSE ================================================ FILE: .github/version-pr/action.yml ================================================ name: "Determine version" description: "Determines npm package version based on PR number and commit SHA" outputs: version: description: "npm package version" runs: using: "node20" main: "index.js" ================================================ FILE: .github/version-pr/index.js ================================================ const fs = require("fs") const path = require("path") const core = require("@actions/core") try { const packageJSONPath = path.join( process.cwd(), `packages/${process.env.PACKAGE_PATH || "next-auth"}/package.json` ) const packageJSON = JSON.parse(fs.readFileSync(packageJSONPath, "utf8")) const sha8 = process.env.GITHUB_SHA.substring(0, 8) const prefix = "0.0.0-" const pr = process.env.PR_NUMBER const source = pr ? `pr.${pr}` : "manual" const packageVersion = `${prefix}${source}.${sha8}` packageJSON.version = packageVersion core.setOutput("version", packageVersion) fs.writeFileSync(packageJSONPath, JSON.stringify(packageJSON)) } catch (error) { core.setFailed(error.message) } ================================================ FILE: .github/workflows/broken-link-checker.yml ================================================ name: "Broken Link Checker" on: issue_comment: types: [edited] permissions: pull-requests: write checks: write jobs: broken-link-checker: runs-on: ubuntu-latest if: github.actor == 'vercel[bot]' steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 - run: corepack enable - uses: aaimio/vercel-preview-url-action@v2.2.0 id: vercel_preview_url with: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} preview_url_regexp: https.*\/(.*-authjs.vercel.app) - name: Install dependencies run: cd ./.github/broken-link-checker && pnpm install --ignore-workspace && pnpm build - name: Run link checker uses: ./.github/broken-link-checker id: broken-links env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} VERCEL_PREVIEW_URL: https://${{ steps.vercel_preview_url.outputs.vercel_preview_url }} ================================================ FILE: .github/workflows/codeql-analysis.yml ================================================ name: Code Analysis on: push: branches: [beta, next] pull_request: branches: [main] schedule: - cron: "43 17 * * 2" jobs: analyze: name: Verify runs-on: ubuntu-latest strategy: fail-fast: false matrix: language: ["javascript"] steps: - name: Checkout repository uses: actions/checkout@v3 - name: Initialize CodeQL uses: github/codeql-action/init@v2 with: languages: ${{ matrix.language }} - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v2 ================================================ FILE: .github/workflows/pr-labeler.yml ================================================ # https://github.com/actions/labeler#create-workflow name: Label Pull Requests on: pull_request_target: jobs: prs: name: Triage runs-on: ubuntu-latest steps: - uses: actions/labeler@v4 with: repo-token: "${{ secrets.GITHUB_TOKEN }}" configuration-path: ".github/pr-labeler.yml" ================================================ FILE: .github/workflows/release.yml ================================================ name: Release on: push: branches: - main - beta - next - 3.x pull_request: merge_group: # TODO: Support latest releases workflow_dispatch: inputs: name: type: choice description: Package name (npm) options: - "next-auth" - "@auth/core" - "@auth/express" - "@auth/nuxt" - "@auth/qwik" - "@auth/solid-start" - "@auth/sveltekit" - "@auth/azure-tables-adapter" - "@auth/d1-adapter" - "@auth/dgraph-adapter" - "@auth/drizzle-adapter" - "@auth/dynamodb-adapter" - "@auth/edgedb-adapter" - "@auth/fauna-adapter" - "@auth/firebase-adapter" - "@auth/hasura-adapter" - "@auth/kysely-adapter" - "@auth/mikro-orm-adapter" - "@auth/mongodb-adapter" - "@auth/neo4j-adapter" - "@auth/pg-adapter" - "@auth/pouchdb-adapter" - "@auth/prisma-adapter" - "@auth/sequelize-adapter" - "@auth/supabase-adapter" - "@auth/surrealdb-adapter" - "@auth/test-adapter" - "@auth/typeorm-adapter" - "@auth/typeorm-legacy-adapter" - "@auth/unstorage-adapter" - "@auth/upstash-redis-adapter" - "@auth/xata-adapter" permissions: id-token: write env: TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }} TURBO_TEAM: ${{ vars.TURBO_TEAM }} FORCE_COLOR: true NPM_CONFIG_PROVENANCE: true jobs: test: name: Test runs-on: ubuntu-22.04 steps: - name: Init uses: actions/checkout@v4 with: fetch-depth: 0 - name: Install pnpm uses: pnpm/action-setup@v4 - name: Setup Node uses: actions/setup-node@v4 with: node-version-file: ".nvmrc" cache: "pnpm" - name: Install dependencies run: pnpm install - name: Peek run: pnpm peek if: ${{ github.repository == 'nextauthjs/next-auth' && github.event_name == 'push' && github.ref == 'refs/heads/main' }} - name: Get base commit SHA from main id: get_base_sha run: echo "BASE_SHA=$(git merge-base origin/main HEAD)" >> $GITHUB_ENV - name: Check for changes under /packages id: check-packages run: | if git diff --name-only ${{ env.BASE_SHA }}...HEAD | grep '^packages/'; then echo "PACKAGES_CHANGES=true" >> $GITHUB_ENV else echo "PACKAGES_CHANGES=false" >> $GITHUB_ENV fi - name: Build if: ${{ env.PACKAGES_CHANGES == 'true' || github.ref == 'refs/heads/main' }} run: pnpm build - name: Check formatting run: pnpm format timeout-minutes: 15 - name: Run unit tests if: ${{ env.PACKAGES_CHANGES == 'true' || github.ref == 'refs/heads/main' }} run: pnpm test - name: Install Playwright if: github.repository == 'nextauthjs/next-auth' run: pnpm exec playwright install --with-deps chromium - name: Run E2E tests (Nextjs-Docker) continue-on-error: true if: false timeout-minutes: 15 run: cd apps/examples/nextjs-docker && pnpm test:docker - name: Run E2E tests continue-on-error: true # TODO: Make this less flakey if: ${{ env.PACKAGES_CHANGES == 'true' || github.ref == 'refs/heads/main' }} timeout-minutes: 15 env: AUTH_SECRET: ${{ secrets.AUTH_SECRET }} TEST_KEYCLOAK_USERNAME: ${{ secrets.TEST_KEYCLOAK_USERNAME }} TEST_KEYCLOAK_PASSWORD: ${{ secrets.TEST_KEYCLOAK_PASSWORD }} AUTH_KEYCLOAK_ID: ${{ secrets.AUTH_KEYCLOAK_ID }} AUTH_KEYCLOAK_SECRET: ${{ secrets.AUTH_KEYCLOAK_SECRET }} AUTH_KEYCLOAK_ISSUER: ${{ secrets.AUTH_KEYCLOAK_ISSUER }} AUTH_TRUST_HOST: 1 DEBUG: "pw:webserver" run: pnpm test:e2e - uses: actions/upload-artifact@v4 name: Upload Playwright artifacts with: name: playwright-traces path: "**/packages/next-auth/test-results/*/trace.zip" retention-days: 7 - uses: codecov/codecov-action@v4 if: always() name: Coverage with: token: ${{ secrets.CODECOV_TOKEN }} release-branch: name: Publish branch timeout-minutes: 120 runs-on: ubuntu-latest needs: test if: ${{ github.event_name == 'push' }} environment: Production steps: - name: Init uses: actions/checkout@v4 with: fetch-depth: 0 # Please upvote https://github.com/orgs/community/discussions/13836 token: ${{ secrets.GH_PAT }} - name: Install pnpm uses: pnpm/action-setup@v4 - name: Setup Node uses: actions/setup-node@v4 with: node-version-file: ".nvmrc" cache: "pnpm" - name: Install dependencies run: pnpm install - name: Publish to npm and GitHub run: pnpm release env: # Please upvote https://github.com/orgs/community/discussions/13836 GITHUB_TOKEN: ${{ secrets.GH_PAT }} NPM_TOKEN: ${{ secrets.NPM_TOKEN }} release-pr: name: Publish PR timeout-minutes: 120 runs-on: ubuntu-latest needs: test if: ${{ github.event_name == 'pull_request' }} environment: Preview steps: - name: Init uses: actions/checkout@v4 - name: Install pnpm uses: pnpm/action-setup@v4 - name: Setup Node uses: actions/setup-node@v4 with: node-version-file: ".nvmrc" cache: "pnpm" - name: Install dependencies run: pnpm install - name: Determine version uses: ./.github/version-pr id: determine-version env: PR_NUMBER: ${{ github.event.number }} - name: Publish to npm run: | cd packages/core echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> .npmrc pnpm publish --no-git-checks --access public --tag experimental env: NPM_TOKEN: ${{ secrets.NPM_TOKEN }} - name: Comment version on PR uses: NejcZdovc/comment-pr@v2 with: message: "🎉 Experimental release [published 📦️ on npm](https://npmjs.com/package/@auth/core/v/${{ env.VERSION }})!\n \ ```sh\npnpm add @auth/core@${{ env.VERSION }}\n```\n \ ```sh\nyarn add @auth/core@${{ env.VERSION }}\n```\n \ ```sh\nnpm i @auth/core@${{ env.VERSION }}\n```" env: VERSION: ${{ steps.determine-version.outputs.version }} GITHUB_TOKEN: ${{ secrets.GH_PAT }} release-manual: name: Publish manually runs-on: ubuntu-latest if: ${{ github.event_name == 'workflow_dispatch' }} steps: - name: Init uses: actions/checkout@v4 - name: Install pnpm uses: pnpm/action-setup@v4 - name: Setup Node uses: actions/setup-node@v4 with: node-version-file: ".nvmrc" cache: "pnpm" - name: Install dependencies run: pnpm install - name: Map package name to path run: | case "${{ github.event.inputs.name }}" in *"-adapter") adapter_name=$(echo "${{ github.event.inputs.name }}" | sed 's/@auth\///' | sed 's/-adapter//') echo "PACKAGE_PATH=adapter-${adapter_name}" >> $GITHUB_ENV ;; "next-auth") echo "PACKAGE_PATH=next-auth" >> $GITHUB_ENV ;; "@auth/core") echo "PACKAGE_PATH=core" >> $GITHUB_ENV ;; *) framework_name=$(echo "${{ github.event.inputs.name }}" | sed 's/@auth\///') echo "PACKAGE_PATH=frameworks-${framework_name}" >> $GITHUB_ENV ;; esac - name: Determine version uses: ./.github/version-pr id: determine-version env: PACKAGE_PATH: ${{ env.PACKAGE_PATH }} - name: Publish to npm run: | pnpm build cd packages/$PACKAGE_PATH echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> .npmrc pnpm publish --no-git-checks --access public --tag experimental echo "🎉 Experimental release published 📦️ on npm: https://npmjs.com/package/${{ github.event.inputs.name }}/v/${{ env.VERSION }}" echo "Install via: pnpm add ${{ github.event.inputs.name }}@${{ env.VERSION }}" env: NPM_TOKEN: ${{ secrets.NPM_TOKEN }} PACKAGE_PATH: ${{ env.PACKAGE_PATH }} VERSION: ${{ steps.determine-version.outputs.version }} ================================================ FILE: .github/workflows/sync-examples.yml ================================================ name: Sync Example Repositories on: push: branches: - main workflow_dispatch: jobs: sync: runs-on: ubuntu-latest steps: - name: Checkout Repository uses: actions/checkout@v3 - name: Run GitHub File Sync uses: balazsorban44/repo-file-sync-action@master with: GH_PAT: ${{ secrets.GH_PAT }} IS_FINE_GRAINED: true SKIP_PR: true ORIGINAL_MESSAGE: true ================================================ FILE: .github/workflows/triage.yml ================================================ name: Triage issue on: issues: types: [labeled, opened] issue_comment: types: [created] env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} permissions: issues: write jobs: triage: runs-on: ubuntu-latest steps: - name: Nissuer uses: balazsorban44/nissuer@1.9.2 with: label-area-prefix: "" label-area-section: "[Provider|Adapter] type(.*)### Environment" label-comments: '{ "incomplete": ".github/invalid-reproduction.md", "good first issue": ".github/good-first-issue.md", "help needed": ".github/help-needed.md" }' reproduction-link-section: "### Reproduction URL(.*)### Describe the issue" reproduction-invalid-label: "invalid reproduction" reproduction-issue-labels: "bug," reproduction-blocklist: "github.com/nextauthjs.*" ================================================ FILE: .gitignore ================================================ # Misc .DS_Store .eslintcache .env .env.local .env.development.local .env.test.local .env.production.local packages/*/.npmrc npm-debug.log* yarn-debug.log* yarn-error.log* firebase-debug.log ui-debug.log .pnpm-debug.log .husky tmp # Dependencies node_modules # Build dirs .next build dist # Generated files .cache-loader packages/next-auth/providers # copied from @auth/core packages/frameworks-*/**/providers packages/*/*.js !packages/*/typedoc.config.js packages/*/*.d.ts packages/*/*.d.ts.map packages/*/lib packages/**/generated .xata* # Qwik needs to use .mjs. REVIEW: Check back, can we just use .js? packages/*/*.mjs # Development app apps/dev/src/css apps/dev/prisma/migrations apps/dev/typeorm apps/dev/nextjs-2 # VS /.vs/slnx.sqlite-journal /.vs/slnx.sqlite /.vs .vscode/generated* # Jetbrains .idea # GitHub Actions runner /actions-runner /_work # DB dev.db* packages/adapter-prisma/prisma/dev.db packages/adapter-prisma/prisma/migrations db.sqlite packages/adapter-supabase/supabase/.branches packages/adapter-drizzle/.drizzle # Tests coverage dynamodblocal-bin firestore-debug.log test.schema.gql test-results playwright-report blob-report playwright/.cache # Turborepo .turbo # Docs docs/.next docs/manifest.mjs # Core packages/core/src/providers/provider-types.ts packages/core/lib packages/core/providers packages/core/src/lib/pages/styles.ts docs/docs/reference/core # Next.js packages/next-auth/lib packages/next-auth/providers # copied from @auth/core packages/next-auth/src/providers docs/docs/reference/nextjs # SvelteKit packages/frameworks-sveltekit/index.* packages/frameworks-sveltekit/client.* packages/frameworks-sveltekit/.svelte-kit packages/frameworks-sveltekit/package packages/frameworks-sveltekit/vite.config.js.timestamp-* packages/frameworks-sveltekit/vite.config.ts.timestamp-* docs/docs/reference/sveltekit # SolidStart docs/docs/reference/solidstart # Express docs/docs/reference/express # Adapters docs/docs/reference/adapter ## Drizzle migration folder .drizzle ================================================ FILE: .nvmrc ================================================ 22 ================================================ FILE: .prettierignore ================================================ .prettierignore .cache-loader .DS_Store .pnpm-debug.log .turbo .vscode/generated* /_work /actions-runner node_modules patches pnpm-lock.yaml .github/actions/issue-validator/index.mjs *.d.ts *.d.ts.map **/*.sh .svelte-kit .next .nuxt # --------------- Docs --------------- .next docs/pages/reference static docs/manifest.mjs # --------------- Packages --------------- coverage dist packages/**/*.cjs packages/**/*.js !packages/*/scripts/*.js # @auth/core packages/core/src/providers/provider-types.ts packages/core/src/lib/pages/styles.ts # @auth/sveltekit packages/frameworks-sveltekit/package packages/frameworks-sveltekit/vite.config.{js,ts}.timestamp-* # @auth/express packages/frameworks-express/providers # next-auth packages/next-auth/src/providers/provider-types.ts packages/next-auth/css/index.css # Adapters .branches db.sqlite dev.db dynamodblocal-bin firebase-debug.log firestore-debug.log migrations test.schema.gql # --------------- Apps --------------- # Examples should have their own Prettier config since they are templates too apps/example-sveltekit # Development app apps/dev/prisma apps/dev/migrations apps/dev/typeorm ================================================ FILE: .vscode/extensions.json ================================================ { "recommendations": ["esbenp.prettier-vscode", "bradlc.vscode-tailwindcss"] } ================================================ FILE: .vscode/settings.json ================================================ { "typescript.tsdk": "node_modules/typescript/lib", "openInGitHub.remote.branch": "main", "typescript.preferences.importModuleSpecifierEnding": "js", "editor.formatOnSave": true, "editor.defaultFormatter": "esbenp.prettier-vscode" } ================================================ FILE: .vscode/snippets.code-snippets ================================================ { "oauth2-spec": { "description": "Markdown link to OAuth 2 specification", "scope": "typescript", "prefix": "oauth2", "body": ["[OAuth 2](https://datatracker.ietf.org/doc/html/rfc6749)"], }, "oidc-spec": { "description": "Markdown link to OpenID Connect specification", "scope": "typescript", "prefix": "oidc", "body": ["[OIDC](https://openid.net/specs/openid-connect-core-1_0.html)"], }, } ================================================ FILE: LICENSE ================================================ ISC License Copyright (c) 2022-2024, Balázs Orbán Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ================================================ FILE: README.md ================================================


Auth.js

Authentication for the Web.

Open Source. Full Stack. Own Your Data.

X (formerly known Twitter) NPM next-auth@latest release Downloads GitHub Stars TypeScript

Auth.js is a set of open-source packages that are built on standard Web APIs for authentication in modern applications with any framework on any platform in any JS runtime.

> Auth js is now part of [Better Auth](https://better-auth.com/blog/authjs-joins-better-auth). We recommend new projects to start with Better Auth unless there are some very specific feature gaps (most notably stateless session management without a database). ## Features ### Flexible and easy to use - Designed to work with any OAuth service, it supports 2.0+, OIDC - Built-in support for [many popular sign-in services](https://github.com/nextauthjs/next-auth/tree/main/packages/core/src/providers) - Email/Passwordless authentication - Passkeys/WebAuthn support - Bring Your Database - or none! - stateless authentication with any backend (Active Directory, LDAP, etc.) - Runtime-agnostic, runs anywhere! (Docker, Node.js, Serverless, etc.) ### Own your data Auth.js can be used with or without a database. - An open-source solution that allows you to keep control of your data - Built-in support for [MySQL, MariaDB, Postgres, Microsoft SQL Server, MongoDB, SQLite, GraphQL, etc.](https://adapters.authjs.dev) - Works great with databases from popular hosting providers ### Secure by default - Promotes the use of passwordless sign-in mechanisms - Designed to be secure by default and encourage best practices for safeguarding user data - Uses Cross-Site Request Forgery (CSRF) Tokens on POST routes (sign in, sign out) - Default cookie policy aims for the most restrictive policy appropriate for each cookie - When JSON Web Tokens are used, they are encrypted by default (JWE) with A256CBC-HS512 - Features tab/window syncing and session polling to support short-lived sessions - Attempts to implement the latest guidance published by [Open Web Application Security Project](https://owasp.org) Advanced configuration allows you to define your routines to handle controlling what accounts are allowed to sign in, for encoding and decoding JSON Web Tokens and to set custom cookie security policies and session properties, so you can control who can sign in and how often sessions have to be re-validated. ### TypeScript Auth.js libraries are written with type safety in mind. [Check out the docs](https://authjs.dev/getting-started/typescript) for more information. ## Security If you think you have found a vulnerability (or are not sure) in Auth.js or any of the related packages (i.e. Adapters), we ask you to read our [Security Policy](https://authjs.dev/security) to reach out responsibly. Please do not open Pull Requests/Issues/Discussions before consulting with us. ## Acknowledgments [Auth.js is made possible thanks to all of its contributors.](https://authjs.dev/contributors)
## Contributing We're open to all community contributions! If you'd like to contribute in any way, please first read our [Contributing Guide](https://github.com/nextauthjs/.github/blob/main/CONTRIBUTING.md). ## License ISC ================================================ FILE: apps/dev/express/.gitignore ================================================ # API keys and secrets .env # Dependency directory node_modules # Editors .idea *.iml .vscode/settings.json # OS metadata .DS_Store Thumbs.db # Ignore built ts files dist/**/* # Ignore built css files /public/css/output.css ================================================ FILE: apps/dev/express/.prettierignore ================================================ .DS_Store node_modules /dist /.turbo /package .env .env.* !.env.example # Ignore files for PNPM, NPM and YARN pnpm-lock.yaml package-lock.json yarn.lock ================================================ FILE: apps/dev/express/README.md ================================================ > The example repository is maintained from a [monorepo](https://github.com/nextauthjs/next-auth/tree/main/apps/examples/express). Pull Requests should be opened against [`nextauthjs/next-auth`](https://github.com/nextauthjs/next-auth).


Auth.js Example App with Express

Open Source. Full Stack. Own Your Data.

npm Bundle Size Downloads TypeScript

# Documentation - [express.authjs.dev](https://express.authjs.dev) ================================================ FILE: apps/dev/express/api/index.js ================================================ import { app } from "../src/app.js" export default app ================================================ FILE: apps/dev/express/package.json ================================================ { "name": "express-auth-app", "description": "Express + Auth.js Developer app", "type": "module", "private": true, "scripts": { "start": "node --env-file=.env dist/server.js", "clean": "rm -rf dist", "build": "pnpm build:ts && pnpm build:css", "build:ts": "tsc", "build:css": "tailwindcss -i ./public/css/style.css -o ./public/css/output.css", "dev": "tsx watch --env-file=.env src/server.ts & pnpm build:css -w", "lint": "eslint src/*.ts --fix", "prettier": "prettier src/*.ts --write" }, "author": "Auth.js Team (https://authjs.dev/contributors)", "license": "MIT", "dependencies": { "@auth/express": "workspace:*", "express": "^4.20.0", "morgan": "^1.10.0", "pug": "^3.0.2" }, "devDependencies": { "@prettier/plugin-pug": "^3.0.0", "@types/express": "^4.17.21", "@types/morgan": "^1.9.9", "@types/pug": "^2.0.10", "tsx": "^4.7.3", "typescript": "5.4.5" } } ================================================ FILE: apps/dev/express/public/css/style.css ================================================ @tailwind base; @tailwind components; @tailwind utilities; ================================================ FILE: apps/dev/express/src/app.ts ================================================ import express, { type Request, type Response } from "express" import logger from "morgan" import { join } from "node:path" import { errorHandler, errorNotFoundHandler, } from "./middleware/error.middleware.js" import { authenticatedUser, currentSession, } from "./middleware/auth.middleware.js" import { ExpressAuth } from "@auth/express" import { authConfig } from "./config/auth.config.js" import * as pug from "pug" export const app = express() app.set("port", process.env.PORT || 3004) // @ts-expect-error (https://stackoverflow.com/questions/45342307/error-cannot-find-module-pug) app.engine("pug", pug.__express) app.set("views", join(import.meta.dirname, "..", "views")) app.set("view engine", "pug") // Trust Proxy for Proxies (Heroku, Render.com, Docker behind Nginx, etc) // https://stackoverflow.com/questions/40459511/in-express-js-req-protocol-is-not-picking-up-https-for-my-secure-link-it-alwa app.set("trust proxy", true) app.use(logger("dev")) // Serve static files // NB: Uncomment this out if you want Express to serve static files for you vs. using a // hosting provider which does so for you (for example through a CDN). // app.use(express.static(join(import.meta.dirname, "..", "public"))) // Parse incoming requests data app.use(express.urlencoded({ extended: true })) app.use(express.json()) // Set session in res.locals app.use(currentSession) // Set up ExpressAuth to handle authentication // IMPORTANT: It is highly encouraged set up rate limiting on this route app.use("/api/auth/*", ExpressAuth(authConfig)) // Routes app.get("/protected", async (_req: Request, res: Response) => { res.render("protected", { session: res.locals.session }) }) app.get( "/api/protected", authenticatedUser, async (_req: Request, res: Response) => { res.json(res.locals.session) } ) app.get("/", async (_req: Request, res: Response) => { res.render("index", { title: "Express Auth Example", user: res.locals.session?.user, }) }) // Error handlers app.use(errorNotFoundHandler) app.use(errorHandler) ================================================ FILE: apps/dev/express/src/config/auth.config.ts ================================================ import Apple from "@auth/express/providers/apple" import Auth0 from "@auth/express/providers/auth0" import AzureB2C from "@auth/express/providers/azure-ad-b2c" import BoxyHQSAML from "@auth/express/providers/boxyhq-saml" import Cognito from "@auth/express/providers/cognito" import Coinbase from "@auth/express/providers/coinbase" import Discord from "@auth/express/providers/discord" import Dropbox from "@auth/express/providers/dropbox" import Facebook from "@auth/express/providers/facebook" import GitHub from "@auth/express/providers/github" import Gitlab from "@auth/express/providers/gitlab" import Google from "@auth/express/providers/google" import Hubspot from "@auth/express/providers/hubspot" import Keycloak from "@auth/express/providers/keycloak" import LinkedIn from "@auth/express/providers/linkedin" import Netlify from "@auth/express/providers/netlify" import Okta from "@auth/express/providers/okta" import Passage from "@auth/express/providers/passage" import Pinterest from "@auth/express/providers/pinterest" import Reddit from "@auth/express/providers/reddit" import Slack from "@auth/express/providers/slack" import Spotify from "@auth/express/providers/spotify" import Twitch from "@auth/express/providers/twitch" import Twitter from "@auth/express/providers/twitter" import WorkOS from "@auth/express/providers/workos" import Zoom from "@auth/express/providers/zoom" export const authConfig = { trustHost: true, debug: process.env.NODE_ENV !== "production" ? true : false, providers: [ Apple, Auth0, AzureB2C({ clientId: process.env.AUTH_AZURE_AD_B2C_ID, clientSecret: process.env.AUTH_AZURE_AD_B2C_SECRET, issuer: process.env.AUTH_AZURE_AD_B2C_ISSUER, }), BoxyHQSAML({ clientId: "dummy", clientSecret: "dummy", issuer: process.env.AUTH_BOXYHQ_SAML_ISSUER, }), Cognito, Coinbase, Discord, Dropbox, Facebook, GitHub, Gitlab, Google, Hubspot, Keycloak, LinkedIn, Netlify, Okta, Passage, Pinterest, Reddit, Slack, Spotify, Twitch, Twitter, WorkOS({ connection: process.env.AUTH_WORKOS_CONNECTION!, }), Zoom, ], } ================================================ FILE: apps/dev/express/src/errors.ts ================================================ export class HttpError extends Error { status: number constructor(status: number, message: string) { super(message) this.status = status } } export class NotFoundError extends HttpError { constructor(message: string, status = 404) { super(status, message) this.name = "NotFoundError" } } ================================================ FILE: apps/dev/express/src/middleware/auth.middleware.ts ================================================ import { getSession } from "@auth/express" import { authConfig } from "../config/auth.config.js" import type { NextFunction, Request, Response } from "express" export async function authenticatedUser( req: Request, res: Response, next: NextFunction ) { const session = res.locals.session ?? (await getSession(req, authConfig)) res.locals.session = session if (session) { return next() } res.status(400).json({ message: "Not Authenticated" }) } export async function currentSession( req: Request, res: Response, next: NextFunction ) { const session = await getSession(req, authConfig) res.locals.session = session return next() } ================================================ FILE: apps/dev/express/src/middleware/error.middleware.ts ================================================ import type { NextFunction, Request, Response } from "express" import { HttpError, NotFoundError } from "../errors.js" export const errorHandler = ( err: HttpError | Error, _req: Request, res: Response, _next: NextFunction ): void => { // Render the error page res.status(("status" in err && err.status) || 500) res.render("error", { title: "status" in err ? err.status : err.name, message: err.message, }) } export const errorNotFoundHandler = ( _req: Request, _res: Response, next: NextFunction ): void => { next(new NotFoundError("Not Found")) } ================================================ FILE: apps/dev/express/src/server.ts ================================================ import { app } from "./app.js" const port = app.get("port") const server = app.listen(port, () => { console.log(`Listening on port ${port}`) }) export default server ================================================ FILE: apps/dev/express/tsconfig.json ================================================ { "compilerOptions": { "module": "NodeNext", "esModuleInterop": true, "target": "esnext", "noImplicitAny": true, "moduleResolution": "NodeNext", "sourceMap": true, "outDir": "dist", "baseUrl": ".", "skipLibCheck": true, "strict": true }, "include": ["src/**/*.ts"], "exclude": ["node_modules"] } ================================================ FILE: apps/dev/express/views/error.pug ================================================ extends layout block content h1=title p=message ================================================ FILE: apps/dev/express/views/index.pug ================================================ extends layout block content h1=title p | This is an example site to demonstrate how to use #{ ' ' } a(href="https://expressjs.com/") Express | #{ ' ' } with #{ ' ' } a(href="https://authjs.dev/reference/express") Express Auth | | for authentication. ================================================ FILE: apps/dev/express/views/layout.pug ================================================ doctype html html head title=title meta(name="viewport" content="width=device-width, initial-scale=1.0") body div div if session div if session.user.image img(src=`${session.user.image}` style="width:64px;border-radius:50%;") span | Signed in as #{ ' ' } strong= session.user.email || session.user.name a( href="/api/auth/signout" ) Sign out else span You are not signed in #{ ' ' } a#sign-indiv( href="/api/auth/signin" ) Sign in nav ul li a(href="/") Home li a(href="/protected") Protected li a(href="/api/protected") Protected (API) block content ================================================ FILE: apps/dev/express/views/protected.pug ================================================ extends layout block content if session h1 Protected page p | This is a protected content. You can access this content because you are | signed in. p Session expiry: #{ session.expires ? session.expires : '' } else h1 Access Denied p | You must be #{ ' ' } a(href="/api/auth/signin") signed in | #{ ' ' } to view this page ================================================ FILE: apps/dev/nextjs/.gitignore ================================================ node_modules/ /test-results/ /playwright-report/ /playwright/.cache/ dbschema/edgeql-js ================================================ FILE: apps/dev/nextjs/.vscode/settings.json ================================================ { "typescript.tsdk": "../../../node_modules/.pnpm/typescript@4.9.4/node_modules/typescript/lib", "typescript.enablePromptUseWorkspaceTsdk": true } ================================================ FILE: apps/dev/nextjs/README.md ================================================ # NextAuth.js Development App This folder contains a Next.js app using NextAuth.js for local development. See the following section on how to start: [Setting up local environment ](https://github.com/nextauthjs/.github/blob/main/CONTRIBUTING.md#setting-up-local-environment) ================================================ FILE: apps/dev/nextjs/app/api/protected/route.ts ================================================ import { auth } from "auth" import { NextResponse } from "next/server" export const GET = auth(function GET(req) { if (req.auth) return NextResponse.json(req.auth) return NextResponse.json({ message: "Not authenticated" }, { status: 401 }) }) ================================================ FILE: apps/dev/nextjs/app/auth/[...nextauth]/route.ts ================================================ import { handlers } from "auth" export const { GET, POST } = handlers // export const runtime = "edge" ================================================ FILE: apps/dev/nextjs/app/client.tsx ================================================ "use client" import { signIn, signOut, useSession } from "next-auth/react" import { useRouter } from "next/navigation" export default function Client() { const { data: session, update, status } = useSession() const router = useRouter() return (

Client Component

Session

          {status === "loading"
            ? "Loading..."
            : JSON.stringify(session, null, 2)}
        
{session ? ( <> ) : ( <> )}
) } ================================================ FILE: apps/dev/nextjs/app/dashboard/page.tsx ================================================ export default function Page() { return

This page is protected.

} ================================================ FILE: apps/dev/nextjs/app/layout.tsx ================================================ import { auth, signIn, signOut, unstable_update as update } from "auth" import Footer from "components/footer" import { Header } from "components/header" import styles from "components/header.module.css" import "./styles.css" import { AuthError } from "next-auth" export default function RootLayout(props: { children: React.ReactNode }) { return (
{props.children}