diff --git a/apps/envited.ascs.digital/.env.example b/apps/envited.ascs.digital/.env.example
index 295af54c..9fba3a9e 100644
--- a/apps/envited.ascs.digital/.env.example
+++ b/apps/envited.ascs.digital/.env.example
@@ -1,5 +1,7 @@
ENV='development'
REGION='eu-central-1'
+NEXTAUTH_URL='http://localhost:4200'
+NEXTAUTH_SECRET='my-secret'
# .env.development only
POSTGRES_HOST='localhost'
diff --git a/apps/envited.ascs.digital/app/api/auth/[...nextauth]/route.ts b/apps/envited.ascs.digital/app/api/auth/[...nextauth]/route.ts
new file mode 100644
index 00000000..bb0000d9
--- /dev/null
+++ b/apps/envited.ascs.digital/app/api/auth/[...nextauth]/route.ts
@@ -0,0 +1,62 @@
+import NextAuth from 'next-auth'
+import type { NextAuthOptions } from 'next-auth'
+import CredentialsProvider from 'next-auth/providers/credentials'
+
+export const authOptions: NextAuthOptions = {
+ providers: [
+ CredentialsProvider({
+ // The name to display on the sign in form (e.g. 'Sign in with...')
+ name: 'Sign in with Your Credentials',
+ // The credentials is used to generate a suitable form on the sign in page.
+ // You can specify whatever fields you are expecting to be submitted.
+ // e.g. domain, username, password, 2FA token, etc.
+ // You can pass any HTML attribute to the tag through the object.
+ credentials: {
+ pkh: { label: 'Address', type: 'text', placeholder: 'tz...' },
+ },
+ async authorize(credentials) {
+ if (!credentials) {
+ return {
+ id: '',
+ pkh: '',
+ memberId: '',
+ role: '',
+ }
+ }
+ const { pkh } = credentials
+
+ return {
+ id: '',
+ pkh,
+ memberId: '',
+ role: '',
+ }
+ },
+ }),
+ ],
+ session: {
+ strategy: 'jwt',
+ },
+ callbacks: {
+ async jwt({ token, user }) {
+ if (user) {
+ token.user = user
+ }
+
+ return token
+ },
+ async session({ session, token }: { session: any; token: any }) {
+ session.user.pkh = token.user.pkh
+ session.user.role = token.user.role
+ session.user.memberId = token.user.memberId
+ session.user.id = token.sub
+ session.user.email = undefined
+ session.user.image = undefined
+ return session
+ },
+ },
+}
+
+const handler = NextAuth(authOptions)
+
+export { handler as GET, handler as POST }
diff --git a/apps/envited.ascs.digital/app/api/hello/route.ts b/apps/envited.ascs.digital/app/api/hello/route.ts
index 52c7cefd..2f86b30e 100644
--- a/apps/envited.ascs.digital/app/api/hello/route.ts
+++ b/apps/envited.ascs.digital/app/api/hello/route.ts
@@ -1,5 +1,5 @@
-import { ok } from '../../../common/utils'
import { db } from '../../../common/database/queries'
+import { ok } from '../../../common/utils'
export async function GET(request: Request) {
try {
diff --git a/apps/envited.ascs.digital/app/dashboard/page.tsx b/apps/envited.ascs.digital/app/dashboard/page.tsx
new file mode 100644
index 00000000..a4762e88
--- /dev/null
+++ b/apps/envited.ascs.digital/app/dashboard/page.tsx
@@ -0,0 +1,14 @@
+import { getServerSession } from '../../common/session'
+import { Header } from '../../modules/Header'
+
+export default async function Index() {
+ const session = await getServerSession()
+ return (
+ <>
+
+
+ {session ? JSON.stringify(session) : 'No session'}
+
+ >
+ )
+}
diff --git a/apps/envited.ascs.digital/app/layout.tsx b/apps/envited.ascs.digital/app/layout.tsx
index 45156432..309b4de4 100644
--- a/apps/envited.ascs.digital/app/layout.tsx
+++ b/apps/envited.ascs.digital/app/layout.tsx
@@ -2,16 +2,20 @@ import { Providers } from '../modules/Theme/Providers'
import './global.css'
export const metadata = {
- title: 'Welcome to marketplace',
- description: 'Generated by create-nx-workspace',
+ title: 'Envited Marketplace',
+ description: '',
}
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
-
-
- {children}
-
+
+
+ {metadata.title}
+
+
+
+ {children}
+
)
}
diff --git a/apps/envited.ascs.digital/app/page.tsx b/apps/envited.ascs.digital/app/page.tsx
index 1dc92e94..fbb260d2 100644
--- a/apps/envited.ascs.digital/app/page.tsx
+++ b/apps/envited.ascs.digital/app/page.tsx
@@ -1,10 +1,8 @@
-'use client'
-
import { ExampleTable } from '../modules/ExampleTable'
import { Header } from '../modules/Header'
import { HeroHeader } from '../modules/HeroHeader'
-export default function Index() {
+export default async function Index() {
return (
<>
diff --git a/apps/envited.ascs.digital/common/database/migrate.ts b/apps/envited.ascs.digital/common/database/migrate.ts
index d20ab562..9d1d008f 100644
--- a/apps/envited.ascs.digital/common/database/migrate.ts
+++ b/apps/envited.ascs.digital/common/database/migrate.ts
@@ -1,15 +1,14 @@
import { RDSDataClient } from '@aws-sdk/client-rds-data'
import { fromIni } from '@aws-sdk/credential-providers'
+import { drizzle as RDSDrizzle } from 'drizzle-orm/aws-data-api/pg'
+import { migrate as AWSDataApiMigrate } from 'drizzle-orm/aws-data-api/pg/migrator'
import { PostgresJsDatabase } from 'drizzle-orm/postgres-js'
import { migrate as PGMigrate } from 'drizzle-orm/postgres-js/migrator'
-import { migrate as AWSDataApiMigrate } from 'drizzle-orm/aws-data-api/pg/migrator'
-import { drizzle as RDSDrizzle } from 'drizzle-orm/aws-data-api/pg'
import { connectDb } from './database'
import * as schema from './schema'
const runMigration = async () => {
-
try {
if (process.env.ENV === 'development') {
const db = await connectDb()
@@ -21,7 +20,7 @@ const runMigration = async () => {
credentials: fromIni({ profile: process.env.AWS_PROFILE || '' }),
region: 'eu-central-1',
})
-
+
const db = RDSDrizzle(rdsClient, {
database: process.env.RDS_DB_NAME || '',
secretArn: process.env.RDS_SECRET_ARN || '',
diff --git a/apps/envited.ascs.digital/common/database/seed.ts b/apps/envited.ascs.digital/common/database/seed.ts
index 5bba5e86..9b014f7d 100644
--- a/apps/envited.ascs.digital/common/database/seed.ts
+++ b/apps/envited.ascs.digital/common/database/seed.ts
@@ -7,14 +7,13 @@ import { connectDb } from './database'
import { role } from './schema'
import * as schema from './schema'
-const insertRoles = (connection: any) => async (roles: any[]) =>
- connection.insert(role).values(roles).execute()
+const insertRoles = (connection: any) => async (roles: any[]) => connection.insert(role).values(roles).execute()
const seed = async () => {
try {
// Insert seeding requirements here
let connection = null
-
+
if (process.env.ENV === 'development') {
connection = await connectDb()
return
@@ -23,7 +22,7 @@ const seed = async () => {
credentials: fromIni({ profile: process.env.AWS_PROFILE || '' }),
region: 'eu-central-1',
})
-
+
connection = RDSDrizzle(rdsClient, {
database: process.env.RDS_DB_NAME || '',
secretArn: process.env.RDS_SECRET_ARN || '',
diff --git a/apps/envited.ascs.digital/common/session/index.ts b/apps/envited.ascs.digital/common/session/index.ts
new file mode 100644
index 00000000..205e1a2b
--- /dev/null
+++ b/apps/envited.ascs.digital/common/session/index.ts
@@ -0,0 +1 @@
+export { getServerSession } from './session'
diff --git a/apps/envited.ascs.digital/common/session/session.test.ts b/apps/envited.ascs.digital/common/session/session.test.ts
new file mode 100644
index 00000000..0b683c6a
--- /dev/null
+++ b/apps/envited.ascs.digital/common/session/session.test.ts
@@ -0,0 +1,17 @@
+import { _getServerSession } from './session'
+
+describe('common/session', () => {
+ describe('getServerSession', () => {
+ it('should should fetch a server session with the correct parameters', async () => {
+ // when ... we want to get the current session server side
+ // then ... it should call the getServerSession function with the correct parameters
+ const authOptions = 'AUTH_OPTIONS' as any
+ const NAGetServerSession = jest.fn().mockResolvedValue('SESSION')
+
+ const session = await _getServerSession(NAGetServerSession)(authOptions)()
+
+ expect(NAGetServerSession).toHaveBeenCalledWith(authOptions)
+ expect(session).toEqual('SESSION')
+ })
+ })
+})
diff --git a/apps/envited.ascs.digital/common/session/session.ts b/apps/envited.ascs.digital/common/session/session.ts
new file mode 100644
index 00000000..0bc18cb9
--- /dev/null
+++ b/apps/envited.ascs.digital/common/session/session.ts
@@ -0,0 +1,8 @@
+import { getServerSession as NAGetServerSession, NextAuthOptions } from 'next-auth'
+
+import { authOptions } from '../../app/api/auth/[...nextauth]/route'
+
+export const _getServerSession = (NAGetServerSession: any) => (authOptions: NextAuthOptions) => () =>
+ NAGetServerSession(authOptions)
+
+export const getServerSession = _getServerSession(NAGetServerSession)(authOptions)
diff --git a/apps/envited.ascs.digital/common/types/types.ts b/apps/envited.ascs.digital/common/types/types.ts
index bc1235a9..8802fbc9 100644
--- a/apps/envited.ascs.digital/common/types/types.ts
+++ b/apps/envited.ascs.digital/common/types/types.ts
@@ -33,8 +33,15 @@ export type Action = {
data?: Obj
}
-export type Role = {
+export interface IRole {
id: string
name: string
description: string
}
+
+export enum Role {
+ admin = 'admin',
+ user = 'user',
+ principal = 'principal',
+ federator = 'federator',
+}
diff --git a/apps/envited.ascs.digital/common/utils/utils.test.ts b/apps/envited.ascs.digital/common/utils/utils.test.ts
index d5775ce9..d4a2ab20 100644
--- a/apps/envited.ascs.digital/common/utils/utils.test.ts
+++ b/apps/envited.ascs.digital/common/utils/utils.test.ts
@@ -1,14 +1,13 @@
/**
* @jest-environment node
*/
-
-import { RESPONSES } from '../constants';
+import { RESPONSES } from '../constants'
import * as SUT from './utils'
describe('common/utils', () => {
- const mockFetch = Promise.resolve({ json: () => Promise.resolve('') });
- global.fetch = jest.fn().mockImplementation(() => mockFetch);
-
+ const mockFetch = Promise.resolve({ json: () => Promise.resolve('') })
+ global.fetch = jest.fn().mockImplementation(() => mockFetch)
+
describe('ok', () => {
it.each([
['Message', 'Message'],
diff --git a/apps/envited.ascs.digital/common/utils/utils.ts b/apps/envited.ascs.digital/common/utils/utils.ts
index a5bafee0..5e4f854b 100644
--- a/apps/envited.ascs.digital/common/utils/utils.ts
+++ b/apps/envited.ascs.digital/common/utils/utils.ts
@@ -2,10 +2,17 @@ import { RESPONSES } from '../constants'
export const ok = (data: any) => Response.json(data)
-export const badRequest = () => Response.json(null, { status: RESPONSES.badRequest.status, statusText: RESPONSES.badRequest.statusText })
+export const badRequest = () =>
+ Response.json(null, { status: RESPONSES.badRequest.status, statusText: RESPONSES.badRequest.statusText })
-export const internalServerError = () => Response.json(null, { status: RESPONSES.internalServerError.status, statusText: RESPONSES.internalServerError.statusText })
+export const internalServerError = () =>
+ Response.json(null, {
+ status: RESPONSES.internalServerError.status,
+ statusText: RESPONSES.internalServerError.statusText,
+ })
-export const notFound = () => Response.json(null, { status: RESPONSES.notFound.status, statusText: RESPONSES.notFound.statusText})
+export const notFound = () =>
+ Response.json(null, { status: RESPONSES.notFound.status, statusText: RESPONSES.notFound.statusText })
-export const noContent = () => new Response(null, { status: RESPONSES.noContent.status, statusText: RESPONSES.noContent.statusText })
+export const noContent = () =>
+ new Response(null, { status: RESPONSES.noContent.status, statusText: RESPONSES.noContent.statusText })
diff --git a/apps/envited.ascs.digital/drizzle/staging/meta/0000_snapshot.json b/apps/envited.ascs.digital/drizzle/staging/meta/0000_snapshot.json
index fb6be74b..ce9c4c88 100644
--- a/apps/envited.ascs.digital/drizzle/staging/meta/0000_snapshot.json
+++ b/apps/envited.ascs.digital/drizzle/staging/meta/0000_snapshot.json
@@ -98,9 +98,7 @@
"issuer_id_unique": {
"name": "issuer_id_unique",
"nullsNotDistinct": false,
- "columns": [
- "id"
- ]
+ "columns": ["id"]
}
}
},
@@ -134,9 +132,7 @@
"role_id_unique": {
"name": "role_id_unique",
"nullsNotDistinct": false,
- "columns": [
- "id"
- ]
+ "columns": ["id"]
}
}
},
@@ -265,12 +261,8 @@
"name": "user_issuer_id_issuer_id_fk",
"tableFrom": "user",
"tableTo": "issuer",
- "columnsFrom": [
- "issuer_id"
- ],
- "columnsTo": [
- "id"
- ],
+ "columnsFrom": ["issuer_id"],
+ "columnsTo": ["id"],
"onDelete": "no action",
"onUpdate": "no action"
},
@@ -278,12 +270,8 @@
"name": "user_address_type_id_addressType_id_fk",
"tableFrom": "user",
"tableTo": "addressType",
- "columnsFrom": [
- "address_type_id"
- ],
- "columnsTo": [
- "id"
- ],
+ "columnsFrom": ["address_type_id"],
+ "columnsTo": ["id"],
"onDelete": "no action",
"onUpdate": "no action"
}
@@ -293,9 +281,7 @@
"user_id_unique": {
"name": "user_id_unique",
"nullsNotDistinct": false,
- "columns": [
- "id"
- ]
+ "columns": ["id"]
}
}
},
@@ -322,12 +308,8 @@
"name": "usersToCredentialTypes_user_id_user_id_fk",
"tableFrom": "usersToCredentialTypes",
"tableTo": "user",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
+ "columnsFrom": ["user_id"],
+ "columnsTo": ["id"],
"onDelete": "no action",
"onUpdate": "no action"
},
@@ -335,12 +317,8 @@
"name": "usersToCredentialTypes_credential_type_id_credentialType_id_fk",
"tableFrom": "usersToCredentialTypes",
"tableTo": "credentialType",
- "columnsFrom": [
- "credential_type_id"
- ],
- "columnsTo": [
- "id"
- ],
+ "columnsFrom": ["credential_type_id"],
+ "columnsTo": ["id"],
"onDelete": "no action",
"onUpdate": "no action"
}
@@ -371,12 +349,8 @@
"name": "usersToRoles_user_id_user_id_fk",
"tableFrom": "usersToRoles",
"tableTo": "user",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
+ "columnsFrom": ["user_id"],
+ "columnsTo": ["id"],
"onDelete": "no action",
"onUpdate": "no action"
},
@@ -384,12 +358,8 @@
"name": "usersToRoles_role_id_role_id_fk",
"tableFrom": "usersToRoles",
"tableTo": "role",
- "columnsFrom": [
- "role_id"
- ],
- "columnsTo": [
- "id"
- ],
+ "columnsFrom": ["role_id"],
+ "columnsTo": ["id"],
"onDelete": "no action",
"onUpdate": "no action"
}
@@ -405,4 +375,4 @@
"schemas": {},
"tables": {}
}
-}
\ No newline at end of file
+}
diff --git a/apps/envited.ascs.digital/drizzle/staging/meta/_journal.json b/apps/envited.ascs.digital/drizzle/staging/meta/_journal.json
index adf49e29..657a65fe 100644
--- a/apps/envited.ascs.digital/drizzle/staging/meta/_journal.json
+++ b/apps/envited.ascs.digital/drizzle/staging/meta/_journal.json
@@ -10,4 +10,4 @@
"breakpoints": true
}
]
-}
\ No newline at end of file
+}
diff --git a/apps/envited.ascs.digital/middleware.ts b/apps/envited.ascs.digital/middleware.ts
new file mode 100644
index 00000000..176d330b
--- /dev/null
+++ b/apps/envited.ascs.digital/middleware.ts
@@ -0,0 +1,3 @@
+export { default } from 'next-auth/middleware'
+
+export const config = { matcher: ['/dashboard'] }
diff --git a/apps/envited.ascs.digital/modules/ExampleTable/ExampleTable.tsx b/apps/envited.ascs.digital/modules/ExampleTable/ExampleTable.tsx
index f34c8f41..b7d96117 100644
--- a/apps/envited.ascs.digital/modules/ExampleTable/ExampleTable.tsx
+++ b/apps/envited.ascs.digital/modules/ExampleTable/ExampleTable.tsx
@@ -1,3 +1,5 @@
+'use client'
+
import { Table, TableBody, TableCell, TableHeader, TableRow } from '@envited-marketplace/design-system'
import React from 'react'
diff --git a/apps/envited.ascs.digital/modules/Header/Header.tsx b/apps/envited.ascs.digital/modules/Header/Header.tsx
index b01334ab..f446db37 100644
--- a/apps/envited.ascs.digital/modules/Header/Header.tsx
+++ b/apps/envited.ascs.digital/modules/Header/Header.tsx
@@ -1,3 +1,5 @@
+'use client'
+
import { Button } from '@envited-marketplace/design-system'
import Image from 'next/image'
import Link from 'next/link'
diff --git a/apps/envited.ascs.digital/modules/HeroHeader/HeroHeader.tsx b/apps/envited.ascs.digital/modules/HeroHeader/HeroHeader.tsx
index 0202e31e..67bd9c6b 100644
--- a/apps/envited.ascs.digital/modules/HeroHeader/HeroHeader.tsx
+++ b/apps/envited.ascs.digital/modules/HeroHeader/HeroHeader.tsx
@@ -1,3 +1,5 @@
+'use client'
+
import { Button, Card, Grid, GridRow, Heading, HeadingWithTooltip, Tooltip } from '@envited-marketplace/design-system'
import React, { FC } from 'react'
diff --git a/apps/envited.ascs.digital/setupTests.ts b/apps/envited.ascs.digital/setupTests.ts
new file mode 100644
index 00000000..54afb4d6
--- /dev/null
+++ b/apps/envited.ascs.digital/setupTests.ts
@@ -0,0 +1,3 @@
+import { TextDecoder, TextEncoder } from 'util'
+
+Object.assign(global, { TextDecoder, TextEncoder })
diff --git a/jest.preset.js b/jest.preset.js
index 4ddde84a..579e808d 100644
--- a/jest.preset.js
+++ b/jest.preset.js
@@ -2,5 +2,5 @@ const nxPreset = require('@nx/jest/preset').default
module.exports = {
...nxPreset,
- setupFilesAfterEnv: ['/src/setupTests.ts'],
+ setupFilesAfterEnv: ['/setupTests.ts'],
}
diff --git a/package-lock.json b/package-lock.json
index 33b2fb09..c1aab2c2 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -15,6 +15,7 @@
"date-fns": "^3.0.6",
"drizzle-orm": "^0.29.3",
"next": "14.0.4",
+ "next-auth": "^4.24.5",
"next-themes": "^0.2.1",
"postgres": "^3.4.3",
"ramda": "^0.29.1",
@@ -9290,6 +9291,14 @@
"node": ">=8"
}
},
+ "node_modules/@panva/hkdf": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@panva/hkdf/-/hkdf-1.1.1.tgz",
+ "integrity": "sha512-dhPeilub1NuIG0X5Kvhh9lH4iW3ZsHlnzwgwbOlgwQ2wG1IqFzsgHqmKPk3WzsdWAeaxKJxgM0+W433RmN45GA==",
+ "funding": {
+ "url": "https://github.com/sponsors/panva"
+ }
+ },
"node_modules/@peculiar/asn1-schema": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/@peculiar/asn1-schema/-/asn1-schema-2.3.8.tgz",
@@ -20161,7 +20170,6 @@
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
"integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==",
- "dev": true,
"engines": {
"node": ">= 0.6"
}
@@ -30991,7 +30999,6 @@
"version": "4.15.4",
"resolved": "https://registry.npmjs.org/jose/-/jose-4.15.4.tgz",
"integrity": "sha512-W+oqK4H+r5sITxfxpSU+MMdr/YSWGvgZMQDIsNoBDGGy4i7GBPTtvFKibQzW06n3U3TqHjhvBJsirShsEJ6eeQ==",
- "dev": true,
"funding": {
"url": "https://github.com/sponsors/panva"
}
@@ -32475,6 +32482,33 @@
}
}
},
+ "node_modules/next-auth": {
+ "version": "4.24.5",
+ "resolved": "https://registry.npmjs.org/next-auth/-/next-auth-4.24.5.tgz",
+ "integrity": "sha512-3RafV3XbfIKk6rF6GlLE4/KxjTcuMCifqrmD+98ejFq73SRoj2rmzoca8u764977lH/Q7jo6Xu6yM+Re1Mz/Og==",
+ "dependencies": {
+ "@babel/runtime": "^7.20.13",
+ "@panva/hkdf": "^1.0.2",
+ "cookie": "^0.5.0",
+ "jose": "^4.11.4",
+ "oauth": "^0.9.15",
+ "openid-client": "^5.4.0",
+ "preact": "^10.6.3",
+ "preact-render-to-string": "^5.1.19",
+ "uuid": "^8.3.2"
+ },
+ "peerDependencies": {
+ "next": "^12.2.5 || ^13 || ^14",
+ "nodemailer": "^6.6.5",
+ "react": "^17.0.2 || ^18",
+ "react-dom": "^17.0.2 || ^18"
+ },
+ "peerDependenciesMeta": {
+ "nodemailer": {
+ "optional": true
+ }
+ }
+ },
"node_modules/next-themes": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/next-themes/-/next-themes-0.2.1.tgz",
@@ -33167,6 +33201,11 @@
"node": ">=6"
}
},
+ "node_modules/oauth": {
+ "version": "0.9.15",
+ "resolved": "https://registry.npmjs.org/oauth/-/oauth-0.9.15.tgz",
+ "integrity": "sha512-a5ERWK1kh38ExDEfoO6qUHJb32rd7aYmPHuyCu3Fta/cnICvYmgd2uhuKXvPD+PXB+gCEYYEaQdIRAjCOwAKNA=="
+ },
"node_modules/object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
@@ -33180,7 +33219,6 @@
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz",
"integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==",
- "dev": true,
"engines": {
"node": ">= 6"
}
@@ -33331,7 +33369,6 @@
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/oidc-token-hash/-/oidc-token-hash-5.0.3.tgz",
"integrity": "sha512-IF4PcGgzAr6XXSff26Sk/+P4KZFJVuHAJZj3wgO3vX2bMdNVp/QXTP3P7CEm9V1IdG8lDLY3HhiqpsE/nOwpPw==",
- "dev": true,
"engines": {
"node": "^10.13.0 || >=12.0.0"
}
@@ -33407,7 +33444,6 @@
"version": "5.6.4",
"resolved": "https://registry.npmjs.org/openid-client/-/openid-client-5.6.4.tgz",
"integrity": "sha512-T1h3B10BRPKfcObdBklX639tVz+xh34O7GjofqrqiAQdm7eHsQ00ih18x6wuJ/E6FxdtS2u3FmUGPDeEcMwzNA==",
- "dev": true,
"dependencies": {
"jose": "^4.15.4",
"lru-cache": "^6.0.0",
@@ -33422,7 +33458,6 @@
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
- "dev": true,
"dependencies": {
"yallist": "^4.0.0"
},
@@ -33433,8 +33468,7 @@
"node_modules/openid-client/node_modules/yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
- "dev": true
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
},
"node_modules/optionator": {
"version": "0.9.3",
@@ -34777,6 +34811,31 @@
"url": "https://github.com/sponsors/porsager"
}
},
+ "node_modules/preact": {
+ "version": "10.19.3",
+ "resolved": "https://registry.npmjs.org/preact/-/preact-10.19.3.tgz",
+ "integrity": "sha512-nHHTeFVBTHRGxJXKkKu5hT8C/YWBkPso4/Gad6xuj5dbptt9iF9NZr9pHbPhBrnT2klheu7mHTxTZ/LjwJiEiQ==",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/preact"
+ }
+ },
+ "node_modules/preact-render-to-string": {
+ "version": "5.2.6",
+ "resolved": "https://registry.npmjs.org/preact-render-to-string/-/preact-render-to-string-5.2.6.tgz",
+ "integrity": "sha512-JyhErpYOvBV1hEPwIxc/fHWXPfnEGdRKxc8gFdAZ7XV4tlzyzG847XAyEZqoDnynP88akM4eaHcSOzNcLWFguw==",
+ "dependencies": {
+ "pretty-format": "^3.8.0"
+ },
+ "peerDependencies": {
+ "preact": ">=10"
+ }
+ },
+ "node_modules/preact-render-to-string/node_modules/pretty-format": {
+ "version": "3.8.0",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-3.8.0.tgz",
+ "integrity": "sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew=="
+ },
"node_modules/prelude-ls": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
diff --git a/package.json b/package.json
index 54cec410..f6f1adf0 100644
--- a/package.json
+++ b/package.json
@@ -11,6 +11,7 @@
"date-fns": "^3.0.6",
"drizzle-orm": "^0.29.3",
"next": "14.0.4",
+ "next-auth": "^4.24.5",
"next-themes": "^0.2.1",
"postgres": "^3.4.3",
"ramda": "^0.29.1",