From 249e1079c4aa2741f50fabff16e447337c6b0d6d Mon Sep 17 00:00:00 2001 From: Neeraj Date: Thu, 17 Oct 2024 14:44:15 +0530 Subject: [PATCH] Fix session management in backend --- packages/backend/package.json | 6 +- packages/backend/src/routes/auth.ts | 2 - packages/backend/src/server.ts | 25 +- packages/frontend/src/App.tsx | 30 +-- .../frontend/src/context/Web3Provider.tsx | 32 ++- packages/frontend/src/pages/auth/Login.tsx | 250 +----------------- .../frontend/src/pages/auth/SnowballAuth.tsx | 6 +- yarn.lock | 12 +- 8 files changed, 54 insertions(+), 309 deletions(-) diff --git a/packages/backend/package.json b/packages/backend/package.json index a7a5d34b..bd5190ed 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -16,11 +16,11 @@ "apollo-server-core": "^3.13.0", "apollo-server-express": "^3.13.0", "cookie-session": "^2.1.0", - "cors": "^2.8.5", + "cors": "2.8.5", "debug": "^4.3.1", "express": "^4.18.2", "express-async-errors": "^3.1.1", - "express-session": "^1.18.0", + "express-session": "1.18.0", "fs-extra": "^11.2.0", "graphql": "^16.8.1", "luxon": "^3.4.4", @@ -51,7 +51,7 @@ }, "devDependencies": { "@types/cookie-session": "^2.0.49", - "@types/express-session": "^1.17.10", + "@types/express-session": "1.17.10", "@types/fs-extra": "^11.0.4", "better-sqlite3": "^9.2.2", "copyfiles": "^2.4.1", diff --git a/packages/backend/src/routes/auth.ts b/packages/backend/src/routes/auth.ts index 7b258e2b..5632e18c 100644 --- a/packages/backend/src/routes/auth.ts +++ b/packages/backend/src/routes/auth.ts @@ -69,7 +69,6 @@ router.post('/validate', async (req, res) => { signature, }); - console.log("VALIDATE CALL",message, signature ) if (!success) { return res.send({ success, error: 'SIWE verifcation failed' } ); } @@ -90,7 +89,6 @@ router.post('/validate', async (req, res) => { req.session.address = user.id; req.session.chainId = data.chainId; } - console.log("VALIDATE CALL FINISHED", req.session) res.send({ success }); }); diff --git a/packages/backend/src/server.ts b/packages/backend/src/server.ts index 2699c515..0c10e009 100644 --- a/packages/backend/src/server.ts +++ b/packages/backend/src/server.ts @@ -8,7 +8,7 @@ import { ApolloServerPluginLandingPageLocalDefault, AuthenticationError, } from 'apollo-server-core'; -import cookieSession from 'cookie-session'; +import session from 'express-session'; import { TypeSource } from '@graphql-tools/utils'; import { makeExecutableSchema } from '@graphql-tools/schema'; @@ -62,7 +62,6 @@ export const createAndStartServer = async ( } const user = await service.getUser(address); - return { user }; }, plugins: [ @@ -81,20 +80,26 @@ export const createAndStartServer = async ( }), ); + const sessionOptions: session.SessionOptions = { + secret: secret, + resave: false, + saveUninitialized: true, + cookie: { + secure: new URL(appOriginUrl).protocol === 'https:', + // 23 hours (less than 24 hours to avoid sessionSigs expiration issues) + maxAge: 23 * 60 * 60 * 1000, + domain: domain || undefined, + sameSite: new URL(appOriginUrl).protocol === 'https:' ? 'none' : 'lax', + } + }; + if (trustProxy) { // trust first proxy app.set('trust proxy', 1); } app.use( - cookieSession({ - secret: secret, - secure: new URL(appOriginUrl).protocol === 'https:', - // 23 hours (less than 24 hours to avoid sessionSigs expiration issues) - maxAge: 23 * 60 * 60 * 1000, - sameSite: new URL(appOriginUrl).protocol === 'https:' ? 'none' : 'lax', - domain: domain || undefined, - }), + session(sessionOptions) ); server.applyMiddleware({ diff --git a/packages/frontend/src/App.tsx b/packages/frontend/src/App.tsx index 4e2c3586..48390503 100644 --- a/packages/frontend/src/App.tsx +++ b/packages/frontend/src/App.tsx @@ -50,28 +50,24 @@ const router = createBrowserRouter([ path: '/login', element: , }, - { - path: '/signup', - element: , - }, ]); function App() { // Hacky way of checking session // TODO: Handle redirect backs - // useEffect(() => { - // fetch(`${baseUrl}/auth/session`, { - // credentials: 'include', - // }).then((res) => { - // if (res.status !== 200) { - // localStorage.clear(); - // const path = window.location.pathname; - // if (path !== '/login' && path !== '/signup') { - // window.location.pathname = '/login'; - // } - // } - // }); - // }, []); + useEffect(() => { + fetch(`${baseUrl}/auth/session`, { + credentials: 'include', + }).then((res) => { + if (res.status !== 200) { + localStorage.clear(); + const path = window.location.pathname; + if (path !== '/login') { + window.location.pathname = '/login'; + } + } + }); + }, []); return ( diff --git a/packages/frontend/src/context/Web3Provider.tsx b/packages/frontend/src/context/Web3Provider.tsx index 5e7618e7..ffe84c85 100644 --- a/packages/frontend/src/context/Web3Provider.tsx +++ b/packages/frontend/src/context/Web3Provider.tsx @@ -1,4 +1,4 @@ -import React, { ReactNode } from 'react'; +import React, { ReactNode, Suspense } from 'react'; import { SiweMessage, generateNonce } from 'siwe'; import { WagmiProvider } from 'wagmi'; import { arbitrum, mainnet } from 'wagmi/chains'; @@ -12,18 +12,17 @@ import type { } from '@web3modal/core'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; -// if (!process.env.VITE_WALLET_CONNECT_ID) { -// throw new Error('Error: VITE_WALLET_CONNECT_ID env config is not set'); -// } +// TODO: Use environment variable const WALLET_CONNECT_ID="d37f5a2f09d22f5e3ccaff4bbc93d37c" const queryClient = new QueryClient(); const axiosInstance = axios.create({ - baseURL: 'http://127.0.0.1:8000', - // headers: { - // 'Content-Type': 'application/json', - // 'Access-Control-Allow-Origin': '*', - // }, - // withCredentials: true, + // TODO: Use environment variable + baseURL: 'http://localhost:8000', + headers: { + 'Content-Type': 'application/json', + 'Access-Control-Allow-Origin': '*', + }, + withCredentials: true, }); const metadata = { name: 'Web3Modal', @@ -78,13 +77,12 @@ const siweConfig = createSIWEConfig({ } }, signOut: async () => { - // try { - // const { success } = (await axiosInstance.post('/auth/logout')).data; - // return success; - // } catch (error) { - // return false; - // } - return false + try { + const { success } = (await axiosInstance.post('/auth/logout')).data; + return success; + } catch (error) { + return false; + } }, onSignOut: () => { window.location.href = '/login'; diff --git a/packages/frontend/src/pages/auth/Login.tsx b/packages/frontend/src/pages/auth/Login.tsx index db47deb0..a514e59f 100644 --- a/packages/frontend/src/pages/auth/Login.tsx +++ b/packages/frontend/src/pages/auth/Login.tsx @@ -1,101 +1,6 @@ -import { Button } from 'components/shared/Button'; -import { - ArrowRightCircleFilledIcon, - GithubIcon, - LinkIcon, - LoaderIcon, - QuestionMarkRoundFilledIcon, -} from 'components/shared/CustomIcon'; -import { GoogleIcon } from 'components/shared/CustomIcon/GoogleIcon'; -import { DotBorder } from 'components/shared/DotBorder'; import { WavyBorder } from 'components/shared/WavyBorder'; -import { useEffect, useState } from 'react'; -import { CreatePasskey } from './CreatePasskey'; -import { AppleIcon } from 'components/shared/CustomIcon/AppleIcon'; -import { KeyIcon } from 'components/shared/CustomIcon/KeyIcon'; -import { useToast } from 'components/shared/Toast'; -import { Link } from 'react-router-dom'; -import { PKPEthersWallet } from '@lit-protocol/pkp-ethers'; -import { signInWithEthereum } from 'utils/siwe'; -import { useSnowball } from 'utils/use-snowball'; -import { logError } from 'utils/log-error'; - -// type Provider = 'google' | 'github' | 'apple' | 'email' | 'passkey'; - -type Props = { - onDone: () => void; -}; - -export const Login = ({ onDone }: Props) => { - // const snowball = useSnowball(); - // const [error, setError] = useState(''); - // const [provider, setProvider] = useState(false); - - // const loading = snowball.auth.state.loading && provider; - // const loading = provider; - // const { toast } = useToast(); - - console.log(">>ondone", onDone) - // if (provider === 'email') { - // return ; - // } - - // async function handleSigninRedirect() { - // let wallet: PKPEthersWallet | undefined; - // const { google } = snowball.auth; - // if (google.canHandleOAuthRedirectBack()) { - // setProvider('google'); - // console.log('Handling google redirect back'); - // try { - // await google.handleOAuthRedirectBack(); - // // @ts-ignore - // wallet = await google.getEthersWallet(); - // // @ts-ignore - // const result = await signInWithEthereum(1, 'login', wallet); - // if (result.error) { - // setError(result.error); - // setProvider(false); - // wallet = undefined; - // logError(new Error(result.error)); - // return; - // } - // } catch (err: any) { - // setError(err.message); - // logError(err); - // setProvider(false); - // return; - // } - // } - // if (apple.canHandleOAuthRedirectBack()) { - // setProvider('apple'); - // console.log('Handling apple redirect back'); - // try { - // await apple.handleOAuthRedirectBack(); - // wallet = await apple.getEthersWallet(); - // const result = await signInWithEthereum(1, 'login', wallet); - // if (result.error) { - // setError(result.error); - // setProvider(false); - // wallet = undefined; - // return; - // } - // } catch (err: any) { - // setError(err.message); - // console.log(err.message, err.name, err.details); - // setProvider(false); - // return; - // } - // } - - // if (wallet) { - // window.location.pathname = '/'; - // } - // } - - // useEffect(() => { - // handleSigninRedirect(); - // }, []); +export const Login = () => { return (
@@ -106,161 +11,8 @@ export const Login = ({ onDone }: Props) => {
- {/*
*/} - {/*
- -
-
- Got a Passkey? -
-
- Use it to sign in securely without using a password. -
-
-
*/} - {/*
*/} - {/* */} - {/* */} - {/*
*/} - - {/*
-
- Lost your passkey? -
-
- - -
-
*/} - {/*
*/} - - {/*
- -
- OR -
- -
*/} -
- {/* */} - - {/* */} - - {/* */} -
- -
- {/* {error && ( -
-
Error: {error}
-
- )} */} - - {/*
-
- Don't have an account? -
-
- - Sign up now - -
-
*/}
diff --git a/packages/frontend/src/pages/auth/SnowballAuth.tsx b/packages/frontend/src/pages/auth/SnowballAuth.tsx index dd5abf1a..0d849a3d 100644 --- a/packages/frontend/src/pages/auth/SnowballAuth.tsx +++ b/packages/frontend/src/pages/auth/SnowballAuth.tsx @@ -40,11 +40,7 @@ export const SnowballAuth: React.FC = () => { } if (screen === 'login') { return ( - { - setScreen('success'); - }} - /> + ); } if (screen === 'success') { diff --git a/yarn.lock b/yarn.lock index 7eea367d..5cd17981 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7495,10 +7495,10 @@ "@types/range-parser" "*" "@types/send" "*" -"@types/express-session@^1.17.10": - version "1.18.0" - resolved "https://registry.yarnpkg.com/@types/express-session/-/express-session-1.18.0.tgz#7c6f25c3604b28d6bc08a2e3929997bbc7672fa2" - integrity sha512-27JdDRgor6PoYlURY+Y5kCakqp5ulC0kmf7y+QwaY+hv9jEFuQOThgkjyA53RP3jmKuBsH5GR6qEfFmvb8mwOA== +"@types/express-session@1.17.10": + version "1.17.10" + resolved "https://registry.yarnpkg.com/@types/express-session/-/express-session-1.17.10.tgz#3a9394f1f314a4c657af3fb1cdb52f00fc207fd2" + integrity sha512-U32bC/s0ejXijw5MAzyaV4tuZopCh/K7fPoUDyNbsRXHvPSeymygYD1RFL99YOLhF5PNOkzswvOTRaVHdL1zMw== dependencies: "@types/express" "*" @@ -10416,7 +10416,7 @@ core-util-is@~1.0.0: resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== -cors@^2.8.5: +cors@2.8.5, cors@^2.8.5: version "2.8.5" resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== @@ -11760,7 +11760,7 @@ express-async-errors@^3.1.1: resolved "https://registry.yarnpkg.com/express-async-errors/-/express-async-errors-3.1.1.tgz#6053236d61d21ddef4892d6bd1d736889fc9da41" integrity sha512-h6aK1da4tpqWSbyCa3FxB/V6Ehd4EEB15zyQq9qe75OZBp0krinNKuH4rAY+S/U/2I36vdLAUFSjQJ+TFmODng== -express-session@^1.18.0: +express-session@1.18.0: version "1.18.0" resolved "https://registry.yarnpkg.com/express-session/-/express-session-1.18.0.tgz#a6ae39d9091f2efba5f20fc5c65a3ce7c9ce16a3" integrity sha512-m93QLWr0ju+rOwApSsyso838LQwgfs44QtOP/WBiwtAgPIo/SAh1a5c6nn2BR6mFNZehTpqKDESzP+fRHVbxwQ==