diff --git a/index.js b/index.js index 7857267..1ede0ef 100644 --- a/index.js +++ b/index.js @@ -1,10 +1,15 @@ -const express = require('express') -const bodyParser = require('body-parser') -const session = require('express-session') -const app = express() +var express = require("express"); +var cookieParser = require("cookie-parser"); +var logger = require("morgan"); +var bodyParser = require("body-parser"); +const app = express(); -app.use(express.static('public')) -app.set('view engine', 'ejs') +app.use(bodyParser.urlencoded({ extended: true })); +app.use(bodyParser.json()); +app.use(logger("dev")); +app.use(express.json()); +app.use(express.urlencoded({ extended: false })); +app.use(cookieParser()); const indexRouter = require('./routes/index'); const api = require('./routes/api'); @@ -12,6 +17,18 @@ const api = require('./routes/api'); app.use('/', indexRouter); app.use('/api', api); -app.listen('3000', ()=> { - console.log('Server sudah berjalan di port 3000') -}) \ No newline at end of file +app.use("/", indexRouter); + +app.use(function (req, res, next) { + res.header("Access-Control-Allow-Origin", "*"); + res.header( + "Access-Control-Allow-Headers", + "Origin, X-Requested-With, Content-Type, Accept" + ); + next(); +}); + +app.listen("3000", () => { + console.log("Server is running on port : 3000"); +}); +module.exports = app; \ No newline at end of file diff --git a/package.json b/package.json index ac34a11..99a6fdd 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { - "name": "nekoya", + "name": "Nekoya", "version": "1.0.0", - "description": "Web application for Nekoya ~", + "description": "Nekoya Website", "main": "index.js", "scripts": { "dev": "npm i && nodemon index.js", diff --git a/public/css/register-error.css b/public/css/register-error.css new file mode 100644 index 0000000..d6dbf20 --- /dev/null +++ b/public/css/register-error.css @@ -0,0 +1,108 @@ +body { + font-family: 'Poppins', sans-serif; + background-color: #1b1c1e; +} + +.nav-color { + background-color: #212226; +} + +.nav-radius { + border-bottom-left-radius: 20px; + border-bottom-right-radius: 20px; +} + +.card { + position: center; + margin: auto; + text-align: center; + border-radius: 20px; + background-color: #212226; +} + +.icon { + position: center; + margin: auto; + width: 70%; + height: 70%; +} + +.btn { + background-color: darkred; + border-color: darkred; + border-radius: 100px; + width: 50%; +} + +.btn:hover { + background-color: red; + border-color: red; +} + +@media screen and (max-width: 766px) { + .card h2 { + font-size: 7vw; + } + + .card h5 { + font-size: 5vw; + } + + .navbar-brand { + width: 11vw; + height: 11vw; + } + +} + +@media screen and (min-width: 767px) { + .card h2 { + font-size: 4vw; + } + + .card h5 { + font-size: 2vw; + } + + .navbar-brand { + width: 8vw; + height: 8vw; + } + +} + +@media screen and (min-width: 993px) { + .card h2 { + font-size: 3vw; + } + + .card h5 { + font-size: 1.3vw; + } + + .navbar-brand { + width: 6vw; + height: 6vw; + } + +} + +@media screen and (min-width: 1400px) { + .card h2 { + font-size: 4vw; + } + + .card h5 { + font-size: 2vw; + } + + .navbar-brand { + width: 6vw; + height: 6vw; + } + + :focus { + outline: 0 !important; + box-shadow: 0 0 0 0 rgba(0, 0, 0, 0) !important; + } +} \ No newline at end of file diff --git a/routes/index.js b/routes/index.js index 1c2f64d..747b8ad 100644 --- a/routes/index.js +++ b/routes/index.js @@ -1,5 +1,10 @@ const express = require('express') const router = express.Router() +var registerlogin = require("./registerlogin"); + +router.post("/register", registerlogin.register); +router.post("/login", registerlogin.login); +router.get("/verify-email", registerlogin.verifyemail); router.get('/', (_req, res) => { res.render('pages/index'); @@ -49,13 +54,6 @@ router.get('/register', (_req, res) => { res.render('pages/register') }) -router.get('/register-verification-completed', (_req, res) => { - res.render('pages/register-verification-completed') -}) - -router.get('/register-verification-sent', (_req, res) => { - res.render('pages/register-verification-sent') -}) router.get('/about-us', (_req, res) => { res.render('pages/about-us') }) diff --git a/routes/registerlogin.js b/routes/registerlogin.js new file mode 100644 index 0000000..0811a81 --- /dev/null +++ b/routes/registerlogin.js @@ -0,0 +1,200 @@ +const bcrypt = require("bcrypt"); +const saltRounds = 10; +var nodemailer = require("nodemailer"); +var randtoken = require("rand-token"); +var db_connect = require("../db.js"); + +//send email +function sendEmail(email, token) { + var email = email; + var token = token; + var mail = nodemailer.createTransport({ + host: "mail.chocola.dev", + port: 587, + secure: false, + auth: { + user: "nekoya@chocola.dev", + pass: "Nekoya123.", + }, + tls: { + rejectUnauthorized: false, + }, + }); + var mailOptions = { + from: "nekoya@chocola.dev", + to: email, + subject: "Account Verification - Nekoya", + html: + '<p>Hello!!! Please click this link <a href="http://localhost:3000/verify-email?token=' + + token + + '">link</a> to verify your account!!! Thanks!!!</p>', + }; + mail.sendMail(mailOptions, function (error, info) { + if (error) { + return 1; + } else { + return 0; + } + }); +} + +exports.register = async function (req, res) { + if ( + !req.body.email || + !req.body.password || + !req.body.first_name || + !req.body.last_name + ) { + // Empty Fields + res.render("pages/register-error"); + } else { + db_connect.query( + "SELECT * FROM users WHERE email = ?", + [req.body.email], + async function (error, response, fields) { + if (error) { + // Error + res.render("pages/register-error"); + } else { + if (response.length > 0) { + // Email Exists + res.render("pages/register-error"); + } else { + const encryptedPassword = await bcrypt.hash( + req.body.password, + saltRounds + ); + var users = { + first_name: req.body.first_name, + last_name: req.body.last_name, + email: req.body.email, + password: encryptedPassword, + }; + db_connect.query( + "INSERT INTO users SET ?", + users, + function (error, response, fields) { + if (error) { + console.log("An error has occured...", error); + // Error + res.render("pages/register-error"); + } else { + var email = req.body.email; + db_connect.query( + 'SELECT * FROM users WHERE email ="' + email + '"', + function (err, result) { + if (err) throw err; + console.log(result[0]); + if (result.length > 0) { + var token = randtoken.generate(20); + if (result[0].verify == 0) { + var sent = sendEmail(email, token); + if (sent != "0") { + var data = { + token: token, + }; + db_connect.query( + 'UPDATE users SET ? WHERE email ="' + email + '"', + data, + function (err, result) { + if (err) throw err; + } + ); + // Success and has been sent + res.render("pages/register-verification-sent"); + } else { + // Error + res.render("pages/register-error"); + } + } + } else { + console.log("2"); + // Email isnt registered + res.render("pages/register-error"); + } + } + ); + } + } + ); + } + } + } + ); + } +}; + +exports.login = async function (req, res) { + var email = req.body.email; + var password = req.body.password; + db_connect.query( + "SELECT * FROM users WHERE email = ?", + [email], + async function (error, response, fields) { + const passCheck = await bcrypt.compare(password, response[0].password); + if (error) { + res.send({ + code: 400, + failed: "An error has occured...", + }); + } else { + if (response.length > 0) { + if (passCheck) { + if (response[0].verify == 0) { + res.send({ + code: 204, + success: "Sorry You havent verified your email", + }); + } else { + res.send({ + code: 200, + success: "Login Successful!!", + }); + } + } else { + res.send({ + code: 204, + success: "Sorry Email and password does not match", + }); + } + } else { + res.send({ + code: 204, + success: "Sorry Email does not exits", + }); + } + } + } + ); +}; + +/* verification email link */ +exports.verifyemail = function (req, res, next) { + db_connect.query( + 'SELECT * FROM users WHERE token ="' + req.query.token + '"', + function (err, result) { + if (err) throw err; + console.log(result[0].verify); + if (result[0].verify == 0) { + if (result.length > 0) { + var data = { + verify: 1, + }; + db_connect.query( + 'UPDATE users SET ? WHERE email ="' + result[0].email + '"', + data, + function (err, result) { + if (err) throw err; + } + ); + res.render("pages/register-verification-completed"); + } else { + console.log("2"); + res.render("pages/register-verification-completed"); + } + } else { + res.render("pages/register-verification-completed"); + } + } + ); +}; diff --git a/views/layouts/header.ejs b/views/layouts/header.ejs index a823a9f..5e4357f 100644 --- a/views/layouts/header.ejs +++ b/views/layouts/header.ejs @@ -41,6 +41,8 @@ <link href="/css/register-verification-completed.css" rel="stylesheet"> <% } else if(state == "register-verification-sent") { %> <link href="/css/register-verification-sent.css" rel="stylesheet"> + <% } else if(state == "register-error") { %> + <link href="/css/register-error.css" rel="stylesheet"> <% } else if(state == "forgot-password") { %> <link href="/css/forgot-password.css" rel="stylesheet"> <% } else if(state == "otp") { %> diff --git a/views/pages/login.ejs b/views/pages/login.ejs index 8e4abbf..8d84e08 100644 --- a/views/pages/login.ejs +++ b/views/pages/login.ejs @@ -13,22 +13,22 @@ <div class="col"> <div class="card text-white col-md-8 col-lg-6 col-xl-5"> <h1 class="card-header text-white">Login</h1> - <lottie-player autoplay background="transparent" class="icon" loop speed="1" + <lottie-player style="display: -webkit-box;-webkit-box-pack: center;" autoplay background="transparent" class="icon" loop speed="1" src="https://assets3.lottiefiles.com/packages/lf20_myor1trh.json"></lottie-player> <div class="card-body"> - <form class="px-4 py-3"> + <form class="px-4 py-3" action="login" method="POST"> <div class="form-group" style="text-align: left;"> <a data-feather="mail" href="" style="font-size: 40px;"></a> - <label for="exampleDropdownFormEmail1">Email</label> - <input class="form-control input-sm text-center" id="exampleDropdownFormEmail1" - placeholder="Email address" type="email"> + <label for="email">Email</label> + <input class="form-control input-sm text-center" id="email" name="email" + placeholder="Email Address" type="email"> </div> <div class="form-group" style="text-align: left;"> <a data-feather="lock" href="" style="font-size: 40px;"></a> - <label for="exampleDropdownFormPassword1">Password</label> + <label for="password">Password</label> <div class="input-group"> - <input class="form-control input-sm text-center" id="exampleDropdownFormPassword1" - name="password" placeholder="Password" type="password"> + <input class="form-control input-sm text-center" id="password" name="password" + placeholder="Password" type="password"> <div class="input-group-append"> <span class="input-group-text"> <i class="fa fa-eye" onclick="revealhidePassword()"></i> @@ -39,7 +39,7 @@ <div class="options-01 hoverlogin-1" style="word-break: keep-all;"> <label class="remember-me text-left"><input name="" type="checkbox">Remember me</label> - <a href="forgot-password" style="margin-left: 15%; font-size: 10pt;">Forgot + <a href="forgot-password.html" style="margin-left: 15%; font-size: 10pt;">Forgot your password?</a> </div> @@ -48,12 +48,12 @@ <div class="links"> <div class="google"> <i><a href=""></a><img class="google-icon-svg lazyload" - src="./img/google.webp" + src="./assets/google.webp" style="height: 30px; width: 30px; margin: 0 30px; padding-top: -3px"/><span></span></i> </div> <div class="facebook"> <i><a href=""></a><img class="facebook-icon-svg lazyload" - src="./img/facebook.webp" + src="./assets/facebook.webp" style="height: 30px; width: 30px; margin: 0 30px; padding-top: -3px"><span></span></i> </div> </div> diff --git a/views/pages/register-error.ejs b/views/pages/register-error.ejs new file mode 100644 index 0000000..9ecdb8d --- /dev/null +++ b/views/pages/register-error.ejs @@ -0,0 +1,33 @@ +<!doctype html> +<html lang="en"> + +<%- include('../layouts/header.ejs', {title: 'Register', state: 'register-error'}); %> + +<body> + <%- include('../layouts/navbar.ejs', {types: 'v2', title: 'Register'}); %> + <br> + + + <div data-aos="fade-in" data-aos-delay="500" class="container"> + <div class="row"> + <div class="col"> + <div class="card col-md-6 col-lg-6 col-xl-8"> + <div class="card-header" style="color: cyan;"> + <h2>ERROR</h2> + </div> + <lottie-player style="display: -webkit-box;-webkit-box-pack: center;" autoplay background="transparent" class="icon" loop speed="1" + src="https://assets5.lottiefiles.com/temp/lf20_QYm9j9.json"></lottie-player> + <div class="card-body"> + <h5 class="card-text" style="color: cyan;">An error has occured... Make sure to check if you have empty fields, or if your email has been registered before. Click the button below to get back to the register page.</h5> + <br style="display: block;content: ' ';margin: 1vw 0;line-height: 1vw;"> + <a class="btn btn-primary" href="register">Register</a> + </div> + </div> + </div> + </div> + </div> + + <%- include('../layouts/footer.ejs', {state: 'register-error'}); %> +</body> + +</html> \ No newline at end of file diff --git a/views/pages/register-verification-completed.ejs b/views/pages/register-verification-completed.ejs index 7a586ff..a8bea48 100644 --- a/views/pages/register-verification-completed.ejs +++ b/views/pages/register-verification-completed.ejs @@ -22,7 +22,7 @@ Using the button below..</h6> <br style="display: block;content: ' ';margin: 1vw 0;line-height: 1vw;"> - <a class="btn btn-primary" href="login.html">Sign in</a> + <a class="btn btn-primary" href="login">Sign in</a> </div> </div> </div> diff --git a/views/pages/register.ejs b/views/pages/register.ejs index d38fc2c..3bdf50a 100644 --- a/views/pages/register.ejs +++ b/views/pages/register.ejs @@ -16,7 +16,7 @@ <lottie-player style="display: -webkit-box;-webkit-box-pack: center;" autoplay background="transparent" class="icon" loop speed="1" src="https://assets10.lottiefiles.com/datafiles/JAmX1SNojoncImC/data.json"></lottie-player> <div class="card-body"> - <form class="px-4 py-3" action="api/register" method="POST"> + <form class="px-4 py-3" action="register" method="POST"> <div class="form-group"> <input class="form-control input-sm text-center" id="first_name" name="first_name" placeholder="First Name" type="text"> @@ -43,7 +43,7 @@ <button class="btn btn-register btn-primary" type="submit" >Register</button> <br style="display: block;content: ' '; margin: 1vw 0; line-height: 1vw;"> <div class="hoversignin-1 text-center"> - <a href="login.html">Already have an account ?? Click here to Sign In !!</a> + <a href="login">Already have an account ?? Click here to Sign In !!</a> </div> </form> </div>