This aws lambda function is supposed to add a user to an rds database and generate a jwt token with the user info as payload. Please it doesnt seem to work. Can someone check it out and help. I am frustrated already.
the index.js file
const{conn}= require('./config');
const {createUser} = require('./controller')
exports.handler = async event =>{
createUser(event)
}
the config file
const mysql = require('mysql');
const jwt = require('jsonwebtoken');
const conn = mysql.createConnection({
host: host'',
port: 'port',
user: 'user',
password: 'assword',
database: 'database'
});
conn.connect(function(err){
if(err){
throw err
};
console.log('connected to dbb');
})
const secret ='secret';
const generateToken = user =>{
const payload = {user: user};
const options = {expiresIn: '1h'};
return jwt.sign(payload, secret, options);
}
const verifyToken = (token)=>{
try{
const decoded = jwt.verify(token, secret)
return {success: true, data: decoded};
}catch(error){
return{success: false, error: error.message}
}
}
const authenticate = (req)=>{
const authHeader = req.headers['authorization'];
const token = authHeader && authHeader.split(' ')[1];
if(!token){
return JSON.stringify(401)
}
const result = verifyToken(token);
if(!result.success){
return JSON.stringify(403).json({error: result.error})
}
return result.data;
}
module.exports = {conn, authenticate, verifyToken, generateToken};
the controllers
const bcrypt = require('bcryptjs');
const {conn} = require('./config')
const { generateToken} = require('./config');
const {sendEmail} = require('./emailservice');
const findByUsername = async (name) => {
const query = "SELECT * FROM users WHERE username = ?"
return new Promise((res, rej) => {
conn.query(
query,
[name],
(error, results) => {
if (error) {
rej(error);
throw error;
}
res(results.length);
}
);
});
};
const createUser = async (body) => {
const check = await findByUsername(event.body.username)
if (check == 0 ) {
const salt = await bcrypt.genSalt(10);
const hash = await bcrypt.hash(event.body.password, salt);
const sql = "INSERT INTO users (firstName, lastName, email, phone, password, username) VALUES (?,?,?,?,?,?)"
const {first_name, last_name, email, phone, username} = event.body;
conn.query(
sql, [first_name,
last_name,
email,
phone,
hash,
username],
async (error, results) => {
if (error) {
return JSON.stringify({
status: false,
message: 'Failed to create, an error occured',
data: {error},
code: 409
})
}
const user = {
status: true,
message: 'successfully created',
data: {first_name,
last_name,
phone,
hash,
email,
username},
code: 201
}
return JSON.stringify(generateToken(user));
}
);
conn.end();
}else{
conn.end();
return JSON.stringify({
status: false,
message: 'email already taken. Please login',
data: {message: 'user with email already exists'},
code: 409
})
}
};
module.exports = {createUser, findByUsername}
All packages are included in the package.json file. Thank you in advance
Also look to add logging to your lambda function to grab any errors and outputs to cloudwatch.
Thanks bro. I had to set up a lambda connection from the tutorials in the link. ALso do i have to do this for each lambda that wants to acess the db please. and is this the most secure way as far as security is concerned?
Glad you figured out and got it working. Yes, to access resources that are only accessible from within VPC, yes lambda function needs to be configured this way. I'm throwing one more AWS documentation Networking and VPC configurations for AWS Lambda your way, which exactly talks about this.