Having Login And Register On The Same Page NodeJS - node.js

I am setting up a simple blog site and am having problems making the user authentication setup section. What I want to be happening is to have both the Register form and the Login form on the same page (for style reasons) but my issue is is that, to my knowledge, you cannot have two POST methods on one page. I have tried multiple work arounds, like using PUT or checking if the fields are empty, but these all feel hacky and don't really work. Is there anyway to have two fully functional forms on the same page that both respond to the same route? This is my method for reference:
const express = require('express')
const bcrypt = require('bcrypt');
const passport = require('passport');
const router = express.Router()
const app = express()
const User = require('../models/User')
router.get('/', async (req, res) => {
res.render('pages/account', {
pageQuery: "Account"
});
// const allUsers = await User.find({})
// console.log(allUsers)
// User.remove({}, function(err) {
// console.log('collection removed')
// });
});
router.post('/', async (req, res) => {
let name = req.body.userNameSignUp
let password = req.body.userPasswordSignUp
let passwordConfirm = req.body.userPasswordSignUpConfirm
const hashedPassword = await bcrypt.hash(password, 10);
const newUser = new User({
userName: name,
userPassword: hashedPassword
});
if (!name || !password) {
res.render('pages/account', {
errorMessage: "*Please fill out all the fields",
pageQuery: "Account"
});
} else if (password !== passwordConfirm) {
res.render('pages/account', {
errorMessage: "*Passwords do not match",
pageQuery: "Account"
});
} else {
User.findOne({ userName: name })
.then(user => {
if (user) {
res.render('pages/account', {
errorMessage: "*Username Is Already In Use",
pageQuery: "Account"
});
}
})
}
try {
await newUser.save()
res.redirect('/account')
} catch (e) {
res.render('pages/account', {
errorMessage: "*Welp... The server's down. Come back later",
pageQuery: "Account"
});
}
});
module.exports = router;
and my ejs view for the forms:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Cheese | Account</title>
<%- include('../partials/linkandsrc'); %>
<script src="js/signUpToggle.js" defer></script>
</head>
<body>
<%- include('../partials/header'); %>
<%- include('../partials/navigation'); %>
<section class="signInSec">
<div class="account-container">
<div class="user signInBx">
<div class="imgBx">
<img src="images/SignUp.jpg" alt="">
</div>
<div class="formBx">
<form action="/account" method="POST">
<h2>Sign Up</h2>
<%- include('../partials/errorMessage'); %>
<input type="text" name="userNameSignUp" placeholder="Username">
<input type="text" name="userPasswordSignUp" placeholder="Password">
<input type="text" name="userPasswordSignUpConfirm" placeholder="Confirm Password">
<input type="submit" value="Create Account">
<p class="signin">Already have an account ? Sign In.</p>
</form>
</div>
</div>
<div class="user signUpBx">
<div class="formBx">
<form action="/account" method="POST">
<h2>Sign In</h2>
<%- include('../partials/errorMessage'); %>
<input type="text" name="userNameLogIn" placeholder="Username">
<input type="text" name="userPasswordLogIn" placeholder="Password">
<input type="submit" value="Login">
<p class="signin">Don't have an account ? Sign Up.</p>
</form>
</div>
<div class="imgBx">
<img src="images/SignIn.jpg" alt="">
</div>
</div>
</div>
</section>
</body>
</html>

If you're sure you want to have the same route (/account) handle both the sign-up and the sign-in, then one approach might be to use hidden input fields.
You could place a hidden input in the sign-up form, with name formType (call it whatever you want, this is just an example) and value signup:
<form action="/account" method="POST">
<h2>Sign Up</h2>
<%- include('../partials/errorMessage'); %>
<input type="text" name="userNameSignUp" placeholder="Username">
<input type="text" name="userPasswordSignUp" placeholder="Password">
<input type="text" name="userPasswordSignUpConfirm" placeholder="Confirm Password">
<input type="hidden" name="formType" value="signup">
<input type="submit" value="Create Account">
<p class="signin">Already have an account ? Sign In.</p>
</form>
and similarly in the sign-in form, with name formType and value signin:
<form action="/account" method="POST">
<h2>Sign In</h2>
<%- include('../partials/errorMessage'); %>
<input type="text" name="userNameLogIn" placeholder="Username">
<input type="text" name="userPasswordLogIn" placeholder="Password">
<input type="hidden" name="formType" value="signin">
<input type="submit" value="Login">
<p class="signin">Don't have an account ? Sign Up.</p>
</form>
Then, in your route handler, you could have some logic that differentiates a sign-up from a sign-in using the received formType:
router.post('/', async (req, res) => {
if ('signup' === req.body.formType) {
// Server-sided sign-up logic can go here...
} else if ('signin' === req.body.formType) {
// Server-sided sign-in logic can go here....
} else {
// Something/someone has submitted an invalid form?
}
}

Related

how to use one ejs template for updating and showing info from mongoose/mongodb?

this is my app.js file for showing and updating info for my posts in one single Ejs template called compose: when I run my code I get this error
**
SyntaxError: missing ) after argument list in C:\Users\john\Desktop\blog\views\compose.ejs while compiling ejs**
app.post("/compose", function (req, res) {
var title= req.body.postTitle
var content= req.body.postText
const post = new Post({
title: title,
content: content
});
post.save(function(err){
if (!err){
res.redirect("/");
}
});
// res.redirect("/");
});
// update posts
app.get('/update/:postid', function (req, res) {
const updateId = req.params.postid;
Post.findById({_id: updateId}, function (err, record) {
if(!err) {
if(window.location.href.indexOf(''))
res.render('compose', {post:record});
}
});
});
and this is my compose Ejs file that I wanna do both showing and updating info with Mongodb in Ejs template:
<h1>Compose</h1>
<form action="/compose" method="post">
<div class="form-group">
<label for="posttitle"> Title</label>
<input type="text" id="" class="form-control" name="postTitle" placeholder="Title" value="<% if(window.location.href.contains("update/") > -1) { %> <%= post.title } %>" >
</div>
<div class="form-group">
<label for="desc">Description</label>
<textarea class="form-control" name="postText" id="desc" cols="30" rows="10" placeholder="Description">
<% if(window.location.href.contains("update/") > -1) { %>
<%= post.content } %>
</textarea>
</div>
<button class="btn btn-myPrimary" type="submit" value="" name="button">Publish</button>
</form>
I tried to show info from mongodb it was okay so then i made a route for updating the info using same template it gives me error

Error: data and salt arguments required [creating new users]

I am a back-end beginner and just want to implement the CRUD functions for my homepage and try to send the user data to my database with a usual sign-up template. However, I keep getting the following error message: "Error: data and salt arguments required".
This is the code for creating a new user:
controller.js
require('dotenv').config()
var UserDB = require('../model/model');
var UserDB2 = require('../model/testmodel');
const jwt = require('jsonwebtoken');
const bcrypt = require('bcrypt');
const salt = 10;
exports.create=(req,res)=>{
//validate
if(!req.body){
res.status(400).send({message:'Empty'});
return;
}
//hash password
const hashedPassword= bcrypt.hashSync(req.body.password,salt)
//
//new user
const user = new UserDB({
name: req.body.name,
email: req.body.email,
password: password
})
//save database
user
.save(user)
.then(data => {
res.redirect('/signup')
})
.catch(err =>{
res.status(500).send({
message: err.message || "Mars Attacks !"
})
});
}
signup.ejs
<body>
<div class="Wrapklasse">
<div class="derKoerper">
<div class="dieKoerper dieKoerper-step-1 is-showing">
<div class="title">Sign Up</div>
<form action="/api/users" method="POST" id="add_user">
<input type="text" placeholder="Username*" required id="username" />
<input type="email" placeholder="E-Mail*" required id="email" />
<input type="password" placeholder="Password*" required id="password" />
<input type="con-password" placeholder="Confirm Password*" />
<div class="text-center">
<span id="SignUp"><img src=/img/knight.jpg alt="knight" style="width:35%" class="das_icon"></span>
<input type="submit" />
</div>
</form>
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" integrity="sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP+u1T9qYdvdihz0PPSiiqn/+/3e7Jo4EaG7TubfWGUrMQ==" crossorigin="anonymous"></script>
<script> src="/js/index.js"</script>
</body>
index.js
$("#add_user").submit(function(event){
alert("Success!");
})
router.js
const express = require('express');
const route = express.Router();
const services = require ('../services/render');
const controller = require ('../controller/controller');
const jwt = require('jsonwebtoken');
//for use
route.get('/',services.homeRoutes);
route.get('/signup',services.signup);
route.get('/forum',services.forum);
route.get('/unterforum',services.unterforum);
route.get('/beitrag',services.beitrag);
route.get('/beitrag_erstellen',services.beitrag_erstellen);
//API
route.post('/api/users',controller.create);
route.get('/api/users',controller.find);
route.put('/api/users/:id',controller.update);
route.delete('/api/users/:id',controller.delete);
module.exports=route;
Unfortunately, I don't know what the fault could be.
Make sure you have defined salt rounds ("Salt" variable) and also make sure that req.body.password is not undefined

how to send data from frontend to backend with node js

Frontend
I use ejs to create forms
<form action="/users/create" method="POST">
<div class="row">
<div class="col-2">
Id Advance Requisition
</div>
<div class="col-6">
<input type="text" class="form-control" id="IdAdvanceRequisition" name="IdAdvanceRequisition" required/>
</div>
</div>
<div class="row">
<div class="col-2">
NoRef
</div>
<div class="col-6">
<input type="text" class="form-control" id="NoRef" name="NoRef" required/>
</div>
</div>
<div class="row">
<div class="col-2">
NIK
</div>
<div class="col-6">
<input type="text" class="form-control" id="Nik" name="Nik" required/>
</div>
</div>
<input type="hidden" class="id" name="id" />
Back
<button type="submit" class="btn btn-primary btn-sm">Save</button>
</form>
router for the router on the frontend, why can I only use post and get? whereas to delete and update you have to use DELETE and PUT
const express = require('express');
const user = require('../controllers/user')
var cors = require('cors')
const router = express.Router();
router.get('/index', user.getUsers);
router.get('/add', user.getAdd);
router.post('/create',cors (), user.createUsers);
router.get('/detail/:id', user.readUsers);
router.post('/delete/:id', cors (), user.deleteUsers);
router.get('/edit/:id', user.detailUpdate);
router.post('/update/:id',cors (), user.updateUsers);
module.exports = router;
controllers for add
createUsers : async (req,res) => {
try {
const Backend = await getBackend();
const dataBackend = await Backend.json();
const user = {id: uuidv4(), IdAdvanceRequisition: req.body.IdAdvanceRequisition, NoRef: req.body.NoRef, Nik: req.body.Nik};
dataBackend.push({...user, id: uuidv4()});
fetch('http://localhost:8000/users', {
method: 'post',
body: JSON.stringify(user)
})
console.log(`Data with the id: ${user.id} added to the database!`);
res.redirect('/users/index');
} catch (error) {
res.send(`data error`);
}
}
Results
[{"id":"3cc4ed6e-5974-4661-ade7-ec448ac0e7e3"}]
Problem: I tried to send all data to the backend, but only the UUID was sent. How can I solve this problem

Use DELETE method on CRUD in SailsJS

I´m doing a CRUD app in Sails, but the delete method doesn´t works fine.
The Homepage.ejs view is a simple form:
<form action="/todo" method="post">
<input type="text" name="title">
<br><br>
<input type="text" name="description">
<br><br>
<button type="submit">Create</button>
</form>
<hr>
<ul>
<% _.each(todos, function(todo){ %>
<li style="<% if(!todo.done){ %>color: red;<% } %>"><b><%= todo.title %></b> - <%= todo.description %> </li>Detail
<form action="/todo/<%= todo.id %>" method="post">
<input type="hidden" name="_method" value="put">
<button type="submit">Completed</button>
</form>
<form action="/todo/<%= todo.id %>" method="post">
<input type="hidden" name="_method" value="delete">
<button type="submit">Delete</button>
</form>
<% }) %>
</ul>
`
The ToDoController of DELETE and findOne methods:
delete:function(req, res){
ToDo.destroy(req.param('id')).exec(function(err, todo){
if(err) return res.serverError();
return res.redirect('/');
});
},
findOne: function(req, res){
ToDo.find(req.param('id')).exec(function(err, todos){
if(err) return res.serverError();
return res.view('details', { id: req.param('id'), title: req.param('title'), description:req.param('description')});
});
}
The routes:
'/': 'ToDoController.index',
'POST /todo' : 'ToDoController.create',
'PUT /todo/:id': 'ToDoController.update',
'DELETE /todo/:id' : 'ToDoController.delete',
'GET /detail/:id': 'ToDoController.findOne'
And the details.ejs view:
<h1> ID task: <%= id %> </h1>
<h3>Title: <%= title %></h3>
<p> Task: <%= description %></p>
Any idea??
Try using your console to debug your application
delete:function(req, res){
console.log(req.param('id'));
ToDo.destroy(req.param('id')).exec(function(err, todo){
console.log(todo);
if(err) return res.serverError();
return res.redirect('/');
});
}
If you still have trouble, you should report what your console is outputting.

save answer with button radio using MEAN stack with MVC framework

i am setting a form with Mean Stack,
in form.html i have
<div ng-controller="InfoCtrl">
<form method="post" ng-submit="info()" name="infoForm">
<div class="radio">
<label>
<input type="radio" name="optionsRadios" id="Homme" value="Homme" checked>
Homme
</label>
</div>
<div class="radio">
<label>
<input type="radio" name="optionsRadios" id="Femme" value="Femme">
Femme
and in the controller info.js i have :
angular.module('MyApp')
.controller('InfoCtrl',[ '$scope', 'infor', function($scope, infor) {
$scope.info = function() {
infor.info({
age: $scope.age,
sexe: $scope.optionsRadios
});
};
}]);
another file infor.js, it only contains the error message after the set of the form, in the class server.js i have this function:
app.post('/infor/info', function(req, res, next) {
console.log('ok');
var query = {'email' : 'mail#mail.fr' };
var age1 = req.body.age;
console.log(req.body.optionsRadios);
User.findOneAndUpdate(query,{ age: age1 } , {upsert:true},function(err, doc){
if (err) return res.send(500, { error: err });
return res.send("succesfully saved");
});
});
but i didn't knew how to save the answer of the button radio in the query like i did in the set of new text. I have searched in many forms but it i didn't found an answer!

Resources