Template
1
0

feat: add documentation to access response

This commit is contained in:
2025-09-19 08:45:30 +02:00
parent 74a9426bcc
commit a140780ec3
4 changed files with 76 additions and 162 deletions

View File

@@ -4,12 +4,81 @@ import { Resource } from "./resources.ts";
export function access(principal: Principal) {
return {
/**
* Check if a principal is allowed to perform an action on a resource.
*
* @param resource - Resource which we are validating.
* @param action - Action which we are validating.
*
* @example
*
* await access.isAllowed(
* {
* kind: "document",
* id: "1",
* attr: { owner: "user@example.com" },
* },
* "view"
* ); // => true
*/
isAllowed(resource: Resource, action: string) {
return cerbos.isAllowed({ principal, resource, action });
},
/**
* Check a principal's permissions on a resource.
*
* @param resource - Resource which we are validating.
* @param actions - Actions which we are validating.
*
* @example
*
* const decision = await access.checkResource(
* {
* kind: "document",
* id: "1",
* attr: { owner: "user@example.com" },
* },
* ["view", "edit"],
* );
*
* decision.isAllowed("view"); // => true
*/
checkResource(resource: Resource, actions: string[]) {
return cerbos.checkResource({ principal, resource, actions });
},
/**
* Check a principal's permissions on a set of resources.
*
* @param resources - Resources which we are validating.
*
* @example
*
* const decision = await access.checkResources([
* {
* resource: {
* kind: "document",
* id: "1",
* attr: { owner: "user@example.com" },
* },
* actions: ["view", "edit"],
* },
* {
* resource: {
* kind: "image",
* id: "1",
* attr: { owner: "user@example.com" },
* },
* actions: ["delete"],
* },
* ]);
*
* decision.isAllowed({
* resource: { kind: "document", id: "1" },
* action: "view",
* }); // => true
*/
checkResources(resources: { resource: Resource; actions: string[] }[]) {
return cerbos.checkResources({ principal, resources });
},

View File

@@ -3,7 +3,7 @@ import { ResourceRegistry } from "@valkyr/auth";
export const resources = new ResourceRegistry([
{
kind: "account",
attributes: {},
attr: {},
},
] as const);

View File

@@ -5,7 +5,6 @@
"migrate": "deno run --allow-all .tasks/migrate.ts"
},
"dependencies": {
"@cerbos/grpc": "0.23.1",
"@cerbos/http": "0.23.1",
"@felix/bcrypt": "npm:@jsr/felix__bcrypt@1.0.5",
"@spec/modules": "workspace:*",
@@ -15,7 +14,7 @@
"@std/dotenv": "npm:@jsr/std__dotenv@0.225.5",
"@std/fs": "npm:@jsr/std__fs@1.0.19",
"@std/path": "npm:@jsr/std__path@1.1.2",
"@valkyr/auth": "npm:@jsr/valkyr__auth@2.1.3",
"@valkyr/auth": "npm:@jsr/valkyr__auth@2.1.4",
"@valkyr/event-store": "npm:@jsr/valkyr__event-store@2",
"@valkyr/inverse": "npm:@jsr/valkyr__inverse@1.0.1",
"@valkyr/json-rpc": "npm:@jsr/valkyr__json-rpc@1.1.0",

164
deno.lock generated
View File

@@ -1,7 +1,6 @@
{
"version": "5",
"specifiers": {
"npm:@cerbos/grpc@0.23.1": "0.23.1",
"npm:@cerbos/http@0.23.1": "0.23.1",
"npm:@eslint/js@9.35.0": "9.35.0",
"npm:@jsr/felix__bcrypt@1.0.5": "1.0.5",
@@ -11,7 +10,7 @@
"npm:@jsr/std__fs@1.0.19": "1.0.19",
"npm:@jsr/std__path@1.1.2": "1.1.2",
"npm:@jsr/std__testing@1.0.15": "1.0.15",
"npm:@jsr/valkyr__auth@2.1.3": "2.1.3",
"npm:@jsr/valkyr__auth@2.1.4": "2.1.4",
"npm:@jsr/valkyr__db@2.0.0": "2.0.0",
"npm:@jsr/valkyr__event-emitter@1.0.1": "1.0.1",
"npm:@jsr/valkyr__event-store@2": "2.0.0",
@@ -182,23 +181,12 @@
"@babel/helper-validator-identifier"
]
},
"@bufbuild/protobuf@2.9.0": {
"integrity": "sha512-rnJenoStJ8nvmt9Gzye8nkYd6V22xUAnu4086ER7h1zJ508vStko4pMvDeQ446ilDTFpV5wnoc5YS7XvMwwMqA=="
},
"@cerbos/core@0.24.1": {
"integrity": "sha512-Gt9ETQR3WDVcPlxN+HiGUDtNgWFulwS5ZjBgzJFsdb7e2GCw0tOPE9Ex1qHNZvG/0JHpFWJWIiYaSKyXcp35YQ==",
"dependencies": [
"uuid"
]
},
"@cerbos/grpc@0.23.1": {
"integrity": "sha512-6ve6d9m+hBZ4xZAI6Oc2/TR2RAoy+QE8zmTVNt38MMyif+BJ3T2dD/Lwd5t75+9+pBJCLch5kLz5ZtnbnGoyuw==",
"dependencies": [
"@bufbuild/protobuf",
"@cerbos/core",
"@grpc/grpc-js"
]
},
"@cerbos/http@0.23.1": {
"integrity": "sha512-XzWFS6L7M+oUnjGEFIoQygtlmZy3zOpUobN6spGp1MAaT6GQJMRFK8P8xhY2BQjTIhqYgnoiEFOAULTkbgNIjg==",
"dependencies": [
@@ -390,23 +378,6 @@
"levn"
]
},
"@grpc/grpc-js@1.14.0": {
"integrity": "sha512-N8Jx6PaYzcTRNzirReJCtADVoq4z7+1KQ4E70jTg/koQiMoUSN1kbNjPOqpPbhMFhfU1/l7ixspPl8dNY+FoUg==",
"dependencies": [
"@grpc/proto-loader",
"@js-sdsl/ordered-map"
]
},
"@grpc/proto-loader@0.8.0": {
"integrity": "sha512-rc1hOQtjIWGxcxpb9aHAfLpIctjEnsDehj0DAiVfBlmT84uvR0uUtN2hEi/ecvWVjXUGf5qPF4qEgiLOx1YIMQ==",
"dependencies": [
"lodash.camelcase",
"long",
"protobufjs",
"yargs"
],
"bin": true
},
"@humanfs/core@0.19.1": {
"integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA=="
},
@@ -456,9 +427,6 @@
"@jridgewell/sourcemap-codec"
]
},
"@js-sdsl/ordered-map@4.4.2": {
"integrity": "sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw=="
},
"@jsr/denosaurs__plug@1.1.0": {
"integrity": "sha512-GNRMr8XcYWbv8C1B5OjDa5u8q3p2lz7YVWQLhH5HAy0pkpb0+Y3npSxzjM49v5ajTFIzUCwIKv1gQukPm9q7qw==",
"dependencies": [
@@ -545,13 +513,13 @@
],
"tarball": "https://npm.jsr.io/~/11/@jsr/std__testing/1.0.15.tgz"
},
"@jsr/valkyr__auth@2.1.3": {
"integrity": "sha512-J2r6bfd2IMoVtln/valsagVh9LDBLG2tBzfxBHoi+6NZzA0g3DAHevC2Rf8TTsMDFSiqz3ewUgntBnmMpR9SVA==",
"@jsr/valkyr__auth@2.1.4": {
"integrity": "sha512-z4/OfPJ+7KZKdILrCWMO9nDQgOsLFw0A6HHgV3h7N1DpH1Ok0uRHUNAUA2IbI5KZif8yUPw+wsKztM6pOEMjbg==",
"dependencies": [
"jose",
"zod"
],
"tarball": "https://npm.jsr.io/~/11/@jsr/valkyr__auth/2.1.3.tgz"
"tarball": "https://npm.jsr.io/~/11/@jsr/valkyr__auth/2.1.4.tgz"
},
"@jsr/valkyr__db@2.0.0": {
"integrity": "sha512-0gIauba+vQW6ssqMACLO1Z/METlhzoX+y4t9Sawh/IafQ986Rgvp6gCI+WArp7vbsO5hpItixrqjkxnnNC+h5g==",
@@ -626,40 +594,6 @@
"fastq"
]
},
"@protobufjs/aspromise@1.1.2": {
"integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ=="
},
"@protobufjs/base64@1.1.2": {
"integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg=="
},
"@protobufjs/codegen@2.0.4": {
"integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg=="
},
"@protobufjs/eventemitter@1.1.0": {
"integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q=="
},
"@protobufjs/fetch@1.1.0": {
"integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==",
"dependencies": [
"@protobufjs/aspromise",
"@protobufjs/inquire"
]
},
"@protobufjs/float@1.0.2": {
"integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ=="
},
"@protobufjs/inquire@1.1.0": {
"integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q=="
},
"@protobufjs/path@1.1.2": {
"integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA=="
},
"@protobufjs/pool@1.1.0": {
"integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw=="
},
"@protobufjs/utf8@1.1.0": {
"integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw=="
},
"@rolldown/pluginutils@1.0.0-beta.27": {
"integrity": "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA=="
},
@@ -1153,9 +1087,6 @@
"uri-js"
]
},
"ansi-regex@5.0.1": {
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="
},
"ansi-styles@4.3.0": {
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dependencies": [
@@ -1235,14 +1166,6 @@
"chownr@3.0.0": {
"integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g=="
},
"cliui@8.0.1": {
"integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
"dependencies": [
"string-width",
"strip-ansi",
"wrap-ansi"
]
},
"clsx@2.1.1": {
"integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="
},
@@ -1301,9 +1224,6 @@
"electron-to-chromium@1.5.222": {
"integrity": "sha512-gA7psSwSwQRE60CEoLz6JBCQPIxNeuzB2nL8vE03GK/OHxlvykbLyeiumQy1iH5C2f3YbRAZpGCMT12a/9ih9w=="
},
"emoji-regex@8.0.0": {
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
},
"enhanced-resolve@5.18.3": {
"integrity": "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==",
"dependencies": [
@@ -1540,9 +1460,6 @@
"gensync@1.0.0-beta.2": {
"integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg=="
},
"get-caller-file@2.0.5": {
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="
},
"get-intrinsic@1.3.0": {
"integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
"dependencies": [
@@ -1632,9 +1549,6 @@
"is-extglob@2.1.1": {
"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="
},
"is-fullwidth-code-point@3.0.0": {
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
},
"is-glob@4.0.3": {
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
"dependencies": [
@@ -1771,15 +1685,9 @@
"p-locate"
]
},
"lodash.camelcase@4.3.0": {
"integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA=="
},
"lodash.merge@4.6.2": {
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="
},
"long@5.3.2": {
"integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA=="
},
"lru-cache@5.1.1": {
"integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
"dependencies": [
@@ -1932,24 +1840,6 @@
"integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==",
"bin": true
},
"protobufjs@7.5.4": {
"integrity": "sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg==",
"dependencies": [
"@protobufjs/aspromise",
"@protobufjs/base64",
"@protobufjs/codegen",
"@protobufjs/eventemitter",
"@protobufjs/fetch",
"@protobufjs/float",
"@protobufjs/inquire",
"@protobufjs/path",
"@protobufjs/pool",
"@protobufjs/utf8",
"@types/node",
"long"
],
"scripts": true
},
"punycode@2.3.1": {
"integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="
},
@@ -1975,9 +1865,6 @@
"react@19.1.1": {
"integrity": "sha512-w8nqGImo45dmMIfljjMwOGtbmC/mk4CMYhWIicdSflH91J9TyCyczcPFXJzrZ/ZXcgGRFeP6BU0BEJTw6tZdfQ=="
},
"require-directory@2.1.1": {
"integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="
},
"resolve-from@4.0.0": {
"integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="
},
@@ -2109,20 +1996,6 @@
"memory-pager"
]
},
"string-width@4.2.3": {
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
"dependencies": [
"emoji-regex",
"is-fullwidth-code-point",
"strip-ansi"
]
},
"strip-ansi@6.0.1": {
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
"dependencies": [
"ansi-regex"
]
},
"strip-json-comments@3.1.1": {
"integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="
},
@@ -2286,38 +2159,12 @@
"word-wrap@1.2.5": {
"integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA=="
},
"wrap-ansi@7.0.0": {
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
"dependencies": [
"ansi-styles",
"string-width",
"strip-ansi"
]
},
"y18n@5.0.8": {
"integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="
},
"yallist@3.1.1": {
"integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="
},
"yallist@5.0.0": {
"integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw=="
},
"yargs-parser@21.1.1": {
"integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="
},
"yargs@17.7.2": {
"integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
"dependencies": [
"cliui",
"escalade",
"get-caller-file",
"require-directory",
"string-width",
"y18n",
"yargs-parser"
]
},
"yocto-queue@0.1.0": {
"integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="
},
@@ -2340,14 +2187,13 @@
"api": {
"packageJson": {
"dependencies": [
"npm:@cerbos/grpc@0.23.1",
"npm:@cerbos/http@0.23.1",
"npm:@jsr/felix__bcrypt@1.0.5",
"npm:@jsr/std__cli@1.0.22",
"npm:@jsr/std__dotenv@0.225.5",
"npm:@jsr/std__fs@1.0.19",
"npm:@jsr/std__path@1.1.2",
"npm:@jsr/valkyr__auth@2.1.3",
"npm:@jsr/valkyr__auth@2.1.4",
"npm:@jsr/valkyr__event-store@2",
"npm:@jsr/valkyr__inverse@1.0.1",
"npm:@jsr/valkyr__json-rpc@1.1.0",