I build nodejs server, and now I'm testing it with mocha.
I have problem with async requests. I send my object to API, and then check record for with object in DB. I need use only co library and generators.
There's error:
TypeError: Cannot read property 'id' of null
It depends on insertUser object is null, but I don't know why object from database is null.
API works fine, and sequilize works fine.
it('it should POST a user', () => {
return co(function *() {
let user = {
name: "testInsertUser",
password: "12345"
};
let res = yield chai.request(server)
.post('/api/users')
.send(user);
res.should.have.status(HTTPStatus.OK);
res.body.should.be.a('object');
res.body.should.have.property('name').eql(user.name);
res.body.should.not.have.property('password');
//Find user in db
let insertUser =
yield models.User.findOne({
where: {
name: user.name,
password: user.password
}
});
res.body.should.have.property('id').eql(insertUser.id);
});
});
I solve my problem.
Code is fine, but password in db is hashing and I check hash password and order password
Related
I am trying to list the matching users from cognito userpool using expressJs api to check if the username already exists or not.
Code:
listUserFromUserpool = async () => {
var params = {
UserPoolId: process.env.USER_POOL_ID /* required */,
AttributesToGet: ["username"],
Filter: 'username = "example"',
Limit: 5,
PaginationToken: "What to pass here initially ?",
};
try {
let data = await this.cognitoIdentity.listUsers(params).promise();
return data;
} catch (error) {
console.log(error);
return false;
}
};
But getting error in PaginationToken . What should i insert into the PaginationToken param initially as I get the PaginationToken in the next response?
Or, is there any way to get single user without using pagination?
I am using http cloud function ( https://firebase.google.com/docs/functions/http-events ) to write documents to a firestore collection:
exports.hello = functions.https.onRequest(
(req: { query: { name: string } }, res: { send: (arg0: string) => void }) => {
console.log(req.query.name);
var name = req.query.name || 'unknown';
res.send('hello' + name);
admin
.firestore()
.collection('ulala')
.doc()
.set({ token: 'asd' }, { merge: true });
}
);
this is a test. The problem is that, once you deploy and get the link to the function, it is executable by everyone. I would like instead that only I (project owner) can use it . Is it possible to do this?
One possible solution is to restrict your HTTPS Cloud Function to only a specific "Admin" user of your app.
There is an official Cloud Function sample which shows how to restrict an HTTPS Function to only the Firebase users of the app/Firebase project: Authorized HTTPS Endpoint sample.
You need to adapt it to check if the user is the Admin user. For example by checking the userID in the try/catch block at line 60 of the index.js file (untested).
try {
const decodedIdToken = await admin.auth().verifyIdToken(idToken);
if (decodedToken.uid !== "<the admin user uid>") {
throw new Error("Wrong user");
} else {
req.user = decodedIdToken;
next();
}
return;
} catch (error) {
functions.logger.error('Error while verifying Firebase ID token:', error);
res.status(403).send('Unauthorized');
return;
}
The two drawbacks of this approach are:
Your Admin user needs to be declared as a Firebase project user in the Authentication service
You hard code the Admin userID in your Cloud Function (you could use the Google Cloud Secret Manager service to securely store it as a configuration value, see the doc).
IMPORTANT SIDE NOTE:
In your Cloud Function you call the send() method before the asynchronous work is complete:
res.send('hello' + name);
admin
.firestore()
.collection('ulala')
.doc()
.set({ token: 'asd' }, { merge: true });
By calling the send() method, you actually terminate the Cloud Function, indicating to the Cloud Functions instance running your function that it can shut down. Therefore in the majority of the cases the asynchronous set() operation will not be executed.
You need to do as follows:
admin
.firestore()
.collection('ulala')
.doc()
.set({ token: 'asd' }, { merge: true })
.then(() => {
res.send('hello' + name);
})
I would suggest you watch the 3 videos about "JavaScript Promises" from the Firebase video series as well as read this page of the documentation which explain this key point.
I cannot save data to the database after creating user authentication on firebase, the following error appears on the console: "TypeError: firebase.auth (...). CurrentUser is null". it seems that the code cannot read the user's uid after creating the authentication
the code:
createUserButton.addEventListener('click', function(){
firebase.auth().createUserWithEmailAndPassword(emailInput.value, passwordInput.value)
var user = {
nome: "Pedro",
sobrenome: "Ribeiro",
cpf: "946.201.340-31",
uid: firebase.auth().currentUser.uid,
email: emailInput.value,
password: passwordInput.value
}
writeUserData(user)
.catch(function(error) {
// Handle Errors here.
})
})
function writeUserData(user) {
firebase.database().ref('users/' + firebase.auth().currentUser.uid).set(user).catch(error =>{
console.log(error.message)
})
}
what needs to be changed so that the code can read the user's uid and save the data in the database?
You're not waiting until the new user creation process is complete before writing the database. createUserWithEmailAndPassword returns a promise which resolves when the work is done. It will give you a UserCredential object to work with.
firebase.auth().createUserWithEmailAndPassword(emailInput.value, passwordInput.value)
.then(userCredential => {
// write the database here
})
.catch(error => {
// there was an error creating the user
})
I am working on billing in node.js and I created a new Model Stripecustomer where I save the stripe customer id and this customer's email. I kinda copied the main code form my other mongoose models and changed it. I had hoped to instantly start using it but when I tried to find a document in this model I got the following error:
⛔️ Error:
TypeError: Cannot read property 'findOne' of undefined
I have looked at it for half an hour and I can't see what I did wrong. Can anyone tell me where I did something wrong?
workspace.controller.js: here is where I try to create a subscription. Stripecustomer is undefined, but I don't get why since I imported it on top
const stripe = require("stripe")("sk_test_dvebbZQPA4Vk8kKZaEuN32sD");
const {
Group, User, Workspace, Stripecustomer
} = require('../models');
const { sendErr } = require('../../utils');
const billing = async (req, res) => {
try {
const email = 'tijl.declerck#outlook.com';
// get the payment plan
const plan = await stripe.plans.retrieve('plan_EK1uRUJLJcDS6e');
// get the stripe customer or create a new one
let customer;
const existingCustomerDoc = await Stripecustomer.findOne({ email: email });
// if we couldn't find an existing customer in our database...
if (!existingCustomerDoc[0]) {
// then we create a new customer
customer = await stripe.customers.create({
email,
source: 'src_18eYalAHEMiOZZp1l9ZTjSU0'
});
} else {
// we retrieve this customer in stripe
customer = await stripe.customers.retrieve(existingCustomerDoc.customer_id);
}
// subscribe the customer to the plan
// You now have a customer subscribed to a plan.
// Behind the scenes, Stripe creates an invoice for every billing cycle.
// The invoice outlines what the customer owes, reflects when they will be or were charged, and tracks the payment status.
// You can even add additional items to an invoice to factor in one-off charges like setup fees.
const subscription = await stripe.subscriptions.create({
customer: customer.id,
items: [{ plan: plan.id }]
});
res.status(200).json({
message: 'payment complete',
obj: subscription
});
} catch (err) {
return sendErr(res, err);
}
};
stripecustomer.model.js
const mongoose = require('mongoose');
const { Schema } = mongoose;
const stripeCustomerSchema = new Schema({
email: {
type: String,
required: true
},
customer_id: {
type: String,
required: true
}
});
const Stripecustomer = mongoose.model('Stripecustomer', stripeCustomerSchema);
module.exports = Stripecustomer;
The error is probably coming from ur models index.js file, can u share ur models/index.js file to make this more clear, because findOne is a mongoose function, if u get undefined it means Stripecustome is not an instance of a mongoose model
I'm trying to implement a voting system so users of my app can vote on other users responses to a question.
It is a Node app using Express and Sequelize on the back-end, for the moment I'm using a SQLite database for ease of testing.
Here's the relevant parts of my models:
// in user.js
User.associate = function (models) {
// ...
models.User.belongsToMany(models.Response, {
through: models.Vote,
as: 'Votes'
})
}
// in response.js
Response.associate = function (models) {
// ...
models.Response.belongsToMany(models.User, {
through: models.Vote,
as: 'Votes'
})
}
// in vote.js
module.exports = (sequelize, DataTypes) => {
return sequelize.define('Vote', {
upVote: {
type: DataTypes.BOOLEAN,
allowNull: false
}
})
}
So now in my votes.js controller file I may try and create a new vote, given a UserId and a ResponseId as so:
const user = await User.findById(req.user.id)
const response = await Response.findById(req.params.responseId)
await response.addVote(user, {
upVote: true
})
res.send(await response.getVotes())
The problem is, although the Votes join table is created correctly, and although I am passing the addVote function a boolean directly indicating what value the upVote attribute should store, I just get an error stating that notNull Violation: Vote.upVote cannot be null.
The only reason I added the not null constraint to begin with was because without it, I just received a vote with a null value for upVote.
Does anyone have any idea why this might be happening?
I don't know exactly why, but replacing the response.addVote with this:
const vote = await Vote.create({
upVote: req.body.upVote,
UserId: req.user.id,
ResponseId: req.params.responseId
})
res.send(vote)
Works fine. Odd. I keep running into issues where the so-called 'magic' auto-generated functions that Sequelize is supposed to provide for relations either aren't available or don't work.