14 |
15 |
16 | ## Overview
17 |
18 | This is the Fauna Adapter for [`next-auth`](https://next-auth.js.org). This package can only be used in conjunction with the primary `next-auth` package. It is not a standalone package.
19 |
20 | You can find the Fauna schema and seed information in the docs at [next-auth.js.org/adapters/fauna](https://next-auth.js.org/adapters/fauna).
21 |
22 | ## Getting Started
23 |
24 | 1. Install `faunadb`, `next-auth` and `@next-auth/fauna-adapter`
25 |
26 | ```js
27 | npm install faunadb next-auth @next-auth/fauna-adapter@next
28 | ```
29 |
30 | 2. Add this adapter to your `pages/api/[...nextauth].js` next-auth configuration object.
31 |
32 | ```js
33 | import NextAuth from "next-auth"
34 | import { Client as FaunaClient } from "faunadb"
35 | import { FaunaAdapter } from "@next-auth/fauna-adapter"
36 |
37 | const client = new FaunaClient({
38 | secret: "secret",
39 | scheme: "http",
40 | domain: "localhost",
41 | port: 8443,
42 | })
43 |
44 | // For more information on each option (and a full list of options) go to
45 | // https://next-auth.js.org/configuration/options
46 | export default NextAuth({
47 | // https://next-auth.js.org/configuration/providers
48 | providers: [],
49 | adapter: FaunaAdapter(client)
50 | ...
51 | })
52 | ```
53 |
54 | ## Contributing
55 |
56 | We're open to all community contributions! If you'd like to contribute in any way, please read our [Contributing Guide](https://github.com/nextauthjs/adapters/blob/main/CONTRIBUTING.md).
57 |
58 | ## License
59 |
60 | ISC
61 |
--------------------------------------------------------------------------------
/packages/mikro-orm/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
Mikro ORM Adapter - NextAuth.js
5 |
6 | Open Source. Full Stack. Own Your Data.
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | ## Overview
16 |
17 | This is the MikroORM Adapter for [`next-auth`](https://next-auth.js.org). This package can only be used in conjunction with the primary `next-auth` package. It is not a standalone package.
18 |
19 | ## Getting Started
20 |
21 | 1. Install `next-auth` and `@next-auth/mikro-orm-adapter`
22 |
23 | ```js
24 | npm install next-auth @next-auth/mikro-orm-adapter@next
25 | ```
26 |
27 | 2. Add this adapter to your `pages/api/[...nextauth].ts` next-auth configuration object.
28 |
29 | ```typescript title="pages/api/auth/[...nextauth].ts"
30 | import NextAuth from "next-auth"
31 | import { MikroOrmAdapter } from "@next-auth/mikro-orm-adapter"
32 |
33 | // For more information on each option (and a full list of options) go to
34 | // https://next-auth.js.org/configuration/options
35 | export default NextAuth({
36 | // https://next-auth.js.org/configuration/providers
37 | providers: [],
38 | // optionally pass extended models as { entities: { } }
39 | adapter: MikroOrmAdapter({
40 | dbName: "./db.sqlite",
41 | type: "sqlite",
42 | debug: process.env.DEBUG === "true" || process.env.DEBUG?.includes("db"),
43 | ...
44 | }),
45 | ...
46 | });
47 | ```
48 |
49 | ## Contributing
50 |
51 | We're open to all community contributions! If you'd like to contribute in any way, please read our [Contributing Guide](https://github.com/nextauthjs/adapters/blob/main/CONTRIBUTING.md).
52 |
53 | ## License
54 |
55 | ISC
56 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/upstash-redis.yaml:
--------------------------------------------------------------------------------
1 | name: Upstash Redis
2 | description: File a support request for the Upstash Redis adapter
3 | labels: upstash-redis
4 |
5 | # note: markdown sections will NOT appear as part of the issue as per documentation, rather they provide context to the user
6 | # https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-githubs-form-schema#markdown
7 |
8 | body:
9 | - type: markdown
10 | attributes:
11 | value: |
12 | Thanks for taking the time to fill out this issue!
13 | ### Important :exclamation:
14 | Please help us maintain this project more efficiently! Before creating the issue make sure you shouldn't be creating it in one the below repos instead:
15 | - Core related: https://github.com/nextauthjs/next-auth
16 | - Docs related: https://github.com/nextauthjs/docs
17 |
18 | If you are in the correct repo, then proceed by providing the following information:
19 | - type: input
20 | id: title
21 | attributes:
22 | label: Title
23 | validations:
24 | required: true
25 | - type: textarea
26 | id: reproduction
27 | attributes:
28 | label: How to reproduce ☕️
29 | description: Please provide a link or code snippets to a minimal reproduction of the bug
30 | validations:
31 | required: true
32 | - type: markdown
33 | attributes:
34 | value: |
35 | We encourage you to use one of the templates set up on **CodeSandbox** to reproduce your issue:
36 | - [`next-auth-example`](https://codesandbox.io/s/next-auth-example-1kktb)
37 | - [`next-auth-typescript-example`](https://codesandbox.io/s/next-auth-typescript-example-se32w)
38 |
39 | 🚧 – _If you don't provide any way to reproduce the bug, the issue is at risk of being closed._
40 |
41 | - type: textarea
42 | id: description
43 | attributes:
44 | label: Your question/bug report 📓
45 | description: Please provide a more in-depth description of your request.
46 | validations:
47 | required: true
48 | - type: dropdown
49 | id: contributing
50 | attributes:
51 | label: Contributing 🙌🏽
52 | description: Are you willing to open a PR for this?
53 | multiple: false
54 | options:
55 | - "Yes, I am"
56 | - "No, I'm afraid I cannot help regarding this"
57 | validations:
58 | required: true
59 | - type: markdown
60 | attributes:
61 | value: |
62 | It takes a lot of work 🏋🏻♀️ maintaining a library like `next-auth`; any contribution is more than welcome 💚
63 |
--------------------------------------------------------------------------------
/.github/workflows/codeql-analysis.yml:
--------------------------------------------------------------------------------
1 | # For most projects, this workflow file will not need changing; you simply need
2 | # to commit it to your repository.
3 | #
4 | # You may wish to alter this file to override the set of languages analyzed,
5 | # or to provide custom queries or build logic.
6 | #
7 | # ******** NOTE ********
8 | # We have attempted to detect the languages in your repository. Please check
9 | # the `language` matrix defined below to confirm you have the correct set of
10 | # supported CodeQL languages.
11 | #
12 | name: "CodeQL"
13 |
14 | on:
15 | push:
16 | branches: [ canary, main ]
17 | pull_request:
18 | # The branches below must be a subset of the branches above
19 | branches: [ canary ]
20 | schedule:
21 | - cron: '19 2 * * 4'
22 |
23 | jobs:
24 | analyze:
25 | name: Analyze
26 | runs-on: ubuntu-latest
27 |
28 | strategy:
29 | fail-fast: false
30 | matrix:
31 | language: [ 'javascript' ]
32 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
33 | # Learn more:
34 | # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
35 |
36 | steps:
37 | - name: Checkout repository
38 | uses: actions/checkout@v2
39 |
40 | # Initializes the CodeQL tools for scanning.
41 | - name: Initialize CodeQL
42 | uses: github/codeql-action/init@v1
43 | with:
44 | languages: ${{ matrix.language }}
45 | # If you wish to specify custom queries, you can do so here or in a config file.
46 | # By default, queries listed here will override any specified in a config file.
47 | # Prefix the list here with "+" to use these queries and those in the config file.
48 | # queries: ./path/to/local/query, your-org/your-repo/queries@main
49 |
50 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
51 | # If this step fails, then you should remove it and run the build manually (see below)
52 | - name: Autobuild
53 | uses: github/codeql-action/autobuild@v1
54 |
55 | # ℹ️ Command-line programs to run using the OS shell.
56 | # 📚 https://git.io/JvXDl
57 |
58 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
59 | # and modify them (or add more) to build your code if your project
60 | # uses a compiled language
61 |
62 | #- run: |
63 | # make bootstrap
64 | # make release
65 |
66 | - name: Perform CodeQL Analysis
67 | uses: github/codeql-action/analyze@v1
68 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/prisma.yaml:
--------------------------------------------------------------------------------
1 | name: Prisma
2 | description: File a support request for the Prisma adapter
3 | labels: prisma
4 |
5 | # note: markdown sections will NOT appear as part of the issue as per documentation, rather they provide context to the user
6 | # https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-githubs-form-schema#markdown
7 |
8 |
9 | body:
10 | - type: markdown
11 | attributes:
12 | value: |
13 | Thanks for taking the time to fill out this issue!
14 | ### Important :exclamation:
15 | Please help us maintain this project more efficiently! Before creating the issue make sure you shouldn't be creating it in one the below repos instead:
16 | - Core related: https://github.com/nextauthjs/next-auth
17 | - Docs related: https://github.com/nextauthjs/docs
18 |
19 | If you are in the correct repo, then proceed by providing the following information:
20 | - type: input
21 | id: title
22 | attributes:
23 | label: Title
24 | validations:
25 | required: true
26 | - type: textarea
27 | id: reproduction
28 | attributes:
29 | label: How to reproduce ☕️
30 | description: Please provide a link or code snippets to a minimal reproduction of the bug
31 | validations:
32 | required: true
33 | - type: markdown
34 | attributes:
35 | value: |
36 | We encourage you to use one of the templates set up on **CodeSandbox** to reproduce your issue:
37 | - [`next-auth-example`](https://codesandbox.io/s/next-auth-example-1kktb)
38 | - [`next-auth-typescript-example`](https://codesandbox.io/s/next-auth-typescript-example-se32w)
39 |
40 | 🚧 – _If you don't provide any way to reproduce the bug, the issue is at risk of being closed._
41 |
42 | - type: textarea
43 | id: description
44 | attributes:
45 | label: Your question/bug report 📓
46 | description: Please provide a more in-depth description of your request.
47 | validations:
48 | required: true
49 | - type: dropdown
50 | id: contributing
51 | attributes:
52 | label: Contributing 🙌🏽
53 | description: Are you willing to open a PR for this?
54 | multiple: false
55 | options:
56 | - "Yes, I am"
57 | - "No, I'm afraid I cannot help regarding this"
58 | validations:
59 | required: true
60 | - type: markdown
61 | attributes:
62 | value: |
63 | It takes a lot of work 🏋🏻♀️ maintaining a library like `next-auth`; any contribution is more than welcome 💚
64 |
65 |
66 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/faunadb.yaml:
--------------------------------------------------------------------------------
1 | name: FaunaDB
2 | description: File a support request for the FaunaDB adapter
3 | labels: fauna
4 |
5 | # note: markdown sections will NOT appear as part of the issue as per documentation, rather they provide context to the user
6 | # https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-githubs-form-schema#markdown
7 |
8 |
9 | body:
10 | - type: markdown
11 | attributes:
12 | value: |
13 | Thanks for taking the time to fill out this issue!
14 | ### Important :exclamation:
15 | Please help us maintain this project more efficiently! Before creating the issue make sure you shouldn't be creating it in one the below repos instead:
16 | - Core related: https://github.com/nextauthjs/next-auth
17 | - Docs related: https://github.com/nextauthjs/docs
18 |
19 | If you are in the correct repo, then proceed by providing the following information:
20 | - type: input
21 | id: title
22 | attributes:
23 | label: Title
24 | validations:
25 | required: true
26 | - type: textarea
27 | id: reproduction
28 | attributes:
29 | label: How to reproduce ☕️
30 | description: Please provide a link or code snippets to a minimal reproduction of the bug
31 | validations:
32 | required: true
33 | - type: markdown
34 | attributes:
35 | value: |
36 | We encourage you to use one of the templates set up on **CodeSandbox** to reproduce your issue:
37 | - [`next-auth-example`](https://codesandbox.io/s/next-auth-example-1kktb)
38 | - [`next-auth-typescript-example`](https://codesandbox.io/s/next-auth-typescript-example-se32w)
39 |
40 | 🚧 – _If you don't provide any way to reproduce the bug, the issue is at risk of being closed._
41 |
42 | - type: textarea
43 | id: description
44 | attributes:
45 | label: Your question/bug report 📓
46 | description: Please provide a more in-depth description of your request.
47 | validations:
48 | required: true
49 | - type: dropdown
50 | id: contributing
51 | attributes:
52 | label: Contributing 🙌🏽
53 | description: Are you willing to open a PR for this?
54 | multiple: false
55 | options:
56 | - "Yes, I am"
57 | - "No, I'm afraid I cannot help regarding this"
58 | validations:
59 | required: true
60 | - type: markdown
61 | attributes:
62 | value: |
63 | It takes a lot of work 🏋🏻♀️ maintaining a library like `next-auth`; any contribution is more than welcome 💚
64 |
65 |
66 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/mongodb.yaml:
--------------------------------------------------------------------------------
1 | name: MongoDB
2 | description: File a support request for the MongoDB adapter
3 | labels: mongodb
4 |
5 | # note: markdown sections will NOT appear as part of the issue as per documentation, rather they provide context to the user
6 | # https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-githubs-form-schema#markdown
7 |
8 |
9 | body:
10 | - type: markdown
11 | attributes:
12 | value: |
13 | Thanks for taking the time to fill out this issue!
14 | ### Important :exclamation:
15 | Please help us maintain this project more efficiently! Before creating the issue make sure you shouldn't be creating it in one the below repos instead:
16 | - Core related: https://github.com/nextauthjs/next-auth
17 | - Docs related: https://github.com/nextauthjs/docs
18 |
19 | If you are in the correct repo, then proceed by providing the following information:
20 | - type: input
21 | id: title
22 | attributes:
23 | label: Title
24 | validations:
25 | required: true
26 | - type: textarea
27 | id: reproduction
28 | attributes:
29 | label: How to reproduce ☕️
30 | description: Please provide a link or code snippets to a minimal reproduction of the bug
31 | validations:
32 | required: true
33 | - type: markdown
34 | attributes:
35 | value: |
36 | We encourage you to use one of the templates set up on **CodeSandbox** to reproduce your issue:
37 | - [`next-auth-example`](https://codesandbox.io/s/next-auth-example-1kktb)
38 | - [`next-auth-typescript-example`](https://codesandbox.io/s/next-auth-typescript-example-se32w)
39 |
40 | 🚧 – _If you don't provide any way to reproduce the bug, the issue is at risk of being closed._
41 |
42 | - type: textarea
43 | id: description
44 | attributes:
45 | label: Your question/bug report 📓
46 | description: Please provide a more in-depth description of your request.
47 | validations:
48 | required: true
49 | - type: dropdown
50 | id: contributing
51 | attributes:
52 | label: Contributing 🙌🏽
53 | description: Are you willing to open a PR for this?
54 | multiple: false
55 | options:
56 | - "Yes, I am"
57 | - "No, I'm afraid I cannot help regarding this"
58 | validations:
59 | required: true
60 | - type: markdown
61 | attributes:
62 | value: |
63 | It takes a lot of work 🏋🏻♀️ maintaining a library like `next-auth`; any contribution is more than welcome 💚
64 |
65 |
66 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/pouchdb.yaml:
--------------------------------------------------------------------------------
1 | name: PouchDP
2 | description: File a support request for the PouchDB adapter
3 | labels: pouchdb
4 |
5 | # note: markdown sections will NOT appear as part of the issue as per documentation, rather they provide context to the user
6 | # https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-githubs-form-schema#markdown
7 |
8 |
9 | body:
10 | - type: markdown
11 | attributes:
12 | value: |
13 | Thanks for taking the time to fill out this issue!
14 | ### Important :exclamation:
15 | Please help us maintain this project more efficiently! Before creating the issue make sure you shouldn't be creating it in one the below repos instead:
16 | - Core related: https://github.com/nextauthjs/next-auth
17 | - Docs related: https://github.com/nextauthjs/docs
18 |
19 | If you are in the correct repo, then proceed by providing the following information:
20 | - type: input
21 | id: title
22 | attributes:
23 | label: Title
24 | validations:
25 | required: true
26 | - type: textarea
27 | id: reproduction
28 | attributes:
29 | label: How to reproduce ☕️
30 | description: Please provide a link or code snippets to a minimal reproduction of the bug
31 | validations:
32 | required: true
33 | - type: markdown
34 | attributes:
35 | value: |
36 | We encourage you to use one of the templates set up on **CodeSandbox** to reproduce your issue:
37 | - [`next-auth-example`](https://codesandbox.io/s/next-auth-example-1kktb)
38 | - [`next-auth-typescript-example`](https://codesandbox.io/s/next-auth-typescript-example-se32w)
39 |
40 | 🚧 – _If you don't provide any way to reproduce the bug, the issue is at risk of being closed._
41 |
42 | - type: textarea
43 | id: description
44 | attributes:
45 | label: Your question/bug report 📓
46 | description: Please provide a more in-depth description of your request.
47 | validations:
48 | required: true
49 | - type: dropdown
50 | id: contributing
51 | attributes:
52 | label: Contributing 🙌🏽
53 | description: Are you willing to open a PR for this?
54 | multiple: false
55 | options:
56 | - "Yes, I am"
57 | - "No, I'm afraid I cannot help regarding this"
58 | validations:
59 | required: true
60 | - type: markdown
61 | attributes:
62 | value: |
63 | It takes a lot of work 🏋🏻♀️ maintaining a library like `next-auth`; any contribution is more than welcome 💚
64 |
65 |
66 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/dynamodb.yaml:
--------------------------------------------------------------------------------
1 | name: DynamoDB
2 | description: File a support request for the DynamoDB adapter
3 | labels: dynamodb
4 |
5 | # note: markdown sections will NOT appear as part of the issue as per documentation, rather they provide context to the user
6 | # https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-githubs-form-schema#markdown
7 |
8 |
9 | body:
10 | - type: markdown
11 | attributes:
12 | value: |
13 | Thanks for taking the time to fill out this issue!
14 | ### Important :exclamation:
15 | Please help us maintain this project more efficiently! Before creating the issue make sure you shouldn't be creating it in one the below repos instead:
16 | - Core related: https://github.com/nextauthjs/next-auth
17 | - Docs related: https://github.com/nextauthjs/docs
18 |
19 | If you are in the correct repo, then proceed by providing the following information:
20 | - type: input
21 | id: title
22 | attributes:
23 | label: Title
24 | validations:
25 | required: true
26 | - type: textarea
27 | id: reproduction
28 | attributes:
29 | label: How to reproduce ☕️
30 | description: Please provide a link or code snippets to a minimal reproduction of the bug
31 | validations:
32 | required: true
33 | - type: markdown
34 | attributes:
35 | value: |
36 | We encourage you to use one of the templates set up on **CodeSandbox** to reproduce your issue:
37 | - [`next-auth-example`](https://codesandbox.io/s/next-auth-example-1kktb)
38 | - [`next-auth-typescript-example`](https://codesandbox.io/s/next-auth-typescript-example-se32w)
39 |
40 | 🚧 – _If you don't provide any way to reproduce the bug, the issue is at risk of being closed._
41 |
42 | - type: textarea
43 | id: description
44 | attributes:
45 | label: Your question/bug report 📓
46 | description: Please provide a more in-depth description of your request.
47 | validations:
48 | required: true
49 | - type: dropdown
50 | id: contributing
51 | attributes:
52 | label: Contributing 🙌🏽
53 | description: Are you willing to open a PR for this?
54 | multiple: false
55 | options:
56 | - "Yes, I am"
57 | - "No, I'm afraid I cannot help regarding this"
58 | validations:
59 | required: true
60 | - type: markdown
61 | attributes:
62 | value: |
63 | It takes a lot of work 🏋🏻♀️ maintaining a library like `next-auth`; any contribution is more than welcome 💚
64 |
65 |
66 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/firebase.yaml:
--------------------------------------------------------------------------------
1 | name: Firebase
2 | description: File a support request for the Firebase adapter
3 | labels: firebase
4 |
5 | # note: markdown sections will NOT appear as part of the issue as per documentation, rather they provide context to the user
6 | # https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-githubs-form-schema#markdown
7 |
8 |
9 | body:
10 | - type: markdown
11 | attributes:
12 | value: |
13 | Thanks for taking the time to fill out this issue!
14 | ### Important :exclamation:
15 | Please help us maintain this project more efficiently! Before creating the issue make sure you shouldn't be creating it in one the below repos instead:
16 | - Core related: https://github.com/nextauthjs/next-auth
17 | - Docs related: https://github.com/nextauthjs/docs
18 |
19 | If you are in the correct repo, then proceed by providing the following information:
20 | - type: input
21 | id: title
22 | attributes:
23 | label: Title
24 | validations:
25 | required: true
26 | - type: textarea
27 | id: reproduction
28 | attributes:
29 | label: How to reproduce ☕️
30 | description: Please provide a link or code snippets to a minimal reproduction of the bug
31 | validations:
32 | required: true
33 | - type: markdown
34 | attributes:
35 | value: |
36 | We encourage you to use one of the templates set up on **CodeSandbox** to reproduce your issue:
37 | - [`next-auth-example`](https://codesandbox.io/s/next-auth-example-1kktb)
38 | - [`next-auth-typescript-example`](https://codesandbox.io/s/next-auth-typescript-example-se32w)
39 |
40 | 🚧 – _If you don't provide any way to reproduce the bug, the issue is at risk of being closed._
41 |
42 | - type: textarea
43 | id: description
44 | attributes:
45 | label: Your question/bug report 📓
46 | description: Please provide a more in-depth description of your request.
47 | validations:
48 | required: true
49 | - type: dropdown
50 | id: contributing
51 | attributes:
52 | label: Contributing 🙌🏽
53 | description: Are you willing to open a PR for this?
54 | multiple: false
55 | options:
56 | - "Yes, I am"
57 | - "No, I'm afraid I cannot help regarding this"
58 | validations:
59 | required: true
60 | - type: markdown
61 | attributes:
62 | value: |
63 | It takes a lot of work 🏋🏻♀️ maintaining a library like `next-auth`; any contribution is more than welcome 💚
64 |
65 |
66 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/typeorm-legacy.yaml:
--------------------------------------------------------------------------------
1 | name: TypeORM
2 | description: File a support request for the TypeORM adapter
3 | labels: typeorm
4 |
5 | # note: markdown sections will NOT appear as part of the issue as per documentation, rather they provide context to the user
6 | # https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-githubs-form-schema#markdown
7 |
8 |
9 | body:
10 | - type: markdown
11 | attributes:
12 | value: |
13 | Thanks for taking the time to fill out this issue!
14 | ### Important :exclamation:
15 | Please help us maintain this project more efficiently! Before creating the issue make sure you shouldn't be creating it in one the below repos instead:
16 | - Core related: https://github.com/nextauthjs/next-auth
17 | - Docs related: https://github.com/nextauthjs/docs
18 |
19 | If you are in the correct repo, then proceed by providing the following information:
20 | - type: input
21 | id: title
22 | attributes:
23 | label: Title
24 | validations:
25 | required: true
26 | - type: textarea
27 | id: reproduction
28 | attributes:
29 | label: How to reproduce ☕️
30 | description: Please provide a link or code snippets to a minimal reproduction of the bug
31 | validations:
32 | required: true
33 | - type: markdown
34 | attributes:
35 | value: |
36 | We encourage you to use one of the templates set up on **CodeSandbox** to reproduce your issue:
37 | - [`next-auth-example`](https://codesandbox.io/s/next-auth-example-1kktb)
38 | - [`next-auth-typescript-example`](https://codesandbox.io/s/next-auth-typescript-example-se32w)
39 |
40 | 🚧 – _If you don't provide any way to reproduce the bug, the issue is at risk of being closed._
41 |
42 | - type: textarea
43 | id: description
44 | attributes:
45 | label: Your question/bug report 📓
46 | description: Please provide a more in-depth description of your request.
47 | validations:
48 | required: true
49 | - type: dropdown
50 | id: contributing
51 | attributes:
52 | label: Contributing 🙌🏽
53 | description: Are you willing to open a PR for this?
54 | multiple: false
55 | options:
56 | - "Yes, I am"
57 | - "No, I'm afraid I cannot help regarding this"
58 | validations:
59 | required: true
60 | - type: markdown
61 | attributes:
62 | value: |
63 | It takes a lot of work 🏋🏻♀️ maintaining a library like `next-auth`; any contribution is more than welcome 💚
64 |
65 |
66 |
--------------------------------------------------------------------------------
/packages/dgraph/src/client.ts:
--------------------------------------------------------------------------------
1 | import * as jwt from "jsonwebtoken"
2 | import fetch from "node-fetch"
3 |
4 | import type { HeadersInit } from "node-fetch"
5 |
6 | export interface DgraphClientParams {
7 | endpoint: string
8 | /**
9 | * `X-Auth-Token` header value
10 | *
11 | * [Dgraph Cloud Authentication](https://dgraph.io/docs/cloud/cloud-api/overview/#dgraph-cloud-authentication)
12 | */
13 | authToken: string
14 | /** [Using JWT and authorization claims](https://dgraph.io/docs/graphql/authorization/authorization-overview#using-jwts-and-authorization-claims) */
15 | jwtSecret?: string
16 | /**
17 | * @default "RS256"
18 | *
19 | * [Using JWT and authorization claims](https://dgraph.io/docs/graphql/authorization/authorization-overview#using-jwts-and-authorization-claims)
20 | */
21 | jwtAlgorithm?: "HS256" | "RS256"
22 | /**
23 | * @default "Authorization"
24 | *
25 | * [Using JWT and authorization claims](https://dgraph.io/docs/graphql/authorization/authorization-overview#using-jwts-and-authorization-claims)
26 | */
27 | authHeader?: string
28 | }
29 |
30 | export class DgraphClientError extends Error {
31 | name = "DgraphClientError"
32 | constructor(errors: any[], query: string, variables: any) {
33 | super(errors.map((error) => error.message).join("\n"))
34 | console.error({ query, variables })
35 | }
36 | }
37 |
38 | export function client(params: DgraphClientParams) {
39 | if (!params.authToken) {
40 | throw new Error("Dgraph client error: Please provide an api key")
41 | }
42 | if (!params.endpoint) {
43 | throw new Error("Dgraph client error: Please provide a graphql endpoint")
44 | }
45 |
46 | const {
47 | endpoint,
48 | authToken,
49 | jwtSecret,
50 | jwtAlgorithm = "HS256",
51 | authHeader = "Authorization",
52 | } = params
53 | const headers: HeadersInit = {
54 | "Content-Type": "application/json",
55 | "X-Auth-Token": authToken,
56 | }
57 |
58 | if (authHeader && jwtSecret) {
59 | headers[authHeader] = jwt.sign({ nextAuth: true }, jwtSecret, {
60 | algorithm: jwtAlgorithm,
61 | })
62 | }
63 |
64 | return {
65 | async run(
66 | query: string,
67 | variables?: Record
68 | ): Promise {
69 | const response = await fetch(endpoint, {
70 | method: "POST",
71 | headers,
72 | body: JSON.stringify({ query, variables }),
73 | })
74 |
75 | const { data = {}, errors } = await response.json()
76 | if (errors?.length) {
77 | throw new DgraphClientError(errors, query, variables)
78 | }
79 | return Object.values(data)[0] as any
80 | },
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/packages/firebase/logo.svg:
--------------------------------------------------------------------------------
1 |
37 |
--------------------------------------------------------------------------------
/packages/fauna/logo.svg:
--------------------------------------------------------------------------------
1 |
10 |
--------------------------------------------------------------------------------
/packages/neo4j/tests/index.test.ts:
--------------------------------------------------------------------------------
1 | import * as neo4j from "neo4j-driver"
2 | import { runBasicTests } from "../../../basic-tests"
3 | import statements from "./resources/statements"
4 |
5 | import { Neo4jAdapter, format } from "../src"
6 |
7 | const driver = neo4j.driver(
8 | "bolt://localhost",
9 | neo4j.auth.basic("neo4j", "password")
10 | )
11 |
12 | const neo4jSession = driver.session()
13 |
14 | runBasicTests({
15 | adapter: Neo4jAdapter(neo4jSession),
16 | db: {
17 | async connect() {
18 | for await (const statement of statements.split(";")) {
19 | if (!statement.length) return
20 | await neo4jSession.writeTransaction((tx) => tx.run(statement))
21 | }
22 | },
23 | async disconnect() {
24 | await neo4jSession.writeTransaction((tx) =>
25 | tx.run(
26 | `MATCH (n)
27 | DETACH DELETE n
28 | RETURN count(n)`
29 | )
30 | )
31 | await neo4jSession.close()
32 | await driver.close()
33 | },
34 | async user(id) {
35 | const result = await neo4jSession.readTransaction((tx) =>
36 | tx.run(`MATCH (u:User) RETURN u`, { id })
37 | )
38 | return format.from(result?.records[0]?.get("u")?.properties)
39 | },
40 |
41 | async session(sessionToken: any) {
42 | const result = await neo4jSession.readTransaction((tx) =>
43 | tx.run(
44 | `MATCH (u:User)-[:HAS_SESSION]->(s:Session)
45 | RETURN s, u.id AS userId`,
46 | { sessionToken }
47 | )
48 | )
49 | const session = result?.records[0]?.get("s")?.properties
50 | const userId = result?.records[0]?.get("userId")
51 |
52 | if (!session || session.userId || !userId) return null
53 |
54 | return { ...format.from(session), userId }
55 | },
56 |
57 | async account(provider_providerAccountId) {
58 | const result = await neo4jSession.readTransaction((tx) =>
59 | tx.run(
60 | `MATCH (u:User)-[:HAS_ACCOUNT]->(a:Account)
61 | RETURN a, u.id AS userId`,
62 | provider_providerAccountId
63 | )
64 | )
65 |
66 | const account = result?.records[0]?.get("a")?.properties
67 | const userId = result?.records[0]?.get("userId")
68 |
69 | if (!account || account.userId || !userId) return null
70 |
71 | return { ...format.from(account), userId }
72 | },
73 |
74 | async verificationToken(identifier_token) {
75 | const result = await neo4jSession.readTransaction((tx) =>
76 | tx.run(
77 | `MATCH (v:VerificationToken)
78 | RETURN v`,
79 | identifier_token
80 | )
81 | )
82 |
83 | return format.from(result?.records[0]?.get("v")?.properties)
84 | },
85 | },
86 | })
87 |
--------------------------------------------------------------------------------
/packages/mikro-orm/tests/index.test.ts:
--------------------------------------------------------------------------------
1 | import { MikroORM, wrap } from "@mikro-orm/core"
2 | import { runBasicTests } from "../../../basic-tests"
3 | import { MikroOrmAdapter, defaultEntities } from "../src"
4 | import { User, VeryImportantEntity } from "./testEntities"
5 |
6 | let _init: MikroORM
7 |
8 | const entities = [
9 | User,
10 | defaultEntities.Account,
11 | defaultEntities.Session,
12 | defaultEntities.VerificationToken,
13 | VeryImportantEntity,
14 | ]
15 |
16 | async function getORM() {
17 | if (_init) return _init
18 |
19 | _init = await MikroORM.init({
20 | dbName: "./db.sqlite",
21 | type: "sqlite",
22 | entities,
23 | debug: process.env.DEBUG === "true" || process.env.DEBUG?.includes("db"),
24 | })
25 | return _init
26 | }
27 |
28 | runBasicTests({
29 | adapter: MikroOrmAdapter(
30 | {
31 | dbName: "./db.sqlite",
32 | type: "sqlite",
33 | entities: [
34 | defaultEntities.User,
35 | defaultEntities.Account,
36 | defaultEntities.Session,
37 | defaultEntities.VerificationToken,
38 | VeryImportantEntity,
39 | ],
40 | debug: process.env.DEBUG === "true" || process.env.DEBUG?.includes("db"),
41 | },
42 | { entities: { User } }
43 | ),
44 | db: {
45 | async connect() {
46 | const orm = await getORM()
47 | await orm.getSchemaGenerator().dropSchema()
48 | await orm.getSchemaGenerator().createSchema()
49 | },
50 | async disconnect() {
51 | const orm = await getORM()
52 | // its fine to tear down the connection if it has been already closed
53 | await orm
54 | .getSchemaGenerator()
55 | .dropSchema()
56 | .catch(() => null)
57 | await orm.close().catch(() => null)
58 | },
59 | async verificationToken(identifier_token) {
60 | const orm = await getORM()
61 | const token = await orm.em
62 | .fork()
63 | .findOne(defaultEntities.VerificationToken, identifier_token)
64 | if (!token) return null
65 | return wrap(token).toObject()
66 | },
67 | async user(id) {
68 | const orm = await getORM()
69 | const user = await orm.em.fork().findOne(defaultEntities.User, { id })
70 | if (!user) return null
71 | return wrap(user).toObject()
72 | },
73 | async account(provider_providerAccountId) {
74 | const orm = await getORM()
75 | const account = await orm.em
76 | .fork()
77 | .findOne(defaultEntities.Account, { ...provider_providerAccountId })
78 | if (!account) return null
79 | return wrap(account).toObject()
80 | },
81 | async session(sessionToken) {
82 | const orm = await getORM()
83 | const session = await orm.em
84 | .fork()
85 | .findOne(defaultEntities.Session, { sessionToken })
86 | if (!session) return null
87 | return wrap(session).toObject()
88 | },
89 | },
90 | })
91 |
--------------------------------------------------------------------------------
/packages/dynamodb/src/utils.ts:
--------------------------------------------------------------------------------
1 | // https://github.com/honeinc/is-iso-date/blob/master/index.js
2 | const isoDateRE =
3 | /(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+([+-][0-2]\d:[0-5]\d|Z))|(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d([+-][0-2]\d:[0-5]\d|Z))|(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d([+-][0-2]\d:[0-5]\d|Z))/
4 | function isDate(value: any) {
5 | return value && isoDateRE.test(value) && !isNaN(Date.parse(value))
6 | }
7 |
8 | export const format = {
9 | /** Takes a plain old JavaScript object and turns it into a Dynamodb object */
10 | to(object: Record) {
11 | const newObject: Record = {}
12 | for (const key in object) {
13 | const value = object[key]
14 | if (value instanceof Date) {
15 | // DynamoDB requires the TTL attribute be a UNIX timestamp (in secs).
16 | if (key === "expires") newObject[key] = value.getTime() / 1000
17 | else newObject[key] = value.toISOString()
18 | } else newObject[key] = value
19 | }
20 | return newObject
21 | },
22 | /** Takes a Dynamo object and returns a plain old JavaScript object */
23 | from>(
24 | object: Record | undefined,
25 | keys: string[] = ["pk", "sk", "GSI1PK", "GSI1SK"]
26 | ): T | null {
27 | if (!object) return null
28 | const newObject: Record = {}
29 | for (const key in object) {
30 | // Filter DynamoDB table and GSI keys so it doesn't get passed to core,
31 | // to avoid revealing the type of database
32 | if (keys.includes(key)) continue
33 |
34 | const value = object[key]
35 |
36 | if (isDate(value)) newObject[key] = new Date(value)
37 | // hack to keep type property in account
38 | else if (key === "type" && ["SESSION", "VT", "USER"].includes(value))
39 | continue
40 | // The expires property is stored as a UNIX timestamp in seconds, but
41 | // JavaScript needs it in milliseconds, so multiply by 1000.
42 | else if (key === "expires" && typeof value === "number")
43 | newObject[key] = new Date(value * 1000)
44 | else newObject[key] = value
45 | }
46 | return newObject as T
47 | },
48 | }
49 |
50 | export function generateUpdateExpression(object: Record): {
51 | UpdateExpression: string
52 | ExpressionAttributeNames: Record
53 | ExpressionAttributeValues: Record
54 | } {
55 | const formatedSession = format.to(object)
56 | let UpdateExpression = "set"
57 | const ExpressionAttributeNames: Record = {}
58 | const ExpressionAttributeValues: Record = {}
59 | for (const property in formatedSession) {
60 | UpdateExpression += ` #${property} = :${property},`
61 | ExpressionAttributeNames["#" + property] = property
62 | ExpressionAttributeValues[":" + property] = formatedSession[property]
63 | }
64 | UpdateExpression = UpdateExpression.slice(0, -1)
65 | return {
66 | UpdateExpression,
67 | ExpressionAttributeNames,
68 | ExpressionAttributeValues,
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/packages/dynamodb/tests/custom.test.ts:
--------------------------------------------------------------------------------
1 | import type { DynamoDBAdapterOptions } from "../src"
2 | import { DynamoDBAdapter, format } from "../src"
3 | import { runBasicTests } from "../../../basic-tests"
4 | import { DynamoDBDocument } from "@aws-sdk/lib-dynamodb"
5 | import { DynamoDB } from "@aws-sdk/client-dynamodb"
6 |
7 | const config = {
8 | endpoint: "http://127.0.0.1:8000",
9 | region: "eu-central-1",
10 | tls: false,
11 | credentials: {
12 | accessKeyId: "foo",
13 | secretAccessKey: "bar",
14 | },
15 | }
16 |
17 | export const client = DynamoDBDocument.from(new DynamoDB(config), {
18 | marshallOptions: {
19 | convertEmptyValues: true,
20 | removeUndefinedValues: true,
21 | convertClassInstanceToMap: true,
22 | },
23 | })
24 |
25 | const tableName = "next-auth-custom"
26 | const indexName = "gsi1"
27 | const partitionKey = "PK"
28 | const sortKey = "SK"
29 | const indexPartitionKey = "gsi1pk"
30 | const indexSortKey = "gsi1sk"
31 | const keys = [partitionKey, sortKey, indexPartitionKey, indexSortKey]
32 |
33 | const options: DynamoDBAdapterOptions = {
34 | tableName,
35 | partitionKey,
36 | sortKey,
37 | indexName,
38 | indexPartitionKey,
39 | indexSortKey,
40 | }
41 |
42 | const adapter = DynamoDBAdapter(client, options)
43 | const TableName = tableName
44 | const IndexName = indexName
45 |
46 | runBasicTests({
47 | adapter,
48 | db: {
49 | async user(id) {
50 | const user = await client.get({
51 | TableName,
52 | Key: {
53 | [partitionKey]: `USER#${id}`,
54 | [sortKey]: `USER#${id}`,
55 | },
56 | })
57 |
58 | return format.from(user.Item, keys)
59 | },
60 | async session(token) {
61 | const session = await client.query({
62 | TableName,
63 | IndexName,
64 | KeyConditionExpression: "#gsi1pk = :gsi1pk AND #gsi1sk = :gsi1sk",
65 | ExpressionAttributeNames: {
66 | "#gsi1pk": indexPartitionKey,
67 | "#gsi1sk": indexSortKey,
68 | },
69 | ExpressionAttributeValues: {
70 | ":gsi1pk": `SESSION#${token}`,
71 | ":gsi1sk": `SESSION#${token}`,
72 | },
73 | })
74 |
75 | return format.from(session.Items?.[0], keys)
76 | },
77 | async account({ provider, providerAccountId }) {
78 | const account = await client.query({
79 | TableName,
80 | IndexName,
81 | KeyConditionExpression: "#gsi1pk = :gsi1pk AND #gsi1sk = :gsi1sk",
82 | ExpressionAttributeNames: {
83 | "#gsi1pk": indexPartitionKey,
84 | "#gsi1sk": indexSortKey,
85 | },
86 | ExpressionAttributeValues: {
87 | ":gsi1pk": `ACCOUNT#${provider}`,
88 | ":gsi1sk": `ACCOUNT#${providerAccountId}`,
89 | },
90 | })
91 |
92 | return format.from(account.Items?.[0], keys)
93 | },
94 | async verificationToken({ token, identifier }) {
95 | const vt = await client.get({
96 | TableName,
97 | Key: {
98 | [partitionKey]: `VT#${identifier}`,
99 | [sortKey]: `VT#${token}`,
100 | },
101 | })
102 | return format.from(vt.Item, keys)
103 | },
104 | },
105 | })
106 |
--------------------------------------------------------------------------------
/packages/fauna/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Change Log
2 |
3 | All notable changes to this project will be documented in this file.
4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5 |
6 | ## [1.0.2](https://github.com/nextauthjs/adapters/compare/@next-auth/fauna-adapter@1.0.1...@next-auth/fauna-adapter@1.0.2) (2022-01-10)
7 |
8 | ### Bug Fixes
9 |
10 | - **fauna:** Convert `value` prop to `Date` only if of type `string` ([#365](https://github.com/nextauthjs/adapters/issues/365)) ([c8dad2b](https://github.com/nextauthjs/adapters/commit/c8dad2b1bf74ab1574c92ee5fda879d798a43977)), closes [#364](https://github.com/nextauthjs/adapters/issues/364)
11 |
12 | ## [1.0.1](https://github.com/nextauthjs/adapters/compare/@next-auth/fauna-adapter@1.0.0...@next-auth/fauna-adapter@1.0.1) (2021-12-06)
13 |
14 | **Note:** Version bump only for package @next-auth/fauna-adapter
15 |
16 | ## [0.2.4](https://github.com/nextauthjs/adapters/compare/@next-auth/fauna-adapter@0.2.3...@next-auth/fauna-adapter@0.2.4) (2021-10-27)
17 |
18 | ### Reverts
19 |
20 | - Revert "docs(fauna): update `README.md` (#244)" (#246) ([26cd24a](https://github.com/nextauthjs/adapters/commit/26cd24a6eba3d42ed7febd5eb45b13c236c57819)), closes [#244](https://github.com/nextauthjs/adapters/issues/244) [#246](https://github.com/nextauthjs/adapters/issues/246)
21 |
22 | ## [0.2.3](https://github.com/nextauthjs/adapters/compare/@next-auth/fauna-adapter@0.2.2...@next-auth/fauna-adapter@0.2.3) (2021-09-19)
23 |
24 | **Note:** Version bump only for package @next-auth/fauna-adapter
25 |
26 | ## [0.2.2](https://github.com/nextauthjs/adapters/compare/@next-auth/fauna-adapter@0.2.1...@next-auth/fauna-adapter@0.2.2) (2021-07-02)
27 |
28 | **Note:** Version bump only for package @next-auth/fauna-adapter
29 |
30 | ## [0.2.1](https://github.com/nextauthjs/adapters/compare/@next-auth/fauna-adapter@0.2.0...@next-auth/fauna-adapter@0.2.1) (2021-06-30)
31 |
32 | ### Bug Fixes
33 |
34 | - **fauna:** change the name of the index to `verification_request_by_token_and_identifier` ([#157](https://github.com/nextauthjs/adapters/issues/157)) ([01a3c52](https://github.com/nextauthjs/adapters/commit/01a3c5205f30eec57c7b9298b762cccf1f2400fd))
35 |
36 | # [0.2.0](https://github.com/nextauthjs/adapters/compare/@next-auth/fauna-adapter@0.1.0...@next-auth/fauna-adapter@0.2.0) (2021-06-30)
37 |
38 | ### Bug Fixes
39 |
40 | - adapter export function name ([eb6a21a](https://github.com/nextauthjs/adapters/commit/eb6a21a0302ef42a32314e48a75542bade26605e))
41 | - include /dist files in published build ([751ea95](https://github.com/nextauthjs/adapters/commit/751ea95a3b40dc3a94bf4de6253974e1664a2661))
42 | - merge conflicts ([aa48f2f](https://github.com/nextauthjs/adapters/commit/aa48f2f7586345764d0a586df23534f9abc2b53d))
43 | - rm type=module from package.json ([c207348](https://github.com/nextauthjs/adapters/commit/c207348d126a766abe341e6afe36b04d47c6bac6))
44 | - specify module in package.json ([d6e85ce](https://github.com/nextauthjs/adapters/commit/d6e85ce68b0a7d70f6b6078ac8d66e36c4724131))
45 | - test match new export ([ee96664](https://github.com/nextauthjs/adapters/commit/ee966647dadbc649d6a93f5ae4d5fb5deb6f6772))
46 |
47 | ### Features
48 |
49 | - add build step to package.json ([28a4f40](https://github.com/nextauthjs/adapters/commit/28a4f403b07fc115c171623d6801c9392f50bd28))
50 |
--------------------------------------------------------------------------------
/packages/upstash-redis/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
Upstash Redis Adapter - NextAuth.js
5 |
6 | Open Source. Full Stack. Own Your Data.
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | ## Overview
16 |
17 | This is the Upstash Redis adapter for [`next-auth`](https://next-auth.js.org). This package can only be used in conjunction with the primary `next-auth` and `@upstash/redis` packages. It is not a standalone package.
18 |
19 | ## Getting Started
20 |
21 | 1. Install `next-auth` and `@next-auth/upstash-redis-adapter` as well as `@upstash/redis` via NPM.
22 |
23 | ```js
24 | npm install next-auth @next-auth/upstash-redis-adapter @upstash/redis
25 | ```
26 |
27 | 2. Add the follwing code to your `pages/api/[...nextauth].js` next-auth configuration object.
28 |
29 | ```js
30 | import NextAuth from "next-auth"
31 | import { UpstashRedisAdapter } from "@next-auth/upstash-adapter"
32 | import upstashRedisClient from "@upstash/redis"
33 |
34 | const redis = upstashRedisClient("UPSTASH_REDIS_REST_URL", "UPSTASH_REDIS_REST_TOKEN")
35 |
36 | // For more information on each option (and a full list of options) go to
37 | // https://next-auth.js.org/configuration/options
38 | export default NextAuth({
39 | ...
40 | adapter: UpstashRedisAdapter(redis)
41 | ...
42 | })
43 | ```
44 |
45 | ## Using Multiple Apps with a Single Upstash Redis Instance
46 |
47 | The Upstash free-tier allows for only one Redis instance. If you have multiple Next-Auth connected apps using this instance, you need different key prefixes for every app.
48 |
49 | You can change the prefixes by passing an `options` object as the second argument to the adapter factory function.
50 |
51 | The default values for this object are:
52 |
53 | ```js
54 | const defaultOptions = {
55 | baseKeyPrefix: "",
56 | accountKeyPrefix: "user:account:",
57 | accountByUserIdPrefix: "user:account:by-user-id:",
58 | emailKeyPrefix: "user:email:",
59 | sessionKeyPrefix: "user:session:",
60 | sessionByUserIdKeyPrefix: "user:session:by-user-id:",
61 | userKeyPrefix: "user:",
62 | verificationTokenKeyPrefix: "user:token:",
63 | }
64 | ```
65 |
66 | Usually changing the `baseKeyPrefix` should be enough for this scenario, but for more custom setups, you can also change the prefixes of every single key.
67 |
68 | Example:
69 |
70 | ```js
71 | export default NextAuth({
72 | ...
73 | adapter: UpstashRedisAdapter(redis, {baseKeyPrefix: "app2:"})
74 | ...
75 | })
76 | ```
77 |
78 | ## Contributing
79 |
80 | We're open to all community contributions! If you'd like to contribute in any way, please read our [Contributing Guide](https://github.com/nextauthjs/adapters/blob/main/CONTRIBUTING.md).
81 |
82 | ## License
83 |
84 | ISC
85 |
--------------------------------------------------------------------------------
/packages/typeorm-legacy/src/entities.ts:
--------------------------------------------------------------------------------
1 | import type { ValueTransformer } from "typeorm"
2 | import {
3 | Entity,
4 | PrimaryGeneratedColumn,
5 | Column,
6 | ManyToOne,
7 | OneToMany,
8 | } from "typeorm"
9 |
10 | const transformer: Record<"date" | "bigint", ValueTransformer> = {
11 | date: {
12 | from: (date: string | null) => date && new Date(parseInt(date, 10)),
13 | to: (date?: Date) => date?.valueOf().toString(),
14 | },
15 | bigint: {
16 | from: (bigInt: string | null) => bigInt && parseInt(bigInt, 10),
17 | to: (bigInt?: number) => bigInt?.toString(),
18 | },
19 | }
20 |
21 | @Entity({ name: "users" })
22 | export class UserEntity {
23 | @PrimaryGeneratedColumn("uuid")
24 | id!: string
25 |
26 | @Column({ type: "varchar", nullable: true })
27 | name!: string | null
28 |
29 | @Column({ type: "varchar", nullable: true, unique: true })
30 | email!: string | null
31 |
32 | @Column({ type: "varchar", nullable: true, transformer: transformer.date })
33 | emailVerified!: string | null
34 |
35 | @Column({ type: "varchar", nullable: true })
36 | image!: string | null
37 |
38 | @OneToMany(() => SessionEntity, (session) => session.userId)
39 | sessions!: SessionEntity[]
40 |
41 | @OneToMany(() => AccountEntity, (account) => account.userId)
42 | accounts!: AccountEntity[]
43 | }
44 |
45 | @Entity({ name: "accounts" })
46 | export class AccountEntity {
47 | @PrimaryGeneratedColumn("uuid")
48 | id!: string
49 |
50 | @Column({ type: "uuid" })
51 | userId!: string
52 |
53 | @Column()
54 | type!: string
55 |
56 | @Column()
57 | provider!: string
58 |
59 | @Column()
60 | providerAccountId!: string
61 |
62 | @Column({ type: "varchar", nullable: true })
63 | refresh_token!: string
64 |
65 | @Column({ type: "varchar", nullable: true })
66 | access_token!: string | null
67 |
68 | @Column({
69 | nullable: true,
70 | type: "bigint",
71 | transformer: transformer.bigint,
72 | })
73 | expires_at!: number | null
74 |
75 | @Column({ type: "varchar", nullable: true })
76 | token_type!: string | null
77 |
78 | @Column({ type: "varchar", nullable: true })
79 | scope!: string | null
80 |
81 | @Column({ type: "varchar", nullable: true })
82 | id_token!: string | null
83 |
84 | @Column({ type: "varchar", nullable: true })
85 | session_state!: string | null
86 |
87 | @ManyToOne(() => UserEntity, (user) => user.accounts, {
88 | createForeignKeyConstraints: true,
89 | })
90 | user!: UserEntity
91 | }
92 |
93 | @Entity({ name: "sessions" })
94 | export class SessionEntity {
95 | @PrimaryGeneratedColumn("uuid")
96 | id!: string
97 |
98 | @Column({ unique: true })
99 | sessionToken!: string
100 |
101 | @Column({ type: "uuid" })
102 | userId!: string
103 |
104 | @Column({ transformer: transformer.date })
105 | expires!: string
106 |
107 | @ManyToOne(() => UserEntity, (user) => user.sessions)
108 | user!: UserEntity
109 | }
110 |
111 | @Entity({ name: "verification_tokens" })
112 | export class VerificationTokenEntity {
113 | @PrimaryGeneratedColumn("uuid")
114 | id!: string
115 |
116 | @Column()
117 | token!: string
118 |
119 | @Column()
120 | identifier!: string
121 |
122 | @Column({ transformer: transformer.date })
123 | expires!: string
124 | }
125 |
--------------------------------------------------------------------------------
/packages/mongodb/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
MongoDB Adapter - NextAuth.js
5 |
6 | Open Source. Full Stack. Own Your Data.
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | ## Overview
16 |
17 | This is the MongoDB Adapter for [`next-auth`](https://next-auth.js.org). This package can only be used in conjunction with the primary `next-auth` package. It is not a standalone package.
18 |
19 | ## Getting Started
20 |
21 | 1. Install `mongodb`, `next-auth` and `@next-auth/mongodb-adapter`
22 |
23 | ```js
24 | npm install mongodb next-auth @next-auth/mongodb-adapter@next
25 | ```
26 |
27 | 2. Add `lib/mongodb.js`
28 |
29 | ```js
30 | // This approach is taken from https://github.com/vercel/next.js/tree/canary/examples/with-mongodb
31 | import { MongoClient } from "mongodb"
32 |
33 | const uri = process.env.MONGODB_URI
34 | const options = {
35 | useUnifiedTopology: true,
36 | useNewUrlParser: true,
37 | }
38 |
39 | let client
40 | let clientPromise
41 |
42 | if (!process.env.MONGODB_URI) {
43 | throw new Error("Please add your Mongo URI to .env.local")
44 | }
45 |
46 | if (process.env.NODE_ENV === "development") {
47 | // In development mode, use a global variable so that the value
48 | // is preserved across module reloads caused by HMR (Hot Module Replacement).
49 | if (!global._mongoClientPromise) {
50 | client = new MongoClient(uri, options)
51 | global._mongoClientPromise = client.connect()
52 | }
53 | clientPromise = global._mongoClientPromise
54 | } else {
55 | // In production mode, it's best to not use a global variable.
56 | client = new MongoClient(uri, options)
57 | clientPromise = client.connect()
58 | }
59 |
60 | // Export a module-scoped MongoClient promise. By doing this in a
61 | // separate module, the client can be shared across functions.
62 | export default clientPromise
63 | ```
64 |
65 | 3. Add this adapter to your `pages/api/[...nextauth].js` next-auth configuration object.
66 |
67 | ```js
68 | import NextAuth from "next-auth"
69 | import { MongoDBAdapter } from "@next-auth/mongodb-adapter"
70 | import clientPromise from "lib/mongodb"
71 |
72 | // For more information on each option (and a full list of options) go to
73 | // https://next-auth.js.org/configuration/options
74 | export default NextAuth({
75 | adapter: MongoDBAdapter(clientPromise),
76 | ...
77 | })
78 | ```
79 |
80 | ## Contributing
81 |
82 | We're open to all community contributions! If you'd like to contribute in any way, please read our [Contributing Guide](https://github.com/nextauthjs/adapters/blob/main/CONTRIBUTING.md).
83 |
84 | ## License
85 |
86 | ISC
87 |
--------------------------------------------------------------------------------
/packages/dgraph/tests/private.key:
--------------------------------------------------------------------------------
1 | -----BEGIN RSA PRIVATE KEY-----
2 | MIIJKQIBAAKCAgEAxqyvd82VacXMBLUADZt+euSNUNJ276XgvH4HW4ms5iQZDgYI
3 | PKxyaZ+wk8EMYSB1dymJ3WQpm0JKHqgTW+z/edfYFQXkduHN/zoIpxMAMyZGsTBi
4 | dGo0xJSHTCDCdYCCBlG9R1ljjhf0l9ChBP7W7lSXaRU/XS/tMH1qYMpsUwDav4G/
5 | RDI3A4t29JRGqU4mnFa5o3XBCxU4ANCp1JaQevzAYox8EGPZ1YZGmhRgca51dBee
6 | d9QKqWjfXP4wboC1ppglm+kPgFUaCiXB8KyfIixhlvzZiO4RLvZw+cILt586vXGz
7 | Ny49eVUTiIOoTZuG/79pCeBS8BCbB4l6y274y42hUN83gHxQ32Y++DI40jz5iGN8
8 | 5Dj6yDDjKwvwqVhCx/kVJFrmyrTJz/E0cp38FeIi7D6e0eXj7G97K+wkNdc4oTs1
9 | DsDPzhO/7wxQOZIjvNp+DJAfxin5MbM+UKoopvJj3sUMHVrTteWxZg94mmLjg2Kn
10 | JYBuSn8kiFPYQ0F5MjE7df4tDDTGJ/VEFIG5EkQffaNYhW0Z5ORLvW1R1Yd1/ew3
11 | UWo+mZ7XAUGLF6clsWSQvzSrrNMYzCk5Fa0LwvMtQdEVLL3q7/KsEHD7N78EVlmE
12 | DlOtC21UidUqXnawCE1QIjAHqFsNNPR2j0lgOoEjrGdzrvUg6hNV9m6CbSECAwEA
13 | AQKCAgAjr8kk/+yiv0DSZ6DG0PN7J6qqpeNvUKB5uzmfG6/O9xT5C+RW4bL7fg+9
14 | uqN6ntX6vZ9iASfoF5QwxYgUrxGE1VyfChvrrsvN2KLNQAB9L5brJQHKX3lzBir3
15 | ZbsIWDkC4ZPaSRg04eCxlGwX9Z6t2MwJuCNVndJBL4X4NOQYVML2O1wb59kx7c9E
16 | R44Zw0v0MS/PSMuQLhONMe4Pnav+K4BzM0DlwMnULPZpntdkFC5M2CFC7PetToUw
17 | swgIEV6PuiynQMnkB2VSBU486QT8onQ1Jt38VqcHhITumAh6x0NJ3C6Q7uFj9gA4
18 | OU32AsXREpTPjVfYf2MZi3xfJmPR+1JTqmnhWY7g/v3K5MpFO9HGmcETNpV4YXRv
19 | U18Bx+m5FsKp0tFASyS/6PJoDAJ/a6yQxVNc1nYL8AKTFqod/0pQz2w2yFGR2t1g
20 | Ui+7HQrWRpdvp2vDJK2GJLs+thybtd73QwsKJ2LFHS91eQ1y1BsSI4z1Ph8/66xK
21 | uQVWfeQqQIhbM8m/pzOYNw90jRx9raKZ6QpdmLqoKj4WF3a/KvLc0TO678wzVoSM
22 | qBDH9FwmkebNHWEMR8rR5Fb1ZVHclSde6DqdPBTvcQzMk66ZGMHB746G68620iKs
23 | YJ6dFDBt3XBnhhOjPhCCH4XR8ZIGTgwxC9hry17/sUMEU5iS8QKCAQEA7WnbfI+h
24 | oLnfw0M6uxIrvl1MMip1Zq/f2/q3HIpE6qLuPoy4fzjONNYm8QBwdJSVPviMCsFx
25 | rU2IIHLeQGUSvMIIcWzn+EWKl3XTzirdn9uYZPPqGr/YuoLW/uN2TCppBbzT1jtA
26 | bbQYUfvyF+ysU+F9amLSdDsqM3MwaFMNChcf3XLMz7QFgoWIDSejq4Uhy6y22KEi
27 | qg+VprX9OejzUQLb0I8ko9S3dKAHkhUZJ8kxowu5oqaaGpowBhko84zKpNrGbinG
28 | bA0+LTxAUKaHhioWWgXya976DQRBdTkp7wOWuD/jnL3wnIHDYF0TKYuidu98d+zH
29 | b/+EH/wPEK4DrwKCAQEA1jpwJm2CDkw41TNexLectOlAjVw9xMt+10hLZ2PYOuwd
30 | kThLYU9zqYIp9thj9/Ddqkx286qHaX92W2q0SZmhuXeNLmcG71QGJp/6uC+up0Hk
31 | 7aFPoQ3uS7JQN5YwinUy/0vbTsxmko0Ie9y2gA0bWDV4Yu5zr/vYd/bLD55GPRD/
32 | WWGWkDlzlQqedQkjaCSRskm6nyFdTSsruw6RMdNiZK6jBR2aY0SsFmJmOwrTrPCS
33 | llg+zaUtqwgC4tLROx8R5rkJh8S+/KjRN46oXPphQLTJlNZu1uTjV5Ue/BqpHgor
34 | hJLgZwfA7YXJFfiSfjYFYTj9vm9Wx50zJSKiEZxALwKCAQEA6Czcy8y/GKqN7Kwj
35 | lGypwMoGyQyCsYCPoNZoGo4R5ZCfAyalCy2nYz6G6KswTqI77lAszBvvqramyGzt
36 | cvYlQ9lRXnNNy5tedM5y6y06fanIN/ndWHmDXqqzzKLvvn6/JDBMzjY1xNMZ8Zs9
37 | Xy5CPOnIt7Ca9bYiiBw/G9cUamjA7dTl/L2locYqjgrU4dkZetCWI/Y5KyyAgn95
38 | fBeXVANCqoxCHcHaA0C5BqCBcEous6+0xB6/mAJvspcKWFu4lU2qPnO2K1csFhrV
39 | HsoswQUJxNIKCHoP+YjO5u+XVbohvGAmnNOXqcaxJdz/72Ix6LQ9+h3h0GKGeK0M
40 | opg62wKCAQEAnyRoXdOp8s8ixRbVRtOTwT0prBmi9UeqoWjeQx8D6bmvuUqVjOOF
41 | 6517aRmVIgI32SPWlerPj0qV9RFOfwJ3Bp1OLvNwTmgf7Z+YlC0v1KZ51yGnUuBT
42 | br43IyQaSTEJQmfqsh3b8PB+Je1vUa7q6ltGZE/5dvli9LNMY/zS9thiqNZ7EAbt
43 | 2wE5d33jZKEN7uEglsglVIdGhD4tFFOQ23R0O/+iyi2gnTxZ73B6kRVh//fsJ76W
44 | L2DTLAcqUX4iQUCiWM6Kho0uZtQ+NFv31Sa4PS4SxubgEBcCHov7qAosC99EfqVe
45 | 59Qj7oNq6AFfe7rnnQl+8OjRrruMpAJsFwKCAQBxq1apDQTav7QW9Sfe19POZas0
46 | b0XIETL3mEh25uCqPTmoaKo45opgw0Cn7zpuy/NntKlG/cnPYneQh91bViqid/Iv
47 | 3M88vQJmS2e4abozqa7iNjd/XwmBcCgdR2yx51oJ9q9dfd2ejKfMDzm0uHs5U7ay
48 | pOlUch5OT0s5utZC4FbeziZ8Th61DtmIHOxQpNYpPXogdkbGSaOhL6dezPOAwJnJ
49 | B2zjH7N1c+dz+5HheVbN3M08aN9DdyD1xsmd8eZVTAi1wcp51GY6cb7G0gE2SzOp
50 | UNtVbc17n82jJ5Qr4ggSRU1QWNBZT9KX4U2/nTe3U5C3+ni4p+opI9Q3vSYw
51 | -----END RSA PRIVATE KEY-----
--------------------------------------------------------------------------------
/packages/mikro-orm/src/entities.ts:
--------------------------------------------------------------------------------
1 | import { v4 as randomUUID } from "uuid"
2 |
3 | import {
4 | Property,
5 | Unique,
6 | PrimaryKey,
7 | Entity,
8 | Enum,
9 | OneToMany,
10 | Collection,
11 | ManyToOne,
12 | } from "@mikro-orm/core"
13 | import type { DefaultAccount } from "next-auth"
14 | import type {
15 | AdapterSession,
16 | AdapterUser,
17 | VerificationToken as AdapterVerificationToken,
18 | } from "next-auth/adapters"
19 | import type { ProviderType } from "next-auth/providers"
20 |
21 | type RemoveIndex = {
22 | // eslint-disable-next-line @typescript-eslint/ban-types
23 | [K in keyof T as {} extends Record ? never : K]: T[K]
24 | }
25 |
26 | @Entity()
27 | export class User implements RemoveIndex {
28 | @PrimaryKey()
29 | id: string = randomUUID()
30 |
31 | @Property({ nullable: true })
32 | name?: string
33 |
34 | @Property({ nullable: true })
35 | @Unique()
36 | email?: string
37 |
38 | @Property({ type: "Date", nullable: true })
39 | emailVerified: Date | null = null
40 |
41 | @Property({ nullable: true })
42 | image?: string
43 |
44 | @OneToMany({
45 | entity: () => Session,
46 | mappedBy: (session) => session.user,
47 | hidden: true,
48 | orphanRemoval: true,
49 | })
50 | sessions = new Collection(this)
51 |
52 | @OneToMany({
53 | entity: () => Account,
54 | mappedBy: (account) => account.user,
55 | hidden: true,
56 | orphanRemoval: true,
57 | })
58 | accounts = new Collection(this)
59 | }
60 |
61 | @Entity()
62 | export class Session implements AdapterSession {
63 | @PrimaryKey()
64 | id: string = randomUUID()
65 |
66 | @ManyToOne({
67 | entity: () => User,
68 | hidden: true,
69 | onDelete: "cascade",
70 | })
71 | user!: User
72 |
73 | @Property({ persist: false })
74 | userId!: string
75 |
76 | @Property()
77 | expires!: Date
78 |
79 | @Property()
80 | @Unique()
81 | sessionToken!: string
82 | }
83 |
84 | @Entity()
85 | @Unique({ properties: ["provider", "providerAccountId"] })
86 | export class Account implements RemoveIndex {
87 | @PrimaryKey()
88 | id: string = randomUUID()
89 |
90 | @ManyToOne({
91 | entity: () => User,
92 | hidden: true,
93 | onDelete: "cascade",
94 | })
95 | user!: User
96 |
97 | @Property({ persist: false })
98 | userId!: string
99 |
100 | @Enum()
101 | type!: ProviderType
102 |
103 | @Property()
104 | provider!: string
105 |
106 | @Property()
107 | providerAccountId!: string
108 |
109 | @Property({ nullable: true })
110 | refresh_token?: string
111 |
112 | @Property({ nullable: true })
113 | access_token?: string
114 |
115 | @Property({ nullable: true })
116 | expires_at?: number
117 |
118 | @Property({ nullable: true })
119 | token_type?: string
120 |
121 | @Property({ nullable: true })
122 | scope?: string
123 |
124 | @Property({ nullable: true })
125 | id_token?: string
126 |
127 | @Property({ nullable: true })
128 | session_state?: string
129 | }
130 |
131 | @Entity()
132 | @Unique({ properties: ["token", "identifier"] })
133 | export class VerificationToken implements AdapterVerificationToken {
134 | @PrimaryKey()
135 | @Property()
136 | token!: string
137 |
138 | @Property()
139 | expires!: Date
140 |
141 | @Property()
142 | identifier!: string
143 | }
144 |
--------------------------------------------------------------------------------
/packages/typeorm-legacy/tests/custom-entities.ts:
--------------------------------------------------------------------------------
1 | import type { ValueTransformer } from "typeorm"
2 | import {
3 | Entity,
4 | PrimaryGeneratedColumn,
5 | Column,
6 | ManyToOne,
7 | OneToMany,
8 | } from "typeorm"
9 |
10 | const transformer: Record<"date" | "bigint", ValueTransformer> = {
11 | date: {
12 | from: (date: string | null) => date && new Date(parseInt(date, 10)),
13 | to: (date?: Date) => date?.valueOf().toString(),
14 | },
15 | bigint: {
16 | from: (bigInt: string | null) => bigInt && parseInt(bigInt, 10),
17 | to: (bigInt?: number) => bigInt?.toString(),
18 | },
19 | }
20 |
21 | @Entity({ name: "users" })
22 | export class UserEntity {
23 | @PrimaryGeneratedColumn("uuid")
24 | id!: string
25 |
26 | @Column({ type: "varchar", nullable: true })
27 | name!: string | null
28 |
29 | @Column({ type: "varchar", nullable: true, unique: true })
30 | email!: string | null
31 |
32 | @Column({ type: "varchar", nullable: true, transformer: transformer.date })
33 | emailVerified!: string | null
34 |
35 | @Column({ type: "varchar", nullable: true })
36 | role!: string | null
37 |
38 | @Column({ type: "varchar", nullable: true })
39 | phone!: string | null
40 |
41 | @Column({ type: "varchar", nullable: true })
42 | image!: string | null
43 |
44 | @OneToMany(() => SessionEntity, (session) => session.userId)
45 | sessions!: SessionEntity[]
46 |
47 | @OneToMany(() => AccountEntity, (account) => account.userId)
48 | accounts!: AccountEntity[]
49 | }
50 |
51 | @Entity({ name: "accounts" })
52 | export class AccountEntity {
53 | @PrimaryGeneratedColumn("uuid")
54 | id!: string
55 |
56 | @Column({ type: "uuid" })
57 | userId!: string
58 |
59 | @Column()
60 | type!: string
61 |
62 | @Column()
63 | provider!: string
64 |
65 | @Column()
66 | providerAccountId!: string
67 |
68 | @Column({ type: "varchar", nullable: true })
69 | refresh_token!: string
70 |
71 | @Column({ type: "varchar", nullable: true })
72 | access_token!: string | null
73 |
74 | @Column({
75 | nullable: true,
76 | type: "bigint",
77 | transformer: transformer.bigint,
78 | })
79 | expires_at!: number | null
80 |
81 | @Column({ type: "varchar", nullable: true })
82 | token_type!: string | null
83 |
84 | @Column({ type: "varchar", nullable: true })
85 | scope!: string | null
86 |
87 | @Column({ type: "varchar", nullable: true })
88 | id_token!: string | null
89 |
90 | @Column({ type: "varchar", nullable: true })
91 | session_state!: string | null
92 |
93 | @ManyToOne(() => UserEntity, (user) => user.accounts, {
94 | createForeignKeyConstraints: true,
95 | })
96 | user!: UserEntity
97 | }
98 |
99 | @Entity({ name: "sessions" })
100 | export class SessionEntity {
101 | @PrimaryGeneratedColumn("uuid")
102 | id!: string
103 |
104 | @Column({ unique: true })
105 | sessionToken!: string
106 |
107 | @Column({ type: "uuid" })
108 | userId!: string
109 |
110 | @Column({ transformer: transformer.date })
111 | expires!: string
112 |
113 | @ManyToOne(() => UserEntity, (user) => user.sessions)
114 | user!: UserEntity
115 | }
116 |
117 | @Entity({ name: "verification_tokens" })
118 | export class VerificationTokenEntity {
119 | @PrimaryGeneratedColumn("uuid")
120 | id!: string
121 |
122 | @Column()
123 | token!: string
124 |
125 | @Column()
126 | identifier!: string
127 |
128 | @Column({ transformer: transformer.date })
129 | expires!: string
130 | }
131 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as
6 | contributors and maintainers pledge to making participation in our project and
7 | our community a harassment-free experience for everyone, regardless of age, body
8 | size, disability, ethnicity, sex characteristics, gender identity and expression,
9 | level of experience, education, socio-economic status, nationality, personal
10 | appearance, race, religion, or sexual identity and orientation.
11 |
12 | ## Our Standards
13 |
14 | Examples of behavior that contributes to creating a positive environment
15 | include:
16 |
17 | - Using welcoming and inclusive language
18 | - Being respectful of differing viewpoints and experiences
19 | - Gracefully accepting constructive criticism
20 | - Focusing on what is best for the community
21 | - Showing empathy towards other community members
22 |
23 | Examples of unacceptable behavior by participants include:
24 |
25 | - The use of sexualized language or imagery and unwelcome sexual attention or
26 | advances
27 | - Trolling, insulting/derogatory comments, and personal or political attacks
28 | - Public or private harassment
29 | - Publishing others' private information, such as a physical or electronic
30 | address, without explicit permission
31 | - Other conduct which could reasonably be considered inappropriate in a
32 | professional setting
33 |
34 | ## Our Responsibilities
35 |
36 | Project maintainers are responsible for clarifying the standards of acceptable
37 | behavior and are expected to take appropriate and fair corrective action in
38 | response to any instances of unacceptable behavior.
39 |
40 | Project maintainers have the right and responsibility to remove, edit, or
41 | reject comments, commits, code, wiki edits, issues, and other contributions
42 | that are not aligned to this Code of Conduct, or to ban temporarily or
43 | permanently any contributor for other behaviors that they deem inappropriate,
44 | threatening, offensive, or harmful.
45 |
46 | ## Scope
47 |
48 | This Code of Conduct applies both within project spaces and in public spaces
49 | when an individual is representing the project or its community. Examples of
50 | representing a project or community include using an official project e-mail
51 | address, posting via an official social media account, or acting as an appointed
52 | representative at an online or offline event. Representation of a project may be
53 | further defined and clarified by project maintainers.
54 |
55 | ## Enforcement
56 |
57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
58 | reported by contacting me@iaincollins.com. All complaints will be reviewed and
59 | investigated and will result in a response that is deemed necessary and
60 | appropriate to the circumstances. The project team is obligated to maintain
61 | confidentiality with regard to the reporter of an incident. Further details of
62 | specific enforcement policies may be posted separately.
63 |
64 | Project maintainers who do not follow or enforce the Code of Conduct in good
65 | faith may face temporary or permanent repercussions as determined by other
66 | members of the project's leadership.
67 |
68 | ## Attribution
69 |
70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
72 |
73 | [homepage]: https://www.contributor-covenant.org
74 |
75 | For answers to common questions about this code of conduct, see
76 | https://www.contributor-covenant.org/faq
77 |
--------------------------------------------------------------------------------
/packages/dynamodb/tests/format.test.ts:
--------------------------------------------------------------------------------
1 | import { format } from "../src/utils"
2 |
3 | describe("dynamodb utils.format", () => {
4 | it("format.to() preserves non-Date non-expires properties", () => {
5 | expect(
6 | format.to({
7 | pk: "test-pk",
8 | email: "test@example.com",
9 | })
10 | ).toEqual({
11 | pk: "test-pk",
12 | email: "test@example.com",
13 | })
14 | })
15 |
16 | it("format.to() converts non-expires Date properties to ISO strings", () => {
17 | const date = new Date()
18 | expect(
19 | format.to({
20 | dateProp: date,
21 | })
22 | ).toEqual({
23 | dateProp: date.toISOString(),
24 | })
25 | })
26 |
27 | it("format.to() converts expires property to a UNIX timestamp", () => {
28 | // DynamoDB requires that the property used for TTL is a UNIX timestamp.
29 | const date = new Date()
30 | const timestamp = date.getTime() / 1000
31 | expect(
32 | format.to({
33 | expires: date,
34 | })
35 | ).toEqual({
36 | expires: timestamp,
37 | })
38 | })
39 |
40 | it("format.from() preserves non-special attributes", () => {
41 | expect(
42 | format.from({
43 | testAttr1: "test-value",
44 | testAttr2: 5,
45 | })
46 | ).toEqual({
47 | testAttr1: "test-value",
48 | testAttr2: 5,
49 | })
50 | })
51 |
52 | it("format.from() removes dynamodb key attributes", () => {
53 | expect(
54 | format.from({
55 | pk: "test-pk",
56 | sk: "test-sk",
57 | GSI1PK: "test-GSI1PK",
58 | GSI1SK: "test-GSI1SK",
59 | })
60 | ).toEqual({})
61 | })
62 |
63 | it("format.from() only removes type attribute from Session, VT, and User", () => {
64 | expect(format.from({ type: "SESSION" })).toEqual({})
65 | expect(format.from({ type: "VT" })).toEqual({})
66 | expect(format.from({ type: "USER" })).toEqual({})
67 | expect(format.from({ type: "ANYTHING" })).toEqual({ type: "ANYTHING" })
68 | expect(format.from({ type: "ELSE" })).toEqual({ type: "ELSE" })
69 | })
70 |
71 | it("format.from() converts ISO strings to Date instances", () => {
72 | const date = new Date()
73 | expect(
74 | format.from({
75 | someDate: date.toISOString(),
76 | })
77 | ).toEqual({
78 | someDate: date,
79 | })
80 | })
81 |
82 | it("format.from() converts expires attribute from timestamp to Date instance", () => {
83 | // AdapterSession["expires"] and VerificationToken["expires"] are both meant
84 | // to be Date instances.
85 | const date = new Date()
86 | const timestamp = date.getTime() / 1000
87 | expect(
88 | format.from({
89 | expires: timestamp,
90 | })
91 | ).toEqual({
92 | expires: date,
93 | })
94 | })
95 |
96 | it("format.from() converts expires attribute from ISO string to Date instance", () => {
97 | // Due to a bug in an old version, some expires attributes were stored as
98 | // ISO strings, so we need to handle those properly too.
99 | const date = new Date()
100 | expect(
101 | format.from({
102 | expires: date.toISOString(),
103 | })
104 | ).toEqual({
105 | expires: date,
106 | })
107 | })
108 |
109 | it("format.from(format.to()) preserves expires attribute", () => {
110 | const date = new Date()
111 | expect(
112 | format.from(
113 | format.to({
114 | expires: date,
115 | })
116 | )
117 | ).toEqual({
118 | expires: date,
119 | })
120 | })
121 | })
122 |
--------------------------------------------------------------------------------
/packages/pouchdb/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
PouchDB Adapter - NextAuth.js
5 |
6 | Open Source. Full Stack. Own Your Data.
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | ## Overview
16 |
17 | This is the PouchDB Adapter for [`next-auth`](https://next-auth.js.org). This package can only be used in conjunction with the primary `next-auth` package. It is not a standalone package.
18 |
19 | Depending on your architecture you can use PouchDB's http adapter to reach any database compliant with the CouchDB protocol (CouchDB, Cloudant, ...) or use any other PouchDB compatible adapter (leveldb, in-memory, ...)
20 |
21 | ## Getting Started
22 |
23 | 1. Install `next-auth` and `@next-auth/pouchdb-adapter`, as well as `pouchdb`.
24 |
25 | > **Prerequesite**: Your PouchDB instance MUST provide the `pouchdb-find` plugin since it is used internally by the adapter to build and manage indexes
26 |
27 | ```js
28 | npm install next-auth @next-auth/pouchdb-adapter pouchdb
29 | ```
30 |
31 | 2. Add this adapter to your `pages/api/[...nextauth].js` next-auth configuration object.
32 |
33 | ```js
34 | import NextAuth from "next-auth"
35 | import Providers from "next-auth/providers"
36 | import { PouchDBAdapter } from "@next-auth/pouchdb-adapter"
37 | import PouchDB from "pouchdb"
38 |
39 | // Setup your PouchDB instance and database
40 | PouchDB.plugin(require("pouchdb-adapter-leveldb")) // Or any other PouchDB-compliant adapter
41 | .plugin(require("pouchdb-find")) // Don't forget the `pouchdb-find` plugin
42 |
43 | const pouchdb = new PouchDB("auth_db", { adapter: "leveldb" })
44 |
45 | // For more information on each option (and a full list of options) go to
46 | // https://next-auth.js.org/configuration/options
47 | export default NextAuth({
48 | // https://next-auth.js.org/configuration/providers
49 | providers: [
50 | Providers.Google({
51 | clientId: process.env.GOOGLE_ID,
52 | clientSecret: process.env.GOOGLE_SECRET,
53 | }),
54 | ],
55 | adapter: PouchDBAdapter(pouchdb),
56 | // ...
57 | })
58 | ```
59 |
60 | ## Advanced
61 |
62 | ### Memory-First Caching Strategy
63 |
64 | If you need to boost your authentication layer performance, you may use PouchDB's powerful sync features and various adapters, to build a memory-first caching strategy.
65 |
66 | Use an in-memory PouchDB as your main authentication database, and synchronize it with any other persisted PouchDB. You may do a one way, one-off replication at startup from the persisted PouchDB into the in-memory PouchDB, then two-way, continuous, retriable sync.
67 |
68 | This will probably not improve performance much in a serverless environment for various reasons such as concurrency, function startup time increases, etc.
69 |
70 | For more details, please see https://pouchdb.com/api.html#sync
71 |
72 | ## Contributing
73 |
74 | We're open to all community contributions! If you'd like to contribute in any way, please read our [Contributing Guide](https://github.com/nextauthjs/adapters/blob/main/CONTRIBUTING.md).
75 |
76 | ## License
77 |
78 | ISC
79 |
--------------------------------------------------------------------------------
/packages/typeorm-legacy/src/utils.ts:
--------------------------------------------------------------------------------
1 | import type { Connection, ConnectionOptions } from "typeorm"
2 | import * as defaultEntities from "./entities"
3 |
4 | /** Ensure configOrString is normalized to an object. */
5 | export function parseConnectionConfig(
6 | configOrString: string | ConnectionOptions
7 | ): ConnectionOptions {
8 | if (typeof configOrString !== "string") {
9 | return {
10 | ...configOrString,
11 | entities: Object.values(configOrString.entities ?? defaultEntities),
12 | }
13 | }
14 |
15 | // If the input is URL string, automatically convert the string to an object
16 | // to make configuration easier (in most use cases).
17 | //
18 | // TypeORM accepts connection string as a 'url' option, but unfortunately
19 | // not for all databases (e.g. SQLite) or for all options, so we handle
20 | // parsing it in this function.
21 | try {
22 | const parsedUrl = new URL(configOrString)
23 | const config: any = {
24 | entities: Object.values(defaultEntities),
25 | }
26 |
27 | if (parsedUrl.protocol.startsWith("mongodb+srv")) {
28 | // Special case handling is required for mongodb+srv with TypeORM
29 | config.type = "mongodb"
30 | config.url = configOrString.replace(/\?(.*)$/, "")
31 | config.useNewUrlParser = true
32 | } else {
33 | config.type = parsedUrl.protocol.replace(/:$/, "")
34 | config.host = parsedUrl.hostname
35 | config.port = Number(parsedUrl.port)
36 | config.username = parsedUrl.username
37 | config.password = parsedUrl.password
38 | config.database = parsedUrl.pathname
39 | .replace(/^\//, "")
40 | .replace(/\?(.*)$/, "")
41 | config.options = {}
42 | }
43 |
44 | // This option is recommended by mongodb
45 | if (config.type === "mongodb") {
46 | config.useUnifiedTopology = true
47 | }
48 |
49 | // Prevents warning about deprecated option (sets default value)
50 | if (config.type === "mssql") {
51 | config.options.enableArithAbort = true
52 | }
53 |
54 | if (parsedUrl.search) {
55 | parsedUrl.search
56 | .replace(/^\?/, "")
57 | .split("&")
58 | .forEach((keyValuePair) => {
59 | let [key, value] = keyValuePair.split("=") as any
60 | // Converts true/false strings to actual boolean values
61 | if (value === "true") {
62 | value = true
63 | }
64 | if (value === "false") {
65 | value = false
66 | }
67 | config[key] = value
68 | })
69 | }
70 |
71 | return config
72 | } catch (error) {
73 | // If URL parsing fails for any reason, try letting TypeORM handle it
74 | return { url: configOrString } as any
75 | }
76 | }
77 |
78 | function entitiesChanged(
79 | prevEntities: any[] | undefined,
80 | newEntities: any[]
81 | ): boolean {
82 | if (prevEntities?.length !== newEntities?.length) return true
83 |
84 | for (let i = 0; i < prevEntities?.length; i++) {
85 | if (prevEntities[i] !== newEntities[i]) return true
86 | }
87 |
88 | return false
89 | }
90 |
91 | export async function updateConnectionEntities(
92 | connection: Connection,
93 | entities: any[]
94 | ) {
95 | if (!entitiesChanged(connection.options.entities, entities)) return
96 |
97 | // @ts-expect-error
98 | connection.options.entities = entities
99 |
100 | // @ts-expect-error
101 | connection.buildMetadatas()
102 |
103 | if (connection.options.synchronize !== false) {
104 | console.warn(
105 | "[next-auth][warn][adapter_typeorm_updating_entities]",
106 | "\nhttps://next-auth.js.org/warnings#adapter_typeorm_updating_entities"
107 | )
108 | await connection.synchronize()
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/packages/dgraph/tests/index.test.ts:
--------------------------------------------------------------------------------
1 | import { DgraphAdapter, format } from "../src"
2 | import { client as dgraphClient } from "../src/client"
3 | import * as fragments from "../src/graphql/fragments"
4 | import { runBasicTests } from "../../../basic-tests"
5 | import fs from "fs"
6 | import path from "path"
7 |
8 | import type { DgraphClientParams } from "../src"
9 |
10 | const params: DgraphClientParams = {
11 | endpoint: "http://localhost:8080/graphql",
12 | authToken: "test",
13 | jwtAlgorithm: "RS256",
14 | jwtSecret: fs.readFileSync(path.join(process.cwd(), "/tests/private.key"), {
15 | encoding: "utf8",
16 | }),
17 | }
18 |
19 | /** TODO: Add test to `dgraphClient` */
20 | const c = dgraphClient(params)
21 |
22 | runBasicTests({
23 | adapter: DgraphAdapter(params),
24 | db: {
25 | id: () => "0x0a0a00a00",
26 | async disconnect() {
27 | await c.run(/* GraphQL */ `
28 | mutation {
29 | deleteUser(filter: {}) {
30 | numUids
31 | }
32 | deleteVerificationToken(filter: {}) {
33 | numUids
34 | }
35 | deleteSession(filter: {}) {
36 | numUids
37 | }
38 | deleteAccount(filter: {}) {
39 | numUids
40 | }
41 | }
42 | `)
43 | },
44 | async user(id) {
45 | const result = await c.run(
46 | /* GraphQL */ `
47 | query ($id: ID!) {
48 | getUser(id: $id) {
49 | ...UserFragment
50 | }
51 | }
52 | ${fragments.User}
53 | `,
54 | { id }
55 | )
56 |
57 | return format.from(result)
58 | },
59 | async session(sessionToken) {
60 | const result = await c.run(
61 | /* GraphQL */ `
62 | query ($sessionToken: String!) {
63 | querySession(filter: { sessionToken: { eq: $sessionToken } }) {
64 | ...SessionFragment
65 | user {
66 | id
67 | }
68 | }
69 | }
70 | ${fragments.Session}
71 | `,
72 | { sessionToken }
73 | )
74 |
75 | const { user, ...session } = result?.[0] ?? {}
76 | if (!user?.id) return null
77 | return format.from({ ...session, userId: user.id })
78 | },
79 | async account(provider_providerAccountId) {
80 | const result = await c.run(
81 | /* GraphQL */ `
82 | query ($providerAccountId: String = "", $provider: String = "") {
83 | queryAccount(
84 | filter: {
85 | providerAccountId: { eq: $providerAccountId }
86 | provider: { eq: $provider }
87 | }
88 | ) {
89 | ...AccountFragment
90 | user {
91 | id
92 | }
93 | }
94 | }
95 | ${fragments.Account}
96 | `,
97 | provider_providerAccountId
98 | )
99 |
100 | const account = format.from(result?.[0])
101 | if (!account?.user) return null
102 |
103 | account.userId = account.user.id
104 | delete account.user
105 | return account
106 | },
107 | async verificationToken(identifier_token) {
108 | const result = await c.run(
109 | /* GraphQL */ `
110 | query ($identifier: String = "", $token: String = "") {
111 | queryVerificationToken(
112 | filter: { identifier: { eq: $identifier }, token: { eq: $token } }
113 | ) {
114 | ...VerificationTokenFragment
115 | }
116 | }
117 | ${fragments.VerificationToken}
118 | `,
119 | identifier_token
120 | )
121 |
122 | return format.from(result?.[0])
123 | },
124 | },
125 | })
126 |
--------------------------------------------------------------------------------
/packages/sequelize/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
Sequelize Adapter - NextAuth.js
5 |
6 | Open Source. Full Stack. Own Your Data.
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | ## Overview
16 |
17 | This is the Sequelize Adapter for [`next-auth`](https://next-auth.js.org). This package can only be used in conjunction with the primary `next-auth` package. It is not a standalone package.
18 |
19 | You can find the Sequelize schema in the docs at [next-auth.js.org/adapters/sequelize](https://next-auth.js.org/adapters/sequelize).
20 |
21 | ## Getting Started
22 |
23 | 1. Install `next-auth` and `@next-auth/sequelize-adapter` as well as `sequelize` and your [database driver](https://sequelize.org/master/manual/getting-started.html) of choice.
24 |
25 | ```js
26 | npm install next-auth @next-auth/sequelize-adapter sequelize sqlite3
27 | npm install --save-dev sequelize
28 | ```
29 |
30 | 2. Add this adapter to your `pages/api/[...nextauth].js` next-auth configuration object.
31 |
32 | ```js
33 | import NextAuth from "next-auth"
34 | import SequelizeAdapter from "@next-auth/sequelize-adapter"
35 | import Sequelize from 'sequelize'
36 |
37 | const sequelize = new Sequelize("sqlite::memory:")
38 |
39 | // For more information on each option (and a full list of options) go to
40 | // https://next-auth.js.org/configuration/options
41 | export default NextAuth({
42 | ...
43 | adapter: SequelizeAdapter(sequelize)
44 | ...
45 | })
46 | ```
47 |
48 | ## Updating the database schema
49 |
50 | In development, the sequelize adapter will create the necessary tables, foreign keys and indexes in your database. In production, synchronization is disabled. Best practice is to create the [required tables](https://next-auth.js.org/adapters/models) in your database via [migrations](https://sequelize.org/master/manual/migrations.html).
51 |
52 | In development, if you do not want the adapter to automatically create tables, you are able to pass `{ synchronize: false }` as the second option to `SequelizeAdapter` to disable this behavior:
53 |
54 | ```js
55 | import NextAuth from "next-auth"
56 | import SequelizeAdapter from "@next-auth/sequelize-adapter"
57 | import Sequelize from 'sequelize'
58 |
59 | const sequelize = new Sequelize("sqlite::memory:")
60 |
61 | export default NextAuth({
62 | ...
63 | adapter: SequelizeAdapter(sequelize, { synchronize: false })
64 | ...
65 | })
66 | ```
67 |
68 | ## Using custom models
69 |
70 | Sequelize models are option to customization like so:
71 |
72 | ```js
73 | import NextAuth from "next-auth"
74 | import SequelizeAdapter, { models } from "@next-auth/sequelize-adapter"
75 | import Sequelize, { DataTypes } from 'sequelize'
76 |
77 | const sequelize = new Sequelize("sqlite::memory:")
78 |
79 | export default NextAuth({
80 | ...
81 | adapter: SequelizeAdapter(sequelize, {
82 | models: {
83 | User: sequelize.define('user', { ...models.User, phoneNumber: DataTypes.STRING })
84 | }
85 | })
86 | ...
87 | })
88 | ```
89 |
90 | ## Contributing
91 |
92 | We're open to all community contributions! If you'd like to contribute in any way, please read our [Contributing Guide](https://github.com/nextauthjs/adapters/blob/main/CONTRIBUTING.md).
93 |
94 | ## License
95 |
96 | ISC
97 |
--------------------------------------------------------------------------------
/packages/firebase/README.md:
--------------------------------------------------------------------------------
1 |
14 |
15 |
16 | ## Overview
17 |
18 | This is the Firebase Adapter for [`next-auth`](https://next-auth.js.org). This package can only be used in conjunction with the primary `next-auth` package. It is not a standalone package.
19 |
20 | You can find more Firebase information in the docs at [next-auth.js.org/adapters/firebase](https://next-auth.js.org/adapters/firebase).
21 |
22 | ## Getting Started
23 |
24 | 1. Install `next-auth` and `@next-auth/firebase-adapter`.
25 |
26 | ```js
27 | npm install next-auth @next-auth/firebase-adapter
28 | ```
29 |
30 | 2. Add this adapter to your `pages/api/[...nextauth].js` next-auth configuration object.
31 |
32 | ```js
33 | import NextAuth from "next-auth"
34 | import Providers from "next-auth/providers"
35 | import { FirebaseAdapter } from "@next-auth/firebase-adapter"
36 |
37 | import firebase from "firebase/app"
38 | import "firebase/firestore"
39 |
40 | const firestore = (
41 | firebase.apps[0] ?? firebase.initializeApp(/* your config */)
42 | ).firestore()
43 |
44 | // For more information on each option (and a full list of options) go to
45 | // https://next-auth.js.org/configuration/options
46 | export default NextAuth({
47 | // https://next-auth.js.org/configuration/providers
48 | providers: [
49 | Providers.Google({
50 | clientId: process.env.GOOGLE_ID,
51 | clientSecret: process.env.GOOGLE_SECRET,
52 | }),
53 | ],
54 | adapter: FirebaseAdapter(firestore),
55 | ...
56 | })
57 | ```
58 |
59 | ## Options
60 |
61 | When initializing the firestore adapter, you must pass in the firebase config object with the details from your project. More details on how to obtain that config object can be found [here](https://support.google.com/firebase/answer/7015592).
62 |
63 | An example firebase config looks like this:
64 |
65 | ```js
66 | const firebaseConfig = {
67 | apiKey: "AIzaSyDOCAbC123dEf456GhI789jKl01-MnO",
68 | authDomain: "myapp-project-123.firebaseapp.com",
69 | databaseURL: "https://myapp-project-123.firebaseio.com",
70 | projectId: "myapp-project-123",
71 | storageBucket: "myapp-project-123.appspot.com",
72 | messagingSenderId: "65211879809",
73 | appId: "1:65211879909:web:3ae38ef1cdcb2e01fe5f0c",
74 | measurementId: "G-8GSGZQ44ST",
75 | }
76 | ```
77 |
78 | See [firebase.google.com/docs/web/setup](https://firebase.google.com/docs/web/setup) for more details.
79 |
80 | > **From Firebase - Caution**: We do not recommend manually modifying an app's Firebase config file or object. If you initialize an app with invalid or missing values for any of these required "Firebase options", then your end users may experience serious issues.
81 | >
82 | > For open source projects, we generally do not recommend including the app's Firebase config file or object in source control because, in most cases, your users should create their own Firebase projects and point their apps to their own Firebase resources (via their own Firebase config file or object).
83 |
84 | ## Contributing
85 |
86 | We're open to all community contributions! If you'd like to contribute in any way, please read our [Contributing Guide](https://github.com/nextauthjs/adapters/blob/main/CONTRIBUTING.md).
87 |
88 | ## License
89 |
90 | ISC
91 |
--------------------------------------------------------------------------------