// routes/front/signup.js
import express from 'express'
const signupRouter = express.Router()
import signup from '../../controllers/front/signup.js'
signupRouter.get('/',async (req,res)=>{
signup.getItem(req,res)
})
signupRouter.post('/',async (req,res)=>{
signup.registerItem(req,res)
})
signupRouter.get('/verify/:token',async (req,res)=>{
signup.verifyToken(req,res)
})
export default signupRouter
// controllers/front/signup.js
// npm install nodemailer
// npm install jsonwebtoken
import config from "../../config.js"
import userdb from '../../models/user.js'
import nodemailer from 'nodemailer'
import jwt from 'jsonwebtoken'
import dotenv from 'dotenv'
dotenv.config()
class Signup{
async getItem(req,res){
this.config = await config()
this.config.pageTitle = 'ទំព័រចុះឈ្មោះ'
this.config.route = '/signup'
res.render('base',{data:this.config})
}
async registerItem(req,res){
this.config = await config()
this.config.pageTitle = 'ទំព័រចុះឈ្មោះ'
this.config.route = '/signup'
if(req.body.password === req.body.password1){
if(await userdb.checkUser(req)){
this.config.message = 'Email នេះមានគេប្រើរួចហើយ ជ្រើសរើស Email ថ្មី'
res.render('base',{data:this.config})
}else{
this.config.message = `សារមួយត្រូវបានផ្ញើរទៅ Email របស់លោកអ្នក សូមចុចបញ្ជាក់ពីការចុះឈ្មោះនេះ`
this.config.route = '/signup/confirm'
const userid = await userdb.registerItem(req)
await this.emailConfirm(req,userid)
res.render('base',{data:this.config})
}
}else{
this.config.message = 'ពាក្យសំងាត់មិនដូចគ្នាទេ សាកល្បងម្តងទៀត'
res.render('base',{data:this.config})
}
}
async emailConfirm(req,userid){
let mailTransporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: process.env.EMAIL_USER,
pass: process.env.EMAIL_SECRET
}
})
let mailDetails = {
from: process.env.EMAIL_USER,
to: req.body.email,
subject: 'Signup Confirmation',
text: `ចុចតំណរភ្ជាប់នេះដើម្បីសំរេចចុះឈ្មោះ ${await this.generateToken(req,userid)}`
}
mailTransporter.sendMail(mailDetails, function(err, data) {
if(err) {
console.log(err)
} else {
console.log('Email sent successfully')
}
})
}
async generateToken(req,userid){
const hostUrl = req.protocol + "://" + req.get('host')
const date = (new Date()).toString()
const mail = {
id: userid,
created: date
}
const token = jwt.sign(mail,process.env.SECRET_KEY,{expiresIn: '1d'})
return (hostUrl + "/signup/verify/" + token)
}
async verifyToken(req,res){
this.config = await config()
const token = req.params.token
if(token){
try{
jwt.verify(token,process.env.SECRET_KEY,(err,decoded)=>{
if(err){
console.log(err)
return res.sendStatus(403)
}else{
userdb.upgradeItem(req,decoded.id)
this.config.pageTitle = 'ផ្ទៀងផ្ទាត់ពាក្យសំងាត់'
this.config.route = '/login'
this.config.message = 'អ្នកអាចចុះឈ្មោះចុះផ្សាយលក់ទំនិញបានហើយ'
res.render('base',{data:this.config})
}
})
}catch(err){
console.log(err)
return res.sendStatus(403)
}
}else{
return res.sendStatus(403)
}
}
}
export default new Signup()
// models/user.js
// npm install bcryptjs
import bcrypt from 'bcryptjs'
class User{
async checkUser(req){
const query = {email:req.body.email}
return await req.mydb.collection("users").findOne(query)
}
async count(req){
return await req.mydb.collection('users').countDocuments()
}
async postItem(req){
const id = Date.now() + Math.round(Math.random() * 1E9).toString()
const hashPassword = bcrypt.hashSync(req.body.password, 12)
let newUser = {
id: id,
title: req.body.title,
content: req.body.content,
thumb: req.body.thumb,
postdate: req.body.datetime,
role: req.body.category,
email: req.body.email,
password: hashPassword,
}
await req.mydb.collection("users").insertOne(newUser)
}
async registerItem(req){
const id = Date.now() + Math.round(Math.random() * 1E9).toString()
const hashPassword = bcrypt.hashSync(req.body.password, 12)
if(req.body.thumb){
var thumb = req.body.thumb
}else{
var thumb = '/images/userthumb.png'
}
const now = new Date();
const date = new Date(now.getTime() - now.getTimezoneOffset() * 60000).toISOString().substring(0, 16)
let newUser = {
id: id,
title: req.body.title,
content: null,
thumb: thumb,
postdate: date,
role: 'subscriber',
email: req.body.email,
password: hashPassword,
}
await req.mydb.collection("users").insertOne(newUser)
return id
}
async upgradeItem(req,userid){
await req.mydb.collection("users").updateOne({id:userid},{$set:{role:'Author'}})
}
async getItem(req,amount){
return await req.mydb.collection("users").find().sort({date:-1,_id:-1}).limit(amount).toArray()
}
async editItem(req,id){
return await req.mydb.collection('users').findOne({id:id})
}
async updateItem(req){
let myquery = {id: req.params.id}
const user = await req.mydb.collection('users').findOne({id:req.params.id})
if(req.body.password === user.password){
var hashPassword = req.body.password
}else{
var hashPassword = bcrypt.hashSync(req.body.password, 12)
}
let newvalue = {$set: {
title: req.body.title,
content: req.body.content,
thumb: req.body.thumb,
postdate: req.body.datetime,
role: req.body.category,
email: req.body.email,
password: hashPassword
}}
await req.mydb.collection("users").updateOne(myquery,newvalue)
}
async updateAuthor(req){
let myquery = {id: req.params.id}
if(req.body.password === req.session.user.password){
var hashPassword = req.body.password
}else{
var hashPassword = bcrypt.hashSync(req.body.password, 12)
}
let newvalue = {$set: {
title: req.body.title,
content: req.body.content,
thumb: req.body.thumb,
postdate: req.body.datetime,
email: req.body.email,
password: hashPassword
}}
await req.mydb.collection("users").updateOne(myquery,newvalue)
}
async deleteItem(req){
await req.mydb.collection("users").deleteOne({id:req.params.id})
}
async paginateItem(req,amount){
const page = req.body.page
return await req.mydb.collection("users").find().skip(amount*page).sort({postdate:-1,_id:-1}).limit(amount).toArray()
}
}
export default new User()