Is possible to export schema from nested folder?
Hello, I'm trying to achieve something like the setup below but I keep getting errors with my functions when I move the schema file. Is this possible?
convex/schema/index.ts
convex/schema/users.ts
19 Replies
What I would do is:
convex/schema.ts
convex/schemas/users.ts
I see thank you! also sorry one more question. This is my first time trying out convex and I was wondering if there was an easy way of writing a mutation that lets me update any field? I was attempting the method below but I would want all fields to be optional.
check out the
partial
helper in convex-helpers/validators
I believe
There's also the crud
helper which might be useful to you. Though I would caution that updateUser
could allow a malicious client to edit any other user's details right now. You probably want to assure the logged in user is the one being edited. In this way, the crud
helper doesn't help since it doesn't have any access controls built in (better for internal functions)Yep the partial was exactly what I was looking for and gotcha will probably look into the row level security stuff from the convex helpers.
Thank you for all the help!
I'm planning to update the interface for RLS to something like:
Would love to know what you think, once you see the current API
Of course, I was looking at this blog post about creating custom queries. I was confused because everywhere I looked I couldn't find any reference to what
wrapDatabaseReader
is actually doing. I assume it's just applying the rules passed to it using the user data on the current database ctx. I was also looking at the RLS blog post but it only documents doing this with wrapper method. Not sure if I'm missing something?Customizing serverless functions without middleware
Re-use code and centralize request handler definitions with discoverability and type safety and without the indirection of middleware or nesting of wr...
Row Level Security: Wrappers as "Middleware"
Implementing row-level security on Convex as a library. Wrap access to the database with access checks written in plain old JS / TS.
Here's an example: https://github.com/get-convex/convex-helpers/blob/main/convex/rowLevelSecurityExample.ts
GitHub
convex-helpers/convex/rowLevelSecurityExample.ts at main · get-conv...
A collection of useful code to complement the official packages. - get-convex/convex-helpers
Thanks!
And as you're using it, I'd love it if you gave me your take on whether it'd be more convenient to structure your rules like
Sorry for the late reply, I took a break for a bit. After using it a bit I do think the above api would be much easier to understand. Plus I think being forced to always pass true or false for each case makes it much more explicit as to what's happening.
It seems this file has now moved? I found the
wrapdb
branch that includes a helpful example, though not sure if this will be merged into main
? https://github.com/get-convex/convex-helpers/blob/wrapdb/convex/lib/rowLevelSecurity.ts
I like the idea of having one wrapDB
compared to separating out the wrapDatabaseReader
and wrapDatabaseWriter
.GitHub
convex-helpers/convex/lib/rowLevelSecurity.ts at wrapdb · get-conve...
A collection of useful code to complement the official packages. - get-convex/convex-helpers
I'm currently iterating on the API. My current strategy is to change that branch to start with a more RLS-specific version. The plan is still to unify the wrappers so there isn't a *Reader & *Writer.
@adam some example usage of the old ones for now is in
rls.test.ts
sorry about moving them. I'm in part starting to hide away the older syntax to make way for the newer one. I got sidetracked working on work stealing and rate limiting but this is what I'll hopefully be focusing on today / next Tuesday when I'm back from camping.Hey Ian, what's the latest on this?
This is the only example I'm working with:
but I don't even know what
rules
is in this case
Right now I'm doing something like:
where ctx
contains a role, user and access document that is used by the checkPermissionByResource
function. It would be a lot more robust of course if these checks could be done at the ctx.db
level, so I'm wondering what the recommended approach is
The wrapdb
interface example linked above makes sense to me thoughSorry, the types & API ended up having some issues and it got deprioritized. Until I get back to this, I would use the rls that's in convex-helpers currently. Here's a utility to apply rules to a bunch of query/mutations at the same time:
Rules look like
Where
Rules
is imported from convex-helpers/server/rowLevelSecurity
, and looks like
The read rules get applied on modifications automatically, so you don't have to duplicate there.Thanks Ian, will give this a try!
So I should be able to update the rule type to use AuthQueryCtx | AuthMutationCtx instead of Ctx right?
I'd assume so, are you seeing any issues trying it?
The current one is generic to whatver ctx you pass into
wrapDatabaseWriter
. You could pass in something custom like { db, userId }
, you're not constrained to off-the-shelf onesAh right, awesome! I think I should be off to the races now, thanks for the support guys 🙏
can I ask why there's
read
modify
and insert
but no delete
? How can we detect if a document is being updated vs deleted?I don't think you can distinguish it with this version - and I believe the version of
doc
passed in is the existing one. That's one thing I liked about a newer API - have control over what they are allowed to modify things to. But concretely is there something you want to allow editing but not deleting?
And the more I've been actually making apps, RLS just feels like a clunkier level to be describing those rules. Yes it's nice to feel there's a safeguard, but if there's an error it's at too granular a level to return a meaningful error, and you have to get around places where you don't have auth - like scheduled functions. doing a semantic check in a customQuery
like that a user has a certain role or ownership, then just using the DB directly. I feel like RLS was introduced for usecases where you're exposing DB queries to clients directly (where clients could be a browser or another less-trusted service)