change link to logout when user login - node.js

I want to change login button to logout when ctx.session.userID have value, I try to use ejs engine, but it didn't work.
I use console.log to print userid after login, but it shows undefined on terminal even it being assigned value in login().
This is server.js:
const M = require('./model')
const Koa = require('koa')
var serve = require('koa-static')
const session = require('koa-session')
var KoaRouter = require('koa-router')
var koaLogger = require('koa-logger')
const koaBody = require('koa-body')
const views = require('koa-views')
var app = new Koa()
const router = new KoaRouter()
app.use(views('view', {map:{html:'ejs'}}))
app.use(koaLogger())
app.use(koaBody())
app.use(router.routes())
app.use(serve(__dirname + '/public'));
app.keys = ['*#&))9kdjafda;983']
const CONFIG = {
key: 'd**#&(_034k3q3&#^(!$!',
maxAge: 86400000
}
app.use(session(CONFIG, app))
router
.get('/', async (ctx) => {
let title = 'ejs test'
let userid = ctx.session.userID
console.log('ctx.session.userID:',userid) // print userid after login, but it shows undefined
await ctx.render('index',{
title, userid
})
})
.post('/login', login)
.get('/error', async (ctx)=> {
await ctx.render('error',{})
})
async function login(ctx){
let {id, password} = ctx.request.body
console.log("test:",id,password)
if ( await M.get(id,password) != null){
ctx.session.userID = id
ctx.redirect('/')
console.log('login success')
}
else {
ctx.redirect('/error')
}
}
And this is a part of index.html:
<% if (userid == null){ %>
Login
<% } else { %>
Logout
<% } %>

Hi If user is not logged in by default it will store undefined.
you need to check if user id is defined or not -
<% if (userid === undefined){ %>
Login
<% } else { %>
Logout
<% } %>
Hop this helps.

Related

I want to tell reactjs login component whether login was successful or not

I am confused as to how to communicate from the nodejs server to the reactjs login component on whether login was successful or not.
I have a reactjs component that handles login as follows:
Login.js
import React, {useState} from 'react';
import axios from "axios";
const Login = () => {
const [user,setUser] = useState({email:"",password:""});
const handleSubmit = (e) => {
e.preventDefault();
console.log(user);
axios.post('http://localhost:5000/login',user)
.then(function (response) {
console.log(response);
console.log("Successfully done");
})
.catch(function (error) {
console.log("error here")
console.log(error.message);
});
}
return (
<div>
<h1>Login</h1>
<form onSubmit={handleSubmit}>
<div>Email:</div>
<div><input type="text" name="email" placeholder='Enter your email'
onChange={(e)=>setUser({...user,email:e.target.value})}
/></div>
<div>Password:</div>
<div><input type="password" name="password" placeholder='Enter your password'
onChange={(e)=>setUser({...user,password:e.target.value})}
/></div>
<div><input type="submit" value="Add" /></div>
</form>
</div>
)
}
export default Login;
and an expressjs backed that processes the login
server.js
const express = require("express");
const mongoose = require("mongoose");
const User = require("./Models/Conn.js");
const bcrypt = require("bcryptjs");
//const Route1 = require("./Routes/Route.js");
const cors = require('cors');
const app = express();
//app.use("/api",Route1);
app.use(express.json({extended:true}));
app.use(express.urlencoded({extended:true}));
app.use(cors());
const url = "mongodb+srv://pekele:pekele#cluster0.yqaef.mongodb.net/myDatabase?retryWrites=true&w=majority";
mongoose.connect(url)
.then(()=>console.log("connected to database successfully"))
.catch(err=>console.log(err));
app.get("/",(req,res)=> {
res.send("<h1>Welcome Guest</h1>");
});
app.get("/signup",(req,res)=> {
res.json({"id":"1"});
})
app.post("/signup",(req,res)=> {
const {email,password} = req.body;
bcrypt.genSalt(10)
.then(salt=> {
bcrypt.hash(password,salt)
.then(hash => {
const user = new User({email,password:hash});
user.save()
.then(()=>console.log("Successfully saved"))
.catch(error=>console.log(error));
})
}).catch(err=>console.log(err));
})
app.post("/login",(req,res)=> {
const {email,password} = req.body;
console.log(`My email is ${email}`)
User.findOne({email:email}, function (err, doc) {
console.log(doc);
if(doc == null) {
//How do i let react login page know that there is no user with such email
}
if(doc != null) {
const emailDB = doc.email;
const passwordDB = doc.password;
bcrypt.compare(password,passwordDB)
.then(res => {
//How do I tell the react login page that the login was successful
}).catch(err=>console.log(err));
}
});
})
app.listen(5000,()=> console.log("Server listening on port 5000"));
The problem is how do I communicate to the react login page whether the login was successful or not in the app.post("/login",(req,res) ... Thanks
You can send data via -
res.json(data)
res.send("Submitted Successfully!")
res.status(200).send(message)

Can't seem to load Sqlite database on Electron JS app, but the same code shows database when I run it on localhost using Express

Now I am fairly very new to Electron JS and I just migrated my Plain JavaScript Game Project to Electron so that I could run it on a desktop application instead of a browser.
The front end code and game logics are all working well but for some reason it doesn't redirects me to the page where the sqlite data is to be presented.
Here is the server code for the game
const express = require("express");
const path = require("path");
const addUser = require("./database.js");
const { BrowserWindow, app } = require("electron");
require("electron-reloader")(module);
const createWindow = () => {
const mainWindow = new BrowserWindow({
width: 900,
height: 700,
webPreferences: {
webSecurity: false
}
}
);
mainWindow.loadFile("../public/index.html");
};
app.whenReady().then(createWindow);
const exp = express();
const PORT = 8000;
const staticPath = path.join(__dirname, "../public");
exp.use(express.static(staticPath));
exp.use(express.json());
exp.use(express.urlencoded());
exp.get("/", (req, res) => {
res.sendFile(staticPath + "/index.html");
});
function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
exp.post("/leaderboard", (req, res) => {
var _username = req.body.username;
var _score = req.body.score;
addUser(_username, _score);
sleep(2000).then(() => {
res.sendFile(dbPath);
})
});
exp.listen(PORT, (req, res) => {
console.log(`Server running on http://localhost:${PORT}/`);
});
When I run this code on localhost in my browser it seems to be working well and shows me the game highscores as defined and updated
I will also provide the database code and the required html part but I dont know if they are needed for the issue
const sqlite3 = require("sqlite3").verbose();
var db = new sqlite3.Database("./scores.db");
const { Console } = require("console");
const fs = require("fs");
var _isExist = false;
// db.run(`CREATE TABLE users (username TEXT, score INT)`);
const addUser = (_username, _score) => {
var myLogger = new Console({
stdout: fs.createWriteStream("./public/scores.txt"),
});
db.get(
`SELECT username FROM users WHERE username = "${_username}"`,
(err, row) => {
if (err) {
return myLogger.log(err.message);
}
if (row !== undefined) {
_isExist = !_isExist;
return myLogger.log(`Username Already Taken`);
} else {
var stmt = db.prepare(`INSERT INTO users VALUES(?, ?)`);
stmt.run(_username, _score);
stmt.finalize();
var i=0;
db.each(
`SELECT username, score FROM users ORDER BY score DESC`,
(err, row) => {
if (err) {
return myLogger.log(err.message);
}
i = i+1;
return myLogger.log(`${i}: Username: ${row.username}, Score: ${row.score}`);
}
);
}
}
);
};
module.exports = addUser;
<div class="form-control pull-right">
<form class="login-form" action="/leaderboard" method="POST">
<h3>
<b
>Scores</b
>
</h3>
<input
type="text"
name="username"
id="username"
placeholder="Enter Your Username"
required
/> <br>
<input
type="text"
name="score"
id="score"
placeholder="Score"
value="Fetched Automatically"
required
/> <br>
<button type="submit" id="btn-submit">Check Leaderboard</button>
</form>
</div>

UnhandledPromiseRejectionWarning: validation_error: Invalid Vehicle ID. Ensure the Vehicle ID matches an ID returned by the /vehicles endpoint

This Is vehicle endpoint
app.get('/vehicles', function(req, res, next) {
const {access, vehicles} = req.session;
if (!access) {
return res.redirect('/');
}
const {accessToken} = access;
smartcar.getVehicleIds(accessToken)
.then(function(data) {
const vehicleIds = data.vehicles;
const vehiclePromises = vehicleIds.map(vehicleId => {
const vehicle = new smartcar.Vehicle(vehicleId, accessToken);
req.session.vehicles[vehicleId] = {
id: vehicleId,
};
return vehicle.info();
});
return Promise.all(vehiclePromises)
.then(function(data) {
// Add vehicle info to vehicle objects
_.forEach(data, vehicle => {
const {id: vehicleId} = vehicle;
req.session.vehicles[vehicleId] = vehicle;
});
res.render('vehicles', {vehicles: req.session.vehicles});
})
.catch(function(err) {
const message = err.message || 'Failed to get vehicle info.';
const action = 'fetching vehicle info';
return redirectToError(res, message, action);
});
});
});
This request is coming smoothly with data
app.post('/request', function(req, res,next) {
const {access, vehicles} = req.session;
if (!access) {
return res.redirect('/');
}
const {vehicleId, requestType: type} = req.body;
const vehicle = vehicles[vehicleId];
const instance = new smartcar.Vehicle(vehicleId, access.accessToken);
const saveRequest = async() => {
const info = await instance.info();
const loc = await instance.location();
const odometer = await instance.odometer()
const battery = await instance.battery()
return{
info:info,
location:loc,
odometer:odometer,
battery: battery,
}
}
saveRequest()
.then(data => {
console.log(data)
return res.render('dash' ,{data})
})
})
Now what i want is when checkbox is clicked it will return static text and car will be locked
So i render the data on same hbs file as on /request and when i press the check box data will be render on same page dash.hbs with additional request its bit complicated for me and when i am trying to get to the /lock end point i am getting this error (node:15772) UnhandledPromiseRejectionWarning: validation_error: Invalid Vehicle ID. Ensure the Vehicle ID matches an ID returned by the /vehicles endpoint.
app.post('/lock', async (req, res,next) => {
const {access, vehicles} = req.session;
if (!access) {
return res.redirect('/');
}
const {vehicleId, requestType: type} = req.body;
const vehicle = vehicles[vehicleId];
const instance = new smartcar.Vehicle(vehicleId, access.accessToken);
const saveRequest = async() => {
const info = await instance.info();
const loc = await instance.location();
const odometer = await instance.odometer()
const battery = await instance.battery()
const lock = await instance.lock()
return{
info:info,
location:loc,
odometer:odometer,
battery: battery,
}
}
saveRequest()
.then(data => {
console.log(data)
return res.render('dash' ,{data})
})
})
Form submitting from here
<form action="/lock" method="post">
<select class="form-control" id="vehicle" name="vehicleId">
{{#each vehicles}}
<option value="{{id}}">{{year}} {{make}} {{model}}</option>
{{/each}}
</select>
<input id="bubble" name="vehicleId" type="submit" name="btn"/></form>

React Socket NodeJs SocketManager not pulling through

Stuck in a problem, unable to understand why it is not working.
Everything seems okay.
Please advice.
This is Server.js
var app = module.exports.ie=require('http').createServer()
var io = require('socket.io')(app)
const PORT = process.env.PORT || 3231
const socketManager = require('./socketManager')
io.on('connection', socketManager)
app.listen(PORT, () =>
console.log(`Connected to Port ${PORT}`)
)
Below is the my Layout file which holds the main render.
import React, {Component} from 'react';
import io from 'socket.io-client';
import { USER_CONNECTED, LOGOUT } from './ConstEvents';
import ChatNameForm from './ChatNameForm';
const socketUrl = "http://localhost:3231"
export default class chatPane extends Component{
constructor(props){
super(props);
this.state ={
socket:null,
user: null
};
}
componentDidMount(){
this.initSocket()
}
/*
*
* Connect to 'socketUrl' and initialise the socket.
*
*/
initSocket =() =>{
const socket = io(socketUrl)
socket.on('connect', () =>{
console.log("Connected");
})
this.setState({socket})
}
/*
* Sets the user property in state
* #Param user {id:number, name:string}
*/
setUser = (user) =>{
const { socket } = this.state
socket.emit(USER_CONNECTED, user);
this.setState({user})
}
/**
* Sets the user property in state to Null.
*
*/
logout = () => {
const { socket } = this.state
socket.emit(LOGOUT);
this.setState({user:null})
}
render(){
const { socket } = this.state
return(
<div>
<ChatNameForm socket={socket} setUser={this.setUser} />
</div>
);
}
}
Below is the UserName form. No Passwords only setting up the user name here.
import React, {Component} from 'react';
import VERIFY_USER from './ConstEvents';
export default class ChatNameForm extends Component {
constructor(props){
super(props);
this.state = {
userChatName:"",
error:""
};
}
setUser = ({user, isUser}) => {
console.log(user, isUser);
if(isUser){
this.setError("User name Taken")
}
else {
this.props.setUser(user)
this.setError("")
}
}
handleSubmit = (e) => {
e.preventDefault()
const { socket } = this.props
const {userChatName} = this.state
socket.emit (VERIFY_USER, userChatName, this.setUser)
}
handleChange = (e) => {
this.setState({userChatName:e.target.value})
}
setError = (error) => {
this.setState({error})
}
render() {
const {userChatName, error} = this.state
return (
<div className='login'>
<form onSubmit = {this.handleSubmit} >
<label htmlFor= "userChatName">
<h2>Enter User Chat Name</h2>
</label>
<input
ref = {(input) => { this.textinput = input}}
type = "text"
id ="userChatName"
value = {userChatName}
onChange={this.handleChange}
placeholder={'userChatName'}
/>
<input type="submit" value= "ok" />
<div className= "error">
{error ? error:null}
</div>
</form>
</div>
)
}
}
And lastly My SocketManager..
const io = require('./Server.js').io
const { VERIFY_USER, USER_CONNECTED, LOGOUT } = require('../ConstEvents');
const { createUser, createMessage, createChat} = require('../ChatFunctions');
let connectedUsers = { }
module.exports = function(socket){
console.log(`Socket Id = ${socket.id}`)
// verify chatName
socket.on(VERIFY_USER, (userChatName, callback) => {
if (isUser (connectedUsers, userChatName)) {
callback ({ isUser:true, user:null })
} else{
callback ({ isUser:false, user:createUser({name:userChatName})})
}
})
//User connects with userName
socket.on(USER_CONNECTED, (user) => {
connectedUsers= addUser(connectedUsers, user)
socket.user = user
io.emit(USER_CONNECTED, connectedUsers)
})
}
function addUser (userList, user){
let newList = Object.assign({}, userList)
newList[user.name] = user
return newList
}
function removeUser(userList, username){
let newList = Object.assign({}, userList)
delete newList[username]
return newList
}
function isUser(userList, userChatName){
return userChatName in userList
}
Issue; I can get the socket working fine. Value from Form fine however I this values are not being pushed over to socketManager. I have done some tests in Form Js to see if the handleSubmit is working or not.. I can see socket, userChatName and socket.emit is working fine. however when I go to socket manager and look into the triggered Event in this case VERIFY_USER... I don't see any results after that. tried testing it but not sure how too get its value out on console to test. If you can help me out plz. Thank you.

Set object in SequelizeJS function

I'd like to get all my projects in the findAll() function of SequelizeJS but it seem's not working outside the function...
var myProjects;
Project.findAll().then(function(projects) {
myProjects = projects;
});
console.log(myProjects); // it doesn't work
EDIT #2
I'm trying to create an object containing all my links that I can get on each views without calling findAll() on each actions... projects was an example, but the real context is on my link's model !
var dbContext = require('./../../db/DbContext');
var _ = require('lodash');
var LinkDao = function () {
this.context = dbContext.entities;
};
_.extend(LinkDao.prototype, {
getAllByOrder: function (callback) {
return this.context.Link.findAll({order: 'position ASC', include: [{ model: this.context.Link}], where: {type: [0,1]}});
},
});
module.exports = LinkDao;
exports.locals = function(app){
app.use(function(request, response, next){
var linkDao = new LinkDao();
linkDao.getAllByOrder().success( function(links){
response.locals.navLinks = links;
});
var ecCategoryDao = new EcCategoryDao();
ecCategoryDao.getAll().success( function(ecCategories) {
response.locals.ecCategories = ecCategories;
next(); // navLinks is not accessible
});
});
};
<% navLinks.forEach(function(link){ %>
<% if(link.type === 0) { %>
<li><%-link.name%></li>
<li class="top-bar-divider"></li>
<% } else { %>
<li><%-link.name%></li>
<li class="top-bar-divider"></li>
<% } %>
<% }); %>

Resources