SeungJun Baek

프로젝트 완성

1 { 1 {
2 - "exec":"npx babel-node src/backend/server.js" 2 + "exec":"npx babel-node src/backend/init.js"
3 } 3 }
4 4
......
This diff is collapsed. Click to expand it.
...@@ -16,8 +16,12 @@ ...@@ -16,8 +16,12 @@
16 }, 16 },
17 "dependencies": { 17 "dependencies": {
18 "babel-loader": "^8.2.5", 18 "babel-loader": "^8.2.5",
19 + "bcrypt": "^5.0.1",
20 + "connect-mongo": "^4.6.0",
19 "dotenv": "^16.0.1", 21 "dotenv": "^16.0.1",
20 "express": "^4.18.1", 22 "express": "^4.18.1",
23 + "express-session": "^1.17.3",
24 + "mongoose": "^6.3.5",
21 "node-fetch": "^2.6.1", 25 "node-fetch": "^2.6.1",
22 "pug": "^3.0.2" 26 "pug": "^3.0.2"
23 } 27 }
......
1 -export const home = (req,res)=>{ 1 +import fetch from"node-fetch";
2 - return res.render("home",{siteTitle: "movie!",pageTitle:"home Page!"}); 2 +import User from "../../models/User"
3 +import bcrypt from "bcrypt"
4 +
5 +export const home = async(req,res)=>{
6 + const KEY= process.env.API_KEY
7 + const data = await fetch(`https://api.themoviedb.org/3/trending/movie/week?api_key=${KEY}`,{
8 + method:"GET",
9 + })
10 + const movies = await data.json();
11 + return res.render("home",{siteTitle: "movie!",pageTitle:"home Page!",movies: movies.results});
12 +}
13 +
14 +export const getJoin = (req,res) =>{
15 + res.render('join.pug',{pageTitle:"Join!",siteTitle:"movie!"})
16 +}
17 +
18 +export const postJoin = async (req,res) =>{
19 + const { email,
20 + username,
21 + password,
22 + passwordcheck, } = req.body;
23 + const pageTitle = "Join";
24 + if (password !== passwordcheck) {
25 + return res.status(400).render("join.pug", {
26 + pageTitle,
27 + errorMessage: "Password confirmation does not match.",
28 + });
29 + }
30 + const exists = await User.exists({ $or: [{ username }, { email }] });
31 + if (exists) {
32 + return res.status(400).render("join", {
33 + pageTitle,
34 + errorMessage: "This username/email is already taken.",
35 + });
36 + }
37 + try {
38 + await User.create({
39 + username,
40 + email,
41 + password,
42 + });
43 + return res.redirect("/login");
44 + } catch(error){
45 + return res.status(400).res.render("join", {
46 + pageTitle: "Upload Video" ,
47 + errorMessage: error._message,
48 + });
49 +}
3 } 50 }
4 51
5 -export const join= (req,res) =>{ 52 +export const getLogin = (req,res)=>{
6 - return res.send("hello this is joinpage!"); 53 + return res.render("login",{siteTitle:"movie!",pageTitle:"Login!"})
7 } 54 }
8 55
9 -export const login = (req,res)=>{ 56 +export const postLogin = async (req,res) =>
10 - return res.send("hello this is login!"); 57 +{
58 + const PAGETITLE = "Login"
59 + const {username,password} = req.body;
60 + console.log(username,password)
61 + const user = await User.findOne({username});
62 + console.log(user)
63 + if(!user){
64 + return res.status(400).render("login",{pageTitle:PAGETITLE,error:"An account with that username is not found"})
65 + }
66 + if (user.isO_Auth)
67 + return res.status(400).render("login",{pageTitle:PAGETITLE,error:"Please login with Github"})
68 + const ok = await bcrypt.compare(password,user.password);
69 + if(!ok){
70 + return res.status(400).render("login",{pageTitle:PAGETITLE,error:"something wrong..."})
71 + }
72 + req.session.loggedIn = true;
73 + req.session.user = user;
74 + return res.redirect('/');
75 +}
76 +
77 +export const startGithubLogin = (req,res) =>
78 +{
79 + const baseURL = `https://github.com/login/oauth/authorize`
80 + const config = {
81 + client_id: process.env.O_Auth_client_id,
82 + allow_signup:false,
83 + scope:"read:user user:email"
84 + }
85 + const params = new URLSearchParams(config).toString();
86 + const finalURL = `${baseURL}?${params}`
87 + console.log(finalURL);
88 + return res.redirect(finalURL);
89 +}
90 +
91 +export const finishGithubLogin = async (req,res) =>
92 +{
93 +
94 + const config = {
95 + client_id: process.env.O_AUTH_CLIENT_ID,
96 + client_secret : process.env.O_Auth_scret,
97 + code: req.query.code
98 + }
99 + const params = new URLSearchParams(config).toString();
100 + const baseURL = `https://github.com/login/oauth/access_token`;
101 + const finalURL = `${baseURL}?${params}`;
102 + console.log(req.query);
103 + const data = await fetch(finalURL,{
104 + method:"POST",
105 + headers:{
106 + Accept: "application/json",
107 + }
108 + });
109 + const token = await data.json();
110 + if("access_token" in token)
111 + {
112 + const {access_token} = token;
113 + const apiUrl = "https://api.github.com"
114 + const getUserData = await fetch(`${apiUrl}/user`,{
115 + method:"GET",
116 + headers:{
117 + Authorization: `token ${access_token}`
118 + }
119 + });
120 + const emailData = await (
121 + await fetch(`${apiUrl}/user/emails`,{
122 + method:"GET",
123 + headers:{
124 + Authorization: `token ${access_token}`
125 + }
126 + })
127 + ).json();
128 + const emailObj = emailData.find((email) => email.primary === true && email.verified === true);
129 + if(!emailObj){
130 + return res.status(400).redirect('/login');
131 + }
132 + let user = await User.findOne({email: emailObj.email});
133 + if(!user){
134 + user = await User.create({
135 + email:emailObj.email,
136 + username:userData.login,
137 + password:"",
138 + isO_Auth: true,
139 + });
140 + }
141 + req.session.loggedIn = true,
142 + req.session.user = user;
143 + return res.redirect("/");
144 + }else{
145 + res.status(400).redirect("/login")
146 + }
11 } 147 }
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -13,6 +13,34 @@ export const showMovies = (req,res) =>{ ...@@ -13,6 +13,34 @@ export const showMovies = (req,res) =>{
13 res.send("movie home"); 13 res.send("movie home");
14 } 14 }
15 15
16 -export const movieInformation = (req,res)=>{ 16 +export const movieInformation = async (req,res)=>{
17 - res.send("movie detail"); 17 + const {id}= req.params;
18 + const KEY= process.env.API_KEY
19 + const data = await fetch(`https://api.themoviedb.org/3/movie/${id}?api_key=${KEY}&language=ko-KR`)
20 + const info = await data.json();
21 + res.render('detail.pug',{siteTitle:"movie!",pageTitle:`${info.original_title}`,info})
22 +}
23 +
24 +export const getDiscover = (req, res)=>{
25 + res.render('discover',{siteTitle:"movie!"})
26 +}
27 +
28 +export const postDiscover = async (req, res)=>{
29 + const {year, genre,rating} = req.body
30 + console.log(year,genre,rating)
31 + const KEY= process.env.API_KEY
32 + const genreData = await fetch(`https://api.themoviedb.org/3/genre/movie/list?api_key=${KEY}&language=en-US`)
33 + const genres = await genreData.json()
34 + const target = genres.genres.filter(index => index.name === genre)
35 + const genreId = target[0].id
36 +
37 + const moviesData = await fetch(`
38 + https://api.themoviedb.org/3/discover/movie?api_key=${KEY}&language=en-US&sort_by=popularity.desc&include_adult=false&include_video=false&page=1&year=${year}&vote_average.gte=${rating}&with_genres=28%2C12&with_watch_monetization_types=flatrate`,
39 + {
40 + method:"GET"
41 + })
42 + const Result = await moviesData.json()
43 + const movies = Result.results
44 + console.log(movies)
45 + return res.render(`discoverResult.pug`,{siteTitle:"movie!",movies})
18 } 46 }
......
1 -export const userId = (req,res) =>{ 1 +export const logout =(req,res)=>{
2 - //getMovies(); 2 + req.session.destroy();
3 - res.send("user page"); 3 + return res.redirect("/")
4 } 4 }
5 -
6 -export const userLikemovie = (req,res) =>{
7 - //getMovies();
8 - res.send("user's favorite");
9 -}
10 -
......
1 +import mongoose from "mongoose";
2 +
3 +
4 +mongoose.connect(process.env.DB_URL)
5 +
6 +const db = mongoose.connection;
7 +
8 +db.on("error",(error)=>console.log("DB Error",error))
9 +db.once("open",()=>console.log("DB is Ready!"))
...\ No newline at end of file ...\ No newline at end of file
1 +import "dotenv/config"
2 +import "./db"
3 +import "../models/User"
4 +import app from "./server";
5 +
6 +console.log("hihihihihih")
7 +
8 +const PORT = 3000
9 +
10 +app.listen(PORT,() => console.log(`The Server is running on http://localhost:${PORT}`));
1 +export const editLocals = (req,res,next) =>{
2 + res.locals.loggedIn = Boolean(req.session.loggedIn)
3 + res.locals.loggedInUser = req.session.user;
4 + next();
5 +}
...\ No newline at end of file ...\ No newline at end of file
1 import express from "express"; 1 import express from "express";
2 -import {home,join,login} from "../controllers/globalController" 2 +import {getJoin, getLogin, home, postJoin, postLogin} from "../controllers/globalController"
3 +import { logout } from "../controllers/usersController";
3 const globalRouter = express.Router(); 4 const globalRouter = express.Router();
4 5
5 globalRouter.get('/',home); 6 globalRouter.get('/',home);
6 -globalRouter.get('/join',join); 7 +globalRouter.get("/logout",logout)
7 -globalRouter.get('/login',login); 8 +globalRouter.route('/join').get(getJoin).post(postJoin)
9 +globalRouter.route('/login').get(getLogin).post(postLogin)
8 export default globalRouter 10 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 { showMovies, movieInformation } from "../controllers/movieController"; 2 +import { showMovies, movieInformation, getDiscover, postDiscover } from "../controllers/movieController";
3 3
4 const movieRouter = express.Router(); 4 const movieRouter = express.Router();
5 5
6 movieRouter.get('/',showMovies); 6 movieRouter.get('/',showMovies);
7 7
8 -movieRouter.get('/:id', movieInformation); 8 +movieRouter.get('/:id(\\d+)', movieInformation);
9 +
10 +movieRouter.route('/discover/').get(getDiscover).post(postDiscover)
11 +
9 12
10 export default movieRouter; 13 export default movieRouter;
...\ No newline at end of file ...\ No newline at end of file
......
1 import express from "express"; 1 import express from "express";
2 -import { userId, userLikemovie } from "../controllers/usersController"; 2 +import { finishGithubLogin, startGithubLogin } from "../controllers/globalController";
3 3
4 const userRouter = express.Router(); 4 const userRouter = express.Router();
5 5
6 -userRouter.get('/:id(\\d+)', userId); 6 +userRouter.get("/github/start",startGithubLogin)
7 -userRouter.get('/likemovie', userLikemovie); 7 +userRouter.get("/github/finish",finishGithubLogin)
8 8
9 export default userRouter 9 export default userRouter
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -2,14 +2,29 @@ import express from "express" ...@@ -2,14 +2,29 @@ import express from "express"
2 import global from "./routers/globalRouter"; 2 import global from "./routers/globalRouter";
3 import movies from "./routers/movieRouter"; 3 import movies from "./routers/movieRouter";
4 import users from "./routers/userRouter"; 4 import users from "./routers/userRouter";
5 +import session from "express-session";
6 +import MongoStore from "connect-mongo";
7 +import { editLocals } from "./middlewares";
5 8
6 const PORT = 3000 9 const PORT = 3000
7 const app = express(); 10 const app = express();
8 11
12 +
13 +app.use(express.json())
14 +app.use(express.urlencoded({extend: true}))
15 +app.use(session({
16 + secret:process.env.COOKIE_SCRET,
17 + resave:false,
18 + saveUninitialized:false,
19 + store: MongoStore.create({mongoUrl: process.env.DB_URL})
20 +}))
21 +
9 app.set('view engine',"pug"); 22 app.set('view engine',"pug");
10 app.set("views",process.cwd() +"/src/views"); 23 app.set("views",process.cwd() +"/src/views");
24 +app.use(editLocals);
11 app.use('/',global); 25 app.use('/',global);
12 app.use('/movies',movies); 26 app.use('/movies',movies);
13 app.use('/users',users) 27 app.use('/users',users)
14 28
15 -app.listen(PORT,() => console.log(`The Server is running on http://localhost:${PORT}`)); 29 +export default app
30 +
......
1 +import bcrypt from "bcrypt";
2 +import mongoose from "mongoose";
3 +
4 +const userSchema = new mongoose.Schema({
5 + email: { type: String, required: true, unique: true },
6 + username: { type: String, unique: true },
7 + password: { type: String, },
8 + likeMovies: [{type: String}],
9 + isO_Auth: {type:Boolean,default:false}
10 +});
11 +
12 +userSchema.pre('save', async function(){
13 + console.log("Users password:", this.password);
14 + this.password = await bcrypt.hash(this.password, 5);``
15 + console.log("Users password:", this.password);
16 +})
17 +
18 +const User = mongoose.model("User", userSchema);
19 +export default User;
...\ No newline at end of file ...\ No newline at end of file
1 +extends layout.pug
2 +include mixins/trending.pug
3 +
4 +block content
5 + div
6 + h1=pageTitle
7 + img(src=`https://www.themoviedb.org/t/p/w600_and_h900_bestv2${info.poster_path}`)
8 + div
9 + span=info.overview
10 + br
11 + span
12 + a(href=`https://www.themoviedb.org/movie/${info.id}`) The movie DB에서 영화정보 보기 →
...\ No newline at end of file ...\ No newline at end of file
1 +extends layout.pug
2 +
3 +block content
4 + form(method="POST")
5 + select(name="year")
6 + option(value="" selected) 년도선택
7 + option(value="2017") 2017
8 + option(value="2018") 2018
9 + option(value="2019") 2019
10 + option(value="2020") 2020
11 + option(value="2021") 2021
12 + option(value="2022") 2022
13 + select(name="genre")
14 + option(value="") 장르 선택
15 + option(value="Action") 액션
16 + option(value="Adventure") 어드벤쳐
17 + option(value="Animation") 애니메이션
18 + option(value="Comedy") 코미디
19 + option(value="Crime") 범죄
20 + option(value="Documentary") 다큐
21 + option(value="Drama") 드라마
22 + option(value="Family") 가족영화
23 + option(value="Fantasy") 판타지
24 + option(value="History") 역사
25 + option(value="Horror") 호러
26 + option(value="Music") 음악
27 + option(value="Mystery") 미스터리
28 + option(value="Romance") 로멘스
29 + option(value="Science Fiction") 공상과학
30 + option(value="TV Movie") Tv영화
31 + option(value="Thriller") 스릴러
32 + option(value="War") 전쟁
33 + option(value="Western") 서부영화
34 + select(name="rating")
35 + option(value="") 평점 선택
36 + option(value="5.0") 5.0
37 + option(value="6.0") 6.0
38 + option(value="7.0") 7.0
39 + option(value="8.0") 8.0
40 + option(value="9.0") 9.0
41 + input(value="영화 검색!" type="submit")
42 +
43 +
1 +extends layout.pug
2 +include mixins/movies.pug
3 +
4 +block content
5 + div
6 + h1 영화 검색 결과
7 + +movies(movies)
...\ No newline at end of file ...\ No newline at end of file
1 extends layout.pug 1 extends layout.pug
2 +include mixins/trending.pug
2 3
3 block content 4 block content
4 div 5 div
5 h1=pageTitle 6 h1=pageTitle
7 + small 이번주에 인기있는 영화들
8 + +trending(movies)
...\ No newline at end of file ...\ No newline at end of file
......
1 +extends layout.pug
2 +
3 +block content
4 + if errorMessage
5 + h3=errorMessage
6 + h1=pageTitle
7 + form(method="POST")
8 + input(name="email" placeholder="your email plz" required type="email")
9 + input(name="username" placeholder="your nickname!" required)
10 + input(name="password" placeholder="your password" required type="password")
11 + input(name="passwordcheck" placeholder="passwowrd validation" required type="password")
12 + input(value="join now!" type="submit")
13 + hr
14 + span
15 + a(href="/login") you already have account? login now! →
...\ No newline at end of file ...\ No newline at end of file
1 +extends layout.pug
2 +
3 +block content
4 + if errorMessage
5 + h3=errorMessage
6 + h1=pageTitle
7 + form(method="POST")
8 + input(name="username" placeholder="your username plz" required type="text")
9 + input(name="password" placeholder="your password" required type="password")
10 + input(value="login now!" type="submit")
11 + hr
12 + span
13 + a(href="/join") you don't have account? Join now! →
14 + a(href="/users/github/start") Continue with Github →
...\ No newline at end of file ...\ No newline at end of file
1 +mixin movies(movies)
2 + div
3 + ul
4 + each movie in movies
5 + li
6 + a(href=`/movies/${movie.id}`)=movie.title
...\ No newline at end of file ...\ No newline at end of file
1 +mixin trending(movies)
2 + div
3 + ul
4 + each movie in movies
5 + li
6 + a(href=`/movies/${movie.id}`)=movie.title
...\ No newline at end of file ...\ No newline at end of file
...@@ -4,4 +4,12 @@ header ...@@ -4,4 +4,12 @@ header
4 li 4 li
5 a(href="/") Home 5 a(href="/") Home
6 li 6 li
7 - a(href="/movies") Movies
...\ No newline at end of file ...\ No newline at end of file
7 + a(href="/movies/discover/") Movies
8 + if loggedIn
9 + li
10 + a(href="/logout") logout
11 + else
12 + li
13 + a(href="/login") login
14 + li
15 + a(href="/join") join
...\ No newline at end of file ...\ No newline at end of file
......