mirror of
https://github.com/SrIzan10/next-auth.git
synced 2026-05-01 10:55:20 +00:00
Compare commits
19 Commits
@next-auth
...
next-auth@
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
37c4a813e3 | ||
|
|
6a23ff7126 | ||
|
|
23db0e68dd | ||
|
|
e03e234b86 | ||
|
|
66fb914a31 | ||
|
|
8ce728197f | ||
|
|
87d1a7af6d | ||
|
|
172813f987 | ||
|
|
cc934fceec | ||
|
|
46e467a7cb | ||
|
|
73d489beac | ||
|
|
e498483b23 | ||
|
|
7cf49566a6 | ||
|
|
2469e44572 | ||
|
|
408b6b175f | ||
|
|
92dfc3c8b0 | ||
|
|
8c5d9faad6 | ||
|
|
49a8d51f79 | ||
|
|
c0d251731d |
4
.github/workflows/release.yml
vendored
4
.github/workflows/release.yml
vendored
@@ -69,7 +69,7 @@ jobs:
|
|||||||
git config --global user.name "Balázs Orbán"
|
git config --global user.name "Balázs Orbán"
|
||||||
pnpm release
|
pnpm release
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
||||||
NPM_TOKEN_PKG: ${{ secrets.NPM_TOKEN_PKG }}
|
NPM_TOKEN_PKG: ${{ secrets.NPM_TOKEN_PKG }}
|
||||||
NPM_TOKEN_ORG: ${{ secrets.NPM_TOKEN_ORG }}
|
NPM_TOKEN_ORG: ${{ secrets.NPM_TOKEN_ORG }}
|
||||||
release-pr:
|
release-pr:
|
||||||
@@ -103,7 +103,7 @@ jobs:
|
|||||||
echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> .npmrc
|
echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> .npmrc
|
||||||
pnpm publish --no-git-checks --access public --tag experimental
|
pnpm publish --no-git-checks --access public --tag experimental
|
||||||
env:
|
env:
|
||||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
NPM_TOKEN: ${{ secrets.NPM_TOKEN_PKG }}
|
||||||
- name: Comment version on PR
|
- name: Comment version on PR
|
||||||
uses: NejcZdovc/comment-pr@v1
|
uses: NejcZdovc/comment-pr@v1
|
||||||
with:
|
with:
|
||||||
|
|||||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -30,7 +30,7 @@ packages/next-auth/providers
|
|||||||
packages/next-auth/src/providers/oauth-types.ts
|
packages/next-auth/src/providers/oauth-types.ts
|
||||||
packages/next-auth/client
|
packages/next-auth/client
|
||||||
packages/next-auth/css
|
packages/next-auth/css
|
||||||
packages/next-auth/lib
|
packages/next-auth/utils
|
||||||
packages/next-auth/core
|
packages/next-auth/core
|
||||||
packages/next-auth/jwt
|
packages/next-auth/jwt
|
||||||
packages/next-auth/react
|
packages/next-auth/react
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// This is an example of how to protect content using server rendering
|
// This is an example of how to protect content using server rendering
|
||||||
import { getServerSession } from "next-auth/next"
|
import { unstable_getServerSession } from "next-auth/next"
|
||||||
import { authOptions } from "./api/auth/[...nextauth]"
|
import { authOptions } from "./api/auth/[...nextauth]"
|
||||||
import Layout from "../components/layout"
|
import Layout from "../components/layout"
|
||||||
import AccessDenied from "../components/access-denied"
|
import AccessDenied from "../components/access-denied"
|
||||||
@@ -26,7 +26,11 @@ export default function Page({ content, session }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function getServerSideProps(context) {
|
export async function getServerSideProps(context) {
|
||||||
const session = await getServerSession(context, authOptions)
|
const session = await unstable_getServerSession(
|
||||||
|
context.req,
|
||||||
|
context.res,
|
||||||
|
authOptions
|
||||||
|
)
|
||||||
let content = null
|
let content = null
|
||||||
|
|
||||||
if (session) {
|
if (session) {
|
||||||
|
|||||||
@@ -65,7 +65,6 @@ You **can** skip configuring a database and come back to it later if you want.
|
|||||||
For more information about setting up a database, please check out the following links:
|
For more information about setting up a database, please check out the following links:
|
||||||
|
|
||||||
* Docs: [next-auth.js.org/adapters/overview](https://next-auth.js.org/adapters/overview)
|
* Docs: [next-auth.js.org/adapters/overview](https://next-auth.js.org/adapters/overview)
|
||||||
* Adapters Repo: [nextauthjs/adapters](https://github.com/nextauthjs/adapters)
|
|
||||||
|
|
||||||
### 3. Configure Authentication Providers
|
### 3. Configure Authentication Providers
|
||||||
|
|
||||||
|
|||||||
@@ -68,7 +68,6 @@ You **can** skip configuring a database and come back to it later if you want.
|
|||||||
For more information about setting up a database, please check out the following links:
|
For more information about setting up a database, please check out the following links:
|
||||||
|
|
||||||
* Docs: [next-auth.js.org/adapters/overview](https://next-auth.js.org/adapters/overview)
|
* Docs: [next-auth.js.org/adapters/overview](https://next-auth.js.org/adapters/overview)
|
||||||
* Adapters Repo: [nextauthjs/adapters](https://github.com/nextauthjs/adapters)
|
|
||||||
|
|
||||||
### 3. Configure Authentication Providers
|
### 3. Configure Authentication Providers
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@
|
|||||||
"type": "module",
|
"type": "module",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"cookie": "0.4.1",
|
"cookie": "0.4.1",
|
||||||
"next-auth": "^4.3.3"
|
"next-auth": "^4.5.0"
|
||||||
},
|
},
|
||||||
"prettier": {
|
"prettier": {
|
||||||
"semi": false,
|
"semi": false,
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ async function SKNextAuthHandler(
|
|||||||
query: Object.fromEntries(url.searchParams),
|
query: Object.fromEntries(url.searchParams),
|
||||||
headers: request.headers,
|
headers: request.headers,
|
||||||
method: request.method,
|
method: request.method,
|
||||||
cookies: cookie.parse(request.headers.get("cookie")),
|
cookies: cookie.parse(request.headers.get("cookie") ?? ""),
|
||||||
action: nextauth[0] as NextAuthAction,
|
action: nextauth[0] as NextAuthAction,
|
||||||
providerId: nextauth[1],
|
providerId: nextauth[1],
|
||||||
error: nextauth[1],
|
error: nextauth[1],
|
||||||
@@ -91,7 +91,7 @@ export async function getServerSession(
|
|||||||
host: import.meta.env.VITE_NEXTAUTH_URL,
|
host: import.meta.env.VITE_NEXTAUTH_URL,
|
||||||
action: "session",
|
action: "session",
|
||||||
method: "GET",
|
method: "GET",
|
||||||
cookies: cookie.parse(request.headers.get("cookie")),
|
cookies: cookie.parse(request.headers.get("cookie") ?? ""),
|
||||||
headers: request.headers,
|
headers: request.headers,
|
||||||
},
|
},
|
||||||
options,
|
options,
|
||||||
|
|||||||
@@ -1232,10 +1232,10 @@ natural-compare@^1.4.0:
|
|||||||
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
|
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
|
||||||
integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=
|
integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=
|
||||||
|
|
||||||
next-auth@^4.3.3:
|
next-auth@^4.5.0:
|
||||||
version "4.3.3"
|
version "4.5.0"
|
||||||
resolved "https://registry.yarnpkg.com/next-auth/-/next-auth-4.3.3.tgz#5ff892e73648a0f33c2af0e9d7cafda729f63ae7"
|
resolved "https://registry.yarnpkg.com/next-auth/-/next-auth-4.5.0.tgz#2df57287fddc705b8971c88c60bad44a89ac6dd1"
|
||||||
integrity sha512-bUs+oOOPT18Pq/+4v9q4PA/DGoVoAX6jwY7RTfE/akFXwlny+y/mNS6lPSUwpqcHjljqBaq34PQA3+01SdOOPw==
|
integrity sha512-B6gYRIbqtj8nlDsx3y2Ruwp/mvZnItPs7VUULY43QYw+M9xtDPIM9EBZ3ryd/wNYA3MDteBJlzGm/ivseXcmJA==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/runtime" "^7.16.3"
|
"@babel/runtime" "^7.16.3"
|
||||||
"@panva/hkdf" "^1.0.1"
|
"@panva/hkdf" "^1.0.1"
|
||||||
|
|||||||
@@ -1,5 +1,73 @@
|
|||||||
# Next.js
|
# Next.js
|
||||||
|
|
||||||
|
## `unstable_getServerSession`
|
||||||
|
|
||||||
|
:::warning
|
||||||
|
This feature is experimental and may be removed or changed in the future.
|
||||||
|
:::
|
||||||
|
|
||||||
|
When calling from server-side i.e. in API routes or in `getServerSideProps`, we recommend using this function instead of `getSession` to retrieve the `session` object. This method is especially useful when you are using NextAuth.js with a database. This method can _drastically_ reduce response time when used over `getSession` server-side, due to avoiding an extra `fetch` to an API Route (this is generally [not recommended in Next.js](https://nextjs.org/docs/basic-features/data-fetching/get-server-side-props#getserversideprops-or-api-routes)). In addition, `unstable_getServerSession` will correctly update the cookie expiry time and update the session content if `callbacks.jwt` or `callbacks.session` changed something.
|
||||||
|
|
||||||
|
Otherwise, if you only want to get the session token, see [`getToken`](tutorials/securing-pages-and-api-routes#using-gettoken).
|
||||||
|
|
||||||
|
`unstable_getServerSession` requires passing the same object you would pass to `NextAuth` when initializing NextAuth.js. To do so, you can export your NextAuth.js options in the following way:
|
||||||
|
|
||||||
|
In `[...nextauth.js]`:
|
||||||
|
```ts
|
||||||
|
import { NextAuth } from 'next-auth'
|
||||||
|
import type { NextAuthOptions } from 'next-auth'
|
||||||
|
|
||||||
|
export const authOptions: NextAuthOptions = {
|
||||||
|
// your configs
|
||||||
|
}
|
||||||
|
|
||||||
|
export default NextAuth(authOptions);
|
||||||
|
```
|
||||||
|
|
||||||
|
In `getServerSideProps`:
|
||||||
|
```js
|
||||||
|
import { authOptions } from 'pages/api/[...nextauth]'
|
||||||
|
import { unstable_getServerSession } from "next-auth/next"
|
||||||
|
|
||||||
|
export async function getServerSideProps(context) {
|
||||||
|
const session = await unstable_getServerSession(context.req, context.res, authOptions)
|
||||||
|
|
||||||
|
if (!session) {
|
||||||
|
return {
|
||||||
|
redirect: {
|
||||||
|
destination: '/',
|
||||||
|
permanent: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
props: {
|
||||||
|
session,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
In API routes:
|
||||||
|
```js
|
||||||
|
import { authOptions } from 'pages/api/[...nextauth]'
|
||||||
|
import { unstable_getServerSession } from "next-auth/next"
|
||||||
|
|
||||||
|
|
||||||
|
export async function handler(req, res) {
|
||||||
|
const session = await unstable_getServerSession(req, res, authOptions)
|
||||||
|
|
||||||
|
if (!session) {
|
||||||
|
res.status(401).json({ message: "You must be logged in." });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res.json({
|
||||||
|
message: 'Success',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## Middleware
|
## Middleware
|
||||||
|
|
||||||
You can use a Next.js Middleware with NextAuth.js to protect your site.
|
You can use a Next.js Middleware with NextAuth.js to protect your site.
|
||||||
|
|||||||
@@ -30,8 +30,8 @@ import GitHubProvider from "next-auth/providers/github";
|
|||||||
...
|
...
|
||||||
providers: [
|
providers: [
|
||||||
GitHubProvider({
|
GitHubProvider({
|
||||||
clientId: process.env.GITHUB_CLIENT_ID,
|
clientId: process.env.GITHUB_ID,
|
||||||
clientSecret: process.env.GITHUB_CLIENT_SECRET
|
clientSecret: process.env.GITHUB_SECRET
|
||||||
})
|
})
|
||||||
]
|
]
|
||||||
...
|
...
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ https://api.slack.com/docs/sign-in-with-slack
|
|||||||
https://api.slack.com/apps
|
https://api.slack.com/apps
|
||||||
|
|
||||||
:::warning
|
:::warning
|
||||||
Slack requires you that the redirect URL of your app uses `https`, even for local development. An easy workaround for this is using a service like [`ngrok`](https://ngrok.com) that creates a secure tunnel to your app, using `https`. Remember to set the url as `NEXTAUTH_URL` as well.
|
Slack requires that the redirect URL of your app uses `https`, even for local development. An easy workaround for this is using a service like [`ngrok`](https://ngrok.com) that creates a secure tunnel to your app, using `https`. Remember to set the url as `NEXTAUTH_URL` as well.
|
||||||
:::
|
:::
|
||||||
|
|
||||||

|

|
||||||
|
|||||||
@@ -15,7 +15,7 @@ https://dashboard.workos.com
|
|||||||
|
|
||||||
The **WorkOS Provider** comes with a set of default options:
|
The **WorkOS Provider** comes with a set of default options:
|
||||||
|
|
||||||
- [WorkOS Provider options](https://github.com/nextauthjs/next-auth/blob/main/packages/next-auth/src/providers/workos.js)
|
- [WorkOS Provider options](https://github.com/nextauthjs/next-auth/blob/main/packages/next-auth/src/providers/workos.ts)
|
||||||
|
|
||||||
You can override any of the options to suit your own use case.
|
You can override any of the options to suit your own use case.
|
||||||
|
|
||||||
|
|||||||
@@ -33,6 +33,10 @@ In development, we generate a `secret` based on your configuration for convenien
|
|||||||
|
|
||||||
Twitter OAuth 2.0 is currently in beta as certain changes might still be necessary. This is not covered by semver. See the docs https://next-auth.js.org/providers/twitter#oauth-2
|
Twitter OAuth 2.0 is currently in beta as certain changes might still be necessary. This is not covered by semver. See the docs https://next-auth.js.org/providers/twitter#oauth-2
|
||||||
|
|
||||||
|
#### EXPERIMENTAL_API
|
||||||
|
|
||||||
|
Some APIs are still experimental; they may be changed or removed in the future. Use at your own risk.
|
||||||
|
|
||||||
## Adapter
|
## Adapter
|
||||||
|
|
||||||
### ADAPTER_TYPEORM_UPDATING_ENTITIES
|
### ADAPTER_TYPEORM_UPDATING_ENTITIES
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
Open Source. Full Stack. Own Your Data.
|
Open Source. Full Stack. Own Your Data.
|
||||||
</p>
|
</p>
|
||||||
<!-- <p align="center" style="align: center;">
|
<!-- <p align="center" style="align: center;">
|
||||||
<img src="https://github.com/nextauthjs/adapters/actions/workflows/release.yml/badge.svg" alt="CI Test" />
|
<img src="https://github.com/nextauthjs/next-auth/actions/workflows/release.yml/badge.svg?branch=main" alt="CI Test" />
|
||||||
<img src="https://img.shields.io/bundlephobia/minzip/@next-auth/prisma-adapter" alt="Bundle Size"/>
|
<img src="https://img.shields.io/bundlephobia/minzip/@next-auth/prisma-adapter" alt="Bundle Size"/>
|
||||||
<img src="https://img.shields.io/npm/v/@next-auth/prisma-adapter" alt="@next-auth/prisma-adapter Version" />
|
<img src="https://img.shields.io/npm/v/@next-auth/prisma-adapter" alt="@next-auth/prisma-adapter Version" />
|
||||||
</p> -->
|
</p> -->
|
||||||
@@ -150,7 +150,7 @@ type User
|
|||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
We're open to all community contributions! If you'd like to contribute in any way, please read our [Contributing Guide](https://github.com/nextauthjs/adapters/blob/main/CONTRIBUTING.md).
|
We're open to all community contributions! If you'd like to contribute in any way, please read our [Contributing Guide](https://github.com/nextauthjs/next-auth/blob/main/CONTRIBUTING.md).
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|||||||
@@ -3,9 +3,9 @@
|
|||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"description": "Dgraph adapter for next-auth.",
|
"description": "Dgraph adapter for next-auth.",
|
||||||
"homepage": "https://next-auth.js.org",
|
"homepage": "https://next-auth.js.org",
|
||||||
"repository": "https://github.com/nextauthjs/adapters",
|
"repository": "https://github.com/nextauthjs/next-auth",
|
||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/nextauthjs/adapters/issues"
|
"url": "https://github.com/nextauthjs/next-auth/issues"
|
||||||
},
|
},
|
||||||
"author": "Arnaud Derbey <arnaud@derbey.dev>",
|
"author": "Arnaud Derbey <arnaud@derbey.dev>",
|
||||||
"contributors": [],
|
"contributors": [],
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
Open Source. Full Stack. Own Your Data.
|
Open Source. Full Stack. Own Your Data.
|
||||||
</p>
|
</p>
|
||||||
<p align="center" style="align: center;">
|
<p align="center" style="align: center;">
|
||||||
<img src="https://github.com/nextauthjs/adapters/actions/workflows/release.yml/badge.svg" alt="Build Test" />
|
<img src="https://github.com/nextauthjs/next-auth/actions/workflows/release.yml/badge.svg?branch=main" alt="Build Test" />
|
||||||
<img src="https://img.shields.io/bundlephobia/minzip/@next-auth/dynamodb-adapter/latest" alt="Bundle Size"/>
|
<img src="https://img.shields.io/bundlephobia/minzip/@next-auth/dynamodb-adapter/latest" alt="Bundle Size"/>
|
||||||
<img src="https://img.shields.io/npm/v/@next-auth/dynamodb-adapter" alt="@next-auth/dynamodb-adapter Version" />
|
<img src="https://img.shields.io/npm/v/@next-auth/dynamodb-adapter" alt="@next-auth/dynamodb-adapter Version" />
|
||||||
</p>
|
</p>
|
||||||
@@ -96,7 +96,7 @@ Here is a schema of the table :
|
|||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
We're open to all community contributions! If you'd like to contribute in any way, please read our [Contributing Guide](https://github.com/nextauthjs/adapters/blob/main/CONTRIBUTING.md).
|
We're open to all community contributions! If you'd like to contribute in any way, please read our [Contributing Guide](https://github.com/nextauthjs/next-auth/blob/main/CONTRIBUTING.md).
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@next-auth/dynamodb-adapter",
|
"name": "@next-auth/dynamodb-adapter",
|
||||||
"repository": "https://github.com/nextauthjs/adapters",
|
"repository": "https://github.com/nextauthjs/next-auth",
|
||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"description": "AWS DynamoDB adapter for next-auth.",
|
"description": "AWS DynamoDB adapter for next-auth.",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
Open Source. Full Stack. Own Your Data.
|
Open Source. Full Stack. Own Your Data.
|
||||||
</p>
|
</p>
|
||||||
<p align="center" style="align: center;">
|
<p align="center" style="align: center;">
|
||||||
<img src="https://github.com/nextauthjs/adapters/actions/workflows/release.yml/badge.svg" alt="Build Test" />
|
<img src="https://github.com/nextauthjs/next-auth/actions/workflows/release.yml/badge.svg?branch=main" alt="Build Test" />
|
||||||
<a href="https://www.npmjs.com/package/@next-auth/faunadb-adapter" target="_blank"><img src="https://img.shields.io/bundlephobia/minzip/@next-auth/fauna-adapter/next" alt="Bundle Size"/></a>
|
<a href="https://www.npmjs.com/package/@next-auth/faunadb-adapter" target="_blank"><img src="https://img.shields.io/bundlephobia/minzip/@next-auth/fauna-adapter/next" alt="Bundle Size"/></a>
|
||||||
<a href="https://www.npmjs.com/package/@next-auth/faunadb-adapter" target="_blank"><img src="https://img.shields.io/npm/v/@next-auth/fauna-adapter/next" alt="@next-auth/fauna-adapter Version" /></a>
|
<a href="https://www.npmjs.com/package/@next-auth/faunadb-adapter" target="_blank"><img src="https://img.shields.io/npm/v/@next-auth/fauna-adapter/next" alt="@next-auth/fauna-adapter Version" /></a>
|
||||||
</p>
|
</p>
|
||||||
@@ -53,7 +53,7 @@ export default NextAuth({
|
|||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
We're open to all community contributions! If you'd like to contribute in any way, please read our [Contributing Guide](https://github.com/nextauthjs/adapters/blob/main/CONTRIBUTING.md).
|
We're open to all community contributions! If you'd like to contribute in any way, please read our [Contributing Guide](https://github.com/nextauthjs/next-auth/blob/main/CONTRIBUTING.md).
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"description": "Fauna Adapter for NextAuth",
|
"description": "Fauna Adapter for NextAuth",
|
||||||
"homepage": "https://next-auth.js.org",
|
"homepage": "https://next-auth.js.org",
|
||||||
"repository": "https://github.com/nextauthjs/adapters",
|
"repository": "https://github.com/nextauthjs/next-auth",
|
||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/nextauthjs/next-auth/issues"
|
"url": "https://github.com/nextauthjs/next-auth/issues"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
Open Source. Full Stack. Own Your Data.
|
Open Source. Full Stack. Own Your Data.
|
||||||
</p>
|
</p>
|
||||||
<p align="center" style="align: center;">
|
<p align="center" style="align: center;">
|
||||||
<img src="https://github.com/nextauthjs/adapters/actions/workflows/release.yml/badge.svg" alt="Build Test" />
|
<img src="https://github.com/nextauthjs/next-auth/actions/workflows/release.yml/badge.svg?branch=main" alt="Build Test" />
|
||||||
<img src="https://img.shields.io/bundlephobia/minzip/@next-auth/firebase-adapter/latest" alt="Bundle Size"/>
|
<img src="https://img.shields.io/bundlephobia/minzip/@next-auth/firebase-adapter/latest" alt="Bundle Size"/>
|
||||||
<img src="https://img.shields.io/npm/v/@next-auth/firebase-adapter" alt="@next-auth/firebase-adapter Version" />
|
<img src="https://img.shields.io/npm/v/@next-auth/firebase-adapter" alt="@next-auth/firebase-adapter Version" />
|
||||||
</p>
|
</p>
|
||||||
@@ -83,7 +83,7 @@ See [firebase.google.com/docs/web/setup](https://firebase.google.com/docs/web/se
|
|||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
We're open to all community contributions! If you'd like to contribute in any way, please read our [Contributing Guide](https://github.com/nextauthjs/adapters/blob/main/CONTRIBUTING.md).
|
We're open to all community contributions! If you'd like to contribute in any way, please read our [Contributing Guide](https://github.com/nextauthjs/next-auth/blob/main/CONTRIBUTING.md).
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|||||||
@@ -3,9 +3,9 @@
|
|||||||
"version": "0.1.3",
|
"version": "0.1.3",
|
||||||
"description": "Firebase adapter for next-auth.",
|
"description": "Firebase adapter for next-auth.",
|
||||||
"homepage": "https://next-auth.js.org",
|
"homepage": "https://next-auth.js.org",
|
||||||
"repository": "https://github.com/nextauthjs/adapters",
|
"repository": "https://github.com/nextauthjs/next-auth",
|
||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/nextauthjs/adapters/issues"
|
"url": "https://github.com/nextauthjs/next-auth/issues"
|
||||||
},
|
},
|
||||||
"author": "Ron Houben <ron.houben85@gmail.com>",
|
"author": "Ron Houben <ron.houben85@gmail.com>",
|
||||||
"contributors": [
|
"contributors": [
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
Open Source. Full Stack. Own Your Data.
|
Open Source. Full Stack. Own Your Data.
|
||||||
</p>
|
</p>
|
||||||
<p align="center" style="align: center;">
|
<p align="center" style="align: center;">
|
||||||
<img src="https://github.com/nextauthjs/adapters/actions/workflows/release.yml/badge.svg" alt="CI Test" />
|
<img src="https://github.com/nextauthjs/next-auth/actions/workflows/release.yml/badge.svg?branch=main" alt="CI Test" />
|
||||||
<a href="https://www.npmjs.com/package/@next-auth/mikro-orm-adapter" target="_blank"><img src="https://img.shields.io/bundlephobia/minzip/@next-auth/mikro-orm-adapter/next" alt="Bundle Size"/></a>
|
<a href="https://www.npmjs.com/package/@next-auth/mikro-orm-adapter" target="_blank"><img src="https://img.shields.io/bundlephobia/minzip/@next-auth/mikro-orm-adapter/next" alt="Bundle Size"/></a>
|
||||||
<a href="https://www.npmjs.com/package/@next-auth/mikro-orm-adapter" target="_blank"><img src="https://img.shields.io/npm/v/@next-auth/mikro-orm-adapter/next" alt="@next-auth/mikro-orm-adapter Version" /></a>
|
<a href="https://www.npmjs.com/package/@next-auth/mikro-orm-adapter" target="_blank"><img src="https://img.shields.io/npm/v/@next-auth/mikro-orm-adapter/next" alt="@next-auth/mikro-orm-adapter Version" /></a>
|
||||||
</p>
|
</p>
|
||||||
@@ -49,7 +49,7 @@ This is the MikroORM Adapter for [`next-auth`](https://next-auth.js.org). This p
|
|||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
We're open to all community contributions! If you'd like to contribute in any way, please read our [Contributing Guide](https://github.com/nextauthjs/adapters/blob/main/CONTRIBUTING.md).
|
We're open to all community contributions! If you'd like to contribute in any way, please read our [Contributing Guide](https://github.com/nextauthjs/next-auth/blob/main/CONTRIBUTING.md).
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"description": "MikroORM adapter for next-auth.",
|
"description": "MikroORM adapter for next-auth.",
|
||||||
"homepage": "https://next-auth.js.org",
|
"homepage": "https://next-auth.js.org",
|
||||||
"repository": "https://github.com/nextauthjs/adapters",
|
"repository": "https://github.com/nextauthjs/next-auth",
|
||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/nextauthjs/next-auth/issues"
|
"url": "https://github.com/nextauthjs/next-auth/issues"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
Open Source. Full Stack. Own Your Data.
|
Open Source. Full Stack. Own Your Data.
|
||||||
</p>
|
</p>
|
||||||
<p align="center" style="align: center;">
|
<p align="center" style="align: center;">
|
||||||
<img src="https://github.com/nextauthjs/adapters/actions/workflows/release.yml/badge.svg" alt="CI Test" />
|
<img src="https://github.com/nextauthjs/next-auth/actions/workflows/release.yml/badge.svg?branch=main" alt="CI Test" />
|
||||||
<a href="https://www.npmjs.com/package/@next-auth/mongodb-adapter" target="_blank"><img src="https://img.shields.io/bundlephobia/minzip/@next-auth/mongodb-adapter" alt="Bundle Size"/></a>
|
<a href="https://www.npmjs.com/package/@next-auth/mongodb-adapter" target="_blank"><img src="https://img.shields.io/bundlephobia/minzip/@next-auth/mongodb-adapter" alt="Bundle Size"/></a>
|
||||||
<a href="https://www.npmjs.com/package/@next-auth/mongodb-adapter" target="_blank"><img src="https://img.shields.io/npm/v/@next-auth/mongodb-adapter" alt="@next-auth/mongodb-adapter Version" /></a>
|
<a href="https://www.npmjs.com/package/@next-auth/mongodb-adapter" target="_blank"><img src="https://img.shields.io/npm/v/@next-auth/mongodb-adapter" alt="@next-auth/mongodb-adapter Version" /></a>
|
||||||
</p>
|
</p>
|
||||||
@@ -79,7 +79,7 @@ export default NextAuth({
|
|||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
We're open to all community contributions! If you'd like to contribute in any way, please read our [Contributing Guide](https://github.com/nextauthjs/adapters/blob/main/CONTRIBUTING.md).
|
We're open to all community contributions! If you'd like to contribute in any way, please read our [Contributing Guide](https://github.com/nextauthjs/next-auth/blob/main/CONTRIBUTING.md).
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"description": "mongoDB adapter for next-auth.",
|
"description": "mongoDB adapter for next-auth.",
|
||||||
"homepage": "https://next-auth.js.org",
|
"homepage": "https://next-auth.js.org",
|
||||||
"repository": "https://github.com/nextauthjs/adapters",
|
"repository": "https://github.com/nextauthjs/next-auth",
|
||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/nextauthjs/next-auth/issues"
|
"url": "https://github.com/nextauthjs/next-auth/issues"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
Open Source. Full Stack. Own Your Data.
|
Open Source. Full Stack. Own Your Data.
|
||||||
</p>
|
</p>
|
||||||
<p align="center" style="align: center;">
|
<p align="center" style="align: center;">
|
||||||
<img src="https://github.com/nextauthjs/adapters/actions/workflows/release.yml/badge.svg" alt="Canary CI Test" />
|
<img src="https://github.com/nextauthjs/next-auth/actions/workflows/release.yml/badge.svg?branch=main" alt="Canary CI Test" />
|
||||||
<img src="https://img.shields.io/bundlephobia/minzip/@next-auth/neo4j-adapter" alt="Bundle Size"/>
|
<img src="https://img.shields.io/bundlephobia/minzip/@next-auth/neo4j-adapter" alt="Bundle Size"/>
|
||||||
<img src="https://img.shields.io/npm/v/@next-auth/neo4j-adapter" alt="@next-auth/neo4j-adapter Version" />
|
<img src="https://img.shields.io/npm/v/@next-auth/neo4j-adapter" alt="@next-auth/neo4j-adapter Version" />
|
||||||
</p>
|
</p>
|
||||||
@@ -50,7 +50,7 @@ export default NextAuth({
|
|||||||
|
|
||||||
## Contributing
|
## 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/adapters/blob/canary/CONTRIBUTING.md).
|
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/next-auth/blob/canary/CONTRIBUTING.md).
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"description": "neo4j adapter for next-auth.",
|
"description": "neo4j adapter for next-auth.",
|
||||||
"homepage": "https://next-auth.js.org",
|
"homepage": "https://next-auth.js.org",
|
||||||
"repository": "https://github.com/nextauthjs/adapters",
|
"repository": "https://github.com/nextauthjs/next-auth",
|
||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/nextauthjs/next-auth/issues"
|
"url": "https://github.com/nextauthjs/next-auth/issues"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
Open Source. Full Stack. Own Your Data.
|
Open Source. Full Stack. Own Your Data.
|
||||||
</p>
|
</p>
|
||||||
<p align="center" style="align: center;">
|
<p align="center" style="align: center;">
|
||||||
<img src="https://github.com/nextauthjs/adapters/actions/workflows/release.yml/badge.svg" alt="CI Test" />
|
<img src="https://github.com/nextauthjs/next-auth/actions/workflows/release.yml/badge.svg?branch=main" alt="CI Test" />
|
||||||
<img src="https://img.shields.io/bundlephobia/minzip/@next-auth/pouchdb-adapter" alt="Bundle Size"/>
|
<img src="https://img.shields.io/bundlephobia/minzip/@next-auth/pouchdb-adapter" alt="Bundle Size"/>
|
||||||
<img src="https://img.shields.io/npm/v/@next-auth/pouchdb-adapter" alt="@next-auth/pouchdb-adapter Version" />
|
<img src="https://img.shields.io/npm/v/@next-auth/pouchdb-adapter" alt="@next-auth/pouchdb-adapter Version" />
|
||||||
</p>
|
</p>
|
||||||
@@ -71,7 +71,7 @@ For more details, please see https://pouchdb.com/api.html#sync
|
|||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
We're open to all community contributions! If you'd like to contribute in any way, please read our [Contributing Guide](https://github.com/nextauthjs/adapters/blob/main/CONTRIBUTING.md).
|
We're open to all community contributions! If you'd like to contribute in any way, please read our [Contributing Guide](https://github.com/nextauthjs/next-auth/blob/main/CONTRIBUTING.md).
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
"version": "0.1.3",
|
"version": "0.1.3",
|
||||||
"description": "PouchDB adapter for next-auth.",
|
"description": "PouchDB adapter for next-auth.",
|
||||||
"homepage": "https://next-auth.js.org",
|
"homepage": "https://next-auth.js.org",
|
||||||
"repository": "https://github.com/nextauthjs/adapters",
|
"repository": "https://github.com/nextauthjs/next-auth",
|
||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/nextauthjs/next-auth/issues"
|
"url": "https://github.com/nextauthjs/next-auth/issues"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
Open Source. Full Stack. Own Your Data.
|
Open Source. Full Stack. Own Your Data.
|
||||||
</p>
|
</p>
|
||||||
<p align="center" style="align: center;">
|
<p align="center" style="align: center;">
|
||||||
<img src="https://github.com/nextauthjs/adapters/actions/workflows/release.yml/badge.svg" alt="CI Test" />
|
<img src="https://github.com/nextauthjs/next-auth/actions/workflows/release.yml/badge.svg?branch=main" alt="CI Test" />
|
||||||
<a href="https://www.npmjs.com/package/@next-auth/prisma-adapter" target="_blank"><img src="https://img.shields.io/bundlephobia/minzip/@next-auth/prisma-adapter/next" alt="Bundle Size"/></a>
|
<a href="https://www.npmjs.com/package/@next-auth/prisma-adapter" target="_blank"><img src="https://img.shields.io/bundlephobia/minzip/@next-auth/prisma-adapter/next" alt="Bundle Size"/></a>
|
||||||
<a href="https://www.npmjs.com/package/@next-auth/prisma-adapter" target="_blank"><img src="https://img.shields.io/npm/v/@next-auth/prisma-adapter/next" alt="@next-auth/prisma-adapter Version" /></a>
|
<a href="https://www.npmjs.com/package/@next-auth/prisma-adapter" target="_blank"><img src="https://img.shields.io/npm/v/@next-auth/prisma-adapter/next" alt="@next-auth/prisma-adapter Version" /></a>
|
||||||
</p>
|
</p>
|
||||||
@@ -48,7 +48,7 @@ export default NextAuth({
|
|||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
We're open to all community contributions! If you'd like to contribute in any way, please read our [Contributing Guide](https://github.com/nextauthjs/adapters/blob/main/CONTRIBUTING.md).
|
We're open to all community contributions! If you'd like to contribute in any way, please read our [Contributing Guide](https://github.com/nextauthjs/next-auth/blob/main/CONTRIBUTING.md).
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"description": "Prisma adapter for next-auth.",
|
"description": "Prisma adapter for next-auth.",
|
||||||
"homepage": "https://next-auth.js.org",
|
"homepage": "https://next-auth.js.org",
|
||||||
"repository": "https://github.com/nextauthjs/adapters",
|
"repository": "https://github.com/nextauthjs/next-auth",
|
||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/nextauthjs/next-auth/issues"
|
"url": "https://github.com/nextauthjs/next-auth/issues"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
Open Source. Full Stack. Own Your Data.
|
Open Source. Full Stack. Own Your Data.
|
||||||
</p>
|
</p>
|
||||||
<p align="center" style="align: center;">
|
<p align="center" style="align: center;">
|
||||||
<img src="https://github.com/nextauthjs/adapters/actions/workflows/release.yml/badge.svg" alt="CI Test" />
|
<img src="https://github.com/nextauthjs/next-auth/actions/workflows/release.yml/badge.svg?branch=main" alt="CI Test" />
|
||||||
<img src="https://img.shields.io/bundlephobia/minzip/@next-auth/sequelize-adapter" alt="Bundle Size"/>
|
<img src="https://img.shields.io/bundlephobia/minzip/@next-auth/sequelize-adapter" alt="Bundle Size"/>
|
||||||
<img src="https://img.shields.io/npm/v/@next-auth/sequelize-adapter" alt="@next-auth/sequelize-adapter Version" />
|
<img src="https://img.shields.io/npm/v/@next-auth/sequelize-adapter" alt="@next-auth/sequelize-adapter Version" />
|
||||||
</p>
|
</p>
|
||||||
@@ -89,7 +89,7 @@ export default NextAuth({
|
|||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
We're open to all community contributions! If you'd like to contribute in any way, please read our [Contributing Guide](https://github.com/nextauthjs/adapters/blob/main/CONTRIBUTING.md).
|
We're open to all community contributions! If you'd like to contribute in any way, please read our [Contributing Guide](https://github.com/nextauthjs/next-auth/blob/main/CONTRIBUTING.md).
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
{
|
{
|
||||||
"name": "@next-auth/sequelize-adapter",
|
"name": "@next-auth/sequelize-adapter",
|
||||||
"version": "1.0.2",
|
"version": "1.0.4",
|
||||||
"description": "Sequelize adapter for next-auth.",
|
"description": "Sequelize adapter for next-auth.",
|
||||||
"homepage": "https://next-auth.js.org",
|
"homepage": "https://next-auth.js.org",
|
||||||
"repository": "https://github.com/nextauthjs/adapters",
|
"repository": "https://github.com/nextauthjs/next-auth",
|
||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/nextauthjs/adapters/issues"
|
"url": "https://github.com/nextauthjs/next-auth/issues"
|
||||||
},
|
},
|
||||||
"author": "github.com/luke-j",
|
"author": "github.com/luke-j",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
transform: {
|
transform: {
|
||||||
".(ts|tsx)$": "ts-jest",
|
".(ts|tsx)$": "@swc/jest",
|
||||||
".(js|jsx)$": "babel-jest", // jest's default
|
".(js|jsx)$": "@swc/jest", // jest's default
|
||||||
},
|
},
|
||||||
transformIgnorePatterns: ["[/\\\\]node_modules[/\\\\].+\\.(js|jsx)$"],
|
transformIgnorePatterns: ["[/\\\\]node_modules[/\\\\].+\\.(js|jsx)$"],
|
||||||
moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"],
|
moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"],
|
||||||
|
|||||||
@@ -19,7 +19,6 @@
|
|||||||
"@types/nodemailer": "^6.4.4",
|
"@types/nodemailer": "^6.4.4",
|
||||||
"@typescript-eslint/eslint-plugin": "^4.24.0",
|
"@typescript-eslint/eslint-plugin": "^4.24.0",
|
||||||
"@typescript-eslint/parser": "^4.24.0",
|
"@typescript-eslint/parser": "^4.24.0",
|
||||||
"babel-jest": "^27.4.2",
|
|
||||||
"eslint": "^7.27.0",
|
"eslint": "^7.27.0",
|
||||||
"eslint-config-prettier": "^8.3.0",
|
"eslint-config-prettier": "^8.3.0",
|
||||||
"eslint-config-standard-with-typescript": "^20.0.0",
|
"eslint-config-standard-with-typescript": "^20.0.0",
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
Open Source. Full Stack. Own Your Data.
|
Open Source. Full Stack. Own Your Data.
|
||||||
</p>
|
</p>
|
||||||
<p align="center" style="align: center;">
|
<p align="center" style="align: center;">
|
||||||
<img src="https://github.com/nextauthjs/adapters/actions/workflows/release.yml/badge.svg" alt="Canary CI Test" />
|
<img src="https://github.com/nextauthjs/next-auth/actions/workflows/release.yml/badge.svg?branch=main" alt="Canary CI Test" />
|
||||||
<img src="https://img.shields.io/bundlephobia/minzip/@next-auth/typeorm-legacy-adapter/canary" alt="Bundle Size"/>
|
<img src="https://img.shields.io/bundlephobia/minzip/@next-auth/typeorm-legacy-adapter/canary" alt="Bundle Size"/>
|
||||||
<img src="https://img.shields.io/npm/v/@next-auth/typeorm-legacy-adapter" alt="@next-auth/typeorm-legacy-adapter Version" />
|
<img src="https://img.shields.io/npm/v/@next-auth/typeorm-legacy-adapter" alt="@next-auth/typeorm-legacy-adapter Version" />
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@@ -3,9 +3,9 @@
|
|||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"description": "TypeORM (legacy) adapter for next-auth.",
|
"description": "TypeORM (legacy) adapter for next-auth.",
|
||||||
"homepage": "https://next-auth.js.org",
|
"homepage": "https://next-auth.js.org",
|
||||||
"repository": "https://github.com/nextauthjs/adapters",
|
"repository": "https://github.com/nextauthjs/next-auth",
|
||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/nextauthjs/adapters/issues"
|
"url": "https://github.com/nextauthjs/next-auth/issues"
|
||||||
},
|
},
|
||||||
"author": "Iain Collins",
|
"author": "Iain Collins",
|
||||||
"contributors": [
|
"contributors": [
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
Open Source. Full Stack. Own Your Data.
|
Open Source. Full Stack. Own Your Data.
|
||||||
</p>
|
</p>
|
||||||
<p align="center" style="align: center;">
|
<p align="center" style="align: center;">
|
||||||
<img src="https://github.com/nextauthjs/adapters/actions/workflows/release.yml/badge.svg" alt="CI Test" />
|
<img src="https://github.com/nextauthjs/next-auth/actions/workflows/release.yml/badge.svg?branch=main" alt="CI Test" />
|
||||||
<img src="https://img.shields.io/bundlephobia/minzip/@next-auth/upstash-adapter" alt="Bundle Size"/>
|
<img src="https://img.shields.io/bundlephobia/minzip/@next-auth/upstash-adapter" alt="Bundle Size"/>
|
||||||
<img src="https://img.shields.io/npm/v/@next-auth/upstash-adapter" alt="@next-auth/upstash-adapter Version" />
|
<img src="https://img.shields.io/npm/v/@next-auth/upstash-adapter" alt="@next-auth/upstash-adapter Version" />
|
||||||
</p>
|
</p>
|
||||||
@@ -80,7 +80,7 @@ export default NextAuth({
|
|||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
We're open to all community contributions! If you'd like to contribute in any way, please read our [Contributing Guide](https://github.com/nextauthjs/adapters/blob/main/CONTRIBUTING.md).
|
We're open to all community contributions! If you'd like to contribute in any way, please read our [Contributing Guide](https://github.com/nextauthjs/next-auth/blob/main/CONTRIBUTING.md).
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|||||||
@@ -3,9 +3,9 @@
|
|||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"description": "Upstash adapter for next-auth. It uses Upstash's connectionless (HTTP based) Redis client.",
|
"description": "Upstash adapter for next-auth. It uses Upstash's connectionless (HTTP based) Redis client.",
|
||||||
"homepage": "https://next-auth.js.org",
|
"homepage": "https://next-auth.js.org",
|
||||||
"repository": "https://github.com/nextauthjs/adapters",
|
"repository": "https://github.com/nextauthjs/next-auth",
|
||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/nextauthjs/adapters/issues"
|
"url": "https://github.com/nextauthjs/next-auth/issues"
|
||||||
},
|
},
|
||||||
"author": "github.com/kay-is",
|
"author": "github.com/kay-is",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ module.exports = (api) => {
|
|||||||
ignore: [
|
ignore: [
|
||||||
"../src/**/__tests__/**",
|
"../src/**/__tests__/**",
|
||||||
"../src/adapters.ts",
|
"../src/adapters.ts",
|
||||||
"../src/lib/types.ts",
|
|
||||||
"../src/providers/oauth-types.ts",
|
"../src/providers/oauth-types.ts",
|
||||||
],
|
],
|
||||||
comments: false,
|
comments: false,
|
||||||
@@ -33,7 +32,7 @@ module.exports = (api) => {
|
|||||||
{
|
{
|
||||||
test: [
|
test: [
|
||||||
"../src/react/index.tsx",
|
"../src/react/index.tsx",
|
||||||
"../src/lib/logger.ts",
|
"../src/utils/logger.ts",
|
||||||
"../src/core/errors.ts",
|
"../src/core/errors.ts",
|
||||||
"../src/client/**",
|
"../src/client/**",
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -1,10 +1,7 @@
|
|||||||
/** @type {import('@jest/types').Config.InitialOptions} */
|
/** @type {import('@jest/types').Config.InitialOptions} */
|
||||||
module.exports = {
|
module.exports = {
|
||||||
transform: {
|
transform: {
|
||||||
"\\.(js|jsx|ts|tsx)$": [
|
"\\.(js|jsx|ts|tsx)$": ["@swc/jest", require("./swc.config")],
|
||||||
"babel-jest",
|
|
||||||
{ configFile: "./config/babel.config.js" },
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
rootDir: "../src",
|
rootDir: "../src",
|
||||||
setupFilesAfterEnv: ["../config/jest-setup.js"],
|
setupFilesAfterEnv: ["../config/jest-setup.js"],
|
||||||
13
packages/next-auth/config/jest.core.config.js
Normal file
13
packages/next-auth/config/jest.core.config.js
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
/** @type {import('@jest/types').Config.InitialOptions} */
|
||||||
|
module.exports = {
|
||||||
|
transform: {
|
||||||
|
"\\.(js|jsx|ts|tsx)$": ["@swc/jest", require("./swc.config")],
|
||||||
|
},
|
||||||
|
rootDir: "..",
|
||||||
|
testMatch: ["**/*.test.ts"],
|
||||||
|
setupFilesAfterEnv: ["./config/jest-setup.js"],
|
||||||
|
watchPlugins: [
|
||||||
|
"jest-watch-typeahead/filename",
|
||||||
|
"jest-watch-typeahead/testname",
|
||||||
|
],
|
||||||
|
}
|
||||||
17
packages/next-auth/config/swc.config.js
Normal file
17
packages/next-auth/config/swc.config.js
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
module.exports = {
|
||||||
|
jsc: {
|
||||||
|
parser: {
|
||||||
|
syntax: "typescript",
|
||||||
|
tsx: true,
|
||||||
|
},
|
||||||
|
transform: {
|
||||||
|
react: {
|
||||||
|
runtime: "automatic",
|
||||||
|
pragma: "React.createElement",
|
||||||
|
pragmaFrag: "React.Fragment",
|
||||||
|
throwIfNamespace: true,
|
||||||
|
useBuiltins: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "next-auth",
|
"name": "next-auth",
|
||||||
"version": "4.3.4",
|
"version": "4.6.1",
|
||||||
"description": "Authentication for Next.js",
|
"description": "Authentication for Next.js",
|
||||||
"homepage": "https://next-auth.js.org",
|
"homepage": "https://next-auth.js.org",
|
||||||
"repository": "https://github.com/nextauthjs/next-auth.git",
|
"repository": "https://github.com/nextauthjs/next-auth.git",
|
||||||
@@ -37,11 +37,13 @@
|
|||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "pnpm clean && pnpm build:js && pnpm build:css",
|
"build": "pnpm clean && pnpm build:js && pnpm build:css",
|
||||||
"clean": "rm -rf client css lib providers core jwt react next index.d.ts index.js adapters.d.ts middleware.d.ts middleware.js",
|
"clean": "rm -rf client css utils providers core jwt react next index.d.ts index.js adapters.d.ts middleware.d.ts middleware.js",
|
||||||
"build:js": "pnpm clean && pnpm generate-providers && tsc && babel --config-file ./config/babel.config.js src --out-dir . --extensions \".tsx,.ts,.js,.jsx\"",
|
"build:js": "pnpm clean && pnpm generate-providers && tsc && babel --config-file ./config/babel.config.js src --out-dir . --extensions \".tsx,.ts,.js,.jsx\"",
|
||||||
"build:css": "postcss --config config/postcss.config.js src/**/*.css --base src --dir . && node config/wrap-css.js",
|
"build:css": "postcss --config config/postcss.config.js src/**/*.css --base src --dir . && node config/wrap-css.js",
|
||||||
"watch:css": "postcss --config config/postcss.config.js --watch src/**/*.css --base src --dir .",
|
"watch:css": "postcss --config config/postcss.config.js --watch src/**/*.css --base src --dir .",
|
||||||
"test": "jest --config ./config/jest.config.js",
|
"test:client": "jest --config ./config/jest.client.config.js",
|
||||||
|
"test:core": "jest --config ./config/jest.core.config.js",
|
||||||
|
"test": "pnpm test:core && pnpm test:client",
|
||||||
"prepublishOnly": "pnpm build",
|
"prepublishOnly": "pnpm build",
|
||||||
"generate-providers": "node ./config/generate-providers.js",
|
"generate-providers": "node ./config/generate-providers.js",
|
||||||
"setup": "pnpm generate-providers",
|
"setup": "pnpm generate-providers",
|
||||||
@@ -60,7 +62,8 @@
|
|||||||
"index.js",
|
"index.js",
|
||||||
"adapters.d.ts",
|
"adapters.d.ts",
|
||||||
"middleware.d.ts",
|
"middleware.d.ts",
|
||||||
"middleware.js"
|
"middleware.js",
|
||||||
|
"utils"
|
||||||
],
|
],
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -85,38 +88,40 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/cli": "^7.16.0",
|
"@babel/cli": "^7.17.10",
|
||||||
"@babel/core": "^7.16.0",
|
"@babel/core": "^7.18.2",
|
||||||
"@babel/plugin-proposal-optional-catch-binding": "^7.16.0",
|
"@babel/plugin-proposal-optional-catch-binding": "^7.16.7",
|
||||||
"@babel/plugin-transform-runtime": "^7.16.4",
|
"@babel/plugin-transform-runtime": "^7.18.2",
|
||||||
"@babel/preset-env": "^7.16.4",
|
"@babel/preset-env": "^7.18.2",
|
||||||
"@babel/preset-react": "^7.16.0",
|
"@babel/preset-react": "^7.17.12",
|
||||||
"@babel/preset-typescript": "^7.16.0",
|
"@babel/preset-typescript": "^7.17.12",
|
||||||
"@next-auth/tsconfig": "workspace:^0.0.0",
|
"@next-auth/tsconfig": "workspace:^0.0.0",
|
||||||
"@testing-library/dom": "^8.11.3",
|
"@swc/core": "^1.2.198",
|
||||||
"@testing-library/jest-dom": "^5.16.1",
|
"@swc/jest": "^0.2.21",
|
||||||
"@testing-library/react": "^12.1.2",
|
"@testing-library/dom": "^8.13.0",
|
||||||
"@testing-library/react-hooks": "^7.0.2",
|
"@testing-library/jest-dom": "^5.16.4",
|
||||||
"@testing-library/user-event": "^13.5.0",
|
"@testing-library/react": "^13.3.0",
|
||||||
"@types/node": "^16.11.12",
|
"@testing-library/react-hooks": "^8.0.0",
|
||||||
|
"@testing-library/user-event": "^14.2.0",
|
||||||
|
"@types/node": "^17.0.42",
|
||||||
"@types/nodemailer": "^6.4.4",
|
"@types/nodemailer": "^6.4.4",
|
||||||
"@types/oauth": "^0.9.1",
|
"@types/oauth": "^0.9.1",
|
||||||
"@types/react": "^17.0.37",
|
"@types/react": "^18.0.2",
|
||||||
"@types/react-dom": "^17.0.11",
|
"@types/react-dom": "^18.0.5",
|
||||||
"autoprefixer": "^10.4.0",
|
"autoprefixer": "^10.4.7",
|
||||||
"babel-jest": "^27.4.2",
|
|
||||||
"babel-plugin-jsx-pragmatic": "^1.0.2",
|
"babel-plugin-jsx-pragmatic": "^1.0.2",
|
||||||
"babel-preset-preact": "^2.0.0",
|
"babel-preset-preact": "^2.0.0",
|
||||||
"cssnano": "^5.0.12",
|
"cssnano": "^5.1.11",
|
||||||
"jest": "^27.4.3",
|
"jest": "^28.1.1",
|
||||||
"jest-watch-typeahead": "^1.0.0",
|
"jest-environment-jsdom": "^28.1.1",
|
||||||
"msw": "^0.36.3",
|
"jest-watch-typeahead": "^1.1.0",
|
||||||
"next": "12.1.0",
|
"msw": "^0.42.1",
|
||||||
"postcss": "^8.4.12",
|
"next": "^12.1.6",
|
||||||
"postcss-cli": "^9.0.2",
|
"postcss": "^8.4.14",
|
||||||
|
"postcss-cli": "^9.1.0",
|
||||||
"postcss-nested": "^5.0.6",
|
"postcss-nested": "^5.0.6",
|
||||||
"react": "^17.0.2",
|
"react": "^18.1.0",
|
||||||
"react-dom": "^17.0.2",
|
"react-dom": "^18.1.0",
|
||||||
"whatwg-fetch": "^3.6.2"
|
"whatwg-fetch": "^3.6.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ export interface VerificationToken {
|
|||||||
* - `deleteUser`
|
* - `deleteUser`
|
||||||
* - `unlinkAccount`
|
* - `unlinkAccount`
|
||||||
*
|
*
|
||||||
* [Community adapters](https://github.com/nextauthjs/adapters) |
|
* [Adapters Overview](https://next-auth.js.org/adapters/overview) |
|
||||||
* [Create a custom adapter](https://next-auth.js.org/tutorials/creating-a-database-adapter)
|
* [Create a custom adapter](https://next-auth.js.org/tutorials/creating-a-database-adapter)
|
||||||
*/
|
*/
|
||||||
export interface Adapter {
|
export interface Adapter {
|
||||||
|
|||||||
@@ -2,11 +2,11 @@ import { useState } from "react"
|
|||||||
import userEvent from "@testing-library/user-event"
|
import userEvent from "@testing-library/user-event"
|
||||||
import { render, screen, waitFor } from "@testing-library/react"
|
import { render, screen, waitFor } from "@testing-library/react"
|
||||||
import { server, mockCSRFToken } from "./helpers/mocks"
|
import { server, mockCSRFToken } from "./helpers/mocks"
|
||||||
import logger from "../../lib/logger"
|
import logger from "../../utils/logger"
|
||||||
import { getCsrfToken } from "../../react"
|
import { getCsrfToken } from "../../react"
|
||||||
import { rest } from "msw"
|
import { rest } from "msw"
|
||||||
|
|
||||||
jest.mock("../../lib/logger", () => ({
|
jest.mock("../../utils/logger", () => ({
|
||||||
__esModule: true,
|
__esModule: true,
|
||||||
default: {
|
default: {
|
||||||
warn: jest.fn(),
|
warn: jest.fn(),
|
||||||
|
|||||||
@@ -3,10 +3,10 @@ import userEvent from "@testing-library/user-event"
|
|||||||
import { render, screen, waitFor } from "@testing-library/react"
|
import { render, screen, waitFor } from "@testing-library/react"
|
||||||
import { server, mockProviders } from "./helpers/mocks"
|
import { server, mockProviders } from "./helpers/mocks"
|
||||||
import { getProviders } from "../../react"
|
import { getProviders } from "../../react"
|
||||||
import logger from "../../lib/logger"
|
import logger from "../../utils/logger"
|
||||||
import { rest } from "msw"
|
import { rest } from "msw"
|
||||||
|
|
||||||
jest.mock("../../lib/logger", () => ({
|
jest.mock("../../utils/logger", () => ({
|
||||||
__esModule: true,
|
__esModule: true,
|
||||||
default: {
|
default: {
|
||||||
warn: jest.fn(),
|
warn: jest.fn(),
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import { render, screen, waitFor } from "@testing-library/react"
|
import { render, screen, waitFor } from "@testing-library/react"
|
||||||
import { rest } from "msw"
|
import { rest } from "msw"
|
||||||
import { server, mockSession } from "./helpers/mocks"
|
import { server, mockSession } from "./helpers/mocks"
|
||||||
import logger from "../../lib/logger"
|
import logger from "../../utils/logger"
|
||||||
import { useState, useEffect } from "react"
|
import { useState, useEffect } from "react"
|
||||||
import { getSession } from "../../react"
|
import { getSession } from "../../react"
|
||||||
import { getBroadcastEvents } from "./helpers/utils"
|
import { getBroadcastEvents } from "./helpers/utils"
|
||||||
|
|
||||||
jest.mock("../../lib/logger", () => ({
|
jest.mock("../../utils/logger", () => ({
|
||||||
__esModule: true,
|
__esModule: true,
|
||||||
default: {
|
default: {
|
||||||
warn: jest.fn(),
|
warn: jest.fn(),
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { useState } from "react"
|
import { useState } from "react"
|
||||||
import userEvent from "@testing-library/user-event"
|
import userEvent from "@testing-library/user-event"
|
||||||
import { render, screen, waitFor } from "@testing-library/react"
|
import { render, screen, waitFor } from "@testing-library/react"
|
||||||
import logger from "../../lib/logger"
|
import logger from "../../utils/logger"
|
||||||
import {
|
import {
|
||||||
server,
|
server,
|
||||||
mockCredentialsResponse,
|
mockCredentialsResponse,
|
||||||
@@ -13,7 +13,7 @@ import { rest } from "msw"
|
|||||||
|
|
||||||
const { location } = window
|
const { location } = window
|
||||||
|
|
||||||
jest.mock("../../lib/logger", () => ({
|
jest.mock("../../utils/logger", () => ({
|
||||||
__esModule: true,
|
__esModule: true,
|
||||||
default: {
|
default: {
|
||||||
warn: jest.fn(),
|
warn: jest.fn(),
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
import logger, { setLogger } from "../lib/logger"
|
import logger, { setLogger } from "../utils/logger"
|
||||||
|
import { detectHost } from "../utils/detect-host"
|
||||||
import * as routes from "./routes"
|
import * as routes from "./routes"
|
||||||
import renderPage from "./pages"
|
import renderPage from "./pages"
|
||||||
import { init } from "./init"
|
import { init } from "./init"
|
||||||
import { assertConfig } from "./lib/assert"
|
import { assertConfig } from "./lib/assert"
|
||||||
import { SessionStore } from "./lib/cookie"
|
import { SessionStore } from "./lib/cookie"
|
||||||
|
|
||||||
import type { NextAuthOptions } from "./types"
|
import type { NextAuthAction, NextAuthOptions } from "./types"
|
||||||
import type { NextAuthAction } from "../lib/types"
|
|
||||||
import type { Cookie } from "./lib/cookie"
|
import type { Cookie } from "./lib/cookie"
|
||||||
import type { ErrorType } from "./pages/error"
|
import type { ErrorType } from "./pages/error"
|
||||||
|
|
||||||
export interface IncomingRequest {
|
export interface RequestInternal {
|
||||||
/** @default "http://localhost:3000" */
|
/** @default "http://localhost:3000" */
|
||||||
host?: string
|
host?: string
|
||||||
method?: string
|
method?: string
|
||||||
@@ -39,18 +39,55 @@ export interface OutgoingResponse<
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface NextAuthHandlerParams {
|
export interface NextAuthHandlerParams {
|
||||||
req: IncomingRequest
|
req: Request | RequestInternal
|
||||||
options: NextAuthOptions
|
options: NextAuthOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function getBody(req: Request): Promise<Record<string, any> | undefined> {
|
||||||
|
try {
|
||||||
|
return await req.json()
|
||||||
|
} catch {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO:
|
||||||
|
async function toInternalRequest(
|
||||||
|
req: RequestInternal | Request
|
||||||
|
): Promise<RequestInternal> {
|
||||||
|
if (req instanceof Request) {
|
||||||
|
const url = new URL(req.url)
|
||||||
|
// TODO: handle custom paths?
|
||||||
|
const nextauth = url.pathname.split("/").slice(3)
|
||||||
|
const headers = Object.fromEntries(req.headers.entries())
|
||||||
|
const query: Record<string, any> = Object.fromEntries(
|
||||||
|
url.searchParams.entries()
|
||||||
|
)
|
||||||
|
query.nextauth = nextauth
|
||||||
|
|
||||||
|
return {
|
||||||
|
action: nextauth[0] as NextAuthAction,
|
||||||
|
method: req.method,
|
||||||
|
headers,
|
||||||
|
body: await getBody(req),
|
||||||
|
cookies: {},
|
||||||
|
providerId: nextauth[1],
|
||||||
|
error: url.searchParams.get("error") ?? nextauth[1],
|
||||||
|
host: detectHost(headers["x-forwarded-host"] ?? headers.host),
|
||||||
|
query,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return req
|
||||||
|
}
|
||||||
|
|
||||||
export async function NextAuthHandler<
|
export async function NextAuthHandler<
|
||||||
Body extends string | Record<string, any> | any[]
|
Body extends string | Record<string, any> | any[]
|
||||||
>(params: NextAuthHandlerParams): Promise<OutgoingResponse<Body>> {
|
>(params: NextAuthHandlerParams): Promise<OutgoingResponse<Body>> {
|
||||||
const { options: userOptions, req } = params
|
const { options: userOptions, req: incomingRequest } = params
|
||||||
|
|
||||||
|
const req = await toInternalRequest(incomingRequest)
|
||||||
|
|
||||||
setLogger(userOptions.logger, userOptions.debug)
|
setLogger(userOptions.logger, userOptions.debug)
|
||||||
|
|
||||||
const assertionResult = assertConfig(params)
|
const assertionResult = assertConfig({ options: userOptions, req })
|
||||||
|
|
||||||
if (typeof assertionResult === "string") {
|
if (typeof assertionResult === "string") {
|
||||||
logger.warn(assertionResult)
|
logger.warn(assertionResult)
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { NextAuthOptions } from ".."
|
import { NextAuthOptions } from ".."
|
||||||
import logger from "../lib/logger"
|
import logger from "../utils/logger"
|
||||||
import parseUrl from "../lib/parse-url"
|
import parseUrl from "../utils/parse-url"
|
||||||
import { InternalOptions } from "../lib/types"
|
|
||||||
import { adapterErrorHandler, eventsErrorHandler } from "./errors"
|
import { adapterErrorHandler, eventsErrorHandler } from "./errors"
|
||||||
import parseProviders from "./lib/providers"
|
import parseProviders from "./lib/providers"
|
||||||
import createSecret from "./lib/utils"
|
import createSecret from "./lib/utils"
|
||||||
@@ -10,7 +9,9 @@ import * as jwt from "../jwt"
|
|||||||
import { defaultCallbacks } from "./lib/default-callbacks"
|
import { defaultCallbacks } from "./lib/default-callbacks"
|
||||||
import { createCSRFToken } from "./lib/csrf-token"
|
import { createCSRFToken } from "./lib/csrf-token"
|
||||||
import { createCallbackUrl } from "./lib/callback-url"
|
import { createCallbackUrl } from "./lib/callback-url"
|
||||||
import { IncomingRequest } from "."
|
import { RequestInternal } from "."
|
||||||
|
|
||||||
|
import type { InternalOptions } from "./types"
|
||||||
|
|
||||||
interface InitParams {
|
interface InitParams {
|
||||||
host?: string
|
host?: string
|
||||||
@@ -23,7 +24,7 @@ interface InitParams {
|
|||||||
csrfToken?: string
|
csrfToken?: string
|
||||||
/** Is the incoming request a POST request? */
|
/** Is the incoming request a POST request? */
|
||||||
isPost: boolean
|
isPost: boolean
|
||||||
cookies: IncomingRequest["cookies"]
|
cookies: RequestInternal["cookies"]
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Initialize all internal options and cookies. */
|
/** Initialize all internal options and cookies. */
|
||||||
|
|||||||
@@ -6,11 +6,11 @@ import {
|
|||||||
UnsupportedStrategy,
|
UnsupportedStrategy,
|
||||||
InvalidCallbackUrl,
|
InvalidCallbackUrl,
|
||||||
} from "../errors"
|
} from "../errors"
|
||||||
import parseUrl from "../../lib/parse-url"
|
import parseUrl from "../../utils/parse-url"
|
||||||
import { defaultCookies } from "./cookie"
|
import { defaultCookies } from "./cookie"
|
||||||
|
|
||||||
import type { NextAuthHandlerParams } from ".."
|
import type { NextAuthHandlerParams, RequestInternal } from ".."
|
||||||
import type { WarningCode } from "../../lib/logger"
|
import type { WarningCode } from "../../utils/logger"
|
||||||
|
|
||||||
type ConfigError =
|
type ConfigError =
|
||||||
| MissingAPIRoute
|
| MissingAPIRoute
|
||||||
@@ -21,9 +21,11 @@ type ConfigError =
|
|||||||
|
|
||||||
let twitterWarned = false
|
let twitterWarned = false
|
||||||
|
|
||||||
function isValidHttpUrl(url: string) {
|
function isValidHttpUrl(url: string, baseUrl: string) {
|
||||||
try {
|
try {
|
||||||
return /^https?:/.test(new URL(url).protocol)
|
return /^https?:/.test(
|
||||||
|
new URL(url, url.startsWith("/") ? baseUrl : undefined).protocol
|
||||||
|
)
|
||||||
} catch {
|
} catch {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -36,11 +38,13 @@ function isValidHttpUrl(url: string) {
|
|||||||
* REVIEW: Make some of these and corresponding docs less Next.js specific?
|
* REVIEW: Make some of these and corresponding docs less Next.js specific?
|
||||||
*/
|
*/
|
||||||
export function assertConfig(
|
export function assertConfig(
|
||||||
params: NextAuthHandlerParams
|
params: NextAuthHandlerParams & {
|
||||||
|
req: RequestInternal
|
||||||
|
}
|
||||||
): ConfigError | WarningCode | undefined {
|
): ConfigError | WarningCode | undefined {
|
||||||
const { options, req } = params
|
const { options, req } = params
|
||||||
|
|
||||||
// req.query isn't defined when asserting `getServerSession` for example
|
// req.query isn't defined when asserting `unstable_getServerSession` for example
|
||||||
if (!req.query?.nextauth && !req.action) {
|
if (!req.query?.nextauth && !req.action) {
|
||||||
return new MissingAPIRoute(
|
return new MissingAPIRoute(
|
||||||
"Cannot find [...nextauth].{js,ts} in `/pages/api/auth`. Make sure the filename is written correctly."
|
"Cannot find [...nextauth].{js,ts} in `/pages/api/auth`. Make sure the filename is written correctly."
|
||||||
@@ -57,23 +61,24 @@ export function assertConfig(
|
|||||||
|
|
||||||
const callbackUrlParam = req.query?.callbackUrl as string | undefined
|
const callbackUrlParam = req.query?.callbackUrl as string | undefined
|
||||||
|
|
||||||
if (callbackUrlParam && !isValidHttpUrl(callbackUrlParam)) {
|
const url = parseUrl(req.host)
|
||||||
|
|
||||||
|
if (callbackUrlParam && !isValidHttpUrl(callbackUrlParam, url.base)) {
|
||||||
return new InvalidCallbackUrl(
|
return new InvalidCallbackUrl(
|
||||||
`Invalid callback URL. Received: ${callbackUrlParam}`
|
`Invalid callback URL. Received: ${callbackUrlParam}`
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This is below the callbackUrlParam check because it would obscure the error
|
||||||
if (!req.host) return "NEXTAUTH_URL"
|
if (!req.host) return "NEXTAUTH_URL"
|
||||||
|
|
||||||
const url = parseUrl(req.host)
|
|
||||||
|
|
||||||
const { callbackUrl: defaultCallbackUrl } = defaultCookies(
|
const { callbackUrl: defaultCallbackUrl } = defaultCookies(
|
||||||
options.useSecureCookies ?? url.base.startsWith("https://")
|
options.useSecureCookies ?? url.base.startsWith("https://")
|
||||||
)
|
)
|
||||||
const callbackUrlCookie =
|
const callbackUrlCookie =
|
||||||
req.cookies?.[options.cookies?.callbackUrl?.name ?? defaultCallbackUrl.name]
|
req.cookies?.[options.cookies?.callbackUrl?.name ?? defaultCallbackUrl.name]
|
||||||
|
|
||||||
if (callbackUrlCookie && !isValidHttpUrl(callbackUrlCookie)) {
|
if (callbackUrlCookie && !isValidHttpUrl(callbackUrlCookie, url.base)) {
|
||||||
return new InvalidCallbackUrl(
|
return new InvalidCallbackUrl(
|
||||||
`Invalid callback URL. Received: ${callbackUrlCookie}`
|
`Invalid callback URL. Received: ${callbackUrlCookie}`
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
|
import { randomBytes, randomUUID } from "crypto"
|
||||||
import { AccountNotLinkedError } from "../errors"
|
import { AccountNotLinkedError } from "../errors"
|
||||||
import { fromDate } from "./utils"
|
import { fromDate } from "./utils"
|
||||||
import { randomBytes, randomUUID } from "crypto"
|
|
||||||
import { InternalOptions } from "../../lib/types"
|
import type { InternalOptions } from "../types"
|
||||||
import { AdapterSession, AdapterUser } from "../../adapters"
|
import type { AdapterSession, AdapterUser } from "../../adapters"
|
||||||
import { JWT } from "../../jwt"
|
import type { JWT } from "../../jwt"
|
||||||
import { Account, User } from "../.."
|
import type { Account, User } from "../.."
|
||||||
import { SessionToken } from "./cookie"
|
import type { SessionToken } from "./cookie"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function handles the complex flow of signing users in, and either creating,
|
* This function handles the complex flow of signing users in, and either creating,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { InternalOptions } from "../../lib/types"
|
import type { InternalOptions } from "../types"
|
||||||
|
|
||||||
interface CreateCallbackUrlParams {
|
interface CreateCallbackUrlParams {
|
||||||
options: InternalOptions
|
options: InternalOptions
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ export class SessionStore {
|
|||||||
constructor(
|
constructor(
|
||||||
option: CookieOption,
|
option: CookieOption,
|
||||||
req: {
|
req: {
|
||||||
cookies?: Record<string, string>
|
cookies?: Record<string, string> | { get: (key: string) => string }
|
||||||
headers?: Headers | IncomingHttpHeaders | Record<string, string>
|
headers?: Headers | IncomingHttpHeaders | Record<string, string>
|
||||||
},
|
},
|
||||||
logger: LoggerInstance | Console
|
logger: LoggerInstance | Console
|
||||||
@@ -132,7 +132,10 @@ export class SessionStore {
|
|||||||
|
|
||||||
for (const name in req.cookies) {
|
for (const name in req.cookies) {
|
||||||
if (name.startsWith(option.name)) {
|
if (name.startsWith(option.name)) {
|
||||||
this.#chunks[name] = req.cookies[name]
|
this.#chunks[name] =
|
||||||
|
typeof req.cookies.get === "function"
|
||||||
|
? req.cookies.get(name)
|
||||||
|
: req.cookies[name]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { createHash, randomBytes } from "crypto"
|
import { createHash, randomBytes } from "crypto"
|
||||||
import { InternalOptions } from "../../lib/types"
|
|
||||||
|
import type { InternalOptions } from "../types"
|
||||||
|
|
||||||
interface CreateCSRFTokenParams {
|
interface CreateCSRFTokenParams {
|
||||||
options: InternalOptions
|
options: InternalOptions
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { randomBytes } from "crypto"
|
import { randomBytes } from "crypto"
|
||||||
import { InternalOptions } from "../../../lib/types"
|
|
||||||
import { hashToken } from "../utils"
|
import { hashToken } from "../utils"
|
||||||
|
import type { InternalOptions } from "../../types"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Starts an e-mail login flow, by generating a token,
|
* Starts an e-mail login flow, by generating a token,
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ import { createState } from "./state-handler"
|
|||||||
import { createPKCE } from "./pkce-handler"
|
import { createPKCE } from "./pkce-handler"
|
||||||
|
|
||||||
import type { AuthorizationParameters } from "openid-client"
|
import type { AuthorizationParameters } from "openid-client"
|
||||||
import type { InternalOptions } from "../../../lib/types"
|
import type { InternalOptions } from "../../types"
|
||||||
import type { IncomingRequest } from "../.."
|
import type { RequestInternal } from "../.."
|
||||||
import type { Cookie } from "../cookie"
|
import type { Cookie } from "../cookie"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -16,7 +16,7 @@ import type { Cookie } from "../cookie"
|
|||||||
*/
|
*/
|
||||||
export default async function getAuthorizationUrl(params: {
|
export default async function getAuthorizationUrl(params: {
|
||||||
options: InternalOptions<"oauth">
|
options: InternalOptions<"oauth">
|
||||||
query: IncomingRequest["query"]
|
query: RequestInternal["query"]
|
||||||
}) {
|
}) {
|
||||||
const { options, query } = params
|
const { options, query } = params
|
||||||
const { logger, provider } = options
|
const { logger, provider } = options
|
||||||
|
|||||||
@@ -8,16 +8,16 @@ import { OAuthCallbackError } from "../../errors"
|
|||||||
import type { CallbackParamsType } from "openid-client"
|
import type { CallbackParamsType } from "openid-client"
|
||||||
import type { Account, LoggerInstance, Profile } from "../../.."
|
import type { Account, LoggerInstance, Profile } from "../../.."
|
||||||
import type { OAuthChecks, OAuthConfig } from "../../../providers"
|
import type { OAuthChecks, OAuthConfig } from "../../../providers"
|
||||||
import type { InternalOptions } from "../../../lib/types"
|
import type { InternalOptions } from "../../types"
|
||||||
import type { IncomingRequest, OutgoingResponse } from "../.."
|
import type { RequestInternal, OutgoingResponse } from "../.."
|
||||||
import type { Cookie } from "../cookie"
|
import type { Cookie } from "../cookie"
|
||||||
|
|
||||||
export default async function oAuthCallback(params: {
|
export default async function oAuthCallback(params: {
|
||||||
options: InternalOptions<"oauth">
|
options: InternalOptions<"oauth">
|
||||||
query: IncomingRequest["query"]
|
query: RequestInternal["query"]
|
||||||
body: IncomingRequest["body"]
|
body: RequestInternal["body"]
|
||||||
method: Required<IncomingRequest>["method"]
|
method: Required<RequestInternal>["method"]
|
||||||
cookies: IncomingRequest["cookies"]
|
cookies: RequestInternal["cookies"]
|
||||||
}): Promise<GetProfileResult & { cookies?: OutgoingResponse["cookies"] }> {
|
}): Promise<GetProfileResult & { cookies?: OutgoingResponse["cookies"] }> {
|
||||||
const { options, query, body, method, cookies } = params
|
const { options, query, body, method, cookies } = params
|
||||||
const { logger, provider } = options
|
const { logger, provider } = options
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
// We have the intentions to provide only minor fixes for this in the future.
|
// We have the intentions to provide only minor fixes for this in the future.
|
||||||
|
|
||||||
import { OAuth } from "oauth"
|
import { OAuth } from "oauth"
|
||||||
import { InternalOptions } from "src/lib/types"
|
import type { InternalOptions } from "../../types"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Client supporting OAuth 1.x
|
* Client supporting OAuth 1.x
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { Issuer, Client, custom } from "openid-client"
|
import { Issuer, custom } from "openid-client"
|
||||||
import { InternalOptions } from "src/lib/types"
|
import type { Client } from "openid-client"
|
||||||
|
import type { InternalOptions } from "../../types"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* NOTE: We can add auto discovery of the provider's endpoint
|
* NOTE: We can add auto discovery of the provider's endpoint
|
||||||
@@ -12,9 +13,9 @@ export async function openidClient(
|
|||||||
options: InternalOptions<"oauth">
|
options: InternalOptions<"oauth">
|
||||||
): Promise<Client> {
|
): Promise<Client> {
|
||||||
const provider = options.provider
|
const provider = options.provider
|
||||||
|
|
||||||
if (provider.httpOptions) custom.setHttpOptionsDefaults(provider.httpOptions)
|
if (provider.httpOptions) custom.setHttpOptionsDefaults(provider.httpOptions)
|
||||||
|
|
||||||
let issuer: Issuer
|
let issuer: Issuer
|
||||||
if (provider.wellKnown) {
|
if (provider.wellKnown) {
|
||||||
issuer = await Issuer.discover(provider.wellKnown)
|
issuer = await Issuer.discover(provider.wellKnown)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import * as jwt from "../../../jwt"
|
import * as jwt from "../../../jwt"
|
||||||
import { generators } from "openid-client"
|
import { generators } from "openid-client"
|
||||||
import type { InternalOptions } from "src/lib/types"
|
import type { InternalOptions } from "../../types"
|
||||||
import type { Cookie } from "../cookie"
|
import type { Cookie } from "../cookie"
|
||||||
|
|
||||||
const PKCE_CODE_CHALLENGE_METHOD = "S256"
|
const PKCE_CODE_CHALLENGE_METHOD = "S256"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { generators } from "openid-client"
|
import { generators } from "openid-client"
|
||||||
|
|
||||||
import type { InternalOptions } from "src/lib/types"
|
import type { InternalOptions } from "../../types"
|
||||||
import type { Cookie } from "../cookie"
|
import type { Cookie } from "../cookie"
|
||||||
|
|
||||||
const STATE_MAX_AGE = 60 * 15 // 15 minutes in seconds
|
const STATE_MAX_AGE = 60 * 15 // 15 minutes in seconds
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { merge } from "../../lib/merge"
|
import { merge } from "../../utils/merge"
|
||||||
|
|
||||||
import type { InternalProvider } from "../../lib/types"
|
import type { InternalProvider } from "../types"
|
||||||
import type { Provider } from "../../providers"
|
import type { Provider } from "../../providers"
|
||||||
import type { InternalUrl } from "../../lib/parse-url"
|
import type { InternalUrl } from "../../utils/parse-url"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds `signinUrl` and `callbackUrl` to each provider
|
* Adds `signinUrl` and `callbackUrl` to each provider
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import { createHash } from "crypto"
|
import { createHash } from "crypto"
|
||||||
import { NextAuthOptions } from "../.."
|
|
||||||
import { InternalOptions } from "../../lib/types"
|
import type { NextAuthOptions } from "../.."
|
||||||
import { InternalUrl } from "../../lib/parse-url"
|
import type { InternalOptions } from "../types"
|
||||||
|
import type { InternalUrl } from "../../utils/parse-url"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Takes a number in seconds and returns the date in the future.
|
* Takes a number in seconds and returns the date in the future.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Theme } from "../.."
|
import { Theme } from "../.."
|
||||||
import { InternalUrl } from "../../lib/parse-url"
|
import { InternalUrl } from "../../utils/parse-url"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The following errors are passed as error query parameters to the default or overridden error page.
|
* The following errors are passed as error query parameters to the default or overridden error page.
|
||||||
|
|||||||
@@ -5,13 +5,13 @@ import VerifyRequestPage from "./verify-request"
|
|||||||
import ErrorPage from "./error"
|
import ErrorPage from "./error"
|
||||||
import css from "../../css"
|
import css from "../../css"
|
||||||
|
|
||||||
import type { InternalOptions } from "../../lib/types"
|
import type { InternalOptions } from "../types"
|
||||||
import type { IncomingRequest, OutgoingResponse } from ".."
|
import type { RequestInternal, OutgoingResponse } from ".."
|
||||||
import type { Cookie } from "../lib/cookie"
|
import type { Cookie } from "../lib/cookie"
|
||||||
import type { ErrorType } from "./error"
|
import type { ErrorType } from "./error"
|
||||||
|
|
||||||
type RenderPageParams = {
|
type RenderPageParams = {
|
||||||
query?: IncomingRequest["query"]
|
query?: RequestInternal["query"]
|
||||||
cookies?: Cookie[]
|
cookies?: Cookie[]
|
||||||
} & Partial<
|
} & Partial<
|
||||||
Pick<
|
Pick<
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { Theme } from "../.."
|
import type { InternalProvider, Theme } from "../types"
|
||||||
import { InternalProvider } from "../../lib/types"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The following errors are passed as error query parameters to the default or overridden sign-in page.
|
* The following errors are passed as error query parameters to the default or overridden sign-in page.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Theme } from "../.."
|
import { Theme } from "../.."
|
||||||
import { InternalUrl } from "../../lib/parse-url"
|
import { InternalUrl } from "../../utils/parse-url"
|
||||||
|
|
||||||
export interface SignoutProps {
|
export interface SignoutProps {
|
||||||
url: InternalUrl
|
url: InternalUrl
|
||||||
@@ -12,15 +12,17 @@ export default function SignoutPage(props: SignoutProps) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="signout">
|
<div className="signout">
|
||||||
{ theme.brandColor && <style
|
{theme.brandColor && (
|
||||||
dangerouslySetInnerHTML={{
|
<style
|
||||||
__html: `
|
dangerouslySetInnerHTML={{
|
||||||
|
__html: `
|
||||||
:root {
|
:root {
|
||||||
--brand-color: ${theme.brandColor}
|
--brand-color: ${theme.brandColor}
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
}}
|
}}
|
||||||
/> }
|
/>
|
||||||
|
)}
|
||||||
{theme.logo && <img src={theme.logo} alt="Logo" className="logo" />}
|
{theme.logo && <img src={theme.logo} alt="Logo" className="logo" />}
|
||||||
<div className="card">
|
<div className="card">
|
||||||
<h1>Signout</h1>
|
<h1>Signout</h1>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Theme } from "../.."
|
import { Theme } from "../.."
|
||||||
import { InternalUrl } from "../../lib/parse-url"
|
import { InternalUrl } from "../../utils/parse-url"
|
||||||
|
|
||||||
interface VerifyRequestPageProps {
|
interface VerifyRequestPageProps {
|
||||||
url: InternalUrl
|
url: InternalUrl
|
||||||
@@ -11,15 +11,17 @@ export default function VerifyRequestPage(props: VerifyRequestPageProps) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="verify-request">
|
<div className="verify-request">
|
||||||
{ theme.brandColor && <style
|
{theme.brandColor && (
|
||||||
dangerouslySetInnerHTML={{
|
<style
|
||||||
__html: `
|
dangerouslySetInnerHTML={{
|
||||||
|
__html: `
|
||||||
:root {
|
:root {
|
||||||
--brand-color: ${theme.brandColor}
|
--brand-color: ${theme.brandColor}
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
}}
|
}}
|
||||||
/> }
|
/>
|
||||||
|
)}
|
||||||
{theme.logo && <img src={theme.logo} alt="Logo" className="logo" />}
|
{theme.logo && <img src={theme.logo} alt="Logo" className="logo" />}
|
||||||
<div className="card">
|
<div className="card">
|
||||||
<h1>Check your email</h1>
|
<h1>Check your email</h1>
|
||||||
|
|||||||
@@ -2,19 +2,19 @@ import oAuthCallback from "../lib/oauth/callback"
|
|||||||
import callbackHandler from "../lib/callback-handler"
|
import callbackHandler from "../lib/callback-handler"
|
||||||
import { hashToken } from "../lib/utils"
|
import { hashToken } from "../lib/utils"
|
||||||
|
|
||||||
import type { InternalOptions } from "../../lib/types"
|
import type { InternalOptions } from "../types"
|
||||||
import type { IncomingRequest, OutgoingResponse } from ".."
|
import type { RequestInternal, OutgoingResponse } from ".."
|
||||||
import type { Cookie, SessionStore } from "../lib/cookie"
|
import type { Cookie, SessionStore } from "../lib/cookie"
|
||||||
import type { User } from "../.."
|
import type { User } from "../.."
|
||||||
|
|
||||||
/** Handle callbacks from login services */
|
/** Handle callbacks from login services */
|
||||||
export default async function callback(params: {
|
export default async function callback(params: {
|
||||||
options: InternalOptions<"oauth" | "credentials" | "email">
|
options: InternalOptions<"oauth" | "credentials" | "email">
|
||||||
query: IncomingRequest["query"]
|
query: RequestInternal["query"]
|
||||||
method: Required<IncomingRequest>["method"]
|
method: Required<RequestInternal>["method"]
|
||||||
body: IncomingRequest["body"]
|
body: RequestInternal["body"]
|
||||||
headers: IncomingRequest["headers"]
|
headers: RequestInternal["headers"]
|
||||||
cookies: IncomingRequest["cookies"]
|
cookies: RequestInternal["cookies"]
|
||||||
sessionStore: SessionStore
|
sessionStore: SessionStore
|
||||||
}): Promise<OutgoingResponse> {
|
}): Promise<OutgoingResponse> {
|
||||||
const { options, query, body, method, headers, sessionStore } = params
|
const { options, query, body, method, headers, sessionStore } = params
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { OutgoingResponse } from ".."
|
import type { OutgoingResponse } from ".."
|
||||||
import { InternalProvider } from "../../lib/types"
|
import type { InternalProvider } from "../types"
|
||||||
|
|
||||||
export interface PublicProvider {
|
export interface PublicProvider {
|
||||||
id: string
|
id: string
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { fromDate } from "../lib/utils"
|
import { fromDate } from "../lib/utils"
|
||||||
|
|
||||||
import type { Adapter } from "../../adapters"
|
import type { Adapter } from "../../adapters"
|
||||||
import type { InternalOptions } from "../../lib/types"
|
import type { InternalOptions } from "../types"
|
||||||
import type { OutgoingResponse } from ".."
|
import type { OutgoingResponse } from ".."
|
||||||
import type { Session } from "../.."
|
import type { Session } from "../.."
|
||||||
import type { SessionStore } from "../lib/cookie"
|
import type { SessionStore } from "../lib/cookie"
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
import getAuthorizationUrl from "../lib/oauth/authorization-url"
|
import getAuthorizationUrl from "../lib/oauth/authorization-url"
|
||||||
import emailSignin from "../lib/email/signin"
|
import emailSignin from "../lib/email/signin"
|
||||||
import { IncomingRequest, OutgoingResponse } from ".."
|
import type { RequestInternal, OutgoingResponse } from ".."
|
||||||
import { InternalOptions } from "../../lib/types"
|
import type { InternalOptions } from "../types"
|
||||||
import { Account, User } from "../.."
|
import type { Account, User } from "../.."
|
||||||
|
|
||||||
/** Handle requests to /api/auth/signin */
|
/** Handle requests to /api/auth/signin */
|
||||||
export default async function signin(params: {
|
export default async function signin(params: {
|
||||||
options: InternalOptions<"oauth" | "email">
|
options: InternalOptions<"oauth" | "email">
|
||||||
query: IncomingRequest["query"]
|
query: RequestInternal["query"]
|
||||||
body: IncomingRequest["body"]
|
body: RequestInternal["body"]
|
||||||
}): Promise<OutgoingResponse> {
|
}): Promise<OutgoingResponse> {
|
||||||
const { options, query, body } = params
|
const { options, query, body } = params
|
||||||
const { url, adapter, callbacks, logger, provider } = options
|
const { url, adapter, callbacks, logger, provider } = options
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import type { Adapter } from "../../adapters"
|
import type { Adapter } from "../../adapters"
|
||||||
import type { InternalOptions } from "../../lib/types"
|
import type { InternalOptions } from "../types"
|
||||||
import type { OutgoingResponse } from ".."
|
import type { OutgoingResponse } from ".."
|
||||||
import type { SessionStore } from "../lib/cookie"
|
import type { SessionStore } from "../lib/cookie"
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,21 @@
|
|||||||
import type { Adapter } from "../adapters"
|
import type { Adapter } from "../adapters"
|
||||||
import type { Provider, CredentialInput, ProviderType } from "../providers"
|
import type {
|
||||||
|
Provider,
|
||||||
|
CredentialInput,
|
||||||
|
ProviderType,
|
||||||
|
OAuthConfig,
|
||||||
|
EmailConfig,
|
||||||
|
CredentialsConfig,
|
||||||
|
} from "../providers"
|
||||||
import type { TokenSetParameters } from "openid-client"
|
import type { TokenSetParameters } from "openid-client"
|
||||||
import type { JWT, JWTOptions } from "../jwt"
|
import type { JWT, JWTOptions } from "../jwt"
|
||||||
import type { LoggerInstance } from "../lib/logger"
|
import type { LoggerInstance } from "../utils/logger"
|
||||||
import type { CookieSerializeOptions } from "cookie"
|
import type { CookieSerializeOptions } from "cookie"
|
||||||
|
|
||||||
|
import type { NextApiRequest, NextApiResponse } from "next"
|
||||||
|
|
||||||
|
import type { InternalUrl } from "../utils/parse-url"
|
||||||
|
|
||||||
export type Awaitable<T> = T | PromiseLike<T>
|
export type Awaitable<T> = T | PromiseLike<T>
|
||||||
|
|
||||||
export type { LoggerInstance }
|
export type { LoggerInstance }
|
||||||
@@ -106,7 +117,7 @@ export interface NextAuthOptions {
|
|||||||
* * **Required**: *No*
|
* * **Required**: *No*
|
||||||
*
|
*
|
||||||
* [Documentation](https://next-auth.js.org/configuration/options#adapter) |
|
* [Documentation](https://next-auth.js.org/configuration/options#adapter) |
|
||||||
* [Community adapters](https://github.com/nextauthjs/adapters)
|
* [Adapters Overview](https://next-auth.js.org/adapters/overview)
|
||||||
*/
|
*/
|
||||||
adapter?: Adapter
|
adapter?: Adapter
|
||||||
/**
|
/**
|
||||||
@@ -471,3 +482,71 @@ export interface DefaultUser {
|
|||||||
* [`profile` OAuth provider callback](https://next-auth.js.org/configuration/providers#using-a-custom-provider)
|
* [`profile` OAuth provider callback](https://next-auth.js.org/configuration/providers#using-a-custom-provider)
|
||||||
*/
|
*/
|
||||||
export interface User extends Record<string, unknown>, DefaultUser {}
|
export interface User extends Record<string, unknown>, DefaultUser {}
|
||||||
|
|
||||||
|
// Below are types that are only supposed be used by next-auth internally
|
||||||
|
|
||||||
|
/** @internal */
|
||||||
|
export type InternalProvider<T extends ProviderType = any> = (T extends "oauth"
|
||||||
|
? OAuthConfig<any>
|
||||||
|
: T extends "email"
|
||||||
|
? EmailConfig
|
||||||
|
: T extends "credentials"
|
||||||
|
? CredentialsConfig
|
||||||
|
: never) & {
|
||||||
|
signinUrl: string
|
||||||
|
callbackUrl: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type NextAuthAction =
|
||||||
|
| "providers"
|
||||||
|
| "session"
|
||||||
|
| "csrf"
|
||||||
|
| "signin"
|
||||||
|
| "signout"
|
||||||
|
| "callback"
|
||||||
|
| "verify-request"
|
||||||
|
| "error"
|
||||||
|
| "_log"
|
||||||
|
|
||||||
|
/** @internal */
|
||||||
|
export interface InternalOptions<T extends ProviderType = any> {
|
||||||
|
providers: InternalProvider[]
|
||||||
|
/**
|
||||||
|
* Parsed from `NEXTAUTH_URL` or `x-forwarded-host` on Vercel.
|
||||||
|
* @default "http://localhost:3000/api/auth"
|
||||||
|
*/
|
||||||
|
url: InternalUrl
|
||||||
|
action: NextAuthAction
|
||||||
|
provider: T extends string
|
||||||
|
? InternalProvider<T>
|
||||||
|
: InternalProvider<T> | undefined
|
||||||
|
csrfToken?: string
|
||||||
|
csrfTokenVerified?: boolean
|
||||||
|
secret: string
|
||||||
|
theme: Theme
|
||||||
|
debug: boolean
|
||||||
|
logger: LoggerInstance
|
||||||
|
session: Required<SessionOptions>
|
||||||
|
pages: Partial<PagesOptions>
|
||||||
|
jwt: JWTOptions
|
||||||
|
events: Partial<EventCallbacks>
|
||||||
|
adapter?: Adapter
|
||||||
|
callbacks: CallbacksOptions
|
||||||
|
cookies: CookiesOptions
|
||||||
|
callbackUrl: string
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @internal */
|
||||||
|
export interface NextAuthRequest extends NextApiRequest {
|
||||||
|
options: InternalOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @internal */
|
||||||
|
export type NextAuthResponse<T = any> = NextApiResponse<T>
|
||||||
|
|
||||||
|
/** @internal */
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
||||||
|
export type NextAuthApiHandler<Result = void, Response = any> = (
|
||||||
|
req: NextAuthRequest,
|
||||||
|
res: NextAuthResponse<Response>
|
||||||
|
) => Awaitable<Result>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
export * from "./core/types"
|
export * from "./core/types"
|
||||||
|
|
||||||
export type { IncomingRequest, OutgoingResponse } from "./core"
|
export type { RequestInternal, OutgoingResponse } from "./core"
|
||||||
|
|
||||||
export * from "./next"
|
export * from "./next"
|
||||||
export { default } from "./next"
|
export { default } from "./next"
|
||||||
|
|||||||
@@ -1,90 +0,0 @@
|
|||||||
import type { NextApiRequest, NextApiResponse } from "next"
|
|
||||||
|
|
||||||
import type {
|
|
||||||
CallbacksOptions,
|
|
||||||
CookiesOptions,
|
|
||||||
EventCallbacks,
|
|
||||||
LoggerInstance,
|
|
||||||
PagesOptions,
|
|
||||||
SessionOptions,
|
|
||||||
Theme,
|
|
||||||
Awaitable,
|
|
||||||
} from ".."
|
|
||||||
|
|
||||||
import type {
|
|
||||||
OAuthConfig,
|
|
||||||
EmailConfig,
|
|
||||||
CredentialsConfig,
|
|
||||||
ProviderType,
|
|
||||||
} from "../providers"
|
|
||||||
import type { JWTOptions } from "../jwt"
|
|
||||||
import type { Adapter } from "../adapters"
|
|
||||||
import { InternalUrl } from "./parse-url"
|
|
||||||
|
|
||||||
// Below are types that are only supposed be used by next-auth internally
|
|
||||||
|
|
||||||
/** @internal */
|
|
||||||
export type InternalProvider<T extends ProviderType = any> = (T extends "oauth"
|
|
||||||
? OAuthConfig<any>
|
|
||||||
: T extends "email"
|
|
||||||
? EmailConfig
|
|
||||||
: T extends "credentials"
|
|
||||||
? CredentialsConfig
|
|
||||||
: never) & {
|
|
||||||
signinUrl: string
|
|
||||||
callbackUrl: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export type NextAuthAction =
|
|
||||||
| "providers"
|
|
||||||
| "session"
|
|
||||||
| "csrf"
|
|
||||||
| "signin"
|
|
||||||
| "signout"
|
|
||||||
| "callback"
|
|
||||||
| "verify-request"
|
|
||||||
| "error"
|
|
||||||
| "_log"
|
|
||||||
|
|
||||||
/** @internal */
|
|
||||||
export interface InternalOptions<T extends ProviderType = any> {
|
|
||||||
providers: InternalProvider[]
|
|
||||||
/**
|
|
||||||
* Parsed from `NEXTAUTH_URL` or `x-forwarded-host` on Vercel.
|
|
||||||
* @default "http://localhost:3000/api/auth"
|
|
||||||
*/
|
|
||||||
url: InternalUrl
|
|
||||||
action: NextAuthAction
|
|
||||||
provider: T extends string
|
|
||||||
? InternalProvider<T>
|
|
||||||
: InternalProvider<T> | undefined
|
|
||||||
csrfToken?: string
|
|
||||||
csrfTokenVerified?: boolean
|
|
||||||
secret: string
|
|
||||||
theme: Theme
|
|
||||||
debug: boolean
|
|
||||||
logger: LoggerInstance
|
|
||||||
session: Required<SessionOptions>
|
|
||||||
pages: Partial<PagesOptions>
|
|
||||||
jwt: JWTOptions
|
|
||||||
events: Partial<EventCallbacks>
|
|
||||||
adapter?: Adapter
|
|
||||||
callbacks: CallbacksOptions
|
|
||||||
cookies: CookiesOptions
|
|
||||||
callbackUrl: string
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @internal */
|
|
||||||
export interface NextAuthRequest extends NextApiRequest {
|
|
||||||
options: InternalOptions
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @internal */
|
|
||||||
export type NextAuthResponse<T = any> = NextApiResponse<T>
|
|
||||||
|
|
||||||
/** @internal */
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
|
||||||
export type NextAuthApiHandler<Result = void, Response = any> = (
|
|
||||||
req: NextAuthRequest,
|
|
||||||
res: NextAuthResponse<Response>
|
|
||||||
) => Awaitable<Result>
|
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
import { NextAuthHandler } from "../core"
|
import { NextAuthHandler } from "../core"
|
||||||
import { setCookie, detectHost } from "./utils"
|
import { detectHost } from "../utils/detect-host"
|
||||||
|
import { setCookie } from "./utils"
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
GetServerSidePropsContext,
|
GetServerSidePropsContext,
|
||||||
@@ -11,7 +12,7 @@ import type {
|
|||||||
NextAuthAction,
|
NextAuthAction,
|
||||||
NextAuthRequest,
|
NextAuthRequest,
|
||||||
NextAuthResponse,
|
NextAuthResponse,
|
||||||
} from "../lib/types"
|
} from "../core/types"
|
||||||
|
|
||||||
async function NextAuthNextHandler(
|
async function NextAuthNextHandler(
|
||||||
req: NextApiRequest,
|
req: NextApiRequest,
|
||||||
@@ -66,7 +67,7 @@ function NextAuth(
|
|||||||
options: NextAuthOptions
|
options: NextAuthOptions
|
||||||
): any
|
): any
|
||||||
|
|
||||||
/** Tha main entry point to next-auth */
|
/** The main entry point to next-auth */
|
||||||
function NextAuth(
|
function NextAuth(
|
||||||
...args:
|
...args:
|
||||||
| [NextAuthOptions]
|
| [NextAuthOptions]
|
||||||
@@ -82,26 +83,33 @@ function NextAuth(
|
|||||||
|
|
||||||
export default NextAuth
|
export default NextAuth
|
||||||
|
|
||||||
export async function getServerSession(
|
export async function unstable_getServerSession(
|
||||||
context:
|
...args:
|
||||||
| GetServerSidePropsContext
|
| [GetServerSidePropsContext['req'], GetServerSidePropsContext['res'], NextAuthOptions]
|
||||||
| { req: NextApiRequest; res: NextApiResponse },
|
| [NextApiRequest, NextApiResponse, NextAuthOptions]
|
||||||
options: NextAuthOptions
|
|
||||||
): Promise<Session | null> {
|
): Promise<Session | null> {
|
||||||
|
console.warn(
|
||||||
|
"[next-auth][warn][EXPERIMENTAL_API]",
|
||||||
|
"\n`unstable_getServerSession` is experimental and may be removed or changed in the future, as the name suggested.",
|
||||||
|
`\nhttps://next-auth.js.org/configuration/nextjs#unstable_getServerSession}`,
|
||||||
|
`\nhttps://next-auth.js.org/warnings#EXPERIMENTAL_API`
|
||||||
|
)
|
||||||
|
|
||||||
|
const [req, res, options] = args;
|
||||||
const session = await NextAuthHandler<Session | {}>({
|
const session = await NextAuthHandler<Session | {}>({
|
||||||
options,
|
options,
|
||||||
req: {
|
req: {
|
||||||
host: detectHost(context.req.headers["x-forwarded-host"]),
|
host: detectHost(req.headers["x-forwarded-host"]),
|
||||||
action: "session",
|
action: "session",
|
||||||
method: "GET",
|
method: "GET",
|
||||||
cookies: context.req.cookies,
|
cookies: req.cookies,
|
||||||
headers: context.req.headers,
|
headers: req.headers,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const { body, cookies } = session
|
const { body, cookies } = session
|
||||||
|
|
||||||
cookies?.forEach((cookie) => setCookie(context.res, cookie))
|
cookies?.forEach((cookie) => setCookie(res, cookie))
|
||||||
|
|
||||||
if (body && Object.keys(body).length) return body as Session
|
if (body && Object.keys(body).length) return body as Session
|
||||||
return null
|
return null
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import type { JWT, JWTOptions } from "../jwt"
|
|||||||
import { NextResponse, NextRequest } from "next/server"
|
import { NextResponse, NextRequest } from "next/server"
|
||||||
|
|
||||||
import { getToken } from "../jwt"
|
import { getToken } from "../jwt"
|
||||||
import parseUrl from "../lib/parse-url"
|
import parseUrl from "../utils/parse-url"
|
||||||
|
|
||||||
type AuthorizedCallback = (params: {
|
type AuthorizedCallback = (params: {
|
||||||
token: JWT | null
|
token: JWT | null
|
||||||
@@ -25,9 +25,9 @@ export interface NextAuthMiddlewareOptions {
|
|||||||
/**
|
/**
|
||||||
* You can override the default cookie names and options for any of the cookies
|
* You can override the default cookie names and options for any of the cookies
|
||||||
* by this middleware. Similar to `cookies` in `NextAuth`.
|
* by this middleware. Similar to `cookies` in `NextAuth`.
|
||||||
*
|
*
|
||||||
* Useful if the token is stored in not a default cookie.
|
* Useful if the token is stored in not a default cookie.
|
||||||
*
|
*
|
||||||
* ---
|
* ---
|
||||||
* [Documentation](https://next-auth.js.org/configuration/options#cookies)
|
* [Documentation](https://next-auth.js.org/configuration/options#cookies)
|
||||||
*
|
*
|
||||||
@@ -36,11 +36,16 @@ export interface NextAuthMiddlewareOptions {
|
|||||||
* You should **try to avoid using advanced options** unless you are very comfortable using them.
|
* You should **try to avoid using advanced options** unless you are very comfortable using them.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
cookies?: Partial<Record<keyof Pick<keyof NextAuthOptions["cookies"], "sessionToken">, Omit<CookieOption, "options">>>
|
cookies?: Partial<
|
||||||
|
Record<
|
||||||
|
keyof Pick<keyof NextAuthOptions["cookies"], "sessionToken">,
|
||||||
|
Omit<CookieOption, "options">
|
||||||
|
>
|
||||||
|
>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If a custom jwt `decode` method is set in `[...nextauth].ts`, the same method should be set here also.
|
* If a custom jwt `decode` method is set in `[...nextauth].ts`, the same method should be set here also.
|
||||||
*
|
*
|
||||||
* ---
|
* ---
|
||||||
* [Documentation](https://next-auth.js.org/configuration/nextjs#custom-jwt-decode-method)
|
* [Documentation](https://next-auth.js.org/configuration/nextjs#custom-jwt-decode-method)
|
||||||
*/
|
*/
|
||||||
@@ -109,7 +114,7 @@ async function handleMiddleware(
|
|||||||
const token = await getToken({
|
const token = await getToken({
|
||||||
req,
|
req,
|
||||||
decode: options?.jwt?.decode,
|
decode: options?.jwt?.decode,
|
||||||
cookieName: options?.cookies?.sessionToken?.name
|
cookieName: options?.cookies?.sessionToken?.name,
|
||||||
})
|
})
|
||||||
|
|
||||||
const isAuthorized =
|
const isAuthorized =
|
||||||
@@ -120,7 +125,10 @@ async function handleMiddleware(
|
|||||||
|
|
||||||
// the user is not logged in, redirect to the sign-in page
|
// the user is not logged in, redirect to the sign-in page
|
||||||
const signInUrl = new URL(signInPage, req.nextUrl.origin)
|
const signInUrl = new URL(signInPage, req.nextUrl.origin)
|
||||||
signInUrl.searchParams.append("callbackUrl", `${req.nextUrl.pathname}${req.nextUrl.search}`)
|
signInUrl.searchParams.append(
|
||||||
|
"callbackUrl",
|
||||||
|
`${req.nextUrl.pathname}${req.nextUrl.search}`
|
||||||
|
)
|
||||||
return NextResponse.redirect(signInUrl)
|
return NextResponse.redirect(signInUrl)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,11 +13,3 @@ export function setCookie(res, cookie: Cookie) {
|
|||||||
setCookieHeader.push(cookieHeader)
|
setCookieHeader.push(cookieHeader)
|
||||||
res.setHeader("Set-Cookie", setCookieHeader)
|
res.setHeader("Set-Cookie", setCookieHeader)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Extract the host from the environment */
|
|
||||||
export function detectHost(forwardedHost: any) {
|
|
||||||
// If we detect a Vercel environment, we can trust the host
|
|
||||||
if (process.env.VERCEL) return forwardedHost
|
|
||||||
// If `NEXTAUTH_URL` is `undefined` we fall back to "http://localhost:3000"
|
|
||||||
return process.env.NEXTAUTH_URL
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { IncomingRequest } from "../core"
|
import type { RequestInternal } from "../core"
|
||||||
import type { CommonProviderOptions } from "."
|
import type { CommonProviderOptions } from "."
|
||||||
import type { User, Awaitable } from ".."
|
import type { User, Awaitable } from ".."
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@ export interface CredentialsConfig<
|
|||||||
credentials: C
|
credentials: C
|
||||||
authorize: (
|
authorize: (
|
||||||
credentials: Record<keyof C, string> | undefined,
|
credentials: Record<keyof C, string> | undefined,
|
||||||
req: Pick<IncomingRequest, "body" | "query" | "headers" | "method">
|
req: Pick<RequestInternal, "body" | "query" | "headers" | "method">
|
||||||
) => Awaitable<(Omit<User, "id"> | { id?: string }) | null>
|
) => Awaitable<(Omit<User, "id"> | { id?: string }) | null>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,6 +35,9 @@ export default function Instagram(options) {
|
|||||||
token: "https://api.instagram.com/oauth/access_token",
|
token: "https://api.instagram.com/oauth/access_token",
|
||||||
userinfo:
|
userinfo:
|
||||||
"https://graph.instagram.com/me?fields=id,username,account_type,name",
|
"https://graph.instagram.com/me?fields=id,username,account_type,name",
|
||||||
|
client: {
|
||||||
|
token_endpoint_auth_method: 'client_secret_post',
|
||||||
|
},
|
||||||
async profile(profile) {
|
async profile(profile) {
|
||||||
return {
|
return {
|
||||||
id: profile.id,
|
id: profile.id,
|
||||||
|
|||||||
@@ -9,8 +9,8 @@
|
|||||||
// We use HTTP POST requests with CSRF Tokens to protect against CSRF attacks.
|
// We use HTTP POST requests with CSRF Tokens to protect against CSRF attacks.
|
||||||
|
|
||||||
import * as React from "react"
|
import * as React from "react"
|
||||||
import _logger, { proxyLogger } from "../lib/logger"
|
import _logger, { proxyLogger } from "../utils/logger"
|
||||||
import parseUrl from "../lib/parse-url"
|
import parseUrl from "../utils/parse-url"
|
||||||
import { Session } from ".."
|
import { Session } from ".."
|
||||||
import {
|
import {
|
||||||
BroadcastChannel,
|
BroadcastChannel,
|
||||||
@@ -175,7 +175,7 @@ export async function getProviders() {
|
|||||||
export async function signIn<
|
export async function signIn<
|
||||||
P extends RedirectableProviderType | undefined = undefined
|
P extends RedirectableProviderType | undefined = undefined
|
||||||
>(
|
>(
|
||||||
provider?: LiteralUnion<BuiltInProviderType>,
|
provider?: LiteralUnion<P extends RedirectableProviderType ? P | BuiltInProviderType : BuiltInProviderType>,
|
||||||
options?: SignInOptions,
|
options?: SignInOptions,
|
||||||
authorizationParams?: SignInAuthorizationParams
|
authorizationParams?: SignInAuthorizationParams
|
||||||
): Promise<
|
): Promise<
|
||||||
|
|||||||
7
packages/next-auth/src/utils/detect-host.ts
Normal file
7
packages/next-auth/src/utils/detect-host.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
/** Extract the host from the environment */
|
||||||
|
export function detectHost(forwardedHost: any) {
|
||||||
|
// If we detect a Vercel environment, we can trust the host
|
||||||
|
if (process.env.VERCEL) return forwardedHost
|
||||||
|
// If `NEXTAUTH_URL` is `undefined` we fall back to "http://localhost:3000"
|
||||||
|
return process.env.NEXTAUTH_URL
|
||||||
|
}
|
||||||
43
packages/next-auth/tests/assert.test.ts
Normal file
43
packages/next-auth/tests/assert.test.ts
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
import { handler } from "./lib"
|
||||||
|
|
||||||
|
it("Show error page if secret is not defined", async () => {
|
||||||
|
const { res, log } = await handler(
|
||||||
|
{ providers: [], secret: undefined },
|
||||||
|
{ prod: true }
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(res.status).toBe(500)
|
||||||
|
expect(res.html).toMatch(/there is a problem with the server configuration./i)
|
||||||
|
expect(res.html).toMatch(/check the server logs for more information./i)
|
||||||
|
|
||||||
|
expect(log.error).toBeCalledWith("NO_SECRET", expect.anything())
|
||||||
|
})
|
||||||
|
|
||||||
|
it("Should show configuration error page on invalid `callbackUrl`", async () => {
|
||||||
|
const { res, log } = await handler(
|
||||||
|
{ providers: [] },
|
||||||
|
{ prod: true, params: { callbackUrl: "invalid-callback" } }
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(res.status).toBe(500)
|
||||||
|
expect(res.html).toMatch(/there is a problem with the server configuration./i)
|
||||||
|
expect(res.html).toMatch(/check the server logs for more information./i)
|
||||||
|
|
||||||
|
expect(log.error).toBeCalledWith(
|
||||||
|
"INVALID_CALLBACK_URL_ERROR",
|
||||||
|
expect.anything()
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("Allow relative `callbackUrl`", async () => {
|
||||||
|
const { res, log } = await handler(
|
||||||
|
{ providers: [] },
|
||||||
|
{ prod: true, params: { callbackUrl: "/callback" } }
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(res.status).not.toBe(500)
|
||||||
|
expect(log.error).not.toBeCalledWith(
|
||||||
|
"INVALID_CALLBACK_URL_ERROR",
|
||||||
|
expect.anything()
|
||||||
|
)
|
||||||
|
})
|
||||||
49
packages/next-auth/tests/lib.ts
Normal file
49
packages/next-auth/tests/lib.ts
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
import type { LoggerInstance, NextAuthOptions } from "../src"
|
||||||
|
import { NextAuthHandler } from "../src/core"
|
||||||
|
|
||||||
|
export async function handler(
|
||||||
|
options: NextAuthOptions,
|
||||||
|
{
|
||||||
|
prod,
|
||||||
|
path,
|
||||||
|
params,
|
||||||
|
}: {
|
||||||
|
prod?: boolean
|
||||||
|
path?: string
|
||||||
|
params?: URLSearchParams | Record<string, string>
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
// @ts-ignore
|
||||||
|
if (prod) process.env.NODE_ENV = "production"
|
||||||
|
|
||||||
|
const mockLogger: LoggerInstance = {
|
||||||
|
error: jest.fn(),
|
||||||
|
warn: jest.fn(),
|
||||||
|
debug: jest.fn(),
|
||||||
|
}
|
||||||
|
const url = new URL(
|
||||||
|
`http://localhost/api/auth/${path ?? "signin"}?${new URLSearchParams(
|
||||||
|
params ?? {}
|
||||||
|
)}`
|
||||||
|
)
|
||||||
|
const req = new Request(url, {
|
||||||
|
headers: {
|
||||||
|
host: "",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
const response = await NextAuthHandler({
|
||||||
|
req,
|
||||||
|
options: { secret: "secret", ...options, logger: mockLogger },
|
||||||
|
})
|
||||||
|
// @ts-ignore
|
||||||
|
if (prod) process.env.NODE_ENV = "test"
|
||||||
|
|
||||||
|
return {
|
||||||
|
res: {
|
||||||
|
...response,
|
||||||
|
html:
|
||||||
|
response.headers?.[0].value === "text/html" ? response.body : undefined,
|
||||||
|
},
|
||||||
|
log: mockLogger,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,7 +14,8 @@
|
|||||||
"stripInternal": true,
|
"stripInternal": true,
|
||||||
"skipDefaultLibCheck": true,
|
"skipDefaultLibCheck": true,
|
||||||
"baseUrl": ".",
|
"baseUrl": ".",
|
||||||
"outDir": "."
|
"outDir": ".",
|
||||||
|
|
||||||
},
|
},
|
||||||
"exclude": ["./*.js", "./*.d.ts", "config", "**/__tests__"]
|
"exclude": ["./*.js", "./*.d.ts", "config", "**/__tests__", "tests"]
|
||||||
}
|
}
|
||||||
|
|||||||
33241
pnpm-lock.yaml
generated
33241
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user