Compare commits

..

23 Commits

Author SHA1 Message Date
GitHub Actions
1a23e41bca chore(release): bump package version(s) [skip ci] 2023-09-01 12:13:47 +00:00
Balázs Orbán
9dfef763fc chore: bump pnpm 2023-09-01 13:54:59 +02:00
Balázs Orbán
f53c16a454 chore: fix supabase tests 2023-09-01 13:53:18 +02:00
Thang Vu
e999511a2e docs: add framework tabs in getting started & guide (#8470) 2023-09-01 13:45:16 +02:00
Rexford Essilfie
2707f9ebfe docs: fix failing docs build (#8463)
chore: lint azure-devops provider
2023-08-31 14:35:40 +01:00
Evgenii Perminov
35977bf132 fix(providers): Update type oidc for Linkedin (#8345)
* linked in provider options and profile update

* interface update

* removed unchecked property access

* unncessary async

* revert changes to v4

* fallback to default properties

* Update packages/core/src/providers/linkedin.ts

---------

Co-authored-by: Thang Vu <hi@thvu.dev>
2023-08-29 11:31:18 +07:00
Pavel Fomchenkov
578ff21d7e feat(providers): add Azure DevOps provider (#4698) 2023-08-27 20:50:59 +07:00
Balázs Orbán
ba238796b8 Merge branch 'main' of github.com:nextauthjs/next-auth 2023-08-25 11:56:22 +02:00
Balázs Orbán
56b27de3be docs: fix edit links for auto-generated pages 2023-08-25 11:56:18 +02:00
Ahmed Abdelbaset
0bc9b4fe5a docs: Correct a typo that is causing a broken link. (#8405)
fix broken link
2023-08-25 10:43:44 +01:00
Balázs Orbán
327061ce70 chore: revert typedoc 2023-08-25 11:39:11 +02:00
Balázs Orbán
2ed407d6a5 fix: allow Prisma v5 as peer dependency 2023-08-25 11:32:38 +02:00
Balázs Orbán
e743340612 chore: suppress TS warning in sveltekit 2023-08-25 11:26:20 +02:00
Balázs Orbán
5140857256 chore: fix deps, upgrade docs dependencies 2023-08-25 11:21:55 +02:00
Balázs Orbán
9c6f81308c chore: bump pnpm and typescript 2023-08-24 20:31:33 +02:00
JunChao
66184c55eb docs: change var to import to solve using https-proxy-agent have the error: "HttpsProxyAgent is not a constructor" (#8400)
Update corporate-proxy.md
2023-08-24 14:54:23 +02:00
Balázs Orbán
07599ba41d Merge branch 'main' of github.com:nextauthjs/next-auth 2023-08-24 11:20:49 +02:00
Balázs Orbán
c5fc3e66ad docs: rename @next-auth/* to @auth/* 2023-08-24 11:20:44 +02:00
Balázs Orbán
5dfec49ee8 chore: rename @next-auth/* packages to @auth/* 2023-08-24 11:18:04 +02:00
brunsten
b20182c5fe fix: handle trailing slash when parsing the url (#8383)
Co-authored-by: Marcus Brunsten <bruno@Marcuss-MacBook-Rd.local>
2023-08-22 15:59:52 +02:00
Balázs Orbán
a6d9459a64 chore: mention that no repro = convert to discussion 2023-08-21 10:28:01 +01:00
GitHub Actions
99035b98f9 chore(release): bump package version(s) [skip ci] 2023-08-18 08:13:39 +00:00
Balázs Orbán
fabb0525d1 fix(adapters): use built-in is() to identify db type (#8342)
* fix(adapters): use built-in `is()` to identify db type

* remove unused .then

* fix imports
2023-08-18 09:11:33 +01:00
93 changed files with 9189 additions and 6597 deletions

View File

@@ -11,7 +11,7 @@ body:
### Important :exclamation:
_Providing incorrect/insufficient information or skipping steps to reproduce the issue may result in closing the issue or converting to a discussion without further explanation._
_Providing incorrect/insufficient information or skipping steps to reproduce the issue will result in closing the issue and/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.

View File

@@ -31,6 +31,7 @@ body:
- "Authentik"
- "Azure Active Directory"
- "Azure Active Directory B2C"
- "Azure DevOps"
- "Battlenet"
- "Beyond Identity"
- "Box"

View File

@@ -24,7 +24,6 @@ body:
- "@auth/dgraph-adapter"
- "@auth/drizzle-adapter"
- "@auth/dynamodb-adapter"
- "@auth/drizzle-adapter"
- "@auth/fauna-adapter"
- "@auth/firebase-adapter"
- "@auth/kysely-adapter"

View File

@@ -15,7 +15,7 @@
"@sveltejs/kit": "next",
"svelte": "3.55.0",
"svelte-check": "2.10.2",
"typescript": "4.9.4",
"typescript": "5.2.2",
"vite": "4.0.5"
},
"dependencies": {

View File

@@ -26,6 +26,6 @@
"devDependencies": {
"@types/node": "^18.16.2",
"@types/react": "^18.2.0",
"typescript": "^5.0.4"
"typescript": "5.2.2"
}
}

View File

@@ -13,7 +13,7 @@
"solid-start-node": "^0.2.9",
"solid-start-vercel": "^0.2.9",
"tailwindcss": "^3.2.4",
"typescript": "^4.8.3",
"typescript": "5.2.2",
"vite": "^3.1.0"
},
"dependencies": {

View File

@@ -18,7 +18,7 @@
"@sveltejs/kit": "next",
"svelte": "3.55.0",
"svelte-check": "2.10.2",
"typescript": "4.9.4",
"typescript": "5.2.2",
"vite": "4.0.1"
},
"dependencies": {

View File

@@ -2,6 +2,9 @@
title: Credentials authentication
---
import Tabs from "@theme/Tabs"
import TabItem from "@theme/TabItem"
Auth.js is built in a way that is flexible to integrate it with any authentication back-end you or your company may already have.
This library has been designed to handle the user session client-wise, to support multiple authentication methods (OAuth, Email, etc...) so that you're not forced to run your own authentication service.
@@ -16,34 +19,49 @@ The functionality provided for credentials based authentication is intentionally
Integrating the Credentials Provider is as simple as initializing it in the Auth.js configuration file:
```ts title="pages/api/auth/[...nextauth].ts"
import NextAuth from "next-auth"
import CredentialsProvider from "next-auth/providers/credentials"
<Tabs groupId="frameworks" queryString>
<TabItem value="next" label="Next.js" default>
export default NextAuth({
providers: [
CredentialsProvider({
async authorize(credentials) {
const authResponse = await fetch("/users/login", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(credentials),
})
```ts title="pages/api/auth/[...nextauth].ts"
import NextAuth from "next-auth"
import CredentialsProvider from "next-auth/providers/credentials"
if (!authResponse.ok) {
return null
}
export default NextAuth({
providers: [
CredentialsProvider({
async authorize(credentials) {
const authResponse = await fetch("/users/login", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(credentials),
})
const user = await authResponse.json()
if (!authResponse.ok) {
return null
}
return user
},
}),
],
})
```
const user = await authResponse.json()
return user
},
}),
],
})
```
</TabItem>
<TabItem value="sveltekit" label="SvelteKit">
TODO SvelteKit
</TabItem>
<TabItem value="solidstart" label="SolidStart">
TODO SolidStart
</TabItem>
<TabItem value="core" label="Vanilla (No Framework)">
TODO Core
</TabItem>
</Tabs>
:::note
Check the [Credentials Provider options](/reference/core/providers_credentials) for further customization

View File

@@ -7,6 +7,8 @@ import startPageImg from "./img/email-tutorial-start.png"
import checkPageImg from "./img/email-tutorial-check.png"
import mailboxImg from "./img/email-tutorial-mailbox.png"
import loggedInImg from "./img/email-tutorial-logged.png"
import Tabs from "@theme/Tabs"
import TabItem from "@theme/TabItem"
Aside from authenticating users in Auth.js via [OAuth](/getting-started/oauth-tutorial), you can also enable the option to authenticate them via "magic links". These are links that are sent to the user's email and when clicking on them they'll sign up the user automatically.
@@ -64,26 +66,43 @@ Note that we're also specifying from which domain email are going to be sent fro
Nice! We're getting there. Now we need to read supply this values as the configuration for our Email Provider. Open `pages/api/auth/[...nextauth].ts` and do the following:
```ts title="pages/api/auth/[...nextauth].ts"
import NextAuth from "next-auth"
import Email from "next-auth/providers/email"
<Tabs groupId="frameworks" queryString>
<TabItem value="next" label="Next.js" default>
export default NextAuth({
providers: [
Email({
server: {
host: process.env.SMTP_HOST,
port: Number(process.env.SMTP_PORT),
auth: {
user: process.env.SMTP_USER,
pass: process.env.SMTP_PASSWORD,
```ts title="pages/api/auth/[...nextauth].ts"
import NextAuth from "next-auth"
import Email from "next-auth/providers/email"
export default NextAuth({
providers: [
Email({
server: {
host: process.env.SMTP_HOST,
port: Number(process.env.SMTP_PORT),
auth: {
user: process.env.SMTP_USER,
pass: process.env.SMTP_PASSWORD,
},
},
},
from: process.env.EMAIL_FROM,
}),
],
})
```
from: process.env.EMAIL_FROM,
}),
],
})
```
</TabItem>
<TabItem value="sveltekit" label="SvelteKit">
TODO SvelteKit
</TabItem>
<TabItem value="solidstart" label="SolidStart">
TODO SolidStart
</TabItem>
<TabItem value="core" label="Vanilla (No Framework)">
TODO Core
</TabItem>
</Tabs>
## 3. Setting up an adapter
@@ -139,30 +158,46 @@ export default clientPromise
And now let's reference this new adapter from our Auth.js configuration file:
```diff title="pages/api/auth/[...nextauth].ts"
import NextAuth from "next-auth"
import EmailProvider from "next-auth/providers/email"
+ import { MongoDBAdapter } from "@auth/mongodb-adapter"
+ import clientPromise from "../../../lib/mongodb/client"
<Tabs groupId="frameworks" queryString>
<TabItem value="next" label="Next.js" default>
```diff title="pages/api/auth/[...nextauth].ts"
import NextAuth from "next-auth"
import EmailProvider from "next-auth/providers/email"
+ import { MongoDBAdapter } from "@auth/mongodb-adapter"
+ import clientPromise from "../../../lib/mongodb/client"
export default NextAuth({
secret: process.env.NEXTAUTH_SECRET,
+ adapter: MongoDBAdapter(clientPromise),
providers: [
EmailProvider({
server: {
host: process.env.EMAIL_SERVER_HOST,
port: process.env.EMAIL_SERVER_PORT,
auth: {
user: process.env.EMAIL_SERVER_USER,
pass: process.env.EMAIL_SERVER_PASSWORD
}
},
from: process.env.EMAIL_FROM
}),
],
})
```
</TabItem>
<TabItem value="sveltekit" label="SvelteKit">
TODO SvelteKit
</TabItem>
<TabItem value="solidstart" label="SolidStart">
TODO SolidStart
</TabItem>
<TabItem value="core" label="Vanilla (No Framework)">
TODO Core
</TabItem>
</Tabs>
export default NextAuth({
secret: process.env.NEXTAUTH_SECRET,
+ adapter: MongoDBAdapter(clientPromise),
providers: [
EmailProvider({
server: {
host: process.env.EMAIL_SERVER_HOST,
port: process.env.EMAIL_SERVER_PORT,
auth: {
user: process.env.EMAIL_SERVER_USER,
pass: process.env.EMAIL_SERVER_PASSWORD
}
},
from: process.env.EMAIL_FROM
}),
],
})
```
## 4. Wiring all together

View File

@@ -100,7 +100,7 @@ NextAuth.js provides [`useSession()`](/reference/react/#usesession) - a [React H
```ts title="pages/_app.tsx"
import { SessionProvider } from "next-auth/react"
import type { AppProps } from 'next/app'
import type { AppProps } from "next/app"
export default function App({
Component,
@@ -218,7 +218,7 @@ The callback URL we insert should have the following pattern:
In this case, given we want to try our authentication working locally on our machine and we're using **GitHub** as our OAuth provider, it'll be:
<Tabs groupId="frameworks">
<Tabs groupId="frameworks" queryString>
<TabItem value="next" label="Next.js" default>
```
@@ -274,7 +274,7 @@ Note that, for each provider, the configuration process will be similar to what
2. Create create your OAuth application within it
3. Set the callback URL
4. Get the Client ID and Generate a Client Secret
:::
:::
## 3. Wiring all together
@@ -289,7 +289,7 @@ GITHUB_SECRET=67890
Here is our server configuration file again:
<Tabs groupId="frameworks">
<Tabs groupId="frameworks" queryString>
<TabItem value="next" label="Next.js" default>
```ts title="pages/api/auth/[...nextauth].ts"

View File

@@ -9,6 +9,9 @@ https://github.com/nextauthjs/next-auth-example
---
import Tabs from "@theme/Tabs"
import TabItem from "@theme/TabItem"
## Adapters
If you're writing your own custom Adapter, you can take advantage of the types to make sure your implementation conforms to what's expected:
@@ -46,30 +49,45 @@ This will work in code editors with a strong TypeScript integration like VSCode
Let's look at `Session`:
```ts title="pages/api/auth/[...nextauth].ts"
import NextAuth from "next-auth"
<Tabs groupId="frameworks" queryString>
<TabItem value="next" label="Next.js" default>
export default NextAuth({
callbacks: {
session({ session, token, user }) {
return session // The return type will match the one returned in `useSession()`
```ts title="pages/api/auth/[...nextauth].ts"
import NextAuth from "next-auth"
export default NextAuth({
callbacks: {
session({ session, token, user }) {
return session // The return type will match the one returned in `useSession()`
},
},
},
})
```
})
```
```ts title="pages/index.ts"
import { useSession } from "next-auth/react"
```ts title="pages/index.ts"
import { useSession } from "next-auth/react"
export default function IndexPage() {
// `session` will match the returned value of `callbacks.session()` from `NextAuth()`
const { data: session } = useSession()
export default function IndexPage() {
// `session` will match the returned value of `callbacks.session()` from `NextAuth()`
const { data: session } = useSession()
return (
// Your component
)
}
```
return (
// Your component
)
}
```
</TabItem>
<TabItem value="sveltekit" label="SvelteKit">
TODO SvelteKit
</TabItem>
<TabItem value="solidstart" label="SolidStart">
TODO SolidStart
</TabItem>
<TabItem value="core" label="Vanilla (No Framework)">
TODO Core
</TabItem>
</Tabs>
To extend/augment this type, create a `types/next-auth.d.ts` file in your project:

View File

@@ -8,6 +8,6 @@ An **Adapter** in Auth.js connects your application to whatever database or back
When using a database, you can still use JWT for session handling for fast access. See the [`session.strategy`](/reference/configuration/auth-config#session) option. Read about the trade-offs of JWT in the [FAQ](/concepts/faq#json-web-tokens).
:::
We have a list of official adapters that are distributed as their own packages under the `@next-auth/{name}-adapter` namespace. Their source code is available in their various adapters package directories at [`nextauthjs/next-auth`](https://github.com/nextauthjs/next-auth/tree/main/packages):
We have a list of official adapters that are distributed as their own packages under the `@auth/{name}-adapter` namespace. Their source code is available in their various adapters package directories at [`nextauthjs/next-auth`](https://github.com/nextauthjs/next-auth/tree/main/packages):
- [All available adapters](/reference/adapters)

View File

@@ -12,7 +12,7 @@ If you want to pass data such as an Access Token or User ID to the browser when
You can specify a handler for any of the callbacks below.
```js title="pages/api/auth/[...nextauth].js"s
```js title="auth.js"
callbacks: {
async signIn({ user, account, profile, email, credentials }) {
return true
@@ -35,7 +35,7 @@ The documentation below shows how to implement each callback, their default beha
Use the `signIn()` callback to control if a user is allowed to sign in.
```js title="pages/api/auth/[...nextauth].js"
```js title="auth.js"
callbacks: {
async signIn({ user, account, profile, email, credentials }) {
const isAllowedToSignIn = true
@@ -79,7 +79,7 @@ By default only URLs on the same URL as the site are allowed, you can use the re
The default redirect callback looks like this:
```js title="pages/api/auth/[...nextauth].js"
```js title="auth.js"
callbacks: {
async redirect({ url, baseUrl }) {
// Allows relative callback URLs
@@ -107,7 +107,7 @@ Requests to `/api/auth/signin`, `/api/auth/session` and calls to `getSession()`,
The contents _user_, _account_, _profile_ and _isNewUser_ will vary depending on the provider and on if you are using a database or not. You can persist data such as User ID, OAuth Access Token in this token. To make it available in the browser, check out the [`session()` callback](#session-callback) as well.
```js title="pages/api/auth/[...nextauth].js"
```js title="auth.js"
callbacks: {
async jwt({ token, account }) {
// Persist the OAuth access_token to the token right after signin
@@ -132,7 +132,7 @@ e.g. `getSession()`, `useSession()`, `/api/auth/session`
- When using database sessions, the User object is passed as an argument.
- When using JSON Web Tokens for sessions, the JWT payload is provided instead.
```js title="pages/api/auth/[...nextauth].js"
```js title="auth.js"
callbacks: {
async session({ session, token, user }) {
// Send properties to the client, like an access_token from a provider.

View File

@@ -2,6 +2,14 @@
title: Custom Initialization
---
import Tabs from "@theme/Tabs"
import TabItem from "@theme/TabItem"
<Tabs groupId="frameworks" queryString>
<TabItem value="next" label="Next.js" default>
In Next.js, you can define an API route that will catch all requests that begin with a certain path. Conveniently, this is called [Catch all API routes](https://nextjs.org/docs/api-routes/dynamic-api-routes#catch-all-api-routes).
When you define a `/pages/api/auth/[...nextauth]` JS/TS file, you instruct Auth.js that every API request beginning with `/api/auth/*` should be handled by the code written in the `[...nextauth]` file.
@@ -120,3 +128,15 @@ This way of initializing `NextAuth` is very powerful, but should be used sparing
:::warning
Changing parts of the request that is essential to `NextAuth` to do it's job - like messing with the [default cookies](/reference/configuration/auth-config#cookies) - can have unforeseen consequences, and have the potential to introduce security holes if done incorrectly. Only change those if you understand consequences.
:::
</TabItem>
<TabItem value="sveltekit" label="SvelteKit">
TODO SvelteKit
</TabItem>
<TabItem value="solidstart" label="SolidStart">
TODO SolidStart
</TabItem>
<TabItem value="core" label="Vanilla (No Framework)">
TODO Core
</TabItem>
</Tabs>

View File

@@ -2,13 +2,16 @@
title: Pages
---
import Tabs from "@theme/Tabs"
import TabItem from "@theme/TabItem"
Auth.js automatically creates simple, unbranded authentication pages for handling Sign in, Sign out, Email Verification and displaying error messages.
The options displayed on the sign-up page are automatically generated based on the providers specified in the options passed to Auth.js.
To add a custom login page, you can use the `pages` option:
```javascript title="pages/api/auth/[...nextauth].js"
```javascript title="auth.js"
...
pages: {
signIn: '/auth/signin',
@@ -76,6 +79,11 @@ In addition, you can define the background color and text color of the button wi
In order to get the available authentication providers and the URLs to use for them, you can make a request to the API endpoint `/api/auth/providers`:
<Tabs groupId="frameworks" queryString>
<TabItem value="next" label="Next.js" default>
```jsx title="pages/auth/signin.js"
import { getProviders, signIn } from "next-auth/react"
@@ -100,6 +108,18 @@ export async function getServerSideProps(context) {
}
}
```
</TabItem>
<TabItem value="sveltekit" label="SvelteKit">
TODO SvelteKit
</TabItem>
<TabItem value="solidstart" label="SolidStart">
TODO SolidStart
</TabItem>
<TabItem value="core" label="Vanilla (No Framework)">
TODO Core
</TabItem>
</Tabs>
There is another, more fully styled example signin page available [here](https://github.com/ndom91/next-auth-example-sign-in-page).
@@ -107,6 +127,10 @@ There is another, more fully styled example signin page available [here](https:/
If you create a custom sign in form for email sign in, you will need to submit both fields for the **email** address and **csrfToken** from **/api/auth/csrf** in a POST request to **/api/auth/signin/email**.
<Tabs groupId="frameworks" queryString>
<TabItem value="next" label="Next.js" default>
```jsx title="pages/auth/email-signin.js"
import { getCsrfToken } from "next-auth/react"
@@ -131,6 +155,18 @@ export async function getServerSideProps(context) {
}
```
</TabItem>
<TabItem value="sveltekit" label="SvelteKit">
TODO SvelteKit
</TabItem>
<TabItem value="solidstart" label="SolidStart">
TODO SolidStart
</TabItem>
<TabItem value="core" label="Vanilla (No Framework)">
TODO Core
</TabItem>
</Tabs>
You can also use the `signIn()` function which will handle obtaining the CSRF token for you:
```js
@@ -141,6 +177,10 @@ signIn("email", { email: "jsmith@example.com" })
If you create a sign in form for credentials based authentication, you will need to pass a **csrfToken** from **/api/auth/csrf** in a `POST` request to **/api/auth/callback/credentials**.
<Tabs groupId="frameworks" queryString>
<TabItem value="next" label="Next.js" default>
```jsx title="pages/auth/credentials-signin.js"
import { getCsrfToken } from "next-auth/react"
@@ -170,6 +210,18 @@ export async function getServerSideProps(context) {
}
```
</TabItem>
<TabItem value="sveltekit" label="SvelteKit">
TODO SvelteKit
</TabItem>
<TabItem value="solidstart" label="SolidStart">
TODO SolidStart
</TabItem>
<TabItem value="core" label="Vanilla (No Framework)">
TODO Core
</TabItem>
</Tabs>
You can also use the `signIn()` function which will handle obtaining the CSRF token for you:
```js

View File

@@ -2,6 +2,9 @@
title: Refresh token rotation
---
import Tabs from "@theme/Tabs"
import TabItem from "@theme/TabItem"
Refresh token rotation is the practice of updating an `access_token` on behalf of the user, without requiring interaction (eg.: re-sign in). `access_token`s are usually issued for a limited time. After they expire, the service verifying them will ignore the value. Instead of asking the user to sign in again to obtain a new `access_token`, certain providers support exchanging a `refresh_token` for a new `access_token`, renewing the expiry time. Let's see how this can be achieved.
:::note
@@ -26,6 +29,20 @@ Using the [jwt](../../reference/core/types#jwt) and [session](../../reference/co
Below is a sample implementation using Google's Identity Provider. Please note that the OAuth 2.0 request in the `refreshAccessToken()` function will vary between different providers, but the core logic should remain similar.
<Tabs groupId="frameworks" queryString>
<TabItem value="next" label="Next.js">
TODO Next.js
</TabItem>
<TabItem value="sveltekit" label="SvelteKit">
TODO SvelteKit
</TabItem>
<TabItem value="solidstart" label="SolidStart">
TODO SolidStart
</TabItem>
<TabItem value="core" label="Vanilla (No Framework)" default>
```ts
import { Auth } from "@auth/core"
import { type TokenSet } from "@auth/core/types"
@@ -109,10 +126,27 @@ declare module "@auth/core/jwt" {
}
```
</TabItem>
</Tabs>
#### Database strategy
Using the database strategy is very similar, but instead of preserving the `access_token` and `refresh_token`, we save it, well, in the database.
<Tabs groupId="frameworks" queryString>
<TabItem value="next" label="Next.js">
What
</TabItem>
<TabItem value="sveltekit" label="SvelteKit">
TODO SvelteKit
</TabItem>
<TabItem value="solidstart" label="SolidStart">
TODO SolidStart
</TabItem>
<TabItem value="core" label="Vanilla (No Framework)" default>
```ts
import { Auth } from "@auth/core"
import { type TokenSet } from "@auth/core/types"
@@ -195,6 +229,8 @@ declare module "@auth/core/jwt" {
}
}
```
</TabItem>
</Tabs>
### Client Side

View File

@@ -22,7 +22,7 @@ This can be done by simply returning a `200` response on `HEAD` requests at the
For example
```jsx title="/pages/api/auth/[...nextauth].js"
```jsx title="auth.js"
import type { NextApiRequest, NextApiResponse } from "next"
import NextAuth from "next-auth"

View File

@@ -24,7 +24,7 @@ index 77161bd..1082fba 100644
var _openidClient = require("openid-client");
+var HttpsProxyAgent = require("https-proxy-agent");
+import { HttpsProxyAgent } from 'https-proxy-agent';
+
async function openidClient(options) {
const provider = options.provider;

View File

@@ -35,7 +35,7 @@ If you return an object it will be persisted to the JSON Web Token and the user
The Credentials provider's `authorize()` method also provides the request object as the second parameter (see the example below).
```js title="pages/api/auth/[...nextauth].js"
```js title="auth.js"
import CredentialsProvider from "next-auth/providers/credentials";
...
providers: [

View File

@@ -17,15 +17,15 @@ We will also refer to the [Prisma Adapter](/reference/adapter/prisma). A [databa
## Setup
First, if you do not have a project using Auth.js, clone and set up a basic Auth.js project like the one [provided in](https://github.com/nextauthjs/next-auth-example.git) our example repo](https://github.com/nextauthjs/next-auth-example.git).
First, if you do not have a project using Auth.js, clone and set up a basic Auth.js project like the one [provided in our example repo](https://github.com/nextauthjs/next-auth-example).
- Install the [Prisma Adapter](/reference/adapter/prisma)
- Generate an API key from your cloud Email provider of choice and add it to your `.env.*` file. For example, mine is going to be called `SENDGRID_API`
- Add the following configuration to your configuration file:
```js title="pages/api/auth/[...nextauth].ts"
```js title="auth.ts"
import NextAuth, { NextAuthOptions } from "next-auth"
import { PrismaAdapter } from "@next-auth/prisma-adapter"
import { PrismaAdapter } from "@auth/prisma-adapter"
import { PrismaClient } from "@prisma/client"
const prisma = new PrismaClient()
@@ -42,16 +42,15 @@ export const authOptions: NextAuthOptions = {
],
}
export default NextAuth(authOptions)
```
Next, all that's left to do is call the HTTP endpoint from our cloud email provider and pass it the required metadata like the `to` address, the email `body`, and any other fields we may need to include.
As mentioned earlier, we're going to be using SendGrid in this example, so the appropriate endpoint is `https://api.sendgrid.com/v3/mail/send` ([more info](https://docs.sendgrid.com/for-developers/sending-email/api-getting-started)). Therefore, we're going to pull out some of the important information from the `params` argument and use it in a `fetch()` call to the previously mentioned SendGrid API.
```js title="pages/api/auth/[...nextauth].ts"
```js title="auth.ts"
import NextAuth, { NextAuthOptions } from "next-auth"
import { PrismaAdapter } from "@next-auth/prisma-adapter"
import { PrismaAdapter } from "@auth/prisma-adapter"
import { PrismaClient } from "@prisma/client"
const prisma = new PrismaClient()

View File

@@ -46,7 +46,7 @@ Create an `.env` file to the root of your project and add the connection string
Now you can add the email provider like this:
```js {3} title="pages/api/auth/[...nextauth].js"
```js {3} title="auth.js"
import EmailProvider from "next-auth/providers/email";
...
providers: [
@@ -71,7 +71,7 @@ EMAIL_FROM=noreply@example.com
Now you can add the provider settings to the NextAuth options object in the Email Provider.
```js title="pages/api/auth/[...nextauth].js"
```js title="auth.js"
import EmailProvider from "next-auth/providers/email";
...
providers: [
@@ -101,7 +101,7 @@ You can fully customize the sign in email that is sent by passing a custom funct
e.g.
```js {3} title="pages/api/auth/[...nextauth].js"
```js {3} title="auth.js"
import EmailProvider from "next-auth/providers/email";
...
providers: [
@@ -206,7 +206,7 @@ If you want to generate great looking email client compatible HTML with React, c
By default, we are generating a random verification token. You can define a `generateVerificationToken` method in your provider options if you want to override it:
```js title="pages/api/auth/[...nextauth].js"
```js title="auth.js"
providers: [
EmailProvider({
async generateVerificationToken() {

View File

@@ -213,7 +213,25 @@ const docusaurusConfig = {
breadcrumbs: false,
routeBasePath: "/",
sidebarPath: require.resolve("./sidebars.js"),
editUrl: "https://github.com/nextauthjs/next-auth/edit/main/docs",
/**
*
* @param {{
* version: string;
* versionDocsDirPath: string;
* docPath: string;
* permalink: string;
* locale: string;
*}} params
*/
editUrl({ docPath }) {
// TODO: support other packages, fix directory links like "providers"
if (docPath.includes("reference/core")) {
const file = docPath.split("reference/core/")[1].replace(".md", ".ts").replace("_", "/")
const base = `https://github.com/nextauthjs/next-auth/edit/main/packages/core/src/${file}`
return base
}
return "https://github.com/nextauthjs/next-auth/edit/main/docs"
},
lastVersion: "current",
showLastUpdateAuthor: true,
showLastUpdateTime: true,

View File

@@ -27,15 +27,15 @@
"styled-components": "5.3.6"
},
"devDependencies": {
"@docusaurus/core": "2.3.1",
"@docusaurus/eslint-plugin": "2.3.1",
"@docusaurus/module-type-aliases": "2.3.1",
"@docusaurus/preset-classic": "2.3.1",
"@docusaurus/theme-common": "2.3.1",
"@docusaurus/theme-mermaid": "2.3.1",
"@docusaurus/types": "2.3.1",
"@docusaurus/core": "2.4.1",
"@docusaurus/eslint-plugin": "2.4.1",
"@docusaurus/module-type-aliases": "2.4.1",
"@docusaurus/preset-classic": "2.4.1",
"@docusaurus/theme-common": "2.4.1",
"@docusaurus/theme-mermaid": "2.4.1",
"@docusaurus/types": "2.4.1",
"docusaurus-plugin-typedoc": "1.0.0-next.5",
"typedoc": "^0.24.4",
"typedoc": "^0.24.8",
"typedoc-plugin-markdown": "4.0.0-next.6"
},
"browserslist": {

View File

@@ -6,7 +6,7 @@
"scripts": {
"build:app": "turbo run build --filter=next-auth-app",
"build:docs": "turbo run build --filter=docs",
"build": "turbo run build --filter=next-auth --filter=@next-auth/* --filter=@auth/* --no-deps",
"build": "turbo run build --filter=next-auth --filter=@auth/* --no-deps",
"test": "turbo run test --concurrency=1 --filter=[HEAD^1] --filter=./packages/* --filter=!@*upstash* --filter=!*dynamodb-* --filter=!*app*",
"clean": "turbo run clean --no-cache",
"dev:db": "turbo run dev --parallel --continue --filter=next-auth-app...",
@@ -44,12 +44,12 @@
"prettier": "2.8.1",
"prettier-plugin-svelte": "^2.8.1",
"turbo": "^1.10.12",
"typescript": "4.9.4"
"typescript": "5.2.2"
},
"engines": {
"node": "^16.13.0 || ^18.12.0"
},
"packageManager": "pnpm@7.23.0",
"packageManager": "pnpm@8.7.1",
"funding": [
{
"type": "github",

View File

@@ -41,13 +41,13 @@
"test": "./tests/test.sh"
},
"devDependencies": {
"@next-auth/adapter-test": "workspace:*",
"@next-auth/tsconfig": "workspace:*",
"@auth/adapter-test": "workspace:*",
"@auth/tsconfig": "workspace:*",
"@types/jest": "^26.0.24",
"@types/jsonwebtoken": "^8.5.5",
"@types/node-fetch": "^2.5.11",
"jest": "^27.4.3",
"ts-jest": "^27.0.3",
"typescript": "5.2.2",
"undici": "5.22.1"
},
"dependencies": {
@@ -55,6 +55,6 @@
"jsonwebtoken": "^8.5.1"
},
"jest": {
"preset": "@next-auth/adapter-test/jest"
"preset": "@auth/adapter-test/jest"
}
}
}

View File

@@ -1,7 +1,7 @@
import { DgraphAdapter, format } from "../src"
import { client as dgraphClient } from "../src/lib/client"
import * as fragments from "../src/lib/graphql/fragments"
import { runBasicTests } from "@next-auth/adapter-test"
import { runBasicTests } from "@auth/adapter-test"
import fs from "fs"
import path from "path"

View File

@@ -1,5 +1,5 @@
{
"extends": "@next-auth/tsconfig/tsconfig.base.json",
"extends": "@auth/tsconfig/tsconfig.base.json",
"compilerOptions": {
"allowJs": true,
"baseUrl": ".",

View File

@@ -1,6 +1,6 @@
{
"name": "@auth/drizzle-adapter",
"version": "0.3.1",
"version": "0.3.2",
"description": "Drizzle adapter for Auth.js.",
"homepage": "https://authjs.dev",
"repository": "https://github.com/nextauthjs/next-auth",
@@ -48,8 +48,8 @@
"@auth/core": "workspace:*"
},
"devDependencies": {
"@next-auth/adapter-test": "workspace:*",
"@next-auth/tsconfig": "workspace:*",
"@auth/adapter-test": "workspace:*",
"@auth/tsconfig": "workspace:*",
"@types/better-sqlite3": "^7.6.4",
"@types/uuid": "^8.3.3",
"better-sqlite3": "^8.4.0",
@@ -60,6 +60,6 @@
"postgres": "^3.3.4"
},
"jest": {
"preset": "@next-auth/adapter-test/jest"
"preset": "@auth/adapter-test/jest"
}
}
}

View File

@@ -16,19 +16,14 @@
* @module @auth/drizzle-adapter
*/
import { MySqlTableFn } from "drizzle-orm/mysql-core/index.js"
import { PgTableFn } from "drizzle-orm/pg-core/index.js"
import { SQLiteTableFn } from "drizzle-orm/sqlite-core/index.js"
import { MySqlDatabase, MySqlTableFn } from "drizzle-orm/mysql-core"
import { PgDatabase, PgTableFn } from "drizzle-orm/pg-core"
import { BaseSQLiteDatabase, SQLiteTableFn } from "drizzle-orm/sqlite-core"
import { mySqlDrizzleAdapter } from "./lib/mysql.js"
import { pgDrizzleAdapter } from "./lib/pg.js"
import { SQLiteDrizzleAdapter } from "./lib/sqlite.js"
import {
isMySqlDatabase,
isPgDatabase,
isSQLiteDatabase,
SqlFlavorOptions,
TableFn,
} from "./lib/utils.js"
import { SqlFlavorOptions, TableFn } from "./lib/utils.js"
import { is } from "drizzle-orm"
import type { Adapter } from "@auth/core/adapters"
@@ -260,18 +255,15 @@ export function DrizzleAdapter<SqlFlavor extends SqlFlavorOptions>(
db: SqlFlavor,
table?: TableFn<SqlFlavor>
): Adapter {
if (isMySqlDatabase(db)) {
// We need to cast to unknown since the type overlaps (PScale is MySQL based)
if (is(db, MySqlDatabase)) {
return mySqlDrizzleAdapter(db, table as MySqlTableFn)
}
if (isPgDatabase(db)) {
} else if (is(db, PgDatabase)) {
return pgDrizzleAdapter(db, table as PgTableFn)
}
if (isSQLiteDatabase(db)) {
} else if (is(db, BaseSQLiteDatabase)) {
return SQLiteDrizzleAdapter(db, table as SQLiteTableFn)
}
throw new Error("Unsupported database type in Auth.js Drizzle adapter.")
throw new Error(
`Unsupported database type (${typeof db}) in Auth.js Drizzle adapter.`
)
}

View File

@@ -6,10 +6,10 @@ import {
primaryKey,
varchar,
MySqlTableFn,
MySqlDatabase,
} from "drizzle-orm/mysql-core"
import type { Adapter, AdapterAccount } from "@auth/core/adapters"
import type { MySql2Database } from "drizzle-orm/mysql2"
export function createTables(mySqlTable: MySqlTableFn) {
const users = mySqlTable("user", {
@@ -77,7 +77,7 @@ export function createTables(mySqlTable: MySqlTableFn) {
export type DefaultSchema = ReturnType<typeof createTables>
export function mySqlDrizzleAdapter(
client: MySql2Database<Record<string, never>>,
client: InstanceType<typeof MySqlDatabase>,
tableFn = defaultMySqlTableFn
): Adapter {
const { users, accounts, sessions, verificationTokens } =
@@ -164,10 +164,7 @@ export function mySqlDrizzleAdapter(
.then((res) => res[0])
},
async linkAccount(rawAccount) {
await client
.insert(accounts)
.values(rawAccount)
.then((res) => res[0])
await client.insert(accounts).values(rawAccount)
},
async getUserByAccount(account) {
const dbAccount =

View File

@@ -6,9 +6,9 @@ import {
primaryKey,
integer,
PgTableFn,
PgDatabase,
} from "drizzle-orm/pg-core"
import type { PostgresJsDatabase } from "drizzle-orm/postgres-js"
import type { Adapter, AdapterAccount } from "@auth/core/adapters"
export function createTables(pgTable: PgTableFn) {
@@ -68,7 +68,7 @@ export function createTables(pgTable: PgTableFn) {
export type DefaultSchema = ReturnType<typeof createTables>
export function pgDrizzleAdapter(
client: PostgresJsDatabase<Record<string, never>>,
client: InstanceType<typeof PgDatabase>,
tableFn = defaultPgTableFn
): Adapter {
const { users, accounts, sessions, verificationTokens } =

View File

@@ -67,7 +67,7 @@ export function createTables(sqliteTable: SQLiteTableFn) {
export type DefaultSchema = ReturnType<typeof createTables>
export function SQLiteDrizzleAdapter(
client: BaseSQLiteDatabase<any, any>,
client: InstanceType<typeof BaseSQLiteDatabase>,
tableFn = defaultSqliteTableFn
): Adapter {
const { users, accounts, sessions, verificationTokens } =

View File

@@ -39,17 +39,3 @@ export type TableFn<Flavor> = Flavor extends AnyMySqlDatabase
: Flavor extends AnySQLiteDatabase
? SQLiteTableFn
: AnySQLiteTable
export function isMySqlDatabase(
db: any
): db is MySqlDatabase<any, any, any, any> {
return db instanceof MySqlDatabase
}
export function isPgDatabase(db: any): db is PgDatabase<any, any, any> {
return db instanceof PgDatabase
}
export function isSQLiteDatabase(db: any): db is AnySQLiteDatabase {
return db instanceof BaseSQLiteDatabase
}

View File

@@ -1,5 +1,5 @@
{
"extends": "@next-auth/tsconfig/tsconfig.base.json",
"extends": "@auth/tsconfig/tsconfig.base.json",
"compilerOptions": {
"allowJs": true,
"baseUrl": ".",

View File

@@ -49,12 +49,12 @@
"devDependencies": {
"@aws-sdk/client-dynamodb": "^3.36.1",
"@aws-sdk/lib-dynamodb": "^3.36.1",
"@next-auth/adapter-test": "workspace:*",
"@next-auth/tsconfig": "workspace:*",
"@auth/adapter-test": "workspace:*",
"@auth/tsconfig": "workspace:*",
"@shelf/jest-dynamodb": "^2.1.0",
"jest": "^27.4.3"
},
"dependencies": {
"@auth/core": "workspace:*"
}
}
}

View File

@@ -1,7 +1,7 @@
import { DynamoDB } from "@aws-sdk/client-dynamodb"
import { DynamoDBDocument } from "@aws-sdk/lib-dynamodb"
import { DynamoDBAdapter } from "../src"
import { runBasicTests } from "@next-auth/adapter-test"
import { runBasicTests } from "@auth/adapter-test"
import { format } from "../src/"
const config = {
endpoint: "http://127.0.0.1:8000",

View File

@@ -1,5 +1,5 @@
{
"extends": "@next-auth/tsconfig/tsconfig.base.json",
"extends": "@auth/tsconfig/tsconfig.base.json",
"compilerOptions": {
"allowJs": true,
"baseUrl": ".",

View File

@@ -51,12 +51,12 @@
},
"devDependencies": {
"@fauna-labs/fauna-schema-migrate": "^2.1.3",
"@next-auth/adapter-test": "workspace:*",
"@next-auth/tsconfig": "workspace:*",
"@auth/adapter-test": "workspace:*",
"@auth/tsconfig": "workspace:*",
"faunadb": "^4.3.0",
"jest": "^27.4.3"
},
"jest": {
"preset": "@next-auth/adapter-test/jest"
"preset": "@auth/adapter-test/jest"
}
}
}

View File

@@ -1,5 +1,5 @@
import { collections, FaunaAdapter, format, indexes, query } from "../src"
import { runBasicTests } from "@next-auth/adapter-test"
import { runBasicTests } from "@auth/adapter-test"
import { Client as FaunaClient, Get, Match, Ref } from "faunadb"
const client = new FaunaClient({

View File

@@ -1,5 +1,5 @@
{
"extends": "@next-auth/tsconfig/tsconfig.base.json",
"extends": "@auth/tsconfig/tsconfig.base.json",
"compilerOptions": {
"allowJs": true,
"baseUrl": ".",

View File

@@ -48,10 +48,10 @@
"firebase-admin": "^11.4.1"
},
"devDependencies": {
"@next-auth/adapter-test": "workspace:*",
"@next-auth/tsconfig": "workspace:*",
"@auth/adapter-test": "workspace:*",
"@auth/tsconfig": "workspace:*",
"firebase-admin": "^11.4.1",
"firebase-tools": "^11.16.1",
"jest": "^29.3.1"
}
}
}

View File

@@ -1,4 +1,4 @@
import { runBasicTests } from "@next-auth/adapter-test"
import { runBasicTests } from "@auth/adapter-test"
import { FirestoreAdapter, type FirebaseAdapterConfig } from "../src"
import {

View File

@@ -1,4 +1,4 @@
import config from "@next-auth/adapter-test/jest/jest-preset.js"
import config from "@auth/adapter-test/jest/jest-preset.js"
//TODO: update rest of the packages to Jest 29+
const {testURL, ...rest} = config

View File

@@ -1,5 +1,5 @@
{
"extends": "@next-auth/tsconfig/tsconfig.base.json",
"extends": "@auth/tsconfig/tsconfig.base.json",
"compilerOptions": {
"allowJs": true,
"baseUrl": ".",

View File

@@ -40,8 +40,8 @@
"kysely": "^0.26.1"
},
"devDependencies": {
"@next-auth/adapter-test": "workspace:*",
"@next-auth/tsconfig": "workspace:*",
"@auth/adapter-test": "workspace:*",
"@auth/tsconfig": "workspace:*",
"@types/better-sqlite3": "^7.6.3",
"@types/pg": "^8.6.5",
"better-sqlite3": "^8.2.0",
@@ -51,6 +51,6 @@
"pg": "^8.10.0"
},
"jest": {
"preset": "@next-auth/adapter-test/jest"
"preset": "@auth/adapter-test/jest"
}
}
}

View File

@@ -1,4 +1,4 @@
import { runBasicTests } from "@next-auth/adapter-test"
import { runBasicTests } from "@auth/adapter-test"
import { Pool } from "pg"
import {
Kysely,

View File

@@ -1,5 +1,5 @@
{
"extends": "@next-auth/tsconfig/tsconfig.base.json",
"extends": "@auth/tsconfig/tsconfig.base.json",
"compilerOptions": {
"allowJs": true,
"baseUrl": ".",

View File

@@ -46,14 +46,14 @@
"devDependencies": {
"@mikro-orm/core": "^5",
"@mikro-orm/sqlite": "^5",
"@next-auth/adapter-test": "workspace:*",
"@next-auth/tsconfig": "workspace:*",
"@auth/adapter-test": "workspace:*",
"@auth/tsconfig": "workspace:*",
"jest": "^29"
},
"dependencies": {
"@auth/core": "workspace:*"
},
"jest": {
"preset": "@next-auth/adapter-test/jest"
"preset": "@auth/adapter-test/jest"
}
}
}

View File

@@ -13,7 +13,7 @@ import {
Options,
types,
} from "@mikro-orm/core"
import { runBasicTests } from "@next-auth/adapter-test"
import { runBasicTests } from "@auth/adapter-test"
globalThis.crypto ??= require("node:crypto").webcrypto

View File

@@ -1,5 +1,5 @@
{
"extends": "@next-auth/tsconfig/tsconfig.base.json",
"extends": "@auth/tsconfig/tsconfig.base.json",
"compilerOptions": {
"allowJs": true,
"baseUrl": ".",

View File

@@ -45,12 +45,12 @@
"mongodb": "^5 || ^4"
},
"devDependencies": {
"@next-auth/adapter-test": "workspace:*",
"@next-auth/tsconfig": "workspace:*",
"@auth/adapter-test": "workspace:*",
"@auth/tsconfig": "workspace:*",
"jest": "^27.4.3",
"mongodb": "^5.1.0"
},
"jest": {
"preset": "@next-auth/adapter-test/jest"
"preset": "@auth/adapter-test/jest"
}
}
}

View File

@@ -1,4 +1,4 @@
import { runBasicTests } from "@next-auth/adapter-test"
import { runBasicTests } from "@auth/adapter-test"
import { defaultCollections, format, MongoDBAdapter, _id } from "../src"
import { MongoClient } from "mongodb"
const name = "custom-test"

View File

@@ -1,4 +1,4 @@
import { runBasicTests } from "@next-auth/adapter-test"
import { runBasicTests } from "@auth/adapter-test"
import { defaultCollections, format, MongoDBAdapter, _id } from "../src"
import { MongoClient } from "mongodb"

View File

@@ -1,5 +1,5 @@
{
"extends": "@next-auth/tsconfig/tsconfig.base.json",
"extends": "@auth/tsconfig/tsconfig.base.json",
"compilerOptions": {
"allowJs": true,
"baseUrl": ".",

View File

@@ -44,8 +44,8 @@
"neo4j-driver": "^4.0.0 || ^5.7.0"
},
"devDependencies": {
"@next-auth/adapter-test": "workspace:*",
"@next-auth/tsconfig": "workspace:*",
"@auth/adapter-test": "workspace:*",
"@auth/tsconfig": "workspace:*",
"@types/uuid": "^8.3.3",
"jest": "^27.4.3",
"neo4j-driver": "^5.7.0"
@@ -54,6 +54,6 @@
"@auth/core": "workspace:*"
},
"jest": {
"preset": "@next-auth/adapter-test/jest"
"preset": "@auth/adapter-test/jest"
}
}
}

View File

@@ -1,5 +1,5 @@
import * as neo4j from "neo4j-driver"
import { runBasicTests } from "@next-auth/adapter-test"
import { runBasicTests } from "@auth/adapter-test"
import statements from "./resources/statements"
import { Neo4jAdapter, format } from "../src"

View File

@@ -1,5 +1,5 @@
{
"extends": "@next-auth/tsconfig/tsconfig.base.json",
"extends": "@auth/tsconfig/tsconfig.base.json",
"compilerOptions": {
"allowJs": true,
"baseUrl": ".",

View File

@@ -45,8 +45,8 @@
"@auth/core": "workspace:*"
},
"devDependencies": {
"@next-auth/adapter-test": "workspace:*",
"@next-auth/tsconfig": "workspace:*",
"@auth/adapter-test": "workspace:*",
"@auth/tsconfig": "workspace:*",
"@types/pouchdb": "^6.4.0",
"jest": "^27.4.3",
"pouchdb": "^8.0.1",
@@ -54,6 +54,6 @@
"pouchdb-find": "^8.0.1"
},
"jest": {
"preset": "@next-auth/adapter-test/jest"
"preset": "@auth/adapter-test/jest"
}
}
}

View File

@@ -1,4 +1,4 @@
import { runBasicTests } from "@next-auth/adapter-test"
import { runBasicTests } from "@auth/adapter-test"
import {
createIndexes,
PouchDBAdapter,

View File

@@ -1,5 +1,5 @@
{
"extends": "@next-auth/tsconfig/tsconfig.base.json",
"extends": "@auth/tsconfig/tsconfig.base.json",
"compilerOptions": {
"allowJs": true,
"baseUrl": ".",

View File

@@ -1,6 +1,6 @@
{
"name": "@auth/prisma-adapter",
"version": "1.0.1",
"version": "1.0.2",
"description": "Prisma adapter for Auth.js",
"homepage": "https://authjs.dev/reference/adapter/prisma",
"repository": "https://github.com/nextauthjs/next-auth",
@@ -51,17 +51,17 @@
"@auth/core": "workspace:*"
},
"peerDependencies": {
"@prisma/client": ">=2.26.0 || >=3 || >=4"
"@prisma/client": ">=2.26.0 || >=3 || >=4 || >=5"
},
"devDependencies": {
"@next-auth/adapter-test": "workspace:*",
"@next-auth/tsconfig": "workspace:*",
"@prisma/client": "^4.15.0",
"@auth/adapter-test": "workspace:*",
"@auth/tsconfig": "workspace:*",
"@prisma/client": "^5.2.0",
"jest": "^27.4.3",
"mongodb": "^4.4.0",
"prisma": "^4.15.0"
"prisma": "^5.2.0"
},
"jest": {
"preset": "@next-auth/adapter-test/jest"
"preset": "@auth/adapter-test/jest"
}
}

View File

@@ -1,4 +1,4 @@
import { randomUUID, runBasicTests } from "@next-auth/adapter-test"
import { randomUUID, runBasicTests } from "@auth/adapter-test"
import { PrismaClient } from "@prisma/client"
import { PrismaAdapter } from "../src"
import { ObjectId } from "mongodb"

View File

@@ -1,5 +1,5 @@
{
"extends": "@next-auth/tsconfig/tsconfig.base.json",
"extends": "@auth/tsconfig/tsconfig.base.json",
"compilerOptions": {
"allowJs": true,
"baseUrl": ".",

View File

@@ -43,12 +43,12 @@
"sequelize": "^6.6.5"
},
"devDependencies": {
"@next-auth/adapter-test": "workspace:*",
"@next-auth/tsconfig": "workspace:*",
"@auth/adapter-test": "workspace:*",
"@auth/tsconfig": "workspace:*",
"jest": "^27.4.3",
"sequelize": "^6.6.5"
},
"jest": {
"preset": "@next-auth/adapter-test/jest"
"preset": "@auth/adapter-test/jest"
}
}
}

View File

@@ -1,5 +1,5 @@
import { Sequelize, DataTypes } from "sequelize"
import { runBasicTests } from "@next-auth/adapter-test"
import { runBasicTests } from "@auth/adapter-test"
import SequelizeAdapter, { models } from "../src"
const sequelize = new Sequelize({

View File

@@ -1,5 +1,5 @@
{
"extends": "@next-auth/tsconfig/tsconfig.base.json",
"extends": "@auth/tsconfig/tsconfig.base.json",
"compilerOptions": {
"allowJs": true,
"baseUrl": ".",

View File

@@ -42,12 +42,12 @@
"@supabase/supabase-js": "^2.0.5"
},
"devDependencies": {
"@next-auth/adapter-test": "workspace:^0.0.0",
"@next-auth/tsconfig": "workspace:^0.0.0",
"@auth/adapter-test": "workspace:^0.0.0",
"@auth/tsconfig": "workspace:^0.0.0",
"@supabase/supabase-js": "^2.0.5",
"jest": "^27.4.3"
},
"jest": {
"preset": "@next-auth/adapter-test/jest"
"preset": "@auth/adapter-test/jest"
}
}
}

View File

@@ -1,4 +1,4 @@
import { runBasicTests } from "@next-auth/adapter-test"
import { runBasicTests } from "@auth/adapter-test"
import { format, SupabaseAdapter } from "../src"
import { createClient } from "@supabase/supabase-js"
import type {

View File

@@ -2,7 +2,7 @@
# install Supabase CLI when run on CI
if [ "$CI" = true ]; then
wget -q -O supabase.deb https://github.com/supabase/cli/releases/download/v0.29.0/supabase_0.29.0_linux_amd64.deb
wget -q -O supabase.deb https://github.com/supabase/cli/releases/download/v1.91.1/supabase_1.91.1_linux_amd64.deb
sudo dpkg -i supabase.deb
fi
@@ -17,3 +17,4 @@ if npx jest; then
else
supabase stop && exit 1
fi

View File

@@ -1,5 +1,5 @@
{
"extends": "@next-auth/tsconfig/tsconfig.base.json",
"extends": "@auth/tsconfig/tsconfig.base.json",
"compilerOptions": {
"allowJs": true,
"baseUrl": ".",

View File

@@ -1,5 +1,5 @@
{
"name": "@next-auth/adapter-test",
"name": "@auth/adapter-test",
"version": "0.0.0",
"repository": "https://github.com/nextauthjs/next-auth.git",
"contributors": [
@@ -21,6 +21,6 @@
"@types/nodemailer": "^6.4.4",
"jest": "^29.5.0",
"ts-jest": "^27.0.3",
"typescript": "^4.2.4"
"typescript": "5.2.2"
}
}

View File

@@ -50,8 +50,8 @@
"@auth/core": "workspace:*"
},
"devDependencies": {
"@next-auth/adapter-test": "workspace:*",
"@next-auth/tsconfig": "workspace:*",
"@auth/adapter-test": "workspace:*",
"@auth/tsconfig": "workspace:*",
"jest": "^27.4.3",
"mssql": "^7.2.1",
"mysql": "^2.18.1",
@@ -59,7 +59,7 @@
"sqlite3": "^5.0.8",
"typeorm": "0.3.15",
"typeorm-naming-strategies": "^4.1.0",
"typescript": "^4.7.4"
"typescript": "5.2.2"
},
"peerDependencies": {
"mssql": "^6.2.1 || 7",
@@ -83,6 +83,6 @@
}
},
"jest": {
"preset": "@next-auth/adapter-test/jest"
"preset": "@auth/adapter-test/jest"
}
}
}

View File

@@ -1,6 +1,6 @@
import { DataSource } from "typeorm"
import type { DataSourceOptions } from "typeorm"
import type { TestOptions } from "@next-auth/adapter-test"
import type { TestOptions } from "@auth/adapter-test"
import * as defaultEntities from "../src/entities"
import { parseDataSourceConfig } from "../src/utils"

View File

@@ -1,5 +1,5 @@
{
"extends": "@next-auth/tsconfig/tsconfig.base.json",
"extends": "@auth/tsconfig/tsconfig.base.json",
"compilerOptions": {
"allowJs": true,
"baseUrl": ".",

View File

@@ -44,8 +44,8 @@
"@upstash/redis": "^1.0.1"
},
"devDependencies": {
"@next-auth/adapter-test": "workspace:*",
"@next-auth/tsconfig": "workspace:*",
"@auth/adapter-test": "workspace:*",
"@auth/tsconfig": "workspace:*",
"@types/uuid": "^8.3.3",
"@upstash/redis": "^1.0.1",
"dotenv": "^10.0.0",
@@ -54,6 +54,6 @@
"next-auth": "workspace:*"
},
"jest": {
"preset": "@next-auth/adapter-test/jest"
"preset": "@auth/adapter-test/jest"
}
}
}

View File

@@ -1,6 +1,6 @@
import "isomorphic-fetch"
import { Redis } from "@upstash/redis"
import { runBasicTests } from "@next-auth/adapter-test"
import { runBasicTests } from "@auth/adapter-test"
import { hydrateDates, UpstashRedisAdapter } from "../src"
import "dotenv/config"

View File

@@ -1,5 +1,5 @@
{
"extends": "@next-auth/tsconfig/tsconfig.base.json",
"extends": "@auth/tsconfig/tsconfig.base.json",
"compilerOptions": {
"allowJs": true,
"baseUrl": ".",

View File

@@ -43,13 +43,13 @@
"@xata.io/client": ">=0.13.0"
},
"devDependencies": {
"@next-auth/adapter-test": "workspace:^0.0.0",
"@next-auth/tsconfig": "workspace:^0.0.0",
"@auth/adapter-test": "workspace:^0.0.0",
"@auth/tsconfig": "workspace:^0.0.0",
"jest": "^27.4.3",
"@xata.io/client": "^0.13.0",
"typescript": "^4.7.4"
"typescript": "5.2.2"
},
"jest": {
"preset": "@next-auth/adapter-test/jest"
"preset": "@auth/adapter-test/jest"
}
}
}

View File

@@ -1,5 +1,5 @@
import "isomorphic-fetch"
import { runBasicTests } from "@next-auth/adapter-test"
import { runBasicTests } from "@auth/adapter-test"
import "dotenv/config"
import { XataClient } from "../src/xata"
import { XataAdapter } from "../src"

View File

@@ -1,5 +1,5 @@
{
"extends": "@next-auth/tsconfig/tsconfig.base.json",
"extends": "@auth/tsconfig/tsconfig.base.json",
"compilerOptions": {
"allowJs": true,
"baseUrl": ".",

View File

@@ -1,6 +1,6 @@
{
"name": "@auth/core",
"version": "0.12.0",
"version": "0.13.0",
"description": "Authentication for the Web.",
"keywords": [
"authentication",
@@ -84,7 +84,7 @@
"providers": "node scripts/generate-providers"
},
"devDependencies": {
"@next-auth/tsconfig": "workspace:*",
"@auth/tsconfig": "workspace:*",
"@types/cookie": "0.5.1",
"@types/node": "18.11.10",
"@types/nodemailer": "6.4.6",

View File

@@ -35,7 +35,7 @@ export async function toInternalRequest(
const url = new URL(req.url.replace(/\/$/, ""))
// FIXME: Upstream issue in Next.js, pathname segments get included as part of the query string
url.searchParams.delete("nextauth")
const { pathname } = url
const pathname = url.pathname.replace(/\/$/, "")
const action = actions.find((a) => pathname.includes(a))
if (!action) {

View File

@@ -0,0 +1,180 @@
import { OAuthConfig, OAuthUserConfig } from "./index.js"
/** @see [Azure DevOps Services REST API 7.0 · Profiles · Get](https://learn.microsoft.com/en-us/rest/api/azure/devops/profile/profiles/get?view=azure-devops-rest-7.0&tabs=HTTP#examples) */
export interface AzureDevOpsProfile extends Record<string, any> {
id: string
displayName: string
emailAddress: string
coreAttributes: { Avatar: { value: { value: string } } }
}
/**
* ## Documentation
*
* [Microsoft Docs](https://docs.microsoft.com/en-us) · [Azure DevOps](https://docs.microsoft.com/en-us/azure/devops/) · [Authorize access to REST APIs with OAuth 2.0](https://docs.microsoft.com/en-us/azure/devops/integrate/get-started/authentication/oauth?view=azure-devops])
*
* ## Configuration
*
* ### Register application
*
* :::tip
* [`https://app.vsaex.visualstudio.com/app/register`](https://app.vsaex.visualstudio.com/app/register)
* :::
*
* Provide the required details:
*
* - Company name
* - Application name
* - Application website
* - Authorization callback URL
* - `https://example.com/api/auth/callback/azure-devops` for production
* - `https://localhost/api/auth/callback/azure-devops` for development
* - Authorized scopes
* - Required minimum is `User profile (read)`
*
* Click Create Application
*
* :::warning
* You are required to use HTTPS even for the localhost
* :::
*
* :::warning
* You will have to delete and create a new application to change the scopes later
* :::
*
* The following data is relevant for the next step:
*
* - App ID
* - Client Secret (after clicking the Show button, ignore App Secret entry above it)
* - Authorized Scopes
*
* ### Set up the environment variables
*
* In `.env.local` create the following entries:
*
* ```
* AZURE_DEVOPS_APP_ID=<copy App ID value here>
* AZURE_DEVOPS_CLIENT_SECRET=<copy generated client secret value here>
* AZURE_DEVOPS_SCOPE=<copy space separated Authorized Scopes list here>
* ```
*
* ## Example
*
* ```js title="pages/api/auth/[...nextauth].js"
* import AzureDevOpsProvider from "next-auth/providers/azure-devops"
* ...
* providers: [
* AzureDevOpsProvider({
* clientId: process.env.AZURE_DEVOPS_APP_ID,
* clientSecret: process.env.AZURE_DEVOPS_CLIENT_SECRET,
* scope: process.env.AZURE_DEVOPS_SCOPE,
* }),
* ]
* ...
* ```
*
* ### Refresh token rotation
*
* Use the [main guide](/guides/basics/refresh-token-rotation) as your starting point with the following considerations:
*
* ```js title="pages/api/auth/[...nextauth].js"
* async jwt({ token, user, account }) {
* ...
* // The token has an absolute expiration time
* const accessTokenExpires = account.expires_at * 1000
* ...
* }
*
* async function refreshAccessToken(token) {
* ...
* const response = await fetch(
* "https://app.vssps.visualstudio.com/oauth2/token",
* {
* headers: { "Content-Type": "application/x-www-form-urlencoded" },
* method: "POST",
* body: new URLSearchParams({
* client_assertion_type:
* "urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
* client_assertion: AZURE_DEVOPS_CLIENT_SECRET,
* grant_type: "refresh_token",
* assertion: token.refreshToken,
* redirect_uri:
* process.env.NEXTAUTH_URL + "/api/auth/callback/azure-devops",
* }),
* }
* )
* ...
* // The refreshed token comes with a relative expiration time
* const accessTokenExpires = Date.now() + newToken.expires_in * 1000
* ...
* }
* ```
*/
export default function AzureDevOpsProvider<P extends AzureDevOpsProfile>(
options: OAuthUserConfig<P> & {
/**
* https://docs.microsoft.com/en-us/azure/devops/integrate/get-started/authentication/oauth?view=azure-devops#scopes
* @default vso.profile
*/
scope?: string
}
): OAuthConfig<P> {
const scope = options.scope ?? "vso.profile"
const tokenEndpointUrl = "https://app.vssps.visualstudio.com/oauth2/authorize"
const userInfoEndpointUrl =
"https://app.vssps.visualstudio.com/_apis/profile/profiles/me?details=true&coreAttributes=Avatar&api-version=6.0"
return {
id: "azure-devops",
name: "Azure DevOps",
type: "oauth",
authorization: {
url: "https://app.vssps.visualstudio.com/oauth2/authorize",
params: { response_type: "Assertion", scope },
},
token: {
url: tokenEndpointUrl,
async request(context) {
const response = await fetch(tokenEndpointUrl, {
headers: { "Content-Type": "application/x-www-form-urlencoded" },
method: "POST",
body: new URLSearchParams({
client_assertion_type:
"urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
client_assertion: context.provider.clientSecret as string,
grant_type: "urn:ietf:params:oauth:grant-type:jwt-bearer",
assertion: context.params.code as string,
redirect_uri: context.provider.callbackUrl,
}),
})
return { tokens: await response.json() }
},
},
userinfo: {
url: userInfoEndpointUrl,
async request(context) {
const accessToken = context.tokens.access_token as string
const response = await fetch(userInfoEndpointUrl, {
headers: {
Authorization: `Bearer ${accessToken}`,
},
})
return response.json()
},
},
profile(profile) {
return {
id: profile.id,
name: profile.displayName,
email: profile.emailAddress,
image: `data:image/jpeg;base64,${profile.coreAttributes.Avatar.value.value}`,
}
},
options,
}
}

View File

@@ -10,23 +10,11 @@
*/
import type { OAuthConfig, OAuthUserConfig } from "./index.js"
interface Identifier {
identifier: string
}
interface Element {
identifiers?: Identifier[]
}
export interface LinkedInProfile extends Record<string, any> {
id: string
localizedFirstName: string
localizedLastName: string
profilePicture: {
"displayImage~": {
elements?: Element[]
}
}
export interface LinkedInProfile {
sub: string
name: string
email: string
picture: string
}
/**
@@ -83,36 +71,10 @@ export default function LinkedIn<P extends LinkedInProfile>(
return {
id: "linkedin",
name: "LinkedIn",
type: "oauth",
authorization: {
url: "https://www.linkedin.com/oauth/v2/authorization",
params: { scope: "r_liteprofile r_emailaddress" },
},
token: "https://www.linkedin.com/oauth/v2/accessToken",
type: "oidc",
client: {
token_endpoint_auth_method: "client_secret_post",
},
userinfo: {
url: "https://api.linkedin.com/v2/me",
params: {
projection: `(id,localizedFirstName,localizedLastName,profilePicture(displayImage~digitalmediaAsset:playableStreams))`,
},
},
async profile(profile, tokens) {
const emailResponse = await fetch(
"https://api.linkedin.com/v2/emailAddress?q=members&projection=(elements*(handle~))",
{ headers: { Authorization: `Bearer ${tokens.access_token}` } }
)
const emailData = await emailResponse.json()
return {
id: profile.id,
name: `${profile.localizedFirstName} ${profile.localizedLastName}`,
email: emailData?.elements?.[0]?.["handle~"]?.emailAddress,
image:
profile.profilePicture?.["displayImage~"]?.elements?.[0]
?.identifiers?.[0]?.identifier,
}
},
style: {
logo: "/linkedin.svg",
logoDark: "/linkedin-dark.svg",

View File

@@ -1,12 +1,16 @@
{
"extends": "@next-auth/tsconfig/tsconfig.base.json",
"extends": "@auth/tsconfig/tsconfig.base.json",
"compilerOptions": {
"allowJs": true,
"baseUrl": ".",
"isolatedModules": true,
"jsx": "react-jsx",
"jsxImportSource": "preact",
"lib": ["dom", "dom.iterable", "esnext"],
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"target": "ES2020",
"module": "ESNext",
"moduleResolution": "node",
@@ -18,6 +22,13 @@
"declarationMap": true,
"declaration": true
},
"include": ["src/**/*"],
"exclude": ["*.js", "*.d.ts", "lib", "providers"]
}
"include": [
"src/**/*"
],
"exclude": [
"*.js",
"*.d.ts",
"lib",
"providers"
]
}

View File

@@ -35,7 +35,7 @@
"solid-js": "^1.5.7",
"solid-start": "^0.2.14",
"tsup": "^6.5.0",
"typescript": "^4.8.2"
"typescript": "5.2.2"
},
"peerDependencies": {
"@auth/core": "~0.2.2 || ^0.2.2",
@@ -50,4 +50,4 @@
"author": "OrJDev <orjdeveloper@gmail.com>",
"repository": "https://github.com/nextauthjs/next-auth",
"license": "ISC"
}
}

View File

@@ -40,7 +40,7 @@
"svelte": "^3.54.0",
"svelte-check": "^2.9.2",
"tslib": "^2.4.1",
"typescript": "^4.9.3",
"typescript": "5.2.2",
"vite": "^4.0.5",
"vitest": "^0.25.3"
},
@@ -69,4 +69,4 @@
},
"./package.json": "./package.json"
}
}
}

View File

@@ -8,11 +8,17 @@
"resolveJsonModule": true,
"skipLibCheck": true,
"sourceMap": true,
"strict": true
"strict": true,
"ignoreDeprecations": "5.0" // TODO: https://github.com/sveltejs/kit/issues/8650
},
// Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias
//
// If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes
// from the referenced tsconfig.json - TypeScript does not merge them in
"exclude": ["scripts", "*.js", "../node_modules/**", "./[!ambient.d.ts]**"]
}
"exclude": [
"scripts",
"*.js",
"../node_modules/**",
"./[!ambient.d.ts]**"
]
}

View File

@@ -95,7 +95,7 @@
"@babel/preset-react": "^7.17.12",
"@babel/preset-typescript": "^7.17.12",
"@edge-runtime/jest-environment": "1.1.0-beta.35",
"@next-auth/tsconfig": "workspace:*",
"@auth/tsconfig": "workspace:*",
"@swc/core": "^1.2.198",
"@swc/jest": "^0.2.21",
"@testing-library/dom": "^8.13.0",

View File

@@ -1,5 +1,5 @@
{
"extends": "@next-auth/tsconfig/tsconfig.base.json",
"extends": "@auth/tsconfig/tsconfig.base.json",
"compilerOptions": {
"declarationMap": true,
"emitDeclarationOnly": true,

View File

@@ -1,10 +1,8 @@
{
"name": "@next-auth/tsconfig",
"name": "@auth/tsconfig",
"private": true,
"version": "0.0.0",
"files": [
"tsconfig.adapters.json",
"tsconfig.base.json",
"tsconfig.eslint.json"
"tsconfig.base.json"
]
}

View File

@@ -1,8 +0,0 @@
{
"extends": "./tsconfig.base.json",
"compilerOptions": {
"target": "ES2019",
"module": "commonjs",
"strict": true
}
}

14773
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff