-
Notifications
You must be signed in to change notification settings - Fork 445
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
Mai, Sofie & Wen | Project Authentication #333
base: master
Are you sure you want to change the base?
Changes from all commits
077f8fd
8702ff4
3b55895
f4fb349
8b3a629
62f31c0
6e18d4f
3e17d0d
9001fc4
a8cc8da
dc384d2
208dd90
fe5a051
cff0ffc
3ee3a81
6d633bd
259ba00
c45bac3
88c131a
de9b987
f66518d
4777510
f456434
d9bc7a1
26aaecc
588f429
a99c971
4cd24ec
2d8c54c
1e3f8b6
41decd1
79b38d4
ed8206c
dd14d82
0f3a61b
3cfc769
b392e7d
08428ab
1c07171
b41d49b
998d801
9b25d4c
e9940bf
25ffea3
6d1e121
0492c38
8dba60a
563046f
0083ec0
aae2f48
3ed1e4a
8bb0793
4f9bbc8
36f8a0e
c970365
6b68167
f72c72c
a131ffc
ceeeae7
52eb2db
fb0fabf
c80e168
ed031f8
8b87e5b
3758a65
fcb137a
db8024c
4546d20
156ed53
af6cbab
d712da0
3a201f3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,12 @@ | ||
# 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 assignment involves creating a backend API with Mongoose for user registration, login, and an authenticated endpoint for logged-in users. The React frontend includes registration and login forms, a page for authenticated content, and a sign-out button that clears the access token from local storage. The API should validate user input, encrypt passwords with bcrypt, and handle unauthorized access with appropriate error messages. | ||
|
||
## 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 were confused by the instructions. Authentication using tokens was required, but we also implemented authentication using sessions with Passport.js for higher security. | ||
|
||
## 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://team-peace-auth.netlify.app | ||
Backend: https://project-auth-lh3p.onrender.com |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,31 @@ | ||
package-lock.json | ||
# dotenv environment variable files | ||
.env | ||
.env.development.local | ||
.env.test.local | ||
.env.production.local | ||
.env.local | ||
# Logs | ||
logs | ||
*.log | ||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log* | ||
pnpm-debug.log* | ||
lerna-debug.log* | ||
|
||
node_modules | ||
package-lock.json | ||
dist | ||
dist-ssr | ||
*.local | ||
|
||
# Editor directories and files | ||
.vscode/* | ||
!.vscode/extensions.json | ||
.idea | ||
.DS_Store | ||
*.suo | ||
*.ntvs* | ||
*.njsproj | ||
*.sln | ||
*.sw? |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,24 +1,128 @@ | ||
import bcrypt from "bcrypt"; | ||
import cors from "cors"; | ||
import dotenv from "dotenv"; | ||
import express from "express"; | ||
import expressListEndpoints from "express-list-endpoints"; | ||
import mongoose from "mongoose"; | ||
|
||
const mongoUrl = process.env.MONGO_URL || "mongodb://localhost/project-mongo"; | ||
dotenv.config(); | ||
const { Schema } = mongoose; | ||
const mongoUrl = | ||
process.env.MONGO_URL || "mongodb://localhost/project-authentication"; | ||
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 userSchema = new Schema({ | ||
username: { type: String, unique: true, required: true, minLength: 8 }, | ||
email: { | ||
type: String, | ||
unique: true, | ||
required: true, | ||
match: /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/, | ||
}, | ||
password: { type: String, required: true }, | ||
accessToken: { type: String, default: () => bcrypt.genSaltSync() }, | ||
}); | ||
|
||
const User = mongoose.model("User", userSchema); | ||
|
||
const port = process.env.PORT || 8080; | ||
const app = express(); | ||
|
||
// Function for authenticate by token | ||
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({ | ||
message: "Unauthorised access", | ||
success: false, | ||
error: "You are not allowed to see our top secret message!", | ||
}); | ||
} | ||
}; | ||
|
||
// Add middlewares to enable cors and json body parsing | ||
app.use(cors()); | ||
app.use( | ||
cors({ | ||
origin: "https://team-peace-auth.netlify.app", | ||
methods: ["GET", "POST"], | ||
}) // Allow sending credentials from frontend to backend | ||
); | ||
app.use(express.json()); | ||
|
||
// Start defining your routes here | ||
app.get("/", (req, res) => { | ||
res.send("Hello Technigo!"); | ||
const endpoints = expressListEndpoints(app); | ||
res.json(endpoints); | ||
}); | ||
|
||
// Sign-up | ||
app.post("/signup", async (req, res) => { | ||
try { | ||
const { username, email, password } = req.body; | ||
const user = new User({ | ||
username, | ||
email, | ||
password: bcrypt.hashSync(password, 10), | ||
}); | ||
await user.save(); | ||
res.status(201).json({ message: "Sign up successfully", success: true }); | ||
} catch (error) { | ||
console.log(error.message); | ||
res.status(400).json({ | ||
message: "Could not sign up.", | ||
success: false, | ||
error: error.message, | ||
}); | ||
} | ||
}); | ||
|
||
// Log-in | ||
app.post("/login", async (req, res) => { | ||
Comment on lines
+63
to
+84
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Usually endpoints are named in plural nouns, after what they return or in this case create. So a name suggestion is: POST /users and POST /sessions |
||
try { | ||
const { username, password } = req.body; | ||
const user = await User.findOne({ username }); | ||
|
||
if (user && bcrypt.compareSync(password, user.password)) { | ||
res.status(200).json({ | ||
message: "Login Successful.", | ||
success: true, | ||
accessToken: user.accessToken, | ||
}); | ||
} else if (user) { | ||
res.status(401).json({ | ||
message: "Could not login.", | ||
success: false, | ||
error: "Incorrect password", | ||
}); | ||
} else { | ||
res.status(401).json({ | ||
message: "Could not login.", | ||
success: false, | ||
error: "Invalid username", | ||
}); | ||
} | ||
} catch (error) { | ||
res.status(400).json({ | ||
message: "Could not login. Something is wrong.", | ||
success: false, | ||
error: error.message, | ||
}); | ||
} | ||
}); | ||
|
||
// secrets - Authentication method 2 - by Token | ||
app.get("/secrets", authenticateUser); | ||
app.get("/secrets", (req, res) => { | ||
res.json({ | ||
message: "This is a super secret message", | ||
success: true, | ||
id: req.user._id, | ||
name: req.user.username, | ||
}); | ||
}); | ||
|
||
// Start the server | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,11 @@ | ||
import { AuthRoutes } from "./routes/AuthRoutes"; | ||
import { BrowserRouter } from "react-router-dom"; | ||
|
||
export const App = () => { | ||
return <div>Find me in src/app.jsx!</div>; | ||
return ( | ||
<BrowserRouter> | ||
<h1>TOP secret saver!</h1> | ||
<AuthRoutes /> | ||
</BrowserRouter> | ||
); | ||
}; |
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{"v":"5.8.1","fr":29.9700012207031,"ip":0,"op":57.0000023216576,"w":1080,"h":1080,"nm":"Comp 1","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":5,"ty":4,"nm":"Load3 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[540,539,0],"ix":2,"l":2},"a":{"a":0,"k":[1518,1004.5,0],"ix":1,"l":2},"s":{"a":0,"k":[51.5,51.5,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-350.603,530.029],[-350.603,-100.78799999999998],[-193.633,-684.641],[0.001,-684.641],[350.603,-527.678],[350.603,334.722],[350.603,339.305],[195.99099999999999,684.641],[-5.267,684.641]],"o":[[-350.603,339.305],[-350.603,-527.678],[0,-684.641],[193.633,-684.641],[350.603,-334.046],[350.603,334.722],[350.603,530.029],[5.267,684.641],[-195.99099999999999,684.641]],"v":[[-350.603,339.305],[-350.603,-334.046],[0,-684.641],[0.001,-684.641],[350.603,-334.046],[350.603,334.722],[350.603,339.305],[5.267,684.641],[-5.267,684.641]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":7,"s":[50]},{"t":37.0000015070409,"s":[0]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":7,"s":[69]},{"t":37.0000015070409,"s":[19]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false,"_render":true},{"ty":"st","c":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":7,"s":[0.9244,0.8486,0.3556,1]},{"t":37.0000015070409,"s":[0.2353,0.149,0.9961,1]}],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":150,"ix":5},"lc":2,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[1327.382,1042.938],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 4","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false,"_render":true}],"ip":0,"op":58.0000023623884,"st":-38.0000015477717,"bm":0,"completed":true},{"ddd":0,"ind":6,"ty":4,"nm":"Load3 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":180,"ix":10},"p":{"a":0,"k":[344,580,0],"ix":2,"l":2},"a":{"a":0,"k":[1518,1004.5,0],"ix":1,"l":2},"s":{"a":0,"k":[51.5,51.5,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-350.603,530.029],[-350.603,-100.78799999999998],[-193.633,-684.641],[0.001,-684.641],[350.603,-527.678],[350.603,334.722],[350.603,339.305],[195.99099999999999,684.641],[-5.267,684.641]],"o":[[-350.603,339.305],[-350.603,-527.678],[0,-684.641],[193.633,-684.641],[350.603,-334.046],[350.603,334.722],[350.603,530.029],[5.267,684.641],[-195.99099999999999,684.641]],"v":[[-350.603,339.305],[-350.603,-334.046],[0,-684.641],[0.001,-684.641],[350.603,-334.046],[350.603,334.722],[350.603,339.305],[5.267,684.641],[-5.267,684.641]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"st","c":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":7,"s":[0.2353,0.149,0.9961,1]},{"t":37.0000015070409,"s":[0.9725,0.8824,0.3216,1]}],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":150,"ix":5},"lc":2,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[1327.382,1042.938],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 2","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":7,"s":[50]},{"t":37.0000015070409,"s":[0]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":7,"s":[69]},{"t":37.0000015070409,"s":[19]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false,"_render":true}],"ip":0,"op":58.0000023623884,"st":-48.0000019550801,"bm":0,"completed":true},{"ddd":0,"ind":7,"ty":4,"nm":"Load3 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[799.136,559.345,0],"ix":2,"l":2},"a":{"a":0,"k":[2021.177,1040.875,0],"ix":1,"l":2},"s":{"a":0,"k":[51.5,51.5,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-347.995,336.15],[-192.192,684.141],[0,684.141],[347.995,528.342],[347.995,-334.141],[347.995,-338.725],[193.347,-684.141],[-2.575,-684.141],[-347.995,-529.491]],"o":[[-347.995,528.342],[0,684.141],[192.192,684.141],[347.995,336.15],[347.995,-334.141],[347.995,-529.493],[2.58,-684.141],[-193.345,-684.141],[-347.995,-338.72]],"v":[[-347.995,336.15],[0,684.141],[0,684.141],[347.995,336.15],[347.995,-334.141],[347.995,-338.725],[2.58,-684.141],[-2.575,-684.141],[-347.995,-338.72]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":21,"s":[81]},{"t":51.0000020772726,"s":[31]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":21,"s":[100]},{"t":51.0000020772726,"s":[50]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false,"_render":true},{"ty":"st","c":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":21,"s":[0.3124,0.3779,0.9676,1]},{"t":51.0000020772726,"s":[1,0.5412,0.4902,1]}],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":150,"ix":5},"lc":2,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[1673.182,1042.438],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false,"_render":true}],"ip":0,"op":58.0000023623884,"st":-42.0000017106951,"bm":0,"completed":true},{"ddd":0,"ind":8,"ty":4,"nm":"Load3 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-180,"ix":10},"p":{"a":0,"k":[440.864,560.955,0],"ix":2,"l":2},"a":{"a":0,"k":[2021.177,1020.875,0],"ix":1,"l":2},"s":{"a":0,"k":[51.5,51.5,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-347.995,336.15],[-192.192,684.141],[0,684.141],[347.995,528.342],[347.995,-334.141],[347.995,-338.725],[193.347,-684.141],[-2.575,-684.141],[-347.995,-529.491]],"o":[[-347.995,528.342],[0,684.141],[192.192,684.141],[347.995,336.15],[347.995,-334.141],[347.995,-529.493],[2.58,-684.141],[-193.345,-684.141],[-347.995,-338.72]],"v":[[-347.995,336.15],[0,684.141],[0,684.141],[347.995,336.15],[347.995,-334.141],[347.995,-338.725],[2.58,-684.141],[-2.575,-684.141],[-347.995,-338.72]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":21,"s":[81]},{"t":51.0000020772726,"s":[31]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":21,"s":[100]},{"t":51.0000020772726,"s":[50]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false,"_render":true},{"ty":"st","c":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":21,"s":[0.9734,0.3373,0.2666,1]},{"t":51.0000020772726,"s":[0.4431,0.502,0.9922,1]}],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":150,"ix":5},"lc":2,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[1673.182,1022.438],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 3","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false,"_render":true}],"ip":0,"op":58.0000023623884,"st":-42.0000017106951,"bm":0,"completed":true}],"markers":[],"__complete":true} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be nice if all properties were formatted like the email one 😄