Finish next-auth proof of concept

This commit is contained in:
Sam Becker 2023-09-06 00:18:10 -05:00
parent 3254d40f75
commit a8d1d0dc15
13 changed files with 196 additions and 435 deletions

View File

@ -8,7 +8,6 @@
"lint": "next lint"
},
"dependencies": {
"@clerk/nextjs": "^4.23.4",
"@tailwindcss/forms": "^0.5.6",
"@types/node": "^20.5.9",
"@types/react": "18.2.21",
@ -26,6 +25,7 @@
"eslint-config-next": "13.4.19",
"framer-motion": "^10.16.3",
"next": "^13.4.19",
"next-auth": "0.0.0-manual.ffd05533",
"next-themes": "^0.2.1",
"postcss": "8.4.29",
"react": "18.2.0",
@ -36,5 +36,10 @@
"tailwindcss": "3.3.3",
"ts-exif-parser": "^0.2.2",
"typescript": "5.2.2"
},
"pnpm": {
"overrides": {
"@auth/core": "0.13.0"
}
}
}

423
pnpm-lock.yaml generated
View File

@ -1,7 +1,9 @@
lockfileVersion: 5.4
overrides:
'@auth/core': 0.13.0
specifiers:
'@clerk/nextjs': ^4.23.4
'@tailwindcss/forms': ^0.5.6
'@types/node': ^20.5.9
'@types/react': 18.2.21
@ -19,6 +21,7 @@ specifiers:
eslint-config-next: 13.4.19
framer-motion: ^10.16.3
next: ^13.4.19
next-auth: 0.0.0-manual.ffd05533
next-themes: ^0.2.1
postcss: 8.4.29
react: 18.2.0
@ -31,7 +34,6 @@ specifiers:
typescript: 5.2.2
dependencies:
'@clerk/nextjs': 4.23.4_m2l4knchnqa6bzxbbtfxlzoxdy
'@tailwindcss/forms': 0.5.6_tailwindcss@3.3.3
'@types/node': 20.5.9
'@types/react': 18.2.21
@ -49,6 +51,7 @@ dependencies:
eslint-config-next: 13.4.19_w2g2uv42be7wag4oipwkfv43p4
framer-motion: 10.16.3_biqbaboplfbrettd7655fr4n2y
next: 13.4.19_biqbaboplfbrettd7655fr4n2y
next-auth: 0.0.0-manual.ffd05533_next@13.4.19+react@18.2.0
next-themes: 0.2.1_m2l4knchnqa6bzxbbtfxlzoxdy
postcss: 8.4.29
react: 18.2.0
@ -72,6 +75,22 @@ packages:
engines: {node: '>=10'}
dev: false
/@auth/core/0.13.0:
resolution: {integrity: sha512-StjrzUenaKfMr68kmvhiqfY0xvxRvg8wllmem9JAULpPAAAt3uwRUDXICWOP/PfWB4OZ2wQT7rgfm0n42b+Mjg==}
peerDependencies:
nodemailer: ^6.8.0
peerDependenciesMeta:
nodemailer:
optional: true
dependencies:
'@panva/hkdf': 1.1.1
cookie: 0.5.0
jose: 4.14.6
oauth4webapi: 2.3.0
preact: 10.11.3
preact-render-to-string: 5.2.3_preact@10.11.3
dev: false
/@babel/code-frame/7.22.10:
resolution: {integrity: sha512-/KKIMG4UEL35WmI9OlvMhurwtytjvXoFcGNrOvyG9zIzA8YmPjVtIZUf7b05+TPO7G7/GEmLHDaoCgACHl9hhA==}
engines: {node: '>=6.9.0'}
@ -101,83 +120,6 @@ packages:
regenerator-runtime: 0.14.0
dev: false
/@clerk/backend/0.28.1:
resolution: {integrity: sha512-L8YT9wCy42yA1q5sxovgmVhmGwUw1/lUY35Yy1e0sDC8FsbdW7763RgXukFvCCFyYrjXTTcfHH6VG/IndbHsTw==}
engines: {node: '>=14'}
dependencies:
'@clerk/types': 3.50.0
'@peculiar/webcrypto': 1.4.1
'@types/node': 16.18.6
cookie: 0.5.0
deepmerge: 4.2.2
node-fetch-native: 1.0.1
snakecase-keys: 5.4.4
tslib: 2.4.1
dev: false
/@clerk/clerk-react/4.24.1_react@18.2.0:
resolution: {integrity: sha512-Xo1Y+jxGs01/v/vtfK0650Ie4ACIseAKnTX02TnXCvJAfiByGVZ6to5DyifGUcvplc7PVTy/NHRXUWSvwV+32A==}
engines: {node: '>=14'}
peerDependencies:
react: '>=16'
dependencies:
'@clerk/shared': 0.22.0_react@18.2.0
'@clerk/types': 3.50.0
react: 18.2.0
tslib: 2.4.1
dev: false
/@clerk/clerk-sdk-node/4.12.4:
resolution: {integrity: sha512-ISXdeI+uMnydbzmjV0ONdsKNACUklpo68kz2j8EnVuxYMnzSuAevpyF3/SQlsNpiG5e4ZTT8EmKMaandUSKKDw==}
engines: {node: '>=14'}
dependencies:
'@clerk/backend': 0.28.1
'@clerk/types': 3.50.0
'@types/cookies': 0.7.7
'@types/express': 4.17.14
'@types/node-fetch': 2.6.2
camelcase-keys: 6.2.2
snakecase-keys: 3.2.1
tslib: 2.4.1
dev: false
/@clerk/nextjs/4.23.4_m2l4knchnqa6bzxbbtfxlzoxdy:
resolution: {integrity: sha512-Alee+R1QiXKbIrVySGTZiAefoS4CE6Dmvj0LvG7n2UP3UhuEoowoz5N1rTTW3qeAffrqJepJOW8UB6jn0ac7Mg==}
engines: {node: '>=14'}
peerDependencies:
next: '>=10'
react: ^17.0.2 || ^18.0.0-0
react-dom: ^17.0.2 || ^18.0.0-0
dependencies:
'@clerk/backend': 0.28.1
'@clerk/clerk-react': 4.24.1_react@18.2.0
'@clerk/clerk-sdk-node': 4.12.4
'@clerk/types': 3.50.0
next: 13.4.19_biqbaboplfbrettd7655fr4n2y
path-to-regexp: 6.2.1
react: 18.2.0
react-dom: 18.2.0_react@18.2.0
tslib: 2.4.1
dev: false
/@clerk/shared/0.22.0_react@18.2.0:
resolution: {integrity: sha512-AHPypu9gZ3v44PRqiMA56c+YNLc2IzLaPUyiYFYU+xeH/R+wqzGp7OxZoZr/kmzgA8taiVl/bjixWgpuZwzI3A==}
peerDependencies:
react: '>=16'
dependencies:
glob-to-regexp: 0.4.1
js-cookie: 3.0.1
react: 18.2.0
swr: 2.2.0_react@18.2.0
dev: false
/@clerk/types/3.50.0:
resolution: {integrity: sha512-3TWalDWPTFToXC/W07QUIBN96TA+4dR3YLBvwr9U2Z4RVG9in9HW4CTC6aHTnJ2kVtTcgDkXjDKeVKS1GjPCcA==}
engines: {node: '>=14'}
dependencies:
csstype: 3.1.1
dev: false
/@emotion/is-prop-valid/0.8.8:
resolution: {integrity: sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==}
requiresBuild: true
@ -437,30 +379,8 @@ packages:
fastq: 1.15.0
dev: false
/@peculiar/asn1-schema/2.3.6:
resolution: {integrity: sha512-izNRxPoaeJeg/AyH8hER6s+H7p4itk+03QCa4sbxI3lNdseQYCuxzgsuNK8bTXChtLTjpJz6NmXKA73qLa3rCA==}
dependencies:
asn1js: 3.0.5
pvtsutils: 1.3.3
tslib: 2.6.1
dev: false
/@peculiar/json-schema/1.1.12:
resolution: {integrity: sha512-coUfuoMeIB7B8/NMekxaDzLhaYmp0HZNPEjYRm9goRou8UZIC3z21s0sL9AWoCw4EG876QyO3kYrc61WNF9B/w==}
engines: {node: '>=8.0.0'}
dependencies:
tslib: 2.6.1
dev: false
/@peculiar/webcrypto/1.4.1:
resolution: {integrity: sha512-eK4C6WTNYxoI7JOabMoZICiyqRRtJB220bh0Mbj5RwRycleZf9BPyZoxsTvpP0FpmVS2aS13NKOuh5/tN3sIRw==}
engines: {node: '>=10.12.0'}
dependencies:
'@peculiar/asn1-schema': 2.3.6
'@peculiar/json-schema': 1.1.12
pvtsutils: 1.3.3
tslib: 2.6.1
webcrypto-core: 1.7.7
/@panva/hkdf/1.1.1:
resolution: {integrity: sha512-dhPeilub1NuIG0X5Kvhh9lH4iW3ZsHlnzwgwbOlgwQ2wG1IqFzsgHqmKPk3WzsdWAeaxKJxgM0+W433RmN45GA==}
dev: false
/@resvg/resvg-wasm/2.4.1:
@ -517,50 +437,6 @@ packages:
engines: {node: '>= 10'}
dev: false
/@types/body-parser/1.19.2:
resolution: {integrity: sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==}
dependencies:
'@types/connect': 3.4.35
'@types/node': 20.5.9
dev: false
/@types/connect/3.4.35:
resolution: {integrity: sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==}
dependencies:
'@types/node': 20.5.9
dev: false
/@types/cookies/0.7.7:
resolution: {integrity: sha512-h7BcvPUogWbKCzBR2lY4oqaZbO3jXZksexYJVFvkrFeLgbZjQkU4x8pRq6eg2MHXQhY0McQdqmmsxRWlVAHooA==}
dependencies:
'@types/connect': 3.4.35
'@types/express': 4.17.14
'@types/keygrip': 1.0.2
'@types/node': 20.5.9
dev: false
/@types/express-serve-static-core/4.17.35:
resolution: {integrity: sha512-wALWQwrgiB2AWTT91CB62b6Yt0sNHpznUXeZEcnPU3DRdlDIz74x8Qg1UUYKSVFi+va5vKOLYRBI1bRKiLLKIg==}
dependencies:
'@types/node': 20.5.9
'@types/qs': 6.9.7
'@types/range-parser': 1.2.4
'@types/send': 0.17.1
dev: false
/@types/express/4.17.14:
resolution: {integrity: sha512-TEbt+vaPFQ+xpxFLFssxUDXj5cWCxZJjIcB7Yg0k0GMHGtgtQgpvx/MUQUeAkNbA9AAGrwkAsoeItdTgS7FMyg==}
dependencies:
'@types/body-parser': 1.19.2
'@types/express-serve-static-core': 4.17.35
'@types/qs': 6.9.7
'@types/serve-static': 1.15.2
dev: false
/@types/http-errors/2.0.1:
resolution: {integrity: sha512-/K3ds8TRAfBvi5vfjuz8y6+GiAYBZ0x4tXv1Av6CWBWn0IlADc+ZX9pMq7oU0fNQPnBwIZl3rmeLp6SBApbxSQ==}
dev: false
/@types/istanbul-lib-coverage/2.0.4:
resolution: {integrity: sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==}
dev: false
@ -593,29 +469,6 @@ packages:
resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==}
dev: false
/@types/keygrip/1.0.2:
resolution: {integrity: sha512-GJhpTepz2udxGexqos8wgaBx4I/zWIDPh/KOGEwAqtuGDkOUJu5eFvwmdBX4AmB8Odsr+9pHCQqiAqDL/yKMKw==}
dev: false
/@types/mime/1.3.2:
resolution: {integrity: sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==}
dev: false
/@types/mime/3.0.1:
resolution: {integrity: sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==}
dev: false
/@types/node-fetch/2.6.2:
resolution: {integrity: sha512-DHqhlq5jeESLy19TYhLakJ07kNumXWjcDdxXsLUMJZ6ue8VZJj4kLPQVE/2mdHh3xZziNF1xppu5lwmS53HR+A==}
dependencies:
'@types/node': 20.5.9
form-data: 3.0.1
dev: false
/@types/node/16.18.6:
resolution: {integrity: sha512-vmYJF0REqDyyU0gviezF/KHq/fYaUbFhkcNbQCuPGFQj6VTbXuHZoxs/Y7mutWe73C8AC6l9fFu8mSYiBAqkGA==}
dev: false
/@types/node/20.5.9:
resolution: {integrity: sha512-PcGNd//40kHAS3sTlzKB9C9XL4K0sTup8nbG5lC14kzEteTNuAFh9u5nA0o5TWnSG2r/JNPRXFVcHJIIeRlmqQ==}
dev: false
@ -632,14 +485,6 @@ packages:
resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==}
dev: false
/@types/qs/6.9.7:
resolution: {integrity: sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==}
dev: false
/@types/range-parser/1.2.4:
resolution: {integrity: sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==}
dev: false
/@types/react-dom/18.2.7:
resolution: {integrity: sha512-GRaAEriuT4zp9N4p1i8BDBYmEyfo+xQ3yHjJU4eiK5NDa1RmUZG+unZABUTK4/Ox/M+GaHwb6Ow8rUITrtjszA==}
dependencies:
@ -662,21 +507,6 @@ packages:
resolution: {integrity: sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==}
dev: false
/@types/send/0.17.1:
resolution: {integrity: sha512-Cwo8LE/0rnvX7kIIa3QHCkcuF21c05Ayb0ZfxPiv0W8VRiZiNW/WuRupHKpqqGVGf7SUA44QSOUKaEd9lIrd/Q==}
dependencies:
'@types/mime': 1.3.2
'@types/node': 20.5.9
dev: false
/@types/serve-static/1.15.2:
resolution: {integrity: sha512-J2LqtvFYCzaj8pVYKw8klQXrLLk7TBZmQ4ShlcdkELFKGwGMfevMLneMMRkMgZxotOD9wg497LpC7O8PcvAmfw==}
dependencies:
'@types/http-errors': 2.0.1
'@types/mime': 3.0.1
'@types/node': 20.5.9
dev: false
/@types/stack-utils/2.0.1:
resolution: {integrity: sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==}
dev: false
@ -1040,15 +870,6 @@ packages:
is-shared-array-buffer: 1.0.2
dev: false
/asn1js/3.0.5:
resolution: {integrity: sha512-FVnvrKJwpt9LP2lAMl8qZswRNm3T4q9CON+bxldk2iwk3FFpuwhx2FfinyitizWHsVYyaY+y5JzDR0rCMV5yTQ==}
engines: {node: '>=12.0.0'}
dependencies:
pvtsutils: 1.3.3
pvutils: 1.1.3
tslib: 2.6.1
dev: false
/ast-types-flow/0.0.7:
resolution: {integrity: sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==}
dev: false
@ -1166,15 +987,6 @@ packages:
engines: {node: '>= 6'}
dev: false
/camelcase-keys/6.2.2:
resolution: {integrity: sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==}
engines: {node: '>=8'}
dependencies:
camelcase: 5.3.1
map-obj: 4.3.0
quick-lru: 4.0.1
dev: false
/camelcase-keys/9.0.0:
resolution: {integrity: sha512-GdZ92DNXdcfFB/5Kq4O82EL6UW5neiRBhfNP5M3mGw7CX2sPDbVA04ZPLsqbp7oMi2l3m2I0AZ/kFP5Nk5kopA==}
engines: {node: '>=16'}
@ -1185,11 +997,6 @@ packages:
type-fest: 4.2.0
dev: false
/camelcase/5.3.1:
resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==}
engines: {node: '>=6'}
dev: false
/camelcase/8.0.0:
resolution: {integrity: sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==}
engines: {node: '>=16'}
@ -1337,10 +1144,6 @@ packages:
cssom: 0.3.8
dev: false
/csstype/3.1.1:
resolution: {integrity: sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==}
dev: false
/csstype/3.1.2:
resolution: {integrity: sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==}
dev: false
@ -1396,11 +1199,6 @@ packages:
resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
dev: false
/deepmerge/4.2.2:
resolution: {integrity: sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==}
engines: {node: '>=0.10.0'}
dev: false
/define-properties/1.2.0:
resolution: {integrity: sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==}
engines: {node: '>= 0.4'}
@ -1455,13 +1253,6 @@ packages:
webidl-conversions: 7.0.0
dev: false
/dot-case/3.0.4:
resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==}
dependencies:
no-case: 3.0.4
tslib: 2.6.1
dev: false
/electron-to-chromium/1.4.492:
resolution: {integrity: sha512-36K9b/6skMVwAIEsC7GiQ8I8N3soCALVSHqWHzNDtGemAcI9Xu8hP02cywWM0A794rTHm0b0zHPeLJHtgFVamQ==}
dev: false
@ -1965,15 +1756,6 @@ packages:
is-callable: 1.2.7
dev: false
/form-data/3.0.1:
resolution: {integrity: sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==}
engines: {node: '>= 6'}
dependencies:
asynckit: 0.4.0
combined-stream: 1.0.8
mime-types: 2.1.35
dev: false
/form-data/4.0.0:
resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==}
engines: {node: '>= 6'}
@ -2518,9 +2300,8 @@ packages:
hasBin: true
dev: false
/js-cookie/3.0.1:
resolution: {integrity: sha512-+0rgsUXZu4ncpPxRL+lNEptWMOWl9etvPHc/koSRp6MPwpRYAhmk0dUG00J4bxVV3r9uUzfo24wW0knS07SKSw==}
engines: {node: '>=12'}
/jose/4.14.6:
resolution: {integrity: sha512-EqJPEUlZD0/CSUMubKtMaYUOtWe91tZXTWMJZoKSbLk+KtdhNdcvppH8lA9XwVu2V4Ailvsj0GBZJ2ZwDjfesQ==}
dev: false
/js-tokens/4.0.0:
@ -2652,12 +2433,6 @@ packages:
js-tokens: 4.0.0
dev: false
/lower-case/2.0.2:
resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==}
dependencies:
tslib: 2.6.1
dev: false
/lru-cache/6.0.0:
resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==}
engines: {node: '>=10'}
@ -2665,11 +2440,6 @@ packages:
yallist: 4.0.0
dev: false
/map-obj/4.3.0:
resolution: {integrity: sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==}
engines: {node: '>=8'}
dev: false
/map-obj/5.0.0:
resolution: {integrity: sha512-2L3MIgJynYrZ3TYMriLDLWocz15okFakV6J12HXvMXDHui2x/zgChzg1u9mFFGbbGWE+GsLpQByt4POb9Or+uA==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
@ -2741,6 +2511,21 @@ packages:
resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
dev: false
/next-auth/0.0.0-manual.ffd05533_next@13.4.19+react@18.2.0:
resolution: {integrity: sha512-oTdpOP93rzABms/Qgp3z0udQG3tCZ3JxOCnwU04xLgX/xnC8+HuDHct7IcEpz+zxhZp6jxN0tdVkMCs5kubUfw==}
peerDependencies:
next: ^13.4.13
nodemailer: ^6.6.5
react: ^18.2.0
peerDependenciesMeta:
nodemailer:
optional: true
dependencies:
'@auth/core': 0.13.0
next: 13.4.19_biqbaboplfbrettd7655fr4n2y
react: 18.2.0
dev: false
/next-themes/0.2.1_m2l4knchnqa6bzxbbtfxlzoxdy:
resolution: {integrity: sha512-B+AKNfYNIzh0vqQQKqQItTS8evEouKD7H5Hj3kmuPERwddR2TxvDSFZuTj6T7Jfn1oyeUyJMydPl1Bkxkh0W7A==}
peerDependencies:
@ -2793,17 +2578,6 @@ packages:
- babel-plugin-macros
dev: false
/no-case/3.0.4:
resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==}
dependencies:
lower-case: 2.0.2
tslib: 2.6.1
dev: false
/node-fetch-native/1.0.1:
resolution: {integrity: sha512-VzW+TAk2wE4X9maiKMlT+GsPU4OMmR1U9CrHSmd3DFLn2IcZ9VJ6M6BBugGfYUnPCLSYxXdZy17M0BEJyhUTwg==}
dev: false
/node-gyp-build/4.6.0:
resolution: {integrity: sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==}
hasBin: true
@ -2827,6 +2601,10 @@ packages:
resolution: {integrity: sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ==}
dev: false
/oauth4webapi/2.3.0:
resolution: {integrity: sha512-JGkb5doGrwzVDuHwgrR4nHJayzN4h59VCed6EW8Tql6iHDfZIabCJvg6wtbn5q6pyB2hZruI3b77Nudvq7NmvA==}
dev: false
/object-assign/4.1.1:
resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
engines: {node: '>=0.10.0'}
@ -2974,10 +2752,6 @@ packages:
resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
dev: false
/path-to-regexp/6.2.1:
resolution: {integrity: sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==}
dev: false
/path-type/4.0.0:
resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
engines: {node: '>=8'}
@ -3123,6 +2897,19 @@ packages:
xtend: 4.0.2
dev: false
/preact-render-to-string/5.2.3_preact@10.11.3:
resolution: {integrity: sha512-aPDxUn5o3GhWdtJtW0svRC2SS/l8D9MAgo2+AWml+BhDImb27ALf04Q2d+AHqUUOc6RdSXFIBVa2gxzgMKgtZA==}
peerDependencies:
preact: '>=10'
dependencies:
preact: 10.11.3
pretty-format: 3.8.0
dev: false
/preact/10.11.3:
resolution: {integrity: sha512-eY93IVpod/zG3uMF22Unl8h9KkrcKIRs2EGar8hwLZZDU1lkjph303V9HZBwufh2s736U6VXuhD109LYqPoffg==}
dev: false
/prelude-ls/1.2.1:
resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
engines: {node: '>= 0.8.0'}
@ -3137,6 +2924,10 @@ packages:
react-is: 18.2.0
dev: false
/pretty-format/3.8.0:
resolution: {integrity: sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew==}
dev: false
/prop-types/15.8.1:
resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==}
dependencies:
@ -3154,17 +2945,6 @@ packages:
engines: {node: '>=6'}
dev: false
/pvtsutils/1.3.3:
resolution: {integrity: sha512-6sAOMlXyrJ+8tRN5IAaYfuYZRp1C2uJ0SyDynEFxL+VY8kCRib9Lpj/+KPaNFpaQWr/iRik5nrzz6iaNlxgEGA==}
dependencies:
tslib: 2.6.1
dev: false
/pvutils/1.1.3:
resolution: {integrity: sha512-pMpnA0qRdFp32b1sJl1wOJNxZLQ2cbQx+k6tjNtZ8CpvVhNqEPRgivZ2WOUev2YMajecdH7ctUPDvEe87nariQ==}
engines: {node: '>=6.0.0'}
dev: false
/querystringify/2.2.0:
resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==}
dev: false
@ -3173,11 +2953,6 @@ packages:
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
dev: false
/quick-lru/4.0.1:
resolution: {integrity: sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==}
engines: {node: '>=8'}
dev: false
/quick-lru/6.1.1:
resolution: {integrity: sha512-S27GBT+F0NTRiehtbrgaSE1idUAJ5bX8dPAQTdylEyNlrdcH5X4Lz7Edz3DYzecbsCluD5zO8ZNEe04z3D3u6Q==}
engines: {node: '>=12'}
@ -3414,30 +3189,6 @@ packages:
engines: {node: '>=8'}
dev: false
/snake-case/3.0.4:
resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==}
dependencies:
dot-case: 3.0.4
tslib: 2.6.1
dev: false
/snakecase-keys/3.2.1:
resolution: {integrity: sha512-CjU5pyRfwOtaOITYv5C8DzpZ8XA/ieRsDpr93HI2r6e3YInC6moZpSQbmUtg8cTk58tq2x3jcG2gv+p1IZGmMA==}
engines: {node: '>=8'}
dependencies:
map-obj: 4.3.0
to-snake-case: 1.0.0
dev: false
/snakecase-keys/5.4.4:
resolution: {integrity: sha512-YTywJG93yxwHLgrYLZjlC75moVEX04LZM4FHfihjHe1FCXm+QaLOFfSf535aXOAd0ArVQMWUAe8ZPm4VtWyXaA==}
engines: {node: '>=12'}
dependencies:
map-obj: 4.3.0
snake-case: 3.0.4
type-fest: 2.19.0
dev: false
/source-map-js/1.0.2:
resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==}
engines: {node: '>=0.10.0'}
@ -3571,15 +3322,6 @@ packages:
engines: {node: '>= 0.4'}
dev: false
/swr/2.2.0_react@18.2.0:
resolution: {integrity: sha512-AjqHOv2lAhkuUdIiBu9xbuettzAzWXmCEcLONNKJRba87WAefz8Ca9d6ds/SzrPc235n1IxWYdhJ2zF3MNUaoQ==}
peerDependencies:
react: ^16.11.0 || ^17.0.0 || ^18.0.0
dependencies:
react: 18.2.0
use-sync-external-store: 1.2.0_react@18.2.0
dev: false
/symbol-tree/3.2.4:
resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==}
dev: false
@ -3641,10 +3383,6 @@ packages:
resolution: {integrity: sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==}
dev: false
/to-no-case/1.0.2:
resolution: {integrity: sha512-Z3g735FxuZY8rodxV4gH7LxClE4H0hTIyHNIHdk+vpQxjLm0cwnKXq/OFVZ76SOQmto7txVcwSCwkU5kqp+FKg==}
dev: false
/to-regex-range/5.0.1:
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
engines: {node: '>=8.0'}
@ -3652,18 +3390,6 @@ packages:
is-number: 7.0.0
dev: false
/to-snake-case/1.0.0:
resolution: {integrity: sha512-joRpzBAk1Bhi2eGEYBjukEWHOe/IvclOkiJl3DtA91jV6NwQ3MwXA4FHYeqk8BNp/D8bmi9tcNbRu/SozP0jbQ==}
dependencies:
to-space-case: 1.0.0
dev: false
/to-space-case/1.0.0:
resolution: {integrity: sha512-rLdvwXZ39VOn1IxGL3V6ZstoTbwLRckQmn/U8ZDLuWwIXNpuZDhQ3AiRUlhTbOXFVE9C+dR51wM0CBDhk31VcA==}
dependencies:
to-no-case: 1.0.2
dev: false
/tough-cookie/4.1.3:
resolution: {integrity: sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==}
engines: {node: '>=6'}
@ -3709,10 +3435,6 @@ packages:
strip-bom: 3.0.0
dev: false
/tslib/2.4.1:
resolution: {integrity: sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==}
dev: false
/tslib/2.6.1:
resolution: {integrity: sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==}
dev: false
@ -3734,11 +3456,6 @@ packages:
engines: {node: '>=10'}
dev: false
/type-fest/2.19.0:
resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==}
engines: {node: '>=12.20'}
dev: false
/type-fest/4.2.0:
resolution: {integrity: sha512-5zknd7Dss75pMSED270A1RQS3KloqRJA9XbXLe0eCxyw7xXFb3rd+9B0UQ/0E+LQT6lnrLviEolYORlRWamn4w==}
engines: {node: '>=16'}
@ -3840,14 +3557,6 @@ packages:
requires-port: 1.0.0
dev: false
/use-sync-external-store/1.2.0_react@18.2.0:
resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==}
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0
dependencies:
react: 18.2.0
dev: false
/utf-8-validate/6.0.3:
resolution: {integrity: sha512-uIuGf9TWQ/y+0Lp+KGZCMuJWc3N9BHA+l/UmHd/oUHwJJDeysyTRxNQVkbzsIWfGFbRe3OcgML/i0mvVRPOyDA==}
engines: {node: '>=6.14.2'}
@ -3880,16 +3589,6 @@ packages:
graceful-fs: 4.2.11
dev: false
/webcrypto-core/1.7.7:
resolution: {integrity: sha512-7FjigXNsBfopEj+5DV2nhNpfic2vumtjjgPmeDKk45z+MJwXKKfhPB7118Pfzrmh4jqOMST6Ch37iPAHoImg5g==}
dependencies:
'@peculiar/asn1-schema': 2.3.6
'@peculiar/json-schema': 1.1.12
asn1js: 3.0.5
pvtsutils: 1.3.3
tslib: 2.6.1
dev: false
/webidl-conversions/7.0.0:
resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==}
engines: {node: '>=12'}

View File

@ -1,5 +1,5 @@
import AuthNav from '@/components/AuthNav';
import { ClerkProvider } from '@clerk/nextjs';
import { SessionProvider } from 'next-auth/react';
export default function RootLayout({
children,
@ -7,11 +7,11 @@ export default function RootLayout({
children: React.ReactNode
}) {
return (
<ClerkProvider>
<SessionProvider>
{children}
<div className="my-8">
<AuthNav />
</div>
</ClerkProvider>
</SessionProvider>
);
}

View File

@ -1,16 +0,0 @@
import { cc } from '@/utility/css';
import { SignIn } from '@clerk/nextjs';
export const runtime = 'edge';
export default function SignInPage() {
return (
<div className={cc(
'fixed top-0 left-0 right-0 bottom-0',
'flex items-center justify-center',
'translate-x-2',
)}>
<SignIn />
</div>
);
}

View File

@ -1,7 +1,4 @@
import SiteGrid from '@/components/SiteGrid';
import ThemeSwitcher from '@/site/ThemeSwitcher';
import { cc } from '@/utility/css';
import Link from 'next/link';
import Footer from '@/components/Footer';
export default function RootLayout({
children,
@ -11,23 +8,7 @@ export default function RootLayout({
return (
<>
{children}
<SiteGrid
contentMain={<div className={cc(
'my-8',
'flex items-center',
'text-gray-400 dark:text-gray-500',
)}>
<div className="flex-grow">
<Link
href="/admin/photos"
className="hover:text-gray-600 dark:hover:text-gray-400"
>
Admin
</Link>
</div>
<ThemeSwitcher />
</div>}
/>
<Footer />
</>
);
}

View File

@ -0,0 +1,2 @@
export { GET, POST } from '@/auth';
export const runtime = 'edge';

21
src/app/sign-in/page.tsx Normal file
View File

@ -0,0 +1,21 @@
import { auth } from '@/auth';
import LoginButton from '@/components/LoginButton';
import { cc } from '@/utility/css';
import Link from 'next/link';
import { redirect } from 'next/navigation';
export default async function SignInPage() {
const session = await auth();
if (session?.user) {
redirect('/');
}
return (
<div className={cc(
'fixed top-0 left-0 right-0 bottom-0',
'flex items-center justify-center flex-col gap-8',
)}>
<LoginButton />
<Link href="/">Home</Link>
</div>
);
}

40
src/auth.ts Normal file
View File

@ -0,0 +1,40 @@
import NextAuth, { type DefaultSession } from 'next-auth';
import GitHub from 'next-auth/providers/github';
declare module 'next-auth' {
interface Session {
user: {
id: string
} & DefaultSession['user']
}
}
export const {
handlers: { GET, POST },
auth,
} = NextAuth({
providers: [GitHub({
clientId: process.env.GITHUB_CLIENT_ID,
clientSecret: process.env.GITHUB_CLIENT_SECRET,
})],
callbacks: {
jwt({ token, profile }) {
if (profile) {
token.id = profile.id;
token.image = profile.avatar_url || profile.picture;
}
return token;
},
authorized({ auth }) {
// this ensures there is a logged in user for -every- request
return (
process.env.GITHUB_ADMIN_EMAIL !== undefined &&
process.env.GITHUB_ADMIN_EMAIL === auth?.user?.email
);
},
},
pages: {
// overrides the next-auth default sign-in page
signIn: '/sign-in',
},
});

View File

@ -2,7 +2,7 @@
import { cc } from '@/utility/css';
import Link from 'next/link';
import { useClerk } from '@clerk/nextjs';
import { useSession, signOut } from 'next-auth/react';
import ThemeSwitcher from '@/site/ThemeSwitcher';
import SiteGrid from './SiteGrid';
import { usePathname } from 'next/navigation';
@ -14,9 +14,9 @@ const LINK_STYLE = cc(
);
export default function AuthNav() {
const { user, signOut } = useClerk();
const { data: session, status } = useSession();
const hasState = signOut !== undefined;
const hasState = status !== 'loading';
const path = usePathname();
@ -29,10 +29,10 @@ export default function AuthNav() {
<div className="flex gap-4 flex-grow">
{hasState
? <>
{user === undefined &&
{session?.user === undefined &&
<>Loading ...</>}
{user !== undefined && user !== null && <>
<div>{user?.emailAddresses[0].emailAddress}</div>
{session?.user.email && <>
<div>{session.user.email}</div>
<div
onClick={() => signOut()}
className={LINK_STYLE}

38
src/components/Footer.tsx Normal file
View File

@ -0,0 +1,38 @@
'use client';
import { cc } from '@/utility/css';
import SiteGrid from './SiteGrid';
import ThemeSwitcher from '@/site/ThemeSwitcher';
import { signOut } from 'next-auth/react';
import Link from 'next/link';
export default function Footer() {
return (
<SiteGrid
contentMain={<div className={cc(
'my-8',
'flex items-center',
'text-gray-400 dark:text-gray-500',
)}>
<div className="flex gap-4 flex-grow">
<Link
href="/admin/photos"
className="hover:text-gray-600 dark:hover:text-gray-400"
>
Admin
</Link>
<div
className={cc(
'cursor-pointer',
'hover:text-gray-600 dark:hover:text-gray-400',
)}
onClick={() => signOut()}
>
Sign out
</div>
</div>
<ThemeSwitcher />
</div>}
/>
);
}

View File

@ -0,0 +1,14 @@
'use client';
import { signIn } from 'next-auth/react';
export default function LoginButton() {
return (
<div
className="button"
onClick={() => signIn('github', { callbackUrl: '/' })}
>
Sign in
</div>
);
}

View File

@ -1,29 +1,5 @@
import { authMiddleware, redirectToSignIn } from '@clerk/nextjs';
import { NextResponse } from 'next/server';
export default authMiddleware({
afterAuth: (auth, req) => {
if (!(
auth.isPublicRoute ||
auth.userId === process.env.CLERK_ADMIN_USER_ID
)) {
return redirectToSignIn({ returnBackUrl: req.url });
} else {
if (req.nextUrl.pathname === '/admin') {
return NextResponse.redirect(new URL('/admin/photos', req.url));
}
}
},
publicRoutes: [
'/',
'/grid',
'/photos/:photoId',
'/photos/:photoId/share',
'/photos/:photoId/image',
'/deploy-image',
],
});
export { auth as middleware } from './auth';
export const config = {
matcher: ['/((?!.*\\..*|_next).*)'],
matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)'],
};

View File

@ -49,6 +49,7 @@
}
button, .button {
@apply
cursor-pointer
inline-flex gap-2 items-center
px-4
text-base