From 0947e9b2ca2048a43edb4bcb1665494b33c6b4f8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E2=80=9Cmikaeloling=E2=80=9D?=
<“mikael.oling@gmail.com”>
Date: Sat, 9 Dec 2023 22:28:33 -0500
Subject: [PATCH 01/16] endpoints set up
---
backend/package.json | 1 +
backend/server.js | 70 ++++++++++++++++++++++++++++++++++++++++++--
package.json | 3 ++
3 files changed, 72 insertions(+), 2 deletions(-)
diff --git a/backend/package.json b/backend/package.json
index 8de5c4ce0..032708a47 100644
--- a/backend/package.json
+++ b/backend/package.json
@@ -12,6 +12,7 @@
"@babel/core": "^7.17.9",
"@babel/node": "^7.16.8",
"@babel/preset-env": "^7.16.11",
+ "bcrypt-nodejs": "^0.0.3",
"cors": "^2.8.5",
"express": "^4.17.3",
"mongoose": "^8.0.0",
diff --git a/backend/server.js b/backend/server.js
index 2d7ae8aa1..4d1abc67c 100644
--- a/backend/server.js
+++ b/backend/server.js
@@ -1,11 +1,43 @@
import express from "express";
+import bodyParser from "body-parser";
import cors from "cors";
import mongoose from "mongoose";
+import crypto from "crypto";
+import bcrypt from "bcrypt-nodejs";
-const mongoUrl = process.env.MONGO_URL || "mongodb://localhost/project-mongo";
+const mongoUrl = process.env.MONGO_URL || "mongodb://localhost/auth";
mongoose.connect(mongoUrl, { useNewUrlParser: true, useUnifiedTopology: true });
mongoose.Promise = Promise;
+
+// A model for users 4 fields: name, email, password, accessToken
+
+const User = mongoose.model("User", {
+ name: {
+ type: String,
+ required: true,
+ minlength: 2,
+ maxlength: 20,
+ },
+ email: {
+ type: String,
+ required: true,
+ unique: true,
+ minlength: 5,
+ maxlength: 30,
+ },
+ password: {
+ type: String,
+ required: true,
+ minlength: 5,
+ maxlength: 60,
+ },
+ accessToken: {
+ type: String,
+ default: () => crypto.randomBytes(128).toString("hex"),
+ },
+});
+
// Defines the port the app will run on. Defaults to 8080, but can be overridden
// when starting the server. Example command to overwrite PORT env variable value:
// PORT=9000 npm start
@@ -14,13 +46,47 @@ const app = express();
// Add middlewares to enable cors and json body parsing
app.use(cors());
-app.use(express.json());
+app.use(bodyParser.json());
// Start defining your routes here
app.get("/", (req, res) => {
res.send("Hello Technigo!");
});
+app.post("/users", async (req, res) => {
+ try {
+ const { name, email, password } = req.body;
+
+ if (existingUser) {
+ throw new Error("User already exists");
+ } else {
+ const user = new User({ name, email, password: bcrypt.hashSync(password) });
+ await user.save();
+ res.status(201).json({ id: user._id, accessToken: user.accessToken });
+ }
+ } catch (err) {
+ res.status(400).json({ message: "Could not create user", errors: err.errors });
+ }
+}
+);
+
+
+const authenticateUser = async (req, res, next) => {
+ const user = await User.findOne({ accessToken: req.header("Authorization") });
+ if (user) {
+ req.user = user;
+ next();
+ } else {
+ res.status(401).json({ loggedOut: true });
+ }
+}
+
+app.get("/secrets", authenticateUser);
+
+app.get("/secrets", (req, res) => {
+ res.json({secret: "This is a super secret message"});
+ });
+
// Start the server
app.listen(port, () => {
console.log(`Server running on http://localhost:${port}`);
diff --git a/package.json b/package.json
index d774b8cc3..d6d416761 100644
--- a/package.json
+++ b/package.json
@@ -3,5 +3,8 @@
"version": "1.0.0",
"scripts": {
"postinstall": "npm install --prefix backend"
+ },
+ "dependencies": {
+ "mongoose": "^8.0.3"
}
}
From 35ccc816c20e582e4c4b0208d637410588875e9b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E2=80=9Cmikaeloling=E2=80=9D?=
<“mikael.oling@gmail.com”>
Date: Sun, 10 Dec 2023 08:50:10 -0500
Subject: [PATCH 02/16] authentication, posting new users working
---
backend/server.js | 17 ++++++++---------
1 file changed, 8 insertions(+), 9 deletions(-)
diff --git a/backend/server.js b/backend/server.js
index 4d1abc67c..2fb169ae6 100644
--- a/backend/server.js
+++ b/backend/server.js
@@ -24,13 +24,10 @@ const User = mongoose.model("User", {
required: true,
unique: true,
minlength: 5,
- maxlength: 30,
},
password: {
type: String,
required: true,
- minlength: 5,
- maxlength: 60,
},
accessToken: {
type: String,
@@ -57,18 +54,20 @@ app.post("/users", async (req, res) => {
try {
const { name, email, password } = req.body;
- if (existingUser) {
- throw new Error("User already exists");
- } else {
+ // if (existingUser) {
+ // throw new Error("User already exists");
+ // } else {
const user = new User({ name, email, password: bcrypt.hashSync(password) });
await user.save();
res.status(201).json({ id: user._id, accessToken: user.accessToken });
}
- } catch (err) {
+ catch (err) {
+ console.log(err);
res.status(400).json({ message: "Could not create user", errors: err.errors });
}
-}
-);
+
+});
+
const authenticateUser = async (req, res, next) => {
From 5f73bdae6a933eb24c3cd2be4805d07e2d6aec26 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E2=80=9Cmikaeloling=E2=80=9D?=
<“mikael.oling@gmail.com”>
Date: Sun, 10 Dec 2023 09:04:20 -0500
Subject: [PATCH 03/16] frontend code added
---
frontend/package.json | 4 ++-
frontend/src/App.jsx | 70 +++++++++++++++++++++++++++++++++++++++++--
package.json | 4 ++-
3 files changed, 73 insertions(+), 5 deletions(-)
diff --git a/frontend/package.json b/frontend/package.json
index e9c95b79f..bd8b14efb 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -11,7 +11,9 @@
},
"dependencies": {
"react": "^18.2.0",
- "react-dom": "^18.2.0"
+ "react-dom": "^18.2.0",
+ "react-router-dom": "^6.20.1",
+ "styled-components": "^6.1.1"
},
"devDependencies": {
"@types/react": "^18.2.15",
diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx
index 1091d4310..6149f2040 100644
--- a/frontend/src/App.jsx
+++ b/frontend/src/App.jsx
@@ -1,3 +1,67 @@
-export const App = () => {
- return
Find me in src/app.jsx!
;
-};
+import React from "react";
+import { BrowserRouter as Router, Switch, Route, Redirect } from 'react-router-dom';
+import styled from 'styled-components';
+
+const AppContainer = styled.div`
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ margin-top: 2rem;
+
+ `;
+
+ const RegistrationForm = () => (
+
+ Username
+
+ Password
+
+ Register
+
+ );
+
+ const SignInForm = () => (
+
+ {/* Add your sign-in form here */}
+
+ );
+
+ const AuthenticatedContent = () => (
+
+ {/* Add your authenticated content here */}
+
+ );
+
+ const SignOutButton = () => {
+ const handleSignOut = () => {
+ // Remove the saved access token here
+ // Redirect the user to the login form
+ };
+
+ return Sign Out ;
+ };
+
+ export const App = () => {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+ };
+
diff --git a/package.json b/package.json
index d6d416761..d4d78b9ea 100644
--- a/package.json
+++ b/package.json
@@ -5,6 +5,8 @@
"postinstall": "npm install --prefix backend"
},
"dependencies": {
- "mongoose": "^8.0.3"
+ "mongoose": "^8.0.3",
+ "react-router-dom": "^6.20.1",
+ "styled-components": "^6.1.1"
}
}
From e9c0b9b9e12cdb4b92a50cecd0abc00bcb6ab75e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E2=80=9Cmikaeloling=E2=80=9D?=
<“mikael.oling@gmail.com”>
Date: Mon, 11 Dec 2023 18:54:18 -0500
Subject: [PATCH 04/16] signup, login, logout workout
---
backend/package.json | 1 +
backend/server.js | 164 +++++++++++++++++++++++++++++++++++--------
2 files changed, 134 insertions(+), 31 deletions(-)
diff --git a/backend/package.json b/backend/package.json
index 032708a47..ddc67cdf0 100644
--- a/backend/package.json
+++ b/backend/package.json
@@ -14,6 +14,7 @@
"@babel/preset-env": "^7.16.11",
"bcrypt-nodejs": "^0.0.3",
"cors": "^2.8.5",
+ "dotenv": "^16.3.1",
"express": "^4.17.3",
"mongoose": "^8.0.0",
"nodemon": "^3.0.1"
diff --git a/backend/server.js b/backend/server.js
index 2fb169ae6..fe289e842 100644
--- a/backend/server.js
+++ b/backend/server.js
@@ -4,30 +4,32 @@ import cors from "cors";
import mongoose from "mongoose";
import crypto from "crypto";
import bcrypt from "bcrypt-nodejs";
+import dotenv from "dotenv";
+dotenv.config();
-const mongoUrl = process.env.MONGO_URL || "mongodb://localhost/auth";
+// mongoose connection
+const mongoUrl = process.env.MONGO_URL
+|| "mongodb://localhost/auth";
mongoose.connect(mongoUrl, { useNewUrlParser: true, useUnifiedTopology: true });
mongoose.Promise = Promise;
-
-// A model for users 4 fields: name, email, password, accessToken
-
-const User = mongoose.model("User", {
+// schema mongoose
+const UserSchema = new mongoose.Schema({
name: {
type: String,
- required: true,
+ required: [true, "Name is required"],
minlength: 2,
maxlength: 20,
},
email: {
type: String,
- required: true,
+ required: [true, "Email is required"],
unique: true,
minlength: 5,
},
password: {
type: String,
- required: true,
+ required: [true, "Password is required"],
},
accessToken: {
type: String,
@@ -35,28 +37,83 @@ const User = mongoose.model("User", {
},
});
-// Defines the port the app will run on. Defaults to 8080, but can be overridden
-// when starting the server. Example command to overwrite PORT env variable value:
-// PORT=9000 npm start
+const SecretSchema = new mongoose.Schema({
+ message: {
+ type: String,
+ required: [true, "Message is required"],
+ },
+});
+
+
+// User model
+const User = mongoose.model("User", UserSchema, "users");
+const Secret = mongoose.model('Secret', SecretSchema, 'secrets');
+
+// Defines the port the app will run on. Defaults to 8080
const port = process.env.PORT || 8080;
const app = express();
-// Add middlewares to enable cors and json body parsing
+// Middlewares to enable cors and json body parsing
app.use(cors());
app.use(bodyParser.json());
-// Start defining your routes here
+const authenticateUser = async (req, res, next) => {
+ const user = await User.findOne({ accessToken: req.header("Authorization") });
+ if (user) {
+ req.user = user;
+ next();
+
+ } else if (!user) {
+ res.status(401).json({ loggedOut: true });
+ } else if (user) {
+ res.status(401).json({ accessDenied: true });
+
+ } else {
+ res.status(401).json({ loggedOut: true });
+ }
+}
+
+// Routes
app.get("/", (req, res) => {
- res.send("Hello Technigo!");
+ res.json([
+ {
+ // home route
+ "path": "/",
+ "methods": ["GET"],
+ "middlewares": ["anonymous"]
+ },
+ {
+ // signup route
+ "path": "/signup",
+ "methods": ["POST"],
+ "middlewares": ["anonymous"]
+ },
+ {
+ // login route
+ "path": "/login",
+ "methods": ["POST"],
+ "middlewares": ["anonymous"]
+ },
+ {
+ // secrets route
+ "path": "/secrets",
+ "methods": ["GET", "POST"],
+ "middlewares": ["authenticateUser"]
+ },
+ {
+ // logout route
+ "path": "/logout",
+ "methods": ["POST"],
+ "middlewares": ["authenticateUser"]
+ }
+
+
+ ]);
});
-app.post("/users", async (req, res) => {
+app.post("/signup", async (req, res) => {
try {
const { name, email, password } = req.body;
-
- // if (existingUser) {
- // throw new Error("User already exists");
- // } else {
const user = new User({ name, email, password: bcrypt.hashSync(password) });
await user.save();
res.status(201).json({ id: user._id, accessToken: user.accessToken });
@@ -68,25 +125,70 @@ app.post("/users", async (req, res) => {
});
+app.post("/secrets", async (req, res) => {
+ const { message } = req.body;
+ const secret = new Secret({ message });
-
-const authenticateUser = async (req, res, next) => {
- const user = await User.findOne({ accessToken: req.header("Authorization") });
- if (user) {
- req.user = user;
- next();
- } else {
- res.status(401).json({ loggedOut: true });
+ try {
+ const savedSecret = await secret.save();
+ res.status(201).json(savedSecret);
+ } catch (err) {
+ res.status(400).json({ message: 'Could not save secret to the Database', error: err.errors });
}
-}
+});
-app.get("/secrets", authenticateUser);
-app.get("/secrets", (req, res) => {
- res.json({secret: "This is a super secret message"});
+app.get("/secrets", authenticateUser, (req, res) => {
+ Secret.find().then((secrets) => {
+ res.json(secrets);
});
+}
+);
+
+// login route
+app.post("/login", async (req, res) => {
+ const { email, password } = req.body;
+
+ try {
+ const user = await User.findOne({ email });
+
+ if (!user) {
+ return res.status(400).json({ message: "Invalid email or password" });
+ }
+
+ bcrypt.compare(password, user.password, (err, isMatch) => {
+ if (err) {
+ return res.status(500).json({ message: "Something went wrong", error: err });
+ }
+
+ if (!isMatch) {
+ return res.status(400).json({ message: "Invalid email or password" });
+ }
+
+ // User is authenticated
+ res.json({ userId: user._id, accessToken: user.accessToken });
+ });
+
+ } catch (err) {
+ res.status(500).json({ message: "Something went wrong", error: err });
+ }
+});
+
+// logout route
+app.post("/logout", authenticateUser, async (req, res) => {
+ try {
+ req.user.accessToken = crypto.randomBytes(128).toString("hex");
+ await req.user.save();
+ res.status(200).json({ loggedOut: true });
+ }
+ catch (err) {
+ res.status(400).json({ message: "Could not log out", error: err });
+ }
+}
+);
// Start the server
app.listen(port, () => {
console.log(`Server running on http://localhost:${port}`);
});
+
From 0ed12537f2ac74fbfa2bd9180d623123bc539f56 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E2=80=9Cmikaeloling=E2=80=9D?=
<“mikael.oling@gmail.com”>
Date: Mon, 11 Dec 2023 20:52:05 -0500
Subject: [PATCH 05/16] basic frontend for endpoints set up
---
frontend/src/App.jsx | 156 ++++++++++++++++++++++++++----------------
frontend/src/main.jsx | 2 +-
2 files changed, 98 insertions(+), 60 deletions(-)
diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx
index 6149f2040..650ba15e6 100644
--- a/frontend/src/App.jsx
+++ b/frontend/src/App.jsx
@@ -1,67 +1,105 @@
-import React from "react";
-import { BrowserRouter as Router, Switch, Route, Redirect } from 'react-router-dom';
+import { useState } from 'react';
import styled from 'styled-components';
-const AppContainer = styled.div`
- display: flex;
- flex-direction: column;
+const API_URL = 'https://project-auth-backend.onrender.com';
+
+const Container = styled.div`
+
+ display: grid;
+ grid-template-columns: 1fr;
+ gap: 10px;
align-items: center;
- margin-top: 2rem;
-
- `;
-
- const RegistrationForm = () => (
-
- Username
-
- Password
-
- Register
-
- );
-
- const SignInForm = () => (
-
- {/* Add your sign-in form here */}
-
- );
+ justify-content: center;
+ max-width: 50%;
+ margin: 0 auto;
+ column-gap: 10px;
+`;
- const AuthenticatedContent = () => (
-
- {/* Add your authenticated content here */}
-
- );
-
- const SignOutButton = () => {
- const handleSignOut = () => {
- // Remove the saved access token here
- // Redirect the user to the login form
- };
-
- return Sign Out ;
+
+const App = () => {
+ const [user, setUser] = useState({ name: '', email: '', password: '' });
+ const [token, setToken] = useState('');
+
+ const handleChange = (event) => {
+ setUser({ ...user, [event.target.name]: event.target.value });
+ };
+
+ const handleSignup = async () => {
+ const response = await fetch(`${API_URL}/signup`, {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify(user),
+ });
+ const data = await response.json();
+ setToken(data.accessToken);
+ };
+
+ const handleLogin = async () => {
+ const response = await fetch(`${API_URL}/login`, {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify({ email: user.email, password: user.password }),
+ });
+ const data = await response.json();
+ setToken(data.accessToken);
+ };
+
+ const handleLogout = async () => {
+ await fetch(`${API_URL}/logout`, {
+ method: 'POST',
+ headers: { Authorization: token },
+ });
+ setToken('');
+ setSecrets(null);
+ }
+
+ const [newSecret, setNewSecret] = useState('');
+
+ const handlePostSecret = async () => {
+ await fetch(`${API_URL}/secrets`, {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json', Authorization: token },
+ body: JSON.stringify({ message: newSecret }),
+ });
+ setNewSecret('');
+ handleFetchSecrets();
};
- export const App = () => {
- return (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- );
+ const [secrets, setSecrets] = useState(null);
+
+ const handleFetchSecrets = async () => {
+ const response = await fetch(`${API_URL}/secrets`, {
+ headers: { Authorization: token },
+ });
+ const data = await response.json();
+ // console.log(data);
+ setSecrets(data);
+
};
+ return (
+
+ Simple Authentication App
+
+
+
+ Sign Up
+ Log In
+ Log Out
+
+ {token && setNewSecret(event.target.value)} placeholder="Enter your secret here" />}
+ {token && Post Secret }
+
+ {token && Fetch Secrets }
+ {secrets && secrets.map((secret, index) => (
+
+ {secret.message}
+
+))}
+
+
+ );
+};
+
+
+export default App;
\ No newline at end of file
diff --git a/frontend/src/main.jsx b/frontend/src/main.jsx
index 51294f399..b91620d35 100644
--- a/frontend/src/main.jsx
+++ b/frontend/src/main.jsx
@@ -1,6 +1,6 @@
import React from "react";
import ReactDOM from "react-dom/client";
-import { App } from "./App.jsx";
+import App from "./App.jsx";
import "./index.css";
ReactDOM.createRoot(document.getElementById("root")).render(
From f6b2ead84effbfc5b03310ab5d287114214ea49d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E2=80=9Cmikaeloling=E2=80=9D?=
<“mikael.oling@gmail.com”>
Date: Mon, 11 Dec 2023 21:06:06 -0500
Subject: [PATCH 06/16] scripts
---
frontend/package.json | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/frontend/package.json b/frontend/package.json
index bd8b14efb..556a713b5 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -5,7 +5,9 @@
"type": "module",
"scripts": {
"dev": "vite",
- "build": "vite build",
+
+ "start": "react-scripts start",
+ "build": "react-scripts build",
"lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0",
"preview": "vite preview"
},
From 2cc9f89483e04728d463cef7e1b75e8764c6a098 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E2=80=9Cmikaeloling=E2=80=9D?=
<“mikael.oling@gmail.com”>
Date: Mon, 11 Dec 2023 21:10:31 -0500
Subject: [PATCH 07/16] more scripts
---
frontend/package.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/frontend/package.json b/frontend/package.json
index 556a713b5..d0b82d1e0 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -5,7 +5,6 @@
"type": "module",
"scripts": {
"dev": "vite",
-
"start": "react-scripts start",
"build": "react-scripts build",
"lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0",
@@ -15,6 +14,7 @@
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.20.1",
+ "react-scripts": "^5.0.1",
"styled-components": "^6.1.1"
},
"devDependencies": {
From bec9baad783c1cc9efc2adc7e26c6b55bb28656b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E2=80=9Cmikaeloling=E2=80=9D?=
<“mikael.oling@gmail.com”>
Date: Tue, 12 Dec 2023 07:32:00 -0500
Subject: [PATCH 08/16] netlify settings
---
netlify.toml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/netlify.toml b/netlify.toml
index 95443a1f3..a0ad77f26 100644
--- a/netlify.toml
+++ b/netlify.toml
@@ -2,5 +2,5 @@
# how it should build the JavaScript assets to deploy from.
[build]
base = "frontend/"
- publish = "build/"
+ publish = "dist/"
command = "npm run build"
From 5842977c68e227f073c86bad479df4e65fc29bd2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E2=80=9Cmikaeloling=E2=80=9D?=
<“mikael.oling@gmail.com”>
Date: Tue, 12 Dec 2023 07:39:40 -0500
Subject: [PATCH 09/16] caps on doctype
---
frontend/index.html | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/frontend/index.html b/frontend/index.html
index 0c589eccd..79c470191 100644
--- a/frontend/index.html
+++ b/frontend/index.html
@@ -1,4 +1,4 @@
-
+
From fc50648ecd8151d00d625886b87f009c3373a43b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E2=80=9Cmikaeloling=E2=80=9D?=
<“mikael.oling@gmail.com”>
Date: Tue, 12 Dec 2023 07:46:57 -0500
Subject: [PATCH 10/16] toml file
---
netlify.toml | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/netlify.toml b/netlify.toml
index a0ad77f26..bfd6c0282 100644
--- a/netlify.toml
+++ b/netlify.toml
@@ -1,6 +1,11 @@
# This file tells netlify where the code for this project is and
# how it should build the JavaScript assets to deploy from.
[build]
- base = "frontend/"
- publish = "dist/"
- command = "npm run build"
+command = "npm run build"
+base = "frontend"
+publish = "dist"
+
+[[redirects]]
+from = "/*"
+to = "/index.html"
+status = 200
\ No newline at end of file
From faa7b20ec06de952545f2d9645311f2bbcbbbf93 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E2=80=9Cmikaeloling=E2=80=9D?=
<“mikael.oling@gmail.com”>
Date: Tue, 12 Dec 2023 07:54:37 -0500
Subject: [PATCH 11/16] moved index
---
frontend/{ => public}/index.html | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename frontend/{ => public}/index.html (100%)
diff --git a/frontend/index.html b/frontend/public/index.html
similarity index 100%
rename from frontend/index.html
rename to frontend/public/index.html
From 5569e2f0d767a5e96fc126edc41157c73fdf476f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E2=80=9Cmikaeloling=E2=80=9D?=
<“mikael.oling@gmail.com”>
Date: Tue, 12 Dec 2023 08:06:37 -0500
Subject: [PATCH 12/16] indexjs
---
frontend/src/{main.jsx => index.js} | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename frontend/src/{main.jsx => index.js} (100%)
diff --git a/frontend/src/main.jsx b/frontend/src/index.js
similarity index 100%
rename from frontend/src/main.jsx
rename to frontend/src/index.js
From e5cc1705f30ff759adbe1cfbf4505a3e6df64f7e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E2=80=9Cmikaeloling=E2=80=9D?=
<“mikael.oling@gmail.com”>
Date: Tue, 12 Dec 2023 08:12:01 -0500
Subject: [PATCH 13/16] package
---
frontend/package.json | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/frontend/package.json b/frontend/package.json
index d0b82d1e0..d41051273 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -6,7 +6,8 @@
"scripts": {
"dev": "vite",
"start": "react-scripts start",
- "build": "react-scripts build",
+
+ "build": "vite build",
"lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0",
"preview": "vite preview"
},
From 00da1a400d163f5af071920608f1cdeebef41761 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E2=80=9Cmikaeloling=E2=80=9D?=
<“mikael.oling@gmail.com”>
Date: Tue, 12 Dec 2023 11:03:36 -0500
Subject: [PATCH 14/16] structure
---
frontend/{public => }/index.html | 2 +-
frontend/package.json | 8 +++-----
frontend/src/{index.js => main.jsx} | 0
3 files changed, 4 insertions(+), 6 deletions(-)
rename frontend/{public => }/index.html (95%)
rename frontend/src/{index.js => main.jsx} (100%)
diff --git a/frontend/public/index.html b/frontend/index.html
similarity index 95%
rename from frontend/public/index.html
rename to frontend/index.html
index 79c470191..0c589eccd 100644
--- a/frontend/public/index.html
+++ b/frontend/index.html
@@ -1,4 +1,4 @@
-
+
diff --git a/frontend/package.json b/frontend/package.json
index d41051273..e59d0b9b4 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -5,17 +5,15 @@
"type": "module",
"scripts": {
"dev": "vite",
- "start": "react-scripts start",
+ "start": "vite preview",
+ "build": "vite build",
+ "lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0"
- "build": "vite build",
- "lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0",
- "preview": "vite preview"
},
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.20.1",
- "react-scripts": "^5.0.1",
"styled-components": "^6.1.1"
},
"devDependencies": {
diff --git a/frontend/src/index.js b/frontend/src/main.jsx
similarity index 100%
rename from frontend/src/index.js
rename to frontend/src/main.jsx
From 2827c90aa0d11805a7d62b62b91fae2ef93d7457 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E2=80=9Cmikaeloling=E2=80=9D?=
<“mikael.oling@gmail.com”>
Date: Tue, 12 Dec 2023 11:16:42 -0500
Subject: [PATCH 15/16] added loading text for login
---
frontend/src/App.jsx | 32 ++++++++++++++++++++++++--------
1 file changed, 24 insertions(+), 8 deletions(-)
diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx
index 650ba15e6..63423cfee 100644
--- a/frontend/src/App.jsx
+++ b/frontend/src/App.jsx
@@ -15,14 +15,19 @@ const Container = styled.div`
column-gap: 10px;
`;
+const Loading = () => Loading...
; // Define a loading component
+
+
const App = () => {
const [user, setUser] = useState({ name: '', email: '', password: '' });
const [token, setToken] = useState('');
+ const [loading, setLoading] = useState(false);
const handleChange = (event) => {
setUser({ ...user, [event.target.name]: event.target.value });
- };
+ }
+
const handleSignup = async () => {
const response = await fetch(`${API_URL}/signup`, {
@@ -32,9 +37,11 @@ const App = () => {
});
const data = await response.json();
setToken(data.accessToken);
- };
+ }
const handleLogin = async () => {
+ try {
+ setLoading(true);
const response = await fetch(`${API_URL}/login`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
@@ -42,7 +49,10 @@ const App = () => {
});
const data = await response.json();
setToken(data.accessToken);
- };
+ } finally {
+ setLoading(false);
+ }
+ }
const handleLogout = async () => {
await fetch(`${API_URL}/logout`, {
@@ -86,7 +96,10 @@ const App = () => {
Sign Up
Log In
Log Out
-
+ {loading ? (
+
+ ) : (
+ <>
{token && setNewSecret(event.target.value)} placeholder="Enter your secret here" />}
{token && Post Secret }
@@ -94,12 +107,15 @@ const App = () => {
{secrets && secrets.map((secret, index) => (
{secret.message}
+
))}
-
-
+ >
+ )}
+
);
-};
+}
+
-export default App;
\ No newline at end of file
+export default App;
From 772fe0d0bd871f4528f657dddcbae6d4c2046a14 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E2=80=9Cmikaeloling=E2=80=9D?=
<“mikael.oling@gmail.com”>
Date: Tue, 12 Dec 2023 11:30:58 -0500
Subject: [PATCH 16/16] readme
---
README.md | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/README.md b/README.md
index dfa05e177..f78797e3c 100644
--- a/README.md
+++ b/README.md
@@ -1,13 +1,15 @@
# Project Auth API
-Replace this readme with your own information about your project.
-
-Start by briefly describing the assignment in a sentence or two. Keep it short and to the point.
+This project is a very simple authentication API built with Node.js and Express. It allows users to sign up, log in, and access protected routes with a valid token.
## The problem
-Describe how you approached to problem, and what tools and techniques you used to solve it. How did you plan? What technologies did you use? If you had more time, what would be next?
+The main challenge was to implement user authentication and authorization. I started by setting up the server with Node.js and Express, and then used the bcrypt library to hash user passwords for secure storage.
+
+If I had more time, I would implement a password reset feature, add email verification for sign up, and refine the error handling.
## View it live
-Every project should be deployed somewhere. Be sure to include the link to the deployed project so that the viewer can click around and see what it's all about.
+Frontend: https://simple-authentication-app.netlify.app/
+
+Backend: https://project-auth-backend.onrender.com/