Description
Bug report
I'm working on creating storage policies that allow users to insert, update, and delete items if their user ID is the same as the folder name. Most of this was given from the storage policy templates. The issue is this doesn't work. If I hard-code the UUID, it will work. Example:
Insert, update, and delete policy. This fails.
((bucket_id = 'avatars'::text) AND ((auth.uid())::text = (storage.foldername(name))[1]))
Returns:
StorageError(statusCode: "403", message: "new row violates row-level security policy", error: "Unauthorized")
Now if I update the policy to a hardcoded UUID like so, it works:
(bucket_id = 'avatars'::text) AND ( '5714F7D7-108B-4D9C-8945-8707075845B0'::text) = ((storage.foldername(name))[1])
This is the function that I'm using to handle my avatar uploads:
func uploadUserAvatar(image: PhotosPickerItem) async throws -> () {
guard let imageData = try await image.loadTransferable(type: Data.self) else { return }
let userId = try await supabaseClient.auth.session.user.id
print(userId.uuidString)
let filePath = "\(userId.uuidString)/avatar.jpeg"
try await supabaseClient.storage
.from("avatars")
.upload(
path: filePath,
file: imageData,
options: FileOptions(contentType: "image/jpeg", upsert: false)
)
}
To summarize, even though I've verified that the UUID is the matching UUID on the auth table. When working with storage policies it seems like there is something wrong when auth.uid()
is being checked on the database storage side or what is being sent back from the session.
Edit: I must also point out this is the case with upsert being false. If upsert is true, this will fail regardless of the two policies I shared up there. Separate issue but hopefully identifying the issue here will help solve the upsert issue as well.