Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Author authentication #56

Merged
merged 12 commits into from
Oct 23, 2023
63 changes: 55 additions & 8 deletions client/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
"react-dom": "^18.2.0",
"react-router-dom": "^6.17.0",
"react-scripts": "5.0.1",
"typescript": "^5.2.2",
"react-toastify": "^9.1.3",
"toastify-js": "^1.12.0",
"typescript": "^4.9.5",
"web-vitals": "^2.1.4"
},
"scripts": {
Expand Down
30 changes: 25 additions & 5 deletions client/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,34 @@ import Login from "./components/authentication/Login";
import SignUp from "./components/authentication/SignUp";

import "./App.css";
import { ToastContainer } from "react-toastify";
import { getToken } from "./utils/localStorageUtils";

const App = () => {
// TODO: Find a way to validate token
// TODO: use userToken to restrict access for not logged in status
const userToken = getToken();

return (
<Routes>
<Route path="/home-page" element={<HomePage />} />
<Route path="/login" element={<Login />} />
<Route path="/sign-up" element={<SignUp />} />
</Routes>
<>
<ToastContainer
position="top-center"
autoClose={5000}
hideProgressBar={false}
newestOnTop={false}
closeOnClick
rtl={false}
pauseOnFocusLoss
draggable
pauseOnHover
theme="light"
/>
<Routes>
<Route path="/home-page" element={<HomePage />} />
<Route path="/login" element={<Login />} />
<Route path="/sign-up" element={<SignUp />} />
</Routes>
</>
);
};

Expand Down
43 changes: 41 additions & 2 deletions client/src/components/authentication/Login.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { FormEvent } from "react";
import React, { FormEvent, useState } from "react";

import Button from "@mui/material/Button";
import CssBaseline from "@mui/material/CssBaseline";
Expand All @@ -8,8 +8,42 @@ import Box from "@mui/material/Box";
import Typography from "@mui/material/Typography";
import Container from "@mui/material/Container";

import { toast } from "react-toastify";
import { useNavigate } from "react-router-dom";
import axios from "axios";

import { storeToken } from "../../utils/localStorageUtils";

const Login = () => {
const navigate = useNavigate();
const [formData, setFormData] = useState({
username: "",
password: "",
});

const handleSubmit = (e: FormEvent) => {
e.preventDefault();

const requestUrl = "http://127.0.0.1:8000/socialdistribution/login/";

const form = new FormData();
form.append("username", formData.username);
form.append("password", formData.password);

axios
.post(requestUrl, form, {
headers: { "Content-Type": "multipart/form-data" },
})
.then((response: any) => {
storeToken(response.data.token);

toast.success("You are now logged in");

navigate("/home-page");
})
.catch((error) => {
toast.error("Wrong password or user does not exist");
});
return;
};

Expand All @@ -18,7 +52,6 @@ const Login = () => {
<CssBaseline />
<Box
sx={{
// marginTop: 8,
display: "flex",
flexDirection: "column",
justifyContent: "center",
Expand All @@ -40,6 +73,9 @@ const Login = () => {
name="email"
autoComplete="email"
autoFocus
onChange={(e) => {
setFormData({ ...formData, username: e.target.value });
}}
/>
<TextField
margin="normal"
Expand All @@ -49,6 +85,9 @@ const Login = () => {
label="Password"
type="password"
id="password"
onChange={(e) => {
setFormData({ ...formData, password: e.target.value });
}}
/>
<Button
type="submit"
Expand Down
67 changes: 62 additions & 5 deletions client/src/components/authentication/SignUp.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { FormEvent } from "react";
import React, { FormEvent, useState } from "react";

import Button from "@mui/material/Button";
import CssBaseline from "@mui/material/CssBaseline";
Expand All @@ -8,9 +8,46 @@ import Box from "@mui/material/Box";
import Typography from "@mui/material/Typography";
import Container from "@mui/material/Container";

import axios from "axios";

import { toast } from "react-toastify";
import { useNavigate } from "react-router-dom";

const SignUp = () => {
const navigate = useNavigate();
const [formData, setFormData] = useState({
username: "",
email: "",
password: "",
repeatPassword: "",
});

const handleSubmit = (e: FormEvent) => {
return;
e.preventDefault();

if (formData.password !== formData.repeatPassword) {
toast.error("Repeat password does not match!");
return;
}

const requestUrl = "http://127.0.0.1:8000/socialdistribution/signup/";

const form = new FormData();
form.append("username", formData.username);
form.append("email", formData.email);
form.append("password", formData.password);

axios
.post(requestUrl, form, {
headers: { "Content-Type": "multipart/form-data" },
})
.then((response: any) => {
toast.success("You have succesfully signed up");
navigate("/login");
})
.catch((error) => {
toast.error(error.response.data.message);
});
};

return (
Expand All @@ -30,14 +67,28 @@ const SignUp = () => {
Already have an account? <Link href="/login">Log In</Link>
</Typography>
<Box component="form" onSubmit={handleSubmit} noValidate sx={{ mt: 1 }}>
<TextField
margin="normal"
required
fullWidth
id="username"
label="Enter your username"
name="username"
autoFocus
onChange={(e) => {
setFormData({ ...formData, username: e.target.value });
}}
/>
<TextField
margin="normal"
required
fullWidth
id="email"
label="Enter your email"
name="email"
autoFocus
onChange={(e) => {
setFormData({ ...formData, email: e.target.value });
}}
/>
<TextField
margin="normal"
Expand All @@ -47,15 +98,21 @@ const SignUp = () => {
label="Create password"
type="password"
id="password"
onChange={(e) => {
setFormData({ ...formData, password: e.target.value });
}}
/>
<TextField
margin="normal"
required
fullWidth
name="repeat-password"
name="repeatPassword"
label="Confirm password"
type="password"
id="password"
id="repeatPassword"
onChange={(e) => {
setFormData({ ...formData, repeatPassword: e.target.value });
}}
/>
<Button
type="submit"
Expand Down
2 changes: 2 additions & 0 deletions client/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import { ThemeProvider, createTheme } from "@mui/material/styles";
import { BrowserRouter, Routes, Route } from "react-router-dom";

import "./index.css";
import 'react-toastify/dist/ReactToastify.css';


const theme = createTheme({
palette: {
Expand Down
7 changes: 7 additions & 0 deletions client/src/utils/localStorageUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export const storeToken = (token: string) => {
localStorage.setItem("authToken", token);
};

export const getToken = () => {
return localStorage.getItem("authToken");
};
3 changes: 2 additions & 1 deletion server/server/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@
"django.contrib.messages",
"django.contrib.staticfiles",
"rest_framework",
"corsheaders"
"corsheaders",
"rest_framework.authtoken"
]

MIDDLEWARE = [
Expand Down
Loading
Loading