Lee SeJin

login system update

...@@ -16,10 +16,15 @@ ...@@ -16,10 +16,15 @@
16 "@babel/node": "^7.13.13", 16 "@babel/node": "^7.13.13",
17 "@babel/preset-env": "^7.14.1", 17 "@babel/preset-env": "^7.14.1",
18 "axios": "^0.21.1", 18 "axios": "^0.21.1",
19 + "connect-mongo": "^4.4.1",
20 + "dotenv": "^9.0.2",
19 "express": "^4.17.1", 21 "express": "^4.17.1",
22 + "express-session": "^1.17.1",
20 "mongoose": "^5.12.9", 23 "mongoose": "^5.12.9",
21 "morgan": "^1.10.0", 24 "morgan": "^1.10.0",
22 "nodemon": "^2.0.7", 25 "nodemon": "^2.0.7",
26 + "passport": "^0.4.1",
27 + "passport-github2": "^0.1.12",
23 "pug": "^3.0.2" 28 "pug": "^3.0.2"
24 }, 29 },
25 "devDependencies": { 30 "devDependencies": {
......
1 import axios from "axios"; 1 import axios from "axios";
2 +import passport from "passport";
2 import User from "../models/User"; 3 import User from "../models/User";
3 4
4 const getQuote = async (req,res) =>{ 5 const getQuote = async (req,res) =>{
...@@ -41,3 +42,40 @@ export const getLogin = (req,res)=>{ ...@@ -41,3 +42,40 @@ export const getLogin = (req,res)=>{
41 export const handleUsers = (req,res)=>{ 42 export const handleUsers = (req,res)=>{
42 res.render("users",{pageTitle:"Users"}); 43 res.render("users",{pageTitle:"Users"});
43 } 44 }
45 +
46 +export const githubLogin = passport.authenticate("github", {scope: [ "user:email" ]});
47 +
48 +export const githubLoginCallback = async (_, __, profile, done) =>{
49 + const {_json: {id:githubId, login:githubName, avatar_url:avatarUrl, name, email}} = profile;
50 +
51 + try{
52 + const user = await User.findOne({email});
53 + if(user){
54 + user.githubId = githubId,
55 + user.githubName = githubName
56 + await user.save();
57 + return done(null, user);
58 + }else{
59 + const newUser = await User.create({
60 + githubId,
61 + githubName,
62 + avatarUrl,
63 + name,
64 + email
65 + });
66 + return done(null, newUser);
67 + }
68 + }catch(error){
69 + return done(error);
70 + }
71 +};
72 +
73 +export const postGithubLogin = (req,res)=>{
74 + const userId = req.user.id;
75 + res.redirect(`/users/${userId}`);
76 +}
77 +
78 +export const logout = (req,res)=>{
79 + req.logout();
80 + res.redirect("/");
81 +}
...\ No newline at end of file ...\ No newline at end of file
......
1 import mongoose from "mongoose"; 1 import mongoose from "mongoose";
2 2
3 -mongoose.connect("mongodb://127.0.0.1:27017/dev-profile",{ 3 +mongoose.connect(process.env.DB_URL,{
4 useNewUrlParser: true, 4 useNewUrlParser: true,
5 useFindAndModify: false, 5 useFindAndModify: false,
6 - useUnifiedTopology: true 6 + useUnifiedTopology: true,
7 + useCreateIndex: true
7 } 8 }
8 ); 9 );
9 10
......
1 +import "dotenv/config";
1 import "./db"; 2 import "./db";
2 import "./models/User"; 3 import "./models/User";
3 import app from "./server"; 4 import app from "./server";
......
1 export const localsMiddleware = (req,res,next) => { 1 export const localsMiddleware = (req,res,next) => {
2 res.locals.siteName = "Dev Profile"; 2 res.locals.siteName = "Dev Profile";
3 + res.locals.loggedUser = req.user || null;
4 +
3 next(); 5 next();
6 +};
7 +
8 +export const onlyPublic = (req, res, next) => {
9 + if(req.user){
10 + res.redirect("/");
11 + } else {
12 + next();
13 + }
14 +};
15 +
16 +export const onlyPrivate = (req, res, next) => {
17 + if(req.user){
18 + next();
19 + } else {
20 + res.redirect("/");
21 + }
4 }; 22 };
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -7,12 +7,14 @@ const UserSchema = new mongoose.Schema({ ...@@ -7,12 +7,14 @@ const UserSchema = new mongoose.Schema({
7 }, 7 },
8 email: { 8 email: {
9 type: String, 9 type: String,
10 - trim: true 10 + trim: true,
11 + unique: true
11 }, 12 },
12 avatarUrl: String, 13 avatarUrl: String,
13 githubId: { 14 githubId: {
14 type: Number, 15 type: Number,
15 - required: "GitHub id is required" 16 + required: "GitHub id is required",
17 + unique: true
16 }, 18 },
17 githubName: { 19 githubName: {
18 type: String, 20 type: String,
...@@ -40,6 +42,13 @@ const UserSchema = new mongoose.Schema({ ...@@ -40,6 +42,13 @@ const UserSchema = new mongoose.Schema({
40 } 42 }
41 }); 43 });
42 44
45 +UserSchema.static("formatTech", function(tech){
46 + return tech.split(",");
47 +});
48 +UserSchema.static("formatCareer",function(career){
49 + return career.split(",");
50 +});
51 +
43 const User = mongoose.model("User", UserSchema); 52 const User = mongoose.model("User", UserSchema);
44 53
45 54
......
1 +import passport from "passport";
2 +import GithubStrategy from "passport-github2";
3 +import { githubLoginCallback } from "./controllers/userController";
4 +import User from "./models/User";
5 +
6 +passport.use(new GithubStrategy(
7 + {
8 + clientID: process.env.GH_ID,
9 + clientSecret: process.env.GH_SECRET,
10 + callbackURL: `http://localhost:5500/auth/github/callback`
11 + },
12 + githubLoginCallback
13 +)
14 +);
15 +
16 +passport.serializeUser(function(user, done) {
17 + done(null, user);
18 + });
19 +
20 + passport.deserializeUser(function(user, done) {
21 + done(null, user);
22 + });
...\ No newline at end of file ...\ No newline at end of file
1 import express from "express"; 1 import express from "express";
2 -import { getJoin, getLogin, handleHome } from "../controllers/userController"; 2 +import passport from "passport";
3 +import { getJoin, getLogin, githubLogin, handleHome, logout, postGithubLogin } from "../controllers/userController";
4 +import { onlyPrivate, onlyPublic } from "../middlewares";
3 5
4 6
5 7
6 const globalRouter = express.Router(); 8 const globalRouter = express.Router();
7 9
8 globalRouter.get("/",handleHome); 10 globalRouter.get("/",handleHome);
9 -globalRouter.get("/join", getJoin); 11 +globalRouter.get("/join", onlyPublic, getJoin);
10 -globalRouter.get("/login",getLogin); 12 +globalRouter.get("/login", onlyPublic, getLogin);
13 +globalRouter.get("/logout", onlyPrivate, logout);
11 14
15 +globalRouter.get("/auth/github", githubLogin);
16 +globalRouter.get(
17 + "/auth/github/callback",
18 + passport.authenticate("github",{failureRedirect: "/login"}),
19 + postGithubLogin
20 +);
12 21
13 export default globalRouter; 22 export default globalRouter;
...\ No newline at end of file ...\ No newline at end of file
......
1 import express from "express"; 1 import express from "express";
2 import { getEditProfile, getUserDetail, handleUsers, postEditProfile } from "../controllers/userController"; 2 import { getEditProfile, getUserDetail, handleUsers, postEditProfile } from "../controllers/userController";
3 +import { onlyPrivate } from "../middlewares";
3 4
4 5
5 const userRouter = express.Router(); 6 const userRouter = express.Router();
6 7
7 userRouter.get("/",handleUsers); 8 userRouter.get("/",handleUsers);
8 9
9 -userRouter.get("/edit-profile", getEditProfile); 10 +userRouter.get("/edit-profile", onlyPrivate, getEditProfile);
10 -userRouter.post("/edit-profile", postEditProfile); 11 +userRouter.post("/edit-profile", onlyPrivate, postEditProfile);
11 12
12 userRouter.get("/:id", getUserDetail); 13 userRouter.get("/:id", getUserDetail);
13 14
......
1 import express from "express"; 1 import express from "express";
2 import path from "path"; 2 import path from "path";
3 import morgan from "morgan"; 3 import morgan from "morgan";
4 +import session from "express-session";
5 +import passport from "passport";
6 +import MongoStore from "connect-mongo";
4 import globalRouter from "./routers/globalRouter"; 7 import globalRouter from "./routers/globalRouter";
5 import userRouter from "./routers/userRouter"; 8 import userRouter from "./routers/userRouter";
6 import { localsMiddleware } from "./middlewares"; 9 import { localsMiddleware } from "./middlewares";
7 - 10 +import "./passport";
8 11
9 12
10 const app = express(); 13 const app = express();
...@@ -16,7 +19,17 @@ app.use(express.static(path.join(__dirname, "static"))); ...@@ -16,7 +19,17 @@ app.use(express.static(path.join(__dirname, "static")));
16 app.use(morgan("dev")); 19 app.use(morgan("dev"));
17 app.use(express.json()); 20 app.use(express.json());
18 app.use(express.urlencoded({ extended: true })); 21 app.use(express.urlencoded({ extended: true }));
19 - 22 +app.use(
23 + session({
24 + secret: process.env.COOKIE_SECRET,
25 + resave: true,
26 + saveUninitialized: false,
27 + store: MongoStore.create({mongoUrl: process.env.DB_URL})
28 + })
29 +);
30 +
31 +app.use(passport.initialize());
32 +app.use(passport.session());
20 33
21 app.use(localsMiddleware); 34 app.use(localsMiddleware);
22 app.use("/", globalRouter); 35 app.use("/", globalRouter);
......
...@@ -4,7 +4,7 @@ block content ...@@ -4,7 +4,7 @@ block content
4 i.fas.fa-location-arrow 4 i.fas.fa-location-arrow
5 h3 Start with GitHub! 5 h3 Start with GitHub!
6 button.login-github 6 button.login-github
7 - a(href="#") 7 + a(href="/auth/github")
8 span 8 span
9 i.fab.fa-github 9 i.fab.fa-github
10 |Join with GitHub 10 |Join with GitHub
......
...@@ -4,7 +4,7 @@ block content ...@@ -4,7 +4,7 @@ block content
4 i.fas.fa-location-arrow 4 i.fas.fa-location-arrow
5 h3 Login with GitHub! 5 h3 Login with GitHub!
6 button.login-github 6 button.login-github
7 - a(href="#") 7 + a(href="/auth/github")
8 span 8 span
9 i.fab.fa-github 9 i.fab.fa-github
10 |Login with GitHub 10 |Login with GitHub
......
...@@ -2,11 +2,18 @@ header.header ...@@ -2,11 +2,18 @@ header.header
2 .header__wrapper 2 .header__wrapper
3 .header__column 3 .header__column
4 ul 4 ul
5 - li
6 - a(href="/") Home
7 - li
8 - a(href="/join") Join
9 - li
10 - a(href="/login") Log In
11 - li
12 - a(href="/users/edit-profile") Edit Profile
...\ No newline at end of file ...\ No newline at end of file
5 + if !loggedUser
6 + li
7 + a(href="/") Home
8 + li
9 + a(href="/join") Join
10 + li
11 + a(href="/login") Log In
12 +
13 + else
14 + li
15 + a(href="/") Home
16 + li
17 + a(href="/users/edit-profile") Edit Profile
18 + li
19 + a(href="/logout") Log Out
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -5,6 +5,7 @@ block content ...@@ -5,6 +5,7 @@ block content
5 .user-quote 5 .user-quote
6 h2=quote 6 h2=quote
7 h3=author 7 h3=author
8 + hr
8 .user-profile 9 .user-profile
9 .user-profile__column 10 .user-profile__column
10 img(src="#") 11 img(src="#")
...@@ -20,6 +21,7 @@ block content ...@@ -20,6 +21,7 @@ block content
20 h3 TECH 21 h3 TECH
21 h3 CAREER 22 h3 CAREER
22 h3 SELF-INTRODUCTION 23 h3 SELF-INTRODUCTION
24 + hr
23 .user-status 25 .user-status
24 .user-status__contributions 26 .user-status__contributions
25 img(src="http://ghchart.rshah.org/lsj8706" alt="Name Your Github chart") 27 img(src="http://ghchart.rshah.org/lsj8706" alt="Name Your Github chart")
......