Compare commits

...

21 Commits

Author SHA1 Message Date
Lluis Agusti
5d815ce593 chore: wip 2023-04-16 23:28:54 +09:00
Lluis Agusti
25be00b749 Merge 'main' into 'docs/providers-to-source-code' 2023-04-14 13:46:47 +09:00
Balázs Orbán
b31f2af66c feat: misc improvements (#7228)
* tweak types, fix typos

* filter non-oauth files when generating provider types

* allow implicit config invoke

* remove workaround for multiple cookie settings in Next.js

* feat: return `null` when session does not exist

* error on missing checks when configured
2023-04-12 11:40:55 +01:00
Prana Adiwira
71bb6f2590 fix(providers): Use the proper check for Reddit (#7224)
Reddit expects the `state` parameter

https://github.com/reddit-archive/reddit/wiki/OAuth2#authorization
2023-04-12 11:37:31 +01:00
Lluis Agusti
f28b58d49d chore: wip 2023-04-10 21:23:27 +09:00
Balázs Orbán
6c07331cc5 chore: upgrade turbo 2023-04-06 12:58:10 +02:00
Saurav Maheshkar
c8ef94b2be chore: move prettier and eslint configs under package.json (#7145) 2023-04-06 12:57:16 +02:00
jakzo
75a59fbd92 chore(docs): fix dynamodb typo (#7130)
fix: typo
2023-04-06 12:57:09 +02:00
Balázs Orbán
3dd47b0735 docs(example): remove unstable_ prefix 2023-03-31 05:01:58 +02:00
Balázs Orbán
4dc1d421f8 docs: mention client in OAuth config options
Related issue #7114
2023-03-30 18:34:30 +02:00
Balázs Orbán
99ca67f1cf docs: fix typo 2023-03-28 13:59:08 +02:00
Balázs Orbán
a087df8494 docs: fix some links 2023-03-28 13:47:53 +02:00
Sai Srikar Dumpeti
1aa4994de6 docs: respect color scheme (#7076) 2023-03-28 04:06:21 +02:00
Alan Hoskins
88023f69b9 fix(docs): remove extra install (#7081) 2023-03-27 15:47:32 +02:00
Alan Hoskins
b02057a72d fix(docs): fix broken links links (#7083)
Co-authored-by: Alan Hoskins <ahoskins@knowland.com>
2023-03-27 15:46:43 +02:00
Balázs Orbán
400da8c766 fix(providers): mention Email Address as required for Azure B2C
closes #7071
2023-03-27 15:44:23 +02:00
Andres Rodriguez
b48104801b chore(provider): added svg for Reddit (#7050)
Added svg for Reddit

Co-authored-by: Nico Domino <yo@ndo.dev>
2023-03-27 09:36:47 +02:00
Balázs Orbán
ccbbc800d2 docs: rephrase buttons on landing page 2023-03-27 02:06:33 +02:00
Abdulaziz Askaraliev
d7888263ca fix(providers): update Yandex to TypeScript (#7054)
* fix(providers): yandex add typescript.

* fix(providers): yandex add avatar to scope

* fix(providers): Yandex - add types & avatar scope

* fix(providers): Yandex - permissions list

* Apply suggestions from code review

* Apply suggestions from code review

* docs(provider): added comments for

* revert yandex.ts from next-auth/providers/

* fix(providers): yandex fix typo

* revert

* Update [...nextauth].ts

* Update yandex.ts

* Update yandex.ts

* Update [...nextauth].ts

---------

Co-authored-by: Balázs Orbán <info@balazsorban.com>
2023-03-27 00:38:06 +01:00
Balázs Orbán
47d3151410 Merge branch 'main' of github.com:nextauthjs/next-auth 2023-03-27 01:32:54 +02:00
Balázs Orbán
7d264860ab chore: package builds as docs#dev task dependencies 2023-03-27 01:32:50 +02:00
46 changed files with 809 additions and 436 deletions

View File

@@ -1,70 +0,0 @@
.eslintrc.js
.cache-loader
.DS_Store
.pnpm-debug.log
.turbo
.vscode/generated*
/_work
/actions-runner
node_modules
patches
pnpm-lock.yaml
.github/actions/issue-validator/index.mjs
*.cjs
*.js
*.d.ts
*.d.ts.map
.svelte-kit
.next
.nuxt
# --------------- Docs ---------------
.docusaurus
build
docs/docs/reference/core
docs/docs/reference/sveltekit
static
# --------------- Packages ---------------
coverage
dist
# @auth/core
packages/core/src/providers/oauth-types.ts
packages/core/src/lib/pages/styles.ts
# @auth/sveltekit
packages/frameworks-sveltekit/package
packages/frameworks-sveltekit/vite.config.{js,ts}.timestamp-*
# next-auth
packages/next-auth/src/providers/oauth-types.ts
packages/next-auth/css/index.css
# Adapters
.branches
db.sqlite
dev.db
dynamodblocal-bin
firebase-debug.log
firestore-debug.log
migrations
test.schema.gql
# --------------- Apps ---------------
# Examples should have their own Prettier config since they are templates too
apps/example-sveltekit
# Development app
apps
# --------------- Tests ---------------
# TODO: these should be linted
packages/**/*test*

View File

@@ -1,75 +0,0 @@
// @ts-check
/** @type {import("eslint").ESLint.ConfigData} */
module.exports = {
env: { browser: true, es2022: true, node: true },
extends: ["eslint:recommended", "prettier"],
overrides: [
{
files: ["*.ts", "*.tsx"],
parser: "@typescript-eslint/parser",
parserOptions: {
project: ["./packages/**/tsconfig.json", "./apps/**/tsconfig.json"],
},
settings: { react: { version: "18" } },
extends: [
"plugin:react/recommended",
"plugin:react/jsx-runtime",
"standard-with-typescript",
"prettier",
],
rules: {
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/method-signature-style": "off",
"@typescript-eslint/naming-convention": "off",
"@typescript-eslint/no-non-null-assertion": "off",
"@typescript-eslint/restrict-template-expressions": "off",
"@typescript-eslint/strict-boolean-expressions": "off",
"react/prop-types": "off",
"react/no-unescaped-entities": "off",
},
},
{
files: ["*.test.ts", "*.test.js"],
extends: ["plugin:jest/recommended"],
env: { jest: true },
},
{
files: ["docs/**"],
plugins: ["@docusaurus"],
extends: ["plugin:@docusaurus/recommended"],
},
{
// TODO: Expand to all packages
files: ["packages/{core,sveltekit}/*.ts"],
plugins: ["jsdoc"],
extends: ["plugin:jsdoc/recommended"],
rules: {
"jsdoc/require-param": "off",
"jsdoc/require-returns": "off",
"jsdoc/require-jsdoc": [
"warn",
{ publicOnly: true, enableFixer: false },
],
"jsdoc/no-multi-asterisks": ["warn", { allowWhitespace: true }],
"jsdoc/tag-lines": "off",
},
},
{
files: ["packages/frameworks-sveltekit"],
plugins: ["svelte3"],
overrides: [{ files: ["*.svelte"], processor: "svelte3/svelte3" }],
settings: {
"svelte3/typescript": () => require("typescript"),
},
parserOptions: { sourceType: "module", ecmaVersion: 2020 },
env: { browser: true, es2017: true, node: true },
},
],
parserOptions: {
sourceType: "module",
ecmaVersion: "latest",
ecmaFeatures: { jsx: true },
},
root: true,
}

View File

@@ -1,22 +0,0 @@
// @ts-check
/** @type {import("prettier").Config} */
module.exports = {
semi: false,
singleQuote: false,
overrides: [
{
files: [
"apps/dev/nextjs/pages/api/auth/[...nextauth].ts",
"docs/{sidebars,docusaurus.config}.js",
],
options: { printWidth: 150 },
},
{
files: ["**/*package.json"],
options: {
trailingComma: "none",
},
},
],
}

View File

@@ -52,6 +52,10 @@ TWITTER_SECRET=
WIKIMEDIA_ID=
WIKIMEDIA_SECRET=
# Yandex OAuth. new app -> https://oauth.yandex.com/client/new/id
YANDEX_ID=
YANDEX_SECRET=
# Example configuration for a Gmail account (will need SMTP enabled)
EMAIL_SERVER=smtps://user@gmail.com:password@smtp.gmail.com:465
EMAIL_FROM=user@gmail.com

View File

@@ -34,6 +34,7 @@ import Spotify from "@auth/core/providers/spotify"
import Trakt from "@auth/core/providers/trakt"
import Twitch from "@auth/core/providers/twitch"
import Twitter from "@auth/core/providers/twitter"
import Yandex from "@auth/core/providers/yandex"
import Vk from "@auth/core/providers/vk"
import Wikimedia from "@auth/core/providers/wikimedia"
import WorkOS from "@auth/core/providers/workos"
@@ -120,6 +121,7 @@ export const authConfig: AuthConfig = {
Twitch({ clientId: process.env.TWITCH_ID, clientSecret: process.env.TWITCH_SECRET }),
Twitter({ clientId: process.env.TWITTER_ID, clientSecret: process.env.TWITTER_SECRET }),
// TwitterLegacy({ clientId: process.env.TWITTER_LEGACY_ID, clientSecret: process.env.TWITTER_LEGACY_SECRET }),
Yandex({ clientId: process.env.YANDEX_ID, clientSecret: process.env.YANDEX_SECRET }),
Vk({ clientId: process.env.VK_ID, clientSecret: process.env.VK_SECRET }),
Wikimedia({ clientId: process.env.WIKIMEDIA_ID, clientSecret: process.env.WIKIMEDIA_SECRET }),
WorkOS({ clientId: process.env.WORKOS_ID, clientSecret: process.env.WORKOS_SECRET }),

View File

@@ -1,4 +1,4 @@
import { unstable_getServerSession } from "next-auth/next"
import { getServerSession } from "next-auth/next"
import { authOptions } from "./api/auth/[...nextauth]"
import Layout from "../components/layout"
@@ -38,7 +38,7 @@ export default function ServerSidePage() {
export async function getServerSideProps(context: GetServerSidePropsContext) {
return {
props: {
session: await unstable_getServerSession(
session: await getServerSession(
context.req,
context.res,
authOptions

View File

@@ -46,7 +46,7 @@ export default NextAuth({
```
:::note
Check the [Credentials Provider options](/reference/providers/credentials) for further customization
Check the [Credentials Provider options](/reference/core/providers_credentials) for further customization
:::
Note that we only need to define an `authorize` method that is in charge of receiving the credentials inserted by the user and call the authorization service.

View File

@@ -66,7 +66,7 @@ Nice! We're getting there. Now we need to read supply this values as the configu
```ts title="pages/api/auth/[...nextauth].ts"
import NextAuth from "next-auth"
import EmailProvider from "next-auth/providers/email"
import Email from "next-auth/providers/email"
export default NextAuth({
providers: [

View File

@@ -239,7 +239,7 @@ Introduced in https://github.com/nextauthjs/next-auth/releases/tag/v4.0.0-next.1
## `nodemailer`
Like `typeorm` and `prisma`, [`nodemailer`](https://npmjs.com/package/nodemailer) is no longer included as a dependency by default. If you are using the Email provider you must install it in your project manually, or use any other Email library in the [`sendVerificationRequest`](/reference/providers/email) callback. This reduces bundle size for those not actually using the Email provider. Remember, when using the Email provider, it is mandatory to also use a database adapter due to the fact that verification tokens need to be persisted longer term for the magic link functionality to work.
Like `typeorm` and `prisma`, [`nodemailer`](https://npmjs.com/package/nodemailer) is no longer included as a dependency by default. If you are using the Email provider you must install it in your project manually, or use any other Email library in the [`sendVerificationRequest`](/guides/providers/email) callback. This reduces bundle size for those not actually using the Email provider. Remember, when using the Email provider, it is mandatory to also use a database adapter due to the fact that verification tokens need to be persisted longer term for the magic link functionality to work.
Introduced in https://github.com/nextauthjs/next-auth/releases/tag/v4.0.0-next.2

View File

@@ -17,7 +17,7 @@ The functionality provided for credentials-based authentication is intentionally
The **Credentials Provider** comes with a set of default options:
- [Credentials Provider options](/reference/providers/credentials)
- [Credentials Provider options](/reference/core/providers_credentials)
You can override any of the options to suit your own use case.

View File

@@ -23,7 +23,7 @@ The Email Provider can be used with both JSON Web Tokens and database sessions,
The **Email Provider** comes with a set of default options:
- [Email Provider options](/reference/providers/email)
- [Email Provider options](/guides/providers/email)
You can override any of the options to suit your own use case.

View File

@@ -52,7 +52,7 @@ Using a Auth.js / NextAuth.js adapter you can connect to any database service or
<a href="/reference/adapter/typeorm" class="adapter-card">
<img src="/img/adapters/typeorm.png" width="30" />
<h4 class="adapter-card__title">TypeORM Adapter</h4>
</a>
</a>
<a href="/reference/adapter/upstash-redis" class="adapter-card">
<img src="/img/adapters/upstash-redis.svg" width="30" />
<h4 class="adapter-card__title">Upstash Adapter</h4>
@@ -133,7 +133,7 @@ If a user first signs in with OAuth then their email address is automatically po
This provides a way to contact users and for users to maintain access to their account and sign in using email in the event they are unable to sign in with the OAuth provider in future (if the [Email Provider](/getting-started/email-tutorial) is configured).
:::
User creation in the database is automatic, and happens when the user is logging in for the first time with a provider. The default data saved is `id`, `name`, `email` and `image`. You can add more profile data by returning extra fields in your [OAuth provider's `profile()`](/reference/providers/oauth) callback.
User creation in the database is automatic, and happens when the user is logging in for the first time with a provider. The default data saved is `id`, `name`, `email` and `image`. You can add more profile data by returning extra fields in your [OAuth provider](/guides/providers/custom-provider)'s [`profile()`](/reference/core/providers#profile) callback.
### Account
@@ -174,7 +174,7 @@ A single User can have multiple open Verification Tokens (e.g. to sign in to dif
It has been designed to be extendable for other verification purposes in the future (e.g. 2FA / short codes).
:::note
Auth.js makes sure that every token is usable only once, and by default has a short (1 day, can be configured by [`maxAge`](/reference/providers/email)) lifetime. If your user did not manage to finish the sign-in flow in time, they will have to start the sign-in process again.
Auth.js makes sure that every token is usable only once, and by default has a short (1 day, can be configured by [`maxAge`](/guides/providers/email)) lifetime. If your user did not manage to finish the sign-in flow in time, they will have to start the sign-in process again.
:::
:::tip
@@ -188,4 +188,4 @@ Auth.js / NextAuth.js uses `camelCase` for its own database rows, while respecti
## TypeScript
Check out the [`@auth/core/adapters` API Reference](/reference/core/adapters) documentation.
Check out the [`@auth/core/adapters` API Reference](/reference/core/adapters) documentation.

View File

@@ -25,6 +25,10 @@
transition: 0.2s background-color ease-in-out;
}
html[data-theme="dark"] .adapter-card {
color: #f5f5f5;
}
.adapter-card:hover {
text-decoration: none;
color: black;

View File

@@ -135,7 +135,7 @@ export default function Home() {
)}
href="https://next-auth-example.vercel.app"
>
Live Demo (Next.js)
Next.js Demo
</a>
<a
className={classnames(
@@ -144,7 +144,7 @@ export default function Home() {
)}
href="https://sveltekit-auth-example.vercel.app"
>
Live Demo (SvelteKit)
SvelteKit Demo
</a>
<a
className={classnames(
@@ -153,7 +153,7 @@ export default function Home() {
)}
href="https://auth-solid.vercel.app"
>
Live Demo (SolidStart)
SolidStart Demo
</a>
<Link
className={classnames(

6
docs/static/img/providers/reddit.svg vendored Normal file
View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" height="32" width="32">
<g>
<circle fill="#FF4500" cx="10" cy="10" r="10"/>
<path fill="#FFF" d="M16.67,10A1.46,1.46,0,0,0,14.2,9a7.12,7.12,0,0,0-3.85-1.23L11,4.65,13.14,5.1a1,1,0,1,0,.13-0.61L10.82,4a0.31,0.31,0,0,0-.37.24L9.71,7.71a7.14,7.14,0,0,0-3.9,1.23A1.46,1.46,0,1,0,4.2,11.33a2.87,2.87,0,0,0,0,.44c0,2.24,2.61,4.06,5.83,4.06s5.83-1.82,5.83-4.06a2.87,2.87,0,0,0,0-.44A1.46,1.46,0,0,0,16.67,10Zm-10,1a1,1,0,1,1,1,1A1,1,0,0,1,6.67,11Zm5.81,2.75a3.84,3.84,0,0,1-2.47.77,3.84,3.84,0,0,1-2.47-.77,0.27,0.27,0,0,1,.38-0.38A3.27,3.27,0,0,0,10,14a3.28,3.28,0,0,0,2.09-.61A0.27,0.27,0,1,1,12.48,13.79Zm-0.18-1.71a1,1,0,1,1,1-1A1,1,0,0,1,12.29,12.08Z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 736 B

1
docs/static/img/providers/yandex.svg vendored Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0,0,256,256" width="480px" height="480px" fill-rule="nonzero"><g transform="translate(32,32) scale(0.75,0.75)"><g fill-opacity="0" fill="#ff0000" fill-rule="nonzero" stroke="none" stroke-width="1" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="10" stroke-dasharray="" stroke-dashoffset="0" font-family="none" font-weight="none" font-size="none" text-anchor="none" style="mix-blend-mode: normal"><path d="M-42.66667,298.66667v-341.33333h341.33333v341.33333z" id="bgRectangle"></path></g><g fill="#ff0000" fill-rule="nonzero" stroke="none" stroke-width="1" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="10" stroke-dasharray="" stroke-dashoffset="0" font-family="none" font-weight="none" font-size="none" text-anchor="none" style="mix-blend-mode: normal"><path d="M128,292.57143c-90.89029,0 -164.57143,-73.68114 -164.57143,-164.57143v0c0,-90.89029 73.68114,-164.57143 164.57143,-164.57143v0c90.89029,0 164.57143,73.68114 164.57143,164.57143v0c0,90.89029 -73.68114,164.57143 -164.57143,164.57143z" id="shape"></path></g><g fill="#ffffff" fill-rule="nonzero" stroke="none" stroke-width="1" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="10" stroke-dasharray="" stroke-dashoffset="0" font-family="none" font-weight="none" font-size="none" text-anchor="none" style="mix-blend-mode: normal"><g transform="scale(5.33333,5.33333)"><path d="M21.413,47.315c1.685,0.076 3.206,-0.076 4.891,0c-0.383,-4.097 0.719,-8.451 0.297,-12.544c-0.118,-1.142 0.076,-2.779 0.171,-3.924c0.102,-1.229 1.069,-3.553 1.533,-4.696c3.541,-8.731 5.77,-15.742 8.924,-24.62c-1.548,-0.029 -3.702,0.029 -5.25,0c-2.934,7.419 -5.846,15.183 -8.022,22.859c-3.659,-6.121 -5.157,-12.182 -7.055,-18.386c-0.13,-0.424 -0.284,-0.885 -0.66,-1.12c-0.247,-0.154 -0.549,-0.183 -0.839,-0.205c-1.56,-0.118 -3.126,-0.149 -4.689,-0.09c3.636,7.742 6.793,16.44 9.267,24.628c0.411,1.36 0.806,2.729 1.013,4.134c0.218,1.48 0.447,2.718 0.453,4.213c0.009,2.887 -0.044,6.865 -0.034,9.751z"></path><path d="M37.228,1.033c-1.75,-0.028 -3.5,0.028 -5.25,0c-0.238,-0.004 -0.401,0.161 -0.482,0.367c-2.823,7.142 -5.525,14.344 -7.685,21.717c-2.11,-3.802 -3.592,-7.875 -4.862,-12.033c-0.335,-1.095 -0.659,-2.193 -0.986,-3.291c-0.27,-0.904 -0.439,-2.011 -0.95,-2.815c-0.522,-0.821 -1.483,-0.798 -2.35,-0.848c-1.315,-0.076 -2.633,-0.086 -3.95,-0.041c-0.401,0.014 -0.593,0.409 -0.432,0.752c2.538,5.416 4.725,10.992 6.675,16.645c1.884,5.463 3.992,11.069 3.99,16.917c0,2.97 -0.043,5.941 -0.034,8.911c0.001,0.199 0.102,0.33 0.234,0.406c0.072,0.051 0.156,0.09 0.266,0.094c1.631,0.063 3.261,-0.063 4.891,0c0.253,0.01 0.523,-0.238 0.5,-0.5c-0.29,-3.347 0.333,-6.672 0.39,-10.014c0.026,-1.503 -0.185,-2.988 -0.088,-4.49c0.082,-1.276 0.2,-2.483 0.603,-3.701c0.908,-2.743 2.12,-5.396 3.142,-8.098c1.122,-2.965 2.185,-5.951 3.229,-8.944c1.21,-3.467 2.4,-6.941 3.629,-10.402c0.114,-0.314 -0.175,-0.627 -0.48,-0.632zM30.286,19.685c-1.051,2.814 -2.242,5.576 -3.274,8.396c-0.426,1.163 -0.695,2.274 -0.806,3.505c-0.061,0.682 -0.122,1.366 -0.138,2.051c-0.018,0.764 0.083,1.516 0.114,2.278c0.148,3.64 -0.621,7.255 -0.403,10.893c-1.288,-0.021 -2.575,0.037 -3.862,0.015c0.012,-5.353 0.438,-10.808 -0.961,-16.031c-1.566,-5.848 -3.647,-11.615 -5.86,-17.245c-1.123,-2.857 -2.331,-5.681 -3.617,-8.468c0.98,-0.018 1.96,-0.013 2.939,0.038c0.445,0.023 1.19,-0.067 1.573,0.2c0.355,0.247 0.446,0.872 0.561,1.249c0.612,2.017 1.195,4.043 1.828,6.053c1.316,4.174 2.906,8.253 5.146,12.025c0.22,0.371 0.796,0.295 0.914,-0.119c2.174,-7.647 4.961,-15.101 7.878,-22.492c1.403,0.014 2.805,-0.007 4.208,0c-2.082,5.883 -4.056,11.805 -6.24,17.652z"></path></g></g></g></svg>

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

@@ -40,7 +40,7 @@
"eslint-plugin-svelte3": "^4.0.0",
"prettier": "2.8.1",
"prettier-plugin-svelte": "^2.8.1",
"turbo": "1.6.3",
"turbo": "1.8.8",
"typescript": "4.9.4"
},
"engines": {
@@ -61,5 +61,205 @@
"patchedDependencies": {
"@balazsorban/monorepo-release@0.1.8": "patches/@balazsorban__monorepo-release@0.1.8.patch"
}
},
"eslintIgnore": [
".eslintrc.js",
".cache-loader",
".DS_Store",
".pnpm-debug.log",
".turbo",
".vscode/generated*",
"/_work",
"/actions-runner",
"node_modules",
"patches",
"pnpm-lock.yaml",
".github/actions/issue-validator/index.mjs",
"*.cjs",
"*.js",
"*.d.ts",
"*.d.ts.map",
".svelte-kit",
".next",
".nuxt",
".docusaurus",
"build",
"docs/docs/reference/core",
"docs/docs/reference/sveltekit",
"static",
"coverage",
"dist",
"packages/core/src/providers/oauth-types.ts",
"packages/core/src/lib/pages/styles.ts",
"packages/frameworks-sveltekit/package",
"packages/frameworks-sveltekit/vite.config.{js,ts}.timestamp-*",
"packages/next-auth/src/providers/oauth-types.ts",
"packages/next-auth/css/index.css",
".branches",
"db.sqlite",
"dev.db",
"dynamodblocal-bin",
"firebase-debug.log",
"firestore-debug.log",
"migrations",
"test.schema.gql",
"apps/example-sveltekit",
"apps",
"packages/**/*test*"
],
"eslintConfig": {
"env": {
"browser": true,
"es2021": true,
"node": true
},
"extends": [
"eslint:recommended",
"prettier"
],
"overrides": [
{
"files": [
"*.ts",
"*.tsx"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"project": [
"./packages/**/tsconfig.json",
"./apps/**/tsconfig.json"
]
},
"settings": {
"react": {
"version": "18"
}
},
"extends": [
"plugin:react/recommended",
"plugin:react/jsx-runtime",
"standard-with-typescript",
"prettier"
],
"rules": {
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/method-signature-style": "off",
"@typescript-eslint/naming-convention": "off",
"@typescript-eslint/no-non-null-assertion": "off",
"@typescript-eslint/restrict-template-expressions": "off",
"@typescript-eslint/strict-boolean-expressions": "off",
"react/prop-types": "off",
"react/no-unescaped-entities": "off"
}
},
{
"files": [
"*.test.ts",
"*.test.js"
],
"extends": [
"plugin:jest/recommended"
],
"env": {
"jest": true
}
},
{
"files": [
"docs/**"
],
"plugins": [
"@docusaurus"
],
"extends": [
"plugin:@docusaurus/recommended"
]
},
{
"files": [
"packages/{core,sveltekit}/*.ts"
],
"plugins": [
"jsdoc"
],
"extends": [
"plugin:jsdoc/recommended"
],
"rules": {
"jsdoc/require-param": "off",
"jsdoc/require-returns": "off",
"jsdoc/require-jsdoc": [
"warn",
{
"publicOnly": true,
"enableFixer": false
}
],
"jsdoc/no-multi-asterisks": [
"warn",
{
"allowWhitespace": true
}
],
"jsdoc/tag-lines": "off"
}
},
{
"files": [
"packages/frameworks-sveltekit"
],
"plugins": [
"svelte3"
],
"overrides": [
{
"files": [
"*.svelte"
],
"processor": "svelte3/svelte3"
}
],
"parserOptions": {
"sourceType": "module",
"ecmaVersion": 2020
},
"env": {
"browser": true,
"es2017": true,
"node": true
}
}
],
"parserOptions": {
"sourceType": "module",
"ecmaVersion": "latest",
"ecmaFeatures": {
"jsx": true
}
},
"root": true
},
"prettier": {
"semi": false,
"singleQuote": false,
"overrides": [
{
"files": [
"apps/dev/nextjs/pages/api/auth/[...nextauth].ts",
"docs/{sidebars,docusaurus.config}.js"
],
"options": {
"printWidth": 150
}
},
{
"files": [
"**/*package.json"
],
"options": {
"trailingComma": "none"
}
}
]
}
}

View File

@@ -9,10 +9,10 @@
* ## Installation
*
* ```bash npm2yarn2pnpm
* npm install next-auth @next-auth/dyanamodb-adapter
* npm install next-auth @next-auth/dynamodb-adapter
* ```
*
* @module @next-auth/dyanamodb-adapter
* @module @next-auth/dynamodb-adapter
*/
import { v4 as uuid } from "uuid"

View File

@@ -9,7 +9,7 @@
* ## Installation
*
* ```bash npm2yarn2pnpm
* npm install install next-auth @next-auth/sequelize-adapter sequelize
* npm install next-auth @next-auth/sequelize-adapter sequelize
* ```
*
* @module @next-auth/sequelize-adapter

View File

@@ -5,10 +5,11 @@ const providersPath = join(process.cwd(), "src/providers")
const files = readdirSync(providersPath, "utf8")
const nonOAuthFile = ["oauth-types", "oauth", "index", "email", "credentials"]
const providers = files.map((file) => {
const strippedProviderName = file.substring(0, file.indexOf("."))
return `"${strippedProviderName}"`
}).filter((provider) => provider !== '"oauth-types"' && provider !== '"index"')
}).filter((provider) => !nonOAuthFile.includes(provider.replace(/"/g, '')))
const result = `
// THIS FILE IS AUTOGENERATED. DO NOT EDIT.

View File

@@ -1,6 +1,5 @@
interface ErrorCause extends Record<string, unknown> {}
/** @internal */
export class AuthError extends Error {
constructor(message: string | Error | ErrorCause, cause?: ErrorCause) {
if (message instanceof Error) {
@@ -91,7 +90,7 @@ export class InvalidCallbackUrl extends AuthError {}
export class InvalidEndpoints extends AuthError {}
/** @todo */
export class InvalidState extends AuthError {}
export class InvalidCheck extends AuthError {}
/** @todo */
export class JWTSessionError extends AuthError {}

View File

@@ -48,9 +48,10 @@ const DEFAULT_MAX_AGE = 30 * 24 * 60 * 60 // 30 days
const now = () => (Date.now() / 1000) | 0
/** Issues a JWT. By default, the JWT is encrypted using "A256GCM". */
export async function encode(params: JWTEncodeParams) {
export async function encode<Payload = JWT>(params: JWTEncodeParams<Payload>) {
const { token = {}, secret, maxAge = DEFAULT_MAX_AGE } = params
const encryptionSecret = await getDerivedEncryptionKey(secret)
// @ts-expect-error `jose` allows any object as payload.
return await new EncryptJWT(token)
.setProtectedHeader({ alg: "dir", enc: "A256GCM" })
.setIssuedAt()
@@ -60,14 +61,16 @@ export async function encode(params: JWTEncodeParams) {
}
/** Decodes a Auth.js issued JWT. */
export async function decode(params: JWTDecodeParams): Promise<JWT | null> {
export async function decode<Payload = JWT>(
params: JWTDecodeParams
): Promise<Payload | null> {
const { token, secret } = params
if (!token) return null
const encryptionSecret = await getDerivedEncryptionKey(secret)
const { payload } = await jwtDecrypt(token, encryptionSecret, {
clockTolerance: 15,
})
return payload
return payload as Payload
}
export interface GetTokenParams<R extends boolean = false> {
@@ -179,9 +182,9 @@ export interface DefaultJWT extends Record<string, unknown> {
*/
export interface JWT extends Record<string, unknown>, DefaultJWT {}
export interface JWTEncodeParams {
export interface JWTEncodeParams<Payload = JWT> {
/** The JWT payload. */
token?: JWT
token?: Payload
/** The secret used to encode the Auth.js issued JWT. */
secret: string
/**

View File

@@ -101,7 +101,8 @@ export function assertConfig(
)
}
for (const provider of options.providers) {
for (const p of options.providers) {
const provider = typeof p === "function" ? p() : p
if (
(provider.type === "oauth" || provider.type === "oidc") &&
!(provider.issuer ?? provider.options?.issuer)
@@ -127,7 +128,7 @@ export function assertConfig(
if (hasCredentials) {
const dbStrategy = options.session?.strategy === "database"
const onlyCredentials = !options.providers.some(
(p) => p.type !== "credentials"
(p) => (typeof p === "function" ? p() : p).type !== "credentials"
)
if (dbStrategy && onlyCredentials) {
return new UnsupportedStrategy(
@@ -135,9 +136,10 @@ export function assertConfig(
)
}
const credentialsNoAuthorize = options.providers.some(
(p) => p.type === "credentials" && !p.authorize
)
const credentialsNoAuthorize = options.providers.some((p) => {
const provider = typeof p === "function" ? p() : p
return provider.type === "credentials" && !provider.authorize
})
if (credentialsNoAuthorize) {
return new MissingAuthorize(
"Must define an authorize() handler to use credentials authentication provider"

View File

@@ -11,6 +11,7 @@ import type {
ResponseInternal,
} from "../types.js"
/** @internal */
export async function AuthInternal<
Body extends string | Record<string, any> | any[]
>(

View File

@@ -73,7 +73,7 @@ export async function handleOAuth(
const state = await checks.state.use(cookies, resCookies, options)
const parameters = o.validateAuthResponse(
const codeGrantParams = o.validateAuthResponse(
as,
client,
new URLSearchParams(query),
@@ -81,36 +81,22 @@ export async function handleOAuth(
)
/** https://www.rfc-editor.org/rfc/rfc6749#section-4.1.2.1 */
if (o.isOAuth2Error(parameters)) {
if (o.isOAuth2Error(codeGrantParams)) {
logger.debug("OAuthCallbackError", {
providerId: provider.id,
...parameters,
...codeGrantParams,
})
throw new OAuthCallbackError(parameters.error)
throw new OAuthCallbackError(codeGrantParams.error)
}
const codeVerifier = await checks.pkce.use(
cookies?.[options.cookies.pkceCodeVerifier.name],
options
)
if (codeVerifier) resCookies.push(codeVerifier.cookie)
// TODO:
const nonce = await checks.nonce.use(
cookies?.[options.cookies.nonce.name],
options
)
if (nonce && provider.type === "oidc") {
resCookies.push(nonce.cookie)
}
const codeVerifier = await checks.pkce.use(cookies, resCookies, options)
let codeGrantResponse = await o.authorizationCodeGrantRequest(
as,
client,
parameters,
codeGrantParams,
provider.callbackUrl,
codeVerifier?.codeVerifier ?? "auth" // TODO: review fallback code verifier
codeVerifier ?? "auth" // TODO: review fallback code verifier
)
if (provider.token?.conform) {
@@ -131,11 +117,12 @@ export async function handleOAuth(
let tokens: TokenSet
if (provider.type === "oidc") {
const nonce = await checks.nonce.use(cookies, resCookies, options)
const result = await o.processAuthorizationCodeOpenIDResponse(
as,
client,
codeGrantResponse,
nonce?.value ?? o.expectNoNonce
nonce ?? o.expectNoNonce
)
if (o.isOAuth2Error(result)) {

View File

@@ -1,14 +1,17 @@
import * as o from "oauth4webapi"
import * as jwt from "../../jwt.js"
import { InvalidCheck } from "../../errors.js"
import { encode, decode } from "../../jwt.js"
import type {
CookiesOptions,
InternalOptions,
RequestInternal,
CookiesOptions,
} from "../../types.js"
import type { Cookie } from "../cookie.js"
import { InvalidState } from "../../errors.js"
interface CheckPayload {
value: string
}
/** Returns a signed cookie. */
export async function signCookie(
@@ -25,7 +28,11 @@ export async function signCookie(
expires.setTime(expires.getTime() + maxAge * 1000)
return {
name: cookies[type].name,
value: await jwt.encode({ ...options.jwt, maxAge, token: { value } }),
value: await encode<CheckPayload>({
...options.jwt,
maxAge,
token: { value },
}),
options: { ...cookies[type].options, expires },
}
}
@@ -44,34 +51,43 @@ export const pkce = {
)
return { cookie, value }
},
/**
* Returns code_verifier if provider uses PKCE,
* Returns code_verifier if the provider is configured to use PKCE,
* and clears the container cookie afterwards.
* An error is thrown if the code_verifier is missing or invalid.
* @see https://www.rfc-editor.org/rfc/rfc7636
* @see https://danielfett.de/2020/05/16/pkce-vs-nonce-equivalent-or-not/#pkce
*/
async use(
codeVerifier: string | undefined,
cookies: RequestInternal["cookies"],
resCookies: Cookie[],
options: InternalOptions<"oauth">
): Promise<{ codeVerifier: string; cookie: Cookie } | undefined> {
const { cookies, provider } = options
): Promise<string | undefined> {
const { provider } = options
if (!provider?.checks?.includes("pkce") || !codeVerifier) {
return
}
if (!provider?.checks?.includes("pkce")) return
const pkce = (await jwt.decode({
const codeVerifier = cookies?.[options.cookies.pkceCodeVerifier.name]
if (!codeVerifier)
throw new InvalidCheck("PKCE code_verifier cookie was missing.")
const value = await decode<CheckPayload>({
...options.jwt,
token: codeVerifier,
})) as any
})
return {
codeVerifier: pkce?.value ?? undefined,
cookie: {
name: cookies.pkceCodeVerifier.name,
value: "",
options: { ...cookies.pkceCodeVerifier.options, maxAge: 0 },
},
}
if (!value?.value)
throw new InvalidCheck("PKCE code_verifier value could not be parsed.")
// Clear the pkce code verifier cookie after use
resCookies.push({
name: options.cookies.pkceCodeVerifier.name,
value: "",
options: { ...options.cookies.pkceCodeVerifier.options, maxAge: 0 },
})
return value.value
},
}
@@ -86,26 +102,29 @@ export const state = {
return { cookie, value }
},
/**
* Returns state from the saved cookie
* if the provider supports states,
* Returns state if the provider is configured to use state,
* and clears the container cookie afterwards.
* An error is thrown if the state is missing or invalid.
* @see https://www.rfc-editor.org/rfc/rfc6749#section-10.12
* @see https://www.rfc-editor.org/rfc/rfc6749#section-4.1.1
*/
async use(
cookies: RequestInternal["cookies"],
resCookies: Cookie[],
options: InternalOptions<"oauth">
): Promise<string | undefined> {
const { provider, jwt } = options
const { provider } = options
if (!provider.checks.includes("state")) return
const state = cookies?.[options.cookies.state.name]
if (!state) throw new InvalidState("State was missing from the cookies.")
if (!state) throw new InvalidCheck("State cookie was missing.")
// IDEA: Let the user do something with the returned state
const value = (await jwt.decode({ ...options.jwt, token: state })) as any
const value = await decode<CheckPayload>({ ...options.jwt, token: state })
if (!value?.value) throw new InvalidState("Could not parse state cookie.")
if (!value?.value)
throw new InvalidCheck("State value could not be parsed.")
// Clear the state cookie after use
resCookies.push({
@@ -128,28 +147,36 @@ export const nonce = {
return { cookie, value }
},
/**
* Returns nonce from if the provider supports nonce,
* Returns nonce if the provider is configured to use nonce,
* and clears the container cookie afterwards.
* An error is thrown if the nonce is missing or invalid.
* @see https://openid.net/specs/openid-connect-core-1_0.html#NonceNotes
* @see https://danielfett.de/2020/05/16/pkce-vs-nonce-equivalent-or-not/#nonce
*/
async use(
nonce: string | undefined,
cookies: RequestInternal["cookies"],
resCookies: Cookie[],
options: InternalOptions<"oauth">
): Promise<{ value: string; cookie: Cookie } | undefined> {
const { cookies, provider } = options
): Promise<string | undefined> {
const { provider } = options
if (!provider?.checks?.includes("nonce") || !nonce) {
return
}
if (!provider?.checks?.includes("nonce")) return
const value = (await jwt.decode({ ...options.jwt, token: nonce })) as any
const nonce = cookies?.[options.cookies.nonce.name]
if (!nonce) throw new InvalidCheck("Nonce cookie was missing.")
return {
value: value?.value ?? undefined,
cookie: {
name: cookies.nonce.name,
value: "",
options: { ...cookies.nonce.options, maxAge: 0 },
},
}
const value = await decode<CheckPayload>({ ...options.jwt, token: nonce })
if (!value?.value)
throw new InvalidCheck("Nonce value could not be parsed.")
// Clear the nonce cookie after use
resCookies.push({
name: options.cookies.nonce.name,
value: "",
options: { ...options.cookies.nonce.options, maxAge: 0 },
})
return value.value
},
}

View File

@@ -23,7 +23,8 @@ export default function parseProviders(params: {
} {
const { url, providerId } = params
const providers = params.providers.map((provider) => {
const providers = params.providers.map((p) => {
const provider = typeof p === "function" ? p() : p
const { options: userOptions, ...defaults } = provider
const id = (userOptions?.id ?? defaults.id) as string

View File

@@ -139,7 +139,6 @@ export async function callback(params: {
})
}
// @ts-expect-error
await events.signIn?.({ user, account, profile, isNewUser })
// Handle first logins on new accounts

View File

@@ -9,7 +9,7 @@ import type { SessionStore } from "../cookie.js"
export async function session(
sessionStore: SessionStore,
options: InternalOptions
): Promise<ResponseInternal<Session | {}>> {
): Promise<ResponseInternal<Session | null>> {
const {
adapter,
jwt,
@@ -19,8 +19,8 @@ export async function session(
session: { strategy: sessionStrategy, maxAge: sessionMaxAge },
} = options
const response: ResponseInternal<Session | {}> = {
body: {},
const response: ResponseInternal<Session | null> = {
body: null,
headers: { "Content-Type": "application/json" },
cookies: [],
}

View File

@@ -78,7 +78,6 @@ export function toResponse(res: ResponseInternal): Response {
const cookieHeader = serialize(name, value, options)
if (headers.has("Set-Cookie")) headers.append("Set-Cookie", cookieHeader)
else headers.set("Set-Cookie", cookieHeader)
// headers.set("Set-Cookie", cookieHeader) // TODO: Remove. Seems to be a bug with Headers in the runtime
})
let body = res.body

View File

@@ -1,22 +1,19 @@
/**
* <div style={{backgroundColor: "#000", display: "flex", justifyContent: "space-between", color: "#fff", padding: 16}}>
* <span>Built-in <b>Apple</b> integration.</span>
* <a href="https://apple.com">
* <img style={{display: "block"}} src="https://authjs.dev/img/providers/apple-dark.svg" height="48" width="48"/>
* <div style={{display: "flex", justifyContent: "space-between", alignItems: "center"}}>
* <span style={{fontSize: "1.35rem" }}>
* Built-in sign in with <b>Apple</b> integration.
* </span>
* <a href="https://apple.com" style={{backgroundColor: "black", padding: "12px", borderRadius: "100%" }}>
* <img style={{display: "block"}} src="https://authjs.dev/img/providers/apple-dark.svg" width="24"/>
* </a>
* </div>
*
* ---
* @module providers/apple
*/
import type { OAuthConfig, OAuthUserConfig } from "./index.js"
/**
* See more at:
* [Retrieve the User's Information from Apple ID Servers
](https://developer.apple.com/documentation/sign_in_with_apple/sign_in_with_apple_rest_api/authenticating_users_with_sign_in_with_apple#3383773)
*/
/** The returned user profile from Apple when using the profile callback. */
export interface AppleProfile extends Record<string, any> {
/**
* The issuer registered claim identifies the principal that issued the identity token.
@@ -99,6 +96,44 @@ export interface AppleProfile extends Record<string, any> {
auth_time: number
}
/**
* ## Setup
*
* Import the provider and configure it in your **Auth.js** initialization file:
*
* ```ts title="pages/api/auth/[...nextauth].ts"
* import NextAuth from "next-auth"
* import AppleProvider from "next-auth/providers/apple"
*
* export default NextAuth({
* providers: [
* AppleProvider({
* clientId: process.env.GITHUB_ID,
* clientSecret: process.env.GITHUB_SECRET,
* }),
* ],
* })
* ```
*
* ## Resources
*
* - Sign in with Apple [Overview](https://developer.apple.com/sign-in-with-apple/get-started/)
* - Sign in with Apple [REST API](https://developer.apple.com/documentation/sign_in_with_apple/sign_in_with_apple_rest_api)
* - [How to retrieve](https://developer.apple.com/documentation/sign_in_with_apple/sign_in_with_apple_rest_api/authenticating_users_with_sign_in_with_apple#3383773) the user's information from Apple ID servers
* - [Learn more about OAuth](https://authjs.dev/concepts/oauth)
* ## Notes
*
* The Apple provider comes with a [default configuration](https://github.com/nextauthjs/next-auth/blob/main/packages/core/src/providers/apple.ts). To override the defaults for your use case, check out [customizing a built-in OAuth provider](https://authjs.dev/guides/providers/custom-provider#override-default-options).
*
* ## Help
*
* If you think you found a bug in the default configuration, you can [open an issue](https://authjs.dev/new/provider-issue).
*
* Auth.js strictly adheres to the specification and it cannot take responsibility for any deviation from
* the spec by the provider. You can open an issue, but if the problem is non-compliance with the spec,
* we might not pursue a resolution. You can ask for more help in [Discussions](https://authjs.dev/new/github-discussions).
*/
export default function Apple<P extends AppleProfile>(
options: Omit<OAuthUserConfig<P>, "clientSecret"> & {
/**

View File

@@ -1,95 +1,100 @@
/**
* <div style={{backgroundColor: "#24292f", display: "flex", justifyContent: "space-between", color: "#fff", padding: 16}}>
* <span>Built-in <b>Asgardeo</b> integration.</span>
* <a href="https://wso2.com/asgardeo/">
* <img style={{display: "block"}} src="https://authjs.dev/img/providers/asgardeo-dark.svg" height="48" width="48"/>
* <div style={{display: "flex", justifyContent: "space-between", alignItems: "center"}}>
* <span style={{fontSize: "1.35rem" }}>
* Built-in sign in with <b>Asgardeo</b> integration.
* </span>
* <a href="https://wso2.com/asgardeo/" style={{backgroundColor: "#ECEFF1", padding: "12px", borderRadius: "100%" }}>
* <img style={{display: "block"}} src="https://authjs.dev/img/providers/asgardeo-dark.svg" width="24"/>
* </a>
* </div>
*
* ---
* @module providers/asgardeo
*/
import type { OIDCConfig, OIDCUserConfig } from "./index.js"
export interface AsgardeoProfile {
/** The returned user profile from Asgardeo when using the profile callback. */
export interface AsgardeoProfile extends Record<string, any> {
/**
* The user Asgardeo account ID
*/
sub: string
/**
* The user name
*/
given_name: string
/**
* The user email
*/
email: string
/**
* The user profile picture
*/
picture: string
}
/**
* Add Asgardeo login to your page.
* ## Documentation
*
* https://wso2.com/asgardeo/docs/guides/authentication
* ## Setup
*
* Import the provider and configure it in your **Auth.js** initialization file:
*
* ## Instructions
* ```ts title="pages/api/auth/[...nextauth].ts"
* import NextAuth from "next-auth"
* import AsgardeoProvider from "next-auth/providers/asgardeo";
*
* - Log into https://console.asgardeo.io.
* - Next, go to "Application" tab (More info: https://wso2.com/asgardeo/docs/guides/applications/register-oidc-web-app/).
* - Register standard based - Open id connect, application.
* - Add callback URL: http://localhost:3000/api/auth/callback/asgardeo and https://your-domain.com/api/auth/callback/asgardeo
* - After registering the application, go to protocol tab.
* - Check `code` grant type.
* - Add Authorized redirect URLs & Allowed origins fields.
* - Make Email, First Name, Photo URL user attributes mandatory from the console.
*
* Create a `.env` file in the project root add the following entries:
*
* These values can be collected from the application created.
*
* ```
* ASGARDEO_CLIENT_ID=<Copy client ID from protocol tab here>
* ASGARDEO_CLIENT_SECRET=<Copy client from protocol tab here>
* ASGARDEO_ISSUER=<Copy the issuer url from the info tab here>
* export default NextAuth({
* providers: [
* AsgardeoProvider({
* clientId: process.env.ASGARDEO_CLIENT_ID,
* clientSecret: process.env.ASGARDEO_CLIENT_SECRET,
* issuer: process.env.ASGARDEO_ISSUER
* }),
* ],
* })
* ```
*
* In `pages/api/auth/[...nextauth].js` find or add the `Asgardeo` entries:
* ### Configuring Asgardeo
*
* ```js
* import Asgardeo from "next-auth/providers/asgardeo";
* ...
* providers: [
* Asgardeo({
* clientId: process.env.ASGARDEO_CLIENT_ID,
* clientSecret: process.env.ASGARDEO_CLIENT_SECRET,
* issuer: process.env.ASGARDEO_ISSUER
* }),
* ],
* Follow these steps:
*
* ...
* 1. Log into the [Asgardeo console](https://console.asgardeo.io)
* 2. Next, go to "Application" tab (more info [here](https://wso2.com/asgardeo/docs/guides/applications/register-oidc-web-app/))
* 3. Register a standard based, Open ID connect, application
* 4. Add the **callback URLs**: `http://localhost:3000/api/auth/callback/asgardeo` (development) and `https://{YOUR_DOMAIN}.com/api/auth/callback/asgardeo` (production)
* 5. After registering the application, go to "Protocol" tab.
* 6. Check `code` as the grant type.
* 7. Add "Authorized redirect URLs" & "Allowed origins fields"
* 8. Make Email, First Name, Photo URL user attributes mandatory from the console.
*
* Then, create a `.env` file in the project root add the following entries:
*
* ```
* ASGARDEO_CLIENT_ID="Copy client ID from protocol tab here"
* ASGARDEO_CLIENT_SECRET="Copy client from protocol tab here"
* ASGARDEO_ISSUER="Copy the issuer url from the info tab here"
* ```
*
* ## Resources
*
* @see [Asgardeo - Authentication Guide](https://wso2.com/asgardeo/docs/guides/authentication)
* @see [Learn more about OAuth](https://authjs.dev/concepts/oauth)
* @see [Source code](https://github.com/nextauthjs/next-auth/blob/main/packages/core/src/providers/asgardeo.ts)
* - [Asgardeo - Authentication Guide](https://wso2.com/asgardeo/docs/guides/authentication)
* - [Learn more about OAuth](https://authjs.dev/concepts/oauth)
*
* ## Notes
*
* By default, Auth.js assumes that the Asgardeo provider is
* based on the [OAuth 2](https://www.rfc-editor.org/rfc/rfc6749.html) specification.
*
* :::tip
*
* The Asgardeo provider comes with a [default configuration](https://github.com/nextauthjs/next-auth/blob/main/packages/core/src/providers/asgardeo.ts).
* To override the defaults for your use case, check out [customizing a built-in OAuth provider](https://authjs.dev/guides/providers/custom-provider#override-default-options).
* The Asgardeo provider comes with a [default configuration](https://github.com/nextauthjs/next-auth/blob/main/packages/core/src/providers/asgardeo.ts). To override the defaults for your use case, check out [customizing a built-in OAuth provider](https://authjs.dev/guides/providers/custom-provider#override-default-options).
*
* :::info
* By default, Auth.js assumes that the Asgardeo provider is based on the [OAuth 2](https://www.rfc-editor.org/rfc/rfc6749.html) spec
* :::
*
* :::info **Disclaimer**
* ## Help
*
* If you think you found a bug in the default configuration, you can [open an issue](https://authjs.dev/new/provider-issue).
*
* Auth.js strictly adheres to the specification and it cannot take responsibility for any deviation from
* the spec by the provider. You can open an issue, but if the problem is non-compliance with the spec,
* we might not pursue a resolution. You can ask for more help in [Discussions](https://authjs.dev/new/github-discussions).
*
* :::
*/
export default function Asgardeo(
config: OIDCUserConfig<AsgardeoProfile>

View File

@@ -1,12 +1,72 @@
/**
* <div style={{display: "flex", justifyContent: "space-between", alignItems: "center"}}>
* <span style={{fontSize: "1.35rem" }}>
* Built-in sign in with <b>Atlassian</b> integration.
* </span>
* <a href="https://www.atlassian.com/" style={{backgroundColor: "black", padding: "12px", borderRadius: "100%" }}>
* <img style={{display: "block"}} src="https://authjs.dev/img/providers/atlassian.svg" width="24" style={{ marginTop: "-3px"}} />
* </a>
* </div>
*
* @module providers/atlassian
*/
import type { OAuthConfig, OAuthUserConfig } from "./index.js"
interface AtlassianProfile extends Record<string, any> {
/** The returned user profile from Atlassian when using the profile callback. */
export interface AtlassianProfile extends Record<string, any> {
/**
* The user's atlassian account ID
*/
account_id: string
/**
* The user name
*/
name: string
/**
* The user's email
*/
email: string
/**
* The user's profile picture
*/
picture: string
}
/**
* ## Setup
*
* Import the provider and configure it in your **Auth.js** initialization file:
*
* ```ts title="pages/api/auth/[...nextauth].ts"
* import NextAuth from "next-auth"
* import AtlassianProvider from "next-auth/providers/atlassian"
*
* export default NextAuth({
* providers: [
* AtlassianProvider({
* clientId: process.env.ATLASSIAN_ID,
* clientSecret: process.env.ATLASSIAN_SECRET,
* }),
* ],
* })
* ```
*
* ## Resources
*
* - [Atlassian docs](https://developer.atlassian.com/server/jira/platform/oauth/)
*
* ## Notes
*
* The Atlassian provider comes with a [default configuration](https://github.com/nextauthjs/next-auth/blob/main/packages/core/src/providers/atlassian.ts). To override the defaults for your use case, check out [customizing a built-in OAuth provider](https://authjs.dev/guides/providers/custom-provider#override-default-options).
*
* ## Help
*
* If you think you found a bug in the default configuration, you can [open an issue](https://authjs.dev/new/provider-issue).
*
* Auth.js strictly adheres to the specification and it cannot take responsibility for any deviation from
* the spec by the provider. You can open an issue, but if the problem is non-compliance with the spec,
* we might not pursue a resolution. You can ask for more help in [Discussions](https://authjs.dev/new/github-discussions).
*/
export default function Atlassian<P extends AtlassianProfile>(
options: OAuthUserConfig<P>
): OAuthConfig<P> {

View File

@@ -1,19 +1,19 @@
/**
* <div style={{backgroundColor: "#EB5424", display: "flex", justifyContent: "space-between", color: "#fff", padding: 16}}>
* <span>Built-in <b>Auth0</b> integration.</span>
* <a href="https://auth0.com">
* <img style={{display: "block"}} src="https://authjs.dev/img/providers/auth0-dark.svg" height="48" width="48"/>
* <div style={{display: "flex", justifyContent: "space-between", alignItems: "center"}}>
* <span style={{fontSize: "1.35rem" }}>
* Built-in sign in with <b>Auth0</b> integration.
* </span>
* <a href="https://auth0.com" style={{backgroundColor: "black", padding: "12px", borderRadius: "100%" }}>
* <img style={{display: "block"}} src="https://authjs.dev/img/providers/auth0-dark.svg" width="24"/>
* </a>
* </div>
*
* ---
* @module providers/auth0
*/
import type { OIDCConfig, OIDCUserConfig } from "./index.js"
/** @see [User Profile Structure](https://auth0.com/docs/manage-users/user-accounts/user-profiles/user-profile-structure) */
export interface Auth0Profile {
/** The returned user profile from Auth0 when using the profile callback. [Reference](https://auth0.com/docs/manage-users/user-accounts/user-profiles/user-profile-structure). */
export interface Auth0Profile extends Record<string, any> {
/** The user's unique identifier. */
sub: string
/** Custom fields that store info about a user that influences the user's access, such as support plan, security roles (if not using the Authorization Core feature set), or access control groups. To learn more, read Metadata Overview. */
@@ -75,51 +75,40 @@ export interface Auth0Profile {
}
/**
* Add Auth0 login to your page.
* ## Setup
*
* ## Example
* Import the provider and configure it in your **Auth.js** initialization file:
*
* ```ts
* import { Auth } from "@auth/core"
* import Auth0 from "@auth/core/providers/auth0"
* ```ts title="pages/api/auth/[...nextauth].ts"
* import NextAuth from "next-auth"
* import Auth0Provider from "next-auth/providers/auth0"
*
* const request = new Request("https://example.com")
* const response = await Auth(request, {
* providers: [Auth0({ clientId: "", clientSecret: "", issuer: "" })],
* export default NextAuth({
* providers: [
* Auth0Provider({
* clientId: process.env.AUTH0_ID,
* clientSecret: process.env.AUTH0_SECRET,
* }),
* ],
* })
* ```
*
* ---
*
* ## Resources
*
* - [Authenticate - Auth0 docs](https://auth0.com/docs/authenticate)
*
* ---
* - [Auth0 docs](https://auth0.com/docs/authenticate)
*
* ## Notes
*
* By default, Auth.js assumes that the Auth0 provider is
* based on the [OIDC](https://openid.net/specs/openid-connect-core-1_0.html) specification.
* The Auth0 provider comes with a [default configuration](https://github.com/nextauthjs/next-auth/blob/main/packages/core/src/providers/auth0.ts). To override the defaults for your use case, check out [customizing a built-in OAuth provider](https://authjs.dev/guides/providers/custom-provider#override-default-options).
*
* :::tip
*
* The Auth0 provider comes with a [default configuration](https://github.com/nextauthjs/next-auth/blob/main/packages/core/src/providers/auth0.ts).
* To override the defaults for your use case, check out [customizing a built-in OAuth provider](https://authjs.dev/guides/providers/custom-provider#override-default-options).
*
* :::
*
* :::info **Disclaimer**
* ## Help
*
* If you think you found a bug in the default configuration, you can [open an issue](https://authjs.dev/new/provider-issue).
*
* Auth.js strictly adheres to the specification and it cannot take responsibility for any deviation from
* the spec by the provider. You can open an issue, but if the problem is non-compliance with the spec,
* we might not pursue a resolution. You can ask for more help in [Discussions](https://authjs.dev/new/github-discussions).
*
* :::
*/
export default function Auth0(
config: OIDCUserConfig<Auth0Profile>
): OIDCConfig<Auth0Profile> {

View File

@@ -44,7 +44,7 @@ export interface AzureADB2CProfile {
* 2. [App Registration](https://docs.microsoft.com/en-us/azure/active-directory-b2c/tutorial-register-applications)
* 3. [User Flow](https://docs.microsoft.com/en-us/azure/active-directory-b2c/tutorial-create-user-flows)
*
* For the step "User attributes and token claims" you might want to set the following:
* For the step "User attributes and token claims" set the following:
*
* - Collect attribute:
* - Email Address

View File

@@ -39,7 +39,7 @@ export interface EmailConfig extends CommonProviderOptions {
* @default 86400
*/
maxAge?: number
/** [Documentation](https://authjs.dev/reference/providers/email#customizing-emails) */
/** [Documentation](https://authjs.dev/guides/providers/email#customizing-emails) */
sendVerificationRequest: (
params: SendVerificationRequestParams
) => Awaitable<void>
@@ -55,7 +55,7 @@ export interface EmailConfig extends CommonProviderOptions {
* }
* })
* ```
* [Documentation](https://authjs.dev/reference/providers/email#customizing-the-verification-token)
* [Documentation](https://authjs.dev/guides/providers/email#customizing-the-verification-token)
*/
generateVerificationToken?: () => Awaitable<string>
/** If defined, it is used to hash the verification token when saving to the database . */
@@ -72,7 +72,7 @@ export interface EmailConfig extends CommonProviderOptions {
* By default, we treat email addresses as all lower case,
* but you can override this function to change this behavior.
*
* [Documentation](https://authjs.dev/reference/providers/email#normalizing-the-e-mail-address) | [RFC 2821](https://tools.ietf.org/html/rfc2821) | [Email syntax](https://en.wikipedia.org/wiki/Email_address#Syntax)
* [Documentation](https://authjs.dev/guides/providers/email#normalizing-the-e-mail-address) | [RFC 2821](https://tools.ietf.org/html/rfc2821) | [Email syntax](https://en.wikipedia.org/wiki/Email_address#Syntax)
*/
normalizeIdentifier?: (identifier: string) => string
}

View File

@@ -44,6 +44,12 @@ export interface CommonProviderOptions {
type: ProviderType
}
interface InternalProviderOptions {
/** Used to deep merge user-provided config with the default config
*/
options?: Record<string, unknown>
}
/**
* Must be a supported authentication provider config:
* - {@link OAuthConfig}
@@ -57,17 +63,14 @@ export interface CommonProviderOptions {
* @see [Credentials guide](https://authjs.dev/guides/providers/credentials)
*/
export type Provider<P extends Profile = Profile> = (
| OIDCConfig<P>
| OAuth2Config<P>
| EmailConfig
| CredentialsConfig
) & {
/**
* Used to deep merge user-provided config with the default config
* @internal
*/
options: Record<string, unknown>
}
| ((OIDCConfig<P> | OAuth2Config<P> | EmailConfig | CredentialsConfig) &
InternalProviderOptions)
| ((
...args: any
) => (OAuth2Config<P> | OIDCConfig<P> | EmailConfig | CredentialsConfig) &
InternalProviderOptions)
) &
InternalProviderOptions
export type BuiltInProviders = Record<
OAuthProviderType,

View File

@@ -19,7 +19,7 @@ type UrlParams = Record<string, unknown>
type EndpointRequest<C, R, P> = (
context: C & {
/** Provider is passed for convenience, ans also contains the `callbackUrl`. */
/** Provider is passed for convenience, and also contains the `callbackUrl`. */
provider: OAuthConfigInternal<P> & {
signinUrl: string
callbackUrl: string
@@ -150,6 +150,10 @@ export interface OAuth2Config<Profile>
checks?: Array<"pkce" | "state" | "none" | "nonce">
clientId?: string
clientSecret?: string
/**
* Pass overrides to the underlying OAuth library.
* See [`oauth4webapi` client](https://github.com/panva/oauth4webapi/blob/main/docs/interfaces/Client.md) for details.
*/
client?: Partial<Client>
style?: OAuthProviderButtonStyles
/**
@@ -179,7 +183,6 @@ export type OAuthEndpointType = "authorization" | "token" | "userinfo"
/**
* We parsed `authorization`, `token` and `userinfo`
* to always contain a valid `URL`, with the params
* @internal
*/
export type OAuthConfigInternal<Profile> = Omit<
OAuthConfig<Profile>,
@@ -189,6 +192,7 @@ export type OAuthConfigInternal<Profile> = Omit<
token?: {
url: URL
request?: TokenEndpointHandler["request"]
/** @internal */
conform?: TokenEndpointHandler["conform"]
}
userinfo?: { url: URL; request?: UserinfoEndpointHandler["request"] }

View File

@@ -7,6 +7,12 @@ export default function Reddit(options) {
authorization: "https://www.reddit.com/api/v1/authorize?scope=identity",
token: "https://www.reddit.com/api/v1/access_token",
userinfo: "https://oauth.reddit.com/api/v1/me",
checks: ["state"],
style: {
logo: "/reddit.svg",
bg: "#fff",
text: "#000",
},
options,
}
}

View File

@@ -1,3 +1,48 @@
/**
* Add Salesforce login to your page.
*
* ## Example
*
* ```ts
* import { Auth } from "@auth/core"
* import Salesforce from "@auth/core/providers/salesforce"
*
* const request = new Request("https://example.com")
* const response = await AuthHandler(request, {
* providers: [Salesforce({ clientId: "", clientSecret: "" })],
* })
* ```
*
* ---
*
* ## Resources
*
* - [](https://example.com)
*
* ---
*
* ## Notes
*
* By default, Auth.js assumes that the Salesforce provider is
* based on the [OAuth 2](https://www.rfc-editor.org/rfc/rfc6749.html) specification.
*
* :::tip
*
* The Salesforce provider comes with a [default configuration](https://github.com/nextauthjs/next-auth/blob/main/packages/core/src/providers/.ts).
* To override the defaults for your use case, check out [customizing a built-in OAuth provider](https://authjs.dev/guides/providers/custom-provider#override-default-options).
*
* :::
*
* :::info **Disclaimer**
*
* If you think you found a bug in the default configuration, you can [open an issue](https://authjs.dev/new/provider-issue).
*
* Auth.js strictly adheres to the specification and it cannot take responsibility for any deviation from
* the spec by the provider. You can open an issue, but if the problem is non-compliance with the spec,
* we might not pursue a resolution. You can ask for more help in [Discussions](https://authjs.dev/new/github-discussions).
*
* :::
*/
import type { OAuthConfig, OAuthUserConfig } from "./index.js"
export interface SalesforceProfile extends Record<string, any> {

View File

@@ -1,23 +0,0 @@
/** @type {import(".").OAuthProvider} */
export default function Yandex(options) {
return {
id: "yandex",
name: "Yandex",
type: "oauth",
authorization:
"https://oauth.yandex.ru/authorize?scope=login:email+login:info",
token: "https://oauth.yandex.ru/token",
userinfo: "https://login.yandex.ru/info?format=json",
profile(profile) {
return {
id: profile.id,
name: profile.real_name,
email: profile.default_email,
image: profile.is_avatar_empty
? null
: `https://avatars.yandex.net/get-yapic/${profile.default_avatar_id}/islands-200`,
}
},
options,
}
}

View File

@@ -0,0 +1,155 @@
/**
* <div style={{backgroundColor: "#ffcc00", display: "flex", justifyContent: "space-between", color: "#000", padding: 16}}>
* <span>Built-in <b>Yandex</b> integration.</span>
* <a href="https://github.com">
* <img style={{display: "block"}} src="https://authjs.dev/img/providers/yandex.svg" height="48" width="48"/>
* </a>
* </div>
*
* ---
* @module providers/yandex
*/
import { OAuthConfig, OAuthUserConfig } from "."
/**
* @see [Getting information about the user](https://yandex.com/dev/id/doc/en/user-information)
* @see [Access to email address](https://yandex.com/dev/id/doc/en/user-information#email-access)
* @see [Access to the user's profile picture](https://yandex.com/dev/id/doc/en/user-information#avatar-access)
* @see [Access to the date of birth](https://yandex.com/dev/id/doc/en/user-information#birthday-access)
* @see [Access to login, first name, last name, and gender](https://yandex.com/dev/id/doc/en/user-information#name-access)
* @see [Access to the phone number](https://yandex.com/dev/id/doc/en/user-information#phone-access)
*/
export interface YandexProfile {
/** User's Yandex login. */
login: string
/** Yandex user's unique ID. */
id: string
/**
* The ID of the app the OAuth token in the request was issued for.
* Available in the [app properties](https://oauth.yandex.com/). To open properties, click the app name.
*/
client_id: string
/** Authorized Yandex user ID. It is formed on the Yandex side based on the `client_id` and `user_id` pair. */
psuid: string
/** An array of the user's email addresses. Currently only includes the default email address. */
emails?: string[]
/** The default email address for contacting the user. */
default_email?: string
/**
* Indicates that the stub (profile picture that is automatically assigned when registering in Yandex)
* ID is specified in the `default_avatar_id` field.
*/
is_avatar_empty?: boolean
/**
* ID of the Yandex user's profile picture.
* The profile picture with this ID can be downloaded via a link that looks like this:
* @example "https://avatars.yandex.net/get-yapic/31804/BYkogAC6AoB17bN1HKRFAyKiM4-1/islands-200"
*/
default_avatar_id?:
| "islands-small"
| "islands-34"
| "islands-middle"
| "islands-50"
| "islands-retina-small"
| "islands-68"
| "islands-75"
| "islands-retina-middle"
| "islands-retina-50"
| "islands-200"
/**
* The user's date of birth in YYYY-MM-DD format.
* Unknown elements of the date are filled in with zeros, such as: `0000-12-23`.
* If the user's date of birth is unknow, birthday will be `null`
*/
birthday?: string | null
first_name?: string
last_name?: string
display_name?: string
/**
* The first and last name that the user specified in Yandex ID.
* Non-Latin characters of the first and last names are presented in Unicode format.
*/
real_name?: string
/** User's gender. Possible values: Male: `male', Female: `female`, Unknown gender: `null` */
sex?: string
/**
* The default phone number for contacting the user.
* The API can exclude the user's phone number from the response at its discretion.
* The field contains the following parameters:
* id: Phone number ID.
* number: The user's phone number.
*/
default_phone?: { id: number; number: string }
}
/**
* Add Yandex login to your page
*
* ## Example
*
* ```ts
* import { Auth } from "@auth/core"
* import Yandex from "@auth/core/providers/yandex"
*
* const request = new Request("https://example.com")
* const response = await Auth(request, {
* providers: [Yandex({ clientId: "", clientSecret: "" })],
* })
* ```
*
* ## Resources
*
* @see [Yandex - Creating an OAuth app](https://yandex.com/dev/id/doc/en/register-client#create)
* @see [Yandex - Manage OAuth apps](https://oauth.yandex.com/)
* @see [Yandex - OAuth documentation](https://yandex.com/dev/id/doc/en/)
* @see [Learn more about OAuth](https://authjs.dev/concepts/oauth)
* @see [Source code](https://github.com/nextauthjs/next-auth/blob/main/packages/core/src/providers/yandex.ts)
*
*:::tip
* The Yandex provider comes with a [default configuration](https://github.com/nextauthjs/next-auth/blob/main/packages/core/src/providers/yandex.ts).
* To override the defaults for your use case, check out [customizing a built-in OAuth provider](https://authjs.dev/guides/providers/custom-provider#override-default-options).
* :::
*
* :::info **Disclaimer**
* If you think you found a bug in the default configuration, you can [open an issue](https://authjs.dev/new/provider-issue).
*
* Auth.js strictly adheres to the specification and it cannot take responsibility for any deviation from
* the spec by the provider. You can open an issue, but if the problem is non-compliance with the spec,
* we might not pursue a resolution. You can ask for more help in [Discussions](https://authjs.dev/new/github-discussions).
* :::
*/
export default function Yandex(
options: OAuthUserConfig<YandexProfile>
): OAuthConfig<YandexProfile> {
return {
id: "yandex",
name: "Yandex",
type: "oauth",
/** @see [Data access](https://yandex.com/dev/id/doc/en/register-client#access) */
authorization:
"https://oauth.yandex.ru/authorize?scope=login:info+login:email+login:avatar",
token: "https://oauth.yandex.ru/token",
userinfo: "https://login.yandex.ru/info?format=json",
profile(profile) {
return {
id: profile.id,
name: profile.display_name ?? profile.real_name ?? profile.first_name,
email: profile.default_email ?? profile.emails?.[0] ?? null,
image:
!profile.is_avatar_empty && profile.default_avatar_id
? `https://avatars.yandex.net/get-yapic/${profile.default_avatar_id}/islands-200`
: null,
}
},
style: {
logo: "/yandex.svg",
logoDark: "/yandex.svg",
bg: "#ffcc00",
text: "#000",
bgDark: "#ffcc00",
textDark: "#000",
},
options,
}
}

View File

@@ -121,10 +121,10 @@ export interface Account extends Partial<OpenIDTokenEndpointResponse> {
/** The OAuth profile returned from your provider */
export interface Profile {
sub?: string
name?: string
email?: string
image?: string
sub?: string | null
name?: string | null
email?: string | null
image?: string | null
}
/** [Documentation](https://authjs.dev/guides/basics/callbacks) */
@@ -406,7 +406,7 @@ export interface RequestInternal {
/** @internal */
export interface ResponseInternal<
Body extends string | Record<string, any> | any[] = any
Body extends string | Record<string, any> | any[] | null = any
> {
status?: number
headers?: Headers | HeadersInit

View File

@@ -5,7 +5,7 @@ export default function Reddit(options) {
name: "Reddit",
type: "oauth",
authorization: "https://www.reddit.com/api/v1/authorize?scope=identity",
token: " https://www.reddit.com/api/v1/access_token",
token: "https://www.reddit.com/api/v1/access_token",
userinfo: "https://oauth.reddit.com/api/v1/me",
profile(profile) {
return {
@@ -15,6 +15,11 @@ export default function Reddit(options) {
image: null,
}
},
style: {
logo: "https://raw.githubusercontent.com/nextauthjs/next-auth/main/packages/next-auth/provider-logos/reddit.svg",
bg: "#fff",
text: "#000",
},
options,
}
}

44
pnpm-lock.yaml generated
View File

@@ -27,7 +27,7 @@ importers:
eslint-plugin-svelte3: ^4.0.0
prettier: 2.8.1
prettier-plugin-svelte: ^2.8.1
turbo: 1.6.3
turbo: 1.8.8
typescript: 4.9.4
devDependencies:
'@actions/core': 1.10.0
@@ -48,7 +48,7 @@ importers:
eslint-plugin-svelte3: 4.0.0_eslint@8.30.0
prettier: 2.8.1
prettier-plugin-svelte: 2.8.1_prettier@2.8.1
turbo: 1.6.3
turbo: 1.8.8
typescript: 4.9.4
apps/dev/nextjs:
@@ -30907,65 +30907,65 @@ packages:
engines: {node: '>=0.6.11 <=0.7.0 || >=0.7.3'}
dev: true
/turbo-darwin-64/1.6.3:
resolution: {integrity: sha512-QmDIX0Yh1wYQl0bUS0gGWwNxpJwrzZU2GIAYt3aOKoirWA2ecnyb3R6ludcS1znfNV2MfunP+l8E3ncxUHwtjA==}
/turbo-darwin-64/1.8.8:
resolution: {integrity: sha512-18cSeIm7aeEvIxGyq7PVoFyEnPpWDM/0CpZvXKHpQ6qMTkfNt517qVqUTAwsIYqNS8xazcKAqkNbvU1V49n65Q==}
cpu: [x64]
os: [darwin]
requiresBuild: true
dev: true
optional: true
/turbo-darwin-arm64/1.6.3:
resolution: {integrity: sha512-75DXhFpwE7CinBbtxTxH08EcWrxYSPFow3NaeFwsG8aymkWXF+U2aukYHJA6I12n9/dGqf7yRXzkF0S/9UtdyQ==}
/turbo-darwin-arm64/1.8.8:
resolution: {integrity: sha512-ruGRI9nHxojIGLQv1TPgN7ud4HO4V8mFBwSgO6oDoZTNuk5ybWybItGR+yu6fni5vJoyMHXOYA2srnxvOc7hjQ==}
cpu: [arm64]
os: [darwin]
requiresBuild: true
dev: true
optional: true
/turbo-linux-64/1.6.3:
resolution: {integrity: sha512-O9uc6J0yoRPWdPg9THRQi69K6E2iZ98cRHNvus05lZbcPzZTxJYkYGb5iagCmCW/pq6fL4T4oLWAd6evg2LGQA==}
/turbo-linux-64/1.8.8:
resolution: {integrity: sha512-N/GkHTHeIQogXB1/6ZWfxHx+ubYeb8Jlq3b/3jnU4zLucpZzTQ8XkXIAfJG/TL3Q7ON7xQ8yGOyGLhHL7MpFRg==}
cpu: [x64]
os: [linux]
requiresBuild: true
dev: true
optional: true
/turbo-linux-arm64/1.6.3:
resolution: {integrity: sha512-dCy667qqEtZIhulsRTe8hhWQNCJO0i20uHXv7KjLHuFZGCeMbWxB8rsneRoY+blf8+QNqGuXQJxak7ayjHLxiA==}
/turbo-linux-arm64/1.8.8:
resolution: {integrity: sha512-hKqLbBHgUkYf2Ww8uBL9UYdBFQ5677a7QXdsFhONXoACbDUPvpK4BKlz3NN7G4NZ+g9dGju+OJJjQP0VXRHb5w==}
cpu: [arm64]
os: [linux]
requiresBuild: true
dev: true
optional: true
/turbo-windows-64/1.6.3:
resolution: {integrity: sha512-lKRqwL3mrVF09b9KySSaOwetehmGknV9EcQTF7d2dxngGYYX1WXoQLjFP9YYH8ZV07oPm+RUOAKSCQuDuMNhiA==}
/turbo-windows-64/1.8.8:
resolution: {integrity: sha512-2ndjDJyzkNslXxLt+PQuU21AHJWc8f6MnLypXy3KsN4EyX/uKKGZS0QJWz27PeHg0JS75PVvhfFV+L9t9i+Yyg==}
cpu: [x64]
os: [win32]
requiresBuild: true
dev: true
optional: true
/turbo-windows-arm64/1.6.3:
resolution: {integrity: sha512-BXY1sDPEA1DgPwuENvDCD8B7Hb0toscjus941WpL8CVd10hg9pk/MWn9CNgwDO5Q9ks0mw+liDv2EMnleEjeNA==}
/turbo-windows-arm64/1.8.8:
resolution: {integrity: sha512-xCA3oxgmW9OMqpI34AAmKfOVsfDljhD5YBwgs0ZDsn5h3kCHhC4x9W5dDk1oyQ4F5EXSH3xVym5/xl1J6WRpUg==}
cpu: [arm64]
os: [win32]
requiresBuild: true
dev: true
optional: true
/turbo/1.6.3:
resolution: {integrity: sha512-FtfhJLmEEtHveGxW4Ye/QuY85AnZ2ZNVgkTBswoap7UMHB1+oI4diHPNyqrQLG4K1UFtCkjOlVoLsllUh/9QRw==}
/turbo/1.8.8:
resolution: {integrity: sha512-qYJ5NjoTX+591/x09KgsDOPVDUJfU9GoS+6jszQQlLp1AHrf1wRFA3Yps8U+/HTG03q0M4qouOfOLtRQP4QypA==}
hasBin: true
requiresBuild: true
optionalDependencies:
turbo-darwin-64: 1.6.3
turbo-darwin-arm64: 1.6.3
turbo-linux-64: 1.6.3
turbo-linux-arm64: 1.6.3
turbo-windows-64: 1.6.3
turbo-windows-arm64: 1.6.3
turbo-darwin-64: 1.8.8
turbo-darwin-arm64: 1.8.8
turbo-linux-64: 1.8.8
turbo-linux-arm64: 1.8.8
turbo-windows-64: 1.8.8
turbo-windows-arm64: 1.8.8
dev: true
/tweetnacl/0.14.5:

View File

@@ -51,7 +51,26 @@
"env": ["UPSTASH_REDIS_KEY", "UPSTASH_REDIS_URL"]
},
"docs#dev": {
"dependsOn": ["^build"],
"dependsOn": [
"@auth/core#build",
"@auth/sveltekit#build",
"@next-auth/dgraph-adapter#build",
"@next-auth/dynamodb-adapter#build",
"@next-auth/fauna-adapter#build",
"@next-auth/firebase-adapter#build",
"@next-auth/mikro-orm-adapter#build",
"@next-auth/mongodb-adapter#build",
"@next-auth/neo4j-adapter#build",
"@next-auth/pouchdb-adapter#build",
"@next-auth/prisma-adapter#build",
"@next-auth/sequelize-adapter#build",
"@next-auth/supabase-adapter#build",
"@next-auth/typeorm-legacy-adapter#build",
"@next-auth/upstash-redis-adapter#build",
"@next-auth/xata-adapter#build",
"^build",
"next-auth#build"
],
"cache": false
},
"docs#build": {
@@ -72,6 +91,7 @@
"@next-auth/typeorm-legacy-adapter#build",
"@next-auth/upstash-redis-adapter#build",
"@next-auth/xata-adapter#build",
"^build",
"next-auth#build"
],
"outputs": [