I am inserting a user row into Postgres from Express.js like as follows:
db.none("INSERT INTO users (email, password) VALUES (${incoming.email}, crypt(${incoming.password}, gen_salt('bf')))",{
incoming: { email: qemail, password: qpwd}
}
).then(function (data) {
// data is null
});
The email and password come from the query parameters on the React.js frontend. I use this query for the signup action on my application and wanted to know if I could get this newly added user back from this same query. I just felt that making another get request right after the signup to get the user info was inefficient, which I do for my login action. Thanks in advance.
Append RETURNING * to your query, and replace none with method one.
const row = await db.one("INSERT INTO users(email, password) VALUES(${incoming.email},
crypt(${incoming.password}, gen_salt('bf'))) RETURNING *",
{
incoming: { email: qemail, password: qpwd}
}
);
// row = the newly inserted row
At the end of the query add RETURNING *. This should return the newly added query. (postgresql docs).
In your query:
"INSERT INTO users (
email, password
) VALUES (
${incoming.email}, crypt(${incoming.password}, gen_salt('bf'))
) RETURNING *"
Related
I'm creating a MERN stack ecommerce application where I want send all user info along with jwt token but except password I'm ok with token part & I know how to send user but i don't know how to exclude the password property while sending the user through res.json
enter image description here
Modified Answer -
#prathamesh
You can change the default behavior at the schema definition level using the select attribute of the field:
password: { type: String, select: false }
Then you can pull it in as needed in find and populate calls via field selection as '+password'. For example:
Users.findOne({_id: id}).select('+password').exec(...);
You can use the aggregation or select method in the mongoose.
const users = await User.find({}, {name: 1, email: 1});
or
const users = await User.find({}).select("name email");
or
const users = await User.aggregate([{"$project": {name: 1, email: 1}}]);
I use this way to save all attributes except password in another variable and then I show info.
let {password, ...foundUser} = user.toJSON();
response.setStatus(200).setRes(foundUser);
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
I am fetching id column value from database for a particular email. In this case I am passing email and want to get primary key i.e id. This operation is successful as I get object which contains Object with the right and expected result. However I am not able to access the object.
I am receiving object like this:
[ UserInfo { id: 21 } ]
And I am not able to access id part of it.
I am using node.js, postgres for database and typeorm library to connect with database.
const id = await userRepo.find({
select:["id"],
where: {
email:email
}
});
console.log(id)
This prints the above object.
The id I am getting is right. But I am not able to retrieve the id part of the object. I tried various ways for e.g.
id['UserInfo'].id, id.UserInfo.
Please help me in accessing the object I am receiving
Typeorm .find() returns an array of objects containing entries corresponding to your filters, in your case, all entries with an email field corresponding to the email you specified.
Because the result is an array, you can access it this way:
const records = await userRepo.find({
select: ['id'],
where: {
email,
},
})
console.log(records[0].id)
You could also use the .findOne() method, which returns a single element and might be a better solution in your case :)
When you are putting a field in the select part select:["id"], you are only retrieving this part of the database.
It is like your query was this: select id from userRepo where email = email
and you need to put * in the select part to retrieve all the information:
const id = await userRepo.find({
select:["*"],
where: {
email:email
}
});
Whenever I check the delete operation in postman than it always deletes the last element of the array. I want a particular element to be deleted.if without using findIndex() method some changes being done in this code only so that it can also make working with splice() only.basically the users[] array is there in which details of each user are stores in json format like
user = {
username: req.body.username,
password: req.body.password
}
so can we apply map function on this code with splice and after serching in array remove that user.it wil be more heplful for me if splice()is used in same code and not findIndex().
Code:
app.post('/delete-user', (req, res)=> {
users.splice(users.indexOf({ username: req.body.username, password:req.body.password}, 1))
res.send(users)
})
Use the filter method: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
const newUsers = users.filter((user) => {
return user.id !== id // Get a new array of users excluding the user with the sepcified ID
})
res.send(newUsers)
I have a table in my database called users. In this table I only store user ID, username and password. Now, in another table called user_meta, I have the following columns: id, uid, meta_key, meta_value. I'm trying to find a way for Bookshelf to automatically load all records in user_meta where uid == userid, and store them as model.meta[meta_key] = meta_value. Sadly, I haven't been able to find a way to make this possible.
If it is possible at all, the 2nd step would be to also save all values in model.meta back on update / insert, inserting records where meta_key doesn't exist for that user ID yet, and updating where it does.
Try to set the associations (relations) between the models:
var User = bookshelf.Model.extend({
tableName: 'users',
meta: function() {
return this.hasMany(Meta);
}
});
var Meta = bookshelf.Model.extend({
tableName: 'user_meta',
user: function() {
return this.belongsTo(User);
}
});
http://bookshelfjs.org/#one-to-many