Toegang en identiteit
Breng identiteit mee. Bepaal toegang.
Section titled “Breng identiteit mee. Bepaal toegang.”De Worker verifieert kortlevende, ondertekende workspace-claims. Je applicatie implementeert de identity-adapter die het ingelogde subject en diens workspacerol bepaalt. Productie weigert de development-claimroute.
Elke actie van een model neemt één van drie beslissingen:
| Regel | Doel |
|---|---|
role(...) |
Vereist een minimumrol voordat SQL draait. |
filter(...) |
Past een leesregel toe binnen SQL-queries en counts. |
check(...) |
Beoordeelt een rij of schrijfactie met applicatielogica. |
board: model({ name: t.string(), ownerId: t.string().index(),}).access({ read: filter(({ auth }) => ({ ownerId: auth.sub })), update: check(({ auth, row }) => row?.ownerId === auth.sub), delete: role("moderator"),}),Defaults: lezen member, create/update editor, delete moderator.
filter(({ auth }) => where)is alleen voorread. Het wordt in de SQL van elke query gecompileerd die het model raakt, dus het gebruikt indexen, vult elke pagina en telt correct. Een array is OR; het filter van de caller ANDt ermee.check()werkt voor elke actie. Het ontvangt{ auth, row, data, changed }en geeft een boolean terug. Schrijfchecks draaien binnen de transactie naast de schrijfactie die ze bewaken. Bijreadscannen ze overeenkomende rijen tot de pagina vol is of de resultaatset uitgeput is. Counts passen dezelfde zichtbaarheidsregel toe.- Een regel die een fout gooit, weigert de toegang.
Geef SQL-filters de voorkeur voor leeszichtbaarheid, omdat een leescheck op basis van een functie na het ophalen draait.
Claims en identiteit
Section titled “Claims en identiteit”De engine verifieert een claim en geeft er nooit een uit. Implementeer twee methoden en de library serveert de claimroute:
import { defineTapeDB, WORKSPACE_ROLE_LEVELS } from "tapedb/worker";import schema from "./tapedb.schema";import { migrations } from "./tapedb/migrations.gen";
const tapedb = defineTapeDB({ schema, migrations, identity: { async getSubject(headers) { const session = await auth.api.getSession({ headers }); return session ? { sub: session.user.id } : null; }, async getRole(workspaceId, sub) { const member = await memberships.get(workspaceId, sub); return member ? WORKSPACE_ROLE_LEVELS[member.role] : null; }, },});
export const WorkspaceRoom = tapedb.WorkspaceRoom;export default tapedb.worker;POST /_tapedb/claim geeft { token, workspaceId, roleLevel, expiresAt } terug. De client stuurt het als Authorization: Bearer <token> en verlengt het bij een reconnect. In development zet tapedb dev een dev-claimroute aan, zodat de client helemaal geen sessie nodig heeft; ENVIRONMENT=production weigert die route, en tapedb deploy weigert de flag te versturen.
Schemawijzigingen en hun SQL-migraties staan in Migraties.