├── .gitignore ├── examples └── full-example │ ├── studio │ ├── plugins │ │ └── .gitkeep │ ├── config │ │ ├── @sanity │ │ │ ├── data-aspects.json │ │ │ ├── form-builder.json │ │ │ ├── default-layout.json │ │ │ └── default-login.json │ │ └── .checksums │ ├── static │ │ ├── .gitkeep │ │ └── favicon.ico │ ├── tsconfig.json │ ├── README.md │ ├── schemas │ │ ├── verification-token.ts │ │ ├── user.ts │ │ ├── schema.ts │ │ ├── account.ts │ │ └── schemaTypes.ts │ ├── sanity.json │ └── package.json │ ├── lerna.json │ ├── next.config.js │ ├── public │ ├── favicon.ico │ └── vercel.svg │ ├── .env.template │ ├── .vscode │ └── settings.json │ ├── src │ ├── app │ │ ├── api │ │ │ └── sanity │ │ │ │ └── signUp │ │ │ │ └── route.ts │ │ ├── layout.tsx │ │ └── app │ │ │ ├── page.tsx │ │ │ └── credentials │ │ │ └── page.tsx │ ├── lib │ │ └── sanity.ts │ ├── pages │ │ ├── _app.tsx │ │ ├── index.tsx │ │ ├── credentials.tsx │ │ └── api │ │ │ └── auth │ │ │ └── [...nextauth].ts │ └── components │ │ ├── Buttons.tsx │ │ └── SignUpForm.tsx │ ├── next-env.d.ts │ ├── .gitignore │ ├── package.json │ ├── tsconfig.json │ └── README.md ├── .github ├── FUNDING.yml ├── workflows │ ├── publish.yml │ └── tests.yml └── dependabot.yml ├── src ├── index.ts ├── queries.ts ├── client.ts ├── schemas.ts ├── credentials.ts └── adapter.ts ├── .npmignore ├── LICENSE ├── package.json ├── tsconfig.json ├── README.md └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | .env 4 | .next 5 | 6 | # misc 7 | .DS_Store 8 | *.pem -------------------------------------------------------------------------------- /examples/full-example/studio/plugins/.gitkeep: -------------------------------------------------------------------------------- 1 | User-specific packages can be placed here 2 | -------------------------------------------------------------------------------- /examples/full-example/studio/config/@sanity/data-aspects.json: -------------------------------------------------------------------------------- 1 | { 2 | "listOptions": {} 3 | } 4 | -------------------------------------------------------------------------------- /examples/full-example/lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "packages": ["studio"], 3 | "version": "0.0.0" 4 | } 5 | -------------------------------------------------------------------------------- /examples/full-example/next.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | module.exports = {}; 3 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: Fedeya 4 | buy_me_a_coffee: fedeya 5 | -------------------------------------------------------------------------------- /examples/full-example/studio/config/@sanity/form-builder.json: -------------------------------------------------------------------------------- 1 | { 2 | "images": { 3 | "directUploads": true 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /examples/full-example/studio/static/.gitkeep: -------------------------------------------------------------------------------- 1 | Files placed here will be served by the Sanity server under the `/static`-prefix 2 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export { SanityAdapter } from './adapter'; 2 | export { SanityCredentials, signUpHandler } from './credentials'; 3 | -------------------------------------------------------------------------------- /examples/full-example/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fedeya/next-auth-sanity/HEAD/examples/full-example/public/favicon.ico -------------------------------------------------------------------------------- /examples/full-example/.env.template: -------------------------------------------------------------------------------- 1 | SANITY_DATASET="" 2 | SANITY_PROJECT_ID="" 3 | SANITY_API_TOKEN="" 4 | GITHUB_CLIENT_ID="" 5 | GITHUB_CLIENT_SECRET="" -------------------------------------------------------------------------------- /examples/full-example/studio/config/@sanity/default-layout.json: -------------------------------------------------------------------------------- 1 | { 2 | "toolSwitcher": { 3 | "order": [], 4 | "hidden": [] 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /examples/full-example/studio/static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fedeya/next-auth-sanity/HEAD/examples/full-example/studio/static/favicon.ico -------------------------------------------------------------------------------- /examples/full-example/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "typescript.tsdk": "node_modules/typescript/lib", 3 | "typescript.enablePromptUseWorkspaceTsdk": true 4 | } -------------------------------------------------------------------------------- /examples/full-example/studio/config/@sanity/default-login.json: -------------------------------------------------------------------------------- 1 | { 2 | "providers": { 3 | "mode": "append", 4 | "redirectOnSingle": false, 5 | "entries": [] 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .*.swp 2 | ._* 3 | .DS_Store 4 | .git 5 | .gitignore 6 | .hg 7 | .npmignore 8 | .npmrc 9 | .lock-wscript 10 | .svn 11 | .wafpickle-* 12 | config.gypi 13 | CVS 14 | npm-debug.log 15 | /examples 16 | .github -------------------------------------------------------------------------------- /examples/full-example/src/app/api/sanity/signUp/route.ts: -------------------------------------------------------------------------------- 1 | 2 | import { signUpHandler } from 'next-auth-sanity'; 3 | import { client } from '@/lib/sanity'; 4 | 5 | const handler = signUpHandler(client); 6 | 7 | export { handler as POST }; -------------------------------------------------------------------------------- /examples/full-example/src/app/layout.tsx: -------------------------------------------------------------------------------- 1 | export default function RootLayout({ children }) { 2 | return ( 3 | 4 | 5 | 6 | {children} 7 | 8 | ); 9 | } 10 | -------------------------------------------------------------------------------- /examples/full-example/next-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | /// 4 | 5 | // NOTE: This file should not be edited 6 | // see https://nextjs.org/docs/basic-features/typescript for more information. 7 | -------------------------------------------------------------------------------- /examples/full-example/src/lib/sanity.ts: -------------------------------------------------------------------------------- 1 | import { createClient } from '@sanity/client'; 2 | 3 | export const client = createClient({ 4 | projectId: process.env.SANITY_PROJECT_ID, 5 | dataset: process.env.SANITY_DATASET, 6 | apiVersion: '2023-01-01', 7 | token: process.env.SANITY_API_TOKEN, 8 | useCdn: process.env.NODE_ENV === 'production' 9 | }); 10 | -------------------------------------------------------------------------------- /examples/full-example/src/pages/_app.tsx: -------------------------------------------------------------------------------- 1 | import type { FC } from 'react'; 2 | import type { AppProps } from 'next/app'; 3 | import { SessionProvider } from 'next-auth/react'; 4 | 5 | const MyApp: FC = ({ Component, pageProps }) => ( 6 | 7 | 8 | 9 | ); 10 | 11 | export default MyApp; 12 | -------------------------------------------------------------------------------- /examples/full-example/studio/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | // Note: This config is only used to help editors like VS Code understand/resolve 3 | // parts, the actual transpilation is done by babel. Any compiler configuration in 4 | // here will be ignored. 5 | "compilerOptions": { 6 | "outDir": "dist" 7 | }, 8 | "include": ["./node_modules/@sanity/base/types/**/*.ts", "./**/*.ts", "./**/*.tsx"] 9 | } 10 | -------------------------------------------------------------------------------- /examples/full-example/studio/config/.checksums: -------------------------------------------------------------------------------- 1 | { 2 | "#": "Used by Sanity to keep track of configuration file checksums, do not delete or modify!", 3 | "@sanity/default-layout": "bb034f391ba508a6ca8cd971967cbedeb131c4d19b17b28a0895f32db5d568ea", 4 | "@sanity/default-login": "6fb6d3800aa71346e1b84d95bbcaa287879456f2922372bb0294e30b968cd37f", 5 | "@sanity/form-builder": "b38478227ba5e22c91981da4b53436df22e48ff25238a55a973ed620be5068aa", 6 | "@sanity/data-aspects": "d199e2c199b3e26cd28b68dc84d7fc01c9186bf5089580f2e2446994d36b3cb6" 7 | } 8 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: Publish Package to npm 2 | on: 3 | release: 4 | types: [published] 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v3 10 | # Setup .npmrc file to publish to npm 11 | - uses: actions/setup-node@v3 12 | with: 13 | node-version: '16.x' 14 | registry-url: 'https://registry.npmjs.org' 15 | - run: yarn install --frozen-lockfile 16 | - run: npm publish 17 | env: 18 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} 19 | -------------------------------------------------------------------------------- /examples/full-example/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | 15 | # production 16 | /build 17 | 18 | # misc 19 | .DS_Store 20 | *.pem 21 | 22 | # debug 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | 27 | # local env files 28 | .env.local 29 | .env.development.local 30 | .env.test.local 31 | .env.production.local 32 | 33 | # vercel 34 | .vercel 35 | -------------------------------------------------------------------------------- /examples/full-example/src/components/Buttons.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | import { signIn, signOut } from 'next-auth/react'; 3 | import { useRouter } from 'next/navigation'; 4 | 5 | export const SignInButton = () => { 6 | return ; 7 | }; 8 | 9 | export const SignOutButton = () => { 10 | const router = useRouter(); 11 | 12 | const handleClick = async () => { 13 | await signOut({ redirect: false }); 14 | 15 | router.refresh(); 16 | }; 17 | 18 | return ; 19 | }; 20 | -------------------------------------------------------------------------------- /examples/full-example/studio/README.md: -------------------------------------------------------------------------------- 1 | # Sanity Clean Content Studio 2 | 3 | Congratulations, you have now installed the Sanity Content Studio, an open source real-time content editing environment connected to the Sanity backend. 4 | 5 | Now you can do the following things: 6 | 7 | - [Read “getting started” in the docs](https://www.sanity.io/docs/introduction/getting-started?utm_source=readme) 8 | - [Join the community Slack](https://slack.sanity.io/?utm_source=readme) 9 | - [Extend and build plugins](https://www.sanity.io/docs/content-studio/extending?utm_source=readme) 10 | -------------------------------------------------------------------------------- /examples/full-example/studio/schemas/verification-token.ts: -------------------------------------------------------------------------------- 1 | import { Document } from './schemaTypes'; 2 | 3 | export default { 4 | name: 'verification-token', 5 | title: 'Verification Token', 6 | type: 'document', 7 | fields: [ 8 | { 9 | name: 'identifier', 10 | title: 'Identifier', 11 | type: 'string' 12 | }, 13 | { 14 | name: 'token', 15 | title: 'Token', 16 | type: 'string' 17 | }, 18 | { 19 | name: 'expires', 20 | title: 'Expires', 21 | type: 'datetime' 22 | } 23 | ] 24 | }; 25 | -------------------------------------------------------------------------------- /.github/workflows/tests.yml: -------------------------------------------------------------------------------- 1 | name: Node.js CI 2 | on: 3 | push: 4 | branches: [ main ] 5 | pull_request: 6 | branches: [ main ] 7 | 8 | jobs: 9 | build: 10 | runs-on: ubuntu-latest 11 | 12 | strategy: 13 | matrix: 14 | node-version: [16.x, 18.x] 15 | 16 | steps: 17 | - uses: actions/checkout@v3 18 | 19 | - name: Use Node.js ${{ matrix.node-version }} 20 | uses: actions/setup-node@v3 21 | with: 22 | node-version: ${{ matrix.node-version }} 23 | - run: yarn install --frozen-lockfile 24 | - run: yarn build 25 | -------------------------------------------------------------------------------- /examples/full-example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "full-example", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start" 9 | }, 10 | "dependencies": { 11 | "@sanity/client": "^5.2.2", 12 | "next": "^13.4.3", 13 | "next-auth": "^4.20.1", 14 | "react": "^18.2.0", 15 | "react-dom": "^18.2.0" 16 | }, 17 | "devDependencies": { 18 | "@types/node": "^18.14.6", 19 | "@types/react": "^18.0.28", 20 | "lerna": "^3.22.1", 21 | "typescript": "^4.9.5" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /examples/full-example/src/app/app/page.tsx: -------------------------------------------------------------------------------- 1 | import { getServerSession } from 'next-auth/next'; 2 | import { authOptions } from '@/pages/api/auth/[...nextauth]'; 3 | import { SignInButton, SignOutButton } from '@/components/Buttons'; 4 | 5 | export default async function Home() { 6 | const session = await getServerSession(authOptions); 7 | 8 | if (session) { 9 | return ( 10 |
11 |

User: {session?.user?.name}

12 | 13 |
14 | ); 15 | } 16 | 17 | return ( 18 |
19 | 20 |
21 | ); 22 | } 23 | -------------------------------------------------------------------------------- /examples/full-example/src/pages/index.tsx: -------------------------------------------------------------------------------- 1 | import type { FC } from 'react'; 2 | import { useSession, signIn, signOut } from 'next-auth/react'; 3 | 4 | const Home: FC = () => { 5 | const { data, status } = useSession(); 6 | 7 | if (status === 'loading') return

Loading...

; 8 | 9 | if (data) { 10 | return ( 11 |
12 |

User: {data.user.name}

13 | 14 |
15 | ); 16 | } 17 | 18 | return ; 19 | }; 20 | 21 | export default Home; 22 | -------------------------------------------------------------------------------- /examples/full-example/studio/sanity.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "project": { 4 | "name": "next-auth-sanity" 5 | }, 6 | "api": { 7 | "projectId": "placeholder", 8 | "dataset": "production" 9 | }, 10 | "plugins": [ 11 | "@sanity/base", 12 | "@sanity/components", 13 | "@sanity/default-layout", 14 | "@sanity/default-login", 15 | "@sanity/desk-tool" 16 | ], 17 | "env": { 18 | "development": { 19 | "plugins": ["@sanity/vision"] 20 | } 21 | }, 22 | "parts": [ 23 | { 24 | "name": "part:@sanity/base/schema", 25 | "path": "./schemas/schema" 26 | } 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /examples/full-example/src/app/app/credentials/page.tsx: -------------------------------------------------------------------------------- 1 | import { getServerSession } from 'next-auth/next'; 2 | import SignUpForm from '@/components/SignUpForm'; 3 | import { SignOutButton } from '@/components/Buttons'; 4 | import { authOptions } from '@/pages/api/auth/[...nextauth]'; 5 | 6 | export default async function Credentials() { 7 | const session = await getServerSession(authOptions); 8 | 9 | return ( 10 |
11 | {session && ( 12 |
13 |

User: {session.user?.name}

14 | 15 |
16 | )} 17 |

Sign Up

18 | 19 | 20 |
21 | ); 22 | } 23 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "npm" # See documentation for possible values 9 | directory: "/" # Location of package manifests 10 | schedule: 11 | interval: "daily" 12 | allow: 13 | - dependency-name: "next-auth" 14 | - dependency-name: "@sanity/client" 15 | versioning-strategy: increase -------------------------------------------------------------------------------- /examples/full-example/src/pages/credentials.tsx: -------------------------------------------------------------------------------- 1 | import type { FC } from 'react'; 2 | import { useSession } from 'next-auth/react'; 3 | import SignUpForm from '@/components/SignUpForm'; 4 | import { SignOutButton } from '@/components/Buttons'; 5 | 6 | const Credentials: FC = () => { 7 | const { data, status } = useSession(); 8 | 9 | if (status === 'loading') return

Loading...

; 10 | 11 | return ( 12 |
13 | {data && ( 14 |
15 |

User: {data?.user?.name}

16 | 17 |
18 | )} 19 |

Sign Up

20 | 21 | 22 |
23 | ); 24 | }; 25 | 26 | export default Credentials; 27 | -------------------------------------------------------------------------------- /examples/full-example/src/pages/api/auth/[...nextauth].ts: -------------------------------------------------------------------------------- 1 | import NextAuth, { NextAuthOptions } from 'next-auth'; 2 | import GitHub from 'next-auth/providers/github'; 3 | import { SanityAdapter, SanityCredentials } from 'next-auth-sanity'; 4 | import { client } from '@/lib/sanity'; 5 | 6 | export const authOptions: NextAuthOptions = { 7 | providers: [ 8 | GitHub({ 9 | clientId: process.env.GITHUB_CLIENT_ID!, 10 | clientSecret: process.env.GITHUB_CLIENT_SECRET! 11 | }), 12 | SanityCredentials(client) 13 | ], 14 | session: { 15 | strategy: 'jwt' 16 | }, 17 | secret: 'any-secret-word', 18 | adapter: SanityAdapter(client) 19 | }; 20 | 21 | export default NextAuth(authOptions); 22 | -------------------------------------------------------------------------------- /examples/full-example/studio/schemas/user.ts: -------------------------------------------------------------------------------- 1 | import { Document } from './schemaTypes'; 2 | 3 | export default { 4 | name: 'user', 5 | title: 'User', 6 | type: 'document', 7 | fields: [ 8 | { 9 | name: 'name', 10 | title: 'Name', 11 | type: 'string' 12 | }, 13 | { 14 | name: 'email', 15 | title: 'Email', 16 | type: 'string' 17 | }, 18 | { 19 | name: 'image', 20 | title: 'Image', 21 | type: 'url' 22 | }, 23 | { 24 | name: 'password', 25 | type: 'string', 26 | hidden: true 27 | }, 28 | { 29 | name: 'emailVerified', 30 | type: 'datetime', 31 | hidden: true, 32 | } 33 | ] 34 | }; 35 | -------------------------------------------------------------------------------- /src/queries.ts: -------------------------------------------------------------------------------- 1 | import groq from 'groq'; 2 | 3 | export const getUserByIdQuery = groq` 4 | *[_type == $userSchema && _id == $id][0] 5 | `; 6 | 7 | export const getUserByProviderAccountIdQuery = groq` 8 | *[_type == $accountSchema && providerId == $providerId && providerAccountId == $providerAccountId] { 9 | accessToken, 10 | accessTokenExpires, 11 | providerId, 12 | providerType, 13 | providerAccountId, 14 | user-> 15 | }[0] 16 | `; 17 | 18 | export const getUserByEmailQuery = groq` 19 | *[_type == $userSchema && email == $email][0] 20 | `; 21 | 22 | export const getVerificationTokenQuery = groq` 23 | *[_type == $verificationTokenSchema && identifier == $identifier && token == $token][0] 24 | `; 25 | -------------------------------------------------------------------------------- /examples/full-example/studio/schemas/schema.ts: -------------------------------------------------------------------------------- 1 | // First, we must import the schema creator 2 | import createSchema from 'part:@sanity/base/schema-creator'; 3 | 4 | // Then import schema types from any plugins that might expose them 5 | import schemaTypes from 'all:part:@sanity/base/schema-type'; 6 | import { user, account, verificationToken } from '../../../../dist/schemas'; 7 | 8 | // Then we give our schema to the builder and provide the result to Sanity 9 | export default createSchema({ 10 | // We name our schema 11 | name: 'default', 12 | // Then proceed to concatenate our document type 13 | // to the ones provided by any plugins that are installed 14 | types: schemaTypes.concat([ 15 | /* Your types here! */ 16 | user, 17 | account, 18 | verificationToken 19 | ]) 20 | }); 21 | -------------------------------------------------------------------------------- /examples/full-example/studio/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nextauthsanity", 3 | "private": true, 4 | "version": "1.0.0", 5 | "description": "", 6 | "main": "package.json", 7 | "author": "Federico Minaya ", 8 | "license": "UNLICENSED", 9 | "scripts": { 10 | "start": "sanity start", 11 | "build": "sanity build" 12 | }, 13 | "keywords": [ 14 | "sanity" 15 | ], 16 | "dependencies": { 17 | "@sanity/base": "^2.8.1", 18 | "@sanity/components": "^2.2.6", 19 | "@sanity/core": "^2.8.0", 20 | "@sanity/default-layout": "^2.8.1", 21 | "@sanity/default-login": "^2.8.0", 22 | "@sanity/desk-tool": "^2.8.1", 23 | "@sanity/vision": "^2.8.0", 24 | "prop-types": "^15.7", 25 | "react": "^17.0", 26 | "react-dom": "^17.0" 27 | }, 28 | "devDependencies": {} 29 | } 30 | -------------------------------------------------------------------------------- /src/client.ts: -------------------------------------------------------------------------------- 1 | import type { User } from 'next-auth'; 2 | 3 | export type SignUpPayload = { 4 | email: string; 5 | password: string; 6 | name?: string; 7 | image?: string; 8 | } & Record; 9 | 10 | export const signUp = async (payload: SignUpPayload): Promise => { 11 | const res = await fetch('/api/sanity/signUp', { 12 | method: 'POST', 13 | body: JSON.stringify(payload), 14 | headers: { 15 | 'Content-Type': 'application/json; charset=UTF-8' 16 | } 17 | }); 18 | 19 | if (!res.ok) { 20 | const isJson = res.headers 21 | .get('Content-Type') 22 | ?.includes('application/json'); 23 | 24 | const data = isJson ? await res.json() : await res.text(); 25 | 26 | throw new Error(data); 27 | } 28 | 29 | const user = await res.json(); 30 | 31 | return user; 32 | }; 33 | -------------------------------------------------------------------------------- /examples/full-example/studio/schemas/account.ts: -------------------------------------------------------------------------------- 1 | import { Document } from './schemaTypes'; 2 | 3 | export default { 4 | name: 'account', 5 | title: 'Account', 6 | type: 'document', 7 | fields: [ 8 | { 9 | name: 'providerType', 10 | type: 'string' 11 | }, 12 | { 13 | name: 'providerId', 14 | type: 'string' 15 | }, 16 | { 17 | name: 'providerAccountId', 18 | type: 'string' 19 | }, 20 | { 21 | name: 'refreshToken', 22 | type: 'string' 23 | }, 24 | { 25 | name: 'accessToken', 26 | type: 'string' 27 | }, 28 | { 29 | name: 'accessTokenExpires', 30 | type: 'number' 31 | }, 32 | { 33 | name: 'user', 34 | title: 'User', 35 | type: 'reference', 36 | to: { type: 'user' } 37 | } 38 | ] 39 | }; 40 | -------------------------------------------------------------------------------- /examples/full-example/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": [ 5 | "dom", 6 | "dom.iterable", 7 | "esnext" 8 | ], 9 | "allowJs": true, 10 | "skipLibCheck": true, 11 | "strict": false, 12 | "forceConsistentCasingInFileNames": true, 13 | "noEmit": true, 14 | "esModuleInterop": true, 15 | "module": "esnext", 16 | "moduleResolution": "node", 17 | "resolveJsonModule": true, 18 | "isolatedModules": true, 19 | "baseUrl": "./src", 20 | "paths": { 21 | "@/*": [ 22 | "./*" 23 | ] 24 | }, 25 | "jsx": "preserve", 26 | "incremental": true, 27 | "plugins": [ 28 | { 29 | "name": "next" 30 | } 31 | ], 32 | "strictNullChecks": true 33 | }, 34 | "include": [ 35 | "next-env.d.ts", 36 | "**/*.ts", 37 | "**/*.tsx", 38 | ".next/types/**/*.ts" 39 | ], 40 | "exclude": [ 41 | "node_modules" 42 | ] 43 | } 44 | -------------------------------------------------------------------------------- /examples/full-example/public/vercel.svg: -------------------------------------------------------------------------------- 1 | 3 | 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Federico Minaya 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /examples/full-example/README.md: -------------------------------------------------------------------------------- 1 | This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app). 2 | 3 | ## Getting Started 4 | 5 | First, run the development server: 6 | 7 | ```bash 8 | npm run dev 9 | # or 10 | yarn dev 11 | ``` 12 | 13 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. 14 | 15 | You can start editing the page by modifying `pages/index.js`. The page auto-updates as you edit the file. 16 | 17 | [API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.js`. 18 | 19 | The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages. 20 | 21 | ## Learn More 22 | 23 | To learn more about Next.js, take a look at the following resources: 24 | 25 | - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. 26 | - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. 27 | 28 | You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome! 29 | 30 | ## Deploy on Vercel 31 | 32 | The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. 33 | 34 | Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. 35 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "next-auth-sanity", 3 | "description": "NextAuth Adapter for Sanity", 4 | "version": "1.5.3", 5 | "main": "index.js", 6 | "types": "index.d.ts", 7 | "sideEffects": false, 8 | "repository": { 9 | "type": "git", 10 | "url": "git+https://github.com/Fedeya/next-auth-sanity.git" 11 | }, 12 | "author": "Fedeya ", 13 | "license": "MIT", 14 | "private": false, 15 | "files": [ 16 | "index.js", 17 | "index.d.ts", 18 | "queries.js", 19 | "queries.d.ts", 20 | "adapter.js", 21 | "adapter.d.ts", 22 | "client.js", 23 | "client.d.ts", 24 | "schemas.js", 25 | "schemas.d.ts", 26 | "credentials.js", 27 | "credentials.d.ts" 28 | ], 29 | "keywords": [ 30 | "next-auth", 31 | "oauth", 32 | "sanity", 33 | "next-auth-sanity" 34 | ], 35 | "scripts": { 36 | "build": "tsc", 37 | "dev": "tsc -w", 38 | "clean": "rm -rf index.js index.d.ts queries.js queries.ts queries.d.ts adapter.js adapter.ts adapter.d.ts client.js client.ts client.d.ts schemas.js schemas.ts schemas.d.ts credentials.js credentials.ts credentials.d.ts", 39 | "prepublishOnly": "yarn build", 40 | "postpublish": "yarn clean" 41 | }, 42 | "devDependencies": { 43 | "@sanity/client": "^6.4.8", 44 | "@types/lru-cache": "^5.1.0", 45 | "@types/node": "^14.14.41", 46 | "next-auth": "^4.22.1", 47 | "typescript": "^4.2.4" 48 | }, 49 | "dependencies": { 50 | "@sanity/uuid": "^3.0.1", 51 | "argon2": "^0.30.3", 52 | "groq": "^2.2.6" 53 | }, 54 | "peerDependencies": { 55 | "@sanity/client": "^6.4.8", 56 | "next-auth": "^4.22.1" 57 | }, 58 | "bugs": { 59 | "url": "https://github.com/Fedeya/next-auth-sanity/issues" 60 | }, 61 | "homepage": "https://github.com/Fedeya/next-auth-sanity#readme" 62 | } 63 | -------------------------------------------------------------------------------- /src/schemas.ts: -------------------------------------------------------------------------------- 1 | export const user = { 2 | name: 'user', 3 | title: 'User', 4 | type: 'document', 5 | fields: [ 6 | { 7 | name: 'name', 8 | title: 'Name', 9 | type: 'string' 10 | }, 11 | { 12 | name: 'email', 13 | title: 'Email', 14 | type: 'string' 15 | }, 16 | { 17 | name: 'image', 18 | title: 'Image', 19 | type: 'url' 20 | }, 21 | { 22 | name: 'password', 23 | type: 'string', 24 | hidden: true 25 | }, 26 | { 27 | name: 'emailVerified', 28 | type: 'datetime', 29 | hidden: true, 30 | } 31 | ] 32 | }; 33 | 34 | export const account = { 35 | name: 'account', 36 | title: 'Account', 37 | type: 'document', 38 | fields: [ 39 | { 40 | name: 'providerType', 41 | type: 'string' 42 | }, 43 | { 44 | name: 'providerId', 45 | type: 'string' 46 | }, 47 | { 48 | name: 'providerAccountId', 49 | type: 'string' 50 | }, 51 | { 52 | name: 'refreshToken', 53 | type: 'string' 54 | }, 55 | { 56 | name: 'accessToken', 57 | type: 'string' 58 | }, 59 | { 60 | name: 'accessTokenExpires', 61 | type: 'number' 62 | }, 63 | { 64 | name: 'user', 65 | title: 'User', 66 | type: 'reference', 67 | to: { type: 'user' } 68 | } 69 | ] 70 | }; 71 | 72 | export const verificationToken = { 73 | name: 'verification-token', 74 | title: 'Verification Token', 75 | type: 'document', 76 | fields: [ 77 | { 78 | name: 'identifier', 79 | title: 'Identifier', 80 | type: 'string', 81 | }, 82 | { 83 | name: 'token', 84 | title: 'Token', 85 | type: 'string', 86 | }, 87 | { 88 | name: 'expires', 89 | title: 'Expires', 90 | type: 'datetime', 91 | }, 92 | ], 93 | }; 94 | -------------------------------------------------------------------------------- /examples/full-example/src/components/SignUpForm.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | import { useState } from 'react'; 3 | import { signIn } from 'next-auth/react'; 4 | import { signUp } from 'next-auth-sanity/client'; 5 | import { useRouter } from 'next/navigation'; 6 | 7 | export default function SignUpForm() { 8 | const [email, setEmail] = useState(''); 9 | const [password, setPassword] = useState(''); 10 | const [name, setName] = useState(''); 11 | const router = useRouter(); 12 | 13 | const handleSubmit = async (e: React.FormEvent) => { 14 | e.preventDefault(); 15 | 16 | await signUp({ 17 | email, 18 | password, 19 | name 20 | }); 21 | 22 | await signIn('sanity-login', { 23 | redirect: false, 24 | email, 25 | password 26 | }); 27 | 28 | router.refresh(); 29 | }; 30 | 31 | const handleSubmitSignIn = async (e: React.FormEvent) => { 32 | e.preventDefault(); 33 | 34 | await signIn('sanity-login', { 35 | redirect: false, 36 | email, 37 | password 38 | }); 39 | 40 | router.refresh(); 41 | }; 42 | 43 | return ( 44 |
45 |
46 | setEmail(e.target.value)} 51 | /> 52 | setPassword(e.target.value)} 57 | /> 58 | setName(e.target.value)} 63 | /> 64 | 65 |
66 | 67 |

Sign In

68 |
69 | setEmail(e.target.value)} 74 | /> 75 | setPassword(e.target.value)} 80 | /> 81 | 82 |
83 |
84 | ); 85 | } 86 | -------------------------------------------------------------------------------- /src/credentials.ts: -------------------------------------------------------------------------------- 1 | import type { CredentialsConfig } from 'next-auth/providers'; 2 | import Credentials from 'next-auth/providers/credentials'; 3 | import type { SanityClient } from '@sanity/client'; 4 | import { getUserByEmailQuery } from './queries'; 5 | import { uuid } from '@sanity/uuid'; 6 | import argon2 from 'argon2'; 7 | 8 | export const signUpHandler = 9 | (client: SanityClient, userSchema: string = 'user') => 10 | async (req: any, res: any) => { 11 | const isEdge = req instanceof Request; 12 | 13 | const body = isEdge ? await req.json() : req.body; 14 | 15 | const { email, password, name, image, ...userData } = body; 16 | 17 | const user = await client.fetch(getUserByEmailQuery, { 18 | userSchema, 19 | email 20 | }); 21 | 22 | if (user) { 23 | const response = { error: 'User already exist' }; 24 | 25 | if (isEdge) { 26 | return new Response(JSON.stringify(response), { 27 | headers: { 28 | 'Content-Type': 'application/json' 29 | }, 30 | status: 400 31 | }); 32 | } 33 | 34 | res.json(response); 35 | return; 36 | } 37 | 38 | const { password: _, ...newUser } = await client.create({ 39 | _id: `user.${uuid()}`, 40 | _type: userSchema, 41 | email, 42 | password: await argon2.hash(password), 43 | name, 44 | image, 45 | ...userData 46 | }); 47 | 48 | if (isEdge) { 49 | return new Response(JSON.stringify(newUser), { 50 | headers: { 51 | 'Content-Type': 'application/json' 52 | }, 53 | status: 200 54 | }); 55 | } 56 | 57 | res.json({ 58 | id: newUser._id, 59 | ...newUser 60 | }); 61 | }; 62 | 63 | export const SanityCredentials = ( 64 | client: SanityClient, 65 | userSchema = 'user' 66 | ): CredentialsConfig => 67 | Credentials({ 68 | name: 'Credentials', 69 | id: 'sanity-login', 70 | type: 'credentials', 71 | credentials: { 72 | email: { 73 | label: 'Email', 74 | type: 'text' 75 | }, 76 | password: { 77 | label: 'Password', 78 | type: 'password' 79 | } 80 | }, 81 | async authorize(credentials) { 82 | const response = await client.fetch(getUserByEmailQuery, { 83 | userSchema, 84 | email: credentials?.email 85 | }); 86 | 87 | if (!response) throw new Error('Email does not exist'); 88 | 89 | const { _id, ...user } = response; 90 | 91 | if (await argon2.verify(user.password, credentials?.password!)) { 92 | return { 93 | id: _id, 94 | ...user 95 | }; 96 | } 97 | 98 | throw new Error('Password Invalid'); 99 | } 100 | }); 101 | -------------------------------------------------------------------------------- /examples/full-example/studio/schemas/schemaTypes.ts: -------------------------------------------------------------------------------- 1 | import { ReactElement } from 'react'; 2 | import { ReactComponentLike } from 'prop-types'; 3 | 4 | type Meta = { 5 | parent: { [key: string]: any }; 6 | path: string[]; 7 | document: { [key: string]: any }; 8 | }; 9 | 10 | type CustomRuleCallback = ( 11 | field: any, 12 | meta: Meta 13 | ) => true | string | Promise; 14 | 15 | export type RuleType = { 16 | required: () => RuleType; 17 | custom: (cb: CustomRuleCallback) => RuleType; 18 | min: (min: number) => RuleType; 19 | max: (max: number) => RuleType; 20 | length: (exactLength: number) => RuleType; 21 | greaterThan: (gt: number) => RuleType; 22 | uri: (options: { scheme: string[] }) => RuleType; 23 | }; 24 | 25 | type Validation = (rule: RuleType) => RuleType; 26 | 27 | type CommonFieldProps = { 28 | name: string; 29 | type: string; 30 | title?: string; 31 | fieldset?: string; 32 | validation?: Validation; 33 | description?: string; 34 | hidden?: boolean; 35 | readOnly?: boolean; 36 | options?: { 37 | isHighlighted?: boolean; // is only available on fields within an image 38 | }; 39 | icon?: ReactComponentLike; // is only available for elements of which include a block 40 | }; 41 | 42 | export type StringField = CommonFieldProps & { 43 | options?: { 44 | list: { title: string; value: string }[]; 45 | layout?: string; 46 | }; 47 | }; 48 | 49 | type TextField = CommonFieldProps & { 50 | rows: number; 51 | }; 52 | 53 | export type Span = { 54 | _type: 'span'; 55 | text: string; 56 | }; 57 | 58 | export type BlockField = { 59 | _type: 'block'; 60 | styles: { 61 | title: string; 62 | value: string; 63 | blockEditor?: { 64 | render: ReactComponentLike; 65 | }; 66 | icon?: ReactComponentLike; 67 | }[]; 68 | children: (Field | Span)[]; 69 | }; 70 | 71 | type ArrayOf = 72 | | ObjectType 73 | | ReferenceField 74 | | ImageField 75 | | { type: string } 76 | | BlockField; 77 | 78 | export type ArrayField = CommonFieldProps & { 79 | name: string; 80 | of: ArrayOf[]; 81 | }; 82 | 83 | type FilterFunctionResult = { filter: string; filterParams?: string }; 84 | type FilterFunction = (args: { 85 | document: { [key: string]: any }; 86 | parentPath: string[]; 87 | parent: {}[]; 88 | }) => FilterFunctionResult; 89 | type ReferenceField = CommonFieldProps & { 90 | to: { type: string }[]; 91 | options: { 92 | filter: string | FilterFunction; 93 | filterParams?: { [key: string]: string }; 94 | }; 95 | }; 96 | 97 | type ImageField = CommonFieldProps & { 98 | options?: { 99 | hotspot?: boolean; 100 | }; 101 | }; 102 | 103 | export type Field = 104 | | CommonFieldProps 105 | | StringField 106 | | TextField 107 | | ArrayField 108 | | ReferenceField 109 | | ImageField 110 | | ObjectType 111 | | BlockField; 112 | 113 | type Preview = { 114 | select?: { [key: string]: string }; 115 | prepare?: (selection: { 116 | [key: string]: any; 117 | }) => { title?: string; subtitle?: string }; // eslint-disable-line @typescript-eslint/no-explicit-any 118 | component?: (props: PreviewProps) => ReactElement; 119 | }; 120 | 121 | type Fieldset = { 122 | name: string; 123 | title: string; 124 | options?: { collapsible: boolean; collapsed?: boolean }; 125 | }; 126 | 127 | export type ObjectType = { 128 | type: 'object'; 129 | title?: string; 130 | name: string; 131 | fields: Field[]; 132 | validation?: Validation; 133 | preview?: Preview; 134 | fieldsets?: Fieldset[]; 135 | description?: string; 136 | options?: { collapsible?: boolean; collapsed?: boolean }; 137 | }; 138 | 139 | export type Document = { 140 | type: 'document'; 141 | name: string; 142 | fields: Field[]; 143 | title?: string; 144 | validation?: Validation; 145 | preview?: Preview; 146 | fieldsets?: Fieldset[]; 147 | initialValue?: { [key: string]: any }; // eslint-disable-line @typescript-eslint/no-explicit-any 148 | orderings?: { 149 | name: string; 150 | title: string; 151 | by: { field: string; direction: string }[]; 152 | }[]; 153 | }; 154 | 155 | export type PreviewProps = { 156 | value: { 157 | [key: string]: any; 158 | }; 159 | }; 160 | 161 | export type Body2TextProps = { children: React.FunctionComponent }; 162 | -------------------------------------------------------------------------------- /src/adapter.ts: -------------------------------------------------------------------------------- 1 | import type { Adapter } from 'next-auth/adapters'; 2 | import { 3 | getUserByIdQuery, 4 | getUserByProviderAccountIdQuery, 5 | getUserByEmailQuery, 6 | getVerificationTokenQuery 7 | } from './queries'; 8 | import type { SanityClient } from '@sanity/client'; 9 | import { uuid } from '@sanity/uuid'; 10 | 11 | export function SanityAdapter( 12 | client: SanityClient, 13 | options = { 14 | schemas: { 15 | account: 'account', 16 | verificationToken: 'verification-token', 17 | user: 'user' 18 | } 19 | } 20 | ): Adapter { 21 | return { 22 | async createUser(profile) { 23 | const { emailVerified: tempEmailVerified, ...tempProfile } = profile; 24 | const { _id, emailVerified, ...user } = await client.create({ 25 | _id: `user.${uuid()}`, 26 | _type: options.schemas.user, 27 | emailVerified: 28 | tempEmailVerified === null ? undefined : tempEmailVerified, 29 | ...tempProfile 30 | }); 31 | 32 | return { 33 | id: _id, 34 | emailVerified: tempEmailVerified, 35 | ...user 36 | }; 37 | }, 38 | 39 | async getUser(id) { 40 | const user = await client.fetch(getUserByIdQuery, { 41 | userSchema: options.schemas.user, 42 | id 43 | }); 44 | 45 | if (!user) return null; 46 | 47 | return { 48 | id: user._id, 49 | ...user 50 | }; 51 | }, 52 | 53 | async linkAccount({ 54 | provider, 55 | providerAccountId, 56 | refresh_token, 57 | access_token, 58 | expires_at, 59 | userId, 60 | type 61 | }) { 62 | await client.create({ 63 | _type: options.schemas.account, 64 | providerId: provider, 65 | providerType: type, 66 | providerAccountId: `${providerAccountId}`, 67 | refreshToken: refresh_token, 68 | accessToken: access_token, 69 | accessTokenExpires: expires_at, 70 | user: { 71 | _type: 'reference', 72 | _ref: userId 73 | } 74 | }); 75 | }, 76 | 77 | async createSession() { 78 | return {} as any; 79 | }, 80 | 81 | async updateSession() { 82 | return {} as any; 83 | }, 84 | 85 | async deleteSession() {}, 86 | 87 | async updateUser(user) { 88 | const { id, emailVerified: tempEmailVerified, ...tempUser } = user; 89 | const { _id, emailVerified, ...newUser } = await client 90 | .patch(user.id!) 91 | .set({ 92 | emailVerified: 93 | tempEmailVerified === null ? undefined : tempEmailVerified, 94 | ...tempUser 95 | }) 96 | .commit(); 97 | 98 | return { 99 | id: _id, 100 | emailVerified: tempEmailVerified, 101 | ...(newUser as any) 102 | }; 103 | }, 104 | 105 | async getUserByEmail(email) { 106 | const user = await client.fetch(getUserByEmailQuery, { 107 | userSchema: options.schemas.user, 108 | email 109 | }); 110 | 111 | if (!user) return null; 112 | 113 | return { 114 | id: user._id, 115 | ...user 116 | }; 117 | }, 118 | 119 | async getUserByAccount({ provider, providerAccountId }) { 120 | const account = await client.fetch(getUserByProviderAccountIdQuery, { 121 | accountSchema: options.schemas.account, 122 | providerId: provider, 123 | providerAccountId 124 | }); 125 | 126 | if (!account) return null; 127 | 128 | return { 129 | id: account.user._id, 130 | ...account.user 131 | }; 132 | }, 133 | async getSessionAndUser() { 134 | return {} as any; 135 | }, 136 | 137 | async createVerificationToken({ identifier, token, expires }) { 138 | const verificationToken = await client.create({ 139 | _type: options.schemas.verificationToken, 140 | identifier, 141 | token, 142 | expires 143 | }); 144 | 145 | return verificationToken; 146 | }, 147 | 148 | async useVerificationToken({ identifier, token }) { 149 | const verificationToken = await client.fetch(getVerificationTokenQuery, { 150 | verificationTokenSchema: options.schemas.verificationToken, 151 | identifier, 152 | token 153 | }); 154 | 155 | if (!verificationToken) return null; 156 | 157 | await client.delete(verificationToken._id); 158 | 159 | return { 160 | id: verificationToken._id, 161 | ...verificationToken 162 | }; 163 | } 164 | }; 165 | } 166 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Visit https://aka.ms/tsconfig.json to read more about this file */ 4 | 5 | /* Basic Options */ 6 | // "incremental": true /* Enable incremental compilation */, 7 | "target": "ES2018" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */, 8 | "module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */, 9 | // "lib": [], /* Specify library files to be included in the compilation. */ 10 | "allowJs": true /* Allow javascript files to be compiled. */, 11 | // "checkJs": true, /* Report errors in .js files. */ 12 | // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */ 13 | "declaration": true /* Generates corresponding '.d.ts' file. */, 14 | // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ 15 | // "sourceMap": true, /* Generates corresponding '.map' file. */ 16 | // "outFile": "./", /* Concatenate and emit output to single file. */ 17 | "outDir": "." /* Redirect output structure to the directory. */, 18 | "rootDir": "./src" /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */, 19 | // "composite": true, /* Enable project compilation */ 20 | // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ 21 | // "removeComments": true, /* Do not emit comments to output. */ 22 | // "noEmit": true, /* Do not emit outputs. */ 23 | // "importHelpers": true, /* Import emit helpers from 'tslib'. */ 24 | // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ 25 | // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ 26 | 27 | /* Strict Type-Checking Options */ 28 | "strict": true /* Enable all strict type-checking options. */, 29 | // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ 30 | // "strictNullChecks": true, /* Enable strict null checks. */ 31 | // "strictFunctionTypes": true, /* Enable strict checking of function types. */ 32 | // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ 33 | // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ 34 | // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ 35 | // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ 36 | 37 | /* Additional Checks */ 38 | // "noUnusedLocals": true, /* Report errors on unused locals. */ 39 | // "noUnusedParameters": true, /* Report errors on unused parameters. */ 40 | // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ 41 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ 42 | // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */ 43 | // "noPropertyAccessFromIndexSignature": true, /* Require undeclared properties from index signatures to use element accesses. */ 44 | 45 | /* Module Resolution Options */ 46 | "moduleResolution": "node" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */, 47 | // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ 48 | // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ 49 | // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ 50 | // "typeRoots": [], /* List of folders to include type definitions from. */ 51 | // "types": [], /* Type declaration files to be included in compilation. */ 52 | // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ 53 | "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */, 54 | // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ 55 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ 56 | 57 | /* Source Map Options */ 58 | // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ 59 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 60 | // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ 61 | // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ 62 | 63 | /* Experimental Options */ 64 | // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ 65 | // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ 66 | 67 | /* Advanced Options */ 68 | "skipLibCheck": true /* Skip type checking of declaration files. */, 69 | "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ 70 | }, 71 | "include": ["./src/**/*"], 72 | "exclude": ["./examples", "./dist"] 73 | } 74 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

Welcome to next-auth-sanity 👋

2 |

3 | 4 | Version 5 | 6 | 7 | npm 8 | 9 | 10 | License: MIT 11 | 12 |

13 | 14 | > NextAuth Adapter and Provider for Sanity 15 | 16 | ## Overview 17 | 18 | ### Features 19 | 20 | - Saving users and account in Sanity 21 | - Email Provider Support 22 | - Retrieving of full linked provider information for a user 23 | - Auth with Credentials 24 | - Hash Credentials Passwords with Argon2 25 | 26 | ### Database sessions 27 | 28 | Database sessions are not implemented, this adapter relies on usage of JSON Web Tokens for stateless session management. 29 | 30 | ### Privacy and user information 31 | 32 | Storing people's user credentials is always a big responsibility. Make sure you understand the risks and inform your users accordingly. This adapter store the user information with [the `_id` on the `user.` path](https://www.sanity.io/docs/ids#fdc25ada5db2). In other words, these documents can't be queried without authentication, even if your dataset is set to be public. That also means that these documents are available for everyone that's part of your Sanity project. 33 | 34 | ## Requirements 35 | 36 | - Sanity Token for Read+Write 37 | 38 | ## Installation 39 | 40 | ### yarn 41 | 42 | ```sh 43 | yarn add next-auth-sanity 44 | ``` 45 | 46 | ### npm 47 | 48 | ```sh 49 | npm i next-auth-sanity 50 | ``` 51 | 52 | ## Usage 53 | 54 | [Full Example](https://github.com/Fedeya/next-auth-sanity/tree/main/examples/full-example) 55 | 56 | ```ts 57 | import NextAuth, { NextAuthOptions } from 'next-auth'; 58 | import GitHub from 'next-auth/providers/github'; 59 | import { NextApiRequest, NextApiResponse } from 'next'; 60 | import { SanityAdapter, SanityCredentials } from 'next-auth-sanity'; 61 | import { client } from 'your/sanity/client'; 62 | 63 | const options: NextAuthOptions = { 64 | providers: [ 65 | GitHub({ 66 | clientId: process.env.GITHUB_CLIENT_ID, 67 | clientSecret: process.env.GITHUB_CLIENT_SECRET 68 | }), 69 | SanityCredentials(client) // only if you use sign in with credentials 70 | ], 71 | session: { 72 | strategy: 'jwt' 73 | }, 74 | adapter: SanityAdapter(client) 75 | }; 76 | 77 | export default NextAuth(options); 78 | ``` 79 | 80 | ### Sanity Schemas 81 | 82 | you can install this package in your studio project and use the schemas like this 83 | 84 | ```ts 85 | import createSchema from 'part:@sanity/base/schema-creator'; 86 | 87 | import schemaTypes from 'all:part:@sanity/base/schema-type'; 88 | import { user, account, verificationToken } from 'next-auth-sanity/schemas'; 89 | 90 | export default createSchema({ 91 | name: 'default', 92 | types: schemaTypes.concat([user, account, verificationToken]) 93 | }); 94 | ``` 95 | 96 |
97 | Or copy paste the schemas 98 | 99 | ```ts 100 | // user - required 101 | 102 | export default { 103 | name: 'user', 104 | title: 'User', 105 | type: 'document', 106 | fields: [ 107 | { 108 | name: 'name', 109 | title: 'Name', 110 | type: 'string' 111 | }, 112 | { 113 | name: 'email', 114 | title: 'Email', 115 | type: 'string' 116 | }, 117 | { 118 | name: 'image', 119 | title: 'Image', 120 | type: 'url' 121 | }, 122 | { 123 | // this is only if you use credentials provider 124 | name: 'password', 125 | type: 'string', 126 | hidden: true 127 | }, 128 | { 129 | name: 'emailVerified', 130 | type: 'datetime', 131 | hidden: true, 132 | } 133 | ] 134 | }; 135 | ``` 136 | 137 | ```ts 138 | // account - required 139 | 140 | export default { 141 | name: 'account', 142 | title: 'Account', 143 | type: 'document', 144 | fields: [ 145 | { 146 | name: 'providerType', 147 | type: 'string' 148 | }, 149 | { 150 | name: 'providerId', 151 | type: 'string' 152 | }, 153 | { 154 | name: 'providerAccountId', 155 | type: 'string' 156 | }, 157 | { 158 | name: 'refreshToken', 159 | type: 'string' 160 | }, 161 | { 162 | name: 'accessToken', 163 | type: 'string' 164 | }, 165 | { 166 | name: 'accessTokenExpires', 167 | type: 'number' 168 | }, 169 | { 170 | name: 'user', 171 | title: 'User', 172 | type: 'reference', 173 | to: { type: 'user' } 174 | } 175 | ] 176 | }; 177 | ``` 178 | 179 | ```ts 180 | // verification-token - only if you use email provider 181 | 182 | export default { 183 | name: 'verification-token', 184 | title: 'Verification Token', 185 | type: 'document', 186 | fields: [ 187 | { 188 | name: 'identifier', 189 | title: 'Identifier', 190 | type: 'string' 191 | }, 192 | { 193 | name: 'token', 194 | title: 'Token', 195 | type: 'string' 196 | }, 197 | { 198 | name: 'expires', 199 | title: 'Expires', 200 | type: 'datetime' 201 | } 202 | ] 203 | }; 204 | ``` 205 |
206 | 207 | ### Sign Up and Sign In With Credentials 208 | 209 | ### Setup 210 | 211 | `API Route` (with pages) 212 | 213 | ```ts 214 | // pages/api/sanity/signUp.ts 215 | import { signUpHandler } from 'next-auth-sanity'; 216 | import { client } from 'your/sanity/client'; 217 | 218 | export default signUpHandler(client); 219 | ``` 220 | 221 | `Route Handler` (with app directory) 222 | 223 | ```ts 224 | // app/api/sanity/signUp/route.ts 225 | import { signUpHandler } from 'next-auth-sanity'; 226 | import { client } from 'your/sanity/client'; 227 | 228 | export const POST = signUpHandler(client); 229 | ``` 230 | 231 | `Client` 232 | 233 | ```ts 234 | import { signUp } from 'next-auth-sanity/client'; 235 | import { signIn } from 'next-auth/react'; 236 | 237 | const user = await signUp({ 238 | email, 239 | password, 240 | name 241 | }); 242 | 243 | await signIn('sanity-login', { 244 | redirect: false, 245 | email, 246 | password 247 | }); 248 | ``` 249 | 250 | ## Custom Schemas 251 | if you want to use another schema or upgrade from previous version you can change the default schema used in the library, to do so you can pass a second argument to all methods with config 252 | ```ts 253 | SanityAdapter(client, { 254 | schemas: { 255 | verificationToken: 'verification-request', 256 | account: 'account', 257 | user: 'profile' 258 | } 259 | }) 260 | 261 | 262 | // the second argument is the name of the user schema 263 | // default: 'user' 264 | 265 | SanityCredentials(client, 'profile'); 266 | 267 | signUpHandler(client, 'profile'); 268 | ``` 269 | 270 | ## Author 271 | 272 | 👤 **Fedeya ** 273 | 274 | - Website: [fedeminaya.com](https://fedeminaya.com) 275 | - Twitter: [@fedeminaya](https://twitter.com/fedeminaya) 276 | - Github: [@Fedeya](https://github.com/Fedeya) 277 | - LinkedIn: [@federico-minaya](https://linkedin.com/in/federico-minaya) 278 | 279 | ## 🤝 Contributing 280 | 281 | Contributions, issues and feature requests are welcome!
Feel free to check [issues page](https://github.com/Fedeya/next-auth-sanity/issues). 282 | 283 | ## Show your support 284 | 285 | Give a ⭐️ if this project helped you! 286 | 287 | --- 288 | 289 | _This README was generated with ❤️ by [readme-md-generator](https://github.com/kefranabg/readme-md-generator)_ 290 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@babel/runtime@^7.20.13": 6 | version "7.21.0" 7 | resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.21.0.tgz#5b55c9d394e5fcf304909a8b00c07dc217b56673" 8 | integrity sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw== 9 | dependencies: 10 | regenerator-runtime "^0.13.11" 11 | 12 | "@mapbox/node-pre-gyp@^1.0.10": 13 | version "1.0.10" 14 | resolved "https://registry.yarnpkg.com/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.10.tgz#8e6735ccebbb1581e5a7e652244cadc8a844d03c" 15 | integrity sha512-4ySo4CjzStuprMwk35H5pPbkymjv1SF3jGLj6rAHp/xT/RF7TL7bd9CTm1xDY49K2qF7jmR/g7k+SkLETP6opA== 16 | dependencies: 17 | detect-libc "^2.0.0" 18 | https-proxy-agent "^5.0.0" 19 | make-dir "^3.1.0" 20 | node-fetch "^2.6.7" 21 | nopt "^5.0.0" 22 | npmlog "^5.0.1" 23 | rimraf "^3.0.2" 24 | semver "^7.3.5" 25 | tar "^6.1.11" 26 | 27 | "@panva/hkdf@^1.0.2": 28 | version "1.0.4" 29 | resolved "https://registry.yarnpkg.com/@panva/hkdf/-/hkdf-1.0.4.tgz#4e02bb248402ff6c5c024e23a68438e2b0e69d67" 30 | integrity sha512-003xWiCuvePbLaPHT+CRuaV4GlyCAVm6XYSbBZDHoWZGn1mNkVKFaDbGJjjxmEFvizUwlCoM6O18FCBMMky2zQ== 31 | 32 | "@phc/format@^1.0.0": 33 | version "1.0.0" 34 | resolved "https://registry.yarnpkg.com/@phc/format/-/format-1.0.0.tgz#b5627003b3216dc4362125b13f48a4daa76680e4" 35 | integrity sha512-m7X9U6BG2+J+R1lSOdCiITLLrxm+cWlNI3HUFA92oLO77ObGNzaKdh8pMLqdZcshtkKuV84olNNXDfMc4FezBQ== 36 | 37 | "@sanity/client@^6.4.8": 38 | version "6.4.8" 39 | resolved "https://registry.yarnpkg.com/@sanity/client/-/client-6.4.8.tgz#f64c80d764fa20b25f9504bcaacf5e4a128410e5" 40 | integrity sha512-uaxBiPszd3nNgAsk6jFM1s2VRJk77dm0pZ6G1j7I15NtKmYF6MgwMFCMLIpVj7w3A29UKytfuM01QnKYbK2FlQ== 41 | dependencies: 42 | "@sanity/eventsource" "^5.0.0" 43 | get-it "^8.4.3" 44 | rxjs "^7.0.0" 45 | 46 | "@sanity/eventsource@^5.0.0": 47 | version "5.0.0" 48 | resolved "https://registry.yarnpkg.com/@sanity/eventsource/-/eventsource-5.0.0.tgz#45410c8259e0bb80b4e308e1872846439590805a" 49 | integrity sha512-0ewT+BDzfiamHwitUfRcwsl/RREHjWv6VNZvQ8Q4OnnNKXfEEGXbWmqzof0okOTkp4XELgyliht4Qj28o9AU2g== 50 | dependencies: 51 | "@types/event-source-polyfill" "1.0.1" 52 | "@types/eventsource" "1.1.11" 53 | event-source-polyfill "1.0.31" 54 | eventsource "2.0.2" 55 | 56 | "@sanity/uuid@^3.0.1": 57 | version "3.0.1" 58 | resolved "https://registry.yarnpkg.com/@sanity/uuid/-/uuid-3.0.1.tgz#e688f5a1f909b3f2dea6f8d0ac922b64bb910234" 59 | integrity sha512-cfWq8l/M6TiDYlp2VYJR2MNdrl0u/lkYWjJVflLHsiGjG8SZKbbRSsfG1fn7rSvdZg+o/xfBlKCfhFTtEiXKJg== 60 | dependencies: 61 | "@types/uuid" "^8.0.0" 62 | uuid "^8.0.0" 63 | 64 | "@types/event-source-polyfill@1.0.1": 65 | version "1.0.1" 66 | resolved "https://registry.yarnpkg.com/@types/event-source-polyfill/-/event-source-polyfill-1.0.1.tgz#ffcb4ca17bc35bc1ca5d3e047fe833292bb73c32" 67 | integrity sha512-dls8b0lUgJ/miRApF0efboQ9QZnAm7ofTO6P1ILu8bRPxUFKDxVwFf8+TeuuErmNui6blpltyr7+eV72dbQXlQ== 68 | 69 | "@types/eventsource@1.1.11": 70 | version "1.1.11" 71 | resolved "https://registry.yarnpkg.com/@types/eventsource/-/eventsource-1.1.11.tgz#a2c0bfd0436b7db42ed1b2b2117f7ec2e8478dc7" 72 | integrity sha512-L7wLDZlWm5mROzv87W0ofIYeQP5K2UhoFnnUyEWLKM6UBb0ZNRgAqp98qE5DkgfBXdWfc2kYmw9KZm4NLjRbsw== 73 | 74 | "@types/lru-cache@^5.1.0": 75 | version "5.1.0" 76 | resolved "https://registry.yarnpkg.com/@types/lru-cache/-/lru-cache-5.1.0.tgz#57f228f2b80c046b4a1bd5cac031f81f207f4f03" 77 | integrity sha512-RaE0B+14ToE4l6UqdarKPnXwVDuigfFv+5j9Dze/Nqr23yyuqdNvzcZi3xB+3Agvi5R4EOgAksfv3lXX4vBt9w== 78 | 79 | "@types/node@^14.14.41": 80 | version "14.14.41" 81 | resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.41.tgz#d0b939d94c1d7bd53d04824af45f1139b8c45615" 82 | integrity sha512-dueRKfaJL4RTtSa7bWeTK1M+VH+Gns73oCgzvYfHZywRCoPSd8EkXBL0mZ9unPTveBn+D9phZBaxuzpwjWkW0g== 83 | 84 | "@types/uuid@^8.0.0": 85 | version "8.3.0" 86 | resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.0.tgz#215c231dff736d5ba92410e6d602050cce7e273f" 87 | integrity sha512-eQ9qFW/fhfGJF8WKHGEHZEyVWfZxrT+6CLIJGBcZPfxUh/+BnEj+UCGYMlr9qZuX/2AltsvwrGqp0LhEW8D0zQ== 88 | 89 | abbrev@1: 90 | version "1.1.1" 91 | resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" 92 | integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== 93 | 94 | agent-base@6: 95 | version "6.0.2" 96 | resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" 97 | integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== 98 | dependencies: 99 | debug "4" 100 | 101 | ansi-regex@^5.0.1: 102 | version "5.0.1" 103 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" 104 | integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== 105 | 106 | "aproba@^1.0.3 || ^2.0.0": 107 | version "2.0.0" 108 | resolved "https://registry.yarnpkg.com/aproba/-/aproba-2.0.0.tgz#52520b8ae5b569215b354efc0caa3fe1e45a8adc" 109 | integrity sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ== 110 | 111 | are-we-there-yet@^2.0.0: 112 | version "2.0.0" 113 | resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz#372e0e7bd279d8e94c653aaa1f67200884bf3e1c" 114 | integrity sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw== 115 | dependencies: 116 | delegates "^1.0.0" 117 | readable-stream "^3.6.0" 118 | 119 | argon2@^0.30.3: 120 | version "0.30.3" 121 | resolved "https://registry.yarnpkg.com/argon2/-/argon2-0.30.3.tgz#795ca57acad76fc67dd5695732662a03018b84ed" 122 | integrity sha512-DoH/kv8c9127ueJSBxAVJXinW9+EuPA3EMUxoV2sAY1qDE5H9BjTyVF/aD2XyHqbqUWabgBkIfcP3ZZuGhbJdg== 123 | dependencies: 124 | "@mapbox/node-pre-gyp" "^1.0.10" 125 | "@phc/format" "^1.0.0" 126 | node-addon-api "^5.0.0" 127 | 128 | balanced-match@^1.0.0: 129 | version "1.0.2" 130 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" 131 | integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== 132 | 133 | brace-expansion@^1.1.7: 134 | version "1.1.11" 135 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" 136 | integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== 137 | dependencies: 138 | balanced-match "^1.0.0" 139 | concat-map "0.0.1" 140 | 141 | chownr@^2.0.0: 142 | version "2.0.0" 143 | resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" 144 | integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== 145 | 146 | color-support@^1.1.2: 147 | version "1.1.3" 148 | resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" 149 | integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== 150 | 151 | concat-map@0.0.1: 152 | version "0.0.1" 153 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 154 | integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== 155 | 156 | console-control-strings@^1.0.0, console-control-strings@^1.1.0: 157 | version "1.1.0" 158 | resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" 159 | integrity sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ== 160 | 161 | cookie@^0.5.0: 162 | version "0.5.0" 163 | resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" 164 | integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== 165 | 166 | core-util-is@~1.0.0: 167 | version "1.0.2" 168 | resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" 169 | integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= 170 | 171 | debug@4, debug@^4.3.4: 172 | version "4.3.4" 173 | resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" 174 | integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== 175 | dependencies: 176 | ms "2.1.2" 177 | 178 | decompress-response@^7.0.0: 179 | version "7.0.0" 180 | resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-7.0.0.tgz#dc42107cc29a258aa8983fddc81c92351810f6fb" 181 | integrity sha512-6IvPrADQyyPGLpMnUh6kfKiqy7SrbXbjoUuZ90WMBJKErzv2pCiwlGEXjRX9/54OnTq+XFVnkOnOMzclLI5aEA== 182 | dependencies: 183 | mimic-response "^3.1.0" 184 | 185 | delegates@^1.0.0: 186 | version "1.0.0" 187 | resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" 188 | integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ== 189 | 190 | detect-libc@^2.0.0: 191 | version "2.0.1" 192 | resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.1.tgz#e1897aa88fa6ad197862937fbc0441ef352ee0cd" 193 | integrity sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w== 194 | 195 | emoji-regex@^8.0.0: 196 | version "8.0.0" 197 | resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" 198 | integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== 199 | 200 | event-source-polyfill@1.0.31: 201 | version "1.0.31" 202 | resolved "https://registry.yarnpkg.com/event-source-polyfill/-/event-source-polyfill-1.0.31.tgz#45fb0a6fc1375b2ba597361ba4287ffec5bf2e0c" 203 | integrity sha512-4IJSItgS/41IxN5UVAVuAyczwZF7ZIEsM1XAoUzIHA6A+xzusEZUutdXz2Nr+MQPLxfTiCvqE79/C8HT8fKFvA== 204 | 205 | eventsource@2.0.2: 206 | version "2.0.2" 207 | resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-2.0.2.tgz#76dfcc02930fb2ff339520b6d290da573a9e8508" 208 | integrity sha512-IzUmBGPR3+oUG9dUeXynyNmf91/3zUSJg1lCktzKw47OXuhco54U3r9B7O4XX+Rb1Itm9OZ2b0RkTs10bICOxA== 209 | 210 | follow-redirects@^1.15.2: 211 | version "1.15.2" 212 | resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" 213 | integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== 214 | 215 | from2@^2.3.0: 216 | version "2.3.0" 217 | resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" 218 | integrity sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g== 219 | dependencies: 220 | inherits "^2.0.1" 221 | readable-stream "^2.0.0" 222 | 223 | fs-minipass@^2.0.0: 224 | version "2.1.0" 225 | resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" 226 | integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== 227 | dependencies: 228 | minipass "^3.0.0" 229 | 230 | fs.realpath@^1.0.0: 231 | version "1.0.0" 232 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" 233 | integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== 234 | 235 | gauge@^3.0.0: 236 | version "3.0.2" 237 | resolved "https://registry.yarnpkg.com/gauge/-/gauge-3.0.2.tgz#03bf4441c044383908bcfa0656ad91803259b395" 238 | integrity sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q== 239 | dependencies: 240 | aproba "^1.0.3 || ^2.0.0" 241 | color-support "^1.1.2" 242 | console-control-strings "^1.0.0" 243 | has-unicode "^2.0.1" 244 | object-assign "^4.1.1" 245 | signal-exit "^3.0.0" 246 | string-width "^4.2.3" 247 | strip-ansi "^6.0.1" 248 | wide-align "^1.1.2" 249 | 250 | get-it@^8.4.3: 251 | version "8.4.3" 252 | resolved "https://registry.yarnpkg.com/get-it/-/get-it-8.4.3.tgz#f5d05fb95644c5414afa6f5dfd3a927820472f7f" 253 | integrity sha512-H9YbPCN3QCbxtojv42fvmrkIYe434qKg1nKpMMtBqwL8U3XprnHMgDbQwMJIxSIFOPpajQPf0BxhjsHoFI0cEQ== 254 | dependencies: 255 | debug "^4.3.4" 256 | decompress-response "^7.0.0" 257 | follow-redirects "^1.15.2" 258 | into-stream "^6.0.0" 259 | is-plain-object "^5.0.0" 260 | is-retry-allowed "^2.2.0" 261 | is-stream "^2.0.1" 262 | parse-headers "^2.0.5" 263 | progress-stream "^2.0.0" 264 | tunnel-agent "^0.6.0" 265 | 266 | glob@^7.1.3: 267 | version "7.2.3" 268 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" 269 | integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== 270 | dependencies: 271 | fs.realpath "^1.0.0" 272 | inflight "^1.0.4" 273 | inherits "2" 274 | minimatch "^3.1.1" 275 | once "^1.3.0" 276 | path-is-absolute "^1.0.0" 277 | 278 | groq@^2.2.6: 279 | version "2.2.6" 280 | resolved "https://registry.yarnpkg.com/groq/-/groq-2.2.6.tgz#8ec9f77b5beb5912c612b02e4beda1402a45e664" 281 | integrity sha512-UJ6zTwXYqp8PRrguMbYmBuFE+G4ZYdOeTT0qS1f35iQTb0ZfrbrzDiDRYk/N4ukuioAVjkLc8b0CECr1pk1uag== 282 | 283 | has-unicode@^2.0.1: 284 | version "2.0.1" 285 | resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" 286 | integrity sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ== 287 | 288 | https-proxy-agent@^5.0.0: 289 | version "5.0.1" 290 | resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" 291 | integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== 292 | dependencies: 293 | agent-base "6" 294 | debug "4" 295 | 296 | inflight@^1.0.4: 297 | version "1.0.6" 298 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" 299 | integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== 300 | dependencies: 301 | once "^1.3.0" 302 | wrappy "1" 303 | 304 | inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3: 305 | version "2.0.4" 306 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" 307 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== 308 | 309 | into-stream@^6.0.0: 310 | version "6.0.0" 311 | resolved "https://registry.yarnpkg.com/into-stream/-/into-stream-6.0.0.tgz#4bfc1244c0128224e18b8870e85b2de8e66c6702" 312 | integrity sha512-XHbaOAvP+uFKUFsOgoNPRjLkwB+I22JFPFe5OjTkQ0nwgj6+pSjb4NmB6VMxaPshLiOf+zcpOCBQuLwC1KHhZA== 313 | dependencies: 314 | from2 "^2.3.0" 315 | p-is-promise "^3.0.0" 316 | 317 | is-fullwidth-code-point@^3.0.0: 318 | version "3.0.0" 319 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" 320 | integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== 321 | 322 | is-plain-object@^5.0.0: 323 | version "5.0.0" 324 | resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344" 325 | integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q== 326 | 327 | is-retry-allowed@^2.2.0: 328 | version "2.2.0" 329 | resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-2.2.0.tgz#88f34cbd236e043e71b6932d09b0c65fb7b4d71d" 330 | integrity sha512-XVm7LOeLpTW4jV19QSH38vkswxoLud8sQ57YwJVTPWdiaI9I8keEhGFpBlslyVsgdQy4Opg8QOLb8YRgsyZiQg== 331 | 332 | is-stream@^2.0.1: 333 | version "2.0.1" 334 | resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" 335 | integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== 336 | 337 | isarray@~1.0.0: 338 | version "1.0.0" 339 | resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" 340 | integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= 341 | 342 | jose@^4.10.0, jose@^4.11.4: 343 | version "4.13.1" 344 | resolved "https://registry.yarnpkg.com/jose/-/jose-4.13.1.tgz#449111bb5ab171db85c03f1bd2cb1647ca06db1c" 345 | integrity sha512-MSJQC5vXco5Br38mzaQKiq9mwt7lwj2eXpgpRyQYNHYt2lq1PjkWa7DLXX0WVcQLE9HhMh3jPiufS7fhJf+CLQ== 346 | 347 | lru-cache@^6.0.0: 348 | version "6.0.0" 349 | resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" 350 | integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== 351 | dependencies: 352 | yallist "^4.0.0" 353 | 354 | make-dir@^3.1.0: 355 | version "3.1.0" 356 | resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" 357 | integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== 358 | dependencies: 359 | semver "^6.0.0" 360 | 361 | mimic-response@^3.1.0: 362 | version "3.1.0" 363 | resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" 364 | integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== 365 | 366 | minimatch@^3.1.1: 367 | version "3.1.2" 368 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" 369 | integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== 370 | dependencies: 371 | brace-expansion "^1.1.7" 372 | 373 | minipass@^3.0.0: 374 | version "3.3.6" 375 | resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.3.6.tgz#7bba384db3a1520d18c9c0e5251c3444e95dd94a" 376 | integrity sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw== 377 | dependencies: 378 | yallist "^4.0.0" 379 | 380 | minipass@^4.0.0: 381 | version "4.2.4" 382 | resolved "https://registry.yarnpkg.com/minipass/-/minipass-4.2.4.tgz#7d0d97434b6a19f59c5c3221698b48bbf3b2cd06" 383 | integrity sha512-lwycX3cBMTvcejsHITUgYj6Gy6A7Nh4Q6h9NP4sTHY1ccJlC7yKzDmiShEHsJ16Jf1nKGDEaiHxiltsJEvk0nQ== 384 | 385 | minizlib@^2.1.1: 386 | version "2.1.2" 387 | resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" 388 | integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== 389 | dependencies: 390 | minipass "^3.0.0" 391 | yallist "^4.0.0" 392 | 393 | mkdirp@^1.0.3: 394 | version "1.0.4" 395 | resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" 396 | integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== 397 | 398 | ms@2.1.2: 399 | version "2.1.2" 400 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" 401 | integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== 402 | 403 | next-auth@^4.22.1: 404 | version "4.22.1" 405 | resolved "https://registry.yarnpkg.com/next-auth/-/next-auth-4.22.1.tgz#1ea5084e38867966dc6492a71c6729c8f5cfa96b" 406 | integrity sha512-NTR3f6W7/AWXKw8GSsgSyQcDW6jkslZLH8AiZa5PQ09w1kR8uHtR9rez/E9gAq/o17+p0JYHE8QjF3RoniiObA== 407 | dependencies: 408 | "@babel/runtime" "^7.20.13" 409 | "@panva/hkdf" "^1.0.2" 410 | cookie "^0.5.0" 411 | jose "^4.11.4" 412 | oauth "^0.9.15" 413 | openid-client "^5.4.0" 414 | preact "^10.6.3" 415 | preact-render-to-string "^5.1.19" 416 | uuid "^8.3.2" 417 | 418 | node-addon-api@^5.0.0: 419 | version "5.1.0" 420 | resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-5.1.0.tgz#49da1ca055e109a23d537e9de43c09cca21eb762" 421 | integrity sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA== 422 | 423 | node-fetch@^2.6.7: 424 | version "2.6.9" 425 | resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.9.tgz#7c7f744b5cc6eb5fd404e0c7a9fec630a55657e6" 426 | integrity sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg== 427 | dependencies: 428 | whatwg-url "^5.0.0" 429 | 430 | nopt@^5.0.0: 431 | version "5.0.0" 432 | resolved "https://registry.yarnpkg.com/nopt/-/nopt-5.0.0.tgz#530942bb58a512fccafe53fe210f13a25355dc88" 433 | integrity sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ== 434 | dependencies: 435 | abbrev "1" 436 | 437 | npmlog@^5.0.1: 438 | version "5.0.1" 439 | resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-5.0.1.tgz#f06678e80e29419ad67ab964e0fa69959c1eb8b0" 440 | integrity sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw== 441 | dependencies: 442 | are-we-there-yet "^2.0.0" 443 | console-control-strings "^1.1.0" 444 | gauge "^3.0.0" 445 | set-blocking "^2.0.0" 446 | 447 | oauth@^0.9.15: 448 | version "0.9.15" 449 | resolved "https://registry.yarnpkg.com/oauth/-/oauth-0.9.15.tgz#bd1fefaf686c96b75475aed5196412ff60cfb9c1" 450 | integrity sha512-a5ERWK1kh38ExDEfoO6qUHJb32rd7aYmPHuyCu3Fta/cnICvYmgd2uhuKXvPD+PXB+gCEYYEaQdIRAjCOwAKNA== 451 | 452 | object-assign@^4.1.1: 453 | version "4.1.1" 454 | resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" 455 | integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== 456 | 457 | object-hash@^2.0.1: 458 | version "2.2.0" 459 | resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-2.2.0.tgz#5ad518581eefc443bd763472b8ff2e9c2c0d54a5" 460 | integrity sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw== 461 | 462 | oidc-token-hash@^5.0.1: 463 | version "5.0.1" 464 | resolved "https://registry.yarnpkg.com/oidc-token-hash/-/oidc-token-hash-5.0.1.tgz#ae6beec3ec20f0fd885e5400d175191d6e2f10c6" 465 | integrity sha512-EvoOtz6FIEBzE+9q253HsLCVRiK/0doEJ2HCvvqMQb3dHZrP3WlJKYtJ55CRTw4jmYomzH4wkPuCj/I3ZvpKxQ== 466 | 467 | once@^1.3.0: 468 | version "1.4.0" 469 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" 470 | integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== 471 | dependencies: 472 | wrappy "1" 473 | 474 | openid-client@^5.4.0: 475 | version "5.4.0" 476 | resolved "https://registry.yarnpkg.com/openid-client/-/openid-client-5.4.0.tgz#77f1cda14e2911446f16ea3f455fc7c405103eac" 477 | integrity sha512-hgJa2aQKcM2hn3eyVtN12tEA45ECjTJPXCgUh5YzTzy9qwapCvmDTVPWOcWVL0d34zeQoQ/hbG9lJhl3AYxJlQ== 478 | dependencies: 479 | jose "^4.10.0" 480 | lru-cache "^6.0.0" 481 | object-hash "^2.0.1" 482 | oidc-token-hash "^5.0.1" 483 | 484 | p-is-promise@^3.0.0: 485 | version "3.0.0" 486 | resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-3.0.0.tgz#58e78c7dfe2e163cf2a04ff869e7c1dba64a5971" 487 | integrity sha512-Wo8VsW4IRQSKVXsJCn7TomUaVtyfjVDn3nUP7kE967BQk0CwFpdbZs0X0uk5sW9mkBa9eNM7hCMaG93WUAwxYQ== 488 | 489 | parse-headers@^2.0.5: 490 | version "2.0.5" 491 | resolved "https://registry.yarnpkg.com/parse-headers/-/parse-headers-2.0.5.tgz#069793f9356a54008571eb7f9761153e6c770da9" 492 | integrity sha512-ft3iAoLOB/MlwbNXgzy43SWGP6sQki2jQvAyBg/zDFAgr9bfNWZIUj42Kw2eJIl8kEi4PbgE6U1Zau/HwI75HA== 493 | 494 | path-is-absolute@^1.0.0: 495 | version "1.0.1" 496 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" 497 | integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== 498 | 499 | preact-render-to-string@^5.1.19: 500 | version "5.2.6" 501 | resolved "https://registry.yarnpkg.com/preact-render-to-string/-/preact-render-to-string-5.2.6.tgz#0ff0c86cd118d30affb825193f18e92bd59d0604" 502 | integrity sha512-JyhErpYOvBV1hEPwIxc/fHWXPfnEGdRKxc8gFdAZ7XV4tlzyzG847XAyEZqoDnynP88akM4eaHcSOzNcLWFguw== 503 | dependencies: 504 | pretty-format "^3.8.0" 505 | 506 | preact@^10.6.3: 507 | version "10.13.0" 508 | resolved "https://registry.yarnpkg.com/preact/-/preact-10.13.0.tgz#f8bd3cf257a4dbe41da71a52131b79916d4ca89d" 509 | integrity sha512-ERdIdUpR6doqdaSIh80hvzebHB7O6JxycOhyzAeLEchqOq/4yueslQbfnPwXaNhAYacFTyCclhwkEbOumT0tHw== 510 | 511 | pretty-format@^3.8.0: 512 | version "3.8.0" 513 | resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-3.8.0.tgz#bfbed56d5e9a776645f4b1ff7aa1a3ac4fa3c385" 514 | integrity sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew== 515 | 516 | process-nextick-args@~2.0.0: 517 | version "2.0.1" 518 | resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" 519 | integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== 520 | 521 | progress-stream@^2.0.0: 522 | version "2.0.0" 523 | resolved "https://registry.yarnpkg.com/progress-stream/-/progress-stream-2.0.0.tgz#fac63a0b3d11deacbb0969abcc93b214bce19ed5" 524 | integrity sha512-xJwOWR46jcXUq6EH9yYyqp+I52skPySOeHfkxOZ2IY1AiBi/sFJhbhAKHoV3OTw/omQ45KTio9215dRJ2Yxd3Q== 525 | dependencies: 526 | speedometer "~1.0.0" 527 | through2 "~2.0.3" 528 | 529 | readable-stream@^2.0.0, readable-stream@~2.3.6: 530 | version "2.3.8" 531 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" 532 | integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== 533 | dependencies: 534 | core-util-is "~1.0.0" 535 | inherits "~2.0.3" 536 | isarray "~1.0.0" 537 | process-nextick-args "~2.0.0" 538 | safe-buffer "~5.1.1" 539 | string_decoder "~1.1.1" 540 | util-deprecate "~1.0.1" 541 | 542 | readable-stream@^3.6.0: 543 | version "3.6.1" 544 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.1.tgz#f9f9b5f536920253b3d26e7660e7da4ccff9bb62" 545 | integrity sha512-+rQmrWMYGA90yenhTYsLWAsLsqVC8osOw6PKE1HDYiO0gdPeKe/xDHNzIAIn4C91YQ6oenEhfYqqc1883qHbjQ== 546 | dependencies: 547 | inherits "^2.0.3" 548 | string_decoder "^1.1.1" 549 | util-deprecate "^1.0.1" 550 | 551 | regenerator-runtime@^0.13.11: 552 | version "0.13.11" 553 | resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" 554 | integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== 555 | 556 | rimraf@^3.0.2: 557 | version "3.0.2" 558 | resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" 559 | integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== 560 | dependencies: 561 | glob "^7.1.3" 562 | 563 | rxjs@^7.0.0: 564 | version "7.8.1" 565 | resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.1.tgz#6f6f3d99ea8044291efd92e7c7fcf562c4057543" 566 | integrity sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg== 567 | dependencies: 568 | tslib "^2.1.0" 569 | 570 | safe-buffer@^5.0.1, safe-buffer@~5.2.0: 571 | version "5.2.1" 572 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" 573 | integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== 574 | 575 | safe-buffer@~5.1.0, safe-buffer@~5.1.1: 576 | version "5.1.2" 577 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" 578 | integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== 579 | 580 | semver@^6.0.0: 581 | version "6.3.0" 582 | resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" 583 | integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== 584 | 585 | semver@^7.3.5: 586 | version "7.3.8" 587 | resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798" 588 | integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A== 589 | dependencies: 590 | lru-cache "^6.0.0" 591 | 592 | set-blocking@^2.0.0: 593 | version "2.0.0" 594 | resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" 595 | integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== 596 | 597 | signal-exit@^3.0.0: 598 | version "3.0.7" 599 | resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" 600 | integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== 601 | 602 | speedometer@~1.0.0: 603 | version "1.0.0" 604 | resolved "https://registry.yarnpkg.com/speedometer/-/speedometer-1.0.0.tgz#cd671cb06752c22bca3370e2f334440be4fc62e2" 605 | integrity sha512-lgxErLl/7A5+vgIIXsh9MbeukOaCb2axgQ+bKCdIE+ibNT4XNYGNCR1qFEGq6F+YDASXK3Fh/c5FgtZchFolxw== 606 | 607 | "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.2.3: 608 | version "4.2.3" 609 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" 610 | integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== 611 | dependencies: 612 | emoji-regex "^8.0.0" 613 | is-fullwidth-code-point "^3.0.0" 614 | strip-ansi "^6.0.1" 615 | 616 | string_decoder@^1.1.1: 617 | version "1.3.0" 618 | resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" 619 | integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== 620 | dependencies: 621 | safe-buffer "~5.2.0" 622 | 623 | string_decoder@~1.1.1: 624 | version "1.1.1" 625 | resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" 626 | integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== 627 | dependencies: 628 | safe-buffer "~5.1.0" 629 | 630 | strip-ansi@^6.0.1: 631 | version "6.0.1" 632 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" 633 | integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== 634 | dependencies: 635 | ansi-regex "^5.0.1" 636 | 637 | tar@^6.1.11: 638 | version "6.1.13" 639 | resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.13.tgz#46e22529000f612180601a6fe0680e7da508847b" 640 | integrity sha512-jdIBIN6LTIe2jqzay/2vtYLlBHa3JF42ot3h1dW8Q0PaAG4v8rm0cvpVePtau5C6OKXGGcgO9q2AMNSWxiLqKw== 641 | dependencies: 642 | chownr "^2.0.0" 643 | fs-minipass "^2.0.0" 644 | minipass "^4.0.0" 645 | minizlib "^2.1.1" 646 | mkdirp "^1.0.3" 647 | yallist "^4.0.0" 648 | 649 | through2@~2.0.3: 650 | version "2.0.5" 651 | resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" 652 | integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== 653 | dependencies: 654 | readable-stream "~2.3.6" 655 | xtend "~4.0.1" 656 | 657 | tr46@~0.0.3: 658 | version "0.0.3" 659 | resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" 660 | integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== 661 | 662 | tslib@^2.1.0: 663 | version "2.5.0" 664 | resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.0.tgz#42bfed86f5787aeb41d031866c8f402429e0fddf" 665 | integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg== 666 | 667 | tunnel-agent@^0.6.0: 668 | version "0.6.0" 669 | resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" 670 | integrity sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w== 671 | dependencies: 672 | safe-buffer "^5.0.1" 673 | 674 | typescript@^4.2.4: 675 | version "4.2.4" 676 | resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.2.4.tgz#8610b59747de028fda898a8aef0e103f156d0961" 677 | integrity sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg== 678 | 679 | util-deprecate@^1.0.1, util-deprecate@~1.0.1: 680 | version "1.0.2" 681 | resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" 682 | integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= 683 | 684 | uuid@^8.0.0, uuid@^8.3.2: 685 | version "8.3.2" 686 | resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" 687 | integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== 688 | 689 | webidl-conversions@^3.0.0: 690 | version "3.0.1" 691 | resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" 692 | integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== 693 | 694 | whatwg-url@^5.0.0: 695 | version "5.0.0" 696 | resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" 697 | integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== 698 | dependencies: 699 | tr46 "~0.0.3" 700 | webidl-conversions "^3.0.0" 701 | 702 | wide-align@^1.1.2: 703 | version "1.1.5" 704 | resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.5.tgz#df1d4c206854369ecf3c9a4898f1b23fbd9d15d3" 705 | integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg== 706 | dependencies: 707 | string-width "^1.0.2 || 2 || 3 || 4" 708 | 709 | wrappy@1: 710 | version "1.0.2" 711 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" 712 | integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== 713 | 714 | xtend@~4.0.1: 715 | version "4.0.2" 716 | resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" 717 | integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== 718 | 719 | yallist@^4.0.0: 720 | version "4.0.0" 721 | resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" 722 | integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== 723 | --------------------------------------------------------------------------------