Unable to change the user password after cognito authentication - node.js

I created the user using adminCreateUser. On trying to authenticate using adminInitiateAuth, a challenge NEW_PASSWORD_REQUIRED is returned. How do I change the password?
I am trying to reset the user password for a user with status FORCE_CHANGE_PASSWORD, using the following snippet:
cognitoidentityserviceprovider.respondToAuthChallenge({
ChallengeName: 'NEW_PASSWORD_REQUIRED',
ClientId:'XXXXXXXXXXXXXXXXXXXX',
ChallengeResponses: {
NEW_PASSWORD: 'T.YpkKu487',
USERNAME: 'XXXXX'
},
Session: "cMcKC5ymFvZG2D10lJMRArpfmLZvnQE25P1XjwkHtl47g4kW-LAjOgB4CAjIgv1CurDmfRHpxzvYgYE61BBrp5-TNyVQcXXX"
}, (err, data) => {
if(err) console.log(err);
else console.log(data);
});
When I run the above code, I get the following error:
InvalidParameterException: Invalid attributes given, name is missing
I do not understand this. Why am I getting this error? Reference doc
Also, is there a way I could disable this challenge altogether?

Found A solution: When I created the user pool I added name and email as required attributes, creating it without requiring attribute name solved it.

Please add the 'name' attribute in your "userattributes" which you will pass for changing the password
.

Related

Exclude user's password from query with Prisma 2

Recently I started working on a new project to learn some new technologies (Prisma 2, REST api with Express, etc.). Tho, I faced a problem.
My app has a user authentication system and the user model has a password column. So, when the client requests a user, the backend selects all the columns from the database including the password (that's hashed by the way).
I tried to not select the password column on the prisma findMany, like this:
await prisma.user.findUnique({
where: {
...
},
select: {
password: false
}
});
But I got an error by prisma saying that the select should contain at least one truly value. Thus, I added id: true to the select. I made an api request and I saw that only the id was returning for the user.
By my understanding, prisma expects me to add all the columns I care to the select object. But, I need a lot of columns from the user and I am making a lot of queries to fetch users and I cannot just write all the field I need everytime.
So, I wanted to ask you if there is a legit way to do that.
PS: I don't take "use rawQuery instead" as a solution.
The only legit way is adding column: true to the columns you want to include. There are requests for excluding columns here so it would be great if you could add a 👍 to the request relevant to you so that we can look at the priority.
https://github.com/prisma/prisma/issues/5042
https://github.com/prisma/prisma/issues/7380
https://github.com/prisma/prisma/issues/3796
I've been wondering about how to implement this as well, and bafflingly the issues linked in #Ryan's post are over two years old, and still unresolved. I came up with a temporary workaround, which is to implement a middleware function for the Prisma client which removes the password field manually after each call.
import { PrismaClient } from '#prisma/client'
async function excludePasswordMiddleware(params, next) {
const result = await next(params)
if (params?.model === 'User' && params?.args?.select?.password !== true) {
delete result.password
}
return result
}
const prisma = new PrismaClient()
prisma.$use(excludePasswordMiddlware)
This will check if the model being queried is a User, and it will not delete the field if you explicitly include the password using a select query. This should allow you to still get the password when needed, like when you need to authenticate a user who is signing in:
async validateUser(email: string, password: string) {
const user = await this.prisma.user.findUnique({
where: { email },
select: {
emailVerified: true,
password: true,
},
})
// Continue to validate user, compare passwords, etc.
return isValid
}
Check out the following code
Exclude keys from user
function exclude(user, ...keys) {
for (let key of keys) {
delete user[key]
}
return user
}
function main() {
const user = await prisma.user.findUnique({ where: 1 })
const userWithoutPassword = exclude(user, 'password')
}
reference
prima official Website

problem with understanding passport local strategy functionality nodejs

I am kinda new in node. recently I decided to create a blog system and it has an authorization system which is created by passport module and local strategy.
I used passport documentation and some video tutorials to design it but I can't understand how does it work, I don't understand the logic.
I have a login form which has two fields (username,password) and a submit button.
you can see my login.jade code here. it is written in jade templating language and used semantic-UI(something like bootstrap).
form.ui.form(method="POST",action="")
div.field
label Username
div.ui.left.icon.input
i.user.icon
input(type="text",name="username",placeholder="username")
div.field
label Password
div.ui.left.icon.input
i.lock.icon
input(type="password",name="password",placeholder="password")
button.ui.primary.button(type="submit") log-in
and here is my passport local strategy
passport.use(new localStrategy(function(username,password,done){
User.checkUserName(username,function(err,user){
if (err) throw err;
if (!user) {
console.log('unknown user');
return done(null,false,{message:'user not found'});
}
if(user.password!=password){
return done(null,false , {message : 'password is wrong'});
}
return done (null,user);
});
}));
checkUserName is a function in my models (user.js) which finds the username in the database.
module.exports.checkUserName= function(username,callback){
User.findOne({username:username},callback);
}
now I don't understand how does the localstrategy work. how does it understand which field in my login form is for username and which field is for the password? it only accepts two arguments (username, password) but I don't know how it specifies where are these arguments come from and how it understands that these must be my login form credentials.
I would be very thankful if someone explains to me what is happening here.
If you're using username / password authentication, by default localStrategy() uses input fields with name="username" and name="password". So, your form is correct.
If you want to use other field names, you can change the defaults. Read this. http://www.passportjs.org/docs/username-password/#parameters
I'd like to point out that you should use a hashing scheme for your passwords, rather than storing them in plain text in your database. Because, Ashley Madison.
This is a well-designed robust hashing scheme. There are others.
Looking at the implementation of the strategy in github it looks at both query of the request and its body and by default will look for username and password keys for their respective values.
This matches the name values in the login form.
If you want to use different name values for your inputs you can specify what values you want it to use by providing a usernameField or passwordField value like follows
passport.use(new localStrategy(function(username,password,done){
User.checkUserName(username,function(err,user){
if (err) throw err;
if (!user) {
console.log('unknown user');
return done(null,false,{message:'user not found'});
}
if(user.password!=password){
return done(null,false , {message : 'password is wrong'});
}
return done (null,user);
});
},
{
usernameField: 'user',
passwordField: 'pass'
}
));
Then you can update the login form name values to match
form.ui.form(method="POST",action="")
div.field
label Username
div.ui.left.icon.input
i.user.icon
input(type="text",name="user",placeholder="username")
div.field
label Password
div.ui.left.icon.input
i.lock.icon
input(type="password",name="pass",placeholder="password")
button.ui.primary.button(type="submit") log-in

How can i get username fron fabric-client , where name set in registerUser.js?

My objective is to show username in web page, where I create user using the following code.
return fabric_client.createUser(
{username: 'user1',
mspid: 'Org1MSP',
cryptoContent: { privateKeyPEM: enrollment.key.toBytes(), signedCertPEM: enrollment.certificate }
});
I couldn't find the way to get the username.
I assume you're calling the Client.createUser function. It returns (asynchronously) a User object which has a getName() function. Looking at the docs and source, it would appear that the user name field is used to store the username.
Take special note that the function is async, meaning that it returns a promise that will resolve to a User.

Loopback 3 crashes when trying to validate a model attached to User base model

I'm stuck at the validation process of my API. I want to validate multiple objects before storing them into the DB. I've created a function that I can call in my remote method in order to handle the validation.
The function below is working as excepted only the Account validation is causing trouble. My Loopback API crashed if the account object is not valid. Very weird because I do exactly the same with the other 2 models?
I've tried many things but nothing is working. Hopefully someone can point me in the right direction.
async function validate() {
vehicle.isValid(function(valid) {
if (!valid)
throw (vehicle.errors);
});
repairJob.isValid(function(valid) {
if (!valid){
console.log(repairJob.errors);
throw (repairJob.errors);
}
});
account.isValid(function(valid) {
if (!valid){
console.log(account.errors);
throw (account.errors);
}
});
}
Output from console:
Browse your REST API at http://localhost:3000/explorer
Errors {
password: [ 'can\'t be blank' ],
email: [ 'can\'t be blank', 'can\'t be blank' ] }
/Users/xxx/Development/xxx/xxx-api-v2/common/models/job.js:105
throw (account.errors);
^
[object Object]
[nodemon] app crashed - waiting for file changes before starting...
In your account.json, you might have mentioned "base": "User", you inherited account model from user model.As you can see below is the user.json where email and password properities are made required:true and so the loopback throws the error.You can change this in account.json by making email and password required:false if you dont want these two fields to be mandatory.Orelse check your request whether these two fileds have value.
According to documentation (https://loopback.io/doc/en/lb3/Validating-model-data.html) you can use isValid method
To invoke the validation constraints explicitly
The same loopback will do automatically each time model instance is created or updated.
As I understand the account model has set "base": "User" and you can't have a user without a password or email.
Can you add how account look like before calling isValid function?

How can I automatically assign a role to a CouchDB user?

I have the following method for registering users:
// Registration method
exports.register = function(req, res) {
var username = req.body.username,
password = req.body.password,
first = req.body.first;
last = req.body.last;
role = req.body.institution;
nano = require('nano')('http://127.0.0.1:5984');
var users = nano.use('_users');
var user = {
"_id": "org.couchdb.user:" + username,
"name": username,
"type": "user",
"roles": [],
"password": password,
"realname": first + " " + last
};
users.insert(user, function(err, body) {
if(err) {
res.send(err.reason, err.status_code);
} else {
res.send(body, 200);
}
});
};
As you can see, I have a variable called role which I would like to set in the "roles" array. Unfortunately, as you probably know, CouchDB only allows the admin to set roles. I'm okay with this, but I'm using the roles as institutions, so I'd like a registering user to be able to pick what institution they're registering under and therefore it should automatically be assigning them this role. Without hard-coding my admin credentials into this method, i.e.
nano.config.url = "http://admin:password#127.0.0.1:5984/"
How can I automatically assign a new user to their specified role as I've mentioned?
The roles array is used by CouchDB to decide database authorization. This allows you to configure access to a given database by a user's role. If the user can set their own role then somebody can give themselves access to any institution. They can even make themselves an admin, which defeats the purpose of protecting your admin password.
I'm not sure what your use-case is, but I don't think you are trying to prevent access to other institutions. Rather, I suspect you are trying to use the roles to perform some other application function (e.g. filtering out information for them to simplify what they see). Since you are wanting to perform a non-security function, I strongly suggest that you just add your own field to the users documents. You could add an institutions property to each user.
If you really want to do this, there is a way. The error you are receiving is coming from an update validation function in _design/_auth in the _users database. As an admin you can change this function.
Download the document. Open the file and search for Only _admin may edit roles to see where the test is being performed. Remove that conditional and save the document back to CouchDB.

Resources