Browse Source

Merge pull request #6 from naresh97/development

-added privacy notice
master
Nareshkumar Rao 3 years ago
committed by GitHub
parent
commit
e2a8454546
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      .env.template
  2. 13
      src/App.css
  3. 2
      src/App.js
  4. 2
      src/features/auth/authSlice.js
  5. 55
      src/screens/HomeScreen.js
  6. 59
      src/screens/LoginScreen.js
  7. 12
      src/screens/ScannerScreen.js
  8. 95
      src/screens/VerifyScreen.js

4
.env.template

@ -1,2 +1,4 @@
REACT_APP_API_URL= REACT_APP_API_URL=
REACT_APP_TELEGRAM_BOT_NAME=
REACT_APP_TELEGRAM_BOT_NAME=
# REACT_APP_DONATE_LINK=

13
src/App.css

@ -1,9 +1,20 @@
:root {
background: var(--chakra-colors-teal-100);
}
#QRFlex { #QRFlex {
width: 30%; width: 30%;
} }
@media only screen and (max-width: 600px) {
#contentFlex {
width: 30%;
}
@media only screen and (max-width: 800px) {
#QRFlex { #QRFlex {
width: 90%; width: 90%;
} }
#contentFlex {
width: 90%;
}
} }

2
src/App.js

@ -24,7 +24,7 @@ function App() {
<Route path="/scanner"> <Route path="/scanner">
<Scanner /> <Scanner />
</Route> </Route>
<Route path="/verify/:id" component={Verify}/>
<Route path="/verify/:id" component={Verify} />
<Route path="/"> <Route path="/">
<Redirect to="/home" /> <Redirect to="/home" />
</Route> </Route>

2
src/features/auth/authSlice.js

@ -2,7 +2,7 @@ import { createSlice } from '@reduxjs/toolkit';
import Cookies from 'js-cookie'; import Cookies from 'js-cookie';
const initialState = { const initialState = {
isAuthenticated: Cookies.get('authorized') === "true" ? true : false,
isAuthenticated: Cookies.get('authorized') === 'true' ? true : false,
}; };
export const authSlice = createSlice({ export const authSlice = createSlice({

55
src/screens/HomeScreen.js

@ -1,6 +1,14 @@
import { Button, Divider, Flex, Image, Spinner, Text } from '@chakra-ui/react';
import {
Button,
Divider,
Flex,
Image,
Link,
Spinner,
Text,
} from '@chakra-ui/react';
import axios from 'axios'; import axios from 'axios';
import { React, useEffect, useState } from 'react';
import { Fragment, React, useEffect, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux'; import { useDispatch, useSelector } from 'react-redux';
import { Redirect, useHistory } from 'react-router-dom'; import { Redirect, useHistory } from 'react-router-dom';
import { authLogout } from '../features/auth/authSlice'; import { authLogout } from '../features/auth/authSlice';
@ -18,9 +26,9 @@ function QRCode() {
} }
}) })
.catch(err => { .catch(err => {
if(!err.response){
console.log("No response... Strange");
}else if (err.response.status === 401) {
if (!err.response) {
console.log('No response... Strange');
} else if (err.response.status === 401) {
dispatch(authLogout()); dispatch(authLogout());
} }
}); });
@ -39,12 +47,12 @@ function Home() {
const handleLogout = () => { const handleLogout = () => {
dispatch(authLogout()); dispatch(authLogout());
history.push("/login");
}
history.push('/login');
};
const isAuthenticated = useSelector(state => state.auth.isAuthenticated); const isAuthenticated = useSelector(state => state.auth.isAuthenticated);
if (!isAuthenticated) return <Redirect to="/login" />; if (!isAuthenticated) return <Redirect to="/login" />;
return ( return (
<Flex <Flex
height="100vh" height="100vh"
@ -65,9 +73,34 @@ function Home() {
contact, or allow them to create an account! contact, or allow them to create an account!
</Text> </Text>
<Divider mb={6} /> <Divider mb={6} />
<Button mb={6} onClick={()=>{history.push("/scanner");}}>Scan a QR Code</Button>
<Divider mb={10} />
<Button mb={6} onClick={handleLogout}>Log Out!</Button>
<Button
mb={6}
onClick={() => {
history.push('/scanner');
}}
>
Scan a QR Code
</Button>
{process.env.REACT_APP_DONATE_LINK && (
<Fragment>
<Divider mb={6} />
<Link href={process.env.REACT_APP_DONATE_LINK}>
<Button style={{ width: '100% ' }} mb={6} colorScheme="blue">
Donate!
</Button>
</Link>
<Text mb={6}>
Servers require money to run, and apps require labor to develop
and maintain. You can show your support by donating what you can.
Every cent counts, buy me my next coffee, or help pay for a month
of server usage!
</Text>
</Fragment>
)}
<Divider mb={6} />
<Button colorScheme="red" mb={6} onClick={handleLogout}>
Log Out!
</Button>
</Flex> </Flex>
</Flex> </Flex>
); );

59
src/screens/LoginScreen.js

@ -1,6 +1,4 @@
import {
Flex, Heading, useToast
} from '@chakra-ui/react';
import { Divider, Flex, Heading, Link, Text, useToast } from '@chakra-ui/react';
import axios from 'axios'; import axios from 'axios';
import { React } from 'react'; import { React } from 'react';
import { useDispatch, useSelector } from 'react-redux'; import { useDispatch, useSelector } from 'react-redux';
@ -16,13 +14,13 @@ function Login() {
const isAuthenticated = useSelector(state => state.auth.isAuthenticated); const isAuthenticated = useSelector(state => state.auth.isAuthenticated);
if (isAuthenticated) return <Redirect to="/home" />; if (isAuthenticated) return <Redirect to="/home" />;
const handleTelegramResponse = (response) => {
const handleTelegramResponse = response => {
toast({ toast({
title: "Logging you in",
title: 'Logging you in',
description: "Hold on, we're logging you in.", description: "Hold on, we're logging you in.",
status: 'info', status: 'info',
duration: 10000, duration: 10000,
isClosable: false
isClosable: false,
}); });
axios axios
.post( .post(
@ -38,9 +36,9 @@ function Login() {
if (response.data.authorized) { if (response.data.authorized) {
dispatch(authLogin()); dispatch(authLogin());
toast.closeAll(); toast.closeAll();
if(response.data.contactSuccess){
if (response.data.contactSuccess) {
history.push('/success'); history.push('/success');
}else{
} else {
history.push('/home'); history.push('/home');
} }
} else { } else {
@ -57,8 +55,8 @@ function Login() {
}) })
.catch(err => { .catch(err => {
toast.closeAll(); toast.closeAll();
if(err.response){
if(err.response.status === 401){
if (err.response) {
if (err.response.status === 401) {
dispatch(authLogout()); dispatch(authLogout());
toast({ toast({
title: 'Login Failed', title: 'Login Failed',
@ -68,7 +66,7 @@ function Login() {
isClosable: true, isClosable: true,
}); });
} }
}else{
} else {
toast({ toast({
title: 'An error occurred', title: 'An error occurred',
description: 'Sorry, an error occurred on our side.', description: 'Sorry, an error occurred on our side.',
@ -77,25 +75,56 @@ function Login() {
isClosable: true, isClosable: true,
}); });
} }
}); });
}; };
return ( return (
<Flex <Flex
height="100vh"
height="100%"
background="teal.100" background="teal.100"
alignItems="center" alignItems="center"
justifyContent="center" justifyContent="center"
> >
<Flex direction="column" background="white" p={12} rounded={6}>
<Flex
direction="column"
mt={5}
mb={5}
background="white"
p={12}
rounded={6}
id="contentFlex"
>
<Heading size="xl" mb={6}> <Heading size="xl" mb={6}>
SSR Covid Tracing SSR Covid Tracing
</Heading> </Heading>
<Heading size="lg" mb={4}> <Heading size="lg" mb={4}>
Login Login
</Heading> </Heading>
<TelegramLoginButton dataOnauth={handleTelegramResponse} botName={process.env.REACT_APP_TELEGRAM_BOT_NAME} />
<TelegramLoginButton
dataOnauth={handleTelegramResponse}
botName={process.env.REACT_APP_TELEGRAM_BOT_NAME}
/>
<Divider mb={6} mt={6} />
<Text fontSize="sm">
<b>Privacy notes:</b> <br />
Telegram Login allows us to verify your identity, without collecting
any of your data. Telegram does NOT give us your phone number. The
only piece of information stored on our server is your Telegram ID,
this is an internal ID Number Telegram uses that is SEPARATE from your
Telegram Username.
<br />
<br />
All the code for this project is{' '}
<Link
color="teal.500"
href="https://github.com/naresh97/ssr-tracing"
isExternal
>
Open Source
</Link>
, that means anyone, including you can audit and verify that your
information is being handled securely.
</Text>
</Flex> </Flex>
</Flex> </Flex>
); );

12
src/screens/ScannerScreen.js

@ -31,11 +31,11 @@ function Scanner() {
const hash = re.exec(scanData); const hash = re.exec(scanData);
if (hash) { if (hash) {
toast({ toast({
title: "Checking QR code.",
title: 'Checking QR code.',
description: "Hold on, we're checking this QR code.", description: "Hold on, we're checking this QR code.",
status: 'info', status: 'info',
duration: 10000, duration: 10000,
isClosable: false
isClosable: false,
}); });
axios axios
.post( .post(
@ -57,7 +57,7 @@ function Scanner() {
} else { } else {
toast({ toast({
title: "You're not logged in!", title: "You're not logged in!",
description: "Please log in and try again!",
description: 'Please log in and try again!',
status: 'error', status: 'error',
duration: 2000, duration: 2000,
}); });
@ -74,13 +74,13 @@ function Scanner() {
duration: 2000, duration: 2000,
}); });
}); });
}else{
} else {
toast.closeAll(); toast.closeAll();
toast({ toast({
title: "Bad QR code",
title: 'Bad QR code',
status: 'error', status: 'error',
duration: 3000, duration: 3000,
isClosable: true
isClosable: true,
}); });
} }
} }

95
src/screens/VerifyScreen.js

@ -1,55 +1,58 @@
import { Flex, Text } from '@chakra-ui/react'; import { Flex, Text } from '@chakra-ui/react';
import axios from 'axios'; import axios from 'axios';
import { useEffect, useState } from "react";
import { useHistory } from "react-router-dom";
import { useEffect, useState } from 'react';
import { useHistory } from 'react-router-dom';
function Verify(props) { function Verify(props) {
const verifyID = props.match.params.id;
const [verifyError, setVerifyError] = useState(false);
const history = useHistory();
const verifyID = props.match.params.id;
const [verifyError, setVerifyError] = useState(false);
const history = useHistory();
useEffect(() => {
if(verifyError) return;
axios
.post(`${process.env.REACT_APP_API_URL}/verify`,
{
id: verifyID,
},
{ withCredentials: true },
)
.then(response => {
if (response.data.success) {
if (response.data.loggedIn) {
history.push("/success");
} else {
history.push("/login");
}
}
})
.catch(err => {
setVerifyError(true);
});
}, [verifyError, history, verifyID]);
useEffect(() => {
if (verifyError) return;
axios
.post(
`${process.env.REACT_APP_API_URL}/verify`,
{
id: verifyID,
},
{ withCredentials: true }
)
.then(response => {
if (response.data.success) {
if (response.data.loggedIn) {
history.push('/success');
} else {
history.push('/login');
}
}
})
.catch(err => {
setVerifyError(true);
});
}, [verifyError, history, verifyID]);
const errorMessage = (
<Text>An error has occured verifying you. Please try scanning the QR code again?</Text>
);
const loadingMessage = (
<Text>We are currently verifying you. Please wait.</Text>
);
const errorMessage = (
<Text>
An error has occured verifying you. Please try scanning the QR code again?
</Text>
);
const loadingMessage = (
<Text>We are currently verifying you. Please wait.</Text>
);
return (
<Flex
height="100vh"
background="teal.100"
alignItems="center"
justifyContent="center"
>
<Flex direction="column" background="white" p={12} rounded={6}>
{verifyError ? errorMessage : loadingMessage}
</Flex>
</Flex>
);
return (
<Flex
height="100vh"
background="teal.100"
alignItems="center"
justifyContent="center"
>
<Flex direction="column" background="white" p={12} rounded={6}>
{verifyError ? errorMessage : loadingMessage}
</Flex>
</Flex>
);
} }
export default Verify;
export default Verify;

Loading…
Cancel
Save