Compare commits

..

3 Commits

Author SHA1 Message Date
Balázs Orbán
b1774ca9bd fix firebase indent 2023-03-21 22:08:39 +01:00
Balázs Orbán
57356021fb tweak 2023-03-21 21:55:42 +01:00
Balázs Orbán
006ee59a2a docs: remove members titles 2023-03-21 21:11:01 +01:00
52 changed files with 1149 additions and 1588 deletions

70
.eslintignore Normal file
View File

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

75
.eslintrc.js Normal file
View 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,
}

1
.gitignore vendored
View File

@@ -63,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

22
.prettierrc.js Normal file
View 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",
},
},
],
}

View File

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

View File

@@ -34,7 +34,6 @@ 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"
@@ -121,7 +120,6 @@ export const authConfig: AuthConfig = {
Twitch({ clientId: process.env.TWITCH_ID, clientSecret: process.env.TWITCH_SECRET }),
Twitter({ clientId: process.env.TWITTER_ID, clientSecret: process.env.TWITTER_SECRET }),
// TwitterLegacy({ clientId: process.env.TWITTER_LEGACY_ID, clientSecret: process.env.TWITTER_LEGACY_SECRET }),
Yandex({ clientId: process.env.YANDEX_ID, clientSecret: process.env.YANDEX_SECRET }),
Vk({ clientId: process.env.VK_ID, clientSecret: process.env.VK_SECRET }),
Wikimedia({ clientId: process.env.WIKIMEDIA_ID, clientSecret: process.env.WIKIMEDIA_SECRET }),
WorkOS({ clientId: process.env.WORKOS_ID, clientSecret: process.env.WORKOS_SECRET }),

View File

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

View File

@@ -174,7 +174,7 @@ If you are deploying directly to a particular cloud platform you may also want t
## Security
Parts of this section has been moved to its [own page](/security).
Parts of this section has been moved to its [own page](/getting-started/security).
<details>
<summary>

View File

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

View File

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

View File

@@ -128,7 +128,7 @@ import { useSession, signIn, signOut } from "next-auth/react"
export default function CamperVanPage() {
const { data: session, status } = useSession()
const userEmail = session?.user?.email
const userEmail = session?.user.email
if (status === "loading") {
return <p>Hang on there...</p>

View File

@@ -2,16 +2,6 @@
title: Security
---
## Supported Versions
Security updates are only released for the current version.
Old releases are not maintained and do not receive updates.
:::caution
`@auth/*` packages are currently under development and - unless stated otherwise - they are not considered ready for production yet. That said, we encourage you to reach out to us if you have any questions or concerns via the below-mentioned channels. We are committed to making Auth.js a secure and reliable solution for your authentication needs.
:::
## Reporting a Vulnerability
Auth.js practices responsible disclosure.
@@ -23,11 +13,16 @@ If you contact us regarding a serious issue:
- We will endeavor to get back to you within 72 hours.
- We will aim to publish a fix within 30 days.
- We will disclose the issue (and credit you, with your consent) once a fix to resolve the issue has been released.
- If 90 days have elapsed and we still don't have a fix, we will disclose the issue publicly.
- If 90 days has elapsed and we still don't have a fix, we will disclose the issue publicly.
The best way to report an issue is by contacting us via email at info@balazsorban.com, hi@thvu.dev and yo@ndo.dev, or raise a public issue requesting someone get in touch with you via whatever means you prefer for more details. (Please do not disclose sensitive details publicly at this stage.)
The best way to report an issue is by contacting us via email at info@balazsorban.com or me@iaincollins.com and yo@ndo.dev, or raise a public issue requesting someone get in touch with you via whatever means you prefer for more details. (Please do not disclose sensitive details publicly at this stage.)
:::note
For less serious issues (e.g. RFC compliance for unsupported flows or potential issues that may cause a problem in the future) it is appropriate to make these public as bug reports or feature requests or to raise a question to open a discussion around them.
:::
## Supported Versions
Security updates are only released for the current version.
Old releases are not maintained and do not receive updates.

View File

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

View File

@@ -10,4 +10,4 @@ When using a database, you can still use JWT for session handling for fast acces
We have a list of official adapters that are distributed as their own packages under the `@next-auth/{name}-adapter` namespace. Their source code is available in their various adapters package directories at [`nextauthjs/next-auth`](https://github.com/nextauthjs/next-auth/tree/main/packages):
- [All available adapters](/reference/adapters)
- [All available adapters](/reference/adapters/overview)

View File

@@ -1,5 +1,5 @@
{
"label": "Basics",
"collapsible": true,
"collapsed": false
"collapsed": true
}

View File

@@ -1,12 +1,9 @@
---
title: Overview
sidebar_label: Guides
sidebar_position: 0
---
This section contains guides for common use cases.
We're creating internal guides to help understand how to use Auth.js and all the possible configurations and uses cases it supports.
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.
:::
If you can't find what you're looking for, [raise an issue](https://github.com/nextauthjs/next-auth/issues/new/choose) then take a look at our third-party [community resources](/guides/resources).

View File

@@ -0,0 +1,5 @@
{
"label": "Other",
"collapsible": true,
"collapsed": true
}

View File

@@ -0,0 +1,79 @@
---
title: LDAP Authentication
---
Auth.js provides the ability to setup a [custom Credential provider](/guides/providers/credentials) which we can take advantage of to authenticate users against an existing LDAP server.
You will need an additional dependency, `ldapjs`, which you can install by running
```bash npm2yarn2pnpm
npm install ldapjs
```
Then you must setup the `CredentialsProvider()` provider key like so:
```js title="[...nextauth].js"
const ldap = require("ldapjs")
import NextAuth from "next-auth"
import CredentialsProvider from "next-auth/providers/credentials"
export default NextAuth({
providers: [
CredentialsProvider({
name: "LDAP",
credentials: {
username: { label: "DN", type: "text", placeholder: "" },
password: { label: "Password", type: "password" },
},
async authorize(credentials, req) {
// You might want to pull this call out so we're not making a new LDAP client on every login attempt
const client = ldap.createClient({
url: process.env.LDAP_URI,
})
// Essentially promisify the LDAPJS client.bind function
return new Promise((resolve, reject) => {
client.bind(credentials.username, credentials.password, (error) => {
if (error) {
console.error("Failed")
reject()
} else {
console.log("Logged in")
resolve({
username: credentials.username,
password: credentials.password,
})
}
})
})
},
}),
],
callbacks: {
async jwt({ token, user }) {
const isSignIn = user ? true : false
if (isSignIn) {
token.username = user.username
token.password = user.password
}
return token
},
async session({ session, token }) {
return { ...session, user: { username: token.username } }
},
},
})
```
The idea is that once one is authenticated with the LDAP server, one can pass through both the username/DN and password to the JWT stored in the browser.
This is then passed back to any API routes and retrieved as such:
```js title="/pages/api/doLDAPWork.js"
token = await jwt.getToken({
req,
})
const { username, password } = token
```
> Thanks to [Winwardo](https://github.com/Winwardo) for the code example

View File

@@ -0,0 +1,60 @@
---
title: Usage with class components
---
If you want to use the [`useSession()`](/reference/react/#usesession) hook in your class components you can do so with the help of a higher order component or with a render prop.
## Higher Order Component
```js
import { useSession } from "next-auth/react"
const withSession = (Component) => (props) => {
const session = useSession()
// if the component has a render property, we are good
if (Component.prototype.render) {
return <Component session={session} {...props} />
}
// if the passed component is a function component, there is no need for this wrapper
throw new Error(
[
"You passed a function component, `withSession` is not needed.",
"You can `useSession` directly in your component.",
].join("\n")
)
}
// Usage
class ClassComponent extends React.Component {
render() {
const { data: session, status } = this.props.session
return null
}
}
const ClassComponentWithSession = withSession(ClassComponent)
```
## Render Prop
```js
import { useSession } from "next-auth/react"
const UseSession = ({ children }) => {
const session = useSession()
return children(session)
}
// Usage
class ClassComponent extends React.Component {
render() {
return (
<UseSession>
{(session) => <pre>{JSON.stringify(session, null, 2)}</pre>}
</UseSession>
)
}
}
```

View File

@@ -3,21 +3,21 @@ id: credentials
title: Credentials Provider
---
The Credentials provider allows you to handle signing in with arbitrary credentials, such as a username and password, domain, or two-factor authentication or hardware device (e.g. YubiKey U2F / FIDO).
The Credentials provider allows you to handle signing in with arbitrary credentials, such as a username and password, domain, or two factor authentication or hardware device (e.g. YubiKey U2F / FIDO).
It is intended to support use cases where you have an existing system you need to authenticate users against.
It comes with the constraint that users authenticated in this manner are not persisted in the database, and consequently that the Credentials provider can only be used if JSON Web Tokens are enabled for sessions.
:::warning
The functionality provided for credentials-based authentication is intentionally limited to discourage the use of passwords due to the inherent security risks associated with them and the additional complexity associated with supporting usernames and passwords.
The functionality provided for credentials based authentication is intentionally limited to discourage use of passwords due to the inherent security risks associated with them and the additional complexity associated with supporting usernames and passwords.
:::
## Options
The **Credentials Provider** comes with a set of default options:
- [Credentials Provider options](/reference/core/providers_credentials)
- [Credentials Provider options](/reference/providers/credentials)
You can override any of the options to suit your own use case.
@@ -33,7 +33,7 @@ If you return an object it will be persisted to the JSON Web Token and the user
3. If you throw an Error, the user will be sent to the error page with the error message as a query parameter.
The Credentials provider's `authorize()` method also provides the request object as the second parameter (see the example below).
The Credentials provider's `authorize()` method also provides the request object as the second parameter (see example below).
```js title="pages/api/auth/[...nextauth].js"
import CredentialsProvider from "next-auth/providers/credentials";
@@ -89,7 +89,7 @@ You can specify more than one credentials provider by specifying a unique `id` f
You can also use them in conjunction with other provider options.
As with all providers, the order you specify is the order they are displayed on the sign-in page.
As with all providers, the order you specify them is the order they are displayed on the sign in page.
```js
providers: [

View File

@@ -1,5 +1,5 @@
---
title: OAuth Provider
title: Customized 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)

View File

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

View File

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

View File

@@ -1,32 +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.
:::warning Warning
The API reference is 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.
:::
## Roadmap
Here are the _currently_ planned and released packages under the `@auth/*` scope. This is not an exhaustive list, but the set of packages that we would like to focus on to begin with.
| Feature | Status |
| ------------------- | -------- |
| `@auth/nextjs` | Planned |
| `@auth/*-adapter` | Planned |
| `@auth/core` | Experimental |
| `@auth/sveltekit` | Experimental |
| `@auth/solid-start` | Experimental |
### 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.
:::note
If you are a maintainer of a package, [reach out](https://twitter.com/balazsorban44) if you want to collaborate on making it official or open a PR to add it to the list below, so others can discover it more easily.
:::
- ...
- ...

View File

@@ -93,9 +93,11 @@ const docusaurusConfig = {
position: "left",
},
{
to: "/reference",
to: "/reference/core",
// TODO: change to this when the overview page looks better.
// to: "/reference",
activeBasePath: "/reference",
label: "API Reference",
label: "Reference",
position: "left",
},
{
@@ -104,12 +106,6 @@ const docusaurusConfig = {
label: "Concepts",
position: "left",
},
{
to: "/security",
activeBasePath: "/security",
label: "Security",
position: "left",
},
{
type: "docsVersionDropdown",
position: "right",
@@ -136,7 +132,7 @@ const docusaurusConfig = {
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. 🏗",
"<a target='_blank' rel='noopener noreferrer' href='https://next-auth.js.org'>NextAuth.js</a> is becoming Auth.js! 🎉 We're creating Authentication for the Web. Everyone included. Starting with SvelteKit, check out <a href='/reference/sveltekit'>the docs</a>. Note, this site is under active development.",
backgroundColor: "#000",
textColor: "#fff",
},
@@ -262,7 +258,6 @@ const docusaurusConfig = {
},
],
typedocAdapter("Dgraph"),
typedocAdapter("Drizzle ORM"),
typedocAdapter("DynamoDB"),
typedocAdapter("Fauna"),
typedocAdapter("Firebase"),

View File

@@ -14,7 +14,6 @@ module.exports = {
},
],
referenceSidebar: [
"reference/index",
{
type: "category",
label: "@auth/core",
@@ -53,7 +52,6 @@ module.exports = {
items: [
{ type: "doc", id: "reference/adapter/dgraph/index" },
{ type: "doc", id: "reference/adapter/dynamodb/index" },
{ type: "doc", id: "reference/adapter/drizzle/index" },
{ type: "doc", id: "reference/adapter/fauna/index" },
{ type: "doc", id: "reference/adapter/firebase/index" },
{ type: "doc", id: "reference/adapter/mikro-orm/index" },

View File

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

View File

@@ -104,7 +104,7 @@ html[data-theme="dark"] hr {
/* Docusaurus announcementBar close button */
.close {
color: inherit!important;
color: inherit;
}
.home-main .code {

View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

View File

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

Before

Width:  |  Height:  |  Size: 736 B

View File

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

Before

Width:  |  Height:  |  Size: 3.6 KiB

View File

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

View File

@@ -1,28 +0,0 @@
<p align="center">
<br/>
<a href="https://authjs.dev" target="_blank">
<img height="64px" src="https://authjs.dev/img/logo/logo-sm.png" />
</a>
<a href="https://github.com/drizzle-team/drizzle-orm" target="_blank">
<img height="64px" src="https://authjs.dev/img/adapters/drizzle-orm.png"/>
</a>
<h3 align="center"><b>Drizzle ORM Adapter</b> - NextAuth.js / Auth.js</a></h3>
<p align="center" style="align: center;">
<a href="https://npm.im/@auth/drizzle-adapter">
<img src="https://img.shields.io/badge/TypeScript-blue?style=flat-square" alt="TypeScript" />
</a>
<a href="https://npm.im/@auth/drizzle-adapter">
<img alt="npm" src="https://img.shields.io/npm/v/@auth/drizzle-adapter?color=green&label=@auth/drizzle-adapter&style=flat-square">
</a>
<a href="https://www.npmtrends.com/@auth/drizzle-adapter">
<img src="https://img.shields.io/npm/dm/@auth/drizzle-adapter?label=%20downloads&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>
</p>
</p>
---
Check out the documentation at [authjs.dev](https://authjs.dev/reference/adapter/drizzle).

View File

@@ -1,57 +0,0 @@
{
"name": "@auth/drizzle-adapter",
"version": "0.0.1",
"description": "Drizzle ORM adapter for Auth.js",
"homepage": "https://authjs.dev/reference/adapter/drizzle",
"repository": "https://github.com/nextauthjs/next-auth",
"bugs": {
"url": "https://github.com/nextauthjs/next-auth/issues"
},
"author": "Anthony Shew",
"license": "ISC",
"type": "module",
"exports": {
".": {
"types": "./index.d.ts",
"import": "./index.js"
}
},
"keywords": [
"auth.js",
"next-auth",
"next.js",
"oauth",
"drizzle"
],
"private": false,
"publishConfig": {
"access": "public"
},
"scripts": {
"clean": "rm -rf *.js *.d.ts* ./drizzle db.sqlite",
"test:init": "pnpm clean && drizzle-kit generate:sqlite --schema=src/schema.ts --breakpoints",
"test": "pnpm test:init && jest",
"build": "pnpm clean && drizzle-kit generate:sqlite --schema=src/schema.ts && tsc",
"dev": "drizzle-kit generate:sqlite --schema=src/schema.ts && tsc -w"
},
"files": [
"src",
"*.js",
"*.d.ts*"
],
"peerDependencies": {
"drizzle-orm": "^0.23.5"
},
"devDependencies": {
"@next-auth/adapter-test": "workspace:*",
"@types/better-sqlite3": "^7.6.3",
"better-sqlite3": "^8.2.0",
"drizzle-kit": "^0.17.3",
"drizzle-orm": "^0.23.5",
"jest": "^27.4.3",
"next-auth": "workspace:*"
},
"jest": {
"preset": "@next-auth/adapter-test/jest"
}
}

View File

@@ -1,248 +0,0 @@
/**
* <div style={{display: "flex", justifyContent: "space-between", alignItems: "center", padding: 16}}>
* <p style={{fontWeight: "normal"}}>Official <a href="https://github.com/drizzle-team/drizzle-orm">Drizzle ORM</a> adapter for Auth.js / NextAuth.js.</p>
* <a href="https://github.com/drizzle-team/drizzle-orm">
* <img style={{display: "block"}} src="https://authjs.dev/img/adapters/drizzle-orm.png" width="38" />
* </a>
* </div>
*
* ## Installation
*
* ```bash npm2yarn2pnpm
* npm install next-auth drizzle-orm @auth/drizzle-adapter
* npm install drizzle-kit --save-dev
* ```
*
* @module @auth/drizzle-adapter
*/
import {
accounts,
users,
sessions,
verificationTokens,
type DrizzleClient,
} from "./schema"
import { and, eq } from "drizzle-orm/expressions"
import type { Adapter } from "next-auth/adapters"
/**
* ## Setup
*
* Add this adapter to your `pages/api/[...nextauth].js` next-auth configuration object:
*
* ```js title="pages/api/auth/[...nextauth].js"
* import NextAuth from "next-auth"
* import GoogleProvider from "next-auth/providers/google"
* import { DrizzleAdapter } from "@auth/drizzle-adapter"
* import { db } from "./db-schema"
*
* export default NextAuth({
* adapter: DrizzleAdapter(db),
* providers: [
* GoogleProvider({
* clientId: process.env.GOOGLE_CLIENT_ID,
* clientSecret: process.env.GOOGLE_CLIENT_SECRET,
* }),
* ],
* })
* ```
*
* ## Advanced usage
*
* ### Create the Drizzle schema from scratch
*
* You'll need to create a database schema that includes the minimal schema for a `next-auth` adapter.
* Be sure to use the Drizzle driver version that you're using for your project.
*
* > This schema is adapted for use in Drizzle and based upon our main [schema](https://authjs.dev/reference/adapters#models)
*
*
* ```json title="db-schema.ts"
*
* import { integer, pgTable, text, primaryKey } from 'drizzle-orm/pg-core';
* import { drizzle } from 'drizzle-orm/node-postgres';
* import { migrate } from 'drizzle-orm/node-postgres/migrator';
* import { Pool } from 'pg'
* import { ProviderType } from 'next-auth/providers';
*
* export const users = pgTable('users', {
* id: text('id').notNull().primaryKey(),
* name: text('name'),
* email: text("email").notNull(),
* emailVerified: integer("emailVerified"),
* image: text("image"),
* });
*
* export const accounts = pgTable("accounts", {
* userId: text("userId").notNull().references(() => users.id, { onDelete: "cascade" }),
* type: text("type").$type<ProviderType>().notNull(),
* provider: text("provider").notNull(),
* providerAccountId: text("providerAccountId").notNull(),
* refresh_token: text("refresh_token"),
* access_token: text("access_token"),
* expires_at: integer("expires_at"),
* token_type: text("token_type"),
* scope: text("scope"),
* id_token: text("id_token"),
* session_state: text("session_state"),
* }, (account) => ({
* _: primaryKey(account.provider, account.providerAccountId)
* }))
*
* export const sessions = pgTable("sessions", {
* userId: text("userId").notNull().references(() => users.id, { onDelete: "cascade" }),
* sessionToken: text("sessionToken").notNull().primaryKey(),
* expires: integer("expires").notNull(),
* })
*
* export const verificationTokens = pgTable("verificationToken", {
* identifier: text("identifier").notNull(),
* token: text("token").notNull(),
* expires: integer("expires").notNull()
* }, (vt) => ({
* _: primaryKey(vt.identifier, vt.token)
* }))
*
* const pool = new Pool({
* connectionString: "YOUR_CONNECTION_STRING"
* });
*
* export const db = drizzle(pool);
*
* migrate(db, { migrationsFolder: "./drizzle" })
*
* ```
*
**/
export function DrizzleAdapter(client: DrizzleClient): Adapter {
return {
createUser(data) {
return client
.insert(users)
.values({ ...data, id: "123" })
.returning()
.get()
},
getUser(data) {
return client.select().from(users).where(eq(users.id, data)).get() ?? null
},
getUserByEmail(data) {
return (
client.select().from(users).where(eq(users.email, data)).get() ?? null
)
},
createSession(data) {
return client.insert(sessions).values(data).returning().get()
},
getSessionAndUser(data) {
return (
client
.select({
session: sessions,
user: users,
})
.from(sessions)
.where(eq(sessions.sessionToken, data))
.innerJoin(users, eq(users.id, sessions.userId))
.get() ?? null
)
},
updateUser(data) {
if (!data.id) throw new Error("No user id.")
return client
.update(users)
.set(data)
.where(eq(users.id, data.id))
.returning()
.get()
},
updateSession(data) {
return client
.update(sessions)
.set(data)
.where(eq(sessions.sessionToken, data.sessionToken))
.returning()
.get()
},
linkAccount(rawAccount) {
const updatedAccount = client
.insert(accounts)
.values(rawAccount)
.returning()
.get()
// HACK: Should not need to set `undefined` values here
return {
...updatedAccount,
access_token: updatedAccount.access_token ?? undefined,
token_type: updatedAccount.token_type ?? undefined,
id_token: updatedAccount.id_token ?? undefined,
refresh_token: updatedAccount.refresh_token ?? undefined,
scope: updatedAccount.scope ?? undefined,
expires_at: updatedAccount.expires_at ?? undefined,
session_state: updatedAccount.session_state ?? undefined,
}
},
getUserByAccount(account) {
return (
client
.select()
.from(users)
.innerJoin(
accounts,
and(
eq(accounts.providerAccountId, account.providerAccountId),
eq(accounts.provider, account.provider)
)
)
.get()?.users ?? null
)
},
deleteSession(sessionToken) {
return client
.delete(sessions)
.where(eq(sessions.sessionToken, sessionToken))
.returning()
.get()
},
createVerificationToken(token) {
return client.insert(verificationTokens).values(token).returning().get()
},
useVerificationToken(token) {
try {
return (
client
.delete(verificationTokens)
.where(
and(
eq(verificationTokens.identifier, token.identifier),
eq(verificationTokens.token, token.token)
)
)
.returning()
.get() ?? null
)
} catch (err) {
throw new Error("No verification token found.")
}
},
deleteUser(id) {
return client.delete(users).where(eq(users.id, id)).returning().get()
},
unlinkAccount(account) {
client
.delete(accounts)
.where(
and(
eq(accounts.providerAccountId, account.providerAccountId),
eq(accounts.provider, account.provider)
)
)
.run()
// HACK: void should be fine
return undefined
},
}
}

View File

@@ -1,63 +0,0 @@
import { integer, sqliteTable, text, primaryKey } from "drizzle-orm/sqlite-core"
import { drizzle } from "drizzle-orm/better-sqlite3"
import { migrate } from "drizzle-orm/better-sqlite3/migrator"
import Database from "better-sqlite3"
import { ProviderType } from "next-auth/providers"
const sqlite = new Database("db.sqlite")
export const users = sqliteTable("users", {
id: text("id").notNull().primaryKey(),
name: text("name"),
email: text("email").notNull(),
emailVerified: integer("emailVerified", { mode: "timestamp_ms" }),
image: text("image"),
})
export const accounts = sqliteTable(
"accounts",
{
userId: text("userId")
.notNull()
.references(() => users.id, { onDelete: "cascade" }),
type: text("type").$type<ProviderType>().notNull(),
provider: text("provider").notNull(),
providerAccountId: text("providerAccountId").notNull(),
refresh_token: text("refresh_token"),
access_token: text("access_token"),
expires_at: integer("expires_at"),
token_type: text("token_type"),
scope: text("scope"),
id_token: text("id_token"),
session_state: text("session_state"),
},
(account) => ({
nameDoesntMatter: primaryKey(account.provider, account.providerAccountId),
})
)
export const sessions = sqliteTable("sessions", {
sessionToken: text("sessionToken").notNull().primaryKey(),
userId: text("userId")
.notNull()
.references(() => users.id, { onDelete: "cascade" }),
expires: integer("expires", { mode: "timestamp_ms" }).notNull(),
})
export const verificationTokens = sqliteTable(
"verificationToken",
{
identifier: text("identifier").notNull(),
token: text("token").notNull(),
expires: integer("expires", { mode: "timestamp_ms" }).notNull(),
},
(vt) => ({
nameDoesntMatter: primaryKey(vt.identifier, vt.token),
})
)
export const db = drizzle(sqlite)
export type DrizzleClient = typeof db
migrate(db, { migrationsFolder: "./drizzle" })

View File

@@ -1,68 +0,0 @@
import { randomUUID, runBasicTests } from "@next-auth/adapter-test"
import { DrizzleAdapter } from "../src"
import { db, users, accounts, sessions, verificationTokens } from '../src/schema'
import { eq, and } from 'drizzle-orm/expressions';
runBasicTests({
adapter: DrizzleAdapter(db),
db: {
id() {
return randomUUID()
},
connect: async () => {
await Promise.all([
db.delete(sessions).run(),
db.delete(accounts).run(),
db.delete(verificationTokens).run(),
db.delete(users).run(),
])
},
disconnect: async () => {
await Promise.all([
db.delete(sessions).run(),
db.delete(accounts).run(),
db.delete(verificationTokens).run(),
db.delete(users).run(),
])
},
user: (id) => db
.select()
.from(users)
.where(eq(users.id, id))
.get() ?? null,
session: (sessionToken) => db
.select()
.from(sessions)
.where(eq(sessions.sessionToken, sessionToken))
.get() ?? null,
account: (provider_providerAccountId) => {
return db
.select()
.from(accounts)
.where(
eq(
accounts.providerAccountId,
provider_providerAccountId.providerAccountId
)
)
.get()
?? null
},
verificationToken: (identifier_token) => db
.select()
.from(verificationTokens)
.where(
and(
eq(
verificationTokens.token,
identifier_token.token
),
eq(
verificationTokens.identifier,
identifier_token.identifier
)
)
).get() ?? null,
},
})

View File

@@ -1,21 +0,0 @@
{
"compilerOptions": {
"allowSyntheticDefaultImports": true,
"declaration": true,
"declarationMap": true,
"module": "ESNext",
"moduleResolution": "node",
"outDir": ".",
"rootDir": "src",
"skipDefaultLibCheck": true,
"skipLibCheck": true,
"strictNullChecks": true,
"stripInternal": true,
"target": "ES2020",
},
"exclude": [
"tests",
"*.js",
"*.d.ts*",
]
}

View File

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

View File

@@ -64,13 +64,13 @@ export interface FirebaseAdapterConfig extends AppOptions {
}
/**
* ## Setup
* ### Setup
*
* First, create a Firebase project and generate a service account key. Visit: `https://console.firebase.google.com/u/0/project/{project-id}/settings/serviceaccounts/adminsdk` (replace `{project-id}` with your project's id)
*
* Now you have a few options to authenticate with the Firebase Admin SDK in your app:
*
* ### Environment variables
* #### Environment variables
* - Download the service account key and save it in your project. (Make sure to add the file to your `.gitignore`!)
* - Add [`GOOGLE_APPLICATION_CREDENTIALS`](https://cloud.google.com/docs/authentication/application-default-credentials#GAC) to your environment variables and point it to the service account key file.
* - The adapter will automatically pick up the environment variable and use it to authenticate with the Firebase Admin SDK.
@@ -86,7 +86,7 @@ export interface FirebaseAdapterConfig extends AppOptions {
* })
* ```
*
* ### Service account values
* #### Service account values
*
* - Download the service account key to a temporary location. (Make sure to not commit this file to your repository!)
* - Add the following environment variables to your project: `FIREBASE_PROJECT_ID`, `FIREBASE_CLIENT_EMAIL`, `FIREBASE_PRIVATE_KEY`.
@@ -110,7 +110,7 @@ export interface FirebaseAdapterConfig extends AppOptions {
* })
* ```
*
* ### Using an existing Firestore instance
* #### Using an existing Firestore instance
*
* If you already have a Firestore instance, you can pass that to the adapter directly instead.
*

View File

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

View File

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

View File

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

View File

@@ -150,10 +150,6 @@ export interface OAuth2Config<Profile>
checks?: Array<"pkce" | "state" | "none" | "nonce">
clientId?: string
clientSecret?: string
/**
* Pass overrides to the underlying OAuth library.
* See [`oauth4webapi` client](https://github.com/panva/oauth4webapi/blob/main/docs/interfaces/Client.md) for details.
*/
client?: Partial<Client>
style?: OAuthProviderButtonStyles
/**

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,30 @@
diff --git a/dist/partials/members.js b/dist/partials/members.js
index 4fe981318e71ea716da9fca652ce6a0dc5a3e6df..e888cb3a4bc0a838229ae00b409b748a236b254c 100644
--- a/dist/partials/members.js
+++ b/dist/partials/members.js
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
exports.members = void 0;
const typedoc_1 = require("typedoc");
const els_1 = require("../support/els");
-const helpers_1 = require("../support/helpers");
+// const helpers_1 = require("../support/helpers");
function members(context, container) {
var _a;
const md = [];
@@ -18,14 +18,14 @@ function members(context, container) {
}
else {
(_a = container.groups) === null || _a === void 0 ? void 0 : _a.filter((group) => !group.allChildrenHaveOwnDocument()).forEach((group) => {
- const headingLevel = (0, helpers_1.getGroupHeadingLevel)(container);
+ // const headingLevel = (0, helpers_1.getGroupHeadingLevel)(container);
if (group.categories) {
group.categories.forEach((groupItem) => groupItem.children.forEach((item) => {
md.push(context.partials.member(item));
}));
}
else {
- md.push((0, els_1.heading)(headingLevel, group.title));
+ // md.push((0, els_1.heading)(headingLevel, group.title));
group.children
.filter((item) => !item.hasOwnDocument)
.forEach((groupChild, index) => {

1321
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

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