auth stuff (prototype)
This commit is contained in:
parent
13426f34eb
commit
2bf719d1e3
|
@ -11,6 +11,7 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@radix-ui/themes": "^2.0.3",
|
"@radix-ui/themes": "^2.0.3",
|
||||||
"next": "14.0.4",
|
"next": "14.0.4",
|
||||||
|
"next-auth": "^4.24.5",
|
||||||
"react": "^18",
|
"react": "^18",
|
||||||
"react-dom": "^18"
|
"react-dom": "^18"
|
||||||
},
|
},
|
||||||
|
|
|
@ -11,6 +11,9 @@ dependencies:
|
||||||
next:
|
next:
|
||||||
specifier: 14.0.4
|
specifier: 14.0.4
|
||||||
version: 14.0.4(react-dom@18.2.0)(react@18.2.0)
|
version: 14.0.4(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
next-auth:
|
||||||
|
specifier: ^4.24.5
|
||||||
|
version: 4.24.5(next@14.0.4)(react-dom@18.2.0)(react@18.2.0)
|
||||||
react:
|
react:
|
||||||
specifier: ^18
|
specifier: ^18
|
||||||
version: 18.2.0
|
version: 18.2.0
|
||||||
|
@ -304,6 +307,10 @@ packages:
|
||||||
fastq: 1.16.0
|
fastq: 1.16.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@panva/hkdf@1.1.1:
|
||||||
|
resolution: {integrity: sha512-dhPeilub1NuIG0X5Kvhh9lH4iW3ZsHlnzwgwbOlgwQ2wG1IqFzsgHqmKPk3WzsdWAeaxKJxgM0+W433RmN45GA==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@pkgjs/parseargs@0.11.0:
|
/@pkgjs/parseargs@0.11.0:
|
||||||
resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
|
resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
|
||||||
engines: {node: '>=14'}
|
engines: {node: '>=14'}
|
||||||
|
@ -1821,6 +1828,11 @@ packages:
|
||||||
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
|
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/cookie@0.5.0:
|
||||||
|
resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==}
|
||||||
|
engines: {node: '>= 0.6'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/cross-spawn@7.0.3:
|
/cross-spawn@7.0.3:
|
||||||
resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
|
resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
|
||||||
engines: {node: '>= 8'}
|
engines: {node: '>= 8'}
|
||||||
|
@ -2835,6 +2847,10 @@ packages:
|
||||||
hasBin: true
|
hasBin: true
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/jose@4.15.4:
|
||||||
|
resolution: {integrity: sha512-W+oqK4H+r5sITxfxpSU+MMdr/YSWGvgZMQDIsNoBDGGy4i7GBPTtvFKibQzW06n3U3TqHjhvBJsirShsEJ6eeQ==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/js-tokens@4.0.0:
|
/js-tokens@4.0.0:
|
||||||
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
|
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
|
||||||
|
|
||||||
|
@ -2940,7 +2956,6 @@ packages:
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
dependencies:
|
dependencies:
|
||||||
yallist: 4.0.0
|
yallist: 4.0.0
|
||||||
dev: true
|
|
||||||
|
|
||||||
/merge2@1.4.1:
|
/merge2@1.4.1:
|
||||||
resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
|
resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
|
||||||
|
@ -3002,6 +3017,31 @@ packages:
|
||||||
resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
|
resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/next-auth@4.24.5(next@14.0.4)(react-dom@18.2.0)(react@18.2.0):
|
||||||
|
resolution: {integrity: sha512-3RafV3XbfIKk6rF6GlLE4/KxjTcuMCifqrmD+98ejFq73SRoj2rmzoca8u764977lH/Q7jo6Xu6yM+Re1Mz/Og==}
|
||||||
|
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
|
||||||
|
dependencies:
|
||||||
|
'@babel/runtime': 7.23.8
|
||||||
|
'@panva/hkdf': 1.1.1
|
||||||
|
cookie: 0.5.0
|
||||||
|
jose: 4.15.4
|
||||||
|
next: 14.0.4(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
oauth: 0.9.15
|
||||||
|
openid-client: 5.6.4
|
||||||
|
preact: 10.19.3
|
||||||
|
preact-render-to-string: 5.2.6(preact@10.19.3)
|
||||||
|
react: 18.2.0
|
||||||
|
react-dom: 18.2.0(react@18.2.0)
|
||||||
|
uuid: 8.3.2
|
||||||
|
dev: false
|
||||||
|
|
||||||
/next@14.0.4(react-dom@18.2.0)(react@18.2.0):
|
/next@14.0.4(react-dom@18.2.0)(react@18.2.0):
|
||||||
resolution: {integrity: sha512-qbwypnM7327SadwFtxXnQdGiKpkuhaRLE2uq62/nRul9cj9KhQ5LhHmlziTNqUidZotw/Q1I9OjirBROdUJNgA==}
|
resolution: {integrity: sha512-qbwypnM7327SadwFtxXnQdGiKpkuhaRLE2uq62/nRul9cj9KhQ5LhHmlziTNqUidZotw/Q1I9OjirBROdUJNgA==}
|
||||||
engines: {node: '>=18.17.0'}
|
engines: {node: '>=18.17.0'}
|
||||||
|
@ -3056,11 +3096,20 @@ packages:
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/oauth@0.9.15:
|
||||||
|
resolution: {integrity: sha512-a5ERWK1kh38ExDEfoO6qUHJb32rd7aYmPHuyCu3Fta/cnICvYmgd2uhuKXvPD+PXB+gCEYYEaQdIRAjCOwAKNA==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/object-assign@4.1.1:
|
/object-assign@4.1.1:
|
||||||
resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
|
resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/object-hash@2.2.0:
|
||||||
|
resolution: {integrity: sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==}
|
||||||
|
engines: {node: '>= 6'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/object-hash@3.0.0:
|
/object-hash@3.0.0:
|
||||||
resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==}
|
resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==}
|
||||||
engines: {node: '>= 6'}
|
engines: {node: '>= 6'}
|
||||||
|
@ -3128,12 +3177,26 @@ packages:
|
||||||
es-abstract: 1.22.3
|
es-abstract: 1.22.3
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/oidc-token-hash@5.0.3:
|
||||||
|
resolution: {integrity: sha512-IF4PcGgzAr6XXSff26Sk/+P4KZFJVuHAJZj3wgO3vX2bMdNVp/QXTP3P7CEm9V1IdG8lDLY3HhiqpsE/nOwpPw==}
|
||||||
|
engines: {node: ^10.13.0 || >=12.0.0}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/once@1.4.0:
|
/once@1.4.0:
|
||||||
resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
|
resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
|
||||||
dependencies:
|
dependencies:
|
||||||
wrappy: 1.0.2
|
wrappy: 1.0.2
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/openid-client@5.6.4:
|
||||||
|
resolution: {integrity: sha512-T1h3B10BRPKfcObdBklX639tVz+xh34O7GjofqrqiAQdm7eHsQ00ih18x6wuJ/E6FxdtS2u3FmUGPDeEcMwzNA==}
|
||||||
|
dependencies:
|
||||||
|
jose: 4.15.4
|
||||||
|
lru-cache: 6.0.0
|
||||||
|
object-hash: 2.2.0
|
||||||
|
oidc-token-hash: 5.0.3
|
||||||
|
dev: false
|
||||||
|
|
||||||
/optionator@0.9.3:
|
/optionator@0.9.3:
|
||||||
resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==}
|
resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==}
|
||||||
engines: {node: '>= 0.8.0'}
|
engines: {node: '>= 0.8.0'}
|
||||||
|
@ -3296,11 +3359,28 @@ packages:
|
||||||
source-map-js: 1.0.2
|
source-map-js: 1.0.2
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/preact-render-to-string@5.2.6(preact@10.19.3):
|
||||||
|
resolution: {integrity: sha512-JyhErpYOvBV1hEPwIxc/fHWXPfnEGdRKxc8gFdAZ7XV4tlzyzG847XAyEZqoDnynP88akM4eaHcSOzNcLWFguw==}
|
||||||
|
peerDependencies:
|
||||||
|
preact: '>=10'
|
||||||
|
dependencies:
|
||||||
|
preact: 10.19.3
|
||||||
|
pretty-format: 3.8.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/preact@10.19.3:
|
||||||
|
resolution: {integrity: sha512-nHHTeFVBTHRGxJXKkKu5hT8C/YWBkPso4/Gad6xuj5dbptt9iF9NZr9pHbPhBrnT2klheu7mHTxTZ/LjwJiEiQ==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/prelude-ls@1.2.1:
|
/prelude-ls@1.2.1:
|
||||||
resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
|
resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
|
||||||
engines: {node: '>= 0.8.0'}
|
engines: {node: '>= 0.8.0'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/pretty-format@3.8.0:
|
||||||
|
resolution: {integrity: sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/prop-types@15.8.1:
|
/prop-types@15.8.1:
|
||||||
resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==}
|
resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==}
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -3901,6 +3981,11 @@ packages:
|
||||||
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
|
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/uuid@8.3.2:
|
||||||
|
resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==}
|
||||||
|
hasBin: true
|
||||||
|
dev: false
|
||||||
|
|
||||||
/watchpack@2.4.0:
|
/watchpack@2.4.0:
|
||||||
resolution: {integrity: sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==}
|
resolution: {integrity: sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==}
|
||||||
engines: {node: '>=10.13.0'}
|
engines: {node: '>=10.13.0'}
|
||||||
|
@ -3989,7 +4074,6 @@ packages:
|
||||||
|
|
||||||
/yallist@4.0.0:
|
/yallist@4.0.0:
|
||||||
resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
|
resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
|
||||||
dev: true
|
|
||||||
|
|
||||||
/yaml@2.3.4:
|
/yaml@2.3.4:
|
||||||
resolution: {integrity: sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==}
|
resolution: {integrity: sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==}
|
||||||
|
|
42
src/app/api/auth/[...nextauth]/route.ts
Normal file
42
src/app/api/auth/[...nextauth]/route.ts
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
import NextAuth from "next-auth";
|
||||||
|
import CredentialProvider from "next-auth/providers/credentials";
|
||||||
|
import { sha256sum } from "@/lib/util";
|
||||||
|
|
||||||
|
export const authOptions = {
|
||||||
|
providers: [
|
||||||
|
CredentialProvider({
|
||||||
|
name: 'Mail account',
|
||||||
|
credentials: {
|
||||||
|
email: { label: "E-Mail", type: "email", placeholder: "webmistress@amogus.cloud" },
|
||||||
|
password: { label: "Password", type: "password" },
|
||||||
|
},
|
||||||
|
async authorize(credentials, req) {
|
||||||
|
console.log(`Authentication attempt for ${credentials?.email}`);
|
||||||
|
|
||||||
|
// todo
|
||||||
|
if (credentials?.email == "balls@fortnite.org" && credentials.password == "ballsack obliteration") {
|
||||||
|
console.log(`[${credentials.email}] Authentication succeeded`);
|
||||||
|
const emailHash = sha256sum(credentials.email.trim().toLowerCase());
|
||||||
|
|
||||||
|
// todo fetch name from gravatar (why not)
|
||||||
|
//const res = await fetch(`https://gravatar.com/${emailHash}`).catch(() => null);
|
||||||
|
//const profile = await res?.json().catch(() => null);
|
||||||
|
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: credentials.email,
|
||||||
|
email: credentials.email,
|
||||||
|
image: `https://gravatar.com/avatar/${emailHash}?d=identicon`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`[${credentials?.email}] Authentication failed`);
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
const handler = NextAuth(authOptions);
|
||||||
|
|
||||||
|
export { handler as GET, handler as POST };
|
|
@ -2,6 +2,8 @@ import type { Metadata } from 'next';
|
||||||
import { Inter } from 'next/font/google';
|
import { Inter } from 'next/font/google';
|
||||||
import ThemeWrapper from '@/lib/components/ThemeWrapper';
|
import ThemeWrapper from '@/lib/components/ThemeWrapper';
|
||||||
import './globals.css';
|
import './globals.css';
|
||||||
|
import AuthWrapper from '@/lib/components/AuthWrapper';
|
||||||
|
import { getServerSession } from 'next-auth';
|
||||||
|
|
||||||
const inter = Inter({ subsets: ['latin'] });
|
const inter = Inter({ subsets: ['latin'] });
|
||||||
|
|
||||||
|
@ -10,7 +12,7 @@ export const metadata: Metadata = {
|
||||||
description: 'Generated by create next app',
|
description: 'Generated by create next app',
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function RootLayout({
|
export default async function RootLayout({
|
||||||
children,
|
children,
|
||||||
}: {
|
}: {
|
||||||
children: React.ReactNode
|
children: React.ReactNode
|
||||||
|
@ -18,9 +20,11 @@ export default function RootLayout({
|
||||||
return (
|
return (
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<body className={`${inter.className} p-4`}>
|
<body className={`${inter.className} p-4`}>
|
||||||
<ThemeWrapper>
|
<AuthWrapper session={await getServerSession()}>
|
||||||
{children}
|
<ThemeWrapper>
|
||||||
</ThemeWrapper>
|
{children}
|
||||||
|
</ThemeWrapper>
|
||||||
|
</AuthWrapper>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,11 +1,39 @@
|
||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { Heading } from '@radix-ui/themes';
|
import { Avatar, Card, Flex, Heading, Text, Box, Button } from '@radix-ui/themes';
|
||||||
|
import { useSession } from 'next-auth/react';
|
||||||
|
import Link from 'next/link';
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
|
const session = useSession().data;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Heading size="9">Welcome back.</Heading>
|
<Heading size="9">Welcome back.</Heading>
|
||||||
|
|
||||||
|
{session?.user && (
|
||||||
|
<Card className='w-fit'>
|
||||||
|
<Flex gap="3" align="center">
|
||||||
|
<Avatar
|
||||||
|
size="3"
|
||||||
|
src={session.user.image ?? "/favicon.ico"}
|
||||||
|
radius='full'
|
||||||
|
fallback={session.user.name?.slice(0, 1) || "@"}
|
||||||
|
/>
|
||||||
|
<Box>
|
||||||
|
<Text as="div" size="2" weight="bold">
|
||||||
|
{session.user.email}
|
||||||
|
</Text>
|
||||||
|
</Box>
|
||||||
|
</Flex>
|
||||||
|
</Card>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<Link href={session?.user ? "/api/auth/signout" : "/api/auth/signin"}>
|
||||||
|
<Button variant='soft'>
|
||||||
|
Sign {session?.user ? "out" : "in"}
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
18
src/lib/components/AuthWrapper.tsx
Normal file
18
src/lib/components/AuthWrapper.tsx
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
"use client";
|
||||||
|
|
||||||
|
import { Session } from "next-auth";
|
||||||
|
import { SessionProvider } from "next-auth/react";
|
||||||
|
|
||||||
|
export default function AuthWrapper({
|
||||||
|
children,
|
||||||
|
session,
|
||||||
|
}: {
|
||||||
|
children: React.ReactNode,
|
||||||
|
session: Session | null,
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<SessionProvider session={session}>
|
||||||
|
{children}
|
||||||
|
</SessionProvider>
|
||||||
|
);
|
||||||
|
}
|
7
src/lib/util.ts
Normal file
7
src/lib/util.ts
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
import crypto from 'node:crypto';
|
||||||
|
|
||||||
|
export function sha256sum(input: any) {
|
||||||
|
const hash = crypto.createHash('sha256');
|
||||||
|
hash.update(input);
|
||||||
|
return hash.digest('hex');
|
||||||
|
}
|
Loading…
Reference in a new issue