User pool does not exist: AWS adminConfirmSignUp - javascript

For some reason, only the adminConfirmSignUp gives this error. Authentication using CognitoUser doesn't give this error. Both of them are configured to the same user pool and region.
Below is the code for authentication using cognitoUser, which is working:
public async login(req: UserLoginRequest): Promise<object> {
return new Promise<any>(async (resolve, reject) => {
console.log(`This is the req password-----> ${req.password}`)
try {
var authenticationDetails = new AmazonCognitoIdentity.AuthenticationDetails({
Username: req.emailAddress,
Password: req.password
});
var userData = {
Username: req.emailAddress,
Pool: this.userPool
};
this.cognitoUser = new AmazonCognitoIdentity.CognitoUser(userData);
await this.authenticateUser(this.cognitoUser, authenticationDetails).then(value=> {
resolve(value)
}).catch(error => {
console.log(`This is the login error catch----> ${JSON.stringify(error)}`)
});
} catch (error) {
console.log(`I entered into catch .......${JSON.stringify(error)}`)
reject(error);
}
});
}
private async authenticateUser(cognitoUser: AmazonCognitoIdentity.CognitoUser, authenticationDetails: AmazonCognitoIdentity.AuthenticationDetails) {
console.log(`Inside authenticate user`);
console.log(`This is the cognitoUser -----> ${JSON.stringify(cognitoUser)} and these are the authentication details-----> ${JSON.stringify(authenticationDetails)}`)
try{
return new Promise<any>(async (resolve, reject) => {
await cognitoUser.authenticateUser(authenticationDetails, {
onSuccess: (result) => {
console.log(`This is the success result ----> ${JSON.stringify(result)}`);
resolve(result)
},
onFailure: (error) => {
console.log(`This is the error being returned in onFailure ----> ${JSON.stringify(error)}`)
resolve(error)
}
})
})
}
catch(error){
rejects(error);
}
}
The confirm user, which uses AWS.CognitoIdentityServiceProvider doesn't work. Gives out an error user pool doesn't exist:
private async confirmUser(resetDetails: ResetPassword, cognitoAdmin: AWS.CognitoIdentityServiceProvider) {
console.log(`This is the admin config cognito ----> ${JSON.stringify(cognitoAdmin)}`)
return new Promise<any>(async (resolve,reject)=>{
console.log(`Inside confirm`);
const confirmParams = {
UserPoolId: process.env.COGNITO_USER_POOL_ID!,
Username: resetDetails.emailAddress!
}
console.log(`This is the user pool ID -----> ${confirmParams.UserPoolId} and this is the region----> ${cognitoAdmin.config.region}`);
await cognitoAdmin.adminConfirmSignUp(confirmParams, async (err, data) => {
if (err) {
console.log(`This is the admin user confirm error ---> ${err}`)
reject(err);
}
else {
cognitoAdmin.adminUpdateUserAttributes({
UserAttributes: [{
Name: 'email_verified',
Value: 'true'
}],
UserPoolId: process.env.COGNITO_USER_POOL_ID!,
Username: resetDetails.emailAddress!
}, (err, data) => {
if (err) {
reject(err)
}
else {
resolve(data)
}
}
)
}
})
})
}
This is the cognitoAdmin argument details sent to the cognitoAdmin parameter of the above confirmUser method:
var cognitoAdmin = new AWS.CognitoIdentityServiceProvider({ region: process.env.COGNITO_POOL_REGION!});

Related

Lambda inconstant when querying my RDS database

When I go to test my code, the lambda does nothing, and at other times it runs my query and returns the data I have queried for. It's very inconsistent. It doesn't even give me an error. I am also using a proxy and that's not showing any errors. That's also not triggering.
I suspect it's something to do with the await/ async...
Here is my code:
async function RDSToken() {
vr signer = new AWS.RDS.Signer({
region: 'us-east-1',
hostname: 'proxy',
port: 3306,
username: 'username'
});
var host ='proxy'
var user ='username'
var db ='name'
let token = signer.getAuthToken({username: 'admin' });
let connectionConfig = {
host: host,
user: user,
database: db,
ssl: { rejectUnauthorized: false},
password: token,
authSwitchHandler: function ({pluginName, pluginData}, cb) {
console.log("Setting new auth handler.");
}
};
connectionConfig.authSwitchHandler = (data, cb) => {
if (data.pluginName === 'mysql_clear_password') {
let password = token + '\0';
let buffer = Buffer.from(password);
cb(null, password);
}};
try {
connection = await mysql2.createConnection(connectionConfig);
} catch(err) {
console.error('error connecting to the database');
console.error(err);
var response = {
statusCode: 500,
"headers": {
"Content-Type": "application/json"
},
body: 'error connecting to the database' +err
};
return response;
}
return connection
}
async function randomfact() {
var connection = await RDSToken();
let sql = 'SELECT * FROM quote_header;';
return await new Promise((resolve, reject) => {
connection.query(sql, (err, result) => {
if (err) {
reject(err);
}
else {
resolve(result);
}
});
});
}
async function Dashboard() {
const result = await randomfact();
console.log(result)
}
So I was correct there is something to do await/asnyc/promise.
Here is my updated code.
const connection = mysql2.createPool({
host: "host",
user: "admin",
password: "pw",
database : 'name',
waitForConnections: true,
connectionLimit: 3,
})
SelectAllElements = (connection) =>{
return new Promise((resolve, reject)=>{
connection.query('SELECT * FROM quote_header ', (error, elements)=>{
if(error){
return reject(error);
}
return resolve(elements);
});
});
};
async function Dashboard() {
try{
const result1 = await SelectAllElements(connection);
console.log(result1)
// here you can do something with the three results
} catch(error){
console.log(error)
}
}
But this works around 95% of the time. It doesn't like to work the first time I run the lambda but after then it works for a short time, then returns null again, then works again. I still dont understand what's causing it not to connect.

my homepage wont render using my google oauth

This is the error that I get:
"You have created a new client application that use…i/web/guides/gis-migration) for more information."
here are my codes on server, the statement inside console.log doesnt even show:
static async googleLogin(req, res, next) {
try {
console.log("masuk google login server")
const { id_token } = req.body
const client = new OAuth2Client(process.env.GOOGLE_CLIENT_ID)
const ticket = await client.verifyIdToken({
idToken: id_token,
audience: process.env.GOOGLE_CLIENT_ID
});
const payload = ticket.getPayload()
const email = payload.email
let password = email.toString().split('#')
password = password[0]
let user = await User.findOne({ where: { email } })
if (!user) {
let newUser = { email, password }
let createUser = await User.create(newUser)
const payload = {
id: createUser.id,
email: createUser.email
}
const access_token = generateToken(payload)
return res.status(201).json({ access_token })
} else {
const payload = {
id: user.id,
email: user.email
}
const access_token = generateToken(payload)
return res.status(200).json({ access_token })
}
} catch (err) {
console.log(err)
return next(err)
}
}
the console.log in my client also doesnt show
function onSignIn(googleUser) {
console.log("masuk client oauth")
$.ajax({
method: "POST",
url: `${baseUrl}/users/google-login`,
data: {
id_token: googleUser.getAuthResponse().id_token
}
})
.done((response) => {
console.log(response, "client response")
localStorage.setItem("access_token", response.access_token)
checkLocalStorage();
})
.fail((err) => {
console.log(err, "error client");
})
.always(() => {
authentication()
})
}
i tried deleting cache and run my app again, recreate a new project on google api (which genereated new ID). they didnt work

cannot send ejs file through nodemailer

it shows this error
The "chunk" argument must be of type string or an instance of Buffer or Uint8Array. Received an instance of Promise
const transporter = nodemailer.createTransport({
service: "gmail",
auth:{
user:process.env.email,
pass: process.env.password
}
})
const mailOptions = {
from:process.env.email,
to : req.user.username,
subject:"Test",
html: ejs.renderFile(path.join(__dirname,'views/home.ejs'))
}
transporter.sendMail(mailOptions,function(err,info){
if(err){
console.log("err");
}
else{
console.log("sent" +info.response);
}
})
ejs.renderFile is asynchronous, use a callback to fetch the rendered HTML
const transporter = nodemailer.createTransport({
service: "gmail",
auth: {
user: process.env.email,
pass: process.env.password
}
})
const mailOptions = {
from: process.env.email,
to: req.user.username,
subject: "Test"
}
ejs.renderFile(path.join(__dirname, 'views/home.ejs'), { name: name }, (err, data) => {
if (err) {
console.log(err);
} else {
mailOptions.html = data
transporter.sendMail(mailOptions, function (err, info) {
if (err) {
console.log("err");
}
else {
console.log("sent" + info.response);
}
})
}
});
Or Using Asyn/Await
export default async (nodemailer) => {
try {
const transporter = nodemailer.createTransport({
service: "gmail",
auth: {
user: process.env.email,
pass: process.env.password
}
})
const mailOptions = {
from: process.env.email,
to: req.user.username,
subject: "Test"
}
const data = await new Promise((resolve, reject) => {
ejs.renderFile(path.join(__dirname, 'views/home.ejs'), { name }, (err, data) => {
if (err) {
reject(err)
}
resolve(data)
});
})
const response = await new Promise((resolve, reject) => {
// eslint-disable-next-line consistent-return
transporter.sendMail(mailOptions, error => {
if (error) {
return reject(error);
}
resolve('Email sent');
});
});
console.log(response);
return response
} catch (error) {
console.log(error);
}
}

What is the problem in the nodejs controller function?

exports.signupController = async (req, res) => {
const { phone, password } = req.body;
try {
const user = await User.findOne({ phone }).exec()
if (user) {
return res.status(400).json({
errorMessage: 'Phone Number already exists',
});
}
const newUser = new User();
newUser.phone = phone;
const salt = await bcrypt.genSalt(10);
newUser.password = await bcrypt.hash(password, salt);
await newUser.save();
return res.status(200).json({
successMessage: 'Registration success. Please login',
});
} catch (err) {
console.log('signupController error: ', err);
res.status(500).json({
errorMessage: 'Server error',
});
}};
**I upload a node application in shared hosting! **
*But an error was showing in this controller function. All the time the catch block is running on the json. The error is unhandled promise rejection. *
signup(data)
.then((response) => {
console.log('Axios signup success: ', response);
setFormData({
phone: '',
password: '',
password2: '',
loading: false,
successMsg: response.data.successMessage,
});
history.push('/signin');
})
.catch((err) => {
console.log('Axios signup error: ', err);
setFormData({
...formData,
loading: false,
errorMsg: err.response.data.errorMessage,
});
});
this is react front end event handler
import axios from 'axios';
export const signup = async (data) => {
const config = {
headers: {
'Content-Type': 'application/json',
},
};
const response = await axios.post('/api/auth/signup', data, config);
return response;
};
the signup api function
Mongoose queries are not promises. They have a .then() function for co and async/await as a convenience. If you need a fully-fledged promise, use the .exec() function. for example:
const query = Band.findOne({name: "Guns N' Roses"});
assert.ok(!(query instanceof Promise));
// A query is not a fully-fledged promise, but it does have a `.then()`.
query.then(function (doc) {
// use doc
});
// `.exec()` gives you a fully-fledged promise
const promise = query.exec();
assert.ok(promise instanceof Promise);
promise.then(function (doc) {
// use doc
});
If you are using exec() on your findOne query you should use:
exports.signupController = async (req, res) => {
const { phone, password } = req.body;
try {
const user = await User.findOne({ phone }).exec();
/// just a pseudo code
user.then('do your things').catch( 'log error')
const newUser = new User();
newUser.phone = phone;
const salt = await bcrypt.genSalt(10);
newUser.password = await bcrypt.hash(password, salt);
await newUser.save();
return res.status(200).json({
successMessage: 'Registration success. Please login',
});
} catch (err) {
console.log('signupController error: ', err);
res.status(500).json({
errorMessage: 'Server error',
});
}};
for more details check this out: https://mongoosejs.com/docs/promises.html#should-you-use-exec-with-await?

_http_outgoing.js:470 throw new ERR_HTTP_HEADERS_SENT('set'); Error: Cannot set headers after they are sent to the client : Nodejs web application

The Code in Users.js gets an error in the snippet at: qrcode.toDataURL(secret.otpauth_url, (err, data_url) => {.
I've tried adding return statement to make sure I'm not sending the response multiple times. I can see that the data_url when converted to image online shows me a QR code but I'm unable to see that when I'm using Postman.
router.post(
"/",
[
check("name", "Name is required")
.not().isEmpty(),
check("email", "Please include a valid email").isEmail(),
check(
"password",
"Please enter a password with 6 or more characters"
).isLength({ min: 6 })
],
async (req, res) => {
console.log("hi");
console.log(JSON.stringify(req.body));
const errors = validationResult(req);
if (!errors.isEmpty()) {
// return res.status(400).json({ errors: errors.array() });
}
const {
name,
email,
password,
type_of_user,
question1,
answer1,
question2,
answer2
} = req.body;
try {
let user = await User.findOne({ email }); // await User.findOne({ email });
user = new User({
name,
email,
avatar,
password,
type_of_user,
question1,
answer1,
question2,
answer2
});
const salt = await bcrypt.genSalt(10); //await
user.password = await bcrypt.hash(password, salt); // await
user
.save()
.then(result => {
// MFAOptions & secret will generate a secret
const MFAOptions = {
issuer: "xyz",
user: req.body.email,
length: 64
};
const secret = speakEasy.generateSecret(MFAOptions);
const token = jwt.sign(
{
name: user.name,
email: user.email,
twofactor: false
},
config.get("jwtSecret"), // chnaged from process env jwt
{
expiresIn: "1h"
}
);
// update the user that is just created:
user
.update(
{ email: req.body.email },
{
$set: { twoFASecret: secret.base32 }
}
)
.exec()
.then(result => {
console.log(result);
qrcode.toDataURL(secret.otpauth_url, (err, data_url) => {
console.log(data_url);
res.status(200).json({
img: data_url,
token: token
});
});
return;
})
//if anything wrong, throws an error
.catch(err => {
console.log(err);
// res.status(500).json({ error: err });
});
})
// originaly this will end here, but now it should redirect to twoFA route,
// if something wrong, shows an error
.catch(err => {
console.log(err);
// res.status(500).json({ error: err });
});
// user with an id, primise which returns an id
const payload = {
user: {
id: user.id
}
};
jwt.sign(
payload,
config.get("jwtSecret"),
{ expiresIn: 3600 },
(err, token) => {
if (err) throw err;
res.json({ token });
}
);
// } //else end
} catch (err) {
console.error(err.message);
res.status(500).send("Server error");
}
}
);
module.exports = router;
I think your problem with executing this line qrcode.toDataURL(secret.otpauth_url, (err, data_url) => {
this calling has callback which means that you will continue in executing the rest of the code and send a response using res.json then after qrcode finish it executes will enter the callback and send another response which is not allowed.
you have multi execution for res.json you need to remove one of them and refactor your code
I tried to refactor your code :
const validation = [check('name', 'Name is required').not().isEmpty(),
check('email', 'Please include a valid email').isEmail(),
check('password', 'Please enter a password with 6 or more characters').isLength({ min: 6 })]
const toDataURL = (otpauth_url) => new Promise((resolve, reject) => {
qrcode.toDataURL(secret.otpauth_url, (err, data_url) => {
if(err)reject(err)
resolve(data_url)
res.status(200).json({
img: data_url,
token,
})
})
});
const signJwt = (payload)=>new Promise((resolve,reject)=>{
return jwt.sign(
payload,
config.get('jwtSecret'),
{ expiresIn: 3600 },
(err, token) => {
if (err) reject(err)
resolve(token)
}
)
})
const postRequest = async (req, res) => {
const errors = validationResult(req)
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() })
}
const { name, email, password, type_of_user, question1, answer1, question2, answer2, } = req.body
try {
let user = await User.findOne({ email })
user = new User({
name,
email,
avatar,
password,
type_of_user,
question1,
answer1,
question2,
answer2,
})
const salt = await bcrypt.genSalt(10) // await
user.password = await bcrypt.hash(password, salt) // await
await user.save()
// MFAOptions & secret will generate a secret
const MFAOptions = {
issuer: 'xyz', user: req.body.email, length: 64,
}
const secret = speakEasy.generateSecret(MFAOptions)
const token = jwt.sign(
{
name: user.name,
email: user.email,
twofactor: false,
},
config.get('jwtSecret'), { expiresIn: '1h', })
// update the user that is just created:
await user.update({ email: req.body.email },
{ $set: { twoFASecret: secret.base32 }, }).exec()
const data_url= await toDataURL(secret.otpauth_url)
if(data_url) return res.status(200).json({
img: data_url,
token,
})
const payload = {
user: {
id: user.id,
},
}
const token= await signJwt(payload)
return res.json({token})
} catch (err) {
console.error(err.message)
return res.status(500).send('Server error')
}
}
router.post('/', validation, postRequest)
module.exports = router

Categories