From fdd6811af8f5e32ccbae52932379e8c0a3bfe95b Mon Sep 17 00:00:00 2001 From: Ian Mancini Date: Mon, 16 Nov 2020 04:51:39 -0300 Subject: [PATCH] Add unauthenticated redirects, logout button and improve UI --- packages/client/package-lock.json | 15 ++++++ packages/client/package.json | 1 + packages/client/src/3d/Phantom.tsx | 1 - .../src/components/DisconnectButton.tsx | 50 +++++++++++++++++++ packages/client/src/components/Error.tsx | 26 ++++++++-- packages/client/src/components/Login.tsx | 34 +++++++++++-- .../client/src/components/MenuOverlay.tsx | 14 ++++-- packages/client/src/components/Museo.tsx | 15 +++++- packages/client/src/hooks/useLogin.ts | 24 +++++++++ packages/client/src/store.ts | 4 +- packages/server/src/auth/middleware.js | 2 +- packages/server/src/auth/passport.js | 10 ++++ 12 files changed, 178 insertions(+), 18 deletions(-) create mode 100644 packages/client/src/components/DisconnectButton.tsx create mode 100644 packages/client/src/hooks/useLogin.ts diff --git a/packages/client/package-lock.json b/packages/client/package-lock.json index 419a45f..8e52a5c 100644 --- a/packages/client/package-lock.json +++ b/packages/client/package-lock.json @@ -12977,6 +12977,21 @@ "use-sidecar": "^1.0.1" } }, + "react-icons": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-3.11.0.tgz", + "integrity": "sha512-JRgiI/vdF6uyBgyZhVyYJUZAop95Sy4XDe/jmT3R/bKliFWpO/uZBwvSjWEdxwzec7SYbEPNPck0Kff2tUGM2Q==", + "requires": { + "camelcase": "^5.0.0" + }, + "dependencies": { + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + } + } + }, "react-is": { "version": "17.0.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.1.tgz", diff --git a/packages/client/package.json b/packages/client/package.json index da8290a..badb3a5 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -23,6 +23,7 @@ "npm": "^6.14.8", "react": "^17.0.1", "react-dom": "^17.0.1", + "react-icons": "^3.11.0", "react-router-dom": "^5.2.0", "react-scripts": "4.0.0", "react-three-fiber": "^5.2.1", diff --git a/packages/client/src/3d/Phantom.tsx b/packages/client/src/3d/Phantom.tsx index 0aeacb2..74373da 100644 --- a/packages/client/src/3d/Phantom.tsx +++ b/packages/client/src/3d/Phantom.tsx @@ -1,6 +1,5 @@ // @ts-nocheck import React, { useEffect, useRef } from 'react' -import { extend } from 'react-three-fiber' import { Vector3, Euler } from 'three' import api, { Transform } from '../store' diff --git a/packages/client/src/components/DisconnectButton.tsx b/packages/client/src/components/DisconnectButton.tsx new file mode 100644 index 0000000..4692f84 --- /dev/null +++ b/packages/client/src/components/DisconnectButton.tsx @@ -0,0 +1,50 @@ +import React from 'react' +import { + Button, + Popover, + PopoverArrow, + PopoverBody, + PopoverCloseButton, + PopoverContent, + PopoverHeader, + PopoverTrigger, + ButtonProps, + Link, +} from '@chakra-ui/react' + +const DisconnectButton: React.FC = (props) => { + return ( + + + + + + + + Confirmación + + ¿Estás segur@ de que querés desconectarte? + + + Desconectarse + + + + ) +} + +export default DisconnectButton diff --git a/packages/client/src/components/Error.tsx b/packages/client/src/components/Error.tsx index 6b937d3..3cbabde 100644 --- a/packages/client/src/components/Error.tsx +++ b/packages/client/src/components/Error.tsx @@ -2,6 +2,8 @@ import React from 'react' import useStore from '../store' import { Box, Heading, Link, Stack, Text } from '@chakra-ui/react' +import DisconnectButton from './DisconnectButton' + const Error: React.FC = () => { const error = useStore((state) => state.error) @@ -28,16 +30,34 @@ const Error: React.FC = () => { align="center" w="100%" spacing="1rem" + position="relative" > + + + ¡Oh no! - + {errorText()} Por favor,{' '} - reloadPage()}>clickeá acá para recargar la página + reloadPage()} + fontWeight="bold" + pading="0.5rem" + _hover={{ backgroundColor: 'gray.100' }} + > + clickeá acá para recargar la página{' '} + - + Si el problema persiste, envía un correo electrónico a{' '} ianmethyst@gmail.com diff --git a/packages/client/src/components/Login.tsx b/packages/client/src/components/Login.tsx index 2a405cb..3ba167d 100644 --- a/packages/client/src/components/Login.tsx +++ b/packages/client/src/components/Login.tsx @@ -1,8 +1,18 @@ import React from 'react' -import { Heading, Stack, Link, Spacer, Text } from '@chakra-ui/react' +import { RiExternalLinkLine } from 'react-icons/ri' +import { Heading, Stack, Link, Spacer, chakra } from '@chakra-ui/react' + +import useLogin from '../hooks/useLogin' +import { Redirect } from 'react-router-dom' const Login: React.FC = () => { - return ( + const { response, isLoading } = useLogin<{ authenticated: boolean }>('auth/check') + + if (isLoading || !response) return null + + return response.authenticated ? ( + + ) : ( @@ -14,9 +24,23 @@ const Login: React.FC = () => { ingresar con google - - Desarrollado por Ian Mancini para Artimañas 2020 - + + Llevado a cabo por Ian Mancini para Artimañas 2020{' '} + + + + ) } diff --git a/packages/client/src/components/MenuOverlay.tsx b/packages/client/src/components/MenuOverlay.tsx index 3839eb3..8f20081 100644 --- a/packages/client/src/components/MenuOverlay.tsx +++ b/packages/client/src/components/MenuOverlay.tsx @@ -9,8 +9,12 @@ import { Button, Kbd, useToast, + Spacer, + Flex, } from '@chakra-ui/react' +import DisconnectButton from './DisconnectButton' + import useStore from '../store' const MenuOverlay: React.FC = () => { @@ -38,16 +42,18 @@ const MenuOverlay: React.FC = () => { return ( <> - undefined}> + undefined} size="xl"> museo.red - + Usa las teclas W, A, S y D para moverte. Usá el mouse para mirar alrededor - - diff --git a/packages/client/src/components/Museo.tsx b/packages/client/src/components/Museo.tsx index cf65b70..af610c4 100644 --- a/packages/client/src/components/Museo.tsx +++ b/packages/client/src/components/Museo.tsx @@ -9,14 +9,21 @@ import Error from './Error' import Scene from '../3d' import useStore, { UserTransforms } from '../store' +import useLogin from '../hooks/useLogin' +import { Redirect } from 'react-router-dom' const Museo: React.FC = () => { + const { response, isLoading } = useLogin<{ authenticated: boolean }>('auth/check') + const setSocket = useStore((state) => state.setSocket) const setError = useStore((state) => state.setError) const error = useStore((state) => state.error) const setUserTransforms = useStore((state) => state.setUserTransforms) useEffect(() => { + if (!response || isLoading) { + return + } const socket = io() setSocket(socket) @@ -29,9 +36,13 @@ const Museo: React.FC = () => { socket.close() setSocket(null) } - }, []) + }, [response, isLoading]) + + if (isLoading || !response) return null - return ( + return response.authenticated === false ? ( + + ) : ( {error ? ( diff --git a/packages/client/src/hooks/useLogin.ts b/packages/client/src/hooks/useLogin.ts new file mode 100644 index 0000000..0bc403a --- /dev/null +++ b/packages/client/src/hooks/useLogin.ts @@ -0,0 +1,24 @@ +import { useEffect, useState } from 'react' + +function useLogin(url: string) { + const [response, setResponse] = useState() + const [error, setError] = useState(null) + const [isLoading, setIsLoading] = useState(true) + useEffect(() => { + const fetchData = async () => { + setIsLoading(true) + try { + const res = await fetch(url) + const json = await res.json() + setResponse(json) + setIsLoading(false) + } catch (error) { + setError(error) + } + } + fetchData() + }, []) + return { response, error, isLoading } +} + +export default useLogin diff --git a/packages/client/src/store.ts b/packages/client/src/store.ts index 68e194d..a2fa8fc 100644 --- a/packages/client/src/store.ts +++ b/packages/client/src/store.ts @@ -5,8 +5,8 @@ import { Socket } from 'socket.io-client' type Error = null | 'SOCKET' export type Transform = { - position?: number[] - rotation?: number[] + position: number[] + rotation: number[] } type userId = string diff --git a/packages/server/src/auth/middleware.js b/packages/server/src/auth/middleware.js index 9c3d81c..1f4adb0 100644 --- a/packages/server/src/auth/middleware.js +++ b/packages/server/src/auth/middleware.js @@ -2,7 +2,7 @@ const ensureAuthenticated = (req, res, next) => { if (req.isAuthenticated()) { return next() } else { - return res.redirect('/') + return res.json({ authenticated: false }) } } diff --git a/packages/server/src/auth/passport.js b/packages/server/src/auth/passport.js index 78bbb26..9d2919a 100644 --- a/packages/server/src/auth/passport.js +++ b/packages/server/src/auth/passport.js @@ -9,6 +9,7 @@ import UserModel from '../models/user' import { facebookRouter, facebookStrategy } from './providers/facebook' import { googleRouter, googleStrategy } from './providers/google' import { twitterRouter, twitterStrategy } from './providers/twitter' +import ensureAuthenticated from './middleware' export function initPassport() { passport.serializeUser((user, done) => { @@ -30,3 +31,12 @@ export const authRouter = Router() authRouter.use(facebookRouter) authRouter.use(twitterRouter) authRouter.use(googleRouter) + +authRouter.get('/logout', function (req, res) { + req.logout() + res.redirect('/') +}) + +authRouter.get('/check', ensureAuthenticated, function (req, res) { + res.json({ authenticated: true }) +})