From 9b6df05f4abb4879586b1c44b32073d43a6f4f7e Mon Sep 17 00:00:00 2001 From: vchikalkin Date: Tue, 24 Dec 2024 18:34:50 +0300 Subject: [PATCH] apps/web: add next-auth --- apps/web/app/(auth)/layout.tsx | 4 +- apps/web/app/(auth)/page.tsx | 32 ++++- apps/web/app/(main)/profile/page.tsx | 9 +- apps/web/app/api/auth/[...nextauth]/route.ts | 6 + apps/web/app/layout.tsx | 7 +- apps/web/components/telegram/index.ts | 1 - apps/web/config/auth.ts | 42 +++++++ apps/web/config/env.ts | 8 ++ apps/web/package.json | 6 +- apps/web/providers/auth.tsx | 6 + apps/web/providers/index.ts | 2 + .../Root.tsx => providers/telegram.tsx} | 4 +- apps/web/tsconfig.json | 3 +- apps/web/types/next-auth.d.ts | 10 ++ apps/web/utils/{ => telegram}/init.ts | 0 pnpm-lock.yaml | 117 ++++++++++++++++++ 16 files changed, 243 insertions(+), 14 deletions(-) create mode 100644 apps/web/app/api/auth/[...nextauth]/route.ts delete mode 100644 apps/web/components/telegram/index.ts create mode 100644 apps/web/config/auth.ts create mode 100644 apps/web/config/env.ts create mode 100644 apps/web/providers/auth.tsx create mode 100644 apps/web/providers/index.ts rename apps/web/{components/telegram/Root.tsx => providers/telegram.tsx} (89%) create mode 100644 apps/web/types/next-auth.d.ts rename apps/web/utils/{ => telegram}/init.ts (100%) diff --git a/apps/web/app/(auth)/layout.tsx b/apps/web/app/(auth)/layout.tsx index 44c2cb5..6225cd2 100644 --- a/apps/web/app/(auth)/layout.tsx +++ b/apps/web/app/(auth)/layout.tsx @@ -1,6 +1,6 @@ -import { Root as TelegramRoot } from '@/components/telegram'; +import { TelegramProvider } from '@/providers'; import { type PropsWithChildren } from 'react'; export default async function RootLayout({ children }: Readonly) { - return {children}; + return {children}; } diff --git a/apps/web/app/(auth)/page.tsx b/apps/web/app/(auth)/page.tsx index 076bbb4..32d357a 100644 --- a/apps/web/app/(auth)/page.tsx +++ b/apps/web/app/(auth)/page.tsx @@ -1,14 +1,42 @@ 'use client'; import { initData, isMiniAppDark, useSignal } from '@telegram-apps/sdk-react'; +import { signIn, useSession } from 'next-auth/react'; +import { redirect } from 'next/navigation'; +import { useEffect } from 'react'; export default function Auth() { const initDataState = useSignal(initData.state); const isDark = isMiniAppDark(); + const { data: session, status } = useSession(); + + useEffect(() => { + if (status === 'authenticated') { + redirect('/profile'); + } + + if (status === 'unauthenticated' && initDataState?.user?.id) { + signIn('telegram', { + callbackUrl: '/profile', + redirect: false, + telegramId: String(initDataState.user.id), + }); + } + }, [initDataState, status]); + + if (status === 'loading') { + return
Loading Auth...
; + } return (
- Hello, {initDataState?.user?.firstName}
- Dark: {JSON.stringify(isDark)} + {session ? ( +
+ Hello, {JSON.stringify(session)}
+ Dark: {JSON.stringify(isDark)} +
+ ) : ( +
Not authenticated
+ )}
); } diff --git a/apps/web/app/(main)/profile/page.tsx b/apps/web/app/(main)/profile/page.tsx index 5e54ed3..2e9ea4f 100644 --- a/apps/web/app/(main)/profile/page.tsx +++ b/apps/web/app/(main)/profile/page.tsx @@ -1,3 +1,8 @@ -export default function ProfilePage() { - return 'Profile'; +import { authOptions } from '@/config/auth'; +import { getServerSession } from 'next-auth/next'; + +export default async function ProfilePage() { + const session = await getServerSession(authOptions); + + return
{JSON.stringify(session, null, 2)}
; } diff --git a/apps/web/app/api/auth/[...nextauth]/route.ts b/apps/web/app/api/auth/[...nextauth]/route.ts new file mode 100644 index 0000000..1dfb0d9 --- /dev/null +++ b/apps/web/app/api/auth/[...nextauth]/route.ts @@ -0,0 +1,6 @@ +import { authOptions } from '@/config/auth'; +import NextAuth from 'next-auth'; + +const handler = NextAuth(authOptions); + +export { handler as GET, handler as POST }; diff --git a/apps/web/app/layout.tsx b/apps/web/app/layout.tsx index 4790ede..02fef8b 100644 --- a/apps/web/app/layout.tsx +++ b/apps/web/app/layout.tsx @@ -1,7 +1,8 @@ +import { AuthProvider } from '@/providers'; import { I18nProvider } from '@/utils/i18n/provider'; import { type Metadata } from 'next'; -import { getLocale } from 'next-intl/server'; import '@repo/ui/globals.css'; +import { getLocale } from 'next-intl/server'; import { type PropsWithChildren } from 'react'; export const metadata: Metadata = { @@ -15,7 +16,9 @@ export default async function RootLayout({ children }: Readonly - {children} + + {children} + ); diff --git a/apps/web/components/telegram/index.ts b/apps/web/components/telegram/index.ts deleted file mode 100644 index c78e011..0000000 --- a/apps/web/components/telegram/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './Root'; diff --git a/apps/web/config/auth.ts b/apps/web/config/auth.ts new file mode 100644 index 0000000..3846dcb --- /dev/null +++ b/apps/web/config/auth.ts @@ -0,0 +1,42 @@ +import { type AuthOptions } from 'next-auth'; +import CredentialsProvider from 'next-auth/providers/credentials'; + +export const authOptions: AuthOptions = { + callbacks: { + async jwt({ token, user }) { + if (user) { + token.id = user.id; + } + + return token; + }, + async session({ session, token }) { + if (token?.id && session?.user) { + session.user.telegramId = token.id as string; + } + + return session; + }, + }, + providers: [ + CredentialsProvider({ + async authorize(credentials) { + const { telegramId } = credentials ?? {}; + + if (!telegramId) { + throw new Error('Invalid Telegram ID'); + } + + return { id: telegramId }; + }, + credentials: { + telegramId: { label: 'Telegram ID', type: 'text' }, + }, + id: 'telegram', + name: 'Telegram', + }), + ], + session: { + strategy: 'jwt', + }, +}; diff --git a/apps/web/config/env.ts b/apps/web/config/env.ts new file mode 100644 index 0000000..c3ccf3b --- /dev/null +++ b/apps/web/config/env.ts @@ -0,0 +1,8 @@ +/* eslint-disable unicorn/prevent-abbreviations */ +import { z } from 'zod'; + +export const envSchema = z.object({ + NEXTAUTH_SECRET: z.string(), +}); + +export const env = envSchema.parse(process.env); diff --git a/apps/web/package.json b/apps/web/package.json index a85489f..cb7f982 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -19,16 +19,18 @@ "graphql": "catalog:", "lucide-react": "catalog:", "next": "catalog:", + "next-auth": "^4.24.11", "next-intl": "catalog:", "react": "catalog:", - "react-dom": "catalog:" + "react-dom": "catalog:", + "zod": "catalog:" }, "devDependencies": { "@playwright/test": "catalog:", "@repo/eslint-config": "workspace:*", + "@repo/graphql": "workspace:*", "@repo/lint-staged-config": "workspace:*", "@repo/typescript-config": "workspace:*", - "@repo/graphql": "workspace:*", "@testing-library/react": "catalog:", "@types/node": "catalog:", "@types/react": "catalog:", diff --git a/apps/web/providers/auth.tsx b/apps/web/providers/auth.tsx new file mode 100644 index 0000000..2027d02 --- /dev/null +++ b/apps/web/providers/auth.tsx @@ -0,0 +1,6 @@ +'use client'; +import { SessionProvider } from 'next-auth/react'; + +export function AuthProvider({ children }: { readonly children: React.ReactNode }) { + return {children}; +} diff --git a/apps/web/providers/index.ts b/apps/web/providers/index.ts new file mode 100644 index 0000000..88e61f2 --- /dev/null +++ b/apps/web/providers/index.ts @@ -0,0 +1,2 @@ +export * from './auth'; +export * from './telegram'; diff --git a/apps/web/components/telegram/Root.tsx b/apps/web/providers/telegram.tsx similarity index 89% rename from apps/web/components/telegram/Root.tsx rename to apps/web/providers/telegram.tsx index 0affc62..999e97f 100644 --- a/apps/web/components/telegram/Root.tsx +++ b/apps/web/providers/telegram.tsx @@ -2,11 +2,11 @@ 'use client'; import { useClientOnce, useDidMount } from '@/hooks/telegram'; import { setLocale } from '@/utils/i18n/locale'; -import { init } from '@/utils/init'; +import { init } from '@/utils/telegram/init'; import { initData, useSignal } from '@telegram-apps/sdk-react'; import { type PropsWithChildren, useEffect } from 'react'; -export function Root(props: Readonly) { +export function TelegramProvider(props: Readonly) { // Unfortunately, Telegram Mini Apps does not allow us to use all features of // the Server Side Rendering. That's why we are showing loader on the server // side. diff --git a/apps/web/tsconfig.json b/apps/web/tsconfig.json index 4f8e45b..f77ef1b 100644 --- a/apps/web/tsconfig.json +++ b/apps/web/tsconfig.json @@ -16,7 +16,8 @@ "next.config.js", "**/*.ts", "**/*.tsx", - ".next/types/**/*.ts" + ".next/types/**/*.ts", + "types/*.ts" ], "exclude": ["node_modules"] } diff --git a/apps/web/types/next-auth.d.ts b/apps/web/types/next-auth.d.ts new file mode 100644 index 0000000..0152d68 --- /dev/null +++ b/apps/web/types/next-auth.d.ts @@ -0,0 +1,10 @@ +/* eslint-disable @typescript-eslint/consistent-type-definitions */ +import { type DefaultSession } from 'next-auth'; + +declare module 'next-auth' { + interface Session extends DefaultSession { + user?: { + telegramId?: null | string; + }; + } +} diff --git a/apps/web/utils/init.ts b/apps/web/utils/telegram/init.ts similarity index 100% rename from apps/web/utils/init.ts rename to apps/web/utils/telegram/init.ts diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 72aed87..ae02257 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -228,6 +228,9 @@ importers: next: specifier: 'catalog:' version: 15.1.0(@babel/core@7.26.0)(@playwright/test@1.49.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + next-auth: + specifier: ^4.24.11 + version: 4.24.11(next@15.1.0(@babel/core@7.26.0)(@playwright/test@1.49.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react-dom@19.0.0(react@19.0.0))(react@19.0.0) next-intl: specifier: 'catalog:' version: 3.26.0(next@15.1.0(@babel/core@7.26.0)(@playwright/test@1.49.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react@19.0.0) @@ -237,6 +240,9 @@ importers: react-dom: specifier: 'catalog:' version: 19.0.0(react@19.0.0) + zod: + specifier: 'catalog:' + version: 3.24.1 devDependencies: '@playwright/test': specifier: 'catalog:' @@ -1938,6 +1944,9 @@ packages: resolution: {integrity: sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==} engines: {node: '>=12.4.0'} + '@panva/hkdf@1.2.1': + resolution: {integrity: sha512-6oclG6Y3PiDFcoyk8srjLfVKyMfVCKJ27JwNPViuXziFpmdz+MZnZN/aKY0JGXgYuO/VghU0jcOAZgWXZ1Dmrw==} + '@peculiar/asn1-schema@2.3.13': resolution: {integrity: sha512-3Xq3a01WkHRZL8X04Zsfg//mGaA21xlL4tlVn4v2xGT0JStiztATRkMwa5b+f/HXmY2smsiLXYK46Gwgzvfg3g==} @@ -2859,6 +2868,10 @@ packages: convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + cookie@0.7.2: + resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} + engines: {node: '>= 0.6'} + core-js-compat@3.39.0: resolution: {integrity: sha512-VgEUx3VwlExr5no0tXlBt+silBvhTryPwCXRI2Id1PN8WTKu7MreethvddqOubrYxkFdv/RnYrqlv1sFNAUelw==} @@ -4079,6 +4092,9 @@ packages: resolution: {integrity: sha512-yPBThwecp1wS9DmoA4x4KR2h3QoslacnDR8ypuFM962kI4/456Iy1oHx2RAgh4jfZNdn0bctsdadceiBUgpU1g==} hasBin: true + jose@4.15.9: + resolution: {integrity: sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==} + jose@5.9.6: resolution: {integrity: sha512-AMlnetc9+CV9asI19zHmrgS/WYsWUwCn2R7RzlbJWD7F9eWYUTGyBmU9o6PxngtLGOiDGPRu+Uc4fhKzbpteZQ==} @@ -4290,6 +4306,10 @@ packages: lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + lru-cache@6.0.0: + resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} + engines: {node: '>=10'} + lucide-react@0.462.0: resolution: {integrity: sha512-NTL7EbAao9IFtuSivSZgrAh4fZd09Lr+6MTkqIxuHaH2nnYiYIzXPo06cOxHg9wKLdj6LL8TByG4qpePqwgx/g==} peerDependencies: @@ -4404,6 +4424,20 @@ packages: resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==} engines: {node: '>= 0.6'} + next-auth@4.24.11: + resolution: {integrity: sha512-pCFXzIDQX7xmHFs4KVH4luCjaCbuPRtZ9oBUjUhOk84mZ9WVPf94n87TxYI4rSRf9HmfHEF8Yep3JrYDVOo3Cw==} + peerDependencies: + '@auth/core': 0.34.2 + next: ^12.2.5 || ^13 || ^14 || ^15 + nodemailer: ^6.6.5 + react: ^17.0.2 || ^18 || ^19 + react-dom: ^17.0.2 || ^18 || ^19 + peerDependenciesMeta: + '@auth/core': + optional: true + nodemailer: + optional: true + next-intl@3.26.0: resolution: {integrity: sha512-gkamnHIANQzeW8xpTGRxd0xiOCztQhY8GDp79fgdlw0GioqrjTEfSWLhHkgaAtvHRbuh/ByJdwiEY5eNK9bUSQ==} peerDependencies: @@ -4474,6 +4508,9 @@ packages: nwsapi@2.2.16: resolution: {integrity: sha512-F1I/bimDpj3ncaNDhfyMWuFqmQDBwDB0Fogc2qpL3BWvkQteFD/8BzWuIRl83rq0DXfm8SGt/HFhLXZyljTXcQ==} + oauth@0.9.15: + resolution: {integrity: sha512-a5ERWK1kh38ExDEfoO6qUHJb32rd7aYmPHuyCu3Fta/cnICvYmgd2uhuKXvPD+PXB+gCEYYEaQdIRAjCOwAKNA==} + obj-props@1.4.0: resolution: {integrity: sha512-p7p/7ltzPDiBs6DqxOrIbtRdwxxVRBj5ROukeNb9RgA+fawhrz5n2hpNz8DDmYR//tviJSj7nUnlppGmONkjiQ==} engines: {node: '>=0.10.0'} @@ -4482,6 +4519,10 @@ packages: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} + object-hash@2.2.0: + resolution: {integrity: sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==} + engines: {node: '>= 6'} + object-hash@3.0.0: resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} engines: {node: '>= 6'} @@ -4510,6 +4551,10 @@ packages: resolution: {integrity: sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==} engines: {node: '>= 0.4'} + oidc-token-hash@5.0.3: + resolution: {integrity: sha512-IF4PcGgzAr6XXSff26Sk/+P4KZFJVuHAJZj3wgO3vX2bMdNVp/QXTP3P7CEm9V1IdG8lDLY3HhiqpsE/nOwpPw==} + engines: {node: ^10.13.0 || >=12.0.0} + once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} @@ -4525,6 +4570,9 @@ packages: resolution: {integrity: sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==} engines: {node: '>=18'} + openid-client@5.7.1: + resolution: {integrity: sha512-jDBPgSVfTnkIh71Hg9pRvtJc6wTwqjRkN88+gCFtYWrlP4Yx2Dsrow8uPi3qLr/aeymPF3o2+dS+wOpglK04ew==} + optimism@0.18.1: resolution: {integrity: sha512-mLXNwWPa9dgFyDqkNi54sjDyNJ9/fTI6WGBLgnXku1vdKY/jovHfZT5r+aiVeFFLOz+foPNOm5YJ4mqgld2GBQ==} @@ -4754,6 +4802,14 @@ packages: resolution: {integrity: sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==} engines: {node: ^10 || ^12 || >=14} + preact-render-to-string@5.2.6: + resolution: {integrity: sha512-JyhErpYOvBV1hEPwIxc/fHWXPfnEGdRKxc8gFdAZ7XV4tlzyzG847XAyEZqoDnynP88akM4eaHcSOzNcLWFguw==} + peerDependencies: + preact: '>=10' + + preact@10.25.3: + resolution: {integrity: sha512-dzQmIFtM970z+fP9ziQ3yG4e3ULIbwZzJ734vaMVUTaKQ2+Ru1Ou/gjshOYVHCcd1rpAelC6ngjvjDXph98unQ==} + prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} @@ -4776,6 +4832,9 @@ packages: resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + pretty-format@3.8.0: + resolution: {integrity: sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew==} + promise@7.3.1: resolution: {integrity: sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==} @@ -5553,6 +5612,10 @@ packages: util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + uuid@8.3.2: + resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} + hasBin: true + validate-npm-package-license@3.0.4: resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} @@ -5760,6 +5823,9 @@ packages: yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + yaml-ast-parser@0.0.43: resolution: {integrity: sha512-2PTINUwsRqSd+s8XxKaJWQlUuEMHJQyEuh2edBbW8KNJz0SJPwUSD2zRWqezFEdN7IzAgeuYHFUCF7o8zRdZ0A==} @@ -7664,6 +7730,8 @@ snapshots: '@nolyfill/is-core-module@1.0.39': {} + '@panva/hkdf@1.2.1': {} + '@peculiar/asn1-schema@2.3.13': dependencies: asn1js: 3.0.5 @@ -8702,6 +8770,8 @@ snapshots: convert-source-map@2.0.0: {} + cookie@0.7.2: {} + core-js-compat@3.39.0: dependencies: browserslist: 4.24.2 @@ -10219,6 +10289,8 @@ snapshots: jiti@2.4.1: {} + jose@4.15.9: {} + jose@5.9.6: {} js-tokens@4.0.0: {} @@ -10456,6 +10528,10 @@ snapshots: dependencies: yallist: 3.1.1 + lru-cache@6.0.0: + dependencies: + yallist: 4.0.0 + lucide-react@0.462.0(react@19.0.0): dependencies: react: 19.0.0 @@ -10537,6 +10613,21 @@ snapshots: negotiator@1.0.0: {} + next-auth@4.24.11(next@15.1.0(@babel/core@7.26.0)(@playwright/test@1.49.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react-dom@19.0.0(react@19.0.0))(react@19.0.0): + dependencies: + '@babel/runtime': 7.26.0 + '@panva/hkdf': 1.2.1 + cookie: 0.7.2 + jose: 4.15.9 + next: 15.1.0(@babel/core@7.26.0)(@playwright/test@1.49.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + oauth: 0.9.15 + openid-client: 5.7.1 + preact: 10.25.3 + preact-render-to-string: 5.2.6(preact@10.25.3) + react: 19.0.0 + react-dom: 19.0.0(react@19.0.0) + uuid: 8.3.2 + next-intl@3.26.0(next@15.1.0(@babel/core@7.26.0)(@playwright/test@1.49.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react@19.0.0): dependencies: '@formatjs/intl-localematcher': 0.5.9 @@ -10607,10 +10698,14 @@ snapshots: nwsapi@2.2.16: {} + oauth@0.9.15: {} + obj-props@1.4.0: {} object-assign@4.1.1: {} + object-hash@2.2.0: {} + object-hash@3.0.0: {} object-inspect@1.13.3: {} @@ -10643,6 +10738,8 @@ snapshots: define-properties: 1.2.1 es-object-atoms: 1.0.0 + oidc-token-hash@5.0.3: {} + once@1.4.0: dependencies: wrappy: 1.0.2 @@ -10659,6 +10756,13 @@ snapshots: dependencies: mimic-function: 5.0.1 + openid-client@5.7.1: + dependencies: + jose: 4.15.9 + lru-cache: 6.0.0 + object-hash: 2.2.0 + oidc-token-hash: 5.0.3 + optimism@0.18.1: dependencies: '@wry/caches': 1.0.1 @@ -10868,6 +10972,13 @@ snapshots: picocolors: 1.1.1 source-map-js: 1.2.1 + preact-render-to-string@5.2.6(preact@10.25.3): + dependencies: + preact: 10.25.3 + pretty-format: 3.8.0 + + preact@10.25.3: {} + prelude-ls@1.2.1: {} prettier-linter-helpers@1.0.0: @@ -10884,6 +10995,8 @@ snapshots: ansi-styles: 5.2.0 react-is: 17.0.2 + pretty-format@3.8.0: {} + promise@7.3.1: dependencies: asap: 2.0.6 @@ -11722,6 +11835,8 @@ snapshots: util-deprecate@1.0.2: {} + uuid@8.3.2: {} + validate-npm-package-license@3.0.4: dependencies: spdx-correct: 3.2.0 @@ -11937,6 +12052,8 @@ snapshots: yallist@3.1.1: {} + yallist@4.0.0: {} + yaml-ast-parser@0.0.43: {} yaml-eslint-parser@1.2.3: