mirror of
https://github.com/SrIzan10/next-auth.git
synced 2026-05-01 10:55:20 +00:00
Compare commits
30 Commits
@auth/soli
...
ndom91/doc
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
623a6e97ca | ||
|
|
f7d964d0b9 | ||
|
|
dd4170cf08 | ||
|
|
b85b5aa5f6 | ||
|
|
d77b97c9fc | ||
|
|
e3cfef3c8f | ||
|
|
50118f305a | ||
|
|
e250dceb38 | ||
|
|
0a1b6eb63b | ||
|
|
0c76c5a5a6 | ||
|
|
26e2f795d8 | ||
|
|
d5eade5ef4 | ||
|
|
2fab7d4cd1 | ||
|
|
177fa44a49 | ||
|
|
92657bade3 | ||
|
|
581d37b50f | ||
|
|
1a928949ce | ||
|
|
8f222b2e56 | ||
|
|
01a78e1282 | ||
|
|
be481e6fe6 | ||
|
|
e1f5fe3e6d | ||
|
|
40f754fbca | ||
|
|
cf236c6bf3 | ||
|
|
b7a38ec7b1 | ||
|
|
db26a4c18d | ||
|
|
42b55f44f4 | ||
|
|
1d3761356a | ||
|
|
79147f1cf5 | ||
|
|
caf63f0eb4 | ||
|
|
7dec2eec71 |
74
.eslintignore
Normal file
74
.eslintignore
Normal file
@@ -0,0 +1,74 @@
|
||||
.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/pages/reference/core
|
||||
docs/pages/reference/sveltekit
|
||||
docs/pages/reference/adapter
|
||||
static
|
||||
|
||||
# TODO: Enable
|
||||
docs-nextra
|
||||
|
||||
# --------------- 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*
|
||||
75
.eslintrc.js
Normal file
75
.eslintrc.js
Normal file
@@ -0,0 +1,75 @@
|
||||
// @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,
|
||||
}
|
||||
33
.github/DISCUSSION_TEMPLATE/ideas.yml
vendored
33
.github/DISCUSSION_TEMPLATE/ideas.yml
vendored
@@ -1,33 +0,0 @@
|
||||
body:
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Goals
|
||||
description: Short list of what the feature request aims to address?
|
||||
value: |
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Non-Goals
|
||||
description: Short list of what the feature request _does not_ aim to address?
|
||||
value: |
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Background
|
||||
description: Discuss prior art, why do you think this feature is needed? Are there current alternatives?
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Proposal
|
||||
description: How should this feature be implemented? Are you interested in contributing?
|
||||
validations:
|
||||
required: true
|
||||
20
.github/DISCUSSION_TEMPLATE/questions.yml
vendored
20
.github/DISCUSSION_TEMPLATE/questions.yml
vendored
@@ -1,20 +0,0 @@
|
||||
body:
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Summary
|
||||
description: What do you need help with?
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Additional information
|
||||
description: Any code snippets, error messages, or dependency details that may be related?
|
||||
render: js
|
||||
validations:
|
||||
required: false
|
||||
- type: input
|
||||
attributes:
|
||||
label: Example
|
||||
description: A link to a minimal reproduction is helpful for collaborative debugging!
|
||||
validations:
|
||||
required: false
|
||||
4
.github/ISSUE_TEMPLATE/1_bug_framework.yml
vendored
4
.github/ISSUE_TEMPLATE/1_bug_framework.yml
vendored
@@ -1,6 +1,6 @@
|
||||
name: Bug report
|
||||
description: Report an issue so we can improve
|
||||
labels: [triage, bug]
|
||||
labels: [triage]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
@@ -11,7 +11,7 @@ body:
|
||||
|
||||
### Important :exclamation:
|
||||
|
||||
_Providing incorrect/insufficient information or skipping steps to reproduce the issue will result in closing the issue and/or converting to a discussion without further explanation._
|
||||
_Providing incorrect/insufficient information or skipping steps to reproduce the issue may result in closing the issue or converting to a discussion without further explanation._
|
||||
|
||||
If you have a generic question specific to your project, it is best asked in Discussions under the [Questions category](https://github.com/nextauthjs/next-auth/discussions/new?category=Questions)
|
||||
# Let's wait with this until adoption in other frameworks.
|
||||
|
||||
8
.github/ISSUE_TEMPLATE/2_bug_provider.yml
vendored
8
.github/ISSUE_TEMPLATE/2_bug_provider.yml
vendored
@@ -1,6 +1,6 @@
|
||||
name: Bug report (Provider)
|
||||
description: Create a provider-specific report
|
||||
labels: [triage, bug, providers]
|
||||
labels: [triage, providers]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
@@ -31,17 +31,13 @@ body:
|
||||
- "Authentik"
|
||||
- "Azure Active Directory"
|
||||
- "Azure Active Directory B2C"
|
||||
- "Azure DevOps"
|
||||
- "Battlenet"
|
||||
- "Beyond Identity"
|
||||
- "Box"
|
||||
- "Bungie"
|
||||
- "ClickUp"
|
||||
- "Cognito"
|
||||
- "Coinbase"
|
||||
- "Descope"
|
||||
- "Discord"
|
||||
- "Dribbble"
|
||||
- "Dropbox"
|
||||
- "EVE Online"
|
||||
- "Facebook"
|
||||
@@ -60,7 +56,6 @@ body:
|
||||
- "LinkedIn"
|
||||
- "Mailchimp"
|
||||
- "Mail.ru"
|
||||
- "Mastodon"
|
||||
- "Medium"
|
||||
- "Naver"
|
||||
- "Netlify"
|
||||
@@ -76,7 +71,6 @@ body:
|
||||
- "Slack"
|
||||
- "Spotify"
|
||||
- "Strava"
|
||||
- "Tiktok"
|
||||
- "Todoist"
|
||||
- "Trakt"
|
||||
- "Twitch"
|
||||
|
||||
36
.github/ISSUE_TEMPLATE/3_bug_adapter.yml
vendored
36
.github/ISSUE_TEMPLATE/3_bug_adapter.yml
vendored
@@ -1,6 +1,6 @@
|
||||
name: Bug report (Adapter)
|
||||
description: Create an adapter-specific report
|
||||
labels: [triage, bug, adapters]
|
||||
labels: [triage, adapters]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
@@ -21,26 +21,20 @@ body:
|
||||
multiple: true
|
||||
options:
|
||||
- "Custom adapter"
|
||||
- "@auth/azure-tables-adapter"
|
||||
- "@auth/edgedb-adapter"
|
||||
- "@auth/d1-adapter"
|
||||
- "@auth/dgraph-adapter"
|
||||
- "@auth/drizzle-adapter"
|
||||
- "@auth/dynamodb-adapter"
|
||||
- "@auth/fauna-adapter"
|
||||
- "@auth/firebase-adapter"
|
||||
- "@auth/kysely-adapter"
|
||||
- "@auth/mikro-orm-adapter"
|
||||
- "@auth/mongodb-adapter"
|
||||
- "@auth/neo4j-adapter"
|
||||
- "@auth/pg-adapter"
|
||||
- "@auth/pouchdb-adapter"
|
||||
- "@auth/prisma-adapter"
|
||||
- "@auth/sequelize-adapter"
|
||||
- "@auth/supabase-adapter"
|
||||
- "@auth/typeorm-adapter"
|
||||
- "@auth/upstash-redis-adapter"
|
||||
- "@auth/xata-adapter"
|
||||
- "@next-auth/dgraph-adapter"
|
||||
- "@next-auth/dynamodb-adapter"
|
||||
- "@next-auth/fauna-adapter"
|
||||
- "@next-auth/firebase-adapter"
|
||||
- "@next-auth/mikro-orm-adapter"
|
||||
- "@next-auth/mongodb-adapter"
|
||||
- "@next-auth/neo4j-adapter"
|
||||
- "@next-auth/pouchdb-adapter"
|
||||
- "@next-auth/prisma-adapter"
|
||||
- "@next-auth/sequelize-adapter"
|
||||
- "@next-auth/supabase-adapter"
|
||||
- "@next-auth/typeorm-legacy-adapter"
|
||||
- "@next-auth/upstash-redis-adapter"
|
||||
- "@next-auth/xata-adapter"
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
|
||||
72
.github/ISSUE_TEMPLATE/5_feature_request.yml
vendored
Normal file
72
.github/ISSUE_TEMPLATE/5_feature_request.yml
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
name: Feature Request
|
||||
description: Suggest an idea for NextAuth.js
|
||||
labels: [triage, enhancement]
|
||||
|
||||
# note: markdown sections will NOT appear as part of the issue as per documentation, rather they provide context to the user
|
||||
# https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-githubs-form-schema#markdown
|
||||
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
**NOTE:** Issues that are potentially security related should be reported to us by following the [Security guidelines](https://next-auth.js.org/security) rather than on GitHub.
|
||||
Thank you very much for reaching out to us regarding the awesome feature that you believe should be included in the NextAuth.js library.
|
||||
|
||||
_NOTE: Feature requests are converted to [discussions (Ideas 💡)](https://github.com/nextauthjs/next-auth/discussions/categories/ideas). Make sure your idea hasn't been asked yet, and upvote the existing one before opening a new instead._
|
||||
|
||||
### Important :exclamation:
|
||||
|
||||
Please proceed by providing the following information:
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Description 📓
|
||||
description: Please provide a more in-depth description of the feature proposed.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Make sure you provide plenty of [links]() to external documentation and inline code examples like so:
|
||||
|
||||
```js
|
||||
function myAwesomeNextAuthFeature() {
|
||||
return 💚
|
||||
}
|
||||
```
|
||||
|
||||
Take time thinking about what you want to say and help us understand your proposal making sure that this description contains:
|
||||
|
||||
- **purpose of the feature**
|
||||
- **potential problems**
|
||||
- **potential alternatives**
|
||||
|
||||
- type: textarea
|
||||
id: reproduction
|
||||
attributes:
|
||||
label: How to reproduce ☕️
|
||||
description: If you have a CodeSandbox playground or some code snippets to help us visualize your idea better, please provide it here.
|
||||
validations:
|
||||
required: true
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
You can use one of the templates set up on **CodeSandbox** to better illustrate your idea:
|
||||
|
||||
- [`next-auth-example`](https://codesandbox.io/s/next-auth-example-1kktb)
|
||||
|
||||
- type: dropdown
|
||||
id: pr
|
||||
attributes:
|
||||
label: Contributing 🙌🏽
|
||||
multiple: false
|
||||
options:
|
||||
- "Yes, I am willing to help implement this feature in a PR"
|
||||
- "No, I am afraid I cannot help regarding this"
|
||||
validations:
|
||||
required: true
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
It takes a lot of work 🏋🏻♀️ maintaining a library like `next-auth`; any contribution is more than welcome 💚
|
||||
57
.github/ISSUE_TEMPLATE/6_typescript.yml
vendored
Normal file
57
.github/ISSUE_TEMPLATE/6_typescript.yml
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
name: TypeScript
|
||||
description: Ask a question about NextAuth.js TypeScript integration
|
||||
labels: [question, TypeScript]
|
||||
assignees: [lluia, balazsorban44]
|
||||
|
||||
# note: markdown sections will NOT appear as part of the issue as per documentation, rather they provide context to the user
|
||||
# https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-githubs-form-schema#markdown
|
||||
|
||||
body:
|
||||
- type: textarea
|
||||
id: question
|
||||
attributes:
|
||||
label: Question 💬
|
||||
description: Please provide an in-depth description of the question you have when using NextAuth.js on a Typescript project or when consuming the built-in types for `next-auth`.
|
||||
validations:
|
||||
required: true
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
**NOTE:** Issues that are potentially security related should be reported to us by following the [Security guidelines](https://next-auth.js.org/security) rather than on GitHub.
|
||||
Make sure you [link]() to external documentation if necessary and provide inline code examples like so:
|
||||
|
||||
```js
|
||||
function myAwesomeNextAuthFeature() {
|
||||
return 💚
|
||||
}
|
||||
```
|
||||
|
||||
**NOTE:** Questions will be converted to Discussions. You can find them [here](https://github.com/nextauthjs/next-auth/discussions)!
|
||||
|
||||
- type: textarea
|
||||
id: codesandbox
|
||||
attributes:
|
||||
label: How to reproduce ☕️
|
||||
description: Please provide a link to a minimal reproduction or code snippets that represents your question
|
||||
validations:
|
||||
required: true
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
We encourage you to use the template set-up on **CodeSandbox** as a playground to represent your question or doubt:
|
||||
- [`next-auth-example`](https://codesandbox.io/s/next-auth-example-1kktb)
|
||||
|
||||
- type: dropdown
|
||||
id: pr
|
||||
attributes:
|
||||
label: Contributing 🙌🏽
|
||||
multiple: false
|
||||
options:
|
||||
- "Yes, I am willing to help answer this question in a PR"
|
||||
- "No, I am afraid I cannot help regarding this"
|
||||
validations:
|
||||
required: true
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
It takes a lot of work 🏋🏻♀️ maintaining a library like `next-auth`; any contribution is more than welcome 💚
|
||||
61
.github/ISSUE_TEMPLATE/7_question.yml
vendored
Normal file
61
.github/ISSUE_TEMPLATE/7_question.yml
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
name: Question
|
||||
description: Ask a question about NextAuth.js or for help using it
|
||||
labels: [question]
|
||||
|
||||
# note: markdown sections will NOT appear as part of the issue as per documentation, rather they provide context to the user
|
||||
# https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-githubs-form-schema#markdown
|
||||
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
**NOTE:** Issues that are potentially security related should be reported to us by following the [Security guidelines](https://next-auth.js.org/security) rather than on GitHub.
|
||||
We are glad that you have a question about this library. Please provide the following information:
|
||||
|
||||
- type: textarea
|
||||
id: question
|
||||
attributes:
|
||||
label: Question 💬
|
||||
description: Please provide an in-depth description of the question you have.
|
||||
validations:
|
||||
required: true
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Make sure you [link]() to external documentation if necessary and provide inline code examples like so:
|
||||
|
||||
```js
|
||||
function myAwesomeNextAuthFeature() {
|
||||
return 💚
|
||||
}
|
||||
```
|
||||
|
||||
**NOTE:** Questions will be converted to Discussions. You can find them [here](https://github.com/nextauthjs/next-auth/discussions)!
|
||||
|
||||
- type: textarea
|
||||
id: reproduction
|
||||
attributes:
|
||||
label: How to reproduce ☕️
|
||||
description: Please provide a link to a minimal reproduction or code snippets that represents your question
|
||||
validations:
|
||||
required: true
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
We encourage you to use the template set-up on **CodeSandbox** as a playground to represent your question or doubt:
|
||||
- [`next-auth-example`](https://codesandbox.io/s/next-auth-example-1kktb)
|
||||
|
||||
- type: dropdown
|
||||
id: pr
|
||||
attributes:
|
||||
label: Contributing 🙌🏽
|
||||
multiple: false
|
||||
options:
|
||||
- "Yes, I am willing to help answer this question in a PR"
|
||||
- "No, I am afraid I cannot help regarding this"
|
||||
validations:
|
||||
required: true
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
It takes a lot of work 🏋🏻♀️ maintaining a library like `next-auth`; any contribution is more than welcome 💚
|
||||
7
.github/ISSUE_TEMPLATE/config.yml
vendored
7
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -1,8 +1 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Ask a question
|
||||
url: https://github.com/nextauthjs/next-auth/discussions/new?category=questions
|
||||
about: Ask questions and discuss with other community members
|
||||
- name: Feature request
|
||||
url: https://github.com/nextauthjs/next-auth/discussions/new?category=ideas
|
||||
about: Feature requests should be opened as discussions
|
||||
|
||||
2
.github/actions/issue-validator/.gitignore
vendored
Normal file
2
.github/actions/issue-validator/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
!dist
|
||||
!package-lock.json
|
||||
7
.github/actions/issue-validator/index.mjs
vendored
Normal file
7
.github/actions/issue-validator/index.mjs
vendored
Normal file
File diff suppressed because one or more lines are too long
653
.github/actions/issue-validator/licenses.txt
vendored
Normal file
653
.github/actions/issue-validator/licenses.txt
vendored
Normal file
@@ -0,0 +1,653 @@
|
||||
@actions/core
|
||||
MIT
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright 2019 GitHub
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
@actions/github
|
||||
MIT
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright 2019 GitHub
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
@actions/http-client
|
||||
MIT
|
||||
Actions Http Client for Node.js
|
||||
|
||||
Copyright (c) GitHub, Inc.
|
||||
|
||||
All rights reserved.
|
||||
|
||||
MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
|
||||
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
@octokit/auth-token
|
||||
MIT
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2019 Octokit contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
|
||||
@octokit/core
|
||||
MIT
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2019 Octokit contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
|
||||
@octokit/endpoint
|
||||
MIT
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2018 Octokit contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
|
||||
@octokit/graphql
|
||||
MIT
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2018 Octokit contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
|
||||
@octokit/plugin-paginate-rest
|
||||
MIT
|
||||
MIT License Copyright (c) 2019 Octokit contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
@octokit/plugin-rest-endpoint-methods
|
||||
MIT
|
||||
MIT License Copyright (c) 2019 Octokit contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
@octokit/request
|
||||
MIT
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2018 Octokit contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
|
||||
@octokit/request-error
|
||||
MIT
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2019 Octokit contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
|
||||
@vercel/ncc
|
||||
MIT
|
||||
Copyright 2018 ZEIT, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
before-after-hook
|
||||
Apache-2.0
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright 2018 Gregor Martynus and other contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
|
||||
deprecation
|
||||
ISC
|
||||
The ISC License
|
||||
|
||||
Copyright (c) Gregor Martynus and contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
|
||||
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
|
||||
is-plain-object
|
||||
MIT
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014-2017, Jon Schlinkert.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
|
||||
node-fetch
|
||||
MIT
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 David Frank
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
|
||||
|
||||
once
|
||||
ISC
|
||||
The ISC License
|
||||
|
||||
Copyright (c) Isaac Z. Schlueter and Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
|
||||
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
|
||||
root
|
||||
ISC License
|
||||
|
||||
Copyright (c) 2022-2023, Balázs Orbán
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
|
||||
tr46
|
||||
MIT
|
||||
|
||||
tunnel
|
||||
MIT
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2012 Koichi Kobayashi
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
|
||||
universal-user-agent
|
||||
ISC
|
||||
# [ISC License](https://spdx.org/licenses/ISC)
|
||||
|
||||
Copyright (c) 2018, Gregor Martynus (https://github.com/gr2m)
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
|
||||
uuid
|
||||
MIT
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2010-2020 Robert Kieffer and other contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
webidl-conversions
|
||||
BSD-2-Clause
|
||||
# The BSD 2-Clause License
|
||||
|
||||
Copyright (c) 2014, Domenic Denicola
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
whatwg-url
|
||||
MIT
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015–2016 Sebastian Mayr
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
|
||||
wrappy
|
||||
ISC
|
||||
The ISC License
|
||||
|
||||
Copyright (c) Isaac Z. Schlueter and Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
|
||||
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
445
.github/actions/issue-validator/package-lock.json
generated
vendored
Normal file
445
.github/actions/issue-validator/package-lock.json
generated
vendored
Normal file
@@ -0,0 +1,445 @@
|
||||
{
|
||||
"name": "issue-validator",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"dependencies": {
|
||||
"@actions/core": "1.10.0",
|
||||
"@actions/github": "5.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vercel/ncc": "0.34.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@actions/core": {
|
||||
"version": "1.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.10.0.tgz",
|
||||
"integrity": "sha512-2aZDDa3zrrZbP5ZYg159sNoLRb61nQ7awl5pSvIq5Qpj81vwDzdMRKzkWJGJuwVvWpvZKx7vspJALyvaaIQyug==",
|
||||
"dependencies": {
|
||||
"@actions/http-client": "^2.0.1",
|
||||
"uuid": "^8.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@actions/github": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@actions/github/-/github-5.1.1.tgz",
|
||||
"integrity": "sha512-Nk59rMDoJaV+mHCOJPXuvB1zIbomlKS0dmSIqPGxd0enAXBnOfn4VWF+CGtRCwXZG9Epa54tZA7VIRlJDS8A6g==",
|
||||
"dependencies": {
|
||||
"@actions/http-client": "^2.0.1",
|
||||
"@octokit/core": "^3.6.0",
|
||||
"@octokit/plugin-paginate-rest": "^2.17.0",
|
||||
"@octokit/plugin-rest-endpoint-methods": "^5.13.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@actions/http-client": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.0.1.tgz",
|
||||
"integrity": "sha512-PIXiMVtz6VvyaRsGY268qvj57hXQEpsYogYOu2nrQhlf+XCGmZstmuZBbAybUl1nQGnvS1k1eEsQ69ZoD7xlSw==",
|
||||
"dependencies": {
|
||||
"tunnel": "^0.0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/auth-token": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz",
|
||||
"integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^6.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/core": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.6.0.tgz",
|
||||
"integrity": "sha512-7RKRKuA4xTjMhY+eG3jthb3hlZCsOwg3rztWh75Xc+ShDWOfDDATWbeZpAHBNRpm4Tv9WgBMOy1zEJYXG6NJ7Q==",
|
||||
"dependencies": {
|
||||
"@octokit/auth-token": "^2.4.4",
|
||||
"@octokit/graphql": "^4.5.8",
|
||||
"@octokit/request": "^5.6.3",
|
||||
"@octokit/request-error": "^2.0.5",
|
||||
"@octokit/types": "^6.0.3",
|
||||
"before-after-hook": "^2.2.0",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/endpoint": {
|
||||
"version": "6.0.12",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz",
|
||||
"integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^6.0.3",
|
||||
"is-plain-object": "^5.0.0",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/graphql": {
|
||||
"version": "4.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz",
|
||||
"integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==",
|
||||
"dependencies": {
|
||||
"@octokit/request": "^5.6.0",
|
||||
"@octokit/types": "^6.0.3",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/openapi-types": {
|
||||
"version": "12.10.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-12.10.1.tgz",
|
||||
"integrity": "sha512-P+SukKanjFY0ZhsK6wSVnQmxTP2eVPPE8OPSNuxaMYtgVzwJZgfGdwlYjf4RlRU4vLEw4ts2fsE2icG4nZ5ddQ=="
|
||||
},
|
||||
"node_modules/@octokit/plugin-paginate-rest": {
|
||||
"version": "2.21.3",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.21.3.tgz",
|
||||
"integrity": "sha512-aCZTEf0y2h3OLbrgKkrfFdjRL6eSOo8komneVQJnYecAxIej7Bafor2xhuDJOIFau4pk0i/P28/XgtbyPF0ZHw==",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^6.40.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@octokit/core": ">=2"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/plugin-rest-endpoint-methods": {
|
||||
"version": "5.16.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.16.2.tgz",
|
||||
"integrity": "sha512-8QFz29Fg5jDuTPXVtey05BLm7OB+M8fnvE64RNegzX7U+5NUXcOcnpTIK0YfSHBg8gYd0oxIq3IZTe9SfPZiRw==",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^6.39.0",
|
||||
"deprecation": "^2.3.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@octokit/core": ">=3"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/request": {
|
||||
"version": "5.6.3",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.3.tgz",
|
||||
"integrity": "sha512-bFJl0I1KVc9jYTe9tdGGpAMPy32dLBXXo1dS/YwSCTL/2nd9XeHsY616RE3HPXDVk+a+dBuzyz5YdlXwcDTr2A==",
|
||||
"dependencies": {
|
||||
"@octokit/endpoint": "^6.0.1",
|
||||
"@octokit/request-error": "^2.1.0",
|
||||
"@octokit/types": "^6.16.1",
|
||||
"is-plain-object": "^5.0.0",
|
||||
"node-fetch": "^2.6.7",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/request-error": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz",
|
||||
"integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^6.0.3",
|
||||
"deprecation": "^2.0.0",
|
||||
"once": "^1.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/types": {
|
||||
"version": "6.40.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.40.0.tgz",
|
||||
"integrity": "sha512-MFZOU5r8SwgJWDMhrLUSvyJPtVsqA6VnbVI3TNbsmw+Jnvrktzvq2fYES/6RiJA/5Ykdwq4mJmtlYUfW7CGjmw==",
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": "^12.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@vercel/ncc": {
|
||||
"version": "0.34.0",
|
||||
"resolved": "https://registry.npmjs.org/@vercel/ncc/-/ncc-0.34.0.tgz",
|
||||
"integrity": "sha512-G9h5ZLBJ/V57Ou9vz5hI8pda/YQX5HQszCs3AmIus3XzsmRn/0Ptic5otD3xVST8QLKk7AMk7AqpsyQGN7MZ9A==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"ncc": "dist/ncc/cli.js"
|
||||
}
|
||||
},
|
||||
"node_modules/before-after-hook": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.2.tgz",
|
||||
"integrity": "sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ=="
|
||||
},
|
||||
"node_modules/deprecation": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz",
|
||||
"integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ=="
|
||||
},
|
||||
"node_modules/is-plain-object": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
|
||||
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/node-fetch": {
|
||||
"version": "2.6.7",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
|
||||
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
|
||||
"dependencies": {
|
||||
"whatwg-url": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "4.x || >=6.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"encoding": "^0.1.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"encoding": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
|
||||
"dependencies": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"node_modules/tr46": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
||||
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
|
||||
},
|
||||
"node_modules/tunnel": {
|
||||
"version": "0.0.6",
|
||||
"resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
|
||||
"integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==",
|
||||
"engines": {
|
||||
"node": ">=0.6.11 <=0.7.0 || >=0.7.3"
|
||||
}
|
||||
},
|
||||
"node_modules/universal-user-agent": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz",
|
||||
"integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w=="
|
||||
},
|
||||
"node_modules/uuid": {
|
||||
"version": "8.3.2",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
|
||||
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
|
||||
"bin": {
|
||||
"uuid": "dist/bin/uuid"
|
||||
}
|
||||
},
|
||||
"node_modules/webidl-conversions": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
||||
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
|
||||
},
|
||||
"node_modules/whatwg-url": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
||||
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
|
||||
"dependencies": {
|
||||
"tr46": "~0.0.3",
|
||||
"webidl-conversions": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@actions/core": {
|
||||
"version": "1.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.10.0.tgz",
|
||||
"integrity": "sha512-2aZDDa3zrrZbP5ZYg159sNoLRb61nQ7awl5pSvIq5Qpj81vwDzdMRKzkWJGJuwVvWpvZKx7vspJALyvaaIQyug==",
|
||||
"requires": {
|
||||
"@actions/http-client": "^2.0.1",
|
||||
"uuid": "^8.3.2"
|
||||
}
|
||||
},
|
||||
"@actions/github": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@actions/github/-/github-5.1.1.tgz",
|
||||
"integrity": "sha512-Nk59rMDoJaV+mHCOJPXuvB1zIbomlKS0dmSIqPGxd0enAXBnOfn4VWF+CGtRCwXZG9Epa54tZA7VIRlJDS8A6g==",
|
||||
"requires": {
|
||||
"@actions/http-client": "^2.0.1",
|
||||
"@octokit/core": "^3.6.0",
|
||||
"@octokit/plugin-paginate-rest": "^2.17.0",
|
||||
"@octokit/plugin-rest-endpoint-methods": "^5.13.0"
|
||||
}
|
||||
},
|
||||
"@actions/http-client": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.0.1.tgz",
|
||||
"integrity": "sha512-PIXiMVtz6VvyaRsGY268qvj57hXQEpsYogYOu2nrQhlf+XCGmZstmuZBbAybUl1nQGnvS1k1eEsQ69ZoD7xlSw==",
|
||||
"requires": {
|
||||
"tunnel": "^0.0.6"
|
||||
}
|
||||
},
|
||||
"@octokit/auth-token": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz",
|
||||
"integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==",
|
||||
"requires": {
|
||||
"@octokit/types": "^6.0.3"
|
||||
}
|
||||
},
|
||||
"@octokit/core": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.6.0.tgz",
|
||||
"integrity": "sha512-7RKRKuA4xTjMhY+eG3jthb3hlZCsOwg3rztWh75Xc+ShDWOfDDATWbeZpAHBNRpm4Tv9WgBMOy1zEJYXG6NJ7Q==",
|
||||
"requires": {
|
||||
"@octokit/auth-token": "^2.4.4",
|
||||
"@octokit/graphql": "^4.5.8",
|
||||
"@octokit/request": "^5.6.3",
|
||||
"@octokit/request-error": "^2.0.5",
|
||||
"@octokit/types": "^6.0.3",
|
||||
"before-after-hook": "^2.2.0",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"@octokit/endpoint": {
|
||||
"version": "6.0.12",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz",
|
||||
"integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==",
|
||||
"requires": {
|
||||
"@octokit/types": "^6.0.3",
|
||||
"is-plain-object": "^5.0.0",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"@octokit/graphql": {
|
||||
"version": "4.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz",
|
||||
"integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==",
|
||||
"requires": {
|
||||
"@octokit/request": "^5.6.0",
|
||||
"@octokit/types": "^6.0.3",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"@octokit/openapi-types": {
|
||||
"version": "12.10.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-12.10.1.tgz",
|
||||
"integrity": "sha512-P+SukKanjFY0ZhsK6wSVnQmxTP2eVPPE8OPSNuxaMYtgVzwJZgfGdwlYjf4RlRU4vLEw4ts2fsE2icG4nZ5ddQ=="
|
||||
},
|
||||
"@octokit/plugin-paginate-rest": {
|
||||
"version": "2.21.3",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.21.3.tgz",
|
||||
"integrity": "sha512-aCZTEf0y2h3OLbrgKkrfFdjRL6eSOo8komneVQJnYecAxIej7Bafor2xhuDJOIFau4pk0i/P28/XgtbyPF0ZHw==",
|
||||
"requires": {
|
||||
"@octokit/types": "^6.40.0"
|
||||
}
|
||||
},
|
||||
"@octokit/plugin-rest-endpoint-methods": {
|
||||
"version": "5.16.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.16.2.tgz",
|
||||
"integrity": "sha512-8QFz29Fg5jDuTPXVtey05BLm7OB+M8fnvE64RNegzX7U+5NUXcOcnpTIK0YfSHBg8gYd0oxIq3IZTe9SfPZiRw==",
|
||||
"requires": {
|
||||
"@octokit/types": "^6.39.0",
|
||||
"deprecation": "^2.3.1"
|
||||
}
|
||||
},
|
||||
"@octokit/request": {
|
||||
"version": "5.6.3",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.3.tgz",
|
||||
"integrity": "sha512-bFJl0I1KVc9jYTe9tdGGpAMPy32dLBXXo1dS/YwSCTL/2nd9XeHsY616RE3HPXDVk+a+dBuzyz5YdlXwcDTr2A==",
|
||||
"requires": {
|
||||
"@octokit/endpoint": "^6.0.1",
|
||||
"@octokit/request-error": "^2.1.0",
|
||||
"@octokit/types": "^6.16.1",
|
||||
"is-plain-object": "^5.0.0",
|
||||
"node-fetch": "^2.6.7",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"@octokit/request-error": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz",
|
||||
"integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==",
|
||||
"requires": {
|
||||
"@octokit/types": "^6.0.3",
|
||||
"deprecation": "^2.0.0",
|
||||
"once": "^1.4.0"
|
||||
}
|
||||
},
|
||||
"@octokit/types": {
|
||||
"version": "6.40.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.40.0.tgz",
|
||||
"integrity": "sha512-MFZOU5r8SwgJWDMhrLUSvyJPtVsqA6VnbVI3TNbsmw+Jnvrktzvq2fYES/6RiJA/5Ykdwq4mJmtlYUfW7CGjmw==",
|
||||
"requires": {
|
||||
"@octokit/openapi-types": "^12.10.0"
|
||||
}
|
||||
},
|
||||
"@vercel/ncc": {
|
||||
"version": "0.34.0",
|
||||
"resolved": "https://registry.npmjs.org/@vercel/ncc/-/ncc-0.34.0.tgz",
|
||||
"integrity": "sha512-G9h5ZLBJ/V57Ou9vz5hI8pda/YQX5HQszCs3AmIus3XzsmRn/0Ptic5otD3xVST8QLKk7AMk7AqpsyQGN7MZ9A==",
|
||||
"dev": true
|
||||
},
|
||||
"before-after-hook": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.2.tgz",
|
||||
"integrity": "sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ=="
|
||||
},
|
||||
"deprecation": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz",
|
||||
"integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ=="
|
||||
},
|
||||
"is-plain-object": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
|
||||
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q=="
|
||||
},
|
||||
"node-fetch": {
|
||||
"version": "2.6.7",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
|
||||
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
|
||||
"requires": {
|
||||
"whatwg-url": "^5.0.0"
|
||||
}
|
||||
},
|
||||
"once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
|
||||
"requires": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"tr46": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
||||
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
|
||||
},
|
||||
"tunnel": {
|
||||
"version": "0.0.6",
|
||||
"resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
|
||||
"integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg=="
|
||||
},
|
||||
"universal-user-agent": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz",
|
||||
"integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w=="
|
||||
},
|
||||
"uuid": {
|
||||
"version": "8.3.2",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
|
||||
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="
|
||||
},
|
||||
"webidl-conversions": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
||||
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
|
||||
},
|
||||
"whatwg-url": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
||||
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
|
||||
"requires": {
|
||||
"tr46": "~0.0.3",
|
||||
"webidl-conversions": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
|
||||
}
|
||||
}
|
||||
}
|
||||
14
.github/actions/issue-validator/package.json
vendored
Normal file
14
.github/actions/issue-validator/package.json
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"private": true,
|
||||
"exports": "./index.mjs",
|
||||
"scripts": {
|
||||
"build": "ncc -m -o . build src/index.mjs --license licenses.txt"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vercel/ncc": "0.34.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@actions/core": "1.10.0",
|
||||
"@actions/github": "5.1.1"
|
||||
}
|
||||
}
|
||||
37
.github/actions/issue-validator/repro.md
vendored
Normal file
37
.github/actions/issue-validator/repro.md
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
We cannot recreate the issue with the provided information. **Please add a reproduction in order for us to be able to investigate.**
|
||||
|
||||
### **Why was this issue marked with the `incomplete` label?**
|
||||
|
||||
To be able to investigate, we need access to a reproduction to identify what triggered the issue. We prefer a link to a public GitHub repository ([template](https://github.com/nextauthjs/next-auth-example)), but you can also use a tool like [CodeSandbox](https://codesandbox.io/s/github/nextauthjs/next-auth-example/tree/main) or [StackBlitz](https://stackblitz.com/fork/github/nextauthjs/next-auth-example).
|
||||
|
||||
To make sure the issue is resolved as quickly as possible, please make sure that the reproduction is as **minimal** as possible. This means that you should **remove unnecessary code, files, and dependencies** that do not contribute to the issue.
|
||||
|
||||
Please test your reproduction against the latest version of NextAuth.js (`next-auth@latest`) to make sure your issue has not already been fixed.
|
||||
|
||||
### **I added a link, why was it still marked?**
|
||||
|
||||
Ensure the link is pointing to a codebase that is accessible (e.g. not a private repository). "[example.com](http://example.com/)", "n/a", "will add later", etc. are not acceptable links -- we need to see a public codebase. See the above section for accepted links.
|
||||
|
||||
### **What happens if I don't provide a sufficient minimal reproduction?**
|
||||
|
||||
Issues with the `incomplete` label that receives no meaningful activity (e.g. new comments with a reproduction link) are closed after 7 days.
|
||||
|
||||
If your issue has _not_ been resolved in that time and it has been closed/locked, please open a new issue with the required reproduction. (It's less likely that we check back on already closed issues.)
|
||||
|
||||
### **I did not open this issue, but it is relevant to me, what can I do to help?**
|
||||
|
||||
Anyone experiencing the same issue is welcome to provide a minimal reproduction following the above steps. Furthermore, you can upvote the issue using the :+1: reaction on the topmost comment (please **do not** comment "I have the same issue" without repro steps). Then, we can sort issues by votes to prioritize.
|
||||
|
||||
### **I think my reproduction is good enough, why aren't you looking into it quicker?**
|
||||
|
||||
We look into every NextAuth.js issue and constantly monitor open issues for new comments.
|
||||
|
||||
However, sometimes we might miss one or two. We apologize, and kindly ask you to refrain from tagging core maintainers, as that will usually not result in increased priority.
|
||||
|
||||
Upvoting issues to show your interest will help us prioritize and address them as quickly as possible. That said, every issue is important to us, and if an issue gets closed by accident, we encourage you to open a new one linking to the old issue and we will look into it.
|
||||
|
||||
### **Useful Resources**
|
||||
|
||||
- [How to create a Minimal, Complete, and Verifiable example](https://stackoverflow.com/help/mcve)
|
||||
- [Reporting a NextAuth.js bug](https://github.com/nextauthjs/next-auth/blob/main/.github/ISSUE_TEMPLATE/1_bug_framework.yml)
|
||||
- [How to Contribute to Open Source (Next.js)](https://www.youtube.com/watch?v=cuoNzXFLitc)
|
||||
91
.github/actions/issue-validator/src/index.mjs
vendored
Normal file
91
.github/actions/issue-validator/src/index.mjs
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
// @ts-check
|
||||
// @ts-expect-error
|
||||
import * as github from "@actions/github"
|
||||
// @ts-expect-error
|
||||
import * as core from "@actions/core"
|
||||
import { readFileSync } from "node:fs"
|
||||
import { join } from "node:path"
|
||||
|
||||
const addReproductionLabel = "incomplete"
|
||||
|
||||
/**
|
||||
* @typedef {{
|
||||
* id :number
|
||||
* node_id :string
|
||||
* url :string
|
||||
* name :string
|
||||
* description :string
|
||||
* color :string
|
||||
* default :boolean
|
||||
* }} Label
|
||||
*
|
||||
* @typedef {{
|
||||
* pull_request: any
|
||||
* issue?: {body: string, number: number, labels: Label[]}
|
||||
* label: Label
|
||||
* }} Payload
|
||||
*
|
||||
* @typedef {{
|
||||
* payload: Payload
|
||||
* repo: any
|
||||
* }} Context
|
||||
*/
|
||||
|
||||
async function run() {
|
||||
try {
|
||||
/** @type {Context} */
|
||||
const { payload, repo } = github.context
|
||||
const {
|
||||
issue,
|
||||
pull_request,
|
||||
label: { name: newLabel },
|
||||
} = payload
|
||||
|
||||
if (pull_request || !issue?.body || !process.env.GITHUB_TOKEN) return
|
||||
|
||||
const labels = issue.labels.map((l) => l.name)
|
||||
// const isBugReport =
|
||||
// labels.includes(bugLabel) || newLabel === bugLabel || !labels.length
|
||||
|
||||
if (
|
||||
// !(isBugReport && issue.number > 43554) &&
|
||||
![addReproductionLabel].includes(newLabel) &&
|
||||
!labels.includes(addReproductionLabel)
|
||||
) {
|
||||
return core.info(
|
||||
"Not a bug report or not manually labeled or already labeled."
|
||||
)
|
||||
}
|
||||
|
||||
const client = github.getOctokit(process.env.GITHUB_TOKEN).rest
|
||||
const issueCommon = { ...repo, issue_number: issue.number }
|
||||
|
||||
if (
|
||||
newLabel === addReproductionLabel
|
||||
// || !hasValidRepro
|
||||
) {
|
||||
await Promise.all([
|
||||
client.issues.addLabels({
|
||||
...issueCommon,
|
||||
labels: [addReproductionLabel],
|
||||
}),
|
||||
client.issues.createComment({
|
||||
...issueCommon,
|
||||
body: readFileSync(
|
||||
join(
|
||||
"/home/runner/work/next-auth/next-auth/.github/actions/issue-validator/repro.md"
|
||||
),
|
||||
"utf8"
|
||||
),
|
||||
}),
|
||||
])
|
||||
return core.info(
|
||||
"Commented on issue, because it did not have a sufficient reproduction."
|
||||
)
|
||||
}
|
||||
} catch (error) {
|
||||
core.setFailed(error.message)
|
||||
}
|
||||
}
|
||||
|
||||
run()
|
||||
51
.github/invalid-reproduction.md
vendored
51
.github/invalid-reproduction.md
vendored
@@ -1,51 +0,0 @@
|
||||
We could not detect a valid reproduction link. **Make sure to follow the bug report template carefully.**
|
||||
|
||||
### Why was this issue closed?
|
||||
|
||||
To be able to investigate, we need access to a reproduction to identify what triggered the issue. We need a link to a **public** GitHub repository. Example: ([NextAuth.js example repository](https://github.com/nextauthjs/next-auth-example)).
|
||||
|
||||
The bug template that you filled out has a section called "Reproduction URL", which is where you should provide the link to the reproduction.
|
||||
|
||||
- If you did not provide a link or the link you provided is not valid, we will close the issue.
|
||||
- If you provide a link to a private repository, we will close the issue.
|
||||
- If you provide a link to a repository but not in the correct section, we will close the issue.
|
||||
|
||||
### What should I do?
|
||||
|
||||
Depending on the reason the issue was closed, you can do the following:
|
||||
|
||||
- If you did not provide a link, please open a new issue with a link to a reproduction.
|
||||
- If you provided a link to a private repository, please open a new issue with a link to a public repository.
|
||||
- If you provided a link to a repository but not in the correct section, please open a new issue with a link to a reproduction in the correct section.
|
||||
|
||||
**In general, assume that we should not go through a lengthy onboarding process at your company code only to be able to verify an issue.**
|
||||
|
||||
### My repository is private and cannot make it public
|
||||
|
||||
In most cases, a private repo will not be a sufficient **minimal reproduction**, as this codebase might contain a lot of unrelated parts that would make our investigation take longer. Please do **not** make it public. Instead, create a new repository using the templates above, adding the relevant code to reproduce the issue. Common things to look out for:
|
||||
|
||||
- Remove any code that is not related to the issue. (pages, API Routes, components, etc.)
|
||||
- Remove any dependencies that are not related to the issue.
|
||||
- Remove any third-party service that would require us to sign up for an account to reproduce the issue.
|
||||
- Remove any environment variables that are not related to the issue.
|
||||
- Remove private packages that we do not have access to.
|
||||
- If the issue is not related to a monorepo specifically, try to reproduce the issue without a complex monorepo setup
|
||||
|
||||
### I did not open this issue, but it is relevant to me, what can I do to help?
|
||||
|
||||
Anyone experiencing the same issue is welcome to provide a minimal reproduction following the above steps by opening a new issue.
|
||||
|
||||
### I think my reproduction is good enough, why aren't you looking into it quickly?
|
||||
|
||||
We look into every issue and monitor open issues for new comments.
|
||||
|
||||
However, sometimes we might miss a few due to the popularity/high traffic of the repository. We apologize, and kindly ask you to refrain from tagging core maintainers, as that will usually not result in increased priority.
|
||||
|
||||
Upvoting issues to show your interest will help us prioritize and address them as quickly as possible. That said, every issue is important to us, and if an issue gets closed by accident, we encourage you to open a new one linking to the old issue and we will look into it.
|
||||
|
||||
### Useful Resources
|
||||
|
||||
- [How to create a Minimal, Complete, and Verifiable example](https://stackoverflow.com/help/mcve)
|
||||
- [Bug report: Framework](https://github.com/nextauthjs/next-auth/issues/new?assignees=&labels=triage&projects=&template=1_bug_framework.yml)
|
||||
- [Bug report: Provider](https://github.com/nextauthjs/next-auth/issues/new?assignees=&labels=triage%2Cproviders&projects=&template=2_bug_provider.yml)
|
||||
- [Bug report: Adapter](https://github.com/nextauthjs/next-auth/issues/new?assignees=&labels=triage%2Cadapters&projects=&template=3_bug_adapter.yml)
|
||||
43
.github/issue-labeler.yml
vendored
Normal file
43
.github/issue-labeler.yml
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
# https://github.com/github/issue-labeler#basic-examples
|
||||
|
||||
dgraph:
|
||||
- "@next-auth/dgraph-adapter"
|
||||
|
||||
dynamodb:
|
||||
- "@next-auth/dynamodb-adapter"
|
||||
|
||||
fauna:
|
||||
- "@next-auth/fauna-adapter"
|
||||
|
||||
firebase:
|
||||
- "@next-auth/firebase-adapter"
|
||||
|
||||
mikro-orm:
|
||||
- "@next-auth/mikro-orm-adapter"
|
||||
|
||||
mongodb:
|
||||
- "@next-auth/mongodb-adapter"
|
||||
|
||||
neo4j:
|
||||
- "@next-auth/neo4j-adapter"
|
||||
|
||||
pouchdb:
|
||||
- "@next-auth/pouchdb-adapter"
|
||||
|
||||
prisma:
|
||||
- "@next-auth/prisma-adapter"
|
||||
|
||||
sequelize:
|
||||
- "@next-auth/sequelize-adapter"
|
||||
|
||||
supabase:
|
||||
- "@next-auth/supabase-adapter"
|
||||
|
||||
typeorm-legacy:
|
||||
- "@next-auth/typeorm-legacy-adapter"
|
||||
|
||||
upstash-redis:
|
||||
- "@next-auth/upstash-redis-adapter"
|
||||
|
||||
xata:
|
||||
- "@next-auth/xata-adapter"
|
||||
11
.github/pr-labeler.yml
vendored
11
.github/pr-labeler.yml
vendored
@@ -1,12 +1,8 @@
|
||||
# https://github.com/actions/labeler#create-githublabeleryml
|
||||
adapters: ["packages/core/src/adapters.ts", "packages/adapter-*/**/*"]
|
||||
core: ["packages/core/src/**/*"]
|
||||
azure-tables: ["packages/adapter-azure-tables/**/*"]
|
||||
edgedb: ["packages/adapter-edgedb/**/*"]
|
||||
d1: ["packages/adapter-d1/**/*"]
|
||||
dgraph: ["packages/adapter-dgraph/**/*"]
|
||||
drizzle: ["packages/adapter-drizzle/**/*"]
|
||||
documentation: ["packages/docs/docs/**/*"]
|
||||
documentation: ["packages/docs/pages/**/*"]
|
||||
dynamodb: ["packages/adapter-dynamodb/**/*"]
|
||||
examples: ["apps/examples/**/*"]
|
||||
fauna: ["packages/adapter-fauna/**/*"]
|
||||
@@ -16,18 +12,15 @@ legacy: ["packages/next-auth/**/*"]
|
||||
mikro-orm: ["packages/adapter-mikro-orm/**/*"]
|
||||
mongodb: ["packages/adapter-mongodb/**/*"]
|
||||
neo4j: ["packages/adapter-neo4j/**/*"]
|
||||
pg: ["packages/adapter-pg/**/*"]
|
||||
playgrounds: ["apps/playgrounds/**/*"]
|
||||
pouchdb: ["packages/adapter-pouchdb/**/*"]
|
||||
prisma: ["packages/adapter-prisma/**/*"]
|
||||
kysely: ["packages/adapter-kysely/**/*"]
|
||||
providers: ["packages/core/src/providers/**/*"]
|
||||
sequelize: ["packages/adapter-sequelize/**/*"]
|
||||
solidjs: ["packages/frameworks-solid-start/**/*"]
|
||||
supabase: ["packages/adapter-supabase/**/*"]
|
||||
surrealdb: ["packages/adapter-surrealdb/**/*"]
|
||||
svelte: ["packages/frameworks-sveltekit/**/*"]
|
||||
test: ["**test**/*"]
|
||||
typeorm: ["packages/adapter-typeorm/**/*"]
|
||||
typeorm-legacy: ["packages/adapter-typeorm-legacy/**/*"]
|
||||
upstash-redis: ["packages/adapter-upstash-redis/**/*"]
|
||||
xata: ["packages/adapter-xata/**/*"]
|
||||
|
||||
9
.github/sync.yml
vendored
9
.github/sync.yml
vendored
@@ -1,3 +1,5 @@
|
||||
# Note that nextauthjs/next-auth-example syncs from the v4 branch
|
||||
|
||||
nextauthjs/sveltekit-auth-example:
|
||||
- source: apps/examples/sveltekit
|
||||
dest: .
|
||||
@@ -18,10 +20,3 @@ nextauthjs/next-auth-gatsby-example:
|
||||
deleteOrphaned: true
|
||||
- .github/FUNDING.yml
|
||||
- LICENSE
|
||||
|
||||
nextauthjs/next-auth-example:
|
||||
- source: apps/examples/nextjs
|
||||
dest: .
|
||||
deleteOrphaned: true
|
||||
- .github/FUNDING.yml
|
||||
- LICENSE
|
||||
|
||||
2
.github/version-pr/action.yml
vendored
2
.github/version-pr/action.yml
vendored
@@ -4,5 +4,5 @@ outputs:
|
||||
version:
|
||||
description: "npm package version"
|
||||
runs:
|
||||
using: "node20"
|
||||
using: "node16"
|
||||
main: "index.js"
|
||||
|
||||
9
.github/version-pr/index.js
vendored
9
.github/version-pr/index.js
vendored
@@ -5,15 +5,14 @@ const core = require("@actions/core")
|
||||
try {
|
||||
const packageJSONPath = path.join(
|
||||
process.cwd(),
|
||||
`packages/${process.env.PACKAGE_PATH || "next-auth"}/package.json`
|
||||
"packages/next-auth/package.json"
|
||||
)
|
||||
const packageJSON = JSON.parse(fs.readFileSync(packageJSONPath, "utf8"))
|
||||
|
||||
const sha8 = process.env.GITHUB_SHA.substring(0, 8)
|
||||
const prefix = "0.0.0-"
|
||||
const pr = process.env.PR_NUMBER
|
||||
const source = pr ? `pr.${pr}` : "manual"
|
||||
const packageVersion = `${prefix}${source}.${sha8}`
|
||||
const prNumber = process.env.PR_NUMBER
|
||||
|
||||
const packageVersion = `0.0.0-pr.${prNumber}.${sha8}`
|
||||
packageJSON.version = packageVersion
|
||||
core.setOutput("version", packageVersion)
|
||||
fs.writeFileSync(packageJSONPath, JSON.stringify(packageJSON))
|
||||
|
||||
18
.github/workflows/issue-labeler.yml
vendored
Normal file
18
.github/workflows/issue-labeler.yml
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
# https://github.com/github/issue-labeler#create-workflow
|
||||
|
||||
name: Label issues
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [opened]
|
||||
|
||||
jobs:
|
||||
triage:
|
||||
name: Triage
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: github/issue-labeler@v2.5
|
||||
with:
|
||||
repo-token: "${{ secrets.GITHUB_TOKEN }}"
|
||||
configuration-path: ".github/issue-labeler.yml"
|
||||
enable-versioned-regex: 0
|
||||
17
.github/workflows/issue-validator.yml
vendored
Normal file
17
.github/workflows/issue-validator.yml
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
name: Validate issue
|
||||
on:
|
||||
issues:
|
||||
types: [labeled]
|
||||
|
||||
jobs:
|
||||
validate:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18
|
||||
- name: Run issue validator
|
||||
run: node /home/runner/work/next-auth/next-auth/.github/actions/issue-validator/index.mjs
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
94
.github/workflows/release.yml
vendored
94
.github/workflows/release.yml
vendored
@@ -8,58 +8,6 @@ on:
|
||||
- next
|
||||
- 3.x
|
||||
pull_request:
|
||||
# TODO: Support latest releases
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
name:
|
||||
type: choice
|
||||
description: Package name (npm)
|
||||
options:
|
||||
- "@auth/core"
|
||||
- "@auth/dgraph-adapter"
|
||||
- "@auth/drizzle-adapter"
|
||||
- "@auth/dynamodb-adapter"
|
||||
- "@auth/fauna-adapter"
|
||||
- "@auth/firebase-adapter"
|
||||
- "@auth/mikro-orm-adapter"
|
||||
- "@auth/mongodb-adapter"
|
||||
- "@auth/neo4j-adapter"
|
||||
- "@auth/pouchdb-adapter"
|
||||
- "@auth/prisma-adapter"
|
||||
- "@auth/sequelize-adapter"
|
||||
- "@auth/supabase-adapter"
|
||||
- "@auth/typeorm-adapter"
|
||||
- "@auth/upstash-redis-adapter"
|
||||
- "@auth/xata-adapter"
|
||||
- "next-auth"
|
||||
# TODO: Infer from package name
|
||||
path:
|
||||
type: choice
|
||||
description: Directory name (packages/*)
|
||||
options:
|
||||
- "core"
|
||||
- "frameworks-nextjs"
|
||||
- "adapter-edgedb"
|
||||
- "adapter-dgraph"
|
||||
- "adapter-drizzle"
|
||||
- "adapter-dynamodb"
|
||||
- "adapter-fauna"
|
||||
- "adapter-firebase"
|
||||
- "adapter-mikro-orm"
|
||||
- "adapter-mongodb"
|
||||
- "adapter-neo4j"
|
||||
- "adapter-pouchdb"
|
||||
- "adapter-prisma"
|
||||
- "adapter-sequelize"
|
||||
- "adapter-supabase"
|
||||
- "adapter-typeorm"
|
||||
- "adapter-upstash-redis"
|
||||
- "adapter-xata"
|
||||
- "next-auth"
|
||||
env:
|
||||
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
|
||||
TURBO_TEAM: ${{ vars.TURBO_TEAM }}
|
||||
FORCE_COLOR: true
|
||||
|
||||
jobs:
|
||||
test:
|
||||
@@ -76,17 +24,16 @@ jobs:
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18
|
||||
cache: "pnpm"
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
- name: Build
|
||||
run: pnpm build
|
||||
- name: Run tests
|
||||
run: pnpm test
|
||||
timeout-minutes: 15
|
||||
env:
|
||||
UPSTASH_REDIS_URL: ${{ secrets.UPSTASH_REDIS_URL }}
|
||||
UPSTASH_REDIS_KEY: ${{ secrets.UPSTASH_REDIS_KEY }}
|
||||
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
|
||||
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
|
||||
# - name: Run E2E tests
|
||||
# if: github.repository == 'nextauthjs/next-auth'
|
||||
# run: pnpm e2e
|
||||
@@ -95,7 +42,7 @@ jobs:
|
||||
# AUTH0_USERNAME: ${{ secrets.AUTH0_USERNAME }}
|
||||
# AUTH0_PASSWORD: ${{ secrets.AUTH0_PASSWORD }}
|
||||
# TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
|
||||
# TURBO_TEAM: ${{ vars.TURBO_TEAM }}
|
||||
# TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
|
||||
# - name: Upload E2E artifacts
|
||||
# if: github.repository == 'nextauthjs/next-auth'
|
||||
# uses: actions/upload-artifact@v3
|
||||
@@ -126,7 +73,6 @@ jobs:
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18
|
||||
cache: "pnpm"
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
- name: Publish to npm and GitHub
|
||||
@@ -151,7 +97,6 @@ jobs:
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18
|
||||
cache: "pnpm"
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
- name: Determine version
|
||||
@@ -177,36 +122,3 @@ jobs:
|
||||
env:
|
||||
VERSION: ${{ steps.determine-version.outputs.version }}
|
||||
GITHUB_TOKEN: ${{ secrets.GH_PAT }}
|
||||
release-manual:
|
||||
name: Publish manually
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event_name == 'workflow_dispatch' }}
|
||||
steps:
|
||||
- name: Init
|
||||
uses: actions/checkout@v3
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@v2.2.4
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18
|
||||
cache: "pnpm"
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
- name: Determine version
|
||||
uses: ./.github/version-pr
|
||||
id: determine-version
|
||||
env:
|
||||
PACKAGE_PATH: ${{ github.event.inputs.path }}
|
||||
- name: Publish to npm
|
||||
run: |
|
||||
pnpm build
|
||||
cd packages/$PACKAGE_PATH
|
||||
echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> .npmrc
|
||||
pnpm publish --no-git-checks --access public --tag experimental
|
||||
echo "🎉 Experimental release published 📦️ on npm: https://npmjs.com/package/${{ github.event.inputs.name }}/v/${{ env.VERSION }}"
|
||||
echo "Install via: pnpm add ${{ github.event.inputs.name }}@${{ env.VERSION }}"
|
||||
env:
|
||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
PACKAGE_PATH: ${{ github.event.inputs.path }}
|
||||
VERSION: ${{ steps.determine-version.outputs.version }}
|
||||
|
||||
24
.github/workflows/triage.yml
vendored
24
.github/workflows/triage.yml
vendored
@@ -1,24 +0,0 @@
|
||||
name: Triage issue
|
||||
on:
|
||||
issues:
|
||||
types: [labeled, opened]
|
||||
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
permissions:
|
||||
issues: write
|
||||
|
||||
jobs:
|
||||
triage:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Nissuer
|
||||
uses: balazsorban44/nissuer@1.5.0
|
||||
with:
|
||||
label-area-prefix: ""
|
||||
label-area-section: "[Provider|Adapter] type(.*)### Environment"
|
||||
label-comments: '{ "incomplete": ".github/invalid-reproduction.md" }'
|
||||
reproduction-link-section: "### Reproduction URL(.*)### Describe the issue"
|
||||
reproduction-invalid-label: "invalid reproduction"
|
||||
reproduction-issue-labels: "bug"
|
||||
13
.gitignore
vendored
13
.gitignore
vendored
@@ -6,8 +6,6 @@
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
packages/*/.npmrc
|
||||
|
||||
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
@@ -40,13 +38,11 @@ packages/next-auth/next
|
||||
packages/*/*.js
|
||||
packages/*/*.d.ts
|
||||
packages/*/*.d.ts.map
|
||||
packages/*/lib
|
||||
|
||||
# Development app
|
||||
apps/dev/src/css
|
||||
apps/dev/prisma/migrations
|
||||
apps/dev/typeorm
|
||||
apps/dev/nextjs-2
|
||||
|
||||
# VS
|
||||
/.vs/slnx.sqlite-journal
|
||||
@@ -67,7 +63,6 @@ packages/adapter-prisma/prisma/dev.db
|
||||
packages/adapter-prisma/prisma/migrations
|
||||
db.sqlite
|
||||
packages/adapter-supabase/supabase/.branches
|
||||
packages/adapter-drizzle/.drizzle
|
||||
|
||||
# Tests
|
||||
coverage
|
||||
@@ -87,8 +82,7 @@ packages/core/src/providers/oauth-types.ts
|
||||
packages/core/lib
|
||||
packages/core/providers
|
||||
packages/core/src/lib/pages/styles.ts
|
||||
docs/docs/reference/core
|
||||
docs/docs/reference/sveltekit
|
||||
docs/pages/reference/core
|
||||
|
||||
|
||||
# SvelteKit
|
||||
@@ -98,9 +92,8 @@ packages/frameworks-sveltekit/.svelte-kit
|
||||
packages/frameworks-sveltekit/package
|
||||
packages/frameworks-sveltekit/vite.config.js.timestamp-*
|
||||
packages/frameworks-sveltekit/vite.config.ts.timestamp-*
|
||||
docs/pages/reference/sveltekit
|
||||
|
||||
# Adapters
|
||||
docs/docs/reference/adapter
|
||||
|
||||
## Drizzle migration folder
|
||||
.drizzle
|
||||
docs/pages/reference/adapter
|
||||
@@ -13,16 +13,14 @@ pnpm-lock.yaml
|
||||
*.d.ts.map
|
||||
|
||||
.svelte-kit
|
||||
.next
|
||||
.nuxt
|
||||
|
||||
# --------------- Docs ---------------
|
||||
|
||||
.docusaurus
|
||||
build
|
||||
docs/docs/reference/core
|
||||
docs/docs/reference/sveltekit
|
||||
static
|
||||
.next
|
||||
docs/pages/reference/core
|
||||
docs/pages/reference/sveltekit
|
||||
docs/pages/reference/adapter
|
||||
docs/providers.json
|
||||
|
||||
# --------------- Packages ---------------
|
||||
|
||||
22
.prettierrc.js
Normal file
22
.prettierrc.js
Normal file
@@ -0,0 +1,22 @@
|
||||
// @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",
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
153
README.md
153
README.md
@@ -1,153 +0,0 @@
|
||||
<p align="center">
|
||||
<br/>
|
||||
<a href="https://authjs.dev" target="_blank"><img width="96px" src="https://authjs.dev/img/logo/logo-sm.png" /></a>
|
||||
<h3 align="center">Auth.js</h3>
|
||||
<p align="center">Authentication for the Web.</p>
|
||||
<p align="center">Open Source. Full Stack. Own Your Data.</p>
|
||||
<p align="center" style="align: center;">
|
||||
<a href="https://npm.im/@auth/prisma-adapter">
|
||||
<img src="https://img.shields.io/badge/TypeScript-blue?style=flat-square" alt="TypeScript" />
|
||||
</a>
|
||||
<a href="https://www.npmtrends.com/next-auth">
|
||||
<img src="https://img.shields.io/npm/dm/next-auth?style=flat-square" alt="Downloads" />
|
||||
</a>
|
||||
<a href="https://github.com/nextauthjs/next-auth/stargazers">
|
||||
<img src="https://img.shields.io/github/stars/nextauthjs/next-auth?style=flat-square" alt="Github Stars" />
|
||||
</a>
|
||||
<a href="https://www.npmjs.com/package/next-auth">
|
||||
<img src="https://img.shields.io/github/v/release/nextauthjs/next-auth?label=latest&style=flat-square" alt="Github Stable Release" />
|
||||
</a>
|
||||
</p>
|
||||
</p>
|
||||
|
||||
Auth.js is a set of open-source packages that are built on Web Standard APIs for authentication in modern applications with any framework on any platform in any JS runtime.
|
||||
|
||||
See [authjs.dev](https://authjs.dev) for our framework-specific libraries, or check out [next-auth.js.org](https://next-auth.js.org) for `next-auth` (Next.js).
|
||||
|
||||
## Features
|
||||
|
||||
### Flexible and easy to use
|
||||
|
||||
- Designed to work with any OAuth service, it supports 2.0+, OIDC
|
||||
- Built-in support for [many popular sign-in services](https://github.com/nextauthjs/next-auth/tree/main/packages/core/src/providers)
|
||||
- Email/Passwordless authentication
|
||||
- Bring Your Database - or none! - stateless authentication with any backend (Active Directory, LDAP, etc.)
|
||||
- Runtime-agnostic, runs anywhere! (Vercel Edge Functions, Node.js, Serverless, etc.)
|
||||
|
||||
### Own your data
|
||||
|
||||
Auth.js can be used with or without a database.
|
||||
|
||||
- An open-source solution that allows you to keep control of your data
|
||||
- Built-in support for [MySQL, MariaDB, Postgres, Microsoft SQL Server, MongoDB, SQLite, etc.](https://adapters.authjs.dev)
|
||||
- Works great with databases from popular hosting providers
|
||||
|
||||
### Secure by default
|
||||
|
||||
- Promotes the use of passwordless sign-in mechanisms
|
||||
- Designed to be secure by default and encourage best practices for safeguarding user data
|
||||
- Uses Cross-Site Request Forgery (CSRF) Tokens on POST routes (sign in, sign out)
|
||||
- Default cookie policy aims for the most restrictive policy appropriate for each cookie
|
||||
- When JSON Web Tokens are used, they are encrypted by default (JWE) with A256GCM
|
||||
- Features tab/window syncing and session polling to support short-lived sessions
|
||||
- Attempts to implement the latest guidance published by [Open Web Application Security Project](https://owasp.org)
|
||||
|
||||
Advanced configuration allows you to define your routines to handle controlling what accounts are allowed to sign in, for encoding and decoding JSON Web Tokens and to set custom cookie security policies and session properties, so you can control who can sign in and how often sessions have to be re-validated.
|
||||
|
||||
### TypeScript
|
||||
|
||||
Auth.js libraries are written with type safety in mind. [Check out the docs](https://authjs.dev/getting-started/typescript) for more information.
|
||||
|
||||
## Security
|
||||
|
||||
If you think you have found a vulnerability (or are not sure) in Auth.js or any of the related packages (i.e. Adapters), we ask you to read our [Security Policy](https://authjs.dev/security) to reach out responsibly. Please do not open Pull Requests/Issues/Discussions before consulting with us.
|
||||
|
||||
## Acknowledgments
|
||||
|
||||
[Auth.js is made possible thanks to all of its contributors.](https://authjs.dev/contributors)
|
||||
|
||||
<a href="https://github.com/nextauthjs/next-auth/graphs/contributors">
|
||||
<img width="500px" src="https://contrib.rocks/image?repo=nextauthjs/next-auth" />
|
||||
</a>
|
||||
<div>
|
||||
<a href="https://vercel.com?utm_source=nextauthjs&utm_campaign=oss"></a>
|
||||
</div>
|
||||
|
||||
### Support
|
||||
|
||||
We have an [OpenCollective](https://opencollective.com/nextauth) for individuals and companies looking to contribute financially to the project!
|
||||
|
||||
<!--sponsors start-->
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td align="center" valign="top">
|
||||
<a href="https://vercel.com" target="_blank">
|
||||
<img width="128px" src="https://avatars.githubusercontent.com/u/14985020?v=4" alt="Vercel Logo" />
|
||||
</a><br />
|
||||
<div>Vercel</div><br />
|
||||
<sub>🥉 Bronze Financial Sponsor <br /> ☁️ Infrastructure Support</sub>
|
||||
</td>
|
||||
<td align="center" valign="top">
|
||||
<a href="https://prisma.io" target="_blank">
|
||||
<img width="128px" src="https://avatars.githubusercontent.com/u/17219288?v=4" alt="Prisma Logo" />
|
||||
</a><br />
|
||||
<div>Prisma</div><br />
|
||||
<sub>🥉 Bronze Financial Sponsor</sub>
|
||||
</td>
|
||||
<td align="center" valign="top">
|
||||
<a href="https://clerk.com" target="_blank">
|
||||
<img width="128px" src="https://avatars.githubusercontent.com/u/49538330?s=200&v=4" alt="Clerk Logo" />
|
||||
</a><br />
|
||||
<div>Clerk</div><br />
|
||||
<sub>🥉 Bronze Financial Sponsor</sub>
|
||||
</td>
|
||||
<td align="center" valign="top">
|
||||
<a href="https://lowdefy.com" target="_blank">
|
||||
<img width="128px" src="https://avatars.githubusercontent.com/u/47087496?s=200&v=4" alt="Lowdefy Logo" />
|
||||
</a><br />
|
||||
<div>Lowdefy</div><br />
|
||||
<sub>🥉 Bronze Financial Sponsor</sub>
|
||||
</td>
|
||||
<td align="center" valign="top">
|
||||
<a href="https://workos.com" target="_blank">
|
||||
<img width="128px" src="https://avatars.githubusercontent.com/u/47638084?s=200&v=4" alt="WorkOS Logo" />
|
||||
</a><br />
|
||||
<div>WorkOS</div><br />
|
||||
<sub>🥉 Bronze Financial Sponsor</sub>
|
||||
</td>
|
||||
<td align="center" valign="top">
|
||||
<a href="https://www.descope.com" target="_blank">
|
||||
<img width="128px" src="https://avatars.githubusercontent.com/u/97479186?v=4" alt="Descope Logo" />
|
||||
</a><br />
|
||||
<div>Descope</div><br />
|
||||
<sub>🥉 Bronze Financial Sponsor</sub>
|
||||
</td>
|
||||
<td align="center" valign="top">
|
||||
<a href="https://checklyhq.com" target="_blank">
|
||||
<img width="128px" src="https://avatars.githubusercontent.com/u/25982255?v=4" alt="Checkly Logo" />
|
||||
</a><br />
|
||||
<div>Checkly</div><br />
|
||||
<sub>☁️ Infrastructure Support</sub>
|
||||
</td>
|
||||
<td align="center" valign="top">
|
||||
<a href="https://superblog.ai/" target="_blank">
|
||||
<img width="128px" src="https://d33wubrfki0l68.cloudfront.net/cdc4a3833bd878933fcc131655878dbf226ac1c5/10cd6/images/logo_bolt_small.png" alt="superblog Logo" />
|
||||
</a><br />
|
||||
<div>superblog</div><br />
|
||||
<sub>☁️ Infrastructure Support</sub>
|
||||
</td>
|
||||
</tr><tr></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<br />
|
||||
<!--sponsors end-->
|
||||
|
||||
## Contributing
|
||||
|
||||
We're open to all community contributions! If you'd like to contribute in any way, please first read
|
||||
our [Contributing Guide](https://github.com/nextauthjs/.github/blob/main/CONTRIBUTING.md).
|
||||
|
||||
## License
|
||||
|
||||
ISC
|
||||
@@ -22,9 +22,6 @@ BEYOND_IDENTITY_CLIENT_ID=
|
||||
BEYOND_IDENTITY_CLIENT_SECRET=
|
||||
BEYOND_IDENTITY_ISSUER=
|
||||
|
||||
DESCOPE_ID=
|
||||
DESCOPE_SECRET=
|
||||
|
||||
GITHUB_ID=
|
||||
GITHUB_SECRET=
|
||||
|
||||
@@ -55,14 +52,6 @@ TWITTER_SECRET=
|
||||
WIKIMEDIA_ID=
|
||||
WIKIMEDIA_SECRET=
|
||||
|
||||
# Yandex OAuth. new app -> https://oauth.yandex.com/client/new/id
|
||||
YANDEX_ID=
|
||||
YANDEX_SECRET=
|
||||
|
||||
# ClickUp OAuth. https://clickup.com/api/
|
||||
CLICK_UP_ID=
|
||||
CLICK_UP_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
|
||||
|
||||
1
apps/dev/nextjs/.gitignore
vendored
1
apps/dev/nextjs/.gitignore
vendored
@@ -2,4 +2,3 @@ node_modules/
|
||||
/test-results/
|
||||
/playwright-report/
|
||||
/playwright/.cache/
|
||||
dbschema/edgeql-js
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
module default {
|
||||
type User {
|
||||
property name -> str;
|
||||
required property email -> str {
|
||||
constraint exclusive;
|
||||
}
|
||||
property emailVerified -> datetime;
|
||||
property image -> str;
|
||||
multi link accounts := .<user[is Account];
|
||||
multi link sessions := .<user[is Session];
|
||||
property createdAt -> datetime {
|
||||
default := datetime_current();
|
||||
};
|
||||
}
|
||||
|
||||
type Account {
|
||||
required property userId := .user.id;
|
||||
required property type -> str;
|
||||
required property provider -> str;
|
||||
required property providerAccountId -> str {
|
||||
constraint exclusive;
|
||||
};
|
||||
property refresh_token -> str;
|
||||
property access_token -> str;
|
||||
property expires_at -> int64;
|
||||
property token_type -> str;
|
||||
property scope -> str;
|
||||
property id_token -> str;
|
||||
property session_state -> str;
|
||||
required link user -> User {
|
||||
on target delete delete source;
|
||||
};
|
||||
property createdAt -> datetime {
|
||||
default := datetime_current();
|
||||
};
|
||||
|
||||
constraint exclusive on ((.provider, .providerAccountId))
|
||||
}
|
||||
|
||||
type Session {
|
||||
required property sessionToken -> str {
|
||||
constraint exclusive;
|
||||
}
|
||||
required property userId := .user.id;
|
||||
required property expires -> datetime;
|
||||
required link user -> User {
|
||||
on target delete delete source;
|
||||
};
|
||||
property createdAt -> datetime {
|
||||
default := datetime_current();
|
||||
};
|
||||
}
|
||||
|
||||
type VerificationToken {
|
||||
required property identifier -> str;
|
||||
required property token -> str {
|
||||
constraint exclusive;
|
||||
}
|
||||
required property expires -> datetime;
|
||||
property createdAt -> datetime {
|
||||
default := datetime_current();
|
||||
};
|
||||
|
||||
constraint exclusive on ((.identifier, .token))
|
||||
}
|
||||
}
|
||||
|
||||
# Disable the application of access policies within access policies
|
||||
# themselves. This behavior will become the default in EdgeDB 3.0.
|
||||
# See: https://www.edgedb.com/docs/reference/ddl/access_policies#nonrecursive
|
||||
using future nonrecursive_access_policies;
|
||||
@@ -1,2 +0,0 @@
|
||||
[edgedb]
|
||||
server-version = "2.6"
|
||||
1
apps/dev/nextjs/next-env.d.ts
vendored
1
apps/dev/nextjs/next-env.d.ts
vendored
@@ -1,6 +1,5 @@
|
||||
/// <reference types="next" />
|
||||
/// <reference types="next/image-types/global" />
|
||||
/// <reference types="next/navigation-types/compat/navigation" />
|
||||
|
||||
// NOTE: This file should not be edited
|
||||
// see https://nextjs.org/docs/basic-features/typescript for more information.
|
||||
|
||||
@@ -15,31 +15,29 @@
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@auth/core": "workspace:*",
|
||||
"@auth/edgedb-adapter": "workspace:*",
|
||||
"@auth/fauna-adapter": "workspace:*",
|
||||
"@auth/prisma-adapter": "workspace:*",
|
||||
"@auth/supabase-adapter": "workspace:*",
|
||||
"@auth/typeorm-adapter": "workspace:*",
|
||||
"@next-auth/fauna-adapter": "workspace:*",
|
||||
"@next-auth/prisma-adapter": "workspace:*",
|
||||
"@next-auth/supabase-adapter": "workspace:*",
|
||||
"@next-auth/typeorm-legacy-adapter": "workspace:*",
|
||||
"@prisma/client": "^3",
|
||||
"edgedb": "^1.0.1",
|
||||
"@supabase/supabase-js": "^2.0.5",
|
||||
"faunadb": "^4",
|
||||
"next": "13.4.0",
|
||||
"next": "13.1.1",
|
||||
"next-auth": "workspace:*",
|
||||
"nodemailer": "^6",
|
||||
"react": "^18",
|
||||
"react-dom": "^18"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@edgedb/generate": "^0.0.4",
|
||||
"@playwright/test": "1.29.2",
|
||||
"@types/jsonwebtoken": "^8.5.5",
|
||||
"@types/react": "18.0.37",
|
||||
"@types/react": "^18.0.15",
|
||||
"@types/react-dom": "^18.0.6",
|
||||
"dotenv": "^16.0.3",
|
||||
"fake-smtp-server": "^0.8.0",
|
||||
"pg": "^8.7.3",
|
||||
"prisma": "^3",
|
||||
"sqlite3": "^5.0.8",
|
||||
"typeorm": "0.3.17"
|
||||
"typeorm": "0.3.7"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,15 +2,14 @@ import { Auth, type AuthConfig } from "@auth/core"
|
||||
|
||||
// Providers
|
||||
import Apple from "@auth/core/providers/apple"
|
||||
// import Asgardeo from "@auth/core/providers/asgardeo"
|
||||
import Asgardeo from "@auth/core/providers/asgardeo"
|
||||
import Auth0 from "@auth/core/providers/auth0"
|
||||
import AzureAD from "@auth/core/providers/azure-ad"
|
||||
import AzureB2C from "@auth/core/providers/azure-ad-b2c"
|
||||
// import BeyondIdentity from "@auth/core/providers/beyondidentity"
|
||||
import BeyondIdentity from "@auth/core/providers/beyondidentity"
|
||||
import BoxyHQSAML from "@auth/core/providers/boxyhq-saml"
|
||||
// import Cognito from "@auth/core/providers/cognito"
|
||||
import Credentials from "@auth/core/providers/credentials"
|
||||
import Descope from "@auth/core/providers/descope"
|
||||
import Discord from "@auth/core/providers/discord"
|
||||
import DuendeIDS6 from "@auth/core/providers/duende-identity-server6"
|
||||
// import Email from "@auth/core/providers/email"
|
||||
@@ -35,29 +34,28 @@ 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"
|
||||
import ClickUp from '@auth/core/providers/click-up'
|
||||
|
||||
// // Prisma
|
||||
// import { PrismaClient } from "@prisma/client"
|
||||
// import { PrismaAdapter } from "@auth/prisma-adapter"
|
||||
// import { PrismaAdapter } from "@next-auth/prisma-adapter"
|
||||
// const client = globalThis.prisma || new PrismaClient()
|
||||
// if (process.env.NODE_ENV !== "production") globalThis.prisma = client
|
||||
// const adapter = PrismaAdapter(client)
|
||||
|
||||
// // Fauna
|
||||
// import { Client as FaunaClient } from "faunadb"
|
||||
// import { FaunaAdapter } from "@auth/fauna-adapter"
|
||||
// import { FaunaAdapter } from "@next-auth/fauna-adapter"
|
||||
// const opts = { secret: process.env.FAUNA_SECRET, domain: process.env.FAUNA_DOMAIN }
|
||||
// const client = globalThis.fauna || new FaunaClient(opts)
|
||||
// if (process.env.NODE_ENV !== "production") globalThis.fauna = client
|
||||
// const adapter = FaunaAdapter(client)
|
||||
|
||||
// // TypeORM
|
||||
// import { TypeORMAdapter } from "@auth/typeorm-adapter"
|
||||
// const adapter = TypeORMAdapter({
|
||||
// import { TypeORMLegacyAdapter } from "@next-auth/typeorm-legacy-adapter"
|
||||
// const adapter = TypeORMLegacyAdapter({
|
||||
// type: "sqlite",
|
||||
// name: "next-auth-test-memory",
|
||||
// database: "./typeorm/dev.db",
|
||||
@@ -65,18 +63,12 @@ import ClickUp from '@auth/core/providers/click-up'
|
||||
// })
|
||||
|
||||
// // Supabase
|
||||
// import { SupabaseAdapter } from "@auth/supabase-adapter"
|
||||
// import { SupabaseAdapter } from "@next-auth/supabase-adapter"
|
||||
// const adapter = SupabaseAdapter({
|
||||
// url: process.env.NEXT_PUBLIC_SUPABASE_URL,
|
||||
// secret: process.env.SUPABASE_SERVICE_ROLE_KEY,
|
||||
// })
|
||||
|
||||
// // EdgeDB
|
||||
// import { EdgeDBAdapter } from "@auth/edgedb-adapter"
|
||||
// import { createHttpClient } from "edgedb"
|
||||
// const client = createHttpClient()
|
||||
// const adapter = EdgeDBAdapter(client)
|
||||
|
||||
export const authConfig: AuthConfig = {
|
||||
// adapter,
|
||||
debug: process.env.NODE_ENV !== "production",
|
||||
@@ -92,8 +84,8 @@ export const authConfig: AuthConfig = {
|
||||
return { name: "Fill Murray", email: "bill@fillmurray.com", image: "https://www.fillmurray.com/64/64", id: "1", foo: "" }
|
||||
},
|
||||
}),
|
||||
Apple({ clientId: process.env.APPLE_ID, clientSecret: process.env.APPLE_SECRET as string }),
|
||||
// Asgardeo({ clientId: process.env.ASGARDEO_CLIENT_ID, clientSecret: process.env.ASGARDEO_CLIENT_SECRET, issuer: process.env.ASGARDEO_ISSUER }),
|
||||
Apple({ clientId: process.env.APPLE_ID, clientSecret: process.env.APPLE_SECRET }),
|
||||
Asgardeo({ clientId: process.env.ASGARDEO_CLIENT_ID, clientSecret: process.env.ASGARDEO_CLIENT_SECRET, issuer: process.env.ASGARDEO_ISSUER }),
|
||||
Auth0({ clientId: process.env.AUTH0_ID, clientSecret: process.env.AUTH0_SECRET, issuer: process.env.AUTH0_ISSUER }),
|
||||
AzureAD({
|
||||
clientId: process.env.AZURE_AD_CLIENT_ID,
|
||||
@@ -101,20 +93,15 @@ export const authConfig: AuthConfig = {
|
||||
tenantId: process.env.AZURE_AD_TENANT_ID,
|
||||
}),
|
||||
AzureB2C({ clientId: process.env.AZURE_B2C_ID, clientSecret: process.env.AZURE_B2C_SECRET, issuer: process.env.AZURE_B2C_ISSUER }),
|
||||
// BeyondIdentity({
|
||||
// clientId: process.env.BEYOND_IDENTITY_CLIENT_ID,
|
||||
// clientSecret: process.env.BEYOND_IDENTITY_CLIENT_SECRET,
|
||||
// issuer: process.env.BEYOND_IDENTITY_ISSUER,
|
||||
// }),
|
||||
BeyondIdentity({ clientId: process.env.BEYOND_IDENTITY_CLIENT_ID, clientSecret: process.env.BEYOND_IDENTITY_CLIENT_SECRET, issuer: process.env.BEYOND_IDENTITY_ISSUER }),
|
||||
BoxyHQSAML({ issuer: "https://jackson-demo.boxyhq.com", clientId: "tenant=boxyhq.com&product=saml-demo.boxyhq.com", clientSecret: "dummy" }),
|
||||
// Cognito({ clientId: process.env.COGNITO_ID, clientSecret: process.env.COGNITO_SECRET, issuer: process.env.COGNITO_ISSUER }),
|
||||
Descope({ clientId: process.env.DESCOPE_ID, clientSecret: process.env.DESCOPE_SECRET }),
|
||||
Discord({ clientId: process.env.DISCORD_ID, clientSecret: process.env.DISCORD_SECRET }),
|
||||
DuendeIDS6({ clientId: "interactive.confidential", clientSecret: "secret", issuer: "https://demo.duendesoftware.com" }),
|
||||
Facebook({ clientId: process.env.FACEBOOK_ID, clientSecret: process.env.FACEBOOK_SECRET }),
|
||||
Foursquare({ clientId: process.env.FOURSQUARE_ID, clientSecret: process.env.FOURSQUARE_SECRET }),
|
||||
Freshbooks({ clientId: process.env.FRESHBOOKS_ID, clientSecret: process.env.FRESHBOOKS_SECRET }),
|
||||
GitHub({ clientId: process.env.GITHUB_ID, clientSecret: process.env.GITHUB_SECRET, redirectProxyUrl: process.env.AUTH_REDIRECT_PROXY_URL }),
|
||||
GitHub({ clientId: process.env.GITHUB_ID, clientSecret: process.env.GITHUB_SECRET }),
|
||||
Gitlab({ clientId: process.env.GITLAB_ID, clientSecret: process.env.GITLAB_SECRET }),
|
||||
Google({ clientId: process.env.GOOGLE_ID, clientSecret: process.env.GOOGLE_SECRET }),
|
||||
// IDS4({ clientId: process.env.IDS4_ID, clientSecret: process.env.IDS4_SECRET, issuer: process.env.IDS4_ISSUER }),
|
||||
@@ -123,7 +110,7 @@ export const authConfig: AuthConfig = {
|
||||
Line({ clientId: process.env.LINE_ID, clientSecret: process.env.LINE_SECRET }),
|
||||
LinkedIn({ clientId: process.env.LINKEDIN_ID, clientSecret: process.env.LINKEDIN_SECRET }),
|
||||
Mailchimp({ clientId: process.env.MAILCHIMP_ID, clientSecret: process.env.MAILCHIMP_SECRET }),
|
||||
Notion({ clientId: process.env.NOTION_ID, clientSecret: process.env.NOTION_SECRET, redirectUri: process.env.NOTION_REDIRECT_URI as string }),
|
||||
Notion({ clientId: process.env.NOTION_ID, clientSecret: process.env.NOTION_SECRET, redirectUri: process.env.NOTION_REDIRECT_URI }),
|
||||
// Okta({ clientId: process.env.OKTA_ID, clientSecret: process.env.OKTA_SECRET, issuer: process.env.OKTA_ISSUER }),
|
||||
Osu({ clientId: process.env.OSU_CLIENT_ID, clientSecret: process.env.OSU_CLIENT_SECRET }),
|
||||
Patreon({ clientId: process.env.PATREON_ID, clientSecret: process.env.PATREON_SECRET }),
|
||||
@@ -133,11 +120,9 @@ 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 }),
|
||||
ClickUp({ clientId: process.env.CLICK_UP_ID, clientSecret: process.env.CLICK_UP_SECRET })
|
||||
],
|
||||
// debug: process.env.NODE_ENV !== "production",
|
||||
}
|
||||
@@ -169,4 +154,4 @@ function AuthHandler(...args: any[]) {
|
||||
|
||||
export default AuthHandler(authConfig)
|
||||
|
||||
export const config = { runtime: "edge" }
|
||||
export const config = { runtime: "experimental-edge" }
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "esnext",
|
||||
"lib": [
|
||||
"dom",
|
||||
"dom.iterable",
|
||||
"esnext"
|
||||
],
|
||||
"lib": ["dom", "dom.iterable", "esnext"],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": false,
|
||||
@@ -23,17 +19,8 @@
|
||||
{
|
||||
"name": "next"
|
||||
}
|
||||
],
|
||||
"strictNullChecks": true
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"next-env.d.ts",
|
||||
"**/*.ts",
|
||||
"**/*.tsx",
|
||||
".next/types/**/*.ts"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
"jest.config.js"
|
||||
]
|
||||
}
|
||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
||||
"exclude": ["node_modules", "jest.config.js"]
|
||||
}
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
"@sveltejs/kit": "next",
|
||||
"svelte": "3.55.0",
|
||||
"svelte-check": "2.10.2",
|
||||
"typescript": "5.2.2",
|
||||
"vite": "4.0.5"
|
||||
"typescript": "4.9.4",
|
||||
"vite": "4.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@auth/core": "workspace:*",
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
NEXTAUTH_URL=http://localhost:3000
|
||||
NEXTAUTH_SECRET= # Linux: `openssl rand -hex 32` or go to https://generate-secret.now.sh/32
|
||||
|
||||
APPLE_ID=
|
||||
APPLE_TEAM_ID=
|
||||
APPLE_PRIVATE_KEY=
|
||||
APPLE_KEY_ID=
|
||||
|
||||
AUTH0_ID=
|
||||
AUTH0_SECRET=
|
||||
AUTH0_ISSUER=
|
||||
|
||||
DESCOPE_ID=
|
||||
DESCOPE_SECRET=
|
||||
|
||||
FACEBOOK_ID=
|
||||
FACEBOOK_SECRET=
|
||||
|
||||
@@ -20,3 +21,8 @@ GOOGLE_SECRET=
|
||||
|
||||
TWITTER_ID=
|
||||
TWITTER_SECRET=
|
||||
|
||||
EMAIL_SERVER=smtp://username:password@smtp.example.com:587
|
||||
EMAIL_FROM=NextAuth <noreply@example.com>
|
||||
|
||||
DATABASE_URL=sqlite://localhost/:memory:?synchronize=true
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
import NextAuth from "next-auth/next"
|
||||
import { config } from "auth"
|
||||
|
||||
const handler = NextAuth(config)
|
||||
export { handler as GET, handler as POST }
|
||||
@@ -1,294 +0,0 @@
|
||||
import type { GetServerSidePropsContext, NextApiRequest, NextApiResponse } from "next"
|
||||
import type { NextAuthOptions as NextAuthConfig } from "next-auth"
|
||||
import { getServerSession } from "next-auth"
|
||||
|
||||
import Apple from "next-auth/providers/apple"
|
||||
import Atlassian from "next-auth/providers/atlassian"
|
||||
import Auth0 from "next-auth/providers/auth0"
|
||||
import Authentik from "next-auth/providers/authentik"
|
||||
import AzureAD from "next-auth/providers/azure-ad"
|
||||
import AzureB2C from "next-auth/providers/azure-ad-b2c"
|
||||
import Battlenet from "next-auth/providers/battlenet"
|
||||
import Box from "next-auth/providers/box"
|
||||
import BoxyHQSAML from "next-auth/providers/boxyhq-saml"
|
||||
import Bungie from "next-auth/providers/bungie"
|
||||
import Cognito from "next-auth/providers/cognito"
|
||||
import Coinbase from "next-auth/providers/coinbase"
|
||||
import Discord from "next-auth/providers/discord"
|
||||
import Dropbox from "next-auth/providers/dropbox"
|
||||
import DuendeIDS6 from "next-auth/providers/duende-identity-server6"
|
||||
import Eveonline from "next-auth/providers/eveonline"
|
||||
import Facebook from "next-auth/providers/facebook"
|
||||
import Faceit from "next-auth/providers/faceit"
|
||||
import FortyTwoSchool from "next-auth/providers/42-school"
|
||||
import Foursquare from "next-auth/providers/foursquare"
|
||||
import Freshbooks from "next-auth/providers/freshbooks"
|
||||
import Fusionauth from "next-auth/providers/fusionauth"
|
||||
import GitHub from "next-auth/providers/github"
|
||||
import Gitlab from "next-auth/providers/gitlab"
|
||||
import Google from "next-auth/providers/google"
|
||||
import Hubspot from "next-auth/providers/hubspot"
|
||||
import Instagram from "next-auth/providers/instagram"
|
||||
import Kakao from "next-auth/providers/kakao"
|
||||
import Keycloak from "next-auth/providers/keycloak"
|
||||
import Line from "next-auth/providers/line"
|
||||
import LinkedIn from "next-auth/providers/linkedin"
|
||||
import Mailchimp from "next-auth/providers/mailchimp"
|
||||
import Mailru from "next-auth/providers/mailru"
|
||||
import Medium from "next-auth/providers/medium"
|
||||
import Naver from "next-auth/providers/naver"
|
||||
import Netlify from "next-auth/providers/netlify"
|
||||
import Okta from "next-auth/providers/okta"
|
||||
import Onelogin from "next-auth/providers/onelogin"
|
||||
import Osso from "next-auth/providers/osso"
|
||||
import Osu from "next-auth/providers/osu"
|
||||
import Passage from "next-auth/providers/passage"
|
||||
import Patreon from "next-auth/providers/patreon"
|
||||
import Pinterest from "next-auth/providers/pinterest"
|
||||
import Pipedrive from "next-auth/providers/pipedrive"
|
||||
import Reddit from "next-auth/providers/reddit"
|
||||
import Salesforce from "next-auth/providers/salesforce"
|
||||
import Slack from "next-auth/providers/slack"
|
||||
import Spotify from "next-auth/providers/spotify"
|
||||
import Strava from "next-auth/providers/strava"
|
||||
import Todoist from "next-auth/providers/todoist"
|
||||
import Trakt from "next-auth/providers/trakt"
|
||||
import Twitch from "next-auth/providers/twitch"
|
||||
import Twitter from "next-auth/providers/twitter"
|
||||
import UnitedEffects from "next-auth/providers/united-effects"
|
||||
import Vk from "next-auth/providers/vk"
|
||||
import Wikimedia from "next-auth/providers/wikimedia"
|
||||
import Wordpress from "next-auth/providers/wordpress"
|
||||
import WorkOS from "next-auth/providers/workos"
|
||||
import Yandex from "next-auth/providers/yandex"
|
||||
import Zitadel from "next-auth/providers/zitadel"
|
||||
import Zoho from "next-auth/providers/zoho"
|
||||
import Zoom from "next-auth/providers/zoom"
|
||||
|
||||
// Read more at: https://next-auth.js.org/getting-started/typescript#module-augmentation
|
||||
declare module "next-auth/jwt" {
|
||||
interface JWT {
|
||||
/** The user's role. */
|
||||
userRole?: "admin"
|
||||
}
|
||||
}
|
||||
|
||||
export const config = {
|
||||
providers: [
|
||||
Apple({ clientId: process.env.AUTH_APPLE_ID, clientSecret: process.env.AUTH_APPLE_SECRET }),
|
||||
Atlassian({ clientId: process.env.AUTH_ATLASSIAN_ID, clientSecret: process.env.AUTH_ATLASSIAN_SECRET }),
|
||||
Auth0({ clientId: process.env.AUTH_AUTH0_ID, clientSecret: process.env.AUTH_AUTH0_SECRET, issuer: process.env.AUTH_AUTH0_ISSUER }),
|
||||
Authentik({ clientId: process.env.AUTH_AUTHENTIK_ID, clientSecret: process.env.AUTH_AUTHENTIK_SECRET }),
|
||||
AzureAD({ clientId: process.env.AUTH_AZUREAD_ID, clientSecret: process.env.AUTH_AZUREAD_SECRET }),
|
||||
AzureB2C({ clientId: process.env.AUTH_AZUREB2C_ID, clientSecret: process.env.AUTH_AZUREB2C_SECRET }),
|
||||
Battlenet({ clientId: process.env.AUTH_BN_ID, clientSecret: process.env.AUTH_BN_SECRET, issuer: process.env.AUTH_BN_ISSUER }),
|
||||
Box({ clientId: process.env.AUTH_BOX_ID, clientSecret: process.env.AUTH_BOX_SECRET }),
|
||||
BoxyHQSAML({ clientId: process.env.AUTH_BOXYHQ_ID, clientSecret: process.env.AUTH_BOXYHQ_SECRET, issuer: process.env.AUTH_BOXYHQ_ISSUER }),
|
||||
Bungie({ clientId: process.env.AUTH_BUNGIE_ID, clientSecret: process.env.AUTH_BUNGIE_SECRET }),
|
||||
Cognito({ clientId: process.env.AUTH_COGNITO_ID, clientSecret: process.env.AUTH_COGNITO_SECRET, issuer: process.env.AUTH_COGNITO_ISSUER }),
|
||||
Coinbase({ clientId: process.env.AUTH_COINBASE_ID, clientSecret: process.env.AUTH_COINBASE_SECRET }),
|
||||
Discord({ clientId: process.env.AUTH_DISCORD_ID, clientSecret: process.env.AUTH_DISCORD_SECRET }),
|
||||
Dropbox({ clientId: process.env.AUTH_DROPBOX_ID, clientSecret: process.env.AUTH_DROPBOX_SECRET }),
|
||||
DuendeIDS6({ clientId: process.env.AUTH_DUENDEIDS6_ID, clientSecret: process.env.AUTH_DUENDEIDS6_SECRET }),
|
||||
Eveonline({ clientId: process.env.AUTH_EVEONLINE_ID, clientSecret: process.env.AUTH_EVEONLINE_SECRET }),
|
||||
Facebook({ clientId: process.env.AUTH_FACEBOOK_ID, clientSecret: process.env.AUTH_FACEBOOK_SECRET }),
|
||||
Faceit({ clientId: process.env.AUTH_FACEIT_ID, clientSecret: process.env.AUTH_FACEIT_SECRET }),
|
||||
FortyTwoSchool({ clientId: process.env.AUTH_FORTYTWOSCHOOL_ID, clientSecret: process.env.AUTH_FORTYTWOSCHOOL_SECRET }),
|
||||
Foursquare({ clientId: process.env.AUTH_FOURSQUARE_ID, clientSecret: process.env.AUTH_FOURSQUARE_SECRET }),
|
||||
Freshbooks({ clientId: process.env.AUTH_FRESHBOOKS_ID, clientSecret: process.env.AUTH_FRESHBOOKS_SECRET }),
|
||||
Fusionauth({ clientId: process.env.AUTH_FUSIONAUTH_ID, clientSecret: process.env.AUTH_FUSIONAUTH_SECRET }),
|
||||
GitHub({ clientId: process.env.AUTH_GITHUB_ID, clientSecret: process.env.AUTH_GITHUB_SECRET }),
|
||||
Gitlab({ clientId: process.env.AUTH_GITLAB_ID, clientSecret: process.env.AUTH_GITLAB_SECRET }),
|
||||
Google({ clientId: process.env.AUTH_GOOGLE_ID, clientSecret: process.env.AUTH_GOOGLE_SECRET }),
|
||||
Hubspot({ clientId: process.env.AUTH_HUBSPOT_ID, clientSecret: process.env.AUTH_HUBSPOT_SECRET }),
|
||||
Instagram({ clientId: process.env.AUTH_INSTAGRAM_ID, clientSecret: process.env.AUTH_INSTAGRAM_SECRET }),
|
||||
Kakao({ clientId: process.env.AUTH_KAKAO_ID, clientSecret: process.env.AUTH_KAKAO_SECRET }),
|
||||
Keycloak({ clientId: process.env.AUTH_KEYCLOAK_ID, clientSecret: process.env.AUTH_KEYCLOAK_SECRET }),
|
||||
Line({ clientId: process.env.AUTH_LINE_ID, clientSecret: process.env.AUTH_LINE_SECRET }),
|
||||
LinkedIn({ clientId: process.env.AUTH_LINKEDIN_ID, clientSecret: process.env.AUTH_LINKEDIN_SECRET }),
|
||||
Mailchimp({ clientId: process.env.AUTH_MAILCHIMP_ID, clientSecret: process.env.AUTH_MAILCHIMP_SECRET }),
|
||||
Mailru({ clientId: process.env.AUTH_MAILRU_ID, clientSecret: process.env.AUTH_MAILRU_SECRET }),
|
||||
Medium({ clientId: process.env.AUTH_MEDIUM_ID, clientSecret: process.env.AUTH_MEDIUM_SECRET }),
|
||||
Naver({ clientId: process.env.AUTH_NAVER_ID, clientSecret: process.env.AUTH_NAVER_SECRET }),
|
||||
Netlify({ clientId: process.env.AUTH_NETLIFY_ID, clientSecret: process.env.AUTH_NETLIFY_SECRET }),
|
||||
Okta({ clientId: process.env.AUTH_OKTA_ID, clientSecret: process.env.AUTH_OKTA_SECRET }),
|
||||
Onelogin({ clientId: process.env.AUTH_ONELOGIN_ID, clientSecret: process.env.AUTH_ONELOGIN_SECRET }),
|
||||
Osso({ clientId: process.env.AUTH_OSSO_ID, clientSecret: process.env.AUTH_OSSO_SECRET, issuer: process.env.AUTH_OSSO_ISSUER }),
|
||||
Osu({ clientId: process.env.AUTH_OSU_ID, clientSecret: process.env.AUTH_OSU_SECRET }),
|
||||
Passage({ clientId: process.env.AUTH_PASSAGE_ID, clientSecret: process.env.AUTH_PASSAGE_SECRET, issuer: process.env.AUTH_PASSAGE_ISSUER }),
|
||||
Patreon({ clientId: process.env.AUTH_PATREON_ID, clientSecret: process.env.AUTH_PATREON_SECRET }),
|
||||
Pinterest({ clientId: process.env.AUTH_PINTEREST_ID, clientSecret: process.env.AUTH_PINTEREST_SECRET }),
|
||||
Pipedrive({ clientId: process.env.AUTH_PIPEDRIVE_ID, clientSecret: process.env.AUTH_PIPEDRIVE_SECRET }),
|
||||
Reddit({ clientId: process.env.AUTH_REDDIT_ID, clientSecret: process.env.AUTH_REDDIT_SECRET }),
|
||||
Salesforce({ clientId: process.env.AUTH_SALESFORCE_ID, clientSecret: process.env.AUTH_SALESFORCE_SECRET }),
|
||||
Slack({ clientId: process.env.AUTH_SLACK_ID, clientSecret: process.env.AUTH_SLACK_SECRET }),
|
||||
Spotify({ clientId: process.env.AUTH_SPOTIFY_ID, clientSecret: process.env.AUTH_SPOTIFY_SECRET }),
|
||||
Strava({ clientId: process.env.AUTH_STRAVA_ID, clientSecret: process.env.AUTH_STRAVA_SECRET }),
|
||||
Todoist({ clientId: process.env.AUTH_TODOIST_ID, clientSecret: process.env.AUTH_TODOIST_SECRET }),
|
||||
Trakt({ clientId: process.env.AUTH_TRAKT_ID, clientSecret: process.env.AUTH_TRAKT_SECRET }),
|
||||
Twitch({ clientId: process.env.AUTH_TWITCH_ID, clientSecret: process.env.AUTH_TWITCH_SECRET }),
|
||||
Twitter({ clientId: process.env.AUTH_TWITTER_ID, clientSecret: process.env.AUTH_TWITTER_SECRET, version: "2.0" }),
|
||||
UnitedEffects({ clientId: process.env.AUTH_UE_ID, clientSecret: process.env.AUTH_UE_SECRET, issuer: process.env.AUTH_UE_ISSUER }),
|
||||
Vk({ clientId: process.env.AUTH_VK_ID, clientSecret: process.env.AUTH_VK_SECRET }),
|
||||
Wikimedia({ clientId: process.env.AUTH_WIKIMEDIA_ID, clientSecret: process.env.AUTH_WIKIMEDIA_SECRET }),
|
||||
Wordpress({ clientId: process.env.AUTH_WORDPRESS_ID, clientSecret: process.env.AUTH_WORDPRESS_SECRET }),
|
||||
WorkOS({ clientId: process.env.AUTH_WORKOS_ID, clientSecret: process.env.AUTH_WORKOS_SECRET }),
|
||||
Yandex({ clientId: process.env.AUTH_YANDEX_ID, clientSecret: process.env.AUTH_YANDEX_SECRET }),
|
||||
Zitadel({ clientId: process.env.AUTH_ZITADEL_ID, clientSecret: process.env.AUTH_ZITADEL_SECRET }),
|
||||
Zoho({ clientId: process.env.AUTH_ZOHO_ID, clientSecret: process.env.AUTH_ZOHO_SECRET }),
|
||||
Zoom({ clientId: process.env.AUTH_ZOOM_ID, clientSecret: process.env.AUTH_ZOOM_SECRET }),
|
||||
],
|
||||
callbacks: {
|
||||
async jwt({ token }) {
|
||||
token.userRole = "admin"
|
||||
return token
|
||||
},
|
||||
},
|
||||
} satisfies NextAuthConfig
|
||||
|
||||
// Helper function to get session without passing config every time
|
||||
// https://next-auth.js.org/configuration/nextjs#getserversession
|
||||
export function auth(...args: [GetServerSidePropsContext["req"], GetServerSidePropsContext["res"]] | [NextApiRequest, NextApiResponse] | []) {
|
||||
return getServerSession(...args, config)
|
||||
}
|
||||
|
||||
// We recommend doing your own environment variable validation
|
||||
declare global {
|
||||
namespace NodeJS {
|
||||
export interface ProcessEnv {
|
||||
NEXTAUTH_SECRET: string
|
||||
|
||||
AUTH_APPLE_ID: string
|
||||
AUTH_APPLE_SECRET: string
|
||||
AUTH_ATLASSIAN_ID: string
|
||||
AUTH_ATLASSIAN_SECRET: string
|
||||
AUTH_AUTH0_ID: string
|
||||
AUTH_AUTH0_ISSUER: string
|
||||
AUTH_AUTH0_SECRET: string
|
||||
AUTH_AUTHENTIK_ID: string
|
||||
AUTH_AUTHENTIK_SECRET: string
|
||||
AUTH_AZUREAD_ID: string
|
||||
AUTH_AZUREAD_SECRET: string
|
||||
AUTH_AZUREB2C_ID: string
|
||||
AUTH_AZUREB2C_SECRET: string
|
||||
AUTH_BN_ID: string
|
||||
AUTH_BN_ISSUER: any
|
||||
AUTH_BN_SECRET: string
|
||||
AUTH_BOX_ID: string
|
||||
AUTH_BOX_SECRET: string
|
||||
AUTH_BOXYHQ_ID: string
|
||||
AUTH_BOXYHQ_ISSUER: string
|
||||
AUTH_BOXYHQ_SECRET: string
|
||||
AUTH_BUNGIE_ID: string
|
||||
AUTH_BUNGIE_SECRET: string
|
||||
AUTH_COGNITO_ID: string
|
||||
AUTH_COGNITO_ISSUER: string
|
||||
AUTH_COGNITO_SECRET: string
|
||||
AUTH_COINBASE_ID: string
|
||||
AUTH_COINBASE_SECRET: string
|
||||
AUTH_DISCORD_ID: string
|
||||
AUTH_DISCORD_SECRET: string
|
||||
AUTH_DROPBOX_ID: string
|
||||
AUTH_DROPBOX_SECRET: string
|
||||
AUTH_DUENDEIDS6_ID: string
|
||||
AUTH_DUENDEIDS6_SECRET: string
|
||||
AUTH_EVEONLINE_ID: string
|
||||
AUTH_EVEONLINE_SECRET: string
|
||||
AUTH_FACEBOOK_ID: string
|
||||
AUTH_FACEBOOK_SECRET: string
|
||||
AUTH_FACEIT_ID: string
|
||||
AUTH_FACEIT_SECRET: string
|
||||
AUTH_FORTYTWOSCHOOL_ID: string
|
||||
AUTH_FORTYTWOSCHOOL_SECRET: string
|
||||
AUTH_FOURSQUARE_ID: string
|
||||
AUTH_FOURSQUARE_SECRET: string
|
||||
AUTH_FRESHBOOKS_ID: string
|
||||
AUTH_FRESHBOOKS_SECRET: string
|
||||
AUTH_FUSIONAUTH_ID: string
|
||||
AUTH_FUSIONAUTH_SECRET: string
|
||||
AUTH_GITHUB_ID: string
|
||||
AUTH_GITHUB_SECRET: string
|
||||
AUTH_GITLAB_ID: string
|
||||
AUTH_GITLAB_SECRET: string
|
||||
AUTH_GOOGLE_ID: string
|
||||
AUTH_GOOGLE_SECRET: string
|
||||
AUTH_HUBSPOT_ID: string
|
||||
AUTH_HUBSPOT_SECRET: string
|
||||
AUTH_INSTAGRAM_ID: string
|
||||
AUTH_INSTAGRAM_SECRET: string
|
||||
AUTH_KAKAO_ID: string
|
||||
AUTH_KAKAO_SECRET: string
|
||||
AUTH_KEYCLOAK_ID: string
|
||||
AUTH_KEYCLOAK_SECRET: string
|
||||
AUTH_LINE_ID: string
|
||||
AUTH_LINE_SECRET: string
|
||||
AUTH_LINKEDIN_ID: string
|
||||
AUTH_LINKEDIN_SECRET: string
|
||||
AUTH_MAILCHIMP_ID: string
|
||||
AUTH_MAILCHIMP_SECRET: string
|
||||
AUTH_MAILRU_ID: string
|
||||
AUTH_MAILRU_SECRET: string
|
||||
AUTH_MEDIUM_ID: string
|
||||
AUTH_MEDIUM_SECRET: string
|
||||
AUTH_NAVER_ID: string
|
||||
AUTH_NAVER_SECRET: string
|
||||
AUTH_NETLIFY_ID: string
|
||||
AUTH_NETLIFY_SECRET: string
|
||||
AUTH_OKTA_ID: string
|
||||
AUTH_OKTA_SECRET: string
|
||||
AUTH_ONELOGIN_ID: string
|
||||
AUTH_ONELOGIN_SECRET: string
|
||||
AUTH_OSSO_ID: string
|
||||
AUTH_OSSO_ISSUER: string
|
||||
AUTH_OSSO_SECRET: string
|
||||
AUTH_OSU_ID: string
|
||||
AUTH_OSU_SECRET: string
|
||||
AUTH_PASSAGE_ID: string
|
||||
AUTH_PASSAGE_ISSUER: string
|
||||
AUTH_PASSAGE_SECRET: string
|
||||
AUTH_PATREON_ID: string
|
||||
AUTH_PATREON_SECRET: string
|
||||
AUTH_PINTEREST_ID: string
|
||||
AUTH_PINTEREST_SECRET: string
|
||||
AUTH_PIPEDRIVE_ID: string
|
||||
AUTH_PIPEDRIVE_SECRET: string
|
||||
AUTH_REDDIT_ID: string
|
||||
AUTH_REDDIT_SECRET: string
|
||||
AUTH_SALESFORCE_ID: string
|
||||
AUTH_SALESFORCE_SECRET: string
|
||||
AUTH_SLACK_ID: string
|
||||
AUTH_SLACK_SECRET: string
|
||||
AUTH_SPOTIFY_ID: string
|
||||
AUTH_SPOTIFY_SECRET: string
|
||||
AUTH_STRAVA_ID: string
|
||||
AUTH_STRAVA_SECRET: string
|
||||
AUTH_TODOIST_ID: string
|
||||
AUTH_TODOIST_SECRET: string
|
||||
AUTH_TRAKT_ID: string
|
||||
AUTH_TRAKT_SECRET: string
|
||||
AUTH_TWITCH_ID: string
|
||||
AUTH_TWITCH_SECRET: string
|
||||
AUTH_TWITTER_ID: string
|
||||
AUTH_TWITTER_SECRET: string
|
||||
AUTH_UE_ID: string
|
||||
AUTH_UE_ISSUER: string
|
||||
AUTH_UE_SECRET: string
|
||||
AUTH_VK_ID: string
|
||||
AUTH_VK_SECRET: string
|
||||
AUTH_WIKIMEDIA_ID: string
|
||||
AUTH_WIKIMEDIA_SECRET: string
|
||||
AUTH_WORDPRESS_ID: string
|
||||
AUTH_WORDPRESS_SECRET: string
|
||||
AUTH_WORKOS_ID: string
|
||||
AUTH_WORKOS_SECRET: string
|
||||
AUTH_YANDEX_ID: string
|
||||
AUTH_YANDEX_SECRET: string
|
||||
AUTH_ZITADEL_ID: string
|
||||
AUTH_ZITADEL_SECRET: string
|
||||
AUTH_ZOHO_ID: string
|
||||
AUTH_ZOHO_SECRET: string
|
||||
AUTH_ZOOM_ID: string
|
||||
AUTH_ZOOM_SECRET: string
|
||||
}
|
||||
}
|
||||
}
|
||||
10
apps/examples/nextjs/next-auth.d.ts
vendored
Normal file
10
apps/examples/nextjs/next-auth.d.ts
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
import "next-auth/jwt"
|
||||
|
||||
// Read more at: https://next-auth.js.org/getting-started/typescript#module-augmentation
|
||||
|
||||
declare module "next-auth/jwt" {
|
||||
interface JWT {
|
||||
/** The user's role. */
|
||||
userRole?: "admin"
|
||||
}
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
/** @type {import("next").NextConfig} */
|
||||
module.exports = {
|
||||
reactStrictMode: true,
|
||||
}
|
||||
@@ -20,12 +20,13 @@
|
||||
"dependencies": {
|
||||
"next": "latest",
|
||||
"next-auth": "latest",
|
||||
"nodemailer": "^6",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^18.16.2",
|
||||
"@types/react": "^18.2.0",
|
||||
"typescript": "5.2.2"
|
||||
"@types/node": "^17",
|
||||
"@types/react": "^18.0.15",
|
||||
"typescript": "^4"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ export default function Page() {
|
||||
<p>Only admin users can see this page.</p>
|
||||
<p>
|
||||
To learn more about the NextAuth middleware see
|
||||
<a href="https://next-auth.js.org/configuration/nextjs#middleware">
|
||||
<a href="https://docs-git-misc-docs-nextauthjs.vercel.app/configuration/nextjs#middleware">
|
||||
the docs
|
||||
</a>
|
||||
.
|
||||
|
||||
65
apps/examples/nextjs/pages/api/auth/[...nextauth].ts
Normal file
65
apps/examples/nextjs/pages/api/auth/[...nextauth].ts
Normal file
@@ -0,0 +1,65 @@
|
||||
import NextAuth, { NextAuthOptions } from "next-auth"
|
||||
import GoogleProvider from "next-auth/providers/google"
|
||||
import FacebookProvider from "next-auth/providers/facebook"
|
||||
import GithubProvider from "next-auth/providers/github"
|
||||
import TwitterProvider from "next-auth/providers/twitter"
|
||||
import Auth0Provider from "next-auth/providers/auth0"
|
||||
// import AppleProvider from "next-auth/providers/apple"
|
||||
// import EmailProvider from "next-auth/providers/email"
|
||||
|
||||
// For more information on each option (and a full list of options) go to
|
||||
// https://next-auth.js.org/configuration/options
|
||||
export const authOptions: NextAuthOptions = {
|
||||
// https://next-auth.js.org/configuration/providers/oauth
|
||||
providers: [
|
||||
/* EmailProvider({
|
||||
server: process.env.EMAIL_SERVER,
|
||||
from: process.env.EMAIL_FROM,
|
||||
}),
|
||||
// Temporarily removing the Apple provider from the demo site as the
|
||||
// callback URL for it needs updating due to Vercel changing domains
|
||||
|
||||
Providers.Apple({
|
||||
clientId: process.env.APPLE_ID,
|
||||
clientSecret: {
|
||||
appleId: process.env.APPLE_ID,
|
||||
teamId: process.env.APPLE_TEAM_ID,
|
||||
privateKey: process.env.APPLE_PRIVATE_KEY,
|
||||
keyId: process.env.APPLE_KEY_ID,
|
||||
},
|
||||
}),
|
||||
*/
|
||||
FacebookProvider({
|
||||
clientId: process.env.FACEBOOK_ID,
|
||||
clientSecret: process.env.FACEBOOK_SECRET,
|
||||
}),
|
||||
GithubProvider({
|
||||
clientId: process.env.GITHUB_ID,
|
||||
clientSecret: process.env.GITHUB_SECRET,
|
||||
}),
|
||||
GoogleProvider({
|
||||
clientId: process.env.GOOGLE_ID,
|
||||
clientSecret: process.env.GOOGLE_SECRET,
|
||||
}),
|
||||
TwitterProvider({
|
||||
clientId: process.env.TWITTER_ID,
|
||||
clientSecret: process.env.TWITTER_SECRET,
|
||||
}),
|
||||
Auth0Provider({
|
||||
clientId: process.env.AUTH0_ID,
|
||||
clientSecret: process.env.AUTH0_SECRET,
|
||||
issuer: process.env.AUTH0_ISSUER,
|
||||
}),
|
||||
],
|
||||
theme: {
|
||||
colorScheme: "light",
|
||||
},
|
||||
callbacks: {
|
||||
async jwt({ token }) {
|
||||
token.userRole = "admin"
|
||||
return token
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
export default NextAuth(authOptions)
|
||||
@@ -1,13 +1,14 @@
|
||||
// This is an example of to protect an API route
|
||||
import { unstable_getServerSession } from "next-auth/next"
|
||||
import { authOptions } from "../auth/[...nextauth]"
|
||||
|
||||
import { auth } from "auth"
|
||||
import type { NextApiRequest, NextApiResponse } from "next"
|
||||
|
||||
export default async function handler(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse
|
||||
) {
|
||||
const session = await auth(req, res)
|
||||
const session = await unstable_getServerSession(req, res, authOptions)
|
||||
|
||||
if (session) {
|
||||
return res.send({
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
// This is an example of how to access a session from an API route
|
||||
import { unstable_getServerSession } from "next-auth"
|
||||
import { authOptions } from "../auth/[...nextauth]"
|
||||
|
||||
import { auth } from "auth"
|
||||
import type { NextApiRequest, NextApiResponse } from "next"
|
||||
|
||||
export default async function handler(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse
|
||||
) {
|
||||
const session = await auth(req, res)
|
||||
const session = await unstable_getServerSession(req, res, authOptions)
|
||||
res.send(JSON.stringify(session, null, 2))
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { auth } from "auth"
|
||||
import { unstable_getServerSession } from "next-auth/next"
|
||||
import { authOptions } from "./api/auth/[...nextauth]"
|
||||
import Layout from "../components/layout"
|
||||
|
||||
import type { GetServerSidePropsContext } from "next"
|
||||
@@ -12,11 +13,11 @@ export default function ServerSidePage() {
|
||||
<Layout>
|
||||
<h1>Server Side Rendering</h1>
|
||||
<p>
|
||||
This page uses the <strong>getServerSession()</strong> method in{" "}
|
||||
<strong>getServerSideProps()</strong>.
|
||||
This page uses the <strong>unstable_getServerSession()</strong> method
|
||||
in <strong>getServerSideProps()</strong>.
|
||||
</p>
|
||||
<p>
|
||||
Using <strong>getServerSession()</strong> in{" "}
|
||||
Using <strong>unstable_getServerSession()</strong> in{" "}
|
||||
<strong>getServerSideProps()</strong> is the recommended approach if you
|
||||
need to support Server Side Rendering with authentication.
|
||||
</p>
|
||||
@@ -35,5 +36,13 @@ export default function ServerSidePage() {
|
||||
|
||||
// Export the `session` prop to use sessions with Server Side Rendering
|
||||
export async function getServerSideProps(context: GetServerSidePropsContext) {
|
||||
return { props: { session: await auth(context.req, context.res) } }
|
||||
return {
|
||||
props: {
|
||||
session: await unstable_getServerSession(
|
||||
context.req,
|
||||
context.res,
|
||||
authOptions
|
||||
),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
16
apps/examples/nextjs/process.d.ts
vendored
Normal file
16
apps/examples/nextjs/process.d.ts
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
declare namespace NodeJS {
|
||||
export interface ProcessEnv {
|
||||
NEXTAUTH_URL: string
|
||||
NEXTAUTH_SECRET: string
|
||||
GITHUB_ID: string
|
||||
GITHUB_SECRET: string
|
||||
FACEBOOK_ID: string
|
||||
FACEBOOK_SECRET: string
|
||||
TWITTER_ID: string
|
||||
TWITTER_SECRET: string
|
||||
GOOGLE_ID: string
|
||||
GOOGLE_SECRET: string
|
||||
AUTH0_ID: string
|
||||
AUTH0_SECRET: string
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,7 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"lib": [
|
||||
"dom",
|
||||
"dom.iterable",
|
||||
"esnext"
|
||||
],
|
||||
"lib": ["dom", "dom.iterable", "esnext"],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
@@ -17,22 +13,14 @@
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"jsx": "preserve",
|
||||
"incremental": true,
|
||||
"baseUrl": ".",
|
||||
"plugins": [
|
||||
{
|
||||
"name": "next"
|
||||
}
|
||||
]
|
||||
"incremental": true
|
||||
},
|
||||
"include": [
|
||||
"process.d.ts",
|
||||
"next-env.d.ts",
|
||||
"next-auth.d.ts",
|
||||
"**/*.ts",
|
||||
"**/*.tsx",
|
||||
".next/types/**/*.ts"
|
||||
"**/*.tsx"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
]
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
"solid-start-node": "^0.2.9",
|
||||
"solid-start-vercel": "^0.2.9",
|
||||
"tailwindcss": "^3.2.4",
|
||||
"typescript": "5.2.2",
|
||||
"typescript": "^4.8.3",
|
||||
"vite": "^3.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
"@sveltejs/kit": "next",
|
||||
"svelte": "3.55.0",
|
||||
"svelte-check": "2.10.2",
|
||||
"typescript": "5.2.2",
|
||||
"typescript": "4.9.4",
|
||||
"vite": "4.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
|
||||
@@ -10,13 +10,13 @@
|
||||
"clean": "gatsby clean"
|
||||
},
|
||||
"dependencies": {
|
||||
"dotenv": "16.0.0",
|
||||
"gatsby": "5.8.0-next.3",
|
||||
"dotenv": "^16.0.0",
|
||||
"gatsby": "next",
|
||||
"next-auth": "workspace:*",
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0"
|
||||
"react": "^18",
|
||||
"react-dom": "^18"
|
||||
},
|
||||
"devDependencies": {
|
||||
"vercel": "23.1.2"
|
||||
"vercel": "^23.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Session } from "@auth/core/types"
|
||||
import { Session } from "@auth/core"
|
||||
|
||||
export default function useSession() {
|
||||
return useState<Session | null>("session", () => null)
|
||||
|
||||
@@ -43,7 +43,7 @@ export async function signIn<
|
||||
|
||||
// TODO: Handle custom base path
|
||||
// TODO: Remove this since Sveltekit offers the CSRF protection via origin check
|
||||
const { csrfToken } = await $fetch<{ csrfToken: string }>("/api/auth/csrf")
|
||||
const { csrfToken } = await $fetch("/api/auth/csrf")
|
||||
|
||||
console.log(_signInUrl)
|
||||
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
import { AuthConfig, Session } from "@auth/core/types"
|
||||
import { Auth } from "@auth/core"
|
||||
import { AuthHandler, AuthOptions, Session } from "@auth/core"
|
||||
import { fromNodeMiddleware, H3Event } from "h3"
|
||||
import getURL from "requrl"
|
||||
import { createMiddleware } from "@hattip/adapter-node"
|
||||
|
||||
export function NuxtAuthHandler(options: AuthConfig) {
|
||||
export function NuxtAuthHandler(options: AuthOptions) {
|
||||
async function handler(ctx: { request: Request }) {
|
||||
options.trustHost ??= true
|
||||
|
||||
return Auth(ctx.request, options)
|
||||
return AuthHandler(ctx.request, options)
|
||||
}
|
||||
|
||||
const middleware = createMiddleware(handler)
|
||||
@@ -18,7 +17,7 @@ export function NuxtAuthHandler(options: AuthConfig) {
|
||||
|
||||
export async function getSession(
|
||||
event: H3Event,
|
||||
options: AuthConfig
|
||||
options: AuthOptions
|
||||
): Promise<Session | null> {
|
||||
options.trustHost ??= true
|
||||
|
||||
@@ -31,7 +30,7 @@ export async function getSession(
|
||||
nodeHeaders.append(key, headers[key] as any)
|
||||
})
|
||||
|
||||
const response = await Auth(
|
||||
const response = await AuthHandler(
|
||||
new Request(url, { headers: nodeHeaders }),
|
||||
options
|
||||
)
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
{
|
||||
"name": "next-auth-nuxt",
|
||||
"name": "playground-nuxt",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "nuxt build",
|
||||
"dev": "nuxt prepare && nuxt dev",
|
||||
"build": "nuxt prepare && nuxt build",
|
||||
"dev": "nuxt prepare && export NODE_OPTIONS='--no-experimental-fetch' && nuxt dev",
|
||||
"generate": "nuxt generate",
|
||||
"preview": "nuxt preview"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nuxt/eslint-config": "^0.1.1",
|
||||
"eslint": "^8.29.0",
|
||||
"h3": "1.6.6",
|
||||
"nuxt": "3.5.1"
|
||||
"h3": "1.0.2",
|
||||
"nuxt": "3.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@auth/core": "workspace:*",
|
||||
"@hattip/adapter-node": "^0.0.34",
|
||||
"@hattip/adapter-node": "^0.0.22",
|
||||
"requrl": "^3.0.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Session } from "@auth/core/types"
|
||||
import { Session } from "@auth/core"
|
||||
|
||||
export default defineNuxtPlugin(async () => {
|
||||
const session = useSession()
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { NuxtAuthHandler } from "@/lib/auth/server"
|
||||
import GithubProvider from "@auth/core/providers/github"
|
||||
import type { AuthConfig } from "@auth/core"
|
||||
import type { AuthOptions } from "@auth/core"
|
||||
|
||||
const runtimeConfig = useRuntimeConfig()
|
||||
|
||||
export const authOptions = {
|
||||
export const authOptions: AuthOptions = {
|
||||
secret: runtimeConfig.secret,
|
||||
providers: [
|
||||
GithubProvider({
|
||||
@@ -12,6 +12,6 @@ export const authOptions = {
|
||||
clientSecret: runtimeConfig.github.clientSecret,
|
||||
}),
|
||||
],
|
||||
} as AuthConfig
|
||||
}
|
||||
|
||||
export default NuxtAuthHandler(authOptions)
|
||||
|
||||
3
docs/.eslintrc
Normal file
3
docs/.eslintrc
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"extends": "next/core-web-vitals"
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
<p align="center">
|
||||
<br/>
|
||||
<a href="https://authjs.dev" target="_blank"><img width="150px" src="https://authjs.dev/img/logo/logo-sm.png" /></a>
|
||||
<h3 align="center">Auth.js</h3>
|
||||
<p align="center">Authentication for Next.js</p>
|
||||
<p align="center">
|
||||
Open Source. Full Stack. Own Your Data.
|
||||
</p>
|
||||
<p align="center" style="align: center;">
|
||||
<a href="https://github.com/nextauthjs/next-auth/actions/workflows/release.yml?query=workflow%3ARelease">
|
||||
<img src="https://github.com/nextauthjs/next-auth/actions/workflows/release.yml/badge.svg" alt="Release" />
|
||||
</a>
|
||||
<a href="https://packagephobia.com/result?p=@auth/core">
|
||||
<img src="https://packagephobia.com/badge?p=@auth/core" alt="Bundle Size"/>
|
||||
</a>
|
||||
<a href="https://www.npmtrends.com/@auth/core">
|
||||
<img src="https://img.shields.io/npm/dm/@auth/core" alt="Downloads" />
|
||||
</a>
|
||||
<a href="https://github.com/nextauthjs/next-auth/stargazers">
|
||||
<img src="https://img.shields.io/github/stars/nextauthjs/next-auth" alt="Github Stars" />
|
||||
</a>
|
||||
<a href="https://www.npmjs.com/package/@auth/core">
|
||||
<img src="https://img.shields.io/github/v/release/nextauthjs/next-auth?label=latest" alt="Github Stable Release" />
|
||||
</a>
|
||||
</p>
|
||||
</p>
|
||||
|
||||
## Overview
|
||||
|
||||
This is the repository for the documentation page for Auth.js!
|
||||
|
||||
NextAuth.js is a complete open source authentication solution for [Next.js](http://nextjs.org/) applications.
|
||||
|
||||
This documentation site is based on the [Docusaurus](https://docusaurus.io) framework.
|
||||
|
||||
## Getting Started
|
||||
|
||||
To start a local environment of this project, please do the following.
|
||||
|
||||
1. Clone the repo:
|
||||
|
||||
```sh
|
||||
git clone git@github.com:nextauthjs/next-auth.git
|
||||
cd next-auth
|
||||
```
|
||||
|
||||
2. Set up the correct pnpm version, using [Corepack](https://nodejs.org/api/corepack.html). Run the following in the project'a root:
|
||||
|
||||
```sh
|
||||
corepack enable pnpm
|
||||
```
|
||||
|
||||
(Now, if you run `pnpm --version`, it should print the same verion as the `packageManager` property in the [`package.json` file](https://github.com/nextauthjs/next-auth/blob/main/package.json))
|
||||
|
||||
3. Install packages. Developing requires Node.js v18:
|
||||
|
||||
```sh
|
||||
pnpm install
|
||||
```
|
||||
|
||||
4. Start the development server
|
||||
|
||||
```bash
|
||||
pnpm dev:docs
|
||||
```
|
||||
|
||||
And thats all! Now you should have a local copy of this docs site running at [localhost:3000](http://localhost:3000)!
|
||||
|
||||
## Contributing
|
||||
|
||||
We're open to all community contributions! If you'd like to contribute in any way, please first read our [Contributing Guide](https://github.com/nextauthjs/.github/blob/main/CONTRIBUTING.md).
|
||||
|
||||
## License
|
||||
|
||||
ISC
|
||||
19
docs/assets/img/blobs/blob1.svg
Normal file
19
docs/assets/img/blobs/blob1.svg
Normal file
@@ -0,0 +1,19 @@
|
||||
<!-- <svg width="1077" height="990" viewBox="0 0 1077 990" fill="none" xmlns="http://www.w3.org/2000/svg"> -->
|
||||
<!-- <path d="M909.079 176.687C486.468 1429.32 94.8519 797.145 -245.666 989.191L-273.518 122.311C-98.0847 109.104 255.784 81.3405 267.79 75.9479C282.798 69.2072 1153.31 -485.661 1071.51 -140.889C1022.28 -26.4819 1001.45 -97.0987 909.079 176.687Z" fill="url(#paint0_linear_228_76)" fill-opacity="1" /> -->
|
||||
<!-- <defs> -->
|
||||
<!-- <linearGradient id="paint0_linear_228_76" x1="588.47" y1="791.265" x2="238.137" y2="497.91" gradientUnits="userSpaceOnUse"> -->
|
||||
<!-- <stop stop-color="#FF4400"/> -->
|
||||
<!-- <stop offset="1" stop-color="#111" /> -->
|
||||
<!-- </linearGradient> -->
|
||||
<!-- </defs> -->
|
||||
<!-- </svg> -->
|
||||
<svg width="1056" height="855" viewBox="0 0 1056 855" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M888.078 42.3027C465.467 1294.94 73.851 662.761 -266.667 854.807L-294.519 -12.0732C-119.086 -25.2807 234.783 -53.0438 246.789 -58.4364C261.797 -65.1771 1132.31 -620.045 1050.51 -275.273C1001.28 -160.866 980.447 -231.483 888.078 42.3027Z" fill="url(#paint0_radial_228_76)"/>
|
||||
<defs>
|
||||
<radialGradient id="paint0_radial_228_76" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(666.999 571.116) rotate(-129.513) scale(513.947 862.777)">
|
||||
<stop stop-color="#FF4400"/>
|
||||
<stop offset="1" stop-color="#111111"/>
|
||||
</radialGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
20
docs/assets/img/blobs/blob2.svg
Normal file
20
docs/assets/img/blobs/blob2.svg
Normal file
@@ -0,0 +1,20 @@
|
||||
<!-- <svg width="1405" height="1025" viewBox="0 0 1405 1025" fill="none" xmlns="http://www.w3.org/2000/svg"> -->
|
||||
<!-- <path d="M1180.05 977.4C483.802 708.04 103.247 143.506 0 -105.091L1102.61 -196C1418.53 307.367 1876.29 1246.76 1180.05 977.4Z" fill="url(#paint0_linear_228_83)" fill-opacity="0.44"/> -->
|
||||
<!-- <defs> -->
|
||||
<!-- <linearGradient id="paint0_linear_228_83" x1="185.171" y1="460.565" x2="641.405" y2="-62.9701" gradientUnits="userSpaceOnUse"> -->
|
||||
<!-- <stop stop-color="#BB44CC"/> -->
|
||||
<!-- <stop offset="1" stop-color="#BB44CC" stop-opacity="0"/> -->
|
||||
<!-- </linearGradient> -->
|
||||
<!-- </defs> -->
|
||||
<!-- </svg> -->
|
||||
|
||||
<svg width="1405" height="1025" viewBox="0 0 1405 1025" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M1180.05 977.4C483.802 708.04 103.247 143.506 0 -105.091L1102.61 -196C1418.53 307.367 1876.29 1246.76 1180.05 977.4Z" fill="url(#paint0_radial_228_83)"/>
|
||||
<defs>
|
||||
<radialGradient id="paint0_radial_228_83" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(498 619) rotate(-46.5881) scale(548.572 1194.34)">
|
||||
<stop stop-color="#BB44CC"/>
|
||||
<stop offset="1" stop-color="#111111"/>
|
||||
</radialGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
20
docs/assets/img/blobs/blob3.svg
Normal file
20
docs/assets/img/blobs/blob3.svg
Normal file
@@ -0,0 +1,20 @@
|
||||
<!-- <svg width="2402" height="275" viewBox="0 0 2402 275" fill="none" xmlns="http://www.w3.org/2000/svg"> -->
|
||||
<!-- <path d="M305.668 155.376C1150.52 -387.169 3270.85 708.01 2011.14 262.274L1847.48 804.627C1613.84 721.267 1142.31 553.804 1125.29 550.832C1104 547.117 -168.361 431.431 18.8067 264.119C109.949 220.108 121.011 273.958 305.668 155.376Z" fill="url(#paint0_linear_228_78)" fill-opacity="0.66"/> -->
|
||||
<!-- <defs> -->
|
||||
<!-- <linearGradient id="paint0_linear_228_78" x1="869.047" y1="-51.7999" x2="921.583" y2="353.448" gradientUnits="userSpaceOnUse"> -->
|
||||
<!-- <stop stop-color="#44BBCC"/> -->
|
||||
<!-- <stop offset="1" stop-color="#44BBCC" stop-opacity="0.12"/> -->
|
||||
<!-- </linearGradient> -->
|
||||
<!-- </defs> -->
|
||||
<!-- </svg> -->
|
||||
|
||||
<svg width="2402" height="275" viewBox="0 0 2402 275" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M305.668 155.376C1150.52 -387.169 3270.85 708.01 2011.14 262.274L1847.48 804.627C1613.84 721.267 1142.31 553.804 1125.29 550.832C1104 547.117 -168.361 431.431 18.8067 264.119C109.949 220.108 121.011 273.958 305.668 155.376Z" fill="url(#paint0_radial_228_78)"/>
|
||||
<defs>
|
||||
<radialGradient id="paint0_radial_228_78" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(883.5 -66) rotate(93.0267) scale(757.557 879.417)">
|
||||
<stop stop-color="#44BBCC"/>
|
||||
<stop offset="1" stop-color="#111111"/>
|
||||
</radialGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
66
docs/components/marquee.jsx
Normal file
66
docs/components/marquee.jsx
Normal file
@@ -0,0 +1,66 @@
|
||||
import { useState, useEffect } from "react"
|
||||
import { motion } from "framer-motion"
|
||||
|
||||
const clamp = (num, min, max) => Math.min(Math.max(num, min), max)
|
||||
|
||||
export default function Marquee({ files }) {
|
||||
const [{ width, height }, setSize] = useState({ height: 0, width: 0 })
|
||||
useEffect(() => {
|
||||
setSize({
|
||||
width: window.innerWidth,
|
||||
height: window.innerHeight,
|
||||
})
|
||||
}, [])
|
||||
|
||||
if (width === 0) return
|
||||
|
||||
return (
|
||||
<div className="absolute w-full h-full top-0 left-0 dark:opacity-5 opacity-20 saturate-0 brightness-75 dark:brightness-[1000] -z-20 overflow-hidden flex flex-col marquee-wrapper">
|
||||
{files.map((name) => (
|
||||
<MarqueeItem key={name} name={name} width={width} height={height} />
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function MarqueeItem({ name, width, height }) {
|
||||
const [y] = useState(height * Math.random())
|
||||
const [reset, setReset] = useState(false)
|
||||
const [duration] = useState(clamp(Math.random() * 25, 20, 25))
|
||||
const offset = Math.random() * width
|
||||
useEffect(() => {
|
||||
const timeout =
|
||||
setTimeout(() => {
|
||||
setReset(true)
|
||||
}, (1000 * (width - offset)) / duration) - 2000
|
||||
return () => clearTimeout(timeout)
|
||||
}, [duration, width, offset])
|
||||
return (
|
||||
<motion.span
|
||||
key={name + reset}
|
||||
className="absolute flex items-center justify-center"
|
||||
initial={{ x: reset ? 0 : offset, y }}
|
||||
animate={{ x: width }}
|
||||
transition={{
|
||||
repeat: Infinity,
|
||||
duration: reset ? duration : (width - offset) / duration,
|
||||
ease: "linear",
|
||||
}}
|
||||
>
|
||||
<motion.img
|
||||
src={`/img/providers/${name}`}
|
||||
alt={name}
|
||||
className="relative w-12 drop-shadow-xl"
|
||||
initial={{ opacity: 0, scale: 0.5 }}
|
||||
animate={{ opacity: 1, scale: 1 }}
|
||||
transition={{
|
||||
delay: reset ? 0 : Math.random() * 5,
|
||||
duration: 1,
|
||||
type: "spring",
|
||||
|
||||
stiffness: 150,
|
||||
}}
|
||||
/>
|
||||
</motion.span>
|
||||
)
|
||||
}
|
||||
85
docs/components/triangle.jsx
Normal file
85
docs/components/triangle.jsx
Normal file
@@ -0,0 +1,85 @@
|
||||
export default function Triangle({ className }) {
|
||||
return (
|
||||
<svg
|
||||
id="triangle"
|
||||
viewBox="0 0 445 379"
|
||||
className={className}
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<style jsx>
|
||||
{`
|
||||
@media (prefers-color-scheme: light) {
|
||||
#triangle-0 {
|
||||
fill: #000;
|
||||
}
|
||||
#triangle-1 {
|
||||
fill: #ff4400;
|
||||
}
|
||||
#triangle-2 {
|
||||
fill: #bb44cc;
|
||||
}
|
||||
#triangle-3 {
|
||||
fill: #44bbcc;
|
||||
}
|
||||
}
|
||||
`}
|
||||
</style>
|
||||
<path
|
||||
id="triangle-0"
|
||||
d="M334.033 238.33L222.692 46.7201L111.352 238.33H334.033Z"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
id="triangle-1"
|
||||
d="M198.174 1.12812L4.62255 51.2473C1.37638 52.0878 -0.550786 55.4258 0.344333 58.6574L53.7157 251.338C55.1362 256.466 62.0336 257.344 64.6942 252.736L204.874 9.93656C207.535 5.32834 203.325 -0.205751 198.174 1.12812Z"
|
||||
fill="url(#triangle-1-gradient)"
|
||||
/>
|
||||
<path
|
||||
id="triangle-2"
|
||||
d="M246.294 1.12825L439.846 51.2473C443.092 52.0879 445.019 55.4259 444.124 58.6574L390.753 251.338C389.332 256.466 382.435 257.344 379.774 252.736L239.594 9.93665C236.933 5.32844 241.143 -0.205634 246.294 1.12825Z"
|
||||
fill="url(#triangle-2-gradient)"
|
||||
/>
|
||||
<path
|
||||
id="triangle-3"
|
||||
d="M361.388 286.577L225.585 377.959C223.559 379.322 220.91 379.322 218.885 377.959L83.0814 286.577C78.1672 283.27 80.5079 275.599 86.4311 275.599H358.039C363.962 275.599 366.303 283.27 361.388 286.577Z"
|
||||
fill="url(#triangle-3-gradient)"
|
||||
/>
|
||||
<defs>
|
||||
<linearGradient
|
||||
id="triangle-1-gradient"
|
||||
x1="-1.28386"
|
||||
y1="52.7769"
|
||||
x2="134.785"
|
||||
y2="131.336"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop stopColor="#992900" />
|
||||
<stop offset="1" stopColor="#FF4400" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="triangle-2-gradient"
|
||||
x1="445.753"
|
||||
y1="52.7769"
|
||||
x2="309.684"
|
||||
y2="131.336"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop stopColor="#6D2178" />
|
||||
<stop offset="1" stopColor="#BB44CC" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="triangle-3-gradient"
|
||||
x1="222.236"
|
||||
y1="380.213"
|
||||
x2="222.236"
|
||||
y2="275.599"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop stopColor="#1B5B64" />
|
||||
<stop offset="1" stopColor="#44BBCC" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"label": "Concepts",
|
||||
"collapsible": true,
|
||||
"collapsed": true
|
||||
}
|
||||
@@ -1,207 +0,0 @@
|
||||
---
|
||||
id: faq
|
||||
title: Frequently Asked Questions
|
||||
---
|
||||
|
||||
## About Auth.js
|
||||
|
||||
### Is Auth.js commercial software?
|
||||
|
||||
Auth.js is an open-source project built by individual contributors.
|
||||
|
||||
It is not commercial software and is not associated with a commercial organization.
|
||||
|
||||
---
|
||||
|
||||
## Compatibility
|
||||
|
||||
<details>
|
||||
<summary>
|
||||
<h3 style={{display: "inline-block"}}>What databases does Auth.js support?</h3>
|
||||
</summary>
|
||||
<p>
|
||||
|
||||
You can use Auth.js with MySQL, MariaDB, Postgres, MongoDB and SQLite or without a database. (See our [using a database adapter guide](/guides/adapters/using-a-database-adapter)).
|
||||
|
||||
You can use also Auth.js with any database using a custom database adapter, or by using a custom credentials authentication provider - e.g. to support signing in with a username and password stored in an existing database.
|
||||
|
||||
</p>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>
|
||||
<h3 style={{display: "inline-block"}}>What authentication services does Auth.js support?</h3>
|
||||
</summary>
|
||||
<p>
|
||||
|
||||
<p>Auth.js includes built-in support for signing in with
|
||||
(See also: <a href="/reference/providers/oauth-builtin">Providers</a>)
|
||||
</p>
|
||||
|
||||
Auth.js also supports email for passwordless sign-in, which is useful for account recovery or for people who are not able to use an account with the configured OAuth services (e.g. due to service outage, account suspension or otherwise becoming locked out of an account).
|
||||
|
||||
You can also use a custom-based provider to support signing in with a username and password stored in an external database and/or using two-factor authentication.
|
||||
|
||||
</p>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>
|
||||
<h3 style={{display: "inline-block"}}>Does Auth.js support signing in with a username and password?</h3>
|
||||
</summary>
|
||||
<p>
|
||||
|
||||
Auth.js is designed to avoid the need to store passwords for user accounts.
|
||||
|
||||
If you have an existing database of usernames and passwords, you can use a custom credentials provider to allow signing in with a username and password stored in an existing database.
|
||||
|
||||
_If you use a custom credentials provider user accounts will not be persisted in a database by Auth.js (even if one is configured). The option to use JSON Web Tokens for session tokens (which allow sign-in without using a session database) must be enabled to use a custom credentials provider._
|
||||
|
||||
</p>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>
|
||||
<h3 style={{display: "inline-block"}}>Can I use Auth.js with a website that does not use Next.js?</h3>
|
||||
</summary>
|
||||
<p>
|
||||
|
||||
Auth.js is designed for use with Next.js and Serverless.
|
||||
|
||||
If you are using a different framework for your website, you can create a website that handles sign-in with Next.js and then access those sessions on a website that does not use Next.js as long as the websites are on the same domain.
|
||||
|
||||
If you use Auth.js on a website with a different subdomain than the rest of your website (e.g. `auth.example.com` vs `www.example.com`) you will need to set a custom cookie domain policy for the Session Token cookie. (See also: [Cookies](/reference/configuration/auth-config#cookies))
|
||||
|
||||
Auth.js does not currently support automatically signing into sites on different top-level domains (e.g. `www.example.com` vs `www.example.org`) using a single session.
|
||||
|
||||
</p>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>
|
||||
<h3 style={{display: "inline-block"}}>Can I use Auth.js with React Native?</h3>
|
||||
</summary>
|
||||
<p>
|
||||
|
||||
Auth.js is designed as a secure, confidential client and implements a server-side authentication flow.
|
||||
|
||||
It is not intended to be used in native applications on desktop or mobile applications, which typically implement public clients (e.g. with client/secrets embedded in the application).
|
||||
|
||||
</p>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>
|
||||
<h3 style={{display: "inline-block"}}>Is Auth.js supporting TypeScript?</h3>
|
||||
</summary>
|
||||
<p>
|
||||
|
||||
Yes! Check out the [TypeScript docs](/getting-started/typescript)
|
||||
|
||||
</p>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>
|
||||
<h3 style={{display: "inline-block"}}>Is Auth.js compatible with Next.js 12 Middleware?</h3>
|
||||
</summary>
|
||||
<p>
|
||||
|
||||
[Next.js Middleware](https://nextjs.org/docs/middleware) is supported. Head over to [this page](https://next-auth.js.org/configuration/nextjs#middleware)
|
||||
|
||||
</p>
|
||||
</details>
|
||||
|
||||
---
|
||||
|
||||
## Session strategies
|
||||
|
||||
Check out the [Session strategies page](/concepts/session-strategies) to learn more.
|
||||
|
||||
---
|
||||
|
||||
## Security
|
||||
|
||||
Parts of this section have been moved to their [page](/security)](/security).
|
||||
|
||||
<details>
|
||||
<summary>
|
||||
<h3 style={{display: "inline-block"}}>How do I get Refresh Tokens and Access Tokens for an OAuth account?</h3>
|
||||
</summary>
|
||||
<p>
|
||||
|
||||
Auth.js provides a solution for authentication, session management and user account creation.
|
||||
|
||||
Auth.js records Refresh Tokens and Access Tokens on sign-in (if supplied by the provider) and it will pass them, along with the User ID, Provider and Provider Account ID, to either:
|
||||
|
||||
1. A database - if a database connection string is provided
|
||||
2. The JSON Web Token callback - if JWT sessions are enabled (e.g. if no database is specified)
|
||||
|
||||
You can then look them up from the database or persist them to the JSON Web Token.
|
||||
|
||||
Note: Auth.js does not currently handle Access Token rotation for OAuth providers for you, however, you can check out [this tutorial](/guides/basics/refresh-token-rotation) if you want to implement it.
|
||||
|
||||
</p>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>
|
||||
<h3 style={{display: "inline-block"}}>When I sign in with another account with the same email address, why are accounts not linked automatically?</h3>
|
||||
</summary>
|
||||
<p>
|
||||
|
||||
Automatic account linking on sign-in is not secure between arbitrary providers - except for allowing users to sign in via email addresses as a fallback (as they must verify their email address as part of the flow).
|
||||
|
||||
When an email address is associated with an OAuth account it does not necessarily mean that it has been verified as belonging to the account holder — how email address verification is handled is not part of the OAuth specification and varies between providers (e.g. some do not verify first, some do verify first, others return metadata indicating the verification status).
|
||||
|
||||
With automatic account linking on sign-in, this can be exploited by bad parties to hijack accounts by creating an OAuth account associated with the email address of another user.
|
||||
|
||||
For this reason, it is not secure to automatically link accounts between arbitrary providers on sign-in, which is why this feature is generally not provided by an authentication service and is not provided by Auth.js.
|
||||
|
||||
Automatic account linking is seen on some sites, sometimes insecurely. It can be technically possible to do automatic account linking securely if you trust all the providers involved to ensure they have securely verified the email address associated with the account, but requires placing trust (and transferring the risk) to those providers to handle the process securely.
|
||||
|
||||
Examples of scenarios where this is secure include an OAuth provider you control (e.g. that only authorizes users internal to your organization) or a provider you explicitly trust to have verified the users' email address.
|
||||
|
||||
Automatic account linking is not a planned feature of Auth.js, however, there is scope to improve the user experience of account linking and of handling this flow, securely. Typically this involves providing a fallback option to sign in via email, which is already possible (and recommended), but the current implementation of this flow could be improved.
|
||||
|
||||
Providing support for secure account linking and unlinking of additional providers - which can only be done if a user is already signed in - was originally a feature in v1.x but has not been present since v2.0, and is planned to return in a future release.
|
||||
|
||||
</p>
|
||||
</details>
|
||||
|
||||
---
|
||||
|
||||
## Feature Requests
|
||||
|
||||
<details>
|
||||
<summary>
|
||||
<h3 style={{display: "inline-block"}}>Why doesn't Auth.js support [a particular feature]?</h3>
|
||||
</summary>
|
||||
<p>
|
||||
|
||||
Auth.js is an open-source project built by individual contributors who are volunteers writing code and providing support in their spare time.
|
||||
|
||||
If you would like Auth.js to support a particular feature, the best way to help make it happen is to raise a feature request describing the feature and offer to work with other contributors to develop and test it.
|
||||
|
||||
If you are not able to develop a feature yourself, you can offer to sponsor someone to work on it.
|
||||
|
||||
</p>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>
|
||||
<h3 style={{display: "inline-block"}}>I disagree with a design decision, how can I change your mind?</h3>
|
||||
</summary>
|
||||
<p>
|
||||
|
||||
Product design decisions on Auth.js are made by core team members.
|
||||
|
||||
You can raise suggestions as feature requests for enhancement.
|
||||
|
||||
Requests that provide the detail requested in the template and follow the format requested may be more likely to be supported, as additional detail prompted in the templates often provides important context.
|
||||
|
||||
Ultimately if your request is not accepted or is not actively in development, you are always free to fork the project under the terms of the ISC License.
|
||||
|
||||
</p>
|
||||
</details>
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
---
|
||||
title: Session strategies
|
||||
---
|
||||
|
||||
When a user logs into your application, you usually want them to not need to log in for some time. This is called a session. Auth.js libraries support different session strategies, which are described below.
|
||||
|
||||
:::note
|
||||
Both strategies have advantages and disadvantages which you have to evaluate based on your requirements
|
||||
:::
|
||||
|
||||
Check out the [`session.strategy`](/reference/core#session) option to see how you can configure the session strategy of your Auth.js library.
|
||||
|
||||
## JWT
|
||||
|
||||
Auth.js libraries can create sessions using [JSON Web Tokens (JWT)](https://datatracker.ietf.org/doc/html/rfc7519). This is the default session strategy for Auth.js libraries. When a user signs in, a JWT is created in a `HttpOnly` cookie. Making the cookie HttpOnly prevents JavaScript from accessing it client-side (`document.cookie`), which makes it harder for attackers to steal the value. In addition, the JWT is encrypted with a secret key only known to the server. So even if an attacker were to steal the JWT from the cookie, they would not be able to decrypt it. Combined with a short expiration time, this makes JWTs a secure way to create sessions.
|
||||
|
||||
When a user signs out, the JWT is deleted from the cookies, and the session is destroyed.
|
||||
|
||||
### Advantages
|
||||
|
||||
- JWTs as a session do not require a database to store sessions, this can be faster and cheaper to run and easier to scale.
|
||||
- Retrieving a JWT session can always run on the Edge.
|
||||
- Using this strategy requires fewer resources as you don't need to manage an extra database/service.
|
||||
- You may then use the created token to pass information between services and APIs on the same domain without having to contact a database to verify the included information.
|
||||
- You can use JWT to securely store information without exposing it to third-party JavaScript running on your site.
|
||||
|
||||
### Disadvantages
|
||||
|
||||
- Expiring a JSON Web Token before its encoded expiry is not possible - doing so requires maintaining a server-side blocklist of invalidated tokens (at least until they truly expire) and checking every token against the list every time a token is presented. Auth.js **will** destroy the cookie, but if the user has the JWT saved elsewhere, it will be valid (the server will accept it) until it expires. (Shorter session expiry times are used when using JSON Web Tokens as session tokens to allow sessions to be invalidated sooner and simplify this problem.)
|
||||
- Auth.js clients enable advanced features to mitigate the downsides of using shorter session expiry times on the user experience, including automatic session token rotation, optionally sending keep-alive messages (session polling) to prevent short-lived sessions from expiring if there is a window or tab open, background re-validation, and automatic tab/window syncing that keeps sessions in sync across windows any time session state changes or a window or tab gains or loses focus.
|
||||
- As with database session tokens, JSON Web Tokens are limited in the amount of data you can store in them. There is typically a limit of around 4096 bytes per cookie, though the exact limit varies between browsers. The more data you try to store in a token and the more other cookies you set, the closer you will come to this limit. Auth.js libraries implement session cookie chunking so that cookies over the 4kb limit will get split and reassembled upon parsing. However since this data needs to be transmitted on every request, you need to be aware of how much data you want to transfer using this technique.
|
||||
- Even if appropriately configured, information stored in an encrypted JWT should not be assumed to be impossible to decrypt at some point - e.g. due to the discovery of a defect or advances in technology. Data stored in an encrypted JSON Web Token (JWE) _may_ be compromised at some point. The recommendation is to generate a [secret](/reference/core#secret) with high entropy.
|
||||
|
||||
## Database
|
||||
|
||||
Alternatively, to a JWT session strategy, Auth.js libraries also support database sessions. In this case, instead of saving a JWT with user data after signing in, Auth.js libraries will create a session in your database. A session ID is then saved in a `HttpOnly` cookie. This is similar to the JWT session strategy, but instead of saving the user data in the cookie, it only stores an obscure value pointing to the session in the database. So whenever you will try to access the user session, you will query the database for the data.
|
||||
|
||||
When a user signs out, the session is deleted from the database, and the session ID is deleted from the cookies.
|
||||
|
||||
### Advantages
|
||||
|
||||
- Database sessions can be at any time modified server-side, so you can implement features that might be more difficult - but not impossible - using the JWT strategy, etc.: "sign out everywhere", or limiting concurrent logins
|
||||
- Auth.js has no opinion on the type of database you are using, we have a big list of [official database adapters](/reference/adapters), but you can [implement your own](guides/adapters/creating-a-database-adapter) as well
|
||||
|
||||
### Disadvantages
|
||||
|
||||
- Database sessions need a roundtrip to your database, so they might be slower on scale unless your connections/databases are accommodated for it
|
||||
- Many database adapters are not yet compatible with the Edge, which would allow faster and cheaper session retrieval
|
||||
- Setting up a database takes more effort and requires extra services to manage compared to the stateless JWT strategy
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"label": "Getting Started",
|
||||
"collapsible": true,
|
||||
"collapsed": true
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
---
|
||||
title: Databases
|
||||
---
|
||||
|
||||
Auth.js offers multiple database adapters. Check our guides on:
|
||||
|
||||
- [Using a database adapter](/guides/adapters/using-a-database-adapter)
|
||||
- [Creating your own](/guides/adapters/creating-a-database-adapter)
|
||||
|
||||
To learn more about databases in Auth.js and how they are used, check out [databases in the FAQ](/concepts/faq#databases).
|
||||
|
||||
## How to use a database
|
||||
|
||||
See the [documentation for adapters](/reference/adapters) for more information on advanced configuration, including how to use Auth.js with other databases using a [custom adapter](/guides/adapters/creating-a-database-adapter).
|
||||
@@ -1,44 +0,0 @@
|
||||
---
|
||||
title: Introduction
|
||||
sidebar_position: 0
|
||||
---
|
||||
|
||||
## About Auth.js
|
||||
|
||||
Auth.js is a complete open-source authentication solution for web applications. Check out the live demos of Auth.js in action:
|
||||
|
||||
- [Next.js](https://next-auth-example.vercel.app/)
|
||||
- [SvelteKit](https://sveltekit-auth-example.vercel.app/)
|
||||
- [SolidStart](https://auth-solid.vercel.app/)
|
||||
|
||||
Continue to our tutorials to see how to use Auth.js for authentication:
|
||||
|
||||
- [Setup with OAuth](/getting-started/oauth-tutorial)
|
||||
- [Setup with magic links](/getting-started/email-tutorial)
|
||||
- [Integrating with external auth](/getting-started/credentials-tutorial)
|
||||
|
||||
### Features
|
||||
|
||||
- Built in support for 60+ popular services (Google, Facebook, Auth0, Apple…)
|
||||
- Built-in email/password-less/magic link
|
||||
- Use with any OAuth 2 or OpenID Connect provider
|
||||
- Use with any username/password store
|
||||
|
||||
### Flexible
|
||||
- Runtime agnostic - run anywhere! Vercel Edge Functions, Node.js, Serverless, etc.
|
||||
- Use with any modern framework! Next.js, SolidStart, SvelteKit, etc.
|
||||
- [Bring Your Own Database](/getting-started/databases) - or none! MySQL, Postgres, MSSQL, MongoDB, etc. Choose database sessions or JWT.
|
||||
|
||||
_Note: Email sign-in requires a database to store single-use verification tokens._
|
||||
|
||||
### Secure by default
|
||||
- Signed, prefixed, server-only cookies
|
||||
- Built-in CSRF protection
|
||||
- Doesn't rely on client-side JavaScript
|
||||
- JWT with JWS / JWE / JWK.
|
||||
|
||||
## Credits
|
||||
|
||||
Auth.js is an open-source project that is only possible [thanks to contributors](/contributors).
|
||||
|
||||
To financially support the development of Auth.js, you can check our [OpenCollective](https://opencollective.com/nextauth) page. We appreciate your support 💚.
|
||||
@@ -1,506 +0,0 @@
|
||||
---
|
||||
title: OAuth authentication
|
||||
---
|
||||
|
||||
import creatingOauthAppImg from "./img/getting-started-creating-oauth-app.png"
|
||||
import addingCallbackUrlImg from "./img/getting-started-oauth-callback-url.png"
|
||||
import gettingClientIdSecretImg from "./img/getting-started-oauth-clientid-secret.png"
|
||||
import startAppAndSignInImg from "./img/getting-started-app-start.png"
|
||||
import githubAuthCredentials from "./img/getting-started-github-auth.png"
|
||||
import nextAuthUserLoggedIn from "./img/getting-started-nextauth-success.png"
|
||||
import Tabs from "@theme/Tabs"
|
||||
import TabItem from "@theme/TabItem"
|
||||
|
||||
The goal of Auth.js is that you can add authentication easily to your project with just a few lines of code.
|
||||
|
||||
The fastest way to set up Auth.js is with an [OAuth](/concepts/oauth) provider. In this tutorial, we'll be setting Auth.js in a web application to be able to log in with **GitHub**.
|
||||
|
||||
:::info
|
||||
Auth.js comes with a list of [built-in providers](/reference/providers/oauth-builtin) (Google, Facebook, Twitter, etc.). You can also integrate it with your OAuth service by [building a custom provider](/guides/providers/custom-provider).
|
||||
:::
|
||||
|
||||
## 1. Configuring Auth.js
|
||||
|
||||
To add Auth.js to your project:
|
||||
|
||||
<Tabs groupId="frameworks" queryString>
|
||||
<TabItem value="next" label="Next.js" default>
|
||||
|
||||
### Prerequisites
|
||||
|
||||
This tutorial assumes you have a Next.js application set up. If you don't, you can follow the [Next.js tutorial](https://nextjs.org/learn/basics/create-nextjs-app) to get started.
|
||||
|
||||
### Installing NextAuth.js
|
||||
|
||||
```bash npm2yarn
|
||||
npm install next-auth
|
||||
```
|
||||
|
||||
### Creating the server config
|
||||
|
||||
Create the following [API route](https://nextjs.org/docs/api-routes/dynamic-api-routes#catch-all-api-routes) file. This route contains the necessary configuration for NextAuth.js, as well as the dynamic route handler:
|
||||
|
||||
```ts title="pages/api/auth/[...nextauth].ts"
|
||||
import NextAuth from "next-auth"
|
||||
import GithubProvider from "next-auth/providers/github"
|
||||
|
||||
export default NextAuth({
|
||||
providers: [
|
||||
GithubProvider({
|
||||
clientId: process.env.GITHUB_ID,
|
||||
clientSecret: process.env.GITHUB_SECRET,
|
||||
}),
|
||||
],
|
||||
})
|
||||
```
|
||||
|
||||
:::info
|
||||
|
||||
Behind the scenes, this creates all the relevant OAuth API routes within `/api/auth/*` so that auth API requests to:
|
||||
|
||||
- [GET `/api/auth/signin`](https://authjs.dev/reference/rest-api#get--apiauthsignin)
|
||||
- [POST `/api/auth/signin/:provider`](https://authjs.dev/reference/rest-api#post--apiauthsigninprovider)
|
||||
- [GET/POST `/api/auth/callback/:provider`](https://authjs.dev/reference/rest-api#get--post--apiauthcallbackprovider)
|
||||
- [GET `/api/auth/signout`](https://authjs.dev/reference/rest-api#get--apiauthsignout)
|
||||
- [POST `/api/auth/signout`](https://authjs.dev/reference/rest-api#post--apiauthsignout)
|
||||
- [GET `/api/auth/session`](https://authjs.dev/reference/rest-api#get--apiauthsession)
|
||||
- [GET `/api/auth/csrf`](https://authjs.dev/reference/rest-api#get--apiauthcsrf)
|
||||
- [GET `/api/auth/providers`](https://authjs.dev/reference/rest-api#get--apiauthproviders)
|
||||
|
||||
can be handled by NextAuth.js. In this way, NextAuth.js stays in charge of the whole application's authentication request/response flow.
|
||||
|
||||
NextAuth.js is fully customizable - [our guides section](/guides/overview) teaches you how to set it up to handle auth in different ways. All the possible configuration options are [listed here](/reference/configuration/auth-config).
|
||||
:::
|
||||
|
||||
### Adding environment variables
|
||||
|
||||
You may notice we are using environment variables in the code example above. We take the value of `GITHUB_ID` and `GITHUB_SECRET` from the GitHub Developer OAuth Portal. See [Configuring OAuth Provider](/getting-started/oauth-tutorial#2-configuring-oauth-provider) section on how to get those.
|
||||
|
||||
In your project root, create a `.env.local` file and add the `NEXTAUTH_SECRET` environment variable:
|
||||
|
||||
```title=".env.local"
|
||||
NEXTAUTH_SECRET="This is an example"
|
||||
```
|
||||
|
||||
`NEXTAUTH_SECRET` is a random string used by the library to encrypt tokens and email verification hashes, and **it's mandatory to keep things secure**! 🔥 🔐 . You can use:
|
||||
|
||||
```
|
||||
openssl rand -base64 32
|
||||
```
|
||||
|
||||
or https://generate-secret.vercel.app/32 to generate a random value for it.
|
||||
|
||||
### Exposing the session via `SessionProvider`:
|
||||
|
||||
NextAuth.js provides [`useSession()`](/reference/react/#usesession) - a [React Hooks](https://reactjs.org/docs/hooks-intro.html) to access the session data and status. To use it first you'll need to expose the session context - [`<SessionProvider />`](/reference/react/#sessionprovider) - at the top level of your application:
|
||||
|
||||
```ts title="pages/_app.tsx"
|
||||
import { SessionProvider } from "next-auth/react"
|
||||
import type { AppProps } from "next/app"
|
||||
|
||||
export default function App({
|
||||
Component,
|
||||
pageProps: { session, ...pageProps },
|
||||
}: AppProps) {
|
||||
return (
|
||||
<SessionProvider session={session}>
|
||||
<Component {...pageProps} />
|
||||
</SessionProvider>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
Instances of `useSession` (more on it in the next section) will have access to the session data and status. The `<SessionProvider />` also keep the session updated and synced between browser tabs and windows. 💪🏽
|
||||
|
||||
:::tip
|
||||
Check our [client docs](/reference/react/) to learn all the available options for handling sessions on the browser.
|
||||
:::
|
||||
|
||||
### Consuming the session via hooks
|
||||
|
||||
You can use the `useSession` hook from anywhere in your application (E.g. in a header component). Behind the scenes, the hook will connect to the `<SessionProvider />` to read the current user session. Learn more about React Context in the [React docs](https://reactjs.org/docs/context.html).
|
||||
|
||||
```ts title="pages/overview.tsx"
|
||||
import { useSession, signIn, signOut } from "next-auth/react"
|
||||
|
||||
export default function CamperVanPage() {
|
||||
const { data: session, status } = useSession()
|
||||
const userEmail = session?.user?.email
|
||||
|
||||
if (status === "loading") {
|
||||
return <p>Hang on there...</p>
|
||||
}
|
||||
|
||||
if (status === "authenticated") {
|
||||
return (
|
||||
<>
|
||||
<p>Signed in as {userEmail}</p>
|
||||
<button onClick={() => signOut()}>Sign out</button>
|
||||
<img src="https://cdn.pixabay.com/photo/2017/08/11/19/36/vw-2632486_1280.png" />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<p>Not signed in.</p>
|
||||
<button onClick={() => signIn("github")}>Sign in</button>
|
||||
</>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
### Protecting API Routes
|
||||
|
||||
To protect your API Routes (blocking unauthorized access to resources), you can use [`getServerSession()`](https://next-auth.js.org/configuration/nextjs#getserversession) to know whether a session exists or not:
|
||||
|
||||
```ts title="pages/api/movies/list.ts"
|
||||
import { getServerSession } from "next-auth/next"
|
||||
import { authOptions } from "../auth/[...nextauth]"
|
||||
|
||||
export default async function listMovies(req, res) {
|
||||
const session = await getServerSession(req, res, authOptions)
|
||||
|
||||
if (session) {
|
||||
res.send({
|
||||
movies: [
|
||||
{ title: "Alien vs Predator", id: 1 },
|
||||
{ title: "Reservoir Dogs", id: 2 },
|
||||
],
|
||||
})
|
||||
} else {
|
||||
res.send({
|
||||
error: "You must sign in to view movies.",
|
||||
})
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="sveltekit" label="SvelteKit">
|
||||
|
||||
:::warning
|
||||
`@auth/sveltekit` is currently experimental. The API _will_ change in the future.
|
||||
:::
|
||||
|
||||
### Prerequisites
|
||||
|
||||
This tutorial assumes you have a SvelteKit application set up. If you don't, you can follow the [SvelteKit tutorial](https://kit.svelte.dev/docs/creating-a-project) to get started.
|
||||
|
||||
### Installing Auth.js
|
||||
|
||||
```bash npm2yarn
|
||||
npm install @auth/core @auth/sveltekit
|
||||
```
|
||||
|
||||
### Create server hook
|
||||
|
||||
Create the following [Server hook](https://kit.svelte.dev/docs/hooks) file. This route contains the necessary configuration for Auth.js, as well as the dynamic route handler:
|
||||
|
||||
```ts title="src/hooks.server.ts"
|
||||
import { SvelteKitAuth } from "@auth/sveltekit"
|
||||
import GitHub from "@auth/core/providers/github"
|
||||
import { GITHUB_ID, GITHUB_SECRET } from "$env/static/private"
|
||||
|
||||
export const handle = SvelteKitAuth({
|
||||
providers: [GitHub({ clientId: GITHUB_ID, clientSecret: GITHUB_SECRET })],
|
||||
})
|
||||
```
|
||||
|
||||
:::info
|
||||
|
||||
Behind the scenes, this creates all the relevant OAuth API routes within `/api/auth/*` so that auth API requests to:
|
||||
|
||||
- [GET `/api/auth/signin`](https://authjs.dev/reference/rest-api#get--apiauthsignin)
|
||||
- [POST `/api/auth/signin/:provider`](https://authjs.dev/reference/rest-api#post--apiauthsigninprovider)
|
||||
- [GET/POST `/api/auth/callback/:provider`](https://authjs.dev/reference/rest-api#get--post--apiauthcallbackprovider)
|
||||
- [GET `/api/auth/signout`](https://authjs.dev/reference/rest-api#get--apiauthsignout)
|
||||
- [POST `/api/auth/signout`](https://authjs.dev/reference/rest-api#post--apiauthsignout)
|
||||
- [GET `/api/auth/session`](https://authjs.dev/reference/rest-api#get--apiauthsession)
|
||||
- [GET `/api/auth/csrf`](https://authjs.dev/reference/rest-api#get--apiauthcsrf)
|
||||
- [GET `/api/auth/providers`](https://authjs.dev/reference/rest-api#get--apiauthproviders)
|
||||
|
||||
can be handled by Auth.js. In this way, Auth.js stays in charge of the whole application's authentication request/response flow.
|
||||
|
||||
Auth.js is fully customizable - [our guides section](/guides/overview) teaches you how to set it up to handle auth in different ways. All the possible configuration options are [listed here](/reference/configuration/auth-config).
|
||||
:::
|
||||
|
||||
### Adding environment variables
|
||||
|
||||
You may notice we are using environment variables in the code example above. We take the value of `GITHUB_ID` and `GITHUB_SECRET` from the GitHub Developer OAuth Portal. See [Configuring OAuth Provider](/getting-started/oauth-tutorial#2-configuring-oauth-provider) section on how to get those.
|
||||
|
||||
In your project root, create a `.env.local` file and add the `AUTH_SECRET` environment variable:
|
||||
|
||||
```title=".env.local"
|
||||
AUTH_SECRET="This is an example"
|
||||
```
|
||||
|
||||
`AUTH_SECRET` is a random string used by the library to encrypt tokens and email verification hashes, and **it's mandatory to keep things secure**! 🔥 🔐 . You can use:
|
||||
|
||||
```
|
||||
openssl rand -base64 32
|
||||
```
|
||||
|
||||
or https://generate-secret.vercel.app/32 to generate a random value for it.
|
||||
|
||||
### Exposing the session via page store
|
||||
|
||||
Auth.js provides us a getSession, function to access the session data and status, to call from the `event.locals` variable. We can now just call it and add it to our `$page` store.
|
||||
|
||||
```ts
|
||||
import type { LayoutServerLoad } from './$types';
|
||||
*
|
||||
export const load: LayoutServerLoad = async (event) => {
|
||||
return {
|
||||
session: await event.locals.getSession()
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
### Consuming the session via page store
|
||||
|
||||
You can use the `$page.data.session` variable from anywhere on your page. Learn more about SvelteKit's page store in the [SvelteKit docs](https://learn.svelte.dev/tutorial/page-store).
|
||||
|
||||
```ts title="route/+page.svelte"
|
||||
<script>
|
||||
import { signIn, signOut } from '@auth/sveltekit/client'
|
||||
import { page } from '$app/stores'
|
||||
</script>
|
||||
|
||||
{#if $page.data.session?.user}
|
||||
<p>Signed in as {$page.data.session.user.email}</p>
|
||||
<button on:click={signOut}>Sign out</button>
|
||||
<img src="https://cdn.pixabay.com/photo/2017/08/11/19/36/vw-2632486_1280.png" />
|
||||
{:else}
|
||||
<p>Not signed in.</p>
|
||||
<button on:click={() => signIn('github')}>Sign in</button>
|
||||
{/if}
|
||||
```
|
||||
|
||||
### Protecting API Routes
|
||||
|
||||
To protect your API Routes (blocking unauthorized access to resources), you can use `locals.getSessions()` just like in the layouts file to know whether a session exists or not:
|
||||
|
||||
```ts title="routes/api/movies/+server.ts"
|
||||
import { json, error } from "@sveltejs/kit"
|
||||
import type { RequestEvent } from "./$types"
|
||||
|
||||
export async function GET({ locals }: RequestEvent) {
|
||||
const session = await locals.getSession()
|
||||
if (!session?.user) {
|
||||
throw error(401, "You must sign in to view movies.")
|
||||
}
|
||||
|
||||
return json({
|
||||
movies: [
|
||||
{ title: "Alien vs Predator", id: 1 },
|
||||
{ title: "Reservoir Dogs", id: 2 },
|
||||
],
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="solidstart" label="SolidStart">
|
||||
TODO: SolidStart
|
||||
</TabItem>
|
||||
<TabItem value="core" label="Vanilla (No Framework)">
|
||||
TODO Core
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## 2. Configuring OAuth Provider
|
||||
|
||||
Ok, we have our app set up with NextAuth.js, however, if you run the app right now, it won't work as we haven't configured our OAuth provider (**GitHub**) yet.
|
||||
|
||||
:::info
|
||||
When using OAuth you're asking for a third-party service (in this case GitHub, although it could be Google, Twitter, etc...) to handle user authentication for your app.
|
||||
:::
|
||||
|
||||
We need to register our new app in GitHub, so that when NextAuth.js forwards the authorization requests to it, GitHub can recognize your application and prompt the user to sign in.
|
||||
|
||||
<img src={creatingOauthAppImg} />
|
||||
|
||||
Log in to **GitHub**, go to [`Settings / Developers / OAuth Apps`](https://github.com/settings/developers) and click "New OAuth App"
|
||||
|
||||
Next, you'll be presented with a screen to add details about your new application. Fill in the required fields, but pay extra attention to the **Authorization Callback URL** one:
|
||||
|
||||
<img src={addingCallbackUrlImg} />
|
||||
|
||||
The callback URL we insert should have the following pattern:
|
||||
|
||||
```
|
||||
[origin]/api/auth/callback/[provider]
|
||||
```
|
||||
|
||||
In this case, given we want to try our authentication working locally on our machine and we're using **GitHub** as our OAuth provider, it'll be:
|
||||
|
||||
<Tabs groupId="frameworks" queryString>
|
||||
<TabItem value="next" label="Next.js" default>
|
||||
|
||||
```
|
||||
http://localhost:3000/api/auth/callback/github
|
||||
```
|
||||
|
||||
:::info
|
||||
NextAuth.js will already create this API endpoint for you when we start the application later. Note that because we're using Next.js, locally it starts our server on port `3000` by default. Hence, the origin is `http://localhost:3000`.
|
||||
:::
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="sveltekit" label="SvelteKit">
|
||||
|
||||
```
|
||||
http://localhost:5173/auth/callback/github
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="solidstart" label="SolidStart">
|
||||
TODO SolidStart
|
||||
</TabItem>
|
||||
<TabItem value="core" label="Vanilla (No Framework)">
|
||||
TODO Core
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
:::info
|
||||
The last part of the URL, `[provider]`, is the ID of the provider you're using. In this case, we're using GitHub, so it's `github`. If you're using Google, it'll be `google`, etc... We keep track of the provider IDs internally.
|
||||
|
||||
The same id is used in the `signIn()` method we saw earlier.
|
||||
:::
|
||||
|
||||
To register, tap on "Register application" button.
|
||||
|
||||
The next screen shows all the configurations for your newly created OAuth app. For now, we need two things from it - the **Client ID** and **Client Secret**:
|
||||
|
||||
<img src={gettingClientIdSecretImg} />
|
||||
|
||||
The Client ID is always there, a public identifier of your OAuth application within GitHub. Click on the **Generate a new client Secret** button and should be presented with a new string (which is just a randomized string).
|
||||
|
||||
:::warning
|
||||
Keep both your Client ID and Client Secret secure and never expose them to the public or share them with people outside your organization. With them, a malicious actor could hijack your application and cause you and your user serious problems!
|
||||
:::
|
||||
|
||||
Cool! We have finished configuring our OAuth provider, now let's wire all together so we can finally see authentication working in our app!
|
||||
|
||||
:::info
|
||||
As noted previously, NextAuth.js has built-in support for multiple OAuth providers, <a href="">here is the full list</a>. You can also easily build your own in case the provider you need is not on the list.
|
||||
|
||||
Note that, for each provider, the configuration process will be similar to what we just did:
|
||||
|
||||
1. Log in to the provider
|
||||
2. Create create your OAuth application within it
|
||||
3. Set the callback URL
|
||||
4. Get the Client ID and Generate a Client Secret
|
||||
:::
|
||||
|
||||
## 3. Wiring all together
|
||||
|
||||
Finally, we just need to reference our **Client ID** and **Client Secret** we just generated in the previous in our Auth.js config. In this way, the library will be able to use them when forwarding users to GitHub, and GitHub will be able to recognize the request as generated from our application.
|
||||
|
||||
Now let's copy both the Client ID and Client Secret and paste them into an environment file in the root of your project like so:
|
||||
|
||||
```title=".env.local"
|
||||
GITHUB_ID=12345
|
||||
GITHUB_SECRET=67890
|
||||
```
|
||||
|
||||
Here is our server configuration file again:
|
||||
|
||||
<Tabs groupId="frameworks" queryString>
|
||||
<TabItem value="next" label="Next.js" default>
|
||||
|
||||
```ts title="pages/api/auth/[...nextauth].ts"
|
||||
import NextAuth from "next-auth"
|
||||
import GithubProvider from "next-auth/providers/github"
|
||||
|
||||
export default NextAuth({
|
||||
providers: [
|
||||
GithubProvider({
|
||||
clientId: process.env.GITHUB_ID,
|
||||
clientSecret: process.env.GITHUB_SECRET,
|
||||
}),
|
||||
],
|
||||
})
|
||||
```
|
||||
|
||||
Great! We're now ready to run our application locally. Start the Next.js app by running on your terminal the following command and navigating to [`http://localhost:3000`](http://localhost:3000):
|
||||
|
||||
```
|
||||
npm run next dev
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="sveltekit" label="SvelteKit">
|
||||
|
||||
```ts title="src/hooks.server.ts"
|
||||
import { SvelteKitAuth } from "@auth/sveltekit"
|
||||
import GitHub from "@auth/core/providers/github"
|
||||
import { GITHUB_ID, GITHUB_SECRET } from "$env/static/private"
|
||||
*
|
||||
export const handle = SvelteKitAuth({
|
||||
providers: [GitHub({ clientId: GITHUB_ID, clientSecret: GITHUB_SECRET })],
|
||||
})
|
||||
```
|
||||
|
||||
Great! We're now ready to run our application locally. Start the Svelte app by running on your terminal the following command and navigating to [`http://localhost:5173`](http://localhost:5173):
|
||||
|
||||
```
|
||||
npm run vite dev
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="solidstart" label="SolidStart">
|
||||
TODO SolidStart
|
||||
</TabItem>
|
||||
<TabItem value="core" label="Vanilla (No Framework)">
|
||||
TODO Core
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
You should see the following page:
|
||||
|
||||
<img src={startAppAndSignInImg} />
|
||||
|
||||
Click on "Sign in" and then on "Sign in with GitHub": Auth.js will redirect you to GitHub, and GitHub will recognize our app [that we just registered](#2-configuring-oauth-provider) and ask the user (in this case you) to enter its credentials to proceed:
|
||||
|
||||
<img src={githubAuthCredentials} />
|
||||
|
||||
Once inserted and correct, GitHub will redirect the user to our app and NextAuth.js will take care of any further calls with GitHub to get access to the user profile and start a user session safely in the background:
|
||||
|
||||
<img src={nextAuthUserLoggedIn} />
|
||||
|
||||
Great! We have completed the whole E2E authentication flow setup so that users can log in to our application through GitHub!
|
||||
|
||||
## 4. Deploying to production
|
||||
|
||||
### Configuring different environments
|
||||
|
||||
It's normal to test your application in different environments. Usually, you'll have a development environment (when you run the application locally on your machine), a staging environment (for team members to try the application), and a production environment.
|
||||
|
||||
For each environment, you need to create an OAuth application in your provider respectively, as [we did previously](#2-configuring-oauth-provider), and point the **callback URL** to it.
|
||||
|
||||
For instance, in the previous section, we pointed the callback URL to `http://localhost:3000/api/auth/callback/github` as we wanted to test our application in the development environment.
|
||||
|
||||
If we were to deploy our app to production, we would need to create a new **OAuth App** in GitHub (calling it something like "Van life – prod") and point the **callback URL** to our production domain: `https://example.com/api/auth/callback/github`
|
||||
|
||||
Finally, we would need to point the environment variables we set ( `GITHUB_ID` and `GITHUB_SECRET` ) to the credentials of the OAuth app we want our application to run with.
|
||||
|
||||
### Setting up `NEXTAUTH_URL`
|
||||
|
||||
:::tip
|
||||
Skip this section if you are deploying to Vercel.
|
||||
:::
|
||||
|
||||
When deploying your site, **you need to set** the `NEXTAUTH_URL` environment variable to the canonical URL of your website:
|
||||
|
||||
```
|
||||
NEXTAUTH_URL=https://example.com
|
||||
```
|
||||
|
||||
:::warning
|
||||
In production, this needs to be set as an environment variable on the service you use to deploy your app.
|
||||
|
||||
To set environment variables on Vercel, you can use the [dashboard](https://vercel.com/dashboard) or the `vercel env pull` [command](https://vercel.com/docs/build-step#development-environment-variables).
|
||||
:::
|
||||
|
||||
For more information please check out our [deployment page](/guides/basics/deployment).
|
||||
@@ -1,612 +0,0 @@
|
||||
---
|
||||
title: Upgrade Guide (v4)
|
||||
---
|
||||
|
||||
Auth.js version 4 includes a few breaking changes from the last major version (3.x). So we're here to help you upgrade your applications as smoothly as possible. It should be possible to upgrade from any version of 3.x to the latest 4 release by following the next few migration steps.
|
||||
|
||||
:::note
|
||||
Version 4 has been released to GA 🚨
|
||||
|
||||
We encourage users to try it out and report any and all issues they come across.
|
||||
:::
|
||||
|
||||
You can upgrade to the new version by running:
|
||||
|
||||
```bash npm2yarn
|
||||
npm install next-auth
|
||||
```
|
||||
|
||||
## `next-auth/jwt`
|
||||
|
||||
We no longer have a default export in `next-auth/jwt`.
|
||||
To comply with this, change the following:
|
||||
|
||||
```diff
|
||||
- import jwt from "next-auth/jwt"
|
||||
+ import { getToken } from "next-auth/jwt"
|
||||
```
|
||||
|
||||
## `next-auth/react`
|
||||
|
||||
We've renamed the client-side import source to `next-auth/react`. To comply with this change, you will simply have to rename anywhere you were using `next-auth/client`.
|
||||
|
||||
For example:
|
||||
|
||||
```diff
|
||||
- import { useSession } from "next-auth/client"
|
||||
+ import { useSession } from "next-auth/react"
|
||||
```
|
||||
|
||||
We've also made the following changes to the names of the exports:
|
||||
|
||||
- `setOptions`: Not exposed anymore, use [`SessionProvider` props](/reference/react/#sessionprovider)
|
||||
- `options`: Not exposed anymore, [use `SessionProvider` props](/reference/react/#sessionprovider)
|
||||
- `session`: Renamed to `getSession`
|
||||
- `providers`: Renamed to `getProviders`
|
||||
- `csrfToken`: Renamed to `getCsrfToken`
|
||||
- `signin`: Renamed to `signIn`
|
||||
- `signout`: Renamed to `signOut`
|
||||
- `Provider`: Renamed to `SessionProvider`
|
||||
|
||||
Introduced in https://github.com/nextauthjs/next-auth/releases/tag/v4.0.0-next.12
|
||||
|
||||
## `SessionProvider`
|
||||
|
||||
Version 4 makes using the `SessionProvider` mandatory. This means that you will have to wrap any part of your application using `useSession` in this provider, if you were not doing so already. The `SessionProvider` has also undergone a few further changes:
|
||||
|
||||
- `Provider` is renamed to `SessionProvider`
|
||||
- The options prop is now flattened as the props of SessionProvider.
|
||||
- `keepAlive` has been renamed to `refetchInterval`.
|
||||
- `clientMaxAge` has been removed in favor of `refetchInterval`, as they overlap in functionality, with the difference that `refetchInterval` will keep re-fetching the session periodically in the background.
|
||||
|
||||
The best practice for wrapping your app in Providers is to do so in your `pages/_app.jsx` file.
|
||||
|
||||
An example use-case with these new changes:
|
||||
|
||||
```jsx
|
||||
import { SessionProvider } from "next-auth/react"
|
||||
|
||||
export default function App({
|
||||
Component,
|
||||
pageProps: { session, ...pageProps },
|
||||
}) {
|
||||
return (
|
||||
// `session` comes from `getServerSideProps` or `getInitialProps`.
|
||||
// Avoids flickering/session loading on first load.
|
||||
<SessionProvider session={session} refetchInterval={5 * 60}>
|
||||
<Component {...pageProps} />
|
||||
</SessionProvider>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
Introduced in https://github.com/nextauthjs/next-auth/releases/tag/v4.0.0-next.12
|
||||
|
||||
## Providers
|
||||
|
||||
Providers now need to be imported individually.
|
||||
|
||||
```diff
|
||||
- import Provider from "next-auth/providers"
|
||||
- Providers.Auth0({...})
|
||||
- Providers.Google({...})
|
||||
+ import Auth0Provider from "next-auth/providers/auth0"
|
||||
+ import GoogleProvider from "next-auth/providers/google"
|
||||
+ Auth0Provider({...})
|
||||
+ GoogleProvider({...})
|
||||
```
|
||||
|
||||
1. The `AzureADB2C` provider has been renamed `AzureAD`.
|
||||
2. The `Basecamp` provider has been removed, see explanation [here](https://github.com/basecamp/api/blob/master/sections/authentication.md#on-authenticating-users-via-oauth).
|
||||
3. The GitHub provider by default now will not request full write access to user profiles. If you need this scope, please add `user` to the scope option manually.
|
||||
|
||||
The following new options are available when defining your Providers in the configuration:
|
||||
|
||||
1. `authorization` (replaces `authorizationUrl`, `authorizationParams`, `scope`)
|
||||
2. `token` replaces (`accessTokenUrl`, `headers`, `params`)
|
||||
3. `userinfo` (replaces `profileUrl`)
|
||||
4. `issuer`(replaces `domain`)
|
||||
|
||||
For more details on their usage, please see [options](/reference/providers/oauth) section of the OAuth Provider documentation.
|
||||
|
||||
When submitting a new OAuth provider to the repository, the `profile` callback is expected to only return these fields from now on: `id`, `name`, `email`, and `image`. If any of these are missing values, they should be set to `null`.
|
||||
|
||||
Also worth noting is that `id` is expected to be returned as a `string` type (For example if your provider returns it as a number, you can cast it by using the `.toString()` method). This makes the returned profile object comply across all providers/accounts/adapters, and hopefully cause less confusion in the future.
|
||||
|
||||
Implemented in: https://github.com/nextauthjs/next-auth/pull/2411
|
||||
Introduced in https://github.com/nextauthjs/next-auth/releases/tag/v4.0.0-next.20
|
||||
|
||||
## `useSession` Hook
|
||||
|
||||
The `useSession` hook has been updated to return an object. This allows you to test states much more cleanly with the new `status` option.
|
||||
|
||||
```diff
|
||||
- const [ session, loading ] = useSession()
|
||||
+ const { data: session, status } = useSession()
|
||||
+ const loading = status === "loading"
|
||||
```
|
||||
|
||||
[Check the docs](/reference/react/#usesession) for the possible values of both `session.status` and `session.data`.
|
||||
|
||||
Introduced in https://github.com/nextauthjs/next-auth/releases/tag/v4.0.0-next.18
|
||||
|
||||
## Named Parameters
|
||||
|
||||
We have changed the arguments to our callbacks to the named parameters pattern. This way you don't have to use dummy `_` placeholders or other tricks.
|
||||
|
||||
### Callbacks
|
||||
|
||||
The signatures for the callback methods now look like this:
|
||||
|
||||
```diff
|
||||
- signIn(user, account, profileOrEmailOrCredentials)
|
||||
+ signIn({ user, account, profile, email, credentials })
|
||||
```
|
||||
|
||||
```diff
|
||||
- redirect(url, baseUrl)
|
||||
+ redirect({ url, baseUrl })
|
||||
```
|
||||
|
||||
```diff
|
||||
- session(session, tokenOrUser)
|
||||
+ session({ session, token, user })
|
||||
```
|
||||
|
||||
```diff
|
||||
- jwt(token, user, account, OAuthProfile, isNewUser)
|
||||
+ jwt({ token, user, account, profile, isNewUser })
|
||||
```
|
||||
|
||||
Introduced in https://github.com/nextauthjs/next-auth/releases/tag/v4.0.0-next.17
|
||||
|
||||
### Events
|
||||
|
||||
Two event signatures have changed to also use the named parameters pattern, `signOut` and `updateUser`.
|
||||
|
||||
```diff
|
||||
// [...nextauth].js
|
||||
...
|
||||
events: {
|
||||
- signOut(tokenOrSession),
|
||||
+ signOut({ token, session }), // token if using JWT, session if DB persisted sessions.
|
||||
- updateUser(user)
|
||||
+ updateUser({ user })
|
||||
}
|
||||
```
|
||||
|
||||
Introduced in https://github.com/nextauthjs/next-auth/releases/tag/v4.0.0-next.20
|
||||
|
||||
## JWT configuration
|
||||
|
||||
We have removed some of the [configuration options](/reference/configuration/auth-config) when using JSON Web Tokens, [here's the PR](https://github.com/nextauthjs/next-auth/pull/3039) for more context.
|
||||
|
||||
```diff
|
||||
export default NextAuth({
|
||||
// ...
|
||||
jwt: {
|
||||
secret,
|
||||
maxAge,
|
||||
- encryptionKey
|
||||
- signingKey
|
||||
- encryptionKey
|
||||
- verificationOptions
|
||||
encode({
|
||||
token
|
||||
secret
|
||||
maxAge
|
||||
- signingKey
|
||||
- signingOptions
|
||||
- encryptionKey
|
||||
- encryptionOptions
|
||||
- encryption
|
||||
}) {},
|
||||
decode({
|
||||
token
|
||||
secret
|
||||
- maxAge
|
||||
- signingKey
|
||||
- verificationKey
|
||||
- verificationOptions
|
||||
- encryptionKey
|
||||
- decryptionKey
|
||||
- decryptionOptions
|
||||
- encryption
|
||||
}) {}
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
## Logger API
|
||||
|
||||
The logger API has been simplified to use at most two parameters, where the second is usually an object (`metadata`) containing an `error` object. If you are not using the logger settings you can ignore this change.
|
||||
|
||||
```diff
|
||||
// [...Auth.js]
|
||||
import log from "some-logger-service"
|
||||
...
|
||||
logger: {
|
||||
- error(code, ...message) {},
|
||||
+ error(code, metadata) {},
|
||||
- warn(code, ...message) {},
|
||||
+ warn(code) {}
|
||||
- debug(code, ...message) {}
|
||||
+ debug(code, metadata) {}
|
||||
}
|
||||
```
|
||||
|
||||
Introduced in https://github.com/nextauthjs/next-auth/releases/tag/v4.0.0-next.19
|
||||
|
||||
## `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`](/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
|
||||
|
||||
## Theme
|
||||
|
||||
We have added some basic customization options to our built-in pages like `signin`, `signout`, etc.
|
||||
|
||||
These can be set under the `theme` configuration key. This used to be a string which only controlled the color scheme option. Now it is an object with the following options:
|
||||
|
||||
```js
|
||||
theme: {
|
||||
colorScheme: "auto", // "auto" | "dark" | "light"
|
||||
brandColor: "", // Hex color value
|
||||
logo: "" // Absolute URL to logo image
|
||||
}
|
||||
```
|
||||
|
||||
The hope is that with some minimal configuration / customization options, users won't immediately feel the need to replace the built-in pages with their own.
|
||||
|
||||
More details and screenshots of the new theme options can be found under [custom pages tutorial](/guides/basics/pages).
|
||||
|
||||
Introduced in https://github.com/nextauthjs/next-auth/pull/2788
|
||||
|
||||
## Session
|
||||
|
||||
The `session.jwt: boolean` option has been renamed to `session.strategy: "jwt" | "database"`. The goal is to make the user's options more intuitive:
|
||||
|
||||
1. No adapter, `strategy: "jwt"`: This is the default. The session is saved in a cookie and never persisted anywhere.
|
||||
2. With Adapter, `strategy: "database"`: If an Adapter is defined, this will be the implicit setting. No user config is needed.
|
||||
3. With Adapter, `strategy: "jwt"`: The user can explicitly instruct `next-auth` to use JWT even if a database is available. This can result in faster lookups in compromise of lowered security. Read more about: https://authjs.dev/concepts/faq#json-web-tokens
|
||||
|
||||
Example:
|
||||
|
||||
```diff
|
||||
session: {
|
||||
- jwt: true,
|
||||
+ strategy: "jwt",
|
||||
}
|
||||
```
|
||||
|
||||
Introduced in https://github.com/nextauthjs/next-auth/pull/3144
|
||||
|
||||
## Adapters
|
||||
|
||||
Most importantly, the core `next-auth` package no longer ships with `typeorm` or any other database adapter by default. This brings the default bundle size down significantly for those not needing to persist user data to a database.
|
||||
|
||||
You can find the official Adapters in the `packages` directory in the primary monorepo ([nextauthjs/next-auth](https://github.com/nextauthjs/next-auth)). Although you can still [create your own](/guides/adapters/creating-a-database-adapter) with a new, [simplified Adapter API](https://github.com/nextauthjs/next-auth/pull/2361).
|
||||
|
||||
If you have a database that was created with a `3.x.x` or earlier version of Auth.js, you will need to run a migration to update the schema to the new version 4 database model. See the bottom of this migration guide for database specific migration examples.
|
||||
|
||||
1. If you use the built-in TypeORM or Prisma adapters, these have been removed from the core `next-auth` package. Thankfully the migration is easy; you just need to install the external packages for your database and change the import in your `[...nextauth].js`.
|
||||
|
||||
The `database` option has been removed, you must now do the following instead:
|
||||
|
||||
```diff
|
||||
// [...nextauth].js
|
||||
import NextAuth from "next-auth"
|
||||
+ import { TypeORMLegacyAdapter } from "@next-auth/typeorm-legacy-adapter"
|
||||
|
||||
...
|
||||
export default NextAuth({
|
||||
- database: "yourconnectionstring",
|
||||
+ adapter: TypeORMLegacyAdapter("yourconnectionstring")
|
||||
})
|
||||
```
|
||||
|
||||
2. The `prisma-legacy` adapter has been removed, please use the [`@next-auth/prisma-adapter`](https://npmjs.com/package/@next-auth/prisma-adapter) instead.
|
||||
|
||||
3. The `typeorm-legacy` adapter has been upgraded to use the newer adapter API, but has retained the `typeorm-legacy` name. We aim to migrate this to individual lighter weight adapters for each database type in the future, or switch out `typeorm`.
|
||||
|
||||
4. MongoDB has been moved to its own adapter under `@next-auth/mongodb-adapter`. See the [MongoDB Adapter docs](/reference/adapters/mongodb).
|
||||
|
||||
Introduced in https://github.com/nextauthjs/next-auth/releases/tag/v4.0.0-next.8 and https://github.com/nextauthjs/next-auth/pull/2361
|
||||
|
||||
### Adapter API
|
||||
|
||||
**This does not require any changes from the user - these are adapter specific changes only**
|
||||
|
||||
The Adapter API has been rewritten and significantly simplified in NextAuth v4. The adapters now have less work to do as some functionality has been migrated to the core of NextAuth, like hashing the [verification token](/reference/adapters/models/#verification-token).
|
||||
|
||||
If you are an adapter maintainer or are interested in writing your own adapter, you can find more information about this change in https://github.com/nextauthjs/next-auth/pull/2361 and release https://github.com/nextauthjs/next-auth/releases/tag/v4.0.0-next.22.
|
||||
|
||||
### Schema changes
|
||||
|
||||
The way we save data with adapters have slightly changed. With the new Adapter API, we wanted to make it easier to extend your database with additional fields. For example if your User needs an extra `phone` field, it should be enough to add that to your database's schema, and no changes will be necessary in your adapter.
|
||||
|
||||
- `created_at`/`createdAt` and `updated_at`/`updatedAt` fields are removed from all Models.
|
||||
- `user_id`/`userId` consistently named `userId`.
|
||||
- `compound_id`/`compoundId` is removed from Account.
|
||||
- `access_token`/`accessToken` is removed from Session.
|
||||
- `email_verified`/`emailVerified` on User is consistently named `emailVerified`.
|
||||
- `provider_id`/`providerId` renamed to `provider` on Account
|
||||
- `provider_type`/`providerType` renamed to `type` on Account
|
||||
- `provider_account_id`/`providerAccountId` on Account is consistently named `providerAccountId`
|
||||
- `access_token_expires`/`accessTokenExpires` on Account renamed to `expires_at`
|
||||
- New fields on Account: `token_type`, `scope`, `id_token`, `session_state`
|
||||
- `verification_requests` table has been renamed to `verification_tokens`
|
||||
|
||||
<!-- REVIEW: Would something like this below be helpful? -->
|
||||
<details>
|
||||
<summary>
|
||||
See the changes
|
||||
</summary>
|
||||
<pre>
|
||||
|
||||
```diff
|
||||
User {
|
||||
id
|
||||
name
|
||||
email
|
||||
- emailVerified
|
||||
+ email_verified
|
||||
image
|
||||
- created_at
|
||||
- updated_at
|
||||
}
|
||||
|
||||
Account {
|
||||
id
|
||||
- compound_id
|
||||
- user_id
|
||||
+ userId
|
||||
- provider_type
|
||||
+ type
|
||||
- provider_id
|
||||
+ provider
|
||||
- provider_account_id
|
||||
+ providerAccountId
|
||||
refresh_token
|
||||
access_token
|
||||
- access_token_expires
|
||||
+ expires_in
|
||||
+ expires_at
|
||||
+ token_type
|
||||
+ scope
|
||||
+ id_token
|
||||
+ session_state
|
||||
- created_at
|
||||
- updated_at
|
||||
}
|
||||
|
||||
Session {
|
||||
id
|
||||
userId
|
||||
expires
|
||||
sessionToken
|
||||
- access_token
|
||||
- created_at
|
||||
- updated_at
|
||||
}
|
||||
|
||||
VerificationToken {
|
||||
id
|
||||
token
|
||||
expires
|
||||
identifier
|
||||
- created_at
|
||||
- updated_at
|
||||
}
|
||||
```
|
||||
|
||||
</pre>
|
||||
</details>
|
||||
|
||||
For more info, see the [Models page](/reference/adapters/models).
|
||||
|
||||
### Database migration
|
||||
|
||||
Auth.js v4 has a slightly different database schema compared to v3. If you're using any of our adapters and want to upgrade, you can use on of the below schemas.
|
||||
|
||||
They are designed to be run directly against the database itself. So instead of having one in Prisma syntax, one in TypeORM syntax, etc. we've decided to just make one for each underlying database type. i.e. one for Postgres, one for MySQL, one for MongoDB, etc.
|
||||
|
||||
#### MySQL
|
||||
|
||||
```sql
|
||||
/* ACCOUNT */
|
||||
ALTER TABLE accounts
|
||||
CHANGE "access_token_expires" "expires_at" int
|
||||
CHANGE "user_id" "userId" varchar(255)
|
||||
ADD CONSTRAINT fk_user_id FOREIGN KEY (userId) REFERENCES users(id)
|
||||
RENAME COLUMN "provider_id" "provider"
|
||||
RENAME COLUMN "provider_account_id" "providerAccountId"
|
||||
DROP COLUMN "provider_type"
|
||||
DROP COLUMN "compound_id"
|
||||
/* The following two timestamp columns have never been necessary for Auth.js to function, but can be kept if you want */
|
||||
DROP COLUMN "created_at"
|
||||
DROP COLUMN "updated_at"
|
||||
|
||||
ADD COLUMN "token_type" varchar(255) NULL
|
||||
ADD COLUMN "scope" varchar(255) NULL
|
||||
ADD COLUMN "id_token" varchar(255) NULL
|
||||
ADD COLUMN "session_state" varchar(255) NULL
|
||||
|
||||
/* Note: These are only needed if you're going to be using the old Twitter OAuth 1.0 provider. */
|
||||
ADD COLUMN "oauth_token_secret" varchar(255) NULL
|
||||
ADD COLUMN "oauth_token" varchar(255) NULL
|
||||
|
||||
/* USER */
|
||||
ALTER TABLE users
|
||||
RENAME COLUMN "email_verified" "emailVerified"
|
||||
/* The following two timestamp columns have never been necessary for Auth.js to function, but can be kept if you want */
|
||||
DROP COLUMN "created_at"
|
||||
DROP COLUMN "updated_at"
|
||||
|
||||
/* SESSION */
|
||||
ALTER TABLE sessions
|
||||
RENAME COLUMN "session_token" "sessionToken"
|
||||
CHANGE "user_id" "userId" varchar(255)
|
||||
ADD CONSTRAINT fk_user_id FOREIGN KEY (userId) REFERENCES users(id)
|
||||
DROP COLUMN "access_token"
|
||||
/* The following two timestamp columns have never been necessary for Auth.js to function, but can be kept if you want */
|
||||
DROP COLUMN "created_at"
|
||||
DROP COLUMN "updated_at"
|
||||
|
||||
/* VERIFICATION REQUESTS */
|
||||
ALTER TABLE verification_requests RENAME verification_tokens
|
||||
ALTER TABLE verification_tokens
|
||||
DROP COLUMN id
|
||||
/* The following two timestamp columns have never been necessary for Auth.js to function, but can be kept if you want */
|
||||
DROP COLUMN "created_at"
|
||||
DROP COLUMN "updated_at"
|
||||
```
|
||||
|
||||
#### Postgres
|
||||
|
||||
```sql
|
||||
/* ACCOUNT */
|
||||
ALTER TABLE accounts RENAME COLUMN "user_id" TO "userId";
|
||||
ALTER TABLE accounts RENAME COLUMN "provider_id" TO "provider";
|
||||
ALTER TABLE accounts RENAME COLUMN "provider_account_id" TO "providerAccountId";
|
||||
ALTER TABLE accounts RENAME COLUMN "access_token_expires" TO "expires_at";
|
||||
ALTER TABLE accounts RENAME COLUMN "provider_type" TO "type";
|
||||
|
||||
/* Do conversion of TIMESTAMPTZ to BIGINT */
|
||||
ALTER TABLE accounts ALTER COLUMN "expires_at" TYPE TEXT USING CAST(extract(epoch FROM "expires_at") AS BIGINT)*1000;
|
||||
|
||||
/* Keep id as SERIAL with autoincrement when using ORM. Using new v4 uuid format won't work because of incompatibility */
|
||||
/* ALTER TABLE accounts ALTER COLUMN "id" TYPE TEXT; */
|
||||
/* ALTER TABLE accounts ALTER COLUMN "userId" TYPE TEXT; */
|
||||
ALTER TABLE accounts ALTER COLUMN "type" TYPE TEXT;
|
||||
ALTER TABLE accounts ALTER COLUMN "provider" TYPE TEXT;
|
||||
ALTER TABLE accounts ALTER COLUMN "providerAccountId" TYPE TEXT;
|
||||
|
||||
ALTER TABLE accounts ADD CONSTRAINT fk_user_id FOREIGN KEY ("userId") REFERENCES users(id);
|
||||
ALTER TABLE accounts
|
||||
DROP COLUMN IF EXISTS "compound_id";
|
||||
/* The following two timestamp columns have never been necessary for Auth.js to function, but can be kept if you want */
|
||||
ALTER TABLE accounts
|
||||
DROP COLUMN IF EXISTS "created_at",
|
||||
DROP COLUMN IF EXISTS "updated_at";
|
||||
|
||||
ALTER TABLE accounts
|
||||
ADD COLUMN IF NOT EXISTS "token_type" TEXT NULL,
|
||||
ADD COLUMN IF NOT EXISTS "scope" TEXT NULL,
|
||||
ADD COLUMN IF NOT EXISTS "id_token" TEXT NULL,
|
||||
ADD COLUMN IF NOT EXISTS "session_state" TEXT NULL;
|
||||
/* Note: These are only needed if you're going to be using the old Twitter OAuth 1.0 provider. */
|
||||
/* ALTER TABLE accounts
|
||||
ADD COLUMN IF NOT EXISTS "oauth_token_secret" TEXT NULL,
|
||||
ADD COLUMN IF NOT EXISTS "oauth_token" TEXT NULL; */
|
||||
|
||||
/* USER */
|
||||
ALTER TABLE users RENAME COLUMN "email_verified" TO "emailVerified";
|
||||
|
||||
/* Keep id as SERIAL with autoincrement when using ORM. Using new v4 uuid format won't work because of incompatibility */
|
||||
/* ALTER TABLE users ALTER COLUMN "id" TYPE TEXT; */
|
||||
ALTER TABLE users ALTER COLUMN "name" TYPE TEXT;
|
||||
ALTER TABLE users ALTER COLUMN "email" TYPE TEXT;
|
||||
ALTER TABLE users ALTER COLUMN "image" TYPE TEXT;
|
||||
/* Do conversion of TIMESTAMPTZ to BIGINT and then TEXT */
|
||||
ALTER TABLE users ALTER COLUMN "emailVerified" TYPE TEXT USING CAST(CAST(extract(epoch FROM "emailVerified") AS BIGINT)*1000 AS TEXT);
|
||||
/* The following two timestamp columns have never been necessary for Auth.js to function, but can be kept if you want */
|
||||
ALTER TABLE users
|
||||
DROP COLUMN IF EXISTS "created_at",
|
||||
DROP COLUMN IF EXISTS "updated_at";
|
||||
|
||||
/* SESSION */
|
||||
ALTER TABLE sessions RENAME COLUMN "session_token" TO "sessionToken";
|
||||
ALTER TABLE sessions RENAME COLUMN "user_id" TO "userId";
|
||||
|
||||
/* Keep id as SERIAL with autoincrement when using ORM. Using new v4 uuid format won't work because of incompatibility */
|
||||
/* ALTER TABLE sessions ALTER COLUMN "id" TYPE TEXT; */
|
||||
/* ALTER TABLE sessions ALTER COLUMN "userId" TYPE TEXT; */
|
||||
ALTER TABLE sessions ALTER COLUMN "sessionToken" TYPE TEXT;
|
||||
ALTER TABLE sessions ADD CONSTRAINT fk_user_id FOREIGN KEY ("userId") REFERENCES users(id);
|
||||
/* Do conversion of TIMESTAMPTZ to BIGINT and then TEXT */
|
||||
ALTER TABLE sessions ALTER COLUMN "expires" TYPE TEXT USING CAST(CAST(extract(epoch FROM "expires") AS BIGINT)*1000 AS TEXT);
|
||||
ALTER TABLE sessions DROP COLUMN IF EXISTS "access_token";
|
||||
/* The following two timestamp columns have never been necessary for Auth.js to function, but can be kept if you want */
|
||||
ALTER TABLE sessions
|
||||
DROP COLUMN IF EXISTS "created_at",
|
||||
DROP COLUMN IF EXISTS "updated_at";
|
||||
|
||||
/* VERIFICATION REQUESTS */
|
||||
ALTER TABLE verification_requests RENAME TO verification_tokens;
|
||||
/* Keep id as ORM needs it */
|
||||
/* ALTER TABLE verification_tokens DROP COLUMN IF EXISTS id; */
|
||||
ALTER TABLE verification_tokens ALTER COLUMN "identifier" TYPE TEXT;
|
||||
ALTER TABLE verification_tokens ALTER COLUMN "token" TYPE TEXT;
|
||||
/* Do conversion of TIMESTAMPTZ to BIGINT and then TEXT */
|
||||
ALTER TABLE verification_tokens ALTER COLUMN "expires" TYPE TEXT USING CAST(CAST(extract(epoch FROM "expires") AS BIGINT)*1000 AS TEXT);
|
||||
/* The following two timestamp columns have never been necessary for Auth.js to function, but can be kept if you want */
|
||||
ALTER TABLE verification_tokens
|
||||
DROP COLUMN IF EXISTS "created_at",
|
||||
DROP COLUMN IF EXISTS "updated_at";
|
||||
```
|
||||
|
||||
#### MongoDB
|
||||
|
||||
MongoDB is a document database and as such new fields will be automatically populated. You do, however, need to update the names of existing fields which are going to be reused.
|
||||
|
||||
```mongo
|
||||
db.getCollection('accounts').updateMany({}, {
|
||||
$rename: {
|
||||
"provider_id": "provider",
|
||||
"provider_account_id": "providerAccountId",
|
||||
"user_id": "userId",
|
||||
"access_token_expires": "expires_at"
|
||||
}
|
||||
})
|
||||
db.getCollection('users').updateMany({}, {
|
||||
$rename: {
|
||||
"email_verified": "emailVerified"
|
||||
}
|
||||
})
|
||||
db.getCollection('sessions').updateMany({}, {
|
||||
$rename: {
|
||||
"session_token": "sessionToken",
|
||||
"user_id": "userId"
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
## Missing `secret`
|
||||
|
||||
Auth.js used to generate a secret for convenience, when the user did not define one. This might have been useful in development, but can be a concern in production. We have always been clear about that in the docs, but from now on, if you forget to define a `secret` property in production, we will show the user an error page. Read more about this option [here](/reference/configuration/auth-config#secret)
|
||||
|
||||
You can generate a secret to be placed in the `secret` configuration option via the following command:
|
||||
|
||||
```bash
|
||||
openssl rand -base64 32
|
||||
```
|
||||
|
||||
Therefore, your Auth.js config should look something like this:
|
||||
|
||||
```javascript title="/pages/api/auth/[...nextauth].js"
|
||||
...
|
||||
export default NextAuth({
|
||||
...
|
||||
providers: [...],
|
||||
secret: "LlKq6ZtYbr+hTC073mAmAh9/h2HwMfsFo4hrfCx5mLg=",
|
||||
...
|
||||
})
|
||||
```
|
||||
|
||||
Introduced in https://github.com/nextauthjs/next-auth/issues/3143
|
||||
|
||||
## Session `strategy`
|
||||
|
||||
We have always supported two different session strategies. The first being our most popular and default strategy - the JWT based one. The second is the database adapter persisted session strategy. Both have their advantages/disadvantages, you can learn more about them on the [FAQ](/concepts/faq) page.
|
||||
|
||||
Previously, the way you configured this was through the `jwt: boolean` flag in the `session` option. The names `session` and `jwt` might have been a bit overused in the options, and so for a clearer message, we renamed this option to `strategy: "jwt" | "database"`, it is still in the `session` object. This will hopefully better indicate the purpose of this option as well as make very explicit which type of session you are going to use.
|
||||
|
||||
See the [`session` option docs](/reference/configuration/auth-config#session) for more details.
|
||||
|
||||
Introduced in https://github.com/nextauthjs/next-auth/pull/3144
|
||||
|
||||
## Summary
|
||||
|
||||
We hope this migration goes smoothly for each and every one of you! If you have any questions or get stuck anywhere, feel free to create [a new issue](https://github.com/nextauthjs/next-auth/issues/new) on GitHub.
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"label": "Adapters",
|
||||
"collapsible": true,
|
||||
"collapsed": true
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"label": "Basics",
|
||||
"collapsible": true,
|
||||
"collapsed": false
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
---
|
||||
title: Deployment
|
||||
---
|
||||
|
||||
Deploying Auth.js only requires a few steps. It can be run anywhere a Next.js application can. Therefore, in a default configuration using only JWT session strategy, i.e. without a database, you will only need these few things in addition to your application:
|
||||
|
||||
1. Auth.js environment variables
|
||||
|
||||
- `NEXTAUTH_SECRET`
|
||||
- `NEXTAUTH_URL`
|
||||
|
||||
2. Auth.js API Route and its configuration (`/pages/api/auth/[...nextauth].js`).
|
||||
- OAuth Provider `clientId` / `clientSecret`
|
||||
|
||||
Deploying a modern JavaScript application using Auth.js consists of making sure your environment variables are set correctly as well as the configuration in the Auth.js API route is setup, as well as any configuration (like Callback URLs, etc.) are correctly done in your OAuth provider(s) themselves.
|
||||
|
||||
See below for more detailed provider settings.
|
||||
|
||||
## Vercel
|
||||
|
||||
1. Make sure to expose the Vercel [System Environment Variables](https://vercel.com/docs/concepts/projects/environment-variables#system-environment-variables) in your project settings. This way, we can detect the environment. (Setting `NEXTAUTH_URL` environment variable on Vercel is **unnecessary**).
|
||||
2. Create a `NEXTAUTH_SECRET` environment variable for both Production and Preview environments.
|
||||
a. You can use `openssl rand -base64 32` or https://generate-secret.vercel.app/32 to generate a random value.
|
||||
3. Add your provider's client ID and client secret to environment variables. _(Skip this step if not using an [OAuth Provider](/reference/providers/index))_
|
||||
4. Deploy!
|
||||
|
||||
Example repository: https://github.com/nextauthjs/next-auth-example
|
||||
|
||||
A few notes about deploying to Vercel. The environment variables are read server-side, so you **should not** prefix them with `NEXT_PUBLIC_` to avoid accidentally bundling a secret in the client-side JavaScript code.
|
||||
|
||||
### Securing a preview deployment
|
||||
|
||||
Most OAuth providers cannot be configured with multiple callback URLs or using a wildcard.
|
||||
|
||||
However, Auth.js **supports Preview deployments**, even **with OAuth providers**:
|
||||
|
||||
1. Determine a stable deployment URL. Eg.: A deployment whose URL does not change between builds, for example. `auth.yourdomain.com` (using a subdomain is not a requirement, this can simply be the main site's URL too.),
|
||||
2. Set `AUTH_REDIRECT_PROXY_URL` to that URL, adding the path up until your `[...nextauth]` route. Eg.: (`https://auth.yourdomain.com/api/auth`)
|
||||
3. For your OAuth provider, set the callback URL using the stable deployment URL. Eg.: For GitHub `https://auth.yourdomain.com/api/auth/callback/github`)
|
||||
|
||||
:::info
|
||||
To support preview deployments, the `AUTH_SECRET` value needs to be the same for the stable deployment and deployments that will need OAuth support.
|
||||
:::
|
||||
|
||||
:::note
|
||||
If you are storing users in a [database](reference/adapters), we recommend using a different OAuth app for development/production so that you don't mix your test and production user base.
|
||||
:::
|
||||
|
||||
<details>
|
||||
<summary>
|
||||
<b>How does this work?</b>
|
||||
</summary>
|
||||
To support preview deployments, Auth.js uses the stable deployment URL as a redirect proxy server.
|
||||
|
||||
It will redirect the OAuth callback request to the preview deployment URL, but only when the `AUTH_REDIRECT_PROXY_URL` environment variable is set. The stable deployment can still act as a regular app.
|
||||
|
||||
When a user initiates an OAuth sign-in flow on a preview deployment, we save its URL in the `state` query parameter but set the `redirect_uri` to the stable deployment.
|
||||
|
||||
Then, the OAuth provider will redirect the user to the stable deployment, which then will verify the `state` parameter and redirect the user to the preview deployment URL if the `state` is valid. This is secured by relying on the same server-side `AUTH_SECRET` for the stable deployment and the preview deployment.
|
||||
|
||||
See also:
|
||||
<ul>
|
||||
<li><a href="https://www.ietf.org/rfc/rfc6749.html#section-4.1.1">OAuth 2.0 specification: `state` query parameter</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
|
||||
## Netlify
|
||||
|
||||
Netlify is very similar to Vercel in that you can deploy a Next.js project without almost any extra work.
|
||||
|
||||
To set up Auth.js correctly here, you will want to make sure you add your `NEXTAUTH_SECRET` environment variable in the project settings. If you are using the [Essential Next.js Build Plugin](https://github.com/netlify/netlify-plugin-nextjs) within your project, you **do not** need to set the `NEXTAUTH_URL` environment variable as it is set automatically as part of the build process.
|
||||
|
||||
Netlify also exposes some [system environment variables](https://docs.netlify.com/configure-builds/environment-variables/) from which you can check which `NODE_ENV` you are currently in and much more.
|
||||
|
||||
After this, make sure you either have your OAuth provider set up correctly with `clientId` / `clientSecret`'s and callback URLs.
|
||||
@@ -1,153 +0,0 @@
|
||||
---
|
||||
title: Role-based access control
|
||||
---
|
||||
|
||||
There are two ways to add role-based access control (RBAC) to your application, based on the [session strategy](/concepts/session-strategies) you choose. Let's see an example for each of these.
|
||||
|
||||
## Getting the role
|
||||
|
||||
We are going to start by adding a `profile()` callback to the providers' config to determine the user role:
|
||||
|
||||
```ts title="/pages/api/auth/[...nextauth].ts"
|
||||
import NextAuth from "next-auth"
|
||||
import Google from "next-auth/providers/google"
|
||||
|
||||
export default NextAuth({
|
||||
providers: [
|
||||
Google({
|
||||
profile(profile) {
|
||||
return { role: profile.role ?? "user", ... }
|
||||
},
|
||||
...
|
||||
})
|
||||
],
|
||||
})
|
||||
```
|
||||
|
||||
:::tip
|
||||
To determine the user's role, you can either add your logic or if your provider assigns roles already, use that instead.
|
||||
:::
|
||||
|
||||
## Persisting the role
|
||||
### With JWT
|
||||
|
||||
When you don't have a database configured, the role will be persisted in a cookie, by using the `jwt()` callback. On sign-in, the `role` property is exposed from the `profile` callback on the `user` object. Persist the `user.role` value by assigning it to `token.role`. That's it!
|
||||
|
||||
If you also want to use the role on the client, you can expose it via the `session` callback.
|
||||
|
||||
```ts title="/pages/api/auth/[...nextauth].ts"
|
||||
import NextAuth from "next-auth"
|
||||
import Google from "next-auth/providers/google"
|
||||
|
||||
export default NextAuth({
|
||||
providers: [
|
||||
Google({
|
||||
profile(profile) {
|
||||
return { role: profile.role ?? "user", ... }
|
||||
},
|
||||
...
|
||||
})
|
||||
],
|
||||
// highlight-start
|
||||
callbacks: {
|
||||
jwt({ token, user }) {
|
||||
if(user) token.role = user.role
|
||||
return token
|
||||
},
|
||||
session({ session, token }) {
|
||||
session.user.role = token.role
|
||||
return session
|
||||
}
|
||||
}
|
||||
// highlight-end
|
||||
})
|
||||
```
|
||||
|
||||
:::info
|
||||
With this strategy, if you want to update the role, the user needs to be forced to sign in again.
|
||||
:::
|
||||
|
||||
### With Database
|
||||
|
||||
When you have a database, you can save the user role on the [User model](/reference/adapters/models#user). The below example is showing you how to do this with Prisma, but the idea is the same for all adapters.
|
||||
|
||||
First, add a `role` column to the User model.
|
||||
|
||||
```ts title="/prisma/schema.prisma"
|
||||
model User {
|
||||
id String @id @default(cuid())
|
||||
name String?
|
||||
email String? @unique
|
||||
emailVerified DateTime?
|
||||
image String?
|
||||
role String? // New column
|
||||
accounts Account[]
|
||||
sessions Session[]
|
||||
}
|
||||
```
|
||||
|
||||
The `profile()` callback's return value is used to create users in the database. That's it! Your newly created users will now have an assigned role.
|
||||
|
||||
If you also want to use the role on the client, you can expose it via the `session` callback.
|
||||
|
||||
```ts title="/pages/api/auth/[...nextauth].ts"
|
||||
import NextAuth from "next-auth"
|
||||
import Google from "next-auth/providers/google"
|
||||
// highlight-next-line
|
||||
import prisma from "lib/prisma"
|
||||
|
||||
export default NextAuth({
|
||||
// highlight-next-line
|
||||
adapter: PrismaAdapter(prisma),
|
||||
providers: [
|
||||
Google({
|
||||
profile(profile) {
|
||||
return { role: profile.role ?? "user", ... }
|
||||
}
|
||||
...
|
||||
})
|
||||
],
|
||||
// highlight-start
|
||||
callbacks: {
|
||||
session({ session, user }) {
|
||||
session.user.role = user.role
|
||||
return session
|
||||
}
|
||||
}
|
||||
// highlight-end
|
||||
})
|
||||
```
|
||||
|
||||
:::info
|
||||
It is up to you how you want to manage to update the roles, either through direct database access or building your role update API.
|
||||
:::
|
||||
|
||||
## Using the role
|
||||
|
||||
If you want to use the role in the client, for both cases above, when using the `useSession` hook, `session.user.role` will have the required role if you exposed it via the `session` callback. You can use this to render a different UI for different users.
|
||||
|
||||
```ts title="/pages/admin.tsx"
|
||||
import { useSession } from "next-auth/react"
|
||||
|
||||
export default function Page() {
|
||||
const session = await useSession()
|
||||
|
||||
if (session?.user.role === "admin") {
|
||||
return <p>You are an admin, welcome!</p>
|
||||
}
|
||||
|
||||
return <p>You are not authorized to view this page!</p>
|
||||
}
|
||||
```
|
||||
|
||||
:::tip
|
||||
When using Next.js and JWT, you can alternatively also use [Middleware](https://next-auth.js.org/configuration/nextjs#wrap-middleware) to redirect the user based on their role, even before rendering the page.
|
||||
:::
|
||||
|
||||
## Resources
|
||||
|
||||
- [Concepts: Session strategies](/concepts/session-strategies)
|
||||
- [Next.js: Middleware](https://next-auth.js.org/configuration/nextjs#wrap-middleware)
|
||||
- [Adapters: User model](/reference/adapters/models#user)
|
||||
- [Adapters: Prisma adapter](/reference/adapters/prisma)
|
||||
- [TypeScript](/getting-started/typescript)
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"label": "Corporate proxies",
|
||||
"collapsible": true,
|
||||
"collapsed": true
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
---
|
||||
title: Overview
|
||||
sidebar_position: 0
|
||||
---
|
||||
|
||||
This section contains guides for common use cases.
|
||||
|
||||
If you can't find what you're looking for, [raise an issue](https://github.com/nextauthjs/next-auth/issues/new?assignees=&labels=triage%2Cdocumentation&template=4_documentation.yml).
|
||||
|
||||
:::warning Warning
|
||||
Guides are being migrated from the [old documentation page](https://next-auth.js.org), so there are going to be references to `next-auth` still. We are continuously working on updating the naming/references.
|
||||
:::
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"label": "Providers",
|
||||
"collapsible": true,
|
||||
"collapsed": true
|
||||
}
|
||||
@@ -1,112 +0,0 @@
|
||||
---
|
||||
title: OAuth Provider
|
||||
---
|
||||
|
||||
Auth.js comes with a set of built-in OAuth providers that you can import from `@auth/core/providers/*`. Every provider has their separate documentation page under the [core package's API Reference](/reference/core)
|
||||
|
||||
|
||||
## Use your own provider
|
||||
|
||||
However, you can use _any_ provider as long as they are compliant with the OAuth/OIDC specifications.
|
||||
|
||||
Auth.js uses the [`oauth4webapi`](https://github.com/panva/oauth4webapi/blob/main/docs/README.md) package under the hood.
|
||||
|
||||
To use a custom OAuth provider with Auth.js, pass an object to the [`providers` list](/reference/core#providers).
|
||||
|
||||
It can implement either the [`OAuth2Config`](/reference/core/providers#oauth2configprofile) or the [`OIDCConfig`](/reference/core/providers#oidcconfigprofile) interface, depending on if your provider is OAuth 2 or OpenID Connect compliant.
|
||||
|
||||
For example, if you have a fully OIDC-compliant provider, this is all you need:
|
||||
|
||||
```ts
|
||||
import type { OIDCConfig } from "@auth/core/providers"
|
||||
|
||||
...
|
||||
providers: [
|
||||
{
|
||||
id: "my-oidc-provider",
|
||||
name: "My Provider",
|
||||
type: "oidc",
|
||||
issuer: "https://my.oidc-provider.com",
|
||||
clientId: process.env.CLIENT_ID,
|
||||
clientSecret: process.env.CLIENT_SECRET
|
||||
} satisfies OIDCConfig
|
||||
]
|
||||
...
|
||||
```
|
||||
|
||||
Then, you can set the [Redirect URI](https://www.ietf.org/archive/id/draft-ietf-oauth-v2-1-07.html#name-client-redirection-endpoint) in your provider's dashboard to something like `https://app-url.com/{path-to-auth-handler}/callback/my-oidc-provider`.
|
||||
|
||||
`{path-to-auth-handler}` is _usually_ `auth` or `api/auth`, depending on your framework of your choice.
|
||||
`my-oidc-provider` matches the `id` you set in the [`providers` list](/reference/core#providers).
|
||||
|
||||
|
||||
## Override default provider config
|
||||
|
||||
For built-in providers, in most cases you will only need to specify the `clientId` and `clientSecret`, and in case of OIDC providers, the `issuer` property. If you need to override any of the defaults, you can add them in the provider's function call and they will be deep-merged with the default configuration options.
|
||||
|
||||
:::note
|
||||
The user provided options are deeply merged with the default options. That means you only have to override part of the options that you need to be different. For example if you want different scopes, overriding `authorization.params.scope` is enough, instead of the whole `authorization` option.
|
||||
:::
|
||||
|
||||
|
||||
For example, to override a provider's default scopes, you can do the following:
|
||||
|
||||
```ts
|
||||
import Auth0Provider from "@auth/core/providers/auth0"
|
||||
|
||||
Auth0Provider({
|
||||
clientId: process.env.CLIENT_ID,
|
||||
clientSecret: process.env.CLIENT_SECRET,
|
||||
issuer: process.env.ISSUER,
|
||||
authorization: { params: { scope: "openid your_custom_scope" } },
|
||||
})
|
||||
```
|
||||
|
||||
Another example, the `profile` callback will return `id`, `name`, `email` and `picture` by default, but you might want to return more information from the provider. After setting the correct scopes, you can then do something like this:
|
||||
|
||||
```ts
|
||||
import GoogleProvider from "@auth/core/providers/google"
|
||||
|
||||
GoogleProvider({
|
||||
clientId: process.env.GOOGLE_CLIENT_ID,
|
||||
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
|
||||
profile(profile) {
|
||||
return {
|
||||
// Return all the profile information you need.
|
||||
// The only truly required field is `id`
|
||||
// to be able identify the account when added to a database
|
||||
}
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
An example of how to enable automatic account linking:
|
||||
|
||||
```ts
|
||||
import GoogleProvider from "@auth/core/providers/google"
|
||||
|
||||
GoogleProvider({
|
||||
clientId: process.env.GOOGLE_CLIENT_ID,
|
||||
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
|
||||
allowDangerousEmailAccountLinking: true,
|
||||
})
|
||||
```
|
||||
|
||||
## Adding a new built-in provider
|
||||
|
||||
If you think your custom provider might be useful to others, we encourage you to open a PR and add it to the built-in list.
|
||||
|
||||
:::note
|
||||
We are only accepting new providers to `@auth/core`, and not `next-auth`. Follow the steps below to make sure your PR is merged!
|
||||
:::
|
||||
|
||||
1. Create a new `{provider}.ts` (for it to get merged, you must use TypeScript) file under the [`packages/core/src/providers`](https://github.com/nextauthjs/next-auth/tree/main/packages/core/src/providers) directory.
|
||||
2. Make sure that you are following other providers, ie.:
|
||||
- Use a named default export: `export default function YourProvider`
|
||||
- Export the TypeScript `interface` that defines the provider's available user info properties
|
||||
- Add the necessary JSDoc comments/documentation (Study the built-in providers to get an understanding what's needed. For example, the [Auth0 provider](https://github.com/nextauthjs/next-auth/blob/main/packages/core/src/providers/auth0.ts) is a good example for OIDC and the [GitHub Provider](https://github.com/nextauthjs/next-auth/blob/main/packages/core/src/providers/github.ts) is an OAuth provider.)
|
||||
- Add links to the provider's API reference/documentation so others can understand how to use the provider
|
||||
3. Add the new provider name to the `Provider type` dropdown options in [`the provider issue template`](https://github.com/nextauthjs/next-auth/edit/main/.github/ISSUE_TEMPLATE/2_bug_provider.yml)
|
||||
4. (Optional): Add a logo `{provider}.svg` to the [`docs/static/img/providers`](https://github.com/nextauthjs/next-auth/tree/main/docs/static/img/providers) directory.
|
||||
|
||||
That's it! 🎉 Others will be able to discover and use this provider!
|
||||
@@ -1,108 +0,0 @@
|
||||
---
|
||||
id: email-http
|
||||
title: HTTP-based Email Provider
|
||||
---
|
||||
|
||||
## Introduction
|
||||
|
||||
:::note
|
||||
The following guide is written for `next-auth` (NextAuth.js), but it should work for any of the Auth.js framework libraries (`@auth/*`) as well.
|
||||
:::
|
||||
|
||||
|
||||
There is a built-in Email provider with which you could connect to the SMTP server of your choice to send "magic link" emails for sign-in purposes. However, the Email provider can also be used with HTTP-based email services, like AWS SES, Postmark, Sendgrid, etc. In this guide, we are going to explain how to use our Email magic link provider with any of the more modern HTTP-based Email APIs.
|
||||
|
||||
For this example, we will be using [SendGrid](https://sendgrid.com), but any email service providing an HTTP API or JS client library will work.
|
||||
We will also refer to the [Prisma Adapter](/reference/adapter/prisma). A [database adapter](/adapters/overview) is a requirement for the Email provider.
|
||||
|
||||
## Setup
|
||||
|
||||
First, if you do not have a project using Auth.js, clone and set up a basic Auth.js project like the one [provided in our example repo](https://github.com/nextauthjs/next-auth-example).
|
||||
|
||||
- Install the [Prisma Adapter](/reference/adapter/prisma)
|
||||
- Generate an API key from your cloud Email provider of choice and add it to your `.env.*` file. For example, mine is going to be called `SENDGRID_API`
|
||||
- Add the following configuration to your configuration file:
|
||||
|
||||
```js title="auth.ts"
|
||||
import NextAuth, { NextAuthOptions } from "next-auth"
|
||||
import { PrismaAdapter } from "@auth/prisma-adapter"
|
||||
import { PrismaClient } from "@prisma/client"
|
||||
|
||||
const prisma = new PrismaClient()
|
||||
|
||||
export const authOptions: NextAuthOptions = {
|
||||
adapter: PrismaAdapter(prisma),
|
||||
providers: [
|
||||
{
|
||||
id: 'sendgrid',
|
||||
type: 'email',
|
||||
async sendVerificationRequest({identifier: email, url}) {
|
||||
}
|
||||
}
|
||||
],
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Next, all that's left to do is call the HTTP endpoint from our cloud email provider and pass it the required metadata like the `to` address, the email `body`, and any other fields we may need to include.
|
||||
|
||||
As mentioned earlier, we're going to be using SendGrid in this example, so the appropriate endpoint is `https://api.sendgrid.com/v3/mail/send` ([more info](https://docs.sendgrid.com/for-developers/sending-email/api-getting-started)). Therefore, we're going to pull out some of the important information from the `params` argument and use it in a `fetch()` call to the previously mentioned SendGrid API.
|
||||
|
||||
```js title="auth.ts"
|
||||
import NextAuth, { NextAuthOptions } from "next-auth"
|
||||
import { PrismaAdapter } from "@auth/prisma-adapter"
|
||||
import { PrismaClient } from "@prisma/client"
|
||||
|
||||
const prisma = new PrismaClient()
|
||||
|
||||
export const authOptions: NextAuthOptions = {
|
||||
adapter: PrismaAdapter(prisma),
|
||||
providers: [
|
||||
{
|
||||
id: 'sendgrid',
|
||||
type: 'email',
|
||||
async sendVerificationRequest({identifier: email, url}) {
|
||||
// highlight-start
|
||||
// Call the cloud Email provider API for sending emails
|
||||
// See https://docs.sendgrid.com/api-reference/mail-send/mail-send
|
||||
const response = await fetch("https://api.sendgrid.com/v3/mail/send", {
|
||||
// The body format will vary depending on provider, please see their documentation
|
||||
// for further details.
|
||||
body: JSON.stringify({
|
||||
personalizations: [{ to: [{ email }] }],
|
||||
from: { email: "noreply@company.com" },
|
||||
subject: "Sign in to Your page",
|
||||
content: [
|
||||
{
|
||||
type: "text/plain",
|
||||
value: `Please click here to authenticate - ${url}`,
|
||||
},
|
||||
],
|
||||
}),
|
||||
headers: {
|
||||
// Authentication will also vary from provider to provider, please see their docs.
|
||||
Authorization: `Bearer ${process.env.SENDGRID_API}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
method: "POST",
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
const { errors } = await response.json()
|
||||
throw new Error(JSON.stringify(errors))
|
||||
}
|
||||
// highlight-end
|
||||
},
|
||||
}
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
And that's all we need to do to send Emails via an HTTP API! Note here that the example is only using `text/plain` as the body type. You'll probably want to change that to `text/html` and pass in a nice-looking HTML email. See, for example, our `html` function in [the Auth.js docs](/providers/email#customizing-emails).
|
||||
|
||||
To sign in via this custom provider, you would refer to it by the `id` in when you are calling the sign-in method, for example: `signIn('sendgrid', { email: 'user@company.com' })`.
|
||||
|
||||
## References
|
||||
|
||||
- [Email provider documentation with HTML generation and more](/reference/core/modules/providers_email)
|
||||
- [SendGrid JSON Body documentation](https://docs.sendgrid.com/api-reference/mail-send/mail-send#body)
|
||||
@@ -1,118 +0,0 @@
|
||||
---
|
||||
id: resources
|
||||
title: Community resources
|
||||
---
|
||||
|
||||
> These tutorials are contributed by the community.
|
||||
> **New submissions and edits are welcome!**
|
||||
|
||||
## Basics
|
||||
|
||||
#### [Introduction to Auth.js](https://www.youtube.com/watch?v=npZsJxWntJM) <svg role="img" viewBox="0 0 24 24" height="24" width="24" style={{ marginLeft: '5px', marginBottom:'-6px'}} xmlns="http://www.w3.org/2000/svg"><title>YouTube</title><path fill="#ff0000" d="M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z"/></svg>
|
||||
|
||||
- This is an introductory video to Auth.js for beginners. In this video, it is explained how to set up authentication in a few easy steps and add different configurations to make it more robust and secure.
|
||||
|
||||
#### [Authentication patterns for Next.js](https://nextjs.org/docs/authentication) <svg xmlns="http://www.w3.org/2000/svg" style={{ marginLeft: '5px', marginBottom:'-6px'}} height="20" width="20" fill="none" viewBox="0 0 24 24" stroke="currentColor"><title>External</title><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" /> </svg>
|
||||
|
||||
- Next.js supports multiple patterns for authentication, each designed for different use cases. This guide will allow you to choose your adventure based on your constraints. By Lee Robinson.
|
||||
|
||||
#### [Adding Authentication to an existing Next.js Application in no time!](https://dev.to/ndom91/adding-authentication-to-an-existing-serverless-next-js-app-in-no-time-with-nextauth-js-192h) <svg style={{ marginLeft: '5px', marginBottom:'-6px'}} width="30" height="25" viewBox="0 0 50 40" fill="none" xmlns="http://www.w3.org/2000/svg"><rect width="50" height="40" rx="3" style={{ fill: '#000' }}></rect><path d="M19.099 23.508c0 1.31-.423 2.388-1.27 3.234-.838.839-1.942 1.258-3.312 1.258h-4.403V12.277h4.492c1.31 0 2.385.423 3.224 1.27.846.838 1.269 1.912 1.269 3.223v6.738zm-2.808 0V16.77c0-.562-.187-.981-.562-1.258-.374-.285-.748-.427-1.122-.427h-1.685v10.107h1.684c.375 0 .75-.138 1.123-.415.375-.285.562-.708.562-1.27zM28.185 28h-5.896c-.562 0-1.03-.187-1.404-.561-.375-.375-.562-.843-.562-1.404V14.243c0-.562.187-1.03.562-1.404.374-.375.842-.562 1.404-.562h5.896v2.808H23.13v3.65h3.088v2.808h-3.088v3.65h5.054V28zm7.12 0c-.936 0-1.684-.655-2.246-1.965l-3.65-13.758h3.089l2.807 10.804 2.808-10.804H41.2l-3.65 13.758C36.99 27.345 36.241 28 35.305 28z" style={{ fill: '#fff' }}></path></svg>
|
||||
|
||||
- This tutorial walks one through adding Auth.js to an existing project. Including setting up the OAuth client id and secret, adding the API routes for authentication, protecting pages and API routes behind that authentication, etc.
|
||||
|
||||
#### [Adding social authentication support to a Next.js app](https://getstarted.sh/bulletproof-next/add-social-authentication) <svg xmlns="http://www.w3.org/2000/svg" style={{ marginLeft: '5px', marginBottom:'-6px'}} height="20" width="20" fill="none" viewBox="0 0 24 24" stroke="currentColor"><title>External</title> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" /> </svg>
|
||||
|
||||
- A tutorial by Arunoda Susirpiala. Checkout [GetStarted](https://getstarted.sh/) for more examples.
|
||||
|
||||
#### [How to Authenticate Next.js Apps with Twitter & Auth.js](https://spacejelly.dev/posts/how-to-authenticate-next-js-apps-with-twitter-nextauth-js/) <svg xmlns="http://www.w3.org/2000/svg" style={{ marginLeft: '5px', marginBottom:'-6px'}} height="20" width="20" fill="none" viewBox="0 0 24 24" stroke="currentColor"><title>External</title> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" /> </svg>
|
||||
|
||||
- Learn how to add Twitter authentication and login to a Next.js app both client-side and server-side with Auth.js.
|
||||
|
||||
#### [NextJS Authentication Crash Course with Auth.js](https://youtu.be/o_wZIVmWteQ) <svg role="img" viewBox="0 0 24 24" height="24" width="24" style={{ marginLeft: '5px', marginBottom:'-6px'}} xmlns="http://www.w3.org/2000/svg"><title>YouTube</title><path fill="#ff0000" d="M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z"/></svg>
|
||||
|
||||
- This tutorial dives into the ins and outs of NextAuth, including using the Email, Github, Twitter and Auth0 providers in under an hour.
|
||||
|
||||
#### [Create your own Auth.js Login Pages](https://youtu.be/kB6YNYZ63fw) <svg role="img" viewBox="0 0 24 24" height="24" width="24" style={{ marginLeft: '5px', marginBottom:'-6px'}} xmlns="http://www.w3.org/2000/svg"><title>YouTube</title><path fill="#ff0000" d="M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z"/></svg>
|
||||
|
||||
- This tutorial shows you how to jump in and create your own custom login pages versus using the ones provided by Auth.js
|
||||
|
||||
#### [Passwordless Authentication with next-auth](https://www.youtube.com/watch?v=GPBD3acOx_M) <svg role="img" viewBox="0 0 24 24" height="24" width="24" style={{ marginLeft: '5px', marginBottom:'-6px'}} xmlns="http://www.w3.org/2000/svg"><title>YouTube</title><path fill="#ff0000" d="M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z"/></svg>
|
||||
|
||||
- A video tutorial by Xiaoru Li from Prisma.
|
||||
|
||||
#### [How to authenticate Next.js Apps with Sign-In With Ethereum (SIWE) & Auth.js](https://docs.login.xyz/integrations/Auth.js) <svg xmlns="http://www.w3.org/2000/svg" style={{ marginLeft: '5px', marginBottom:'-6px'}} height="20" width="20" fill="none" viewBox="0 0 24 24" stroke="currentColor"><title>External</title> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" /> </svg>
|
||||
|
||||
- Learn how to use Sign-In With Ethereum to authenticate your users with their existing Ethereum wallets - identifiers they personally control.
|
||||
- Example application: [spruceid/siwe-next-auth-example](https://github.com/spruceid/siwe-next-auth-example)
|
||||
|
||||
#### [Next.js Authentication with Okta and Auth.js 4.0](https://thetombomb.com/posts/nextjs-nextauth-okta) <svg xmlns="http://www.w3.org/2000/svg" style={{ marginLeft: '5px', marginBottom:'-6px'}} height="20" width="20" fill="none" viewBox="0 0 24 24" stroke="currentColor"><title>External</title> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" /> </svg>
|
||||
|
||||
- Learn how to perform authentication with an OIDC Application in Okta and Auth.js.
|
||||
|
||||
## Fullstack
|
||||
|
||||
#### [Build a FullStack App with Next.js, Auth.js, Supabase & Prisma](https://themodern.dev/courses/build-a-fullstack-app-with-nextjs-supabase-and-prisma-322389284337222224) <svg xmlns="http://www.w3.org/2000/svg" style={{ marginLeft: '5px', marginBottom:'-6px'}} height="20" width="20" fill="none" viewBox="0 0 24 24" stroke="currentColor"><title>External</title> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" /> </svg>
|
||||
|
||||
In this [free course](https://themodern.dev/courses/build-a-fullstack-app-with-nextjs-supabase-and-prisma-322389284337222224), you'll learn how to build a full-stack app using the following technologies:
|
||||
|
||||
- **Next.js** - The React framework for building the UI of the app and the REST API
|
||||
- **Auth.js** - For implementing passwordless and OAuth authentication
|
||||
- **Supabase** - For persisting the app data into a PostgreSQL database and storing media files
|
||||
- **Prisma** - For making it easy to read and write data from our app from and to the database
|
||||
|
||||
The app that we'll work on in this course is called **_SupaVacation_**. It is an online marketplace for vacation rentals where users can browse through all the properties for rent, bookmark their favorite ones, and even rent their own properties.
|
||||
|
||||
> Here's [a live demo](https://supa-vacation.vercel.app/) of the app's final version. It is what your app should look likes after completing this course. Feel free to play with it to get an overview of all the features you'll be working on.
|
||||
|
||||
#### [Magic Link Authentication in Next.js with NextAuth and Fauna](https://alterclass.io/tutorials/magic-link-authentication-in-nextjs-with-nextauth-and-fauna) <svg xmlns="http://www.w3.org/2000/svg" style={{ marginLeft: '5px', marginBottom:'-6px'}} height="20" width="20" fill="none" viewBox="0 0 24 24" stroke="currentColor"><title>External</title> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" /> </svg>
|
||||
|
||||
Learn how to implement passwordless/magic link authentication with database storage in your Next.js projects using NextAuth and Fauna DB.
|
||||
|
||||
> The final version of the project's code can be found on [Github](https://github.com/AlterClassIO/magic-next-auth). You can use it as a starting point for any Next.js app that requires passwordless authentication.
|
||||
|
||||
> You can also preview the example live [here](https://magic-next-auth.vercel.app/).
|
||||
|
||||
This tutorial covers:
|
||||
|
||||
- Configuring Next.js, Auth.js, and Fauna to work together seamlessly
|
||||
- Using Next.js dynamic API routes to handle authentication requests
|
||||
- Using Fauna and the Fauna Adapter for `next-auth` to persist users, email sign in tokens, and sessions
|
||||
- Creating custom login and confirmation pages with React + Tailwind CSS
|
||||
- Customizing the sign-in email and sending a welcome email to new users
|
||||
|
||||
#### [Passwordless Authentication with Next.js, Prisma, and next-auth](https://dev.to/prisma/passwordless-authentication-with-next-js-prisma-and-next-auth-5g8g) <svg style={{ marginLeft: '5px', marginBottom:'-6px'}} width="30" height="25" viewBox="0 0 50 40" fill="none" xmlns="http://www.w3.org/2000/svg"><rect width="50" height="40" rx="3" style={{ fill: '#000' }}></rect><path d="M19.099 23.508c0 1.31-.423 2.388-1.27 3.234-.838.839-1.942 1.258-3.312 1.258h-4.403V12.277h4.492c1.31 0 2.385.423 3.224 1.27.846.838 1.269 1.912 1.269 3.223v6.738zm-2.808 0V16.77c0-.562-.187-.981-.562-1.258-.374-.285-.748-.427-1.122-.427h-1.685v10.107h1.684c.375 0 .75-.138 1.123-.415.375-.285.562-.708.562-1.27zM28.185 28h-5.896c-.562 0-1.03-.187-1.404-.561-.375-.375-.562-.843-.562-1.404V14.243c0-.562.187-1.03.562-1.404.374-.375.842-.562 1.404-.562h5.896v2.808H23.13v3.65h3.088v2.808h-3.088v3.65h5.054V28zm7.12 0c-.936 0-1.684-.655-2.246-1.965l-3.65-13.758h3.089l2.807 10.804 2.808-10.804H41.2l-3.65 13.758C36.99 27.345 36.241 28 35.305 28z" style={{ fill: '#fff' }}></path></svg>
|
||||
|
||||
- In this post, you'll learn how to add passwordless authentication to your Next.js app using Prisma and next-auth. By the end of this tutorial, your users will be able to log in to your app with either their GitHub account or a Slack-styled magic link sent right to their Email inbox. By Xiaoru Li.
|
||||
|
||||
#### [Fullstack Authentication Example with Next.js and Auth.js](https://github.com/prisma/prisma-examples/tree/latest/typescript/rest-nextjs-api-routes-auth) <svg xmlns="http://www.w3.org/2000/svg" style={{ marginLeft: '5px', marginBottom:'-6px'}} height="20" width="20" fill="none" viewBox="0 0 24 24" stroke="currentColor"><title>External</title> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" /> </svg>
|
||||
|
||||
- This example shows how to implement a full-stack app in TypeScript with Next.js using Prisma Client as a backend. It also demonstrates how to implement authentication using Auth.js. By Nikolas Burk at Prisma.
|
||||
|
||||
## Advanced
|
||||
|
||||
#### [Add auth support to a Next.js app with a custom backend](https://arunoda.me/blog/add-auth-support-to-a-next-js-app-with-a-custom-backend) <svg xmlns="http://www.w3.org/2000/svg" style={{ marginLeft: '5px', marginBottom:'-6px'}} height="20" width="20" fill="none" viewBox="0 0 24 24" stroke="currentColor"><title>External</title> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" /> </svg>
|
||||
|
||||
- A tutorial by Arunoda Susirpiala.
|
||||
|
||||
#### [How to Configure Azure AD B2C Authentication with Next.js](https://benjaminwfox.com/blog/tech/how-to-configure-azure-b2c-with-nextjs) <svg xmlns="http://www.w3.org/2000/svg" style={{ marginLeft: '5px', marginBottom:'-6px'}} height="20" width="20" fill="none" viewBox="0 0 24 24" stroke="currentColor"><title>External</title> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" /> </svg>
|
||||
|
||||
- Configuring authentication with Azure B2C in Next.js is not a particularly straight forward process. We'll look at how to facilitate this using the Auth.js library. By Ben Fox.
|
||||
|
||||
#### [Sign in with Apple in NextJS](https://thesiddd.com/blog/apple-auth) <svg xmlns="http://www.w3.org/2000/svg" style={{ marginLeft: '5px', marginBottom:'-6px'}} height="20" width="20" fill="none" viewBox="0 0 24 24" stroke="currentColor"><title>External</title> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" /> </svg>
|
||||
|
||||
- This tutorial walks step by step on how to get sign in with Apple working (both locally and on a deployed website) using Auth.js.
|
||||
|
||||
#### [Using Auth.js with Magic links](https://dev.to/narciero/using-nextauth-js-with-magic-links-df4) <svg style={{ marginLeft: '5px', marginBottom:'-6px'}} width="30" height="25" viewBox="0 0 50 40" fill="none" xmlns="http://www.w3.org/2000/svg"><rect width="50" height="40" rx="3" style={{ fill: '#000' }}></rect><path d="M19.099 23.508c0 1.31-.423 2.388-1.27 3.234-.838.839-1.942 1.258-3.312 1.258h-4.403V12.277h4.492c1.31 0 2.385.423 3.224 1.27.846.838 1.269 1.912 1.269 3.223v6.738zm-2.808 0V16.77c0-.562-.187-.981-.562-1.258-.374-.285-.748-.427-1.122-.427h-1.685v10.107h1.684c.375 0 .75-.138 1.123-.415.375-.285.562-.708.562-1.27zM28.185 28h-5.896c-.562 0-1.03-.187-1.404-.561-.375-.375-.562-.843-.562-1.404V14.243c0-.562.187-1.03.562-1.404.374-.375.842-.562 1.404-.562h5.896v2.808H23.13v3.65h3.088v2.808h-3.088v3.65h5.054V28zm7.12 0c-.936 0-1.684-.655-2.246-1.965l-3.65-13.758h3.089l2.807 10.804 2.808-10.804H41.2l-3.65 13.758C36.99 27.345 36.241 28 35.305 28z" style={{ fill: '#fff' }}></path></svg>
|
||||
|
||||
- Learn how to use [Magic.Link](https://magic.link) authentication with [Auth.js](https://authjs.dev) to enable passwordless authentication without a database.
|
||||
|
||||
## Database
|
||||
|
||||
#### [Create a Auth.js Custom Adapter with HarperDB & Next.js](https://spacejelly.dev/posts/how-to-create-a-nextauth-js-custom-adapter-with-harperdb-next-js/) <svg xmlns="http://www.w3.org/2000/svg" style={{ marginLeft: '5px', marginBottom:'-6px'}} height="20" width="20" fill="none" viewBox="0 0 24 24" stroke="currentColor"><title>External</title> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" /> </svg>
|
||||
|
||||
- Use a custom database in a Custom Adapter for persisted Auth.js sessions using HarperDB as an example.
|
||||
- Video tutorial also available: <https://www.youtube.com/watch?v=pu7xBv7sZ8s>
|
||||
|
||||
#### [Using Auth.js with Prisma and PlanetScale serverless databases](https://github.com/planetscale/nextjs-planetscale-starter) <svg xmlns="http://www.w3.org/2000/svg" style={{ marginLeft: '5px', marginBottom:'-6px'}} height="20" width="20" fill="none" viewBox="0 0 24 24" stroke="currentColor"><title>External</title> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" /> </svg>
|
||||
|
||||
- How to set up a PlanetScale database to fetch and store user / account data with the Prisma adapter.
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"label": "Testing",
|
||||
"collapsible": true,
|
||||
"collapsed": true
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"label": "Database adapters",
|
||||
"collapsible": true,
|
||||
"collapsed": true
|
||||
}
|
||||
@@ -1,219 +0,0 @@
|
||||
---
|
||||
title: Overview
|
||||
---
|
||||
|
||||
Using an Auth.js / NextAuth.js adapter you can connect to any database service or even several different services at the same time. The following listed official adapters are created and maintained by the community:
|
||||
|
||||
<div class="adapter-card-list">
|
||||
<a href="/reference/adapter/azure-tables" class="adapter-card">
|
||||
<img src="/img/adapters/azure-tables.svg" width="40" />
|
||||
<h4 class="adapter-card__title">Azure Table Storage Adapter</h4>
|
||||
</a>
|
||||
<a href="/reference/adapter/d1" class="adapter-card">
|
||||
<img src="/img/adapters/d1.svg" width="40" />
|
||||
<h4 class="adapter-card__title">D1 Adapter</h4>
|
||||
</a>
|
||||
<a href="/reference/adapter/edgedb" class="adapter-card">
|
||||
<img src="/img/adapters/edgedb.svg" width="30" />
|
||||
<h4 class="adapter-card__title">EdgeDB Adapter</h4>
|
||||
</a>
|
||||
<a href="/reference/adapter/dgraph" class="adapter-card">
|
||||
<img src="/img/adapters/dgraph.png" width="30" />
|
||||
<h4 class="adapter-card__title">Dgraph Adapter</h4>
|
||||
</a>
|
||||
<a href="/reference/adapter/drizzle" class="adapter-card">
|
||||
<img src="/img/adapters/drizzle-orm.png" width="30" />
|
||||
<h4 class="adapter-card__title">Drizzle Adapter</h4>
|
||||
</a>
|
||||
<a href="/reference/adapter/dynamodb" class="adapter-card">
|
||||
<img src="/img/adapters/dynamodb.png" width="30" />
|
||||
<h4 class="adapter-card__title">DynamoDB Adapter</h4>
|
||||
</a>
|
||||
<a href="/reference/adapter/fauna" class="adapter-card">
|
||||
<img src="/img/adapters/fauna.png" width="30" />
|
||||
<h4 class="adapter-card__title">Fauna Adapter</h4>
|
||||
</a>
|
||||
<a href="/reference/adapter/firebase" class="adapter-card">
|
||||
<img src="/img/adapters/firebase.svg" width="40" />
|
||||
<h4 class="adapter-card__title">Firebase Adapter</h4>
|
||||
</a>
|
||||
<a href="/reference/adapter/kysely" class="adapter-card">
|
||||
<img src="/img/adapters/kysely.svg" width="40" />
|
||||
<h4 class="adapter-card__title">Kysely Adapter</h4>
|
||||
</a>
|
||||
<a href="/reference/adapter/mikro-orm" class="adapter-card">
|
||||
<img src="/img/adapters/mikro-orm.png" width="30" />
|
||||
<h4 class="adapter-card__title">Mikro ORM Adapter</h4>
|
||||
</a>
|
||||
<a href="/reference/adapter/mongodb" class="adapter-card">
|
||||
<img src="/img/adapters/mongodb.svg" width="15" />
|
||||
<h4 class="adapter-card__title">MongoDB Adapter</h4>
|
||||
</a>
|
||||
<a href="/reference/adapter/neo4j" class="adapter-card">
|
||||
<img src="/img/adapters/neo4j.svg" width="50" />
|
||||
<h4 class="adapter-card__title">Neo4j Adapter</h4>
|
||||
</a>
|
||||
<a href="/reference/adapter/pg" class="adapter-card">
|
||||
<img src="/img/adapters/pg.png" width="20" />
|
||||
<h4 class="adapter-card__title">Postgres Adapter</h4>
|
||||
</a>
|
||||
<a href="/reference/adapter/pouchdb" class="adapter-card">
|
||||
<img src="/img/adapters/pouchdb.svg" width="20" />
|
||||
<h4 class="adapter-card__title">PouchDB Adapter</h4>
|
||||
</a>
|
||||
<a href="/reference/adapter/prisma" class="adapter-card">
|
||||
<img src="/img/adapters/prisma.svg" width="30" />
|
||||
<h4 class="adapter-card__title">Prisma Adapter</h4>
|
||||
</a>
|
||||
<a href="/reference/adapter/sequelize" class="adapter-card">
|
||||
<img src="/img/adapters/sequelize.svg" width="30" />
|
||||
<h4 class="adapter-card__title">Sequelize Adapter</h4>
|
||||
</a>
|
||||
<a href="/reference/adapter/supabase" class="adapter-card">
|
||||
<img src="/img/adapters/supabase.svg" width="25" />
|
||||
<h4 class="adapter-card__title">Supabase Adapter</h4>
|
||||
</a>
|
||||
<a href="/reference/adapter/surrealdb" class="adapter-card">
|
||||
<img src="/img/adapters/surreal.png" width="25" />
|
||||
<h4 class="adapter-card__title">SurrealDB Adapter</h4>
|
||||
</a>
|
||||
<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 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>
|
||||
</a>
|
||||
<a href="/reference/adapter/xata" class="adapter-card">
|
||||
<img src="/img/adapters/xata.svg" width="20" />
|
||||
<h4 class="adapter-card__title">Xata Adapter</h4>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
:::info
|
||||
If you don't find an adapter for the database or service you use, you can always create one yourself. Have a look at our guide on [how to create a database adapter](/guides/adapters/creating-a-database-adapter).
|
||||
:::
|
||||
|
||||
## Models
|
||||
|
||||
Auth.js can be used with any database. Models tell you what structures Auth.js expects from your database. Models will vary slightly depending on which adapter you use, but in general, will look something like this:
|
||||
|
||||
```mermaid
|
||||
erDiagram
|
||||
User ||--|{ Account : ""
|
||||
User {
|
||||
string id
|
||||
string name
|
||||
string email
|
||||
timestamp emailVerified
|
||||
string image
|
||||
}
|
||||
User ||--|{ Session : ""
|
||||
Session {
|
||||
string id
|
||||
timestamp expires
|
||||
string sessionToken
|
||||
string userId
|
||||
}
|
||||
Account {
|
||||
string id
|
||||
string userId
|
||||
string type
|
||||
string provider
|
||||
string providerAccountId
|
||||
string refresh_token
|
||||
string access_token
|
||||
int expires_at
|
||||
string token_type
|
||||
string scope
|
||||
string id_token
|
||||
string session_state
|
||||
}
|
||||
VerificationToken {
|
||||
string identifier
|
||||
string token
|
||||
timestamp expires
|
||||
}
|
||||
```
|
||||
|
||||
More information about each Model/Table can be found below.
|
||||
|
||||
:::note
|
||||
You can [create your adapter](/guides/adapters/creating-a-database-adapter) if you want to use Auth.js with a database that is not supported out of the box, or you have to change fields on any of the models.
|
||||
:::
|
||||
|
||||
---
|
||||
|
||||
### User
|
||||
|
||||
The User model is for information such as the user's name and email address.
|
||||
|
||||
Email address is optional, but if one is specified for a User, then it must be unique.
|
||||
|
||||
:::note
|
||||
If a user first signs in with an OAuth provider, then their email address is automatically populated using the one from their OAuth profile if the OAuth provider returns one.
|
||||
|
||||
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 the future (if the [Email Provider](/reference/core/providers_email) is configured).
|
||||
:::
|
||||
|
||||
User creation in the database is automatic and happens when the user is logging in for the first time with a provider.
|
||||
If the first sign-in is via the [OAuth Provider](/reference/core/providers_oauth), 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.
|
||||
|
||||
If the first sign-in is via the [Email Provider](/reference/core/providers_email), then the saved user will have `id`, `email`, `emailVerified`, where `emailVerified` is the timestamp of when the user was created.
|
||||
|
||||
### Account
|
||||
|
||||
The Account model is for information about OAuth accounts associated with a User
|
||||
|
||||
A single User can have multiple Accounts, but each Account can only have one User.
|
||||
|
||||
Account creation in the database is automatic and happens when the user is logging in for the first time with a provider, or the [`Adapter.linkAccount`](/reference/core/adapters#linkaccount) method is invoked. The default data saved is `access_token`, `expires_at`, `refresh_token`, `id_token`, `token_type`, `scope` and `session_state`. You can save other fields or remove the ones you don't need by returning them in the [OAuth provider](/guides/providers/custom-provider)'s [`account()`](/reference/core/providers#account) callback.
|
||||
|
||||
Linking Accounts to Users happen automatically, only when they have the same e-mail address, and the user is currently signed in. Check the [FAQ](/concepts/faq#security) for more information on why this is a requirement.
|
||||
|
||||
:::tip
|
||||
You can manually unlink accounts if your adapter implements the `unlinkAccount` method. Make sure to take all the necessary security steps to avoid data loss.
|
||||
:::
|
||||
|
||||
:::note
|
||||
Linking and unlinking accounts through an API is a planned feature: https://github.com/nextauthjs/next-auth/issues/230
|
||||
:::
|
||||
|
||||
### Session
|
||||
|
||||
The Session model is used for database sessions. It is not used if JSON Web Tokens are enabled. Keep in mind, that you can use a database to persist Users and Accounts, and still use JWT for sessions. See the [`session.strategy`](/reference/configuration/auth-config) option.
|
||||
|
||||
A single User can have multiple Sessions, each Session can only have one User.
|
||||
|
||||
:::tip
|
||||
When a Session is read, we check if its `expires` field indicates an invalid session, and delete it from the database. You can also do this clean-up periodically in the background to avoid our extra delete call to the database during an active session retrieval. This might result in a slight performance increase in a few cases.
|
||||
:::
|
||||
|
||||
### Verification Token
|
||||
|
||||
The Verification Token model is used to store tokens for passwordless sign in.
|
||||
|
||||
A single User can have multiple open Verification Tokens (e.g. to sign in to different devices).
|
||||
|
||||
It has been designed to be extendable for other verification purposes in the future (e.g. 2FA / magic codes, etc.).
|
||||
|
||||
:::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`](/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
|
||||
Due to users forgetting or failing at the sign-in flow, you might end up with unwanted rows in your database, that you might have to periodically clean up to avoid filling the database up with unnecessary data.
|
||||
:::
|
||||
|
||||
## RDBMS Naming Convention
|
||||
|
||||
Auth.js / NextAuth.js uses `camelCase` for its database rows while respecting the conventional `snake_case` formatting for OAuth-related values. If the mixed casing is an issue for you, most adapters have a dedicated documentation section on how to force a casing convention.
|
||||
|
||||
## TypeScript
|
||||
|
||||
Check out the [`@auth/core/adapters` API Reference](/reference/core/adapters) documentation.
|
||||
|
||||
## Create a custom adapter
|
||||
|
||||
If you are using a database that we don't have an official adapter for, you can check out the [Creating a database adapter](/guides/adapters/creating-a-database-adapter) guide.
|
||||
@@ -1,34 +0,0 @@
|
||||
---
|
||||
title: Overview
|
||||
---
|
||||
|
||||
This section of the documentation contains the API reference for all the official packages under the `@auth/*` and `@next-auth/*` scopes.
|
||||
|
||||
## Roadmap
|
||||
|
||||
Here are the _state_ of planned and released packages under the `@auth/*` and `@next-auth/*` scope, as well as `next-auth`. This is not an exhaustive list, but the set of packages that we would like to focus on, to begin with.
|
||||
|
||||
| Feature | Status |
|
||||
| ---------------------- | -------- |
|
||||
| `next-auth` | Release (stable). See [docs](https://next-auth.js.org) |
|
||||
| `@auth/*-adapter` | Released (stable). Fully compatible with `next-auth` and all `@auth/*` libraries. |
|
||||
| `@next-auth/*-adapter` | Maintenance has stopped. Update to `@auth/*-adapter`. See above. |
|
||||
| `@auth/core` | Released (experimental). |
|
||||
| `@auth/sveltekit` | Released (experimental, [help needed](#help-needed)). |
|
||||
| `@auth/solid-start` | Released (experimental, [help needed](#help-needed)). Community package: [`@solid-mediakit/auth`](https://www.npmjs.com/package/@solid-mediakit/auth) |
|
||||
| `@auth/express` | [Planned](https://github.com/nextauthjs/next-auth/issues/8257). |
|
||||
| `@auth/remix` | Planned, [help needed](#help-needed). |
|
||||
| `@auth/astro` | Planned, [help needed](#help-needed). |
|
||||
| `@auth/nuxt` | Planned, [help needed](#help-needed). Community packages: [`@sidebase/nuxt-auth`](https://github.com/sidebase/nuxt-auth), [`@hebilicious/authjs-nuxt`](https://authjs-nuxt.pages.dev/) |
|
||||
|
||||
:::info
|
||||
`next-auth` is still the official package for Next.js. The documentation is at [next-auth.js.org](https://next-auth.js.org), while guides are being migrated over to the new documentation page. A major refactor of `next-auth` is on the way, you can [follow this PR](https://github.com/nextauthjs/next-auth/pull/7443) for updates.
|
||||
:::
|
||||
|
||||
### Help needed
|
||||
|
||||
In case you are a maintainer of a package that uses `@auth/core`, feel free to [reach out to Balázs](https://twitter.com/balazsorban44), if you want to collaborate on making it an official package, maintained in our repository. If you are interested in bringing `@auth/core` support to your favorite framework, we would love to hear from you!
|
||||
|
||||
#### Community Packages
|
||||
|
||||
While we are migrating the documentation and working on stabilizing the core package, the community has been working on some packages that are already available. With collaboration, we hope to make these packages official in the future.
|
||||
@@ -1,15 +0,0 @@
|
||||
---
|
||||
id: warnings
|
||||
title: Warnings
|
||||
---
|
||||
|
||||
A list of warnings from Auth.js that need your attention.
|
||||
|
||||
|
||||
## Debug enabled
|
||||
|
||||
The `debug` option was evaluated to `true`. It adds extra logs in the terminal which is useful in development, but since it can print sensitive information about users, make sure to set this to `false` in production. In Node.js environments, you can for example set `debug: process.env.NODE_ENV !== "production"`. Consult with your runtime/framework on how to set this value correctly.
|
||||
|
||||
## CSRF disabled
|
||||
|
||||
You were trying to get a CSRF response from Auth.js (eg.: by calling a `/csrf` endpoint), but in this setup, CSRF protection via Auth.js was turned off. This is likely if you are not directly using `@auth/core` but a framework library (like `@auth/sveltekit`) that already has CSRF protection built-in. You likely won't need the CSRF response.
|
||||
@@ -1,376 +0,0 @@
|
||||
// @ts-check
|
||||
|
||||
const fs = require("fs")
|
||||
const path = require("path")
|
||||
|
||||
// list providers entries from @auth/core/providers/*.ts
|
||||
const coreSrc = "../packages/core/src"
|
||||
const providers = fs
|
||||
.readdirSync(path.join(__dirname, coreSrc, "/providers"))
|
||||
.filter((file) => file.endsWith(".ts"))
|
||||
.map((p) => `${coreSrc}/providers/${p}`)
|
||||
|
||||
const typedocConfig = require("./typedoc.json")
|
||||
// @ts-expect-error
|
||||
delete typedocConfig.$schema
|
||||
|
||||
/**
|
||||
* @param {string} name
|
||||
* @returns Record<[string, any]>
|
||||
*/
|
||||
function typedocAdapter(name) {
|
||||
const slug = name.toLowerCase().replace(" ", "-")
|
||||
|
||||
return [
|
||||
"docusaurus-plugin-typedoc",
|
||||
{
|
||||
id: slug,
|
||||
plugin: [require.resolve("./typedoc-mdn-links")],
|
||||
watch: process.env.TYPEDOC_WATCH,
|
||||
entryPoints: [`../packages/adapter-${slug}/src/index.ts`],
|
||||
tsconfig: `../packages/adapter-${slug}/tsconfig.json`,
|
||||
out: `reference/adapter/${slug}`,
|
||||
...typedocConfig,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
function typedocFramework(pkgDir, entrypoints) {
|
||||
const id = pkgDir.replace("frameworks-", "")
|
||||
return [
|
||||
"docusaurus-plugin-typedoc",
|
||||
{
|
||||
...typedocConfig,
|
||||
id: id,
|
||||
plugin: [require.resolve("./typedoc-mdn-links")],
|
||||
watch: process.env.TYPEDOC_WATCH,
|
||||
entryPoints: entrypoints.map((e) => `../packages/${pkgDir}/src/${e}`),
|
||||
tsconfig: `../packages/${pkgDir}/tsconfig.json`,
|
||||
out: `reference/${id === "next-auth" ? "nextjs" : id}`,
|
||||
skipIndexPage: true,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
/** @type {import("@docusaurus/types").Config} */
|
||||
const docusaurusConfig = {
|
||||
markdown: {
|
||||
mermaid: true,
|
||||
},
|
||||
themes: ["@docusaurus/theme-mermaid"],
|
||||
title: "Auth.js",
|
||||
tagline: "Authentication for the Web.",
|
||||
url: "https://authjs.dev",
|
||||
baseUrl: "/",
|
||||
favicon: "img/favicon.ico",
|
||||
trailingSlash: false,
|
||||
organizationName: "nextauthjs",
|
||||
// TODO: remove this once ready
|
||||
onBrokenLinks: "log",
|
||||
projectName: "next-auth",
|
||||
themeConfig: {
|
||||
prism: {
|
||||
theme: require("prism-react-renderer/themes/nightOwl"),
|
||||
magicComments: [
|
||||
{
|
||||
className: "theme-code-block-highlighted-line",
|
||||
line: "highlight-next-line",
|
||||
block: { start: "highlight-start", end: "highlight-end" },
|
||||
},
|
||||
],
|
||||
},
|
||||
algolia: {
|
||||
appId: "OUEDA16KPG",
|
||||
apiKey: "97c0894508f2d1d4a2fef4fe6db28448",
|
||||
indexName: "next-auth",
|
||||
searchParameters: {},
|
||||
contextualSearch: false,
|
||||
externalUrlRegex: "authjs\\.dev|next-auth\\.js\\.org",
|
||||
},
|
||||
navbar: {
|
||||
title: "Auth.js",
|
||||
logo: {
|
||||
alt: "Auth.js Logo",
|
||||
src: "img/logo/logo-xs.webp",
|
||||
},
|
||||
items: [
|
||||
{
|
||||
to: "/getting-started/introduction",
|
||||
activeBasePath: "/getting-started/",
|
||||
label: "Getting started",
|
||||
position: "left",
|
||||
},
|
||||
{
|
||||
to: "/guides",
|
||||
activeBasePath: "/guides",
|
||||
label: "Guides",
|
||||
position: "left",
|
||||
},
|
||||
{
|
||||
to: "/reference",
|
||||
activeBasePath: "/reference",
|
||||
label: "API Reference",
|
||||
position: "left",
|
||||
},
|
||||
{
|
||||
to: "/concepts/faq",
|
||||
activeBasePath: "/concepts",
|
||||
label: "Concepts",
|
||||
position: "left",
|
||||
},
|
||||
{
|
||||
to: "/security",
|
||||
activeBasePath: "/security",
|
||||
label: "Security",
|
||||
position: "left",
|
||||
},
|
||||
{
|
||||
type: "docsVersionDropdown",
|
||||
position: "right",
|
||||
dropdownActiveClassDisabled: true,
|
||||
dropdownItemsAfter: [
|
||||
{
|
||||
to: "https://github.com/nextauthjs/next-auth/releases",
|
||||
label: "All Releases",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
to: "https://www.npmjs.com/package/next-auth",
|
||||
label: "npm",
|
||||
position: "right",
|
||||
},
|
||||
{
|
||||
to: "https://github.com/nextauthjs/next-auth",
|
||||
label: "GitHub",
|
||||
position: "right",
|
||||
},
|
||||
],
|
||||
},
|
||||
announcementBar: {
|
||||
id: "new-major-announcement",
|
||||
content:
|
||||
"<a target='_blank' rel='noopener noreferrer' href='https://next-auth.js.org'>NextAuth.js</a> is becoming Auth.js! 🎉 <a target='_blank' rel='noopener noreferrer' href='https://twitter.com/balazsorban44/status/1603082914362986496'>Read the announcement.</a> Note, this site is under active development. 🏗",
|
||||
backgroundColor: "#000",
|
||||
textColor: "#fff",
|
||||
},
|
||||
footer: {
|
||||
links: [
|
||||
{
|
||||
title: "About Auth.js",
|
||||
items: [
|
||||
{
|
||||
label: "Introduction",
|
||||
to: "/getting-started/introduction",
|
||||
},
|
||||
{
|
||||
html: `
|
||||
<a target="_blank" rel="noopener noreferrer" href="https://vercel.com?utm_source=authjs&utm_campaign=oss">
|
||||
<img
|
||||
alt="Powered by Vercel"
|
||||
style="margin-top: 8px"
|
||||
height="32"
|
||||
width="167"
|
||||
src="https://raw.githubusercontent.com/nextauthjs/next-auth/main/docs/static/img/powered-by-vercel.svg"
|
||||
/>
|
||||
</a>`,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Download",
|
||||
items: [
|
||||
{
|
||||
label: "GitHub",
|
||||
to: "https://github.com/nextauthjs/next-auth",
|
||||
},
|
||||
{
|
||||
label: "NPM",
|
||||
to: "https://www.npmjs.com/package/next-auth",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Acknowledgements",
|
||||
items: [
|
||||
{
|
||||
label: "Contributors",
|
||||
to: "/contributors",
|
||||
},
|
||||
{
|
||||
label: "Sponsors",
|
||||
to: "https://opencollective.com/nextauth",
|
||||
},
|
||||
{
|
||||
label: "Images by unDraw",
|
||||
to: "https://undraw.co/",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
copyright: `Auth.js © Balázs Orbán ${new Date().getFullYear()}`,
|
||||
},
|
||||
colorMode: {
|
||||
respectPrefersColorScheme: true,
|
||||
},
|
||||
docs: {
|
||||
sidebar: {
|
||||
autoCollapseCategories: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
presets: [
|
||||
[
|
||||
"@docusaurus/preset-classic",
|
||||
{
|
||||
docs: {
|
||||
breadcrumbs: false,
|
||||
routeBasePath: "/",
|
||||
sidebarPath: require.resolve("./sidebars.js"),
|
||||
/**
|
||||
*
|
||||
* @param {{
|
||||
* version: string;
|
||||
* versionDocsDirPath: string;
|
||||
* docPath: string;
|
||||
* permalink: string;
|
||||
* locale: string;
|
||||
*}} params
|
||||
*/
|
||||
editUrl({ docPath }) {
|
||||
// TODO: support other packages, fix directory links like "providers"
|
||||
const base = "https://github.com/nextauthjs/next-auth/edit/main/packages"
|
||||
if (docPath.includes("reference/core")) {
|
||||
const file = docPath.split("reference/core/")[1].replace(".md", ".ts").replace("_", "/")
|
||||
return `${base}/core/src/${file}`
|
||||
} else if (docPath.includes("reference/adapter/")) {
|
||||
const file = docPath.split("reference/adapter/")[1].replace("index.md", "src/index.ts")
|
||||
return `${base}/adapter-${file}`
|
||||
}
|
||||
return `https://github.com/nextauthjs/next-auth/edit/main/docs/docs/${docPath}`
|
||||
},
|
||||
lastVersion: "current",
|
||||
showLastUpdateAuthor: true,
|
||||
showLastUpdateTime: true,
|
||||
remarkPlugins: [require("@sapphire/docusaurus-plugin-npm2yarn2pnpm").npm2yarn2pnpm],
|
||||
versions: {
|
||||
current: {
|
||||
label: "experimental",
|
||||
},
|
||||
},
|
||||
async sidebarItemsGenerator({ defaultSidebarItemsGenerator, ...args }) {
|
||||
const sidebarItems = await defaultSidebarItemsGenerator(args)
|
||||
const sidebarIdsToOmit = ["reference/core/index", "reference/sveltekit/index", "reference/solidstart/index"]
|
||||
return sidebarItems.filter((sidebarItem) => !sidebarIdsToOmit.includes(sidebarItem.id))
|
||||
},
|
||||
},
|
||||
theme: {
|
||||
customCss: require.resolve("./src/css/index.css"),
|
||||
},
|
||||
},
|
||||
],
|
||||
],
|
||||
plugins: [
|
||||
typedocFramework("core", ["index.ts", "adapters.ts", "errors.ts", "jwt.ts", "types.ts"]),
|
||||
typedocFramework("frameworks-sveltekit", ["lib/index.ts", "lib/client.ts"]),
|
||||
...(process.env.TYPEDOC_SKIP_ADAPTERS
|
||||
? []
|
||||
: [
|
||||
typedocAdapter("Azure Tables"),
|
||||
typedocAdapter("D1"),
|
||||
typedocAdapter("EdgeDb"),
|
||||
typedocAdapter("Dgraph"),
|
||||
typedocAdapter("Drizzle"),
|
||||
typedocAdapter("DynamoDB"),
|
||||
typedocAdapter("Fauna"),
|
||||
typedocAdapter("Firebase"),
|
||||
typedocAdapter("Kysely"),
|
||||
typedocAdapter("Mikro ORM"),
|
||||
typedocAdapter("MongoDB"),
|
||||
typedocAdapter("Neo4j"),
|
||||
typedocAdapter("PG"),
|
||||
typedocAdapter("PouchDB"),
|
||||
typedocAdapter("Prisma"),
|
||||
typedocAdapter("TypeORM"),
|
||||
typedocAdapter("Sequelize"),
|
||||
typedocAdapter("Supabase"),
|
||||
typedocAdapter("SurrealDB"),
|
||||
typedocAdapter("Upstash Redis"),
|
||||
typedocAdapter("Xata"),
|
||||
]),
|
||||
],
|
||||
}
|
||||
|
||||
docusaurusConfig.headTags = [
|
||||
{
|
||||
tagName: "meta",
|
||||
attributes: {
|
||||
charSet: "utf-8",
|
||||
},
|
||||
},
|
||||
{
|
||||
tagName: "link",
|
||||
attributes: {
|
||||
rel: "canonical",
|
||||
href: docusaurusConfig.url,
|
||||
},
|
||||
},
|
||||
{
|
||||
tagName: "meta",
|
||||
attributes: {
|
||||
property: "og:title",
|
||||
content: docusaurusConfig.title,
|
||||
},
|
||||
},
|
||||
{
|
||||
tagName: "meta",
|
||||
attributes: {
|
||||
property: "og:description",
|
||||
content: docusaurusConfig.tagline,
|
||||
},
|
||||
},
|
||||
{
|
||||
tagName: "meta",
|
||||
attributes: {
|
||||
property: "og:image",
|
||||
content: `${docusaurusConfig.url}/img/og-image.png`,
|
||||
},
|
||||
},
|
||||
{
|
||||
tagName: "meta",
|
||||
attributes: {
|
||||
property: "og:url",
|
||||
content: docusaurusConfig.url,
|
||||
},
|
||||
},
|
||||
{
|
||||
tagName: "meta",
|
||||
attributes: {
|
||||
name: "twitter:card",
|
||||
content: "summary_large_image",
|
||||
},
|
||||
},
|
||||
{
|
||||
tagName: "meta",
|
||||
attributes: {
|
||||
name: "twitter:title",
|
||||
content: docusaurusConfig.title,
|
||||
},
|
||||
},
|
||||
{
|
||||
tagName: "meta",
|
||||
attributes: {
|
||||
name: "twitter:description",
|
||||
content: docusaurusConfig.tagline,
|
||||
},
|
||||
},
|
||||
{
|
||||
tagName: "meta",
|
||||
attributes: {
|
||||
name: "twitter:image",
|
||||
content: `${docusaurusConfig.url}/img/og-image.png`,
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
module.exports = docusaurusConfig
|
||||
5
docs/next-env.d.ts
vendored
Normal file
5
docs/next-env.d.ts
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
/// <reference types="next" />
|
||||
/// <reference types="next/image-types/global" />
|
||||
|
||||
// NOTE: This file should not be edited
|
||||
// see https://nextjs.org/docs/basic-features/typescript for more information.
|
||||
26
docs/next.config.mjs
Normal file
26
docs/next.config.mjs
Normal file
@@ -0,0 +1,26 @@
|
||||
import withNextra from "nextra"
|
||||
import RemarkLinkRewrite from "remark-link-rewrite"
|
||||
|
||||
export default withNextra({
|
||||
theme: "nextra-theme-docs",
|
||||
themeConfig: "./theme.config.jsx",
|
||||
mdxOptions: {
|
||||
format: "detect",
|
||||
remarkPlugins: [
|
||||
[
|
||||
RemarkLinkRewrite,
|
||||
{
|
||||
replacer(url) {
|
||||
if (url.includes(".md")) {
|
||||
url = url.replace(/\.md$/, "").replace(".md#", "#")
|
||||
}
|
||||
if (url.startsWith("https://authjs.dev")) {
|
||||
url = url.replace("https://authjs.dev", "")
|
||||
}
|
||||
return url
|
||||
},
|
||||
},
|
||||
],
|
||||
],
|
||||
},
|
||||
})()
|
||||
@@ -1,53 +1,33 @@
|
||||
{
|
||||
"private": true,
|
||||
"repository": "https://github.com/nextauthjs/next-auth",
|
||||
"name": "docs",
|
||||
"version": "0.0.1",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"start": "TYPEDOC_WATCH=true docusaurus start --no-open",
|
||||
"dev": "pnpm providers && pnpm snippets && pnpm start",
|
||||
"build": "pnpm providers && docusaurus build",
|
||||
"docusaurus": "docusaurus",
|
||||
"swizzle": "docusaurus swizzle",
|
||||
"deploy": "docusaurus deploy",
|
||||
"serve": "docusaurus serve",
|
||||
"clear": "docusaurus clear",
|
||||
"providers": "node scripts/generate-providers.mjs",
|
||||
"snippets": "node scripts/generate-snippets.mjs"
|
||||
"typedoc": "typedoc",
|
||||
"dev": "TYPEDOC_WATCH=1 pnpm typedoc & next dev",
|
||||
"start": "next start",
|
||||
"build": "next build"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "ndom91 <yo@ndo.dev> (https://ndo.dev/)",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@mdx-js/react": "1.6.22",
|
||||
"@sapphire/docusaurus-plugin-npm2yarn2pnpm": "1.1.4",
|
||||
"classnames": "^2.3.2",
|
||||
"mdx-mermaid": "1.2.2",
|
||||
"mermaid": "9.0.1",
|
||||
"prism-react-renderer": "1.3.5",
|
||||
"@codesandbox/sandpack-react": "^2.0.6",
|
||||
"framer-motion": "^8.4.3",
|
||||
"next": "13.2.4",
|
||||
"nextra": "^2.2.19",
|
||||
"nextra-theme-docs": "^2.2.19",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-marquee-slider": "^1.1.5",
|
||||
"styled-components": "5.3.6"
|
||||
"remark-link-rewrite": "^1.0.6",
|
||||
"typedoc": "^0.23.24",
|
||||
"typedoc-plugin-markdown": "next"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@docusaurus/core": "2.4.1",
|
||||
"@docusaurus/eslint-plugin": "2.4.1",
|
||||
"@docusaurus/module-type-aliases": "2.4.1",
|
||||
"@docusaurus/preset-classic": "2.4.1",
|
||||
"@docusaurus/theme-common": "2.4.1",
|
||||
"@docusaurus/theme-mermaid": "2.4.1",
|
||||
"@docusaurus/types": "2.4.1",
|
||||
"docusaurus-plugin-typedoc": "1.0.0-next.13",
|
||||
"typedoc": "^0.24.8",
|
||||
"typedoc-plugin-markdown": "4.0.0-next.16"
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
"autoprefixer": "^10.4.13",
|
||||
"eslint-config-next": "^13.2.4",
|
||||
"postcss": "^8.4.21",
|
||||
"tailwindcss": "^3.2.4"
|
||||
}
|
||||
}
|
||||
|
||||
5
docs/pages/404.mdx
Normal file
5
docs/pages/404.mdx
Normal file
@@ -0,0 +1,5 @@
|
||||
import { NotFoundPage } from 'nextra-theme-docs'
|
||||
|
||||
# 404 - This page could not be found
|
||||
|
||||
<NotFoundPage />
|
||||
5
docs/pages/500.mdx
Normal file
5
docs/pages/500.mdx
Normal file
@@ -0,0 +1,5 @@
|
||||
import { ServerSideErrorPage } from 'nextra-theme-docs'
|
||||
|
||||
# 500 - Internal Server Error
|
||||
|
||||
<ServerSideErrorPage />
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user