I have just started learning Node.js and I want to insert a new user in a database. When I try to test the code with Postman I get req undefined.
Here is my json in Postman:
//userController.js
router.post('/user/new', function (req, res) {
var newUser = {
email: req.email,
first_name: req.first_name,
last_name: req.last_name,
phonenumber: req.phonenumber,
password: req.password
}
console.log(req.email)
User.createUser(newUser, function(err, user){
});
Any suggestions?
Related
I'm trying to unit test with Prisma and Jest following this link https://www.prisma.io/docs/guides/testing/unit-testing.
Here is my test code:
test("should create a user ", async () => {
var user: any = {
store_id: "601d6dea-9b89-4c0d-adfc-6ed52424a2a0",
password: '1234',
user_name: "username",
first_name: "Rich",
last_name: "hello#prisma.io",
phone: "12345",
is_phone_verified: true,
is_email_verified: true, };
prismaMock.sec_user_fs.create.mockImplementation(user)
await expect(createUser(user)).resolves.toEqual({
store_id: "601d6dea-9b89-4c0d-adfc-6ed52424a2a0" }); });
createUser method is save data to database. Here is code:
export async function createUser(user: CreateUser) {
user = await prisma.sec_user_fs.create({
data: user,
})
return {"store_id": user.store_id} }
So my questions are:
prismaMock.sec_user_fs.create.mockImplementation(user) - In my understanding this line mocked database table, it prevent not insert data to table while testing. But, it does. How can mock without inserting, updating,deleting to table?
createUser method return json object. But if i test my api end point /code is below/ how expect result? Because it does return res.status(200) etc.?
export default asyncHandler(async (req: CustomRequest, res: Response)=> {
const body = {
user_name: req.body.user_name,
first_name: req.body.first_name,
last_name: req.body.last_name,
phone: req.body.phone,
phone_country_code: req.body.phone_country_code }
const user_id = req.params.id
const user = await prisma.sec_user_fs.updateMany({
where: {
user_id,
status: 'A'
},
data: body });
res.status(200).send({
status: 'Success',
message: req.t('success'),
errors: [],
data: user, }); });
Thanks in advance :)
I am working to implement passport.js in my react/node/express/sequelize app.
I currently have middleware working for logging a user in, and checking if the user is authenticated. However, when a new user signs up or registers, their user data is not being saved to the server session (even though it is created in the DB). This means after a user registers, they have to go to the login page, enter their credentials and hit login before their session is saved.
My login function is simple:
router.post('/login', passport.authenticate('local'), (req, res) => {
//console.log(req);
console.log("Is authenticated: " + req.isAuthenticated());
res.json(req.user);
});
it uses passport.authenticate local strategy, which I've defined as:
passport.use(new LocalStrategy(
{
usernameField: 'email',
},
((email, password, done) => {
User.findOne({
where: {
email,
},
}).then((dbUser) => {
if (!dbUser) {
return done(null, false, {
message: 'Incorrect email.',
});
}
if (!dbUser.validPassword(password)) {
return done(null, false, {
message: 'Incorrect password.',
});
}
return done(null, dbUser);
});
}),
));
I know from the passport documentation and from looking at other questions that the passport.authenticate local strategy automatically calls the req.login() function, which serializes my user information and saves it in the server session.
My main issue is I'm not sure exactly how to implement this during my register function.
router.post('/signup', (req, res) => {
const user = {
first_name: req.body.first_name,
last_name: req.body.last_name,
email: req.body.email,
password: req.body.password,
};
User.findOrCreate({where: {email: user.email}, defaults: user})
.then(data => {
res.send(data);
})
.catch(err => {
res.status(500).send({
message:
err.message || "Some error occurred while creating the User."
});
});
});
I've tried calling req.login() after findOrCreate, but I get an error:
(node:42313) UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
If I use my local strategy, I get an unauthorized response (since the credentials I'm using to authorize are not yet in the DB).
I figure I need to make a custom strategy for sign in, but it's not clear to me if that's the right approach, or how I would specify it.
I fixed this by adding req.login before res.send:
router.post('/signup', (req, res) => {
const user = {
first_name: req.body.first_name,
last_name: req.body.last_name,
email: req.body.email,
password: req.body.password,
};
User.findOrCreate({where: {email: user.email}, defaults: user})
.then(data => {
req.login(data[0], function(err) {
if (err) {
console.log("login function erroring out with: " + err)
}
});
res.send(data);
})
.catch(err => {
res.status(500).send({
message:
err.message || "Some error occurred while creating the User."
});
});
});
I have a rails api connected to a VueJS front end. I am working on login. When I enter credentials and click login the sign-in method is called and In the Network tab, I see the response, but Vue throws the error:
login error: TypeError: Cannot read property 'auth_token' of undefined
here is the the data returned as seen in the network tab:
{user: {id: 1, email: "test#test.ca",…},…}
auth_token: "eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2MDYwNDU3ODgsImlzcyI6Imlzc3Vlcl9uYW1lIiwiYXVkIjoiY2xpZW50IiwidXNlcl9pZCI6MX0.ZLlKtsdyqS-qFwJljvDsQeBxOJyU756q38-cX6MN_2Q"
user: {id: 1, email: "test#test.ca",…}
created_at: "2020-11-10T22:37:01.775Z"
email: "test#test.ca"
id: 1
password_digest: "$2a$12$bVmG1cvMidLice0Qcn8sBu36/F1HxhY0NeHT5gRKcAoV8u5Lk5wx6"
updated_at: "2020-11-10T22:37:01.775Z"
Here is my signin method:
async signin () {
try {
console.log('base rute is: ', process.env.VUE_APP_ROOT_API)
const response = await Api.post('users/login', {
user: {
email: this.email_input,
password: this.password
}
})
const loggedUser = response.data
console.log('this is login response data: ', loggedUser)
this.$store.commit('set_token', this.loggedUser.auth_token) [THIS IS WHERE THE ERROR IS THROWN]
this.$store.commit('set_user', this.loggedUser.user)
localStorage.setItem('token', this.loggedUser.auth_token)
localStorage.setItem('user', JSON.stringify(this.loggedUser.user))
this.$emit('authenticated', true)
} catch (err) {
console.log('login error: ', err)
}
}
}
I am really not sure what the problem is.
You would call this.loggedUser if it was in data. But you have set it as constant.
async signin () {
try {
console.log('base rute is: ', process.env.VUE_APP_ROOT_API)
const response = await Api.post('users/login', {
user: {
email: this.email_input,
password: this.password
}
})
const loggedUser = response.data
console.log('this is login response data: ', loggedUser)
this.$store.commit('set_token', loggedUser.auth_token)
this.$store.commit('set_user', loggedUser.user)
localStorage.setItem('token', loggedUser.auth_token)
localStorage.setItem('user', JSON.stringify(loggedUser.user))
this.$emit('authenticated', true)
} catch (err) {
console.log('login error: ', err)
}
}
I have a api in which for login it works like this. To make api call i have to add authorization basic auth like this.
And the body
But the problem is when i make api request through axios it always give me response error like this
Error: "Request failed with status code 401"
createError createError.js:17
settle settle.js:19
handleLoad xhr.js:60
I made request something like this.
//TODO: AUTH Actions
export const login = (username, password) => (dispatch) => {
//User Loading:
dispatch({ type: USER_LOADING });
//Make API Call here
console.log('featch adata', data);
axios.post('https://api.smartocart.com/oauth/token', {
data: {
username: username,
password: password,
grant_type: 'password',
},
auth: {
username: 'topseller',
password: 'topseller'
}
})
.then((res) => {
console.log('Then response', res)
}).catch(err => {
console.log(err)
})
// console.log('Action login', username, password);
}
As mentioned try the config object as third param to .post function, Request post body should be the second param.
https://github.com/axios/axios#axiosposturl-data-config-1
You are trying something like axios.post(url, config) but such a function is not there. You should use axios.post(url, data, config)
axios.post('https://api.smartocart.com/oauth/token',
{
username: username,
password: password,
grant_type: 'password',
},
{
auth: {
username: 'topseller',
password: 'topseller'
}
}
).then((res) => {
console.log('Then response', res)
}).catch(err => {
console.log(err)
})
Having trouble doing this - is it even possible?
Sign-up Email Verification is off, and I'm doing this in the config:
BackandProvider.setAppName( 'test' );
BackandProvider.runSigninAfterSignup( true );
// ... tokens, etc.
Getting this back in the response after hitting the /1/user/signup endpoint:
data : {
currentStatus : 1,
listOfPossibleStatus : [...],
message : "The user is ready to sign in",
token : "...",
username : "tester#test.com"
}
Do I need to make another API call? Can't find where and with which params.
Yes, you must make another API call to get token after sign up. If you use the Backand SDK by default it makes the second call.
$scope.signup = function (form) {
return Backand.signup(form.firstName, form.lastName,
form.username, form.password,
form.password,
{company: form.company})
.then(function (response) {
$scope.getUserDetails();
return response;
});
};
If you lool at the SDK code, this is what happens there:
self.signup = function (firstName, lastName, email, password, confirmPassword, parameters) {
return http({
method: 'POST',
url: config.apiUrl + urls.signup,
headers: {
'SignUpToken': config.signUpToken
},
data: {
firstName: firstName,
lastName: lastName,
email: email,
password: password,
confirmPassword: confirmPassword,
parameters: parameters
}
}).then(function (response) {
$rootScope.$broadcast(EVENTS.SIGNUP);
if (config.runSigninAfterSignup
&& response.data.currentStatus === 1) {
return self.signin(email, password);
}
return response;
})
};