I'm testing a sign-in controller and therefore I've written the following test:
it("return 200 when user signed in successfully", async () => {
await request(app)
.post("/api/v1/signup")
.send({
name: "some-name",
email: "test#mail.com",
password: "abcdefg",
})
.expect(StatusCodes.CREATED);
await request(app).post("/api/v1/signin")
.send({
name: "some-name",
email: "test#mail.com",
password: "abcdefg",
});
.expect(StatusCodes.OK);
});
The test code is straightforward. When the two controllers are tested in postman, everything work well and when start to test in jest, I receive bad request when a user try to sign in. The reason for this bad request is because when try to find an user by email in the signin controller, I receive null which I really don't understand what is the cause of this result.
What I must take into account to resolve this issue when testing in jest?
After doing a deep research into this problem, I had realised that when I use the supertest post-request to save particular data into an user collection, this doesn't seems to work. A workaround for this problem is to import the user-model to create particular data into the collection.
Updated Code
it("return 200 when user signed in successfully", async () => {
await new User({
name: "some-name",
email: "test#mail.com",
password: "abcdefg",
}).save();
const response = await request(app)
.post("/api/v1/signin")
.send({
name: "some-name",
email: "test#mail.com",
password: "abcdefg",
});
expect(response.status).toBe(StatusCodes.OK);
});
Related
Hello? I'm from brazil.
Can you help me with a test? I'm the whole day trying to execute correct and nothing works.
In nutshell, i tried evertying that i saw on internet, but nothing really works.
The follow code was one of the first attempts
const responseToken = await request(app)
.post("/sessions")
.send({ email: "gustavo#gmail.com", password: "gustavo" });
// .send({ email: "admin#admin.com", password: "admin" });
const { token } = responseToken.body;
const userResponse = await request(app)
.post("/users")
.set({ Authorization: Bearer ${token} })
.send({
email: "testIntegration#test.com.br",
name: "Test ",
lastName: "Integration",
password: "test",
});
expect(userResponse).rejects.toEqual(
new AppError("User is not an Admin!")
);
});```
Git: https://github.com/gustavogmfarias/iffolha-js-backend/tree/feature/CreateUser
Okay, I see.
You wrote next code:
expect(userResponse).rejects.toEqual(
new AppError("User is not an Admin!")
);
But on previous step you have already resolved promise with response body from supertest.
Supertest just make a external request to your server and resolve object with response and HTTP Status Code. It doesn't matter what kind of error was throw on your backend.
You should change strategy of code testing. You should check json schema of your response not an error.
For example:
const userResponse = await request(app)
.post("/users")
.set({ Authorization: Bearer ${token} })
.send({
email: "testIntegration#test.com.br",
name: "Test ",
lastName: "Integration",
password: "test",
});
expect(userResponse.body).toEqual({
status: 403,
message: "User is not an Admin!",
});
Please read API of supertest - https://www.npmjs.com/package/supertest
But if you want to check that specific function of your app reject error AppError you should write unit tests for your function and/or create spies - https://jestjs.io/ru/docs/jest-object#jestspyonobject-methodname
Hey this should be very simple for you nodejs gods, I am trying to make authentication system with nodejs using mongoose so the server is successfully receiving the email and parameters entered in the front-end but it seems as if somewhere in my in my logic I am not doing everything properly can I please get some assistance in handling this error because what happens when I console log on the back-end I get the following.
User Successfully Found
EMAIL: test1#gmail.com
PASSWORD: test1
SIGNINUSER: undefined
I get that User Successfully found even when I entered a wrong user
**Interesting part is when I remove the .then I get back the user object but return errors with regards to unhandled promise
Code below where I am handling the signing in of users
router.post("/signin", async (request, response) => {
const signinUser = await User.find({
email: request.body.email,
password: request.body.password,
})
.then((response) => {
console.log("User Successfully Found");
})
.catch((error) => {
console.log("User Does not exist");
});
//Here I was trying to check if I really am receiving the data from the client
//Just to find that I am receiving the clients data
console.log("EMAIL: ", request.body.email);
console.log("PASSWORD: ", request.body.password);
//Here I was trying to check if the usersInfo is being set inside the siginUser variable
//just to find that I getting the value of undefined
console.log("SIGNINUSER: ", signinUser);
if (signinUser) {
response.status(200).json({
_id: signinUser.id,
name: signinUser.name,
email: signinUser.email,
isAdmin: signinUser.isAdmin,
token: getToken(user),
});
} else {
response.status(401).send({ message: "Invalid Email or Password" });
}
});
Without running the code I would say you are mixing await with then and monoogose queries. So in the proposed solution User.find() returns the query (which is not a promise but a theneable), you exec it to get a promise and await for result. Removing then but keeping your code behavior might look like.
router.post("/signin", async (request, response) => {
const signinUser = await User.find({
email: request.body.email,
password: request.body.password,
}).exec();
if (!signinUser) {
console.log("User Does not exist");
return response.status(401).send({ message: "Invalid Email or Password" });
}
console.log("User Successfully Found");
console.log("EMAIL: ", request.body.email);
console.log("PASSWORD: ", request.body.password);
console.log("SIGNINUSER: ", signinUser);
return response.status(200).json({
_id: signinUser.id,
name: signinUser.name,
email: signinUser.email,
isAdmin: signinUser.isAdm
token: getToken(user),
});
});
I hope it helps.
More info here
Mongoose - What does the exec function do?
Just change your response Code i think this problem will be Gone
return response.status(200).json({
_id: signinUser.id,
name: signinUser.name,
email: signinUser.email,
isAdmin: signinUser.isAdm,
token: getToken(user.toObject()),
});
I changed Only
token: getToken(user.toObject()),
I'm creating users using the admin SDK and I'm wanting them to be able to login with email and password. For some reason when I create users through the client using only email and password, the user can login using those credentials, but when I create a user using the admin SDK, the user is shown as anonymous in the auth dashboard, and the user can't login using their email and password. No errors are shown client side or Firebase side.
How can I create a Firebase user using the admin SDK and have that user linked to email authentication?
Node:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
exports.createUser = functions.https.onRequest(async (req, res) => {
//grab the email and password parameters
await admin.auth().createUser({
email: req.query.email,
password: req.query.password
})
//create the user
.then(function(userRecord) {
const child = userRecord.uid;
console.log('Successfully created new user:', userRecord.uid);
res.json({
status: 201,
data: {
"message": userRecord.uid
}
});
})
//handle errors
.catch(function(error) {
console.log();
res.json({
status: 500,
data: {
"error": 'error creating user: ', error
}
});
});
});
Swift:
func createChild(for parent: Parent,
with firstName: String,
lastName: String,
displayName: String?,
chores: [Chore]?,
username: String,
password: String,
completion: #escaping () -> Void = { }) {
let funcCallDict = [
"email": username,
"password": password
]
functions.httpsCallable(addChildIdentifier).call(funcCallDict) { (result, error) in
if let error = error {
NSLog("error: adding child with firebase function: \(error)")
completion()
return
}
}
completion()
}
Your function is an HTTP type trigger:
exports.createUser = functions.https.onRequest
But you're trying to invoke it as a callable type trigger:
functions.httpsCallable(addChildIdentifier).call(funcCallDict)
(Note that a callable trigger would be defined with onCall, not onRequest.)
As you can see from the documentation links, they are not the same thing. You are probably invoking the HTTP trigger, and it's not actually getting the arguments you expect from the client, since the protocol is different between them. Try logging req.query.email in the function to see what I mean.
You will have to either make your function a proper callable so it can be invoked from the client using the provided library, or change the way you invoke it on the client to use a regular http library instead of the Firebase library.
I've been following the Firebase SDK Admin - Manager User docs and everything went find for me with it's system. Either way, i want to extend my users information with fields such as first name, last name, nacionality, etc etc.
Right now i'm using Vue.JS (fronted), Axios (Http client) and Express.js (server) to manage my project and this is the way i create my users:
Vue.JS createUser method:
createUser() {
axios.post('http://localhost:3000/users',
{
username: this.username,
email: this.email,
firstName: this.firstName,
lastName: this.lastName,
password: this.password,
}).then(r => {
console.log(r)
}).catch(e => {
console.log(e)
})
// createUser
}
Each field: username, email, firstName, etc... got its value form a common HTML Form and they work just fine.
This is my "user create" route on the server side:
router.post('/', function (req, res, next) {
firebase.auth().createUser({
email: req.body.email,
username: req.body.username,
firstName: req.body.firstName,
lastName: req.body.lastName,
emailVerified: false,
password: req.body.password,
disabled: false
}).then(function(userRecord) {
console.log("Successfully created new user:", userRecord.uid);
}).catch(function(error) {
console.log("Error creating new user:", error);
});
});
And this is how i retrieve the users information:
router.get('/', function(req, res, next) {
firebase.auth().listUsers()
.then(function(listUsersResult) {
res.send(listUsersResult.users);
}).catch(function(error) {
console.log("Error listing users:", error);
})
});
The problem is that i can't get the custom fields i added (or they simply does not exists). Here's is a pictures of the data once i get it with the next method:
getItems() {
axios.get('http://localhost:3000/users').then(r => {
this.users = r.data
}).catch(e => {
console.log(e)
})
},
Is there a way to set custom fields on my user creation or (if my process is right) a way to retrieve them?
Firebase users are not customizable, unfortunately you can not add custom fields to the user... check out these docs for the properties of this object. Also check out this question & answer where Frank explains that you need to store any extra info separately... this is typically done in a table (named something like /userDetails) in your database.
FEBRUARY 2022 EDIT:
Since writing this answer, custom user claims are now a thing. It's meant for authentication / rules purposes and not data-storage, so most things should still be kept in the database as originally stated. Note that you CAN access the custom fields client-side.
Keep in mind, this is adding additional data to the ID token that gets sent with EVERY server request, so you should try to limit usage of this to role/permission based things and not, say, image data for a 2nd profile avatar. Read the best practices for custom claims on the official docs.
You can set a user's profile, immediately after creating.
firebase.auth().createUserWithEmailAndPassword(
email,
password,
).then(credential => {
if (credential) {
credential.user.updateProfile({
displayName: username
})
}
}
I am using feathers server and I want to implement Oauth2 authentification with facebook or github strategy or whatever. But I also would like to use with graphql
But I dont know how to implement with graphql I'm using https://github.com/feathersjs/feathers-authentication-oauth2 it works as a API if I send GET request on callback url it works correctly I get token but I'd like do this with graphql as for example in LOCAL or LDAP strategy
const authentication = feathers()
authentication.configure(hooks())
.configure(rest(base).superagent(superagent))
.configure(auth({ storage: localStorage }));
RootMutation: {
signInLocal(root, {email, password}, context){
return authentication.authenticate({
strategy: 'local',
email: email,
password: password
}, context).then(data=>{
// console.log(data)
return data
})
},
signInLdap(root, {username, password}, context){
return authentication.authenticate({
strategy: 'ldap',
username: username,
password: password
}, context).then(data=>{
// console.log(data)
return data
})
}
}
I tried
RootQuery: {
signInGithub(root, data, context){
return authentication.authenticate({
strategy: 'github',
}, context).then(data=>{
console.log(data)
return data
})
}
},
But I got error
feathers-authentication:passport:authenticate 'github' authentication redirecting to https://github.com/login/oauth/authorize?response_type=code&redirect_uri=https%3A%2F%2Flocalhost%3A3000%2Fauth%2Fgithub
%2Fcallback&scope=user&client_id=0b786a43497059d2a28b 302 +3ms
feathers-authentication:middleware:failure-redirect Redirecting to https://github.com/login/oauth/authorize?response_type=code&redirect_uri=https%3A%2F%2Flocalhost%3A3000%2Fauth%2Fgithub%2Fcallback&scope=
user&client_id=0b786a43497059d2a28b after failed authentication. +7ms
Error: Unexpected end of JSON input
Thanks for any help