import { Callout } from "nextra/components"
import { Code } from "@/components/Code"

<img align="right" src="/img/adapters/hasura.svg" width="64" height="64" />

# Hasura Adapter

## Resources

- [Hasura documentation](https://hasura.io/docs)

## Setup

### Installation

```bash npm2yarn
npm install @auth/hasura-adapter
```

### Environment variables

```sh
AUTH_HASURA_GRAPHQL=http://localhost:8000/graphql
AUTH_HASURA_SECRET=abc123
```

### Configuration

<Code>
<Code.Next>

```ts filename="./auth.ts"
import NextAuth from "next-auth"
import { HasuraAdapter } from "@auth/hasura-adapter"

export const { handlers, auth, signIn, signOut } = NextAuth({
  adapter: HasuraAdapter({
    endpoint: process.env.AUTH_HASURA_GRAPHQL,
    adminSecret: process.env.AUTH_HASURA_SECRET,
  }),
})
```

</Code.Next>
<Code.Qwik>

```ts filename="/src/routes/plugin@auth.ts"
import { QwikAuth$ } from "@auth/qwik"
import { HasuraAdapter } from "@auth/hasura-adapter"

export const { onRequest, useSession, useSignIn, useSignOut } = QwikAuth$(
  () => ({
    providers: [],
    adapter: HasuraAdapter({
      endpoint: import.meta.env.AUTH_HASURA_GRAPHQL,
      adminSecret: import.meta.env.AUTH_HASURA_SECRET,
    }),
  })
)
```

</Code.Qwik>
<Code.Svelte>

```ts filename="./auth.ts"
import { SvelteKitAuth } from "@auth/sveltekit"
import { HasuraAdapter } from "@auth/hasura-adapter"

export const { handle, signIn, signOut } = SvelteKitAuth({
  adapter: HasuraAdapter({
    endpoint: process.env.AUTH_HASURA_GRAPHQL,
    adminSecret: process.env.AUTH_HASURA_SECRET,
  }),
})
```

</Code.Svelte>
<Code.Express>

```ts filename="./src/routes/auth.route.ts"
import { ExpressAuth } from "@auth/express"
import { HasuraAdapter } from "@auth/hasura-adapter"

const app = express()

app.set("trust proxy", true)
app.use(
  "/auth/*",
  ExpressAuth({
    providers: [],
    adapter: HasuraAdapter({
      endpoint: process.env.AUTH_HASURA_GRAPHQL,
      adminSecret: process.env.AUTH_HASURA_SECRET,
    }),
  })
)
```

</Code.Express>
</Code>

### Migrations

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;
```

<Callout>
  Tips: [Track all the tables and relationships in
  Hasura](https://hasura.io/docs/latest/schema/postgres/using-existing-database/#step-1-track-tablesviews)
</Callout>
