Supabase bucket - new row violates row-level security policy for table "objects" - supabase

i am having an issue with uploading avatars to my supabase bucket as its giving me "new row violates row-level security policy for table "objects"". I tried other StackOverflow solutions and nothing.
Before trying to upload I log in using supabse so my user is authenticated yet its still not letting me upload. I added this policy in storage.objects:
(role() = 'authenticated'::text) and clicked the insert button. Does anyone know what I am doing wrong? I assume its something to do with the policies. Thanks
this is how I'm trying to upload my avatar:
try{
const { data, error } = await supabase
.storage
.from('/public/avatars')
.upload(`${values.email}.png`, values.avatar, {
cacheControl: '3600',
upsert: true
});
if(error) throw error;
}catch(error){
console.log(error);
}

add new policy and enjoy :)
Because upsert need DELETE and UPDATE

I'm guessing you have a bucket named public with a folder named avatars, correct?
In that case you would upload as follows:
const avatarFile = event.target.files[0]
const { data, error } = await supabase
.storage
.from('public')
.upload(`avatars/avatar1.png`, avatarFile, {
cacheControl: '3600',
upsert: false
})

Related

Iron session is not updating req.session object

I have a page where users can give themselves a "role" like member or admin. They can go to another route to create messages. I am trying to update user's role from "user" to "admin". It updates req.session to admin role in the admin.js file, but when I go to messages/create.js and try to log req.session, it shows that user still has the "user" role. I am saving the changes I make by calling req.session.save(), but it is not working.
admin.js
import { withIronSessionApiRoute } from "iron-session/next";
import nc from "next-connect";
import { session_config } from "../../lib/config";
import Users from "../../models/user";
import { connectToDatabase } from "../../util/mongodb";
const handler = nc()
handler.post(async (req) => {
if (req.body.password === process.env.ADMIN_PASSWORD) {
await connectToDatabase()
await Users.findOneAndUpdate({ name: req.session.user.name }, { role: "admin" })
const updated_user = { name: req.session.user.name, role: "admin" }
req.session.user = updated_user
await req.session.save()
}
})
export default withIronSessionApiRoute(handler, session_config);
messages/create.js
import { withIronSessionApiRoute } from "iron-session/next";
import nc from "next-connect";
import { session_config } from "../../../lib/config";
const handler = nc()
handler.post(async (req) => {
console.log(req.session.user)
console.log(req.body)
})
export default withIronSessionApiRoute(handler, session_config)
Please let me know what the issue is and how I can fix it. Thank you
The first thing I noticed from looking at the code is that you're not sending a response back to the client. Iron session uses cookies to manage stateless authentication and the way it manages is by setting the response header. Because you're not sending a response, it can't update the session.
Looking further into the API documentation, session.save() - "Saves the session and sets the cookie header to be sent once the response is sent."
Not knowing your full implementation or having a working code example from something like codesandbox.io, I suggest the following code to see if this solves your problem.
// please make sure that `res` is a parameter on the `.post()` function
// on your original code. I've already set it as shown below.
handler.post(async (req, res) => {
if (req.body.password === process.env.ADMIN_PASSWORD) {
await connectToDatabase()
await Users.findOneAndUpdate({ name: req.session.user.name }, { role: "admin" })
const updated_user = { name: req.session.user.name, role: "admin" }
req.session.user = updated_user
await req.session.save()
// response below
res.send({ ok: true })
// or if you don't want to send custom data back, comment the line above,
// and then uncomment the line below
// res.status(200).end()
}
})
Attempt 2
I made an iron session demo on Codesandbox using some of the demo code from the iron session repo NextJs example.
The code example shows:
login
log out
setting a user as an admin
fetching user data from server-side
fetching user data from client-side
fetching using SWR
Some side notes to be aware of: if you are doing something like
const sessionData = req.session.user, then trying to mutate the req.session.user, and then sending the data back, it won't work because the session object will be recreated per request and node cannot store req.session as a reference.
If my demo doesn't help you, then you're going to have to share more info and code, and maybe create a Codesandbox to reproduce what is happening to you.

Trying to update the database using the strapi.db.query even providing data, failed with "Update required data object"

Below is the code that I tried to update the database using the id,
try {
await strapi.db.query("api::otp.otp").update(otpSent.id, {
where: { otpSent },
data,
});
} catch (error) {
console.log(error);
}
but I am stuck at the error saying
Error: Update requires a data object.
I have checked the entity-manager.js to see arguments are correct. But, at last I do not get any idea to update the query. Please give some tips to me to figure this out. The only thing is to update the database entries by id in the strapi controller.
Actually, I should use
strapi.service("api::otp.otp").update(otpSent.id, { data: data })

beforeSave doesn't modify request.object

I'm trying to add some additional attributes for new user through cloud code:
Parse.Cloud.beforeSave(Parse.User, (request) => {
if (!request.original) {
// New user
Parse.Config.get()
.then((config) => {
const ProfileIcon = Parse.Object.extend("ProfileIcon");
const iconId = config.get("defaultProfileIcon");
const user = request.object;
// ...many user.set
user.set("profileIcon", ProfileIcon.createWithoutData(iconId), {
useMasterKey: true,
}); // Pointer
// This will save as expected, but cause recursion
// user.save({ useMasterKey: true });
})
.catch((err) => {
console.error(err);
});
}
});
The code above triggered and executed without any error, but when I check the database, none of my custom attributes show up. Passing the master key also does nothing. How can I fix this?
Or is it because the request from the client (Android, have no access to master key), if so then how can I set master key for the request, since Parse.Cloud.useMasterKey() is deprecated?
Here, modifying object on save does not mention anything about return, but before save file does. So I thought I would give it a try, turns out it worked. Still not sure if this is the right way though.

Parse Server - How to delete image file from the server using cloud code

How can I delete an image's file from the server using Parse Cloud Code. I am using back4app.com
After Deleting Image Row
I am getting the images urls, then calling a function to delete the image using its url
Parse.Cloud.afterDelete("Image", function(request) {
// get urls
var imageUrl = request.object.get("image").url();
var thumbUrl = request.object.get("thumb").url();
if(imageUrl!=null){
//delete
deleteFile(imageUrl);
}
if(thumbUrl!=null){
//delete
deleteFile(thumbUrl);
}
});
Delete the image file from the server
function deleteFile(url){
Parse.Cloud.httpRequest({
url: url.substring(url.lastIndexOf("/")+1),
method: 'DELETE',
headers: {
'X-Parse-Application-Id': 'xxx',
'X-Parse-Master-Key': 'xxx'
}
}).then(function(httpResponse) {
console.log(httpResponse.text);
}, function(httpResponse) {
console.error('Request failed with response code ' + httpResponse.status);
});
}
for security reasons, not is posible to delete directly the image from Back4App, using DELETE from SDK or REST API. I believe that you can follow the guide below:
https://help.back4app.com/hc/en-us/articles/360002327652-How-to-delete-files-completely-
After struggling with this for a while it seems to be possible through cloud function as mentioned here. One need to use MasterKey in the cloud code:
Parse.Cloud.define('deleteGalleryPicture', async (request) => {
const {image_id} = request.params;
const Gallery = Parse.Object.extend('Gallery');
const query = new Parse.Query(Gallery);
try {
const Image = await query.get(image_id);
const picture = Image.get('picture');
await picture.destroy({useMasterKey: true});
await Image.destroy();
return 'Image removed.';
} catch (error) {
console.log(error);
throw new Error('Error deleting image');
}
});
For me it was first confusing since I could open the link to that file even after I deleted the reference object in the dashboard, but then I found out that the dashboard is not calling Parse.Cloud.beforeDelete() trigger for some reason.
Trying to download the data from the url after deleting the file through the cloud code function returns 0kB data and therefore confirms that they were deleted.

Setting some Parse.User property on beforeSave when running on Heroku

Can you edit data in beforeSave callback and if yes, how?
Looking at various docs, it seem like this code should work (using "_User" or Parse.User) and I can see Ran beforeSave on a User and new user! in my logs but the key aaa is still empty..
I've tried to add user.save() after user.set but still no luck.
Any idea?
Parse.Cloud.beforeSave("_User", function(request, response) {
console.log('Ran beforeSave on a User');
var user = request.object;
if(user.existed()) {
response.success();
} else {
console.log('new user!');
user.set('aaa', 'xxx');
response.success();
}
});
EDIT 2015/12/03: Maybe critical info, this code is running on heroku. http://blog.parse.com/announcements/introducing-heroku-parse/
EDIT 2015/12/05: It seem to be a bug with Heroku / Parse integration. beforeSave hook are called but doesn't seem to allow you to edit the request.object..
EDIT 2015/12/07: I've created an issue on the CloudCode-Express repo https://github.com/ParsePlatform/CloudCode-Express/issues/6
Using Webhooks, you need to pass back the changed object:
response.success(object);
Change your code to use isNew() method:
Parse.Cloud.beforeSave(Parse.User, function(request, response) {
console.log('Ran beforeSave on a User');
if(!request.object.isNew()) {
response.success();
} else {
console.log('new user!');
request.object.set('aaa', 'xxx');
response.success();
}
});

Resources