diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 37c43671ca..127d2241ca 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -74,7 +74,7 @@ env: jobs: test: - name: Run release + name: Test runs-on: ubuntu-latest steps: - name: Init @@ -82,7 +82,7 @@ jobs: with: fetch-depth: 0 - name: Install pnpm - uses: pnpm/action-setup@v2.2.4 + uses: pnpm/action-setup@v4 - name: Setup Node uses: actions/setup-node@v4 with: @@ -114,7 +114,7 @@ jobs: if: steps.playwright-cache.outputs.cache-hit != 'true' && github.repository == 'nextauthjs/next-auth' run: | pnpm exec playwright install --with-deps chromium - - name: Run Docker E2E + - name: Run E2E tests (Nextjs-Docker) continue-on-error: true if: false timeout-minutes: 15 @@ -148,7 +148,7 @@ jobs: name: playwright-traces path: "**/packages/utils/test-results/*/trace.zip" retention-days: 7 - - uses: codecov/codecov-action@v3 + - uses: codecov/codecov-action@v4 if: always() name: Coverage with: @@ -156,21 +156,22 @@ jobs: release-branch: name: Publish branch + timeout-minutes: 120 runs-on: ubuntu-latest needs: test if: ${{ github.event_name == 'push' }} environment: Production steps: - name: Init - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 0 # Please upvote https://github.com/orgs/community/discussions/13836 token: ${{ secrets.GH_PAT }} - name: Install pnpm - uses: pnpm/action-setup@v2.2.4 + uses: pnpm/action-setup@v4 - name: Setup Node - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: cache: "pnpm" - name: Install dependencies @@ -183,17 +184,18 @@ jobs: NPM_TOKEN: ${{ secrets.NPM_TOKEN }} release-pr: name: Publish PR + timeout-minutes: 120 runs-on: ubuntu-latest needs: test if: ${{ github.event_name == 'pull_request' }} environment: Preview steps: - name: Init - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Install pnpm - uses: pnpm/action-setup@v2.2.4 + uses: pnpm/action-setup@v4 - name: Setup Node - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version: 18 cache: "pnpm" @@ -228,11 +230,11 @@ jobs: if: ${{ github.event_name == 'workflow_dispatch' }} steps: - name: Init - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Install pnpm - uses: pnpm/action-setup@v2.2.4 + uses: pnpm/action-setup@v4 - name: Setup Node - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version: 18 cache: "pnpm" diff --git a/apps/dev/express/src/app.ts b/apps/dev/express/src/app.ts index 27cc8db60c..6157373064 100644 --- a/apps/dev/express/src/app.ts +++ b/apps/dev/express/src/app.ts @@ -56,7 +56,7 @@ app.get( authenticatedUser, async (_req: Request, res: Response) => { res.json(res.locals.session) - }, + } ) app.get("/", async (_req: Request, res: Response) => { diff --git a/apps/examples/nextjs/Dockerfile b/apps/examples/nextjs/Dockerfile index 525aaea3e4..2c27bcee0a 100644 --- a/apps/examples/nextjs/Dockerfile +++ b/apps/examples/nextjs/Dockerfile @@ -7,8 +7,8 @@ RUN apk add --no-cache libc6-compat WORKDIR /app # Install dependencies -COPY package.json ./ -RUN npm i +COPY package.json pnpm-lock.yaml ./ +RUN corepack enable && pnpm install # Rebuild the source code only when needed @@ -54,4 +54,4 @@ ENV PORT 3000 # server.js is created by next build from the standalone output # https://nextjs.org/docs/pages/api-reference/next-config-js/output -CMD HOSTNAME="0.0.0.0" node server.js \ No newline at end of file +CMD HOSTNAME="0.0.0.0" node server.js diff --git a/apps/examples/nextjs/app/[...proxy]/route.tsx b/apps/examples/nextjs/app/[...proxy]/route.tsx index 6e28669335..26f1449ae0 100644 --- a/apps/examples/nextjs/app/[...proxy]/route.tsx +++ b/apps/examples/nextjs/app/[...proxy]/route.tsx @@ -13,7 +13,7 @@ function stripContentEncoding(result: Response) { }) } -export async function handler(request: NextRequest) { +async function handler(request: NextRequest) { const session = await auth() const headers = new Headers(request.headers) diff --git a/apps/examples/nextjs/docker-compose.yml b/apps/examples/nextjs/docker-compose.yml new file mode 100644 index 0000000000..e5408dd83f --- /dev/null +++ b/apps/examples/nextjs/docker-compose.yml @@ -0,0 +1,17 @@ +version: "3" + +services: + authjs-docker-test: + environment: + - TEST_KEYCLOAK_USERNAME + - TEST_KEYCLOAK_PASSWORD + - AUTH_KEYCLOAK_ID + - AUTH_KEYCLOAK_SECRET + - AUTH_KEYCLOAK_ISSUER + - AUTH_SECRET="MohY0/2zSQw/psWEnejC2ka3Al0oifvY4YjOkUaFfnI=" + - AUTH_URL=http://localhost:3000/auth + build: + context: . + dockerfile: Dockerfile + ports: + - "3000:3000" diff --git a/apps/examples/nextjs/test-docker.sh b/apps/examples/nextjs/test-docker.sh new file mode 100755 index 0000000000..824fdb3e9f --- /dev/null +++ b/apps/examples/nextjs/test-docker.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash + +# Easier to read `docker-compose up` output +# export BUILDKIT_PROGRESS=plain + +args=("-f" "docker-compose.yml") +if [[ -z "${CI}" ]]; then + args+=("--env-file" ".env") +fi +args+=("up" "--detach" "--build") + +echo "Running: docker-compose ${args[*]}" + +if ! docker-compose "${args[@]}"; then + echo "Failed to start container" + exit 1 +fi + +echo "waiting 10 seconds for container to start..." +sleep 10 + +# Used to control which env vars to load in the playwright process +export TEST_DOCKER=1 + +# Always stop container, but exit with 1 when tests are failing +if playwright test -c ../../../packages/utils/playwright.config.ts; then + docker-compose down +else + docker-compose down && exit 1 +fi diff --git a/packages/adapter-azure-tables/src/index.ts b/packages/adapter-azure-tables/src/index.ts index 232beef223..d96c6a5769 100644 --- a/packages/adapter-azure-tables/src/index.ts +++ b/packages/adapter-azure-tables/src/index.ts @@ -1,6 +1,6 @@ /** *
An official Azure Table Storage adapter for Auth.js / NextAuth.js.
+ *An official Azure Table Storage adapter for Auth.js / NextAuth.js.
* * * @@ -51,46 +51,7 @@ export function withoutKeysAn official Cloudflare D1 adapter for Auth.js / NextAuth.js.
+ *An official Cloudflare D1 adapter for Auth.js / NextAuth.js.
* * * diff --git a/packages/adapter-drizzle/src/index.ts b/packages/adapter-drizzle/src/index.ts index 024a72228a..6fa34f49bc 100644 --- a/packages/adapter-drizzle/src/index.ts +++ b/packages/adapter-drizzle/src/index.ts @@ -1,6 +1,6 @@ /** *Official Drizzle ORM adapter for Auth.js / NextAuth.js.
+ *Official Drizzle ORM adapter for Auth.js / NextAuth.js.
* * * @@ -26,250 +26,7 @@ import { DefaultSQLiteSchema, SQLiteDrizzleAdapter } from "./lib/sqlite.js" import { DefaultSchema, SqlFlavorOptions } from "./lib/utils.js" import type { Adapter } from "@auth/core/adapters" -/** - * Create db instance and pass it to adapter. Add this adapter to your `auth.ts` Auth.js configuration object: - * - * ```ts title="auth.ts" - * import NextAuth from "next-auth" - * import Google from "next-auth/providers/google" - * import { DrizzleAdapter } from "@auth/drizzle-adapter" - * import { db } from "./db.ts" - * - * export const { handlers, auth } = NextAuth({ - * adapter: DrizzleAdapter(db), - * providers: [ - * Google, - * ], - * }) - * ``` - * - * Follow the Drizzle documentation for [PostgreSQL setup](https://orm.drizzle.team/docs/get-started-postgresql), [MySQL setup](https://orm.drizzle.team/docs/get-started-mysql) and [SQLite setup](https://orm.drizzle.team/docs/get-started-sqlite). - * - * :::info - * If you want to use your own tables, you can pass them as a second argument. If you add non-nullable columns, make sure to provide a default value or rewrite functions to handle the missing values. - * ::: - * - * ```ts title="auth.ts" - * import NextAuth from "next-auth" - * import Google from "next-auth/providers/google" - * import { DrizzleAdapter } from "@auth/drizzle-adapter" - * import { accounts, sessions, users, verificationTokens } from "./schema" - * import { db } from "./db.ts" - * - * export const { handlers, auth } = NextAuth({ - * adapter: DrizzleAdapter(db, { usersTable: users, accountsTable: accounts, sessionsTable: sessions, verificationTokensTable: verificationTokens }), - * providers: [ - * Google, - * ], - * }) - * ``` - * - * ## Setup - * - * First, create a schema that includes [the minimum requirements for a `next-auth` adapter](/reference/core/adapters#models). You can select your favorite SQL flavor below and copy it. - * Additionally, you may extend the schema from the minimum requirements to suit your needs. - * - * - [Postgres](#postgres) - * - [MySQL](#mysql) - * - [SQLite](#sqlite) - * - * ### Postgres - * ```ts title="schema.ts" - * import { - * timestamp, - * pgTable, - * text, - * primaryKey, - * integer - * } from "drizzle-orm/pg-core" - * import type { AdapterAccountType } from '@auth/core/adapters' - * - * export const users = pgTable("user", { - * id: text("id").primaryKey().$defaultFn(() => crypto.randomUUID()), - * name: text("name"), - * email: text("email").notNull(), - * emailVerified: timestamp("emailVerified", { mode: "date" }), - * image: text("image"), - * }) - * - * export const accounts = pgTable( - * "account", - * { - * userId: text("userId") - * .notNull() - * .references(() => users.id, { onDelete: "cascade" }), - * type: text("type").$typeOfficial DynamoDB adapter for Auth.js / NextAuth.js.
+ *Official DynamoDB adapter for Auth.js / NextAuth.js.
* * * @@ -36,182 +36,6 @@ export interface DynamoDBAdapterOptions { indexSortKey?: string } -/** - * ## Setup - * - * By default, the adapter expects a table with a partition key `pk` and a sort key `sk`, as well as a global secondary index named `GSI1` with `GSI1PK` as partition key and `GSI1SK` as sorting key. To automatically delete sessions and verification requests after they expire using [dynamodb TTL](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/TTL.html) you should [enable the TTL](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/time-to-live-ttl-how-to.html) with attribute name 'expires'. You can set whatever you want as the table name and the billing method. - * You can find the full schema in the table structure section below. - * - * ### Configuring Auth.js - * - * You need to pass `DynamoDBDocument` client from the modular [`aws-sdk`](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/dynamodb-example-dynamodb-utilities.html) v3 to the adapter. - * The default table name is `next-auth`, but you can customise that by passing `{ tableName: 'your-table-name' }` as the second parameter in the adapter. - * - * ```js title="pages/api/auth/[...nextauth].js" - * import { DynamoDB, DynamoDBClientConfig } from "@aws-sdk/client-dynamodb" - * import { DynamoDBDocument } from "@aws-sdk/lib-dynamodb" - * import NextAuth from "next-auth"; - * import Providers from "next-auth/providers"; - * import { DynamoDBAdapter } from "@auth/dynamodb-adapter" - * - * const config: DynamoDBClientConfig = { - * credentials: { - * accessKeyId: process.env.NEXT_AUTH_AWS_ACCESS_KEY, - * secretAccessKey: process.env.NEXT_AUTH_AWS_SECRET_KEY, - * }, - * region: process.env.NEXT_AUTH_AWS_REGION, - * }; - * - * const client = DynamoDBDocument.from(new DynamoDB(config), { - * marshallOptions: { - * convertEmptyValues: true, - * removeUndefinedValues: true, - * convertClassInstanceToMap: true, - * }, - * }) - * - * export default NextAuth({ - * // Configure one or more authentication providers - * providers: [ - * Providers.GitHub({ - * clientId: process.env.GITHUB_ID, - * clientSecret: process.env.GITHUB_SECRET, - * }), - * Providers.Email({ - * server: process.env.EMAIL_SERVER, - * from: process.env.EMAIL_FROM, - * }), - * // ...add more providers here - * ], - * adapter: DynamoDBAdapter( - * client - * ), - * }); - * ``` - * - * (AWS secrets start with `NEXT_AUTH_` in order to not conflict with [Vercel's reserved environment variables](https://vercel.com/docs/environment-variables#reserved-environment-variables).) - * - * ## AWS Credentials - * - * :::note - * Always follow the **principle of least privilege** when giving access to AWS - * services/resources -> identities should only be permitted to perform the - * smallest set of actions necessary to fulfill a specific task. - * ::: - * - * 1. Open the [AWS console](https://console.aws.amazon.com/) and go to "IAM", then "Users". - * 2. Create a new user. The purpose of this user is to give programmatic access to DynamoDB. - * 3. Create an Access Key and then copy Key ID and Secret to your `.env`/`.env.local` file. - * 4. Select "Add Permission" and "Create Inline Policy". - * 5. Copy the JSON below into the JSON input and replace `region`, `account_id` and `table_name` with your values. - * - * ```json - * { - * "Version": "2012-10-17", - * "Statement": [ - * { - * "Sid": "DynamoDBAccess", - * "Effect": "Allow", - * "Action": [ - * "dynamodb:BatchGetItem", - * "dynamodb:BatchWriteItem", - * "dynamodb:Describe*", - * "dynamodb:List*", - * "dynamodb:PutItem", - * "dynamodb:DeleteItem", - * "dynamodb:GetItem", - * "dynamodb:Scan", - * "dynamodb:Query", - * "dynamodb:UpdateItem" - * ], - * "Resource": [ - * "arn:aws:dynamodb:{region}:{account_id}:table/{table_name}", - * "arn:aws:dynamodb:{region}:{account_id}:table/{table_name}/index/GSI1" - * ] - * } - * ] - * } - * ``` - * - * ## Advanced usage - * - * ### Default schema - * - * The table respects the single table design pattern. This has many advantages: - * - * - Only one table to manage, monitor and provision. - * - Querying relations is faster than with multi-table schemas (for eg. retrieving all sessions for a user). - * - Only one table needs to be replicated if you want to go multi-region. - * - * > This schema is adapted for use in DynamoDB and based upon our main [schema](https://authjs.dev/reference/core/adapters#models) - * - * ![DynamoDB Table](https://i.imgur.com/hGZtWDq.png) - * - * You can create this table with infrastructure as code using [`aws-cdk`](https://github.com/aws/aws-cdk) with the following table definition: - * - * ```js title="stack.ts" - * new dynamodb.Table(this, `NextAuthTable`, { - * tableName: "next-auth", - * partitionKey: { name: "pk", type: dynamodb.AttributeType.STRING }, - * sortKey: { name: "sk", type: dynamodb.AttributeType.STRING }, - * timeToLiveAttribute: "expires", - * }).addGlobalSecondaryIndex({ - * indexName: "GSI1", - * partitionKey: { name: "GSI1PK", type: dynamodb.AttributeType.STRING }, - * sortKey: { name: "GSI1SK", type: dynamodb.AttributeType.STRING }, - * }) - * ``` - * - * Alternatively, you can use this cloudformation template: - * - * ```yaml title=cloudformation.yaml - * NextAuthTable: - * Type: "AWS::DynamoDB::Table" - * Properties: - * TableName: next-auth - * AttributeDefinitions: - * - AttributeName: pk - * AttributeType: S - * - AttributeName: sk - * AttributeType: S - * - AttributeName: GSI1PK - * AttributeType: S - * - AttributeName: GSI1SK - * AttributeType: S - * KeySchema: - * - AttributeName: pk - * KeyType: HASH - * - AttributeName: sk - * KeyType: RANGE - * GlobalSecondaryIndexes: - * - IndexName: GSI1 - * Projection: - * ProjectionType: ALL - * KeySchema: - * - AttributeName: GSI1PK - * KeyType: HASH - * - AttributeName: GSI1SK - * KeyType: RANGE - * TimeToLiveSpecification: - * AttributeName: expires - * Enabled: true - * ``` - * - * ### Using a custom schema - * - * You can configure your custom table schema by passing the `options` key to the adapter constructor: - * - * ```js - * const adapter = DynamoDBAdapter(client, { - * tableName: "custom-table-name", - * partitionKey: "custom-pk", - * sortKey: "custom-sk", - * indexName: "custom-index-name", - * indexPartitionKey: "custom-index-pk", - * indexSortKey: "custom-index-sk", - * }) - * ``` - **/ export function DynamoDBAdapter( client: DynamoDBDocument, options?: DynamoDBAdapterOptions diff --git a/packages/adapter-edgedb/src/index.ts b/packages/adapter-edgedb/src/index.ts index 7f61593499..4e13a41f56 100644 --- a/packages/adapter-edgedb/src/index.ts +++ b/packages/adapter-edgedb/src/index.ts @@ -1,6 +1,6 @@ /** *Official Edge DB adapter for Auth.js / NextAuth.js.
+ *Official Edge DB adapter for Auth.js / NextAuth.js.
* * * @@ -24,222 +24,6 @@ import type { } from "@auth/core/adapters" import type { Client } from "edgedb" -/** - * - * To use this Adapter, you need to install `edgedb`, `@edgedb/generate`, and the separate `@auth/edgedb-adapter` package: - * - * ```bash npm2yarn - * npm install edgedb @auth/edgedb-adapter - * npm install @edgedb/generate --save-dev - * ``` - * - * ## Installation - * - * First, ensure you have the EdgeDB CLI installed. - * - * Follow the instructions below, or read the [EdgeDB quickstart](https://www.edgedb.com/docs/intro/quickstart) to install the EdgeDB CLI and initialize a project - * - * ### Linux or macOS - * - * ```bash - * curl --proto '=https' --tlsv1.2 -sSf https://sh.edgedb.com | sh - * ``` - * - * ### Windows - * - * ```powershell - * iwr https://ps1.edgedb.com -useb | iex - * ``` - * - * Check that the CLI is available with the `edgedb --version` command. If you get a `Command not found` error, you may need to open a new terminal window before the `edgedb` command is available. - * - * Once the CLI is installed, initialize a project from the application’s root directory. You’ll be presented with a series of prompts. - * - * ```bash - * edgedb project init - * ``` - * - * This process will spin up an EdgeDB instance and [“link”](https://www.edgedb.com/docs/cli/edgedb_instance/edgedb_instance_link#edgedb-instance-link) it with your current directory. As long as you’re inside that directory, CLI commands and client libraries will be able to connect to the linked instance automatically, without additional configuration. - * - * ## Setup - * - * ### NextAuth.js configuration - * - * Configure your NextAuth.js to use the EdgeDB Adapter: - * - * ```js title="pages/api/auth/[...nextauth].js" - * import NextAuth from "next-auth" - * import GoogleProvider from "next-auth/providers/google" - * import { EdgeDBAdapter } from "@auth/edgedb-adapter" - * import { createClient } from "edgedb" - * - * const client = createClient() - * - * export default NextAuth({ - * adapter: EdgeDBAdapter(client), - * providers: [ - * GoogleProvider({ - * clientId: process.env.GOOGLE_CLIENT_ID, - * clientSecret: process.env.GOOGLE_CLIENT_SECRET, - * }), - * ], - * }) - * ``` - * - * ### Create the EdgeDB schema - * - * Replace the contents of the auto-generated file in `dbschema/default.esdl` with the following: - * - * > This schema is adapted for use in EdgeDB and based upon our main [schema](https://authjs.dev/getting-started/adapters#models) - * - * ```json title="default.esdl" - * module default { - * type User { - * property name -> str; - * required property email -> str { - * constraint exclusive; - * }; - * property emailVerified -> datetime; - * property image -> str; - * multi link accounts := .Official Fauna adapter for Auth.js / NextAuth.js.
+ *Official Fauna adapter for Auth.js / NextAuth.js.
* - * + * * *Official Hasura adapter for Auth.js / NextAuth.js.
+ *Official Hasura adapter for Auth.js / NextAuth.js.
* * * @@ -42,101 +42,6 @@ import { VerificationTokenFragmentDoc, } from "./lib/generated/graphql.js" -/** - * - * ## Setup - * - * 1. Create the Auth.js schema in your database using SQL. - * - * ```sql - * CREATE TABLE accounts ( - * id uuid DEFAULT gen_random_uuid() NOT NULL, - * type text NOT NULL, - * provider text NOT NULL, - * "providerAccountId" text NOT NULL, - * refresh_token text, - * access_token text, - * expires_at integer, - * token_type text, - * scope text, - * id_token text, - * session_state text, - * "userId" uuid NOT NULL - * ); - * - * CREATE TABLE sessions ( - * id uuid DEFAULT gen_random_uuid() NOT NULL, - * "sessionToken" text NOT NULL, - * "userId" uuid NOT NULL, - * expires timestamptz NOT NULL - * ); - * - * CREATE TABLE users ( - * id uuid DEFAULT gen_random_uuid() NOT NULL, - * name text, - * email text NOT NULL, - * "emailVerified" timestamptz, - * image text - * ); - * - * CREATE TABLE verification_tokens ( - * token text NOT NULL, - * identifier text NOT NULL, - * expires timestamptz NOT NULL - * ); - * - * CREATE TABLE provider_type ( - * value text NOT NULL - * ); - * - * ALTER TABLE ONLY accounts - * ADD CONSTRAINT accounts_pkey PRIMARY KEY (id); - * - * ALTER TABLE ONLY sessions - * ADD CONSTRAINT sessions_pkey PRIMARY KEY ("sessionToken"); - * - * ALTER TABLE ONLY users - * ADD CONSTRAINT users_email_key UNIQUE (email); - * - * ALTER TABLE ONLY users - * ADD CONSTRAINT users_pkey PRIMARY KEY (id); - * - * ALTER TABLE ONLY verification_tokens - * ADD CONSTRAINT verification_tokens_pkey PRIMARY KEY (token); - * - * ALTER TABLE ONLY provider_type - * ADD CONSTRAINT provider_type_pkey PRIMARY KEY (value); - * - * ALTER TABLE ONLY accounts - * ADD CONSTRAINT "accounts_userId_fkey" FOREIGN KEY ("userId") REFERENCES public.users(id) ON UPDATE RESTRICT ON DELETE CASCADE; - * - * ALTER TABLE ONLY sessions - * ADD CONSTRAINT "sessions_userId_fkey" FOREIGN KEY ("userId") REFERENCES public.users(id) ON UPDATE RESTRICT ON DELETE CASCADE; - * - * INSERT INTO provider_type (value) VALUES ('credentials'), ('email'), ('oauth'), ('oidc'); - * - * ALTER TABLE ONLY accounts - * ADD CONSTRAINT "accounts_type_fkey" FOREIGN KEY ("type") REFERENCES public.provider_type(value) ON UPDATE RESTRICT ON DELETE RESTRICT; - * ``` - * - * :::info - * Tips: [Track all the tables and relationships in Hasura](https://hasura.io/docs/latest/schema/postgres/using-existing-database/#step-1-track-tablesviews) - * ::: - * - * 2. Add the adapter to your `pages/api/[...nextauth].ts` next-auth configuration object. - * - * ```js title="pages/api/auth/[...nextauth].js" - * import NextAuth from "next-auth" - * import { HasuraAdapter } from "@auth/hasura-adapter" - * - * export default NextAuth({ - * adapter: HasuraAdapter({ - * endpoint: "Official Kysely adapter for Auth.js / NextAuth.js.
+ *Official Kysely adapter for Auth.js / NextAuth.js.
* * * @@ -57,187 +57,6 @@ export const format = { }, } -/** - * - * ## Setup - * - * This adapter supports the same first party dialects that Kysely (as of v0.24.2) supports: PostgreSQL, MySQL, and SQLite. The examples below use PostgreSQL with the [pg](https://www.npmjs.com/package/pg) client. - * - * ```bash npm2yarn - * npm install pg - * npm install --save-dev @types/pg - * ``` - * - * ```ts title="pages/api/auth/[...nextauth].ts" - * import NextAuth from "next-auth" - * import GoogleProvider from "next-auth/providers/google" - * import { KyselyAdapter } from "@auth/kysely-adapter" - * import { db } from "../../../db" - * - * export default NextAuth({ - * adapter: KyselyAdapter(db), - * providers: [ - * GoogleProvider({ - * clientId: process.env.GOOGLE_CLIENT_ID, - * clientSecret: process.env.GOOGLE_CLIENT_SECRET, - * }), - * ], - * }) - * ``` - * - * Kysely's constructor requires a database interface that contains an entry with an interface for each of your tables. You can define these types manually, or use `kysely-codegen` / `prisma-kysely` to automatically generate them. Check out the default [models](/reference/core/adapters#models) required by Auth.js. - * - * ```ts title="db.ts" - * import { PostgresDialect } from "kysely" - * import { Pool } from "pg" - * - * // This adapter exports a wrapper of the original `Kysely` class called `KyselyAuth`, - * // that can be used to provide additional type-safety. - * // While using it isn't required, it is recommended as it will verify - * // that the database interface has all the fields that Auth.js expects. - * import { KyselyAuth } from "@auth/kysely-adapter" - * - * import type { GeneratedAlways } from "kysely" - * - * interface Database { - * User: { - * id: GeneratedAlwaysOfficial MikroORM adapter for Auth.js / NextAuth.js.
+ *Official MikroORM adapter for Auth.js / NextAuth.js.
* - * + * * *Official MongoDB adapter for Auth.js / NextAuth.js.
+ *Official MongoDB adapter for Auth.js / NextAuth.js.
* * * @@ -88,60 +88,6 @@ export function _id(hex?: string) { return new ObjectId(hex) } -/** - * ## Setup - * - * The MongoDB adapter does not handle connections automatically, so you will have to make sure that you pass the Adapter a `MongoClient` that is connected already. Below you can see an example how to do this. - * - * ### Add the MongoDB client - * - * ```ts - * // This approach is taken from https://github.com/vercel/next.js/tree/canary/examples/with-mongodb - * import { MongoClient } from "mongodb" - * - * if (!process.env.MONGODB_URI) { - * throw new Error('Invalid/Missing environment variable: "MONGODB_URI"') - * } - * - * const uri = process.env.MONGODB_URI - * const options = {} - * - * let client - * let clientPromise: PromiseOfficial Neo4j adapter for Auth.js / NextAuth.js.
+ *Official Neo4j adapter for Auth.js / NextAuth.js.
* - * + * * *An official PostgreSQL adapter for Auth.js / NextAuth.js.
+ *An official PostgreSQL adapter for Auth.js / NextAuth.js.
* - * + * * *Official PouchDB adapter for Auth.js / NextAuth.js.
+ *Official PouchDB adapter for Auth.js / NextAuth.js.
* * * @@ -82,59 +82,6 @@ export interface PouchDBAdapterOptions { indexes?: IndexConfig } -/** - * :::info - * Depending on your architecture you can use PouchDB's http adapter to reach any database compliant with the CouchDB protocol (CouchDB, Cloudant, etc.) or use any other PouchDB compatible adapter (leveldb, in-memory, etc.) - * ::: - * - * ## Setup - * - * :::note - * Your PouchDB instance MUST provide the `pouchdb-find` plugin since it is used internally by the adapter to build and manage indexes - * ::: - * - * Add this adapter to your `pages/api/auth/[...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 { PouchDBAdapter } from "@auth/pouchdb-adapter" - * import PouchDB from "pouchdb" - * - * // Setup your PouchDB instance and database - * PouchDB - * .plugin(require("pouchdb-adapter-leveldb")) // Or any other adapter - * .plugin(require("pouchdb-find")) // Don't forget the `pouchdb-find` plugin - * - * const pouchdb = new PouchDB("auth_db", { adapter: "leveldb" }) - * - * // For more information on each option (and a full list of options) go to - * // https://authjs.dev/reference/core/types#authconfig - * export default NextAuth({ - * // https://authjs.dev/getting-started/authentication/oauth - * providers: [ - * GoogleProvider({ - * clientId: process.env.GOOGLE_ID, - * clientSecret: process.env.GOOGLE_SECRET, - * }), - * ], - * adapter: PouchDBAdapter(pouchdb), - * }) - * ``` - * - * ## Advanced usage - * - * ### Memory-First Caching Strategy - * - * 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. - * - * 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 sync. - * - * This will most likely not increase performance much in a serverless environment due to various reasons such as concurrency, function startup time increases, etc. - * - * For more details, please see https://pouchdb.com/api.html#sync - * - */ export function PouchDBAdapter(options: PouchDBAdapterOptions): Adapter { const { pouchdb } = options const { diff --git a/packages/adapter-sequelize/src/index.ts b/packages/adapter-sequelize/src/index.ts index bebcc6744a..701d9a08b2 100644 --- a/packages/adapter-sequelize/src/index.ts +++ b/packages/adapter-sequelize/src/index.ts @@ -1,6 +1,6 @@ /** *Official Sequilize adapter for Auth.js / NextAuth.js.
+ *Official Sequilize adapter for Auth.js / NextAuth.js.
* * * @@ -58,83 +58,6 @@ export interface SequelizeAdapterOptions { }> } -/** - * :::warning - * You'll also have to manually install [the driver for your database](https://sequelize.org/master/manual/getting-started.html) of choice. - * ::: - * - * ## Setup - * - * ### Configuring Auth.js - * - * 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 SequelizeAdapter from "@auth/sequelize-adapter" - * import { Sequelize } from "sequelize" - * - * // https://sequelize.org/master/manual/getting-started.html#connecting-to-a-database - * const sequelize = new Sequelize("yourconnectionstring") - * - * // For more information on each option (and a full list of options) go to - * // https://authjs.dev/reference/core#authconfig - * export default NextAuth({ - * // https://authjs.dev/reference/providers/ - * providers: [], - * adapter: SequelizeAdapter(sequelize), - * }) - * ``` - * - * ### Updating the database schema - * - * By default, the sequelize adapter will not create tables in your database. In production, best practice is to create the [required tables](https://authjs.dev/reference/core/adapters#models) in your database via [migrations](https://sequelize.org/master/manual/migrations.html). In development, you are able to call [`sequelize.sync()`](https://sequelize.org/master/manual/model-basics.html#model-synchronization) to have sequelize create the necessary tables, foreign keys and indexes: - * - * > This schema is adapted for use in Sequelize and based upon our main [schema](https://authjs.dev/reference/core/adapters#models) - * - * ```js - * import NextAuth from "next-auth" - * import SequelizeAdapter from "@auth/sequelize-adapter" - * import Sequelize from 'sequelize' - * - * const sequelize = new Sequelize("sqlite::memory:") - * const adapter = SequelizeAdapter(sequelize) - * - * // Calling sync() is not recommended in production - * sequelize.sync() - * - * export default NextAuth({ - * adapter - * }) - * ``` - * - * ## Advanced usage - * - * ### Using custom models - * - * Sequelize models are option to customization like so: - * - * ```js - * import NextAuth from "next-auth" - * import SequelizeAdapter, { models } from "@auth/sequelize-adapter" - * import Sequelize, { DataTypes } from "sequelize" - * - * const sequelize = new Sequelize("sqlite::memory:") - * - * export default NextAuth({ - * // https://authjs.dev/reference/providers/ - * providers: [], - * adapter: SequelizeAdapter(sequelize, { - * models: { - * User: sequelize.define("user", { - * ...models.User, - * phoneNumber: DataTypes.STRING, - * }), - * }, - * }), - * }) - * ``` - */ export default function SequelizeAdapter( client: Sequelize, options?: SequelizeAdapterOptions diff --git a/packages/adapter-supabase/src/index.ts b/packages/adapter-supabase/src/index.ts index d94faffc7f..54f96e336a 100644 --- a/packages/adapter-supabase/src/index.ts +++ b/packages/adapter-supabase/src/index.ts @@ -1,6 +1,6 @@ /** *Official Supabase adapter for Auth.js / NextAuth.js.
+ *Official Supabase adapter for Auth.js / NextAuth.js.
* * * @@ -56,294 +56,6 @@ export interface SupabaseAdapterOptions { secret: string } -/** - * :::note - * This adapter is developed by the community and not officially maintained or supported by Supabase. It uses the Supabase Database to store user and session data in a separate `next_auth` schema. It is a standalone Auth server that does not interface with Supabase Auth and therefore provides a different feature set. - * - * If you're looking for an officially maintained Auth server with additional features like [built-in email server](https://supabase.com/docs/guides/auth/auth-email#configure-email-settings?utm_source=authjs-docs&medium=referral&campaign=authjs), [phone auth](https://supabase.com/docs/guides/auth/auth-twilio?utm_source=authjs-docs&medium=referral&campaign=authjs), and [Multi Factor Authentication (MFA / 2FA)](https://supabase.com/contact/mfa?utm_source=authjs-docs&medium=referral&campaign=authjs), please use [Supabase Auth](https://supabase.com/auth) with the [Auth Helpers for Next.js](https://supabase.com/docs/guides/auth/auth-helpers/nextjs?utm_source=authjs-docs&medium=referral&campaign=authjs). - * ::: - * - * ## Setup - * - * ### Configure Auth.js - * - * 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 { SupabaseAdapter } from "@auth/supabase-adapter" - * - * // For more information on each option (and a full list of options) go to - * // https://authjs.dev/reference/core#authconfig - * export default NextAuth({ - * // https://authjs.dev/reference/core/providers - * providers: [], - * adapter: SupabaseAdapter({ - * url: process.env.NEXT_PUBLIC_SUPABASE_URL, - * secret: process.env.SUPABASE_SERVICE_ROLE_KEY, - * }), - * }) - * ``` - * - * ### Create the NextAuth schema in Supabase - * - * Setup your database as described in our main [schema](https://authjs.dev/reference/core/adapters#models), by copying the SQL schema below in the Supabase [SQL Editor](https://app.supabase.com/project/_/sql). - * - * Alternatively you can select the NextAuth Quickstart card on the [SQL Editor page](https://app.supabase.com/project/_/sql), or [create a migration with the Supabase CLI](https://supabase.com/docs/guides/cli/local-development#database-migrations?utm_source=authjs-docs&medium=referral&campaign=authjs). - * - * ```sql - * -- - * -- Name: next_auth; Type: SCHEMA; - * -- - * CREATE SCHEMA next_auth; - * - * GRANT USAGE ON SCHEMA next_auth TO service_role; - * GRANT ALL ON SCHEMA next_auth TO postgres; - * - * -- - * -- Create users table - * -- - * CREATE TABLE IF NOT EXISTS next_auth.users - * ( - * id uuid NOT NULL DEFAULT uuid_generate_v4(), - * name text, - * email text, - * "emailVerified" timestamp with time zone, - * image text, - * CONSTRAINT users_pkey PRIMARY KEY (id), - * CONSTRAINT email_unique UNIQUE (email) - * ); - * - * GRANT ALL ON TABLE next_auth.users TO postgres; - * GRANT ALL ON TABLE next_auth.users TO service_role; - * - * --- uid() function to be used in RLS policies - * CREATE FUNCTION next_auth.uid() RETURNS uuid - * LANGUAGE sql STABLE - * AS $$ - * select - * coalesce( - * nullif(current_setting('request.jwt.claim.sub', true), ''), - * (nullif(current_setting('request.jwt.claims', true), '')::jsonb ->> 'sub') - * )::uuid - * $$; - * - * -- - * -- Create sessions table - * -- - * CREATE TABLE IF NOT EXISTS next_auth.sessions - * ( - * id uuid NOT NULL DEFAULT uuid_generate_v4(), - * expires timestamp with time zone NOT NULL, - * "sessionToken" text NOT NULL, - * "userId" uuid, - * CONSTRAINT sessions_pkey PRIMARY KEY (id), - * CONSTRAINT sessionToken_unique UNIQUE ("sessionToken"), - * CONSTRAINT "sessions_userId_fkey" FOREIGN KEY ("userId") - * REFERENCES next_auth.users (id) MATCH SIMPLE - * ON UPDATE NO ACTION - * ON DELETE CASCADE - * ); - * - * GRANT ALL ON TABLE next_auth.sessions TO postgres; - * GRANT ALL ON TABLE next_auth.sessions TO service_role; - * - * -- - * -- Create accounts table - * -- - * CREATE TABLE IF NOT EXISTS next_auth.accounts - * ( - * id uuid NOT NULL DEFAULT uuid_generate_v4(), - * type text NOT NULL, - * provider text NOT NULL, - * "providerAccountId" text NOT NULL, - * refresh_token text, - * access_token text, - * expires_at bigint, - * token_type text, - * scope text, - * id_token text, - * session_state text, - * oauth_token_secret text, - * oauth_token text, - * "userId" uuid, - * CONSTRAINT accounts_pkey PRIMARY KEY (id), - * CONSTRAINT provider_unique UNIQUE (provider, "providerAccountId"), - * CONSTRAINT "accounts_userId_fkey" FOREIGN KEY ("userId") - * REFERENCES next_auth.users (id) MATCH SIMPLE - * ON UPDATE NO ACTION - * ON DELETE CASCADE - * ); - * - * GRANT ALL ON TABLE next_auth.accounts TO postgres; - * GRANT ALL ON TABLE next_auth.accounts TO service_role; - * - * -- - * -- Create verification_tokens table - * -- - * CREATE TABLE IF NOT EXISTS next_auth.verification_tokens - * ( - * identifier text, - * token text, - * expires timestamp with time zone NOT NULL, - * CONSTRAINT verification_tokens_pkey PRIMARY KEY (token), - * CONSTRAINT token_unique UNIQUE (token), - * CONSTRAINT token_identifier_unique UNIQUE (token, identifier) - * ); - * - * GRANT ALL ON TABLE next_auth.verification_tokens TO postgres; - * GRANT ALL ON TABLE next_auth.verification_tokens TO service_role; - * ``` - * - * ### Expose the NextAuth schema in Supabase - * - * Expose the `next_auth` schema via the Serverless API in the [API settings](https://app.supabase.com/project/_/settings/api) by adding `next_auth` to the "Exposed schemas" list. - * - * When developing locally add `next_auth` to the `schemas` array in the `config.toml` file in the `supabase` folder that was generated by the [Supabase CLI](https://supabase.com/docs/guides/cli/local-development#initialize-your-project?utm_source=authjs-docs&medium=referral&campaign=authjs). - * - * ## Advanced usage - * - * ### Enabling Row Level Security (RLS) - * - * Postgres provides a powerful feature called [Row Level Security (RLS)](https://supabase.com/docs/guides/auth/row-level-security?utm_source=authjs-docs&medium=referral&campaign=authjs) to limit access to data. - * - * This works by sending a signed JWT to your [Supabase Serverless API](https://supabase.com/docs/guides/api?utm_source=authjs-docs&medium=referral&campaign=authjs). There is two steps to make this work with NextAuth: - * - * #### Generate the Supabase `access_token` JWT in the session callback - * - * To sign the JWT use the `jsonwebtoken` package: - * - * ```bash npm2yarn - * npm install jsonwebtoken - * ``` - * - * Using the [NexthAuth.js Session callback](https://authjs.dev/reference/core/types#session) create the Supabase `access_token` and append it to the `session` object. - * - * To sign the JWT use the Supabase JWT secret which can be found in the [API settings](https://app.supabase.com/project/_/settings/api) - * - * ```js title="pages/api/auth/[...nextauth].js" - * import NextAuth from "next-auth" - * import { SupabaseAdapter } from "@auth/supabase-adapter" - * import jwt from "jsonwebtoken" - * - * // For more information on each option (and a full list of options) go to - * // https://authjs.dev/reference/core/types#authconfig - * export default NextAuth({ - * // https://authjs.dev/getting-started/authentication/oauth - * providers: [], - * adapter: SupabaseAdapter({ - * url: process.env.NEXT_PUBLIC_SUPABASE_URL, - * secret: process.env.SUPABASE_SERVICE_ROLE_KEY, - * }), - * callbacks: { - * async session({ session, user }) { - * const signingSecret = process.env.SUPABASE_JWT_SECRET - * if (signingSecret) { - * const payload = { - * aud: "authenticated", - * exp: Math.floor(new Date(session.expires).getTime() / 1000), - * sub: user.id, - * email: user.email, - * role: "authenticated", - * } - * session.supabaseAccessToken = jwt.sign(payload, signingSecret) - * } - * return session - * }, - * }, - * }) - * ``` - * - * #### Inject the Supabase `access_token` JWT into the client - * - * For example, given the following public schema: - * - * ```sql - * -- Note: This table contains user data. Users should only be able to view and update their own data. - * create table users ( - * -- UUID from next_auth.users - * id uuid not null primary key, - * name text, - * email text, - * image text, - * constraint "users_id_fkey" foreign key ("id") - * references next_auth.users (id) match simple - * on update no action - * on delete cascade -- if a user is deleted in NextAuth they will also be deleted in our public table. - * ); - * alter table users enable row level security; - * create policy "Can view own user data." on users for select using (next_auth.uid() = id); - * create policy "Can update own user data." on users for update using (next_auth.uid() = id); - * - * -- This trigger automatically creates a user entry when a new user signs up via NextAuth. - * create function public.handle_new_user() - * returns trigger as $$ - * begin - * insert into public.users (id, name, email, image) - * values (new.id, new.name, new.email, new.image); - * return new; - * end; - * $$ language plpgsql security definer; - * create trigger on_auth_user_created - * after insert on next_auth.users - * for each row execute procedure public.handle_new_user(); - * ``` - * - * The `supabaseAccessToken` is now available on the `session` object and can be passed to the supabase-js client. This works in any environment: client-side, server-side (API routes, SSR), as well as in middleware edge functions! - * - * ```js - * // Use `useSession()` or `unstable_getServerSession()` to get the NextAuth session. - * - * const { supabaseAccessToken } = session - * - * const supabase = createClient( - * process.env.NEXT_PUBLIC_SUPABASE_URL, - * process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY, - * { - * global: { - * headers: { - * Authorization: `Bearer ${supabaseAccessToken}`, - * }, - * }, - * } - * ) - * // Now you can query with RLS enabled. - * const { data, error } = await supabase.from("users").select("*") - * ``` - * - * ### Usage with TypeScript - * - * You can pass types that were generated with the Supabase CLI to the Supabase Client to get enhanced type safety and auto-completion. - * - * Creating a new supabase client object: - * - * ```tsx - * import { createClient } from "@supabase/supabase-js" - * import { Database } from "../database.types" - * - * const supabase = createClientOfficial SurrealDB adapter for Auth.js / NextAuth.js.
+ *Official SurrealDB adapter for Auth.js / NextAuth.js.
* - * + * * *Official TypeORM adapter for Auth.js / NextAuth.js.
+ *Official TypeORM adapter for Auth.js / NextAuth.js.
* * * @@ -64,218 +64,6 @@ export async function getManager(options: { return manager } -/** - * ## Setup - * - * Configure Auth.js to use the TypeORM Adapter: - * - * ```ts title="pages/api/auth/[...nextauth].ts" - * import NextAuth from "next-auth" - * import { TypeORMAdapter } from "@auth/typeorm-adapter" - * - * export default NextAuth({ - * adapter: TypeORMAdapter("yourconnectionstring"), - * }) - * ``` - * - * `TypeORMAdapter` takes either a connection string, or a [`ConnectionOptions`](https://github.com/typeorm/typeorm/blob/master/docs/connection-options.md) object as its first parameter. - * - * ## Advanced usage - * - * ### Custom models - * - * The TypeORM adapter uses [`Entity` classes](https://github.com/typeorm/typeorm/blob/master/docs/entities.md) to define the shape of your data. - * - * If you want to override the default entities (for example to add a `role` field to your `UserEntity`), you will have to do the following: - * - * 1. Create a file containing your modified entities: - * - * (The file below is based on the [default entities](https://github.com/nextauthjs/next-auth/blob/main/packages/adapter-typeorm/src/entities.ts)) - * - * ```ts title="lib/entities.ts" {37-38} - * import { - * Entity, - * PrimaryGeneratedColumn, - * Column, - * ManyToOne, - * OneToMany, - * ValueTransformer, - * } from "typeorm" - * - * const transformer: Record<"date" | "bigint", ValueTransformer> = { - * date: { - * from: (date: string | null) => date && new Date(parseInt(date, 10)), - * to: (date?: Date) => date?.valueOf().toString(), - * }, - * bigint: { - * from: (bigInt: string | null) => bigInt && parseInt(bigInt, 10), - * to: (bigInt?: number) => bigInt?.toString(), - * }, - * } - * - * @Entity({ name: "users" }) - * export class UserEntity { - * @PrimaryGeneratedColumn("uuid") - * id!: string - * - * @Column({ type: "varchar", nullable: true }) - * name!: string | null - * - * @Column({ type: "varchar", nullable: true, unique: true }) - * email!: string | null - * - * @Column({ type: "varchar", nullable: true, transformer: transformer.date }) - * emailVerified!: string | null - * - * @Column({ type: "varchar", nullable: true }) - * image!: string | null - * - * @Column({ type: "varchar", nullable: true }) - * role!: string | null - * - * @OneToMany(() => SessionEntity, (session) => session.userId) - * sessions!: SessionEntity[] - * - * @OneToMany(() => AccountEntity, (account) => account.userId) - * accounts!: AccountEntity[] - * } - * - * @Entity({ name: "accounts" }) - * export class AccountEntity { - * @PrimaryGeneratedColumn("uuid") - * id!: string - * - * @Column({ type: "uuid" }) - * userId!: string - * - * @Column() - * type!: string - * - * @Column() - * provider!: string - * - * @Column() - * providerAccountId!: string - * - * @Column({ type: "varchar", nullable: true }) - * refresh_token!: string | null - * - * @Column({ type: "varchar", nullable: true }) - * access_token!: string | null - * - * @Column({ - * nullable: true, - * type: "bigint", - * transformer: transformer.bigint, - * }) - * expires_at!: number | null - * - * @Column({ type: "varchar", nullable: true }) - * token_type!: string | null - * - * @Column({ type: "varchar", nullable: true }) - * scope!: string | null - * - * @Column({ type: "varchar", nullable: true }) - * id_token!: string | null - * - * @Column({ type: "varchar", nullable: true }) - * session_state!: string | null - * - * @Column({ type: "varchar", nullable: true }) - * oauth_token_secret!: string | null - * - * @Column({ type: "varchar", nullable: true }) - * oauth_token!: string | null - * - * @ManyToOne(() => UserEntity, (user) => user.accounts, { - * createForeignKeyConstraints: true, - * }) - * user!: UserEntity - * } - * - * @Entity({ name: "sessions" }) - * export class SessionEntity { - * @PrimaryGeneratedColumn("uuid") - * id!: string - * - * @Column({ unique: true }) - * sessionToken!: string - * - * @Column({ type: "uuid" }) - * userId!: string - * - * @Column({ transformer: transformer.date }) - * expires!: string - * - * @ManyToOne(() => UserEntity, (user) => user.sessions) - * user!: UserEntity - * } - * - * @Entity({ name: "verification_tokens" }) - * export class VerificationTokenEntity { - * @PrimaryGeneratedColumn("uuid") - * id!: string - * - * @Column() - * token!: string - * - * @Column() - * identifier!: string - * - * @Column({ transformer: transformer.date }) - * expires!: string - * } - * ``` - * - * 2. Pass them to `TypeORMAdapter` - * - * ```js title="pages/api/auth/[...nextauth].js" - * import NextAuth from "next-auth" - * import { TypeORMAdapter } from "@auth/typeorm-adapter" - * import * as entities from "lib/entities" - * - * export default NextAuth({ - * adapter: TypeORMAdapter("yourconnectionstring", { entities }) - * }) - * ``` - * - * :::tip Synchronize your database - * The `synchronize: true` option in TypeORM will generate SQL that exactly matches the entities. This will automatically apply any changes it finds in the entity model. This is a useful option in development. - * ::: - * - * :::warning Using synchronize in production - * The option `synchronize: true` should not be enabled against production databases as it may cause data loss if the configured schema does not match the expected schema! We recommend that you synchronize/migrate your production database at build-time. - * ::: - * - * ### Naming Conventions - * - * If mixed snake_case and camelCase column names are an issue for you and/or your underlying database system, we recommend using TypeORM's naming strategy feature to change the target field names. There is a package called `typeorm-naming-strategies` which includes a `snake_case` strategy which will translate the fields from how Auth.js expects them, to snake_case in the actual database. - * - * For example, you can add the naming convention option to the connection object in your NextAuth config. - * - * ```js title="pages/api/auth/[...nextauth].js" - * import NextAuth from "next-auth" - * import { TypeORMAdapter } from "@auth/typeorm-adapter" - * import { SnakeNamingStrategy } from 'typeorm-naming-strategies' - * import { ConnectionOptions } from "typeorm" - * - * const connection: ConnectionOptions = { - * type: "mysql", - * host: "localhost", - * port: 3306, - * username: "test", - * password: "test", - * database: "test", - * namingStrategy: new SnakeNamingStrategy() - * } - * - * export default NextAuth({ - * adapter: TypeORMAdapter(connection) - * }) - * ``` - * - */ export function TypeORMAdapter( dataSource: string | DataSourceOptions, options?: TypeORMAdapterOptions diff --git a/packages/adapter-unstorage/src/index.ts b/packages/adapter-unstorage/src/index.ts index f909ec8d42..27f39ff775 100644 --- a/packages/adapter-unstorage/src/index.ts +++ b/packages/adapter-unstorage/src/index.ts @@ -1,6 +1,6 @@ /** *Official Unstorage adapter for Auth.js / NextAuth.js.
+ *Official Unstorage adapter for Auth.js / NextAuth.js.
* * * @@ -101,80 +101,6 @@ export function hydrateDates(json: object) { }, {} as any) } -/** - * ## Setup - * - * Configure Auth.js to use the Unstorage Adapter. - * - * ```js title="pages/api/auth/[...nextauth].js" - * import NextAuth from "next-auth" - * import GoogleProvider from "next-auth/providers/google" - * import { UnstorageAdapter } from "@auth/unstorage-adapter" - * import { createStorage } from "unstorage"; - * - * const storage = createStorage(); - * - * export default NextAuth({ - * adapter: UnstorageAdapter(storage), - * providers: [ - * GoogleProvider({ - * clientId: process.env.GOOGLE_CLIENT_ID, - * clientSecret: process.env.GOOGLE_CLIENT_SECRET, - * }), - * ], - * }) - * ``` - * - * ## Advanced usage - * - * ### Using multiple apps with a single storage - * - * If you have multiple Auth.js connected apps using the same storage, you need different key prefixes for every app. - * - * You can change the prefixes by passing an `options` object as the second argument to the adapter factory function. - * - * The default values for this object are: - * - * ```js - * const defaultOptions = { - * baseKeyPrefix: "", - * accountKeyPrefix: "user:account:", - * accountByUserIdPrefix: "user:account:by-user-id:", - * emailKeyPrefix: "user:email:", - * sessionKeyPrefix: "user:session:", - * sessionByUserIdKeyPrefix: "user:session:by-user-id:", - * userKeyPrefix: "user:", - * verificationTokenKeyPrefix: "user:token:", - * authenticatorKeyPrefix: "authenticator:id:", - * authenticatorUserKeyPrefix: "authenticator:by-user-id:", - * } - * ``` - * - * 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. - * - * Example: - * - * ```js - * export default NextAuth({ - * adapter: UnstorageAdapter(storage, {baseKeyPrefix: "app2:"}) - * }) - * ``` - * - * ### Using getItemRaw/setItemRaw instead of getItem/setItem - * - * If you are using storage that supports JSON, you can make it use `getItemRaw/setItemRaw` instead of `getItem/setItem`. - * - * This is an experimental feature. Please check [unjs/unstorage#142](https://github.com/unjs/unstorage/issues/142) for more information. - * - * You can enable this functionality by passing `useItemRaw: true` (default: false) in the `options` object as the second argument to the adapter factory function. - * - * ```js - * export default NextAuth({ - * adapter: UnstorageAdapter(storage, {useItemRaw: true}) - * }) - * ``` - * - */ export function UnstorageAdapter( storage: Storage, options: UnstorageAdapterOptions = {} diff --git a/packages/adapter-upstash-redis/src/index.ts b/packages/adapter-upstash-redis/src/index.ts index 6f044768a7..656b401ee2 100644 --- a/packages/adapter-upstash-redis/src/index.ts +++ b/packages/adapter-upstash-redis/src/index.ts @@ -1,6 +1,6 @@ /** *Official Upstash Redis adapter for Auth.js / NextAuth.js.
+ *Official Upstash Redis adapter for Auth.js / NextAuth.js.
* * * @@ -83,64 +83,6 @@ export function hydrateDates(json: object) { }, {} as any) } -/** - * ## Setup - * - * Configure Auth.js to use the Upstash Redis Adapter: - * - * ```js title="pages/api/auth/[...nextauth].js" - * import NextAuth from "next-auth" - * import GoogleProvider from "next-auth/providers/google" - * import { UpstashRedisAdapter } from "@auth/upstash-redis-adapter" - * import upstashRedisClient from "@upstash/redis" - * - * const redis = upstashRedisClient( - * process.env.UPSTASH_REDIS_URL, - * process.env.UPSTASH_REDIS_TOKEN - * ) - * - * export default NextAuth({ - * adapter: UpstashRedisAdapter(redis), - * providers: [ - * GoogleProvider({ - * clientId: process.env.GOOGLE_CLIENT_ID, - * clientSecret: process.env.GOOGLE_CLIENT_SECRET, - * }), - * ], - * }) - * ``` - * - * ## Advanced usage - * - * ### Using multiple apps with a single Upstash Redis instance - * - * The Upstash free-tier allows for only one Redis instance. If you have multiple Auth.js connected apps using this instance, you need different key prefixes for every app. - * - * You can change the prefixes by passing an `options` object as the second argument to the adapter factory function. - * - * The default values for this object are: - * - * ```js - * const defaultOptions = { - * baseKeyPrefix: "", - * accountKeyPrefix: "user:account:", - * accountByUserIdPrefix: "user:account:by-user-id:", - * emailKeyPrefix: "user:email:", - * sessionKeyPrefix: "user:session:", - * sessionByUserIdKeyPrefix: "user:session:by-user-id:", - * userKeyPrefix: "user:", - * verificationTokenKeyPrefix: "user:token:", - * } - * ``` - * - * 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. - * - * ```js - * export default NextAuth({ - * adapter: UpstashRedisAdapter(redis, {baseKeyPrefix: "app2:"}) - * }) - * ``` - */ export function UpstashRedisAdapter( client: Redis, options: UpstashRedisAdapterOptions = {} diff --git a/packages/adapter-xata/src/index.ts b/packages/adapter-xata/src/index.ts index 2f9a4640ba..09cd813b86 100644 --- a/packages/adapter-xata/src/index.ts +++ b/packages/adapter-xata/src/index.ts @@ -1,6 +1,6 @@ /** *Official Xata adapter for Auth.js / NextAuth.js.
+ *Official Xata adapter for Auth.js / NextAuth.js.
* * * @@ -30,222 +30,8 @@ */ import type { Adapter } from "@auth/core/adapters" - import type { XataClient } from "./xata" -/** - * ## Setup - * - * This adapter allows using Auth.js with Xata as a database to store users, sessions, and more. The preferred way to create a Xata project and use Xata databases is using the [Xata Command Line Interface (CLI)](https://docs.xata.io/cli/getting-started). - * - * The CLI allows generating a `XataClient` that will help you work with Xata in a safe way, and that this adapter depends on. - * - * When you're ready, let's create a new Xata project using our Auth.js schema that the Xata adapter can work with. To do that, copy and paste this schema file into your project's directory: - * - * ```json title="schema.json" - * { - * "tables": [ - * { - * "name": "nextauth_users", - * "columns": [ - * { - * "name": "email", - * "type": "email" - * }, - * { - * "name": "emailVerified", - * "type": "datetime" - * }, - * { - * "name": "name", - * "type": "string" - * }, - * { - * "name": "image", - * "type": "string" - * } - * ] - * }, - * { - * "name": "nextauth_accounts", - * "columns": [ - * { - * "name": "user", - * "type": "link", - * "link": { - * "table": "nextauth_users" - * } - * }, - * { - * "name": "type", - * "type": "string" - * }, - * { - * "name": "provider", - * "type": "string" - * }, - * { - * "name": "providerAccountId", - * "type": "string" - * }, - * { - * "name": "refresh_token", - * "type": "string" - * }, - * { - * "name": "access_token", - * "type": "string" - * }, - * { - * "name": "expires_at", - * "type": "int" - * }, - * { - * "name": "token_type", - * "type": "string" - * }, - * { - * "name": "scope", - * "type": "string" - * }, - * { - * "name": "id_token", - * "type": "text" - * }, - * { - * "name": "session_state", - * "type": "string" - * } - * ] - * }, - * { - * "name": "nextauth_verificationTokens", - * "columns": [ - * { - * "name": "identifier", - * "type": "string" - * }, - * { - * "name": "token", - * "type": "string" - * }, - * { - * "name": "expires", - * "type": "datetime" - * } - * ] - * }, - * { - * "name": "nextauth_users_accounts", - * "columns": [ - * { - * "name": "user", - * "type": "link", - * "link": { - * "table": "nextauth_users" - * } - * }, - * { - * "name": "account", - * "type": "link", - * "link": { - * "table": "nextauth_accounts" - * } - * } - * ] - * }, - * { - * "name": "nextauth_users_sessions", - * "columns": [ - * { - * "name": "user", - * "type": "link", - * "link": { - * "table": "nextauth_users" - * } - * }, - * { - * "name": "session", - * "type": "link", - * "link": { - * "table": "nextauth_sessions" - * } - * } - * ] - * }, - * { - * "name": "nextauth_sessions", - * "columns": [ - * { - * "name": "sessionToken", - * "type": "string" - * }, - * { - * "name": "expires", - * "type": "datetime" - * }, - * { - * "name": "user", - * "type": "link", - * "link": { - * "table": "nextauth_users" - * } - * } - * ] - * } - * ] - * } - * ``` - * - * Now, run the following command: - * - * ```bash - * xata init --schema=./path/to/your/schema.json - * ``` - * - * The CLI will walk you through a setup process where you choose a [workspace](https://xata.io/docs/api-reference/workspaces) (kind of like a GitHub org or a Vercel team) and an appropriate database. We recommend using a fresh database for this, as we'll augment it with tables that Auth.js needs. - * - * Once you're done, you can continue using Auth.js in your project as expected, like creating a `./pages/api/auth/[...nextauth]` route. - * - * ```ts title="pages/api/auth/[...nextauth].ts" - * import NextAuth from "next-auth" - * import GoogleProvider from "next-auth/providers/google" - * - * const client = new XataClient() - * - * export default NextAuth({ - * providers: [ - * GoogleProvider({ - * clientId: process.env.GOOGLE_CLIENT_ID, - * clientSecret: process.env.GOOGLE_CLIENT_SECRET, - * }), - * ], - * }) - * ``` - * - * Now to Xata-fy this route, let's add the Xata client and adapter: - * - * ```diff - * import NextAuth from "next-auth" - * import GoogleProvider from "next-auth/providers/google" - * + import { XataAdapter } from "@auth/xata-adapter" - * + import { XataClient } from "../../../xata" // or wherever you've chosen to create the client - * - * + const client = new XataClient() - * - * export default NextAuth({ - * + adapter: XataAdapter(client), - * providers: [ - * GoogleProvider({ - * clientId: process.env.GOOGLE_CLIENT_ID, - * clientSecret: process.env.GOOGLE_CLIENT_SECRET, - * }), - * ], - * }) - * ``` - * - * This fully sets up your Auth.js app to work with Xata. - */ export function XataAdapter(client: XataClient): Adapter { return { async createUser(user) { diff --git a/packages/core/test/e2e/basic-auth.spec.ts b/packages/core/test/e2e/basic-auth.spec.ts index fc33bf9559..681e082c9f 100644 --- a/packages/core/test/e2e/basic-auth.spec.ts +++ b/packages/core/test/e2e/basic-auth.spec.ts @@ -14,10 +14,6 @@ test.describe("Basic Auth", () => { user: { email: "test@example.com", name: "Test User", - sub: expect.any(String), - iat: expect.any(Number), - exp: expect.any(Number), - jti: expect.any(String), }, expires: expect.any(String), }) @@ -58,11 +54,7 @@ test.describe("Basic Auth", () => { user: { email: "bob@alice.com", name: "Bob Alice", - picture: "https://avatars.githubusercontent.com/u/67470890?s=200&v=4", - sub: expect.any(String), - iat: expect.any(Number), - exp: expect.any(Number), - jti: expect.any(String), + image: "https://avatars.githubusercontent.com/u/67470890?s=200&v=4", }, expires: expect.any(String), })