Hello I want to implement database to the node project I'm working on. On testing the authentication endpoint I getting the error "message": { "length": 164, "name": "error", "severity": "ERROR", "code": "22001", "file": "d:\\pginstaller_13.auto\\postgres.windows-x64\\src\\backend\\utils\\adt\\varchar.c", "line": "635", "routine": "varchar" } via postman
I am not certain I did my database set up correctly, any advice on how to set up postgresql environment properly such that I can deploy to Heroku and please how can I resolve the error ?
Auth.js
const bcrypt = require('bcrypt')
const pool = require('../configuration/config');
const validate = require('../middleware/auth.validation')
const signup = async (request, response)=>{
try {
//1. destructure req.body
const {firstname, lastname, username, email, password} = request.body;
//2. validate user input
const validationError = validate.signup(firstname,lastname,username, email, password)
if(validationError.message){
return response.status(400).json({status:'Validation Error', message: validationError.message})
}
//3. check if user exist (if user exist , throw err)
const userExist = await pool.query(`SELECT * FROM users WHERE username = $1`, [username]);
if(userExist.rows.length !== 0){
return response.status(401).json({message: "User Already Exist"})
}
// 4. hash user password
const salt = await bcrypt.genSalt(10)
const hashPassword = await bcrypt.hash(password, salt)
//5. Insert user into db
const newUser = await pool.query('INSERT INTO users (firstname, lastname, username, email, password) VALUES($1, $2, $3, $4, $5) RETURNING *', [firstname, lastname, username,email, hashPassword]);
response.json(newUser)
// 6. generate jwt token
} catch (error) {
response.status(500).send({message:error})
}
}
module.exports = {signup}
config.js
require('dotenv').config()
const { Pool } = require('pg')
const pool = new Pool({
user: process.env.DB_USER,
host: process.env.DB_HOST,
database: process.env.DB_DATABASE,
password: process.env.DATABASE_PASSWORD,
port: process.env.DB_PORT,
})
pool.on('connect', ()=>{
console.log('connected to database')
})
module.exports = pool
pool.js database Schema
require('dotenv').config()
const { Pool } = require('pg')
const pool = new Pool({
user: process.env.DB_USER,
host: process.env.DB_HOST,
database: process.env.DB_DATABASE,
password: process.env.DATABASE_PASSWORD,
port: process.env.DB_PORT,
})
pool.on('connect', ()=>{
console.log('connected to database')
})
module.exports = pool
queries.js
const pool = require('./pool')
module.exports = {
/**
* DB Query
* #param {object} req
* #param {object} res
* #returns {object} object
*/
query(quertText, params) {
return new Promise((resolve, reject) => {
pool.query(quertText, params)
.then((res) => {
resolve(res);
})
.catch((err) => {
reject(err);
});
});
},
};
It's weird that it gives you the exact source code line in the postgres source code but not the actual error message... Looking at line 635 of src/backend/utils/adt/varchar.c gives:
ereport(ERROR,
(errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
errmsg("value too long for type character varying(%d)",
maxlen)));
So, yeah, the column was probably declared as VARCHAR(N) and the string you're trying to put in the column has more than N characters, so it throws an error.
Related
So I am making a post api for registration/signup. If a user is successfully been registered, an access token will be provided to the user for saving it in frontend.
Everything works, the username, password is saving in database along with the token. But the access token is not returning. I have used mongoDB as my database and used mongoose. Here what I have done so far:
Edited code
const UserModel = require("../models/userModel");
var bcrypt = require("bcryptjs");
const jwt = require("jsonwebtoken");
const registration = async (req, res) => {
try {
const { email, password } = req.body;
if (!(email && password)) {
res.status(400).send("All input is required");
}
const existingEmail = await UserModel.find({ email: email });
if (existingEmail.length === 0) {
const userToken = jwt.sign({ email: email }, process.env.SECRET, {
expiresIn: "90d",
});
let hashedPassword = await bcrypt.hash(password, 8);
const user = await UserModel.create({
email,
password: hashedPassword,
token: userToken,
});
await userRegistration.save(function (err, result) {
if (err) {
console.error(err);
} else {
console.log(result);
}
});
res.json(userToken);
} else {
res.json("email has already been registered");
}
} catch (err) {
res.json(err);
}
};
module.exports = registration;
if I test the api in thunder client on vscode, it is returning {}, an empty object. Please tell me what I have done wrong?
const existingEmail = await UserModel.find({ email }); This line of yours will provide you the array of all the users because email property has nothing, it will be just like .find({})
If you are checking if the email inserted by user is already in your database or not, I suggest you do it like this: const existingEmail = await UserModel.find({ email : email});
This will return the document with email property's value equal to the email you received in req.body i.e. email : xyz#gmail.com
And In this line const userToken = jwt.sign({ email }, process.env.SECRET, {expiresIn: "90d",});
You are again making same mistake. The object you pass in payload, has email property, but no value/email is assigned to that property.
It's just like email : undefined
Here, do it like this jwt.sign({email : email}, process.env.SECRET, {expiresIn: '90d')})
So, I made a simple mistake in the code. I was trying to save userRegistration which was not defined. That's why the bug was occurring. I should be more careful about this.
Apart from what has been mentioned in the other answers, to me it looks like you are not giving the token to res.json anywhere.
Your function is returning the token, but I dont think its going anywhere. You need to pass the token to res.json, not return from the function.
You are using await as well as .then() which looks wrong to me. You have to use just one of them.
Update:
jwt.sign returns a string so userToken contains string. You are giving that string to res.json which is expecting a json. You need to pass an object to it.
Kindly try the below mentioned code.
const UserModel = require("../models/userModel");
var bcrypt = require("bcryptjs");
const jwt = require("jsonwebtoken");
const registration = async (req, res) => {
try {
const { email, password } = req.body;
if (!(email && password)) {
res.status(400).send("All input is required");
}
const existingEmail = await UserModel.find({ email });
if (existingEmail.length === 0) {
const userToken = jwt.sign({ email }, process.env.SECRET, {
expiresIn: "90d",
});
let hashedPassword = await bcrypt.hash(password, 8);
const user = await UserModel.create({
email,
password: hashedPassword,
token: userToken,
});
const userRegistrationResponse = await userRegistration.save();
const responseObj = {
...userRegistrationResponse,
accesstoken: `${userToken}`
};
res.json(responseObj);
} else {
res.json("email has already been registered");
}
} catch (err) {
res.json(err);
}
};
module.exports = registration;
I have a auth.js file And a middleware named as fetchuser code given beolow
Can anyone please tell me why am i getting this error.
I am using express js and mongoose but this error is occured during sending token to the user and verify the user whether is user logged in or not.
auth.js
const express = require('express');
const User = require('../models/User');
const router = express.Router();
const { body, validationResult } = require('express-validator');
const bcrypt = require('bcryptjs'); // it is used for password hashing
const jwt = require('jsonwebtoken');
const fetchuser=require('../middleware/fetchuser');
// Route:1 - Create a User using :POST. "/api/auth/createuser". NO Login Required.
router.post('/createuser', [
body('email', 'Enter valid email').isEmail(),
body('name', 'Enter valid email').isLength({ min: 3 }),
body('password').isLength({ min: 5 })
], async (req, res) => {
// Check fo vaidation whether is any rule(defined in User model) breaked or not
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
// Check Whether user with same email id exist or not
try {
let user = await User.findOne({ email: req.body.email });
if (user) {
return res.status(400).json({ error: "Sorry user with same email id already exist" });
}
// hashing of password
const salt = await bcrypt.genSalt(10);
const securePassword = await bcrypt.hash(req.body.password, salt);
// create A new User
user = await User.create({
name: req.body.name,
email: req.body.email,
password: securePassword
})
// returning user id in Token
const JWT_secret = "Rishiisa#boy";
const data = { user:{id: user.id} };
const auth_token = jwt.sign(data, JWT_secret);
res.json({ auth_token });
}
catch (error) {
console.error(error.message);
res.status(500).send("Internal server error");
}
})
// Route:2 - Login a User using credential. "/api/auth/login". NO Login Required.
router.post('/login', [
body('email', 'Enter valid email').isEmail(),
body('password', 'password can not be blank').exists(),
], async (req, res) => {
// Check for vaidation according to the rule defined at line no. 53, 54;
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
// destructure the email and password from body request
const { email, password } = req.body;
try {
// Checking whether email is exist or not
let user = await User.findOne({ email });
if (!user) {
return res.status(400).json({ error: "Please try to login using correct credentials" });
}
// Now Comparing password with help of bcryptjs
const comparepassword = await bcrypt.compare(password, user.password);
if (!comparepassword) {
return res.status(400).json({ error: "Please try to login using correct credentials" });
}
// Now if user enter coorect password and login then user got logged in;
// And We will send authtoken to user;
// returning user id in Token
const JWT_secret = "Rishiisa#boy";
const data = { user:{id: user.id} };
const auth_token = jwt.sign(data, JWT_secret);
res.json({ auth_token });
}
catch (error) {
console.error(error.message);
res.status(500).send("Internal server error");
}
})
// Route:3 - Get Loggedin User details using:POST "/api/auth/getuser" Login required
router.post('/getuser', fetchuser, async (req, res) => {
try {
const userid = req.user.id;
const user = await User.findById(userid).select("-password");
res.send(user);
} catch (error) {
console.error(error.message);
res.status(500).send("Internal server error");
}
})
module.exports = router
middleware:
fetchuser.js
const jwt = require('jsonwebtoken');
const JWT_secret = "Rishiisa#boy";
const fetchuser = (req, res, next) => {
// Get the user from jwt token and add user id to req object
const token = req.header('auth_token');
if (!token) {
res.status(401).send({ error: "Please authenticate using a valid token" });
}
try {
const data = jwt.verify(token, JWT_secret);
req.user = data.user;
next();
} catch (error) {
res.status(401).send({ error: "Please authenticate using a valid token" });
}
}
module.exports = fetchuser;
In auth.js, where you wrote: "const data = { user:{id: user.id} };" Try changing user.id to user._id, since in MongoDB the user id is referred to as '_id'.
Let me know if that works.
I've had problems sending jwt token back and even verifying it, but all is good on my side now.
Also, below is my (inspired) method of going about this:
router.post('/register', (req, res)=>{
const { username, password } = req.body;
const user = new User({
username,
password
});
bcrypt.genSalt(10, (err, salt)=>{
bcrypt.hash(user.password, salt, (err, hash)=>{
if(err) throw err;
user.password = hash;
user.save()
.then(user=>{
jwt.sign(
{ id: user._id },
process.env.jwtSecret,
{ expiresIn: 3600 },
(err, token) =>{
if(err) throw err;
res.status(200)
}
)
})
})
})
})
I keep getting this MongoDB error, this is my connection to mongodb. I am trying to make a register and login application
const { MongoClient } = require('mongodb');
const uri = "mongodbconnection";
const client = new MongoClient(uri, { useNewUrlParser: true, useUnifiedTopology: true });
client.connect(error => {
const collection = client.db("test").collection("devices");
// perform actions on the collection object
client.close();
});
this is the signup application
router.post('/register', async (req, res) => {
//hashing the password
const hashedPwd = await bcrypt.hash(req.body.password, saltRounds);
//using passport-local for authentication
const newUser = new User({
email: req.body.email,
password: hashedPwd
})
try {
await newUser.save()
console.log("new user created")
} catch (error) {
if (error) {
console.log(error)
}
}
})
Im learning from a ready application and im trying to make the connection so the app to start working and save data.
picture of the hostname and port
I done the connectin also make a 'employees database' with the two tables that I need
picture of the schema
The server is running on localhost 3000 and the front end is listening on port 4200. This is the code for the connection and creating the database/schema.
config.json
{
"host": "localhost",
"user": "cveto",
"database": "employees",
"password": "1234567"
}
database.js creating pool
const mysql = require('mysql2');
const config = require('../config/config.json');
const pool = mysql.createPool({
host: config.host,
user: config.user,
database: config.database,
password: config.password,
});
module.exports = pool.promise();
And some query models
const db = require('../util/database');
module.exports = class Employee {
constructor(names, address, number, salary) {
this.names = names;
this.address = address;
this.number = number;
this.salary = salary;
}
static fetchAll() {
return db.execute('SELECT * FROM employees');
}
static save(employee) {
return db.execute(
'INSERT INTO employees (names, address, number, salary) VALUES (?, ?, ?, ?)',
[employee.names, employee.address, employee.number, employee.salary]
);
}
static delete(id) {
return db.execute('DELETE FROM employees WHERE id = ?', [id]);
}
};
I just want to know how I can make the connection so the app to work and save to my database the users and new employees. The code is from public repositority so the code is working, its now from the code its from tha database or server conncetion.
DB.js File
var mysql = require('mysql');
const pool = mysql.createPool({
connectionLimit: 100,
host : 'localhost',
user : 'root',
password : '',
database : '',
});
let myDb = {};
myDb.searchDataQ = (query) => {
return new Promise((resolve, reject) => {
pool.query(query, function (err, rows) {
if (err) {
reject(err);
}
resolve(rows)
})
});
};
module.exports = myDb;
Other JS File to execute
const db = require('../db/db');
function testMethod() {
let query = 'SELECT * FROM employees';
return new Promise(async (resolve, reject) => {
try {
resolve(await db.searchDataQ(query));
} catch (e) {
reject(0);
}
});
}
I have the following code written. I am not sure if it works but basically am trying to create a function that inserts a new todo with a description unless that description is bad todo. Obviously this is just for testing but I want to call this function I created in my express app.
BEGIN;
CREATE OR REPLACE FUNCTION perntodo.createTodo(
description perntodo.todoDescription%Type)
RETURNS VARCHAR AS
$$
DECLARE
BEGIN
IF description == 'bad todo' THEN
RAISE EXCEPTION 'Cannot post this todo!';
ELSE
INSERT INTO TODO VALUES(description);
END IF;
END;
COMMIT;
My controller looks like this...
router.post('/', async (req, res) => {
try {
const { description } = req.body;
// const newTodo = await pool.query(
// 'INSERT INTO todo (description) VALUES($1) RETURNING *',
// [description]
// );
const newTodo = await pool.func('perntodo.createTodo', [description]);
res.json(newTodo.rows[0]);
} catch (err) {
console.error(err.message);
res.status(500).send('Server Error...');
}
});
The commented out code works. But the pool.func says it's not a function. What am I doing wrong.
This is how I connected to my database
const Pool = require('pg').Pool;
const user = './user';
const DBPASSWORD = './pass';
const pool = new Pool({
user: user,
password: DBPASSWORD,
host: 'localhost',
port: 5432,
database: 'perntodo',
});
module.exports = pool;