diff --git a/.env.template b/.env.template
new file mode 100644
index 0000000000..35ac3b9b58
--- /dev/null
+++ b/.env.template
@@ -0,0 +1,2 @@
+# openssl rand -base64 32
+AUTH_SECRET=your-secret-key
diff --git a/app/(auth)/layout.tsx b/app/(auth)/layout.tsx
new file mode 100644
index 0000000000..5ff842ef07
--- /dev/null
+++ b/app/(auth)/layout.tsx
@@ -0,0 +1,16 @@
+export const metadata = {
+ title: "Next.js",
+ description: "Generated by Next.js",
+};
+
+export default function RootLayout({
+ children,
+}: {
+ children: React.ReactNode;
+}) {
+ return (
+
+
{children}
+
+ );
+}
diff --git a/app/(auth)/sign-in/page.tsx b/app/(auth)/sign-in/page.tsx
new file mode 100644
index 0000000000..e12af16f4c
--- /dev/null
+++ b/app/(auth)/sign-in/page.tsx
@@ -0,0 +1,7 @@
+import React from "react";
+
+const SignIn = () => {
+ return SignIn
;
+};
+
+export default SignIn;
diff --git a/app/(auth)/sign-up/page.tsx b/app/(auth)/sign-up/page.tsx
new file mode 100644
index 0000000000..b466e40354
--- /dev/null
+++ b/app/(auth)/sign-up/page.tsx
@@ -0,0 +1,7 @@
+import React from "react";
+
+const SignUp = () => {
+ return SignUp
;
+};
+
+export default SignUp;
diff --git a/auth.config.ts b/auth.config.ts
new file mode 100644
index 0000000000..7baf25dd7d
--- /dev/null
+++ b/auth.config.ts
@@ -0,0 +1,9 @@
+import type { NextAuthConfig } from "next-auth";
+
+export const authConfig = {
+ pages: {
+ signIn: "/sign-in",
+ // signUp: "/sign-up",
+ },
+ providers: [],
+} satisfies NextAuthConfig;
diff --git a/package-lock.json b/package-lock.json
index ccef367e4e..0ce80ed402 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -27,6 +27,7 @@
"intl-messageformat": "^10.5.0",
"lucide-react": "^0.417.0",
"next": "14.2.3",
+ "next-auth": "^5.0.0-beta.20",
"next-themes": "^0.2.1",
"react": "18.3.1",
"react-dom": "18.3.1",
@@ -90,6 +91,36 @@
"nun": "bin/nun.mjs"
}
},
+ "node_modules/@auth/core": {
+ "version": "0.34.2",
+ "resolved": "https://registry.npmjs.org/@auth/core/-/core-0.34.2.tgz",
+ "integrity": "sha512-KywHKRgLiF3l7PLyL73fjLSIBe1YNcA6sMeew4yMP6cfCWGXZrkkXd32AjRi1hlJ9nvovUBGZHvbn+LijO6ZeQ==",
+ "dependencies": {
+ "@panva/hkdf": "^1.1.1",
+ "@types/cookie": "0.6.0",
+ "cookie": "0.6.0",
+ "jose": "^5.1.3",
+ "oauth4webapi": "^2.10.4",
+ "preact": "10.11.3",
+ "preact-render-to-string": "5.2.3"
+ },
+ "peerDependencies": {
+ "@simplewebauthn/browser": "^9.0.1",
+ "@simplewebauthn/server": "^9.0.2",
+ "nodemailer": "^6.8.0"
+ },
+ "peerDependenciesMeta": {
+ "@simplewebauthn/browser": {
+ "optional": true
+ },
+ "@simplewebauthn/server": {
+ "optional": true
+ },
+ "nodemailer": {
+ "optional": true
+ }
+ }
+ },
"node_modules/@babel/code-frame": {
"version": "7.24.7",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz",
@@ -2233,6 +2264,14 @@
"node": ">= 8"
}
},
+ "node_modules/@panva/hkdf": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@panva/hkdf/-/hkdf-1.2.1.tgz",
+ "integrity": "sha512-6oclG6Y3PiDFcoyk8srjLfVKyMfVCKJ27JwNPViuXziFpmdz+MZnZN/aKY0JGXgYuO/VghU0jcOAZgWXZ1Dmrw==",
+ "funding": {
+ "url": "https://github.com/sponsors/panva"
+ }
+ },
"node_modules/@pkgjs/parseargs": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
@@ -4082,6 +4121,11 @@
"url": "https://github.com/sponsors/isaacs"
}
},
+ "node_modules/@types/cookie": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz",
+ "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA=="
+ },
"node_modules/@types/d3-array": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz",
@@ -5204,6 +5248,14 @@
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
"dev": true
},
+ "node_modules/cookie": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz",
+ "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
"node_modules/cosmiconfig": {
"version": "8.3.6",
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz",
@@ -7856,6 +7908,14 @@
"jiti": "bin/jiti.js"
}
},
+ "node_modules/jose": {
+ "version": "5.7.0",
+ "resolved": "https://registry.npmjs.org/jose/-/jose-5.7.0.tgz",
+ "integrity": "sha512-3P9qfTYDVnNn642LCAqIKbTGb9a1TBxZ9ti5zEVEr48aDdflgRjhspWFb6WM4PzAfFbGMJYC4+803v8riCRAKw==",
+ "funding": {
+ "url": "https://github.com/sponsors/panva"
+ }
+ },
"node_modules/js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -8555,6 +8615,32 @@
}
}
},
+ "node_modules/next-auth": {
+ "version": "5.0.0-beta.20",
+ "resolved": "https://registry.npmjs.org/next-auth/-/next-auth-5.0.0-beta.20.tgz",
+ "integrity": "sha512-+48SjV9k9AtUU3JbEIa4PXNjKIewfFjVGL7Xs2RKkuQ5QqegDNIQiIG8sLk6/qo7RTScQYIGKgeQ5IuQRtrTQg==",
+ "dependencies": {
+ "@auth/core": "0.34.2"
+ },
+ "peerDependencies": {
+ "@simplewebauthn/browser": "^9.0.1",
+ "@simplewebauthn/server": "^9.0.2",
+ "next": "^14.0.0-0 || ^15.0.0-0",
+ "nodemailer": "^6.6.5",
+ "react": "^18.2.0 || ^19.0.0-0"
+ },
+ "peerDependenciesMeta": {
+ "@simplewebauthn/browser": {
+ "optional": true
+ },
+ "@simplewebauthn/server": {
+ "optional": true
+ },
+ "nodemailer": {
+ "optional": true
+ }
+ }
+ },
"node_modules/next-themes": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/next-themes/-/next-themes-0.2.1.tgz",
@@ -8684,6 +8770,14 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/oauth4webapi": {
+ "version": "2.12.0",
+ "resolved": "https://registry.npmjs.org/oauth4webapi/-/oauth4webapi-2.12.0.tgz",
+ "integrity": "sha512-WFmcHzhFtq2Ar91crpGQZUD8DS0SG7Zti1AgbansUAfdpIsoRXE+hcMNi8MW6bGNNObWis0x8BZRl6K+FR4oQg==",
+ "funding": {
+ "url": "https://github.com/sponsors/panva"
+ }
+ },
"node_modules/object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
@@ -9244,6 +9338,26 @@
"resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
"integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="
},
+ "node_modules/preact": {
+ "version": "10.11.3",
+ "resolved": "https://registry.npmjs.org/preact/-/preact-10.11.3.tgz",
+ "integrity": "sha512-eY93IVpod/zG3uMF22Unl8h9KkrcKIRs2EGar8hwLZZDU1lkjph303V9HZBwufh2s736U6VXuhD109LYqPoffg==",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/preact"
+ }
+ },
+ "node_modules/preact-render-to-string": {
+ "version": "5.2.3",
+ "resolved": "https://registry.npmjs.org/preact-render-to-string/-/preact-render-to-string-5.2.3.tgz",
+ "integrity": "sha512-aPDxUn5o3GhWdtJtW0svRC2SS/l8D9MAgo2+AWml+BhDImb27ALf04Q2d+AHqUUOc6RdSXFIBVa2gxzgMKgtZA==",
+ "dependencies": {
+ "pretty-format": "^3.8.0"
+ },
+ "peerDependencies": {
+ "preact": ">=10"
+ }
+ },
"node_modules/prelude-ls": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
@@ -9281,6 +9395,11 @@
"node": ">=6.0.0"
}
},
+ "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/prompts": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz",
diff --git a/package.json b/package.json
index 2f7d6287ab..8f2d01c7c9 100644
--- a/package.json
+++ b/package.json
@@ -19,6 +19,7 @@
"intl-messageformat": "^10.5.0",
"lucide-react": "^0.417.0",
"next": "14.2.3",
+ "next-auth": "^5.0.0-beta.20",
"next-themes": "^0.2.1",
"react": "18.3.1",
"react-dom": "18.3.1",