amosbastian / template

A Next.js 13 application with authentication and payments, built with PlanetScale, Drizzle ORM, Lucia, Tailwind and LemonSqueezy
MIT License
250 stars 19 forks source link

a question on the Kind field #2

Open orenmizr opened 11 months ago

orenmizr commented 11 months ago

i see you added kind: "Team" and more to the type with partial Db entity. but the actual entity has no kind when save. when do you inject that field ? i assume after retrieve from db but could not see that line

amosbastian commented 11 months ago

It is just used for authorisation, so e.g. you'd do something like

const ability = await defineAbilityFor({ userId: user.id, teamId: user.activeTeamId });
const canUpdateTeam = ability.can("update", { kind: "Team" })

and it will return true or false depending on if the user is allowed to

orenmizr commented 11 months ago

i read this like so: update if the condition (user has kind in the object is true). the missing part for me is there is no kind in the schema which i get it as it bloats the db... and when extracted from the db, i could not see where you enrich the user/team data with an extra field of kind: user/team so the ability can read...

amosbastian commented 11 months ago

It isn't needed to have a kind field in the database. I'd recommend reading the documentation I linked to above, as it should make it more clear. This code

function defineMemberRules({ can }: AbilityBuilder<AppAbility>, user: NonNullable<Member>) {
  // Team
  can(["create"], "Team");

  // User
  can("update", "User", { id: { $eq: user.id } });
}

defines what a normal member can do, for example.

Since there is no can(["update"], "Team"); canUpdateTeam in my comment above will return false (for more information see authorisation.ts) if the user for the given userId has the role "member"

orenmizr commented 11 months ago

i've read the docs. i understood since we're not using classes we need a way to mark an object as "team" or "user"

we have 2 options:

  1. push a kind field to the object we want to test ability
  2. use subject helper

my thinking: once you select a user from db - you enrich it with a casl kind field or use subject. i only saw the kind in the type but not on the user object. so i thought "what am i missing here"