Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
6e18d4f
Delete netlify.toml
AntonellaMorittu May 22, 2024
2f01730
create folder and form
jyy009 May 22, 2024
530fca6
added backend user
viktoria-olo May 22, 2024
dbd5e32
added some styling to registration section
schouenkes May 23, 2024
47ae853
changed the registration layout for bigger screens
schouenkes May 23, 2024
f1616bc
added a focus/blur function for the placeholder
schouenkes May 23, 2024
fa9f16b
small styling changes
schouenkes May 23, 2024
2936a6a
Merge pull request #1 from jyy009/styling
schouenkes May 23, 2024
cdd227f
Co-authored-by: viktoria-olo <viktoria-olo@users.noreply.github.com>
jyy009 May 23, 2024
980aa59
create register form
jyy009 May 23, 2024
d618568
fetch from authenticated endpoint
viktoria-olo May 23, 2024
95d8b2d
simplified the form data
viktoria-olo May 23, 2024
cc87c2e
Merge pull request #2 from jyy009/secondary
viktoria-olo May 23, 2024
5d0c53f
add store.jsx
jyy009 May 24, 2024
8ed5598
Co-authored-by: Maja Schouenke <schouenkes@users.noreply.github.com>
viktoria-olo May 24, 2024
345cb60
Co-authored-by: Maja Schouenke <schouenkes@users.noreply.github.com>
viktoria-olo May 24, 2024
4d0d982
redirecting, exchanged errors
viktoria-olo May 24, 2024
3462935
got fetch authorization and sign out to work
viktoria-olo May 24, 2024
8d9822c
added redirection after signing up
viktoria-olo May 24, 2024
c205c88
added some validation and greetings
viktoria-olo May 25, 2024
02cac10
Merge pull request #3 from jyy009/state
viktoria-olo May 25, 2024
ec71b99
style session page
jyy009 May 25, 2024
41db70b
Merge pull request #4 from jyy009/styling-session
jyy009 May 25, 2024
7b6ae70
split up formData state management
jyy009 May 25, 2024
58b6a98
Merge pull request #5 from jyy009/state-v2
jyy009 May 25, 2024
339e580
add expressListEndpoints and update readme
jyy009 May 26, 2024
cee8c4e
Merge pull request #6 from jyy009/state-v2
jyy009 May 26, 2024
0a11cbd
i dotenv && mongodb
jyy009 May 26, 2024
a30aa7c
updated the api url
viktoria-olo May 26, 2024
53385a5
added _redirects
viktoria-olo May 26, 2024
6b8ca5a
copied _redirects to public
viktoria-olo May 26, 2024
70dc24e
added netlify link
viktoria-olo May 26, 2024
633f188
updated readme
viktoria-olo May 27, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
# Project Auth API

Replace this readme with your own information about your project.
Developed a backend API and frontend registration & sign-in form.

API uses mongoose to include endpoints for user registration & sign-in, authenticated endpoint accessible only to logged-in users, storing and removing access tokens.

Start by briefly describing the assignment in a sentence or two. Keep it short and to the point.

## 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?
We had issues storing the access token, but figured it out by parsing the token to JSON.

## 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.
#### Backend:
https://project-auth-kh49.onrender.com/

#### Frontend:
https://heroic-beignet-77e068.netlify.app/
8 changes: 6 additions & 2 deletions backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,13 @@
"@babel/core": "^7.17.9",
"@babel/node": "^7.16.8",
"@babel/preset-env": "^7.16.11",
"bcrypt": "^5.1.1",
"cors": "^2.8.5",
"dotenv": "^16.4.5",
"express": "^4.17.3",
"mongoose": "^8.0.0",
"nodemon": "^3.0.1"
"express-list-endpoints": "^7.1.0",
"mongodb": "^6.6.2",
"mongoose": "^8.4.0",
"nodemon": "^3.1.1"
}
}
99 changes: 94 additions & 5 deletions backend/server.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,59 @@
import cors from "cors";
import express from "express";
import mongoose from "mongoose";
import bcrypt from "bcrypt";
import expressListEndpoints from "express-list-endpoints";

const mongoUrl = process.env.MONGO_URL || "mongodb://localhost/project-mongo";
const mongoUrl = process.env.MONGO_URL || "mongodb://localhost/project-auth";
mongoose.connect(mongoUrl);
mongoose.Promise = Promise;

// 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 { Schema } = mongoose;

// Schema
const userSchema = new Schema({
name: {
type: String,
required: true,
},
username: {
type: String,
unique: true,
required: true,
},
email: {
type: String,
unique: true,
required: true,
},
password: {
type: String,
required: true,
},
address: {
type: String,
required: true,
},
accessToken: {
type: String,
default: () => bcrypt.genSaltSync(),
},
});

// Model
const User = mongoose.model("User", userSchema);

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 });
}
};

// Defines the port the app will run on. Defaults to 8080
const port = process.env.PORT || 8080;
const app = express();

Expand All @@ -18,7 +63,51 @@ app.use(express.json());

// Start defining your routes here
app.get("/", (req, res) => {
res.send("Hello Technigo!");
const endpoints = expressListEndpoints(app)
res.json(endpoints)
});

app.get("/users", async (req, res) => {
const allUsers = await User.find().exec();
if (allUsers.length > 0) {
res.json(allUsers);
} else {
res.status(404).send("No users found");
}
});

app.post("/users", async (req, res) => {
try {
const { name, username, email, password, address } = req.body;
const salt = bcrypt.genSaltSync();
const user = new User({
name,
username,
email,
password: bcrypt.hashSync(password, salt),
address,
});
await user.save();
res.status(201).json({ userId: user._id, accessToken: user.accessToken });
} catch (error) {
res
.status(400)
.json({ message: "Could not create user", errors: error.errors });
}
});

app.get("/logged-in", authenticateUser);
app.get("/logged-in", (req, res) => {
res.json({ message: "You are signed in." });
});

app.post("/sessions", async (req, res) => {
const user = await User.findOne({ username: req.body.username });
if (user && bcrypt.compareSync(req.body.password, user.password)) {
res.json({ userId: user._id, accessToken: user.accessToken });
} else {
res.json({ notFound: true });
}
});

// Start the server
Expand Down
2 changes: 2 additions & 0 deletions frontend/.eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,6 @@ module.exports = {
{ allowConstantExport: true },
],
},
'react/prop-types': "off"
}

1 change: 1 addition & 0 deletions frontend/_redirects
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/* /index.html 200
7 changes: 4 additions & 3 deletions frontend/index.html
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
<!doctype html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Playfair+Display" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Work+Sans:300,400" />
<title>Log in</title>
</head>
<body>
<div id="root"></div>
Expand Down
4 changes: 3 additions & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
},
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0"
"react-dom": "^18.2.0",
"react-router-dom": "^6.23.1",
"zustand": "^4.5.2"
},
"devDependencies": {
"@types/react": "^18.2.15",
Expand Down
1 change: 1 addition & 0 deletions frontend/public/_redirects
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/* /index.html 200
10 changes: 9 additions & 1 deletion frontend/src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
import { BrowserRouter } from "react-router-dom";
import { Home } from "./components/Home";
import { RouteList } from "./components/RouteList";

export const App = () => {
return <div>Find me in src/app.jsx!</div>;
return (
<BrowserRouter>
<RouteList />
</BrowserRouter>
);
};
7 changes: 7 additions & 0 deletions frontend/src/components/Button.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export const Button = ({ btnText, type, onClick }) => {
return (
<button onClick={onClick} type={type}>
{btnText}
</button>
);
};
3 changes: 3 additions & 0 deletions frontend/src/components/Headline.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const Headline = ({ titleText }) => {
return <h2>{titleText}</h2>;
};
11 changes: 11 additions & 0 deletions frontend/src/components/Home.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { LogIn } from "./LogIn";
import { Register } from "./Register";

export const Home = () => {
return (
<div className="outer-container">
<LogIn />
<Register />
</div>
);
};
61 changes: 61 additions & 0 deletions frontend/src/components/LogIn.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { Button } from "./Button";
import { Headline } from "./Headline";
import { TextInput } from "./TextInput";
import { useStore } from "../store/useStore";
import { useState } from "react";

export const LogIn = () => {
const { loginData, handleSubmitLogin, handleLoginChange } = useStore();
const [isLoading, setIsLoading] = useState(false);

const handleFormSubmit = async (event) => {
event.preventDefault();
setIsLoading(true);

try {
await handleSubmitLogin(event);
// Redirect to /logged-in after successful login
window.location.href = "/logged-in";
} catch (error) {
console.error("Error logging in", error);
setIsLoading(false);
}
};

return (
<>
<form onSubmit={handleFormSubmit}>
<div className="title-box">
<Headline titleText={"Log in"} />
<div className="text-box">
<p>Welcome back, let the literary adventures continue!</p>
</div>
</div>
<div className="input-tablet-desktop">
<TextInput
label={"Username"}
inputType={"text"}
inputName={"username"}
placeholder={"Type your username"}
value={loginData.username}
onChange={(event) =>
handleLoginChange("username", event.target.value)
}
/>

<TextInput
label={"Password"}
inputType={"password"}
inputName={"password"}
placeholder={"Type your password"}
value={loginData.password}
onChange={(event) =>
handleLoginChange("password", event.target.value)
}
/>
</div>
<Button type={"submit"} btnText={"Log in"} disabled={isLoading} />
</form>
</>
);
};
Loading