permdock 0.0.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +327 -1
- package/dist/a2a/index.d.ts +169 -0
- package/dist/a2a/index.js +232 -0
- package/dist/adapter-context-mlWsVGGg.js +23 -0
- package/dist/ai-sdk/index.d.ts +95 -0
- package/dist/ai-sdk/index.js +154 -0
- package/dist/approval-required-TzNB9oQA.js +6 -0
- package/dist/approvals/index.d.ts +3 -0
- package/dist/approvals/index.js +5 -0
- package/dist/approvals-DbYAuNkG.js +224 -0
- package/dist/approvers-DT4AVyIg.js +52 -0
- package/dist/arazzo-BAgw9ap6.js +70 -0
- package/dist/arazzo-cmvX2jDe.js +54 -0
- package/dist/authzen/index.d.ts +39 -0
- package/dist/authzen/index.js +302 -0
- package/dist/better-auth/index.d.ts +109 -0
- package/dist/better-auth/index.js +344 -0
- package/dist/better-supabase/index.d.ts +206 -0
- package/dist/better-supabase/index.js +620 -0
- package/dist/bind-CVy3Espv.d.ts +25 -0
- package/dist/bind-VnYn2HKq.js +97 -0
- package/dist/boundary-BM8a_P6E.js +13 -0
- package/dist/boundary-BmHxVH1J.d.ts +15 -0
- package/dist/budget-JqcRqyhK.d.ts +11 -0
- package/dist/budget-NbEtbJC_.js +11 -0
- package/dist/canonical-json-DemiK4Vp.js +26 -0
- package/dist/capability-4qPdO9gk.js +173 -0
- package/dist/capability-Dq43tT1u.d.ts +99 -0
- package/dist/catalog/index.d.ts +12 -0
- package/dist/catalog/index.js +2 -0
- package/dist/catalog-BjZSovXQ.js +2 -0
- package/dist/catalog-doc-Dsc9y7sd.js +309 -0
- package/dist/catalog-h2tlKFkq.js +48 -0
- package/dist/catalog-path-CnI0XTFK.js +12 -0
- package/dist/catalog-z8q6bi_r.js +55 -0
- package/dist/claude-agent/index.d.ts +72 -0
- package/dist/claude-agent/index.js +77 -0
- package/dist/clerk/index.d.ts +65 -0
- package/dist/clerk/index.js +301 -0
- package/dist/cli/bin.d.ts +1 -0
- package/dist/cli/bin.js +20 -0
- package/dist/cli/index.d.ts +46 -0
- package/dist/cli/index.js +5 -0
- package/dist/clients-C7zLFuWT.d.ts +12 -0
- package/dist/clients-DjU5ABMy.js +23 -0
- package/dist/cloud/index.d.ts +90 -0
- package/dist/cloud/index.js +404 -0
- package/dist/cloud-BGhHS-lY.js +50 -0
- package/dist/cloud-Bo3e9Ak3.js +118 -0
- package/dist/collect-DDDv_ESs.js +502 -0
- package/dist/collect-DLlujdHC.js +83 -0
- package/dist/collect-rG2IQ3t0.js +2 -0
- package/dist/commands-DWOrSQic.js +97 -0
- package/dist/compact-y6vfu2_f.js +19 -0
- package/dist/compare-pfyVnBjE.js +12 -0
- package/dist/compile/index.d.ts +3 -0
- package/dist/compile/index.js +2 -0
- package/dist/compile-Ba4blROR.js +613 -0
- package/dist/compile-CNnl6uIt.d.ts +94 -0
- package/dist/config-BJiM-xAm.js +157 -0
- package/dist/config-Bn00Z3ks.js +36 -0
- package/dist/config-report-Dw_JcUqT.js +44 -0
- package/dist/connection-CU8MQxRi.js +194 -0
- package/dist/context-Ttp0ekMT.js +82 -0
- package/dist/convex/index.d.ts +45 -0
- package/dist/convex/index.js +65 -0
- package/dist/create-BWyx3jua.d.ts +245 -0
- package/dist/create-CPhDL6qx.js +253 -0
- package/dist/credential-8P81ff4u.js +306 -0
- package/dist/delegation-D8pUEuce.js +103 -0
- package/dist/describe-B_gVZEVi.js +94 -0
- package/dist/describe-PdoqESvg.d.ts +36 -0
- package/dist/diff-B8Tunc3o.js +451 -0
- package/dist/diff-CzqLxZ77.js +48 -0
- package/dist/digest-B3kc_PgQ.d.ts +19 -0
- package/dist/digest-BI-6aa6d.js +27 -0
- package/dist/doctor-WpvG6p4k.js +1194 -0
- package/dist/doctor-collect-ByfYlNv1.js +664 -0
- package/dist/doctor-rOr-4ZfS.js +53 -0
- package/dist/drizzle/index.d.ts +73 -0
- package/dist/drizzle/index.js +160 -0
- package/dist/duration-xK2jGFVc.js +25 -0
- package/dist/elysia/index.d.ts +49 -0
- package/dist/elysia/index.js +59 -0
- package/dist/errors-CWfoNg9N.js +47 -0
- package/dist/errors-Cz5zn0mW.js +123 -0
- package/dist/errors-DAqevpNk.d.ts +125 -0
- package/dist/errors-DRnGZHzF.js +30 -0
- package/dist/evaluation-items-CfCCejQd.js +40 -0
- package/dist/evaluations-tz6D9A2G.js +461 -0
- package/dist/eve/index.d.ts +86 -0
- package/dist/eve/index.js +176 -0
- package/dist/expiry-BoBJ8Tvc.js +7 -0
- package/dist/express/index.d.ts +23 -0
- package/dist/express/index.js +78 -0
- package/dist/fastify/index.d.ts +33 -0
- package/dist/fastify/index.js +92 -0
- package/dist/fields-BMl1RxoX.js +26 -0
- package/dist/files-DWUN9PzI.js +125 -0
- package/dist/fixtures-ht28Cplr.js +67 -0
- package/dist/freeze-CrU8nQeX.js +60 -0
- package/dist/from-snapshot-C3sHpZNS.js +569 -0
- package/dist/generate-CH7ThJ14.js +173 -0
- package/dist/grantee-Cv5Sogfv.js +602 -0
- package/dist/graph-sql-B-dsAT6j.d.ts +29 -0
- package/dist/headers-BZSDieNT.js +6 -0
- package/dist/headers-Cf-zWvsO.d.ts +6 -0
- package/dist/helpers-H_KARDVC.js +421 -0
- package/dist/hono/index.d.ts +48 -0
- package/dist/hono/index.js +99 -0
- package/dist/hosted-DJQw46hn.js +266 -0
- package/dist/http-BIhmLfCc.js +95 -0
- package/dist/http-DPuDaChb.d.ts +13 -0
- package/dist/http-SO7qGttf.js +44 -0
- package/dist/ids-DC4V4CFu.js +18 -0
- package/dist/index-A0YNL8jZ.d.ts +177 -0
- package/dist/index-CtE07CBF.d.ts +6 -0
- package/dist/index-D3vbkoSI.d.ts +483 -0
- package/dist/index-D6_cSa1z.d.ts +201 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.js +26 -0
- package/dist/instance-options-BK_rNOSC.d.ts +11 -0
- package/dist/instance-options-Dhhcnm3y.js +22 -0
- package/dist/json-schema-BsAflUGW.js +106 -0
- package/dist/jwt/index.d.ts +91 -0
- package/dist/jwt/index.js +590 -0
- package/dist/kernel-GSQnMz3O.js +208 -0
- package/dist/kysely/index.d.ts +78 -0
- package/dist/kysely/index.js +129 -0
- package/dist/live-options-H2eG8dfJ.js +60 -0
- package/dist/load-DhWEB9P1.js +75 -0
- package/dist/load-DwJUafYN.js +2 -0
- package/dist/load-jose-BL6LH4bL.js +11 -0
- package/dist/lru-8q4WZjBV.js +28 -0
- package/dist/manifest-iaoBXHKc.js +783 -0
- package/dist/manifest-uDS9y5de.d.ts +206 -0
- package/dist/map-AcxK9o_D.js +147 -0
- package/dist/map-claims-Z4QZOiFF.js +369 -0
- package/dist/map-error-pgUWNNtG.js +23 -0
- package/dist/markers-B0hYLvMD.js +60 -0
- package/dist/may-use-DndQ5tQ-.js +77 -0
- package/dist/mcp/index.d.ts +159 -0
- package/dist/mcp/index.js +603 -0
- package/dist/nest/index.d.ts +75 -0
- package/dist/nest/index.js +261 -0
- package/dist/next/client.d.ts +23 -0
- package/dist/next/client.js +33 -0
- package/dist/next/index.d.ts +93 -0
- package/dist/next/index.js +180 -0
- package/dist/next/plugin.d.ts +14 -0
- package/dist/next/plugin.js +33 -0
- package/dist/node/index.d.ts +24 -0
- package/dist/node/index.js +34 -0
- package/dist/openai/index.d.ts +62 -0
- package/dist/openai/index.js +92 -0
- package/dist/openapi/index.d.ts +176 -0
- package/dist/openapi/index.js +3 -0
- package/dist/openapi-Bbg4wGVL.js +164 -0
- package/dist/openapi-BqRBvAng.js +538 -0
- package/dist/openapi-CqqEbHsL.js +250 -0
- package/dist/openapi-import-cmwetbzw.js +5959 -0
- package/dist/openapi-schema--ARjyfQr.js +6902 -0
- package/dist/orpc/index.d.ts +51 -0
- package/dist/orpc/index.js +145 -0
- package/dist/otel/index.d.ts +13 -0
- package/dist/otel/index.js +202 -0
- package/dist/package-root-zGkxO3oN.js +30 -0
- package/dist/parse-BuyjxhZV.js +53 -0
- package/dist/parse-local-manifest-BkGQNzAh.d.ts +10 -0
- package/dist/parse-local-manifest-BrMozJCo.js +36 -0
- package/dist/pdp/index.d.ts +22 -0
- package/dist/pdp/index.js +682 -0
- package/dist/peer-BOr_kJE1.js +31 -0
- package/dist/permdock-CzqXjCpU.js +3471 -0
- package/dist/permissions-CDgvKG5L.d.ts +52 -0
- package/dist/permissions-CpZrivYv.js +142 -0
- package/dist/permissions-DVoF6dMt.js +662 -0
- package/dist/permissions-DttnqqxC.d.ts +214 -0
- package/dist/pins-8ILTftC9.js +12 -0
- package/dist/policy-CFZAr_Al.d.ts +2252 -0
- package/dist/policy-D8UFyERw.d.ts +20 -0
- package/dist/policy-xyWg7QdR.js +1122 -0
- package/dist/powersync-A8x_Yyvh.js +2 -0
- package/dist/powersync-C7kLglqX.js +540 -0
- package/dist/powersync-yW1UUFzp.js +62 -0
- package/dist/prisma/index.d.ts +136 -0
- package/dist/prisma/index.js +455 -0
- package/dist/problem-B43ztKIm.js +191 -0
- package/dist/problem-details-CkL50EEf.d.ts +7 -0
- package/dist/problem-details-_AMOYz-w.js +144 -0
- package/dist/prompt-CXYhLfsS.js +32 -0
- package/dist/protected-CNsMzrVd.d.ts +27 -0
- package/dist/protected-Cs6kTaHo.js +100 -0
- package/dist/protected-bZs6rbT1.d.ts +40 -0
- package/dist/provider-Cjr62YMV.d.ts +6 -0
- package/dist/provider-DLzpb2Xz.js +52 -0
- package/dist/provider-store-DNyC1y48.js +43 -0
- package/dist/react/index.d.ts +8 -0
- package/dist/react/index.js +7 -0
- package/dist/react/provider-client.d.ts +2 -0
- package/dist/react/provider-client.js +3 -0
- package/dist/react-native/index.d.ts +198 -0
- package/dist/react-native/index.js +696 -0
- package/dist/refs-KYb4ntaz.js +91 -0
- package/dist/relations-cjOL01hZ.js +505 -0
- package/dist/replay-BsOyTrdV.js +28 -0
- package/dist/replay-sqBGMnNs.d.ts +5 -0
- package/dist/resource-ref-CaS9yVPi.js +20 -0
- package/dist/revocations-Bhr0aMIC.js +27 -0
- package/dist/revocations-Cy06JNx2.d.ts +21 -0
- package/dist/rls-BMNydpHk.js +2521 -0
- package/dist/rls-CEvs64Kj.js +238 -0
- package/dist/rls-fields-BMasREhR.js +3502 -0
- package/dist/rls-graph-pc9fuXYm.js +435 -0
- package/dist/rls-import-D8F7j35Q.js +943 -0
- package/dist/rls-migrate-7wikfrVI.js +367 -0
- package/dist/rls-ownership-B5Lkq62W.js +843 -0
- package/dist/rls-shared-aOQ4hGTO.js +493 -0
- package/dist/rls-verify-D8B7dOTh.js +745 -0
- package/dist/row-check-Dt35czLy.d.ts +40 -0
- package/dist/rpc-DOK54_CS.js +89 -0
- package/dist/run-YXCJDNYk.js +174 -0
- package/dist/runtime-CB8gQFvS.js +11 -0
- package/dist/saas-Bj_FFkjN.js +1203 -0
- package/dist/schema-D3MnDMxa.js +300 -0
- package/dist/scim/index.d.ts +2 -0
- package/dist/scim/index.js +2 -0
- package/dist/scim-BFGBBAqR.js +1445 -0
- package/dist/scopes-CVdPrWN-.js +239 -0
- package/dist/server/index.d.ts +134 -0
- package/dist/server/index.js +11 -0
- package/dist/server-DlZ28Oz5.js +268 -0
- package/dist/sha256-BO0swRXL.js +150 -0
- package/dist/shared-DRu8VFVM.js +123 -0
- package/dist/sink-Bd9PSyfq.js +141 -0
- package/dist/sink-Gs6TTVa-.d.ts +104 -0
- package/dist/skills-Biq5uup3.js +192 -0
- package/dist/skills-JaymNCdK.js +56 -0
- package/dist/snapshot-Enxd0n-s.js +975 -0
- package/dist/snapshot-cache-D6jLelln.js +44 -0
- package/dist/snapshot-cache-DwQH8ufx.d.ts +45 -0
- package/dist/solid/index.d.ts +93 -0
- package/dist/solid/index.js +188 -0
- package/dist/sources-B0UvrJ21.js +534 -0
- package/dist/sources-BcJgw0lt.d.ts +192 -0
- package/dist/sql-xdg5f4Fi.js +27 -0
- package/dist/src-CSbUiozF.js +568 -0
- package/dist/ssf/index.d.ts +4 -0
- package/dist/ssf/index.js +596 -0
- package/dist/store-DMAWwAJV.js +371 -0
- package/dist/store-D_pjn91-.d.ts +36 -0
- package/dist/store-options-yO0V6gRn.js +716 -0
- package/dist/stores-4_sqiOA1.js +87 -0
- package/dist/stores-DVR5NHLE.d.ts +52 -0
- package/dist/stream-DDpvynSB.js +66 -0
- package/dist/stream-DlvG2hs-.d.ts +12 -0
- package/dist/style-CTm1AXDT.js +22 -0
- package/dist/subject-C6dLxqHU.js +24 -0
- package/dist/subject-settings-BwBmCdTR.js +128 -0
- package/dist/supabase/index.d.ts +183 -0
- package/dist/supabase/index.js +5 -0
- package/dist/supabase/middleware.d.ts +82 -0
- package/dist/supabase/middleware.js +102 -0
- package/dist/supabase-CwafwxxF.js +83 -0
- package/dist/supabase-DTBaC20O.js +774 -0
- package/dist/supabase-config-Bs44dare.js +472 -0
- package/dist/supabase-hook-BuxLQLpU.js +1814 -0
- package/dist/supabase-hook-D5qVd_D8.js +2 -0
- package/dist/supautils-DYZnzRWV.js +91 -0
- package/dist/svelte/PermissionBoundary.svelte +37 -0
- package/dist/svelte/Protected.svelte +40 -0
- package/dist/svelte/index.d.ts +13 -0
- package/dist/svelte/index.js +107 -0
- package/dist/svelte/runtime.d.ts +7 -0
- package/dist/svelte/runtime.js +4 -0
- package/dist/svelte/source.d.ts +13 -0
- package/dist/svelte/source.js +11 -0
- package/dist/terminal/index.d.ts +163 -0
- package/dist/terminal/index.js +833 -0
- package/dist/testing/index.d.ts +745 -0
- package/dist/testing/index.js +3672 -0
- package/dist/testing/saas/index.d.ts +194 -0
- package/dist/testing/saas/index.js +3 -0
- package/dist/testing/saas/permissions.d.ts +2 -0
- package/dist/testing/saas/permissions.js +2 -0
- package/dist/text-diff-BdkkYSbi.js +15 -0
- package/dist/thenable-okc2xDsj.js +10 -0
- package/dist/timeout-D51niuQP.js +8 -0
- package/dist/token-CIWxJOCh.js +50 -0
- package/dist/trpc/index.d.ts +61 -0
- package/dist/trpc/index.js +122 -0
- package/dist/types-9AWO9EGt.d.ts +197 -0
- package/dist/types-BPxgszlT.d.ts +550 -0
- package/dist/types-BVyImy5I.d.ts +120 -0
- package/dist/types-Bvc4oWT6.d.ts +9 -0
- package/dist/types-C3s9xVJG.d.ts +48 -0
- package/dist/types-Dnemwd77.d.ts +183 -0
- package/dist/types-kxznc7cn.d.ts +52 -0
- package/dist/types-vKyAMtcX.d.ts +157 -0
- package/dist/types-vNSDF7Dq.d.ts +66 -0
- package/dist/types-yF5LmQVD.d.ts +306 -0
- package/dist/unplugin/index.d.ts +7 -0
- package/dist/unplugin/index.js +31 -0
- package/dist/usage-D07N9QJ3.js +42 -0
- package/dist/usage-D82l1CwK.js +2 -0
- package/dist/usage-DG1oeCca.js +693 -0
- package/dist/validation-error-CnjZ4t92.js +33 -0
- package/dist/validation-error-CtF23SrC.d.ts +26 -0
- package/dist/validity-uOp8UpYn.js +245 -0
- package/dist/verifier-BxBo6I44.js +466 -0
- package/dist/version-BvacVTZR.js +17 -0
- package/dist/views-Soe7bGSC.js +95 -0
- package/dist/vocabulary-DA8a8zif.d.ts +56 -0
- package/dist/vue/index.d.ts +79 -0
- package/dist/vue/index.js +196 -0
- package/dist/watch-Etoa_Mvr.js +2 -0
- package/dist/watch-UihESpsJ.js +128 -0
- package/dist/webmcp/index.d.ts +75 -0
- package/dist/webmcp/index.js +307 -0
- package/package.json +450 -5
- package/rulesets/permdock.yaml +29 -0
- package/schemas/approval-request-v1.json +175 -0
- package/schemas/catalog-v1.json +535 -0
- package/schemas/openapi/oas-3.1.json +1298 -0
- package/schemas/openapi/oas-3.2.json +1516 -0
- package/schemas/openapi/overlay-1.1.json +79 -0
- package/schemas/supabase-claims-v1.json +144 -0
- package/schemas/supabase-manifest-v1.json +361 -0
- package/skills/permdock/SKILL.md +66 -0
- package/skills/permdock-agents/SKILL.md +77 -0
- package/skills/permdock-agents/references/runtimes.md +213 -0
- package/skills/permdock-approvals/SKILL.md +80 -0
- package/skills/permdock-approvals/references/stores-and-resume.md +94 -0
- package/skills/permdock-audit/SKILL.md +67 -0
- package/skills/permdock-credentials/SKILL.md +55 -0
- package/skills/permdock-credentials/references/tokens-keys-links.md +132 -0
- package/skills/permdock-data/SKILL.md +57 -0
- package/skills/permdock-data/references/queries-and-rls.md +62 -0
- package/skills/permdock-data/references/relationships.md +67 -0
- package/skills/permdock-tenancy/SKILL.md +80 -0
- package/skills/permdock-tenancy/references/ownership-and-custom-roles.md +89 -0
- package/skills/permdock-wire/SKILL.md +116 -0
- package/skills/permdock-wire/references/adapters.md +492 -0
- package/skills/permdock-wire/references/policy-options.md +45 -0
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
import { t as compact } from "./compact-y6vfu2_f.js";
|
|
2
|
+
import { n as freezeDeep } from "./freeze-CrU8nQeX.js";
|
|
3
|
+
import { T as isForbiddenKey, c as getResource, g as isSelfParented, i as findPermission, k as splitPath } from "./permissions-DVoF6dMt.js";
|
|
4
|
+
import { c as indexPolicy, i as declaredRoleNames, m as role, o as deny, r as completeGrant, t as allow, v as normalizeWhere } from "./policy-xyWg7QdR.js";
|
|
5
|
+
import { t as parseDuration } from "./duration-xK2jGFVc.js";
|
|
6
|
+
import { S as findRole, T as listPlans, s as flattenGrantee } from "./grantee-Cv5Sogfv.js";
|
|
7
|
+
import { n as sha256, t as bytesToBase64Url } from "./sha256-BO0swRXL.js";
|
|
8
|
+
//#region src/core/hosted.ts
|
|
9
|
+
function memoryPolicySource(document = null) {
|
|
10
|
+
const current = document === null ? null : parsePolicyDocument(document);
|
|
11
|
+
return Object.freeze({
|
|
12
|
+
current: () => current,
|
|
13
|
+
refresh: () => Promise.resolve()
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
function isRecord(value) {
|
|
17
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
18
|
+
}
|
|
19
|
+
function rejectUnsafe(value) {
|
|
20
|
+
if (value === null || typeof value !== "object") return;
|
|
21
|
+
if (Array.isArray(value)) {
|
|
22
|
+
for (const item of value) rejectUnsafe(item);
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
for (const key of Object.keys(value)) {
|
|
26
|
+
if (isForbiddenKey(key)) throw new Error(`PermDock: unsafe policy document key '${key}'`);
|
|
27
|
+
rejectUnsafe(value[key]);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/** Validates the document envelope; per-grant checks happen at merge time. */
|
|
31
|
+
function parsePolicyDocument(json) {
|
|
32
|
+
const input = typeof json === "string" ? JSON.parse(json) : json;
|
|
33
|
+
if (!isRecord(input)) throw new TypeError("PermDock: policy document must be an object");
|
|
34
|
+
const copy = JSON.parse(JSON.stringify(input));
|
|
35
|
+
rejectUnsafe(copy);
|
|
36
|
+
if (copy["v"] !== 1) throw new Error(`PermDock: unsupported policy document version '${String(copy["v"])}'`);
|
|
37
|
+
if (typeof copy["id"] !== "string" || typeof copy["fingerprint"] !== "string" || typeof copy["catalog"] !== "string" || typeof copy["issuedAt"] !== "number" || !Array.isArray(copy["grants"])) throw new TypeError("PermDock: malformed policy document");
|
|
38
|
+
return freezeDeep(copy);
|
|
39
|
+
}
|
|
40
|
+
const COMPARISONS = /* @__PURE__ */ new Set([
|
|
41
|
+
"eq",
|
|
42
|
+
"ne",
|
|
43
|
+
"gt",
|
|
44
|
+
"gte",
|
|
45
|
+
"lt",
|
|
46
|
+
"lte",
|
|
47
|
+
"contains"
|
|
48
|
+
]);
|
|
49
|
+
function safePath(path) {
|
|
50
|
+
if (typeof path !== "string" || path.length === 0) return false;
|
|
51
|
+
return splitPath(path).every((segment) => !isForbiddenKey(segment));
|
|
52
|
+
}
|
|
53
|
+
function portableValue(value) {
|
|
54
|
+
if (value === null || typeof value === "string" || typeof value === "boolean" || typeof value === "number" && Number.isFinite(value)) return true;
|
|
55
|
+
if (Array.isArray(value)) return value.every(portableValue);
|
|
56
|
+
if (!isRecord(value)) return false;
|
|
57
|
+
const keys = Object.keys(value);
|
|
58
|
+
if (keys.length !== 1) return false;
|
|
59
|
+
if (keys[0] === "ref") return safePath(value["ref"]);
|
|
60
|
+
return keys[0] === "date" && typeof value["date"] === "string";
|
|
61
|
+
}
|
|
62
|
+
/** True for the portable subset only: no `opaque`, no `sqlFunction`, no unknown op. */
|
|
63
|
+
function isPortableCondition(value) {
|
|
64
|
+
if (!isRecord(value) || typeof value["op"] !== "string") return false;
|
|
65
|
+
const op = value["op"];
|
|
66
|
+
if (COMPARISONS.has(op)) return safePath(value["field"]) && portableValue(value["value"]);
|
|
67
|
+
switch (op) {
|
|
68
|
+
case "in":
|
|
69
|
+
case "notIn": return safePath(value["field"]) && (Array.isArray(value["value"]) || isRecord(value["value"])) && portableValue(value["value"]);
|
|
70
|
+
case "isNull": return safePath(value["field"]) && typeof value["value"] === "boolean";
|
|
71
|
+
case "and":
|
|
72
|
+
case "or": return Array.isArray(value["conditions"]) && value["conditions"].every(isPortableCondition);
|
|
73
|
+
case "not": return isPortableCondition(value["condition"]);
|
|
74
|
+
case "memberOf": return (value["scope"] === "tenant" || value["scope"] === "team" || value["scope"] === "resource") && safePath(value["field"]) && Array.isArray(value["roles"]) && value["roles"].every((item) => typeof item === "string") && (value["resource"] === void 0 || typeof value["resource"] === "string") && (value["parents"] === void 0 || Array.isArray(value["parents"]) && value["parents"].every((parent) => safePath(parent) || isRecord(parent) && safePath(parent["field"]) && typeof parent["resource"] === "string"));
|
|
75
|
+
default: return false;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
function approvalRank(approval) {
|
|
79
|
+
if (approval === void 0) return;
|
|
80
|
+
if (approval === "human") return {
|
|
81
|
+
distinct: true,
|
|
82
|
+
stale: false,
|
|
83
|
+
quorum: 1,
|
|
84
|
+
ttl: Number.POSITIVE_INFINITY,
|
|
85
|
+
escalates: false
|
|
86
|
+
};
|
|
87
|
+
return {
|
|
88
|
+
by: approval.stages === void 0 ? JSON.stringify(approval.by) : JSON.stringify([approval.mode, approval.stages]),
|
|
89
|
+
distinct: approval.distinct !== false,
|
|
90
|
+
stale: approval.staleOn === "resource-change",
|
|
91
|
+
quorum: approval.quorum ?? 1,
|
|
92
|
+
ttl: parseDuration(approval.ttl) ?? Number.POSITIVE_INFINITY,
|
|
93
|
+
escalates: approval.escalation !== void 0
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
/** A hosted approval must meet every approval a code allow requires on the permission. */
|
|
97
|
+
function approvalAtLeast(hosted, code) {
|
|
98
|
+
const mine = approvalRank(hosted);
|
|
99
|
+
for (const required of code) {
|
|
100
|
+
const theirs = approvalRank(required);
|
|
101
|
+
if (theirs === void 0) continue;
|
|
102
|
+
if (mine === void 0) return false;
|
|
103
|
+
if (theirs.distinct && !mine.distinct) return false;
|
|
104
|
+
if (theirs.stale && !mine.stale) return false;
|
|
105
|
+
if (theirs.by !== void 0 && mine.by !== theirs.by) return false;
|
|
106
|
+
if (mine.quorum < theirs.quorum || mine.ttl > theirs.ttl) return false;
|
|
107
|
+
if (mine.escalates && !theirs.escalates) return false;
|
|
108
|
+
}
|
|
109
|
+
return true;
|
|
110
|
+
}
|
|
111
|
+
/** A grantee kind this build does not know is never declared, so the hosted grant is dropped. */
|
|
112
|
+
function undeclaredKind(_grantee) {
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
function declaredGrantee(policy, grantee, permissionResource) {
|
|
116
|
+
switch (grantee.kind) {
|
|
117
|
+
case "role": return declaredRoleNames(policy).has(grantee.role);
|
|
118
|
+
case "plan": return listPlans(policy.vocabulary.plans).some((leaf) => leaf.key === grantee.plan);
|
|
119
|
+
case "relation": return grantee.resource === permissionResource && getResource(policy.permissions, grantee.resource)?.relations[grantee.relation] !== void 0 && (grantee.through === void 0 || grantee.through === "parent" && isSelfParented(getResource(policy.permissions, grantee.resource))) && (grantee.depth === void 0 || grantee.through === "parent" && Number.isInteger(grantee.depth) && grantee.depth >= 0 && grantee.depth <= 32);
|
|
120
|
+
case "anyone":
|
|
121
|
+
case "authenticated":
|
|
122
|
+
case "actor":
|
|
123
|
+
case "assurance":
|
|
124
|
+
case "inherit": return false;
|
|
125
|
+
default: return undeclaredKind(grantee);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
/** Approvers are declared roles, plans or relations, or any authenticated human. */
|
|
129
|
+
function approvalAcceptable(policy, approval, permissionResource) {
|
|
130
|
+
if (approval === void 0 || approval === "human") return true;
|
|
131
|
+
if (!isRecord(approval)) return false;
|
|
132
|
+
if (approval["mode"] !== void 0 || approval["stages"] !== void 0) return false;
|
|
133
|
+
if (approval["distinct"] !== void 0 && typeof approval["distinct"] !== "boolean") return false;
|
|
134
|
+
if (approval["staleOn"] !== void 0 && (approval["staleOn"] !== "resource-change" || getResource(policy.permissions, permissionResource)?.version === void 0)) return false;
|
|
135
|
+
if (approval["quorum"] !== void 0 && (!Number.isInteger(approval["quorum"]) || approval["quorum"] < 1)) return false;
|
|
136
|
+
if (approval["ttl"] !== void 0 && (typeof approval["ttl"] !== "string" || parseDuration(approval["ttl"]) === void 0)) return false;
|
|
137
|
+
const escalation = approval["escalation"];
|
|
138
|
+
if (escalation !== void 0 && (!isRecord(escalation) || typeof escalation["after"] !== "string" || parseDuration(escalation["after"]) === void 0 || !granteesAcceptable(policy, escalation["to"], permissionResource))) return false;
|
|
139
|
+
if (approval["by"] === void 0) return true;
|
|
140
|
+
return granteesAcceptable(policy, approval["by"], permissionResource);
|
|
141
|
+
}
|
|
142
|
+
function granteesAcceptable(policy, raw, permissionResource) {
|
|
143
|
+
if (raw === void 0) return false;
|
|
144
|
+
const items = flattenGrantee(raw);
|
|
145
|
+
return items.length > 0 && items.every((item) => isRecord(item) && item.kind !== "relation" && (item.kind === "authenticated" || declaredGrantee(policy, item, permissionResource)));
|
|
146
|
+
}
|
|
147
|
+
function buildGrant(policy, document, raw) {
|
|
148
|
+
if (!isRecord(raw) || typeof raw["id"] !== "string" || typeof raw["permission"] !== "string" || raw["effect"] !== void 0 && raw["effect"] !== "allow" && raw["effect"] !== "deny" || raw["to"] === void 0) return {
|
|
149
|
+
ok: false,
|
|
150
|
+
reason: "invalid"
|
|
151
|
+
};
|
|
152
|
+
const permission = findPermission(policy.permissions, raw["permission"]);
|
|
153
|
+
if (permission === void 0) return {
|
|
154
|
+
ok: false,
|
|
155
|
+
reason: "unknown-permission"
|
|
156
|
+
};
|
|
157
|
+
if (!policy.hostable.includes(permission.key)) return {
|
|
158
|
+
ok: false,
|
|
159
|
+
reason: "not-hostable"
|
|
160
|
+
};
|
|
161
|
+
const to = flattenGrantee(raw["to"]);
|
|
162
|
+
if (to.length === 0 || !to.every((item) => isRecord(item) && declaredGrantee(policy, item, permission.resource))) return {
|
|
163
|
+
ok: false,
|
|
164
|
+
reason: "unknown-grantee"
|
|
165
|
+
};
|
|
166
|
+
for (const condition of [raw["where"], raw["check"]]) if (condition !== void 0 && !isPortableCondition(condition)) return {
|
|
167
|
+
ok: false,
|
|
168
|
+
reason: "non-portable"
|
|
169
|
+
};
|
|
170
|
+
if (!approvalAcceptable(policy, raw["approval"], permission.resource)) return {
|
|
171
|
+
ok: false,
|
|
172
|
+
reason: "invalid"
|
|
173
|
+
};
|
|
174
|
+
if (raw["fields"] !== void 0 && !(Array.isArray(raw["fields"]) && raw["fields"].every((field) => typeof field === "string"))) return {
|
|
175
|
+
ok: false,
|
|
176
|
+
reason: "invalid"
|
|
177
|
+
};
|
|
178
|
+
const effect = raw["effect"] ?? "allow";
|
|
179
|
+
const options = compact({
|
|
180
|
+
where: raw["where"] === void 0 ? void 0 : normalizeWhere(raw["where"]),
|
|
181
|
+
check: raw["check"] === void 0 ? void 0 : normalizeWhere(raw["check"]),
|
|
182
|
+
approval: raw["approval"],
|
|
183
|
+
fields: raw["fields"]
|
|
184
|
+
});
|
|
185
|
+
let built;
|
|
186
|
+
try {
|
|
187
|
+
const roleItem = to.length === 1 && to[0]?.kind === "role" ? to[0] : null;
|
|
188
|
+
if (roleItem === null) {
|
|
189
|
+
const partial = (effect === "allow" ? allow : deny)(permission, {
|
|
190
|
+
...options,
|
|
191
|
+
to
|
|
192
|
+
});
|
|
193
|
+
built = completeGrant(partial);
|
|
194
|
+
} else {
|
|
195
|
+
const binding = policy.rolesByName.get(roleItem.role);
|
|
196
|
+
const leaf = findRole(policy.vocabulary.roles, roleItem.role);
|
|
197
|
+
const [first] = role(leaf ?? roleItem.role, [(effect === "allow" ? allow : deny)(permission, options)], binding?.on === void 0 ? {} : { on: binding.on }).grants;
|
|
198
|
+
if (first === void 0) throw new TypeError("PermDock: role produced no grant");
|
|
199
|
+
built = first;
|
|
200
|
+
}
|
|
201
|
+
} catch {
|
|
202
|
+
return {
|
|
203
|
+
ok: false,
|
|
204
|
+
reason: "invalid"
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
if (effect === "allow") {
|
|
208
|
+
const codeApprovals = policy.grants.filter((grant) => grant.effect === "allow" && grant.hosted === void 0 && grant.permission.key === permission.key).map((grant) => grant.approval);
|
|
209
|
+
if (!approvalAtLeast(built.approval, codeApprovals)) return {
|
|
210
|
+
ok: false,
|
|
211
|
+
reason: "weaker-approval"
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
return {
|
|
215
|
+
ok: true,
|
|
216
|
+
grant: freezeDeep({
|
|
217
|
+
...built,
|
|
218
|
+
hosted: {
|
|
219
|
+
document: document.fingerprint,
|
|
220
|
+
grant: raw["id"]
|
|
221
|
+
}
|
|
222
|
+
})
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* The code policy plus the hosted grants that pass every rule. Hosted
|
|
227
|
+
* allows OR with code allows and any deny still wins, so a hosted grant can
|
|
228
|
+
* never override a code deny; one that fails a rule is dropped, not thrown.
|
|
229
|
+
*/
|
|
230
|
+
function mergeHostedGrants(policy, document) {
|
|
231
|
+
if (document === null || document.grants.length === 0) return {
|
|
232
|
+
policy,
|
|
233
|
+
dropped: []
|
|
234
|
+
};
|
|
235
|
+
const merged = [];
|
|
236
|
+
const dropped = [];
|
|
237
|
+
for (const raw of document.grants) {
|
|
238
|
+
const result = buildGrant(policy, document, raw);
|
|
239
|
+
if (result.ok) {
|
|
240
|
+
merged.push(result.grant);
|
|
241
|
+
continue;
|
|
242
|
+
}
|
|
243
|
+
dropped.push(freezeDeep({
|
|
244
|
+
kind: "hosted-grant-dropped",
|
|
245
|
+
document: document.fingerprint,
|
|
246
|
+
grant: isRecord(raw) && typeof raw.id === "string" ? raw.id : "",
|
|
247
|
+
reason: result.reason
|
|
248
|
+
}));
|
|
249
|
+
}
|
|
250
|
+
if (merged.length === 0) return {
|
|
251
|
+
policy,
|
|
252
|
+
dropped
|
|
253
|
+
};
|
|
254
|
+
const grants = [...policy.grants, ...merged];
|
|
255
|
+
return {
|
|
256
|
+
policy: freezeDeep({
|
|
257
|
+
...policy,
|
|
258
|
+
grants,
|
|
259
|
+
index: indexPolicy(policy.roles, grants, policy.vocabulary),
|
|
260
|
+
fingerprint: bytesToBase64Url(sha256(`${policy.fingerprint}:${document.fingerprint}`))
|
|
261
|
+
}),
|
|
262
|
+
dropped
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
//#endregion
|
|
266
|
+
export { parsePolicyDocument as i, memoryPolicySource as n, mergeHostedGrants as r, isPortableCondition as t };
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { i as parsedBody, r as headersFrom, t as firstHeader } from "./http-SO7qGttf.js";
|
|
2
|
+
//#region src/node/http.ts
|
|
3
|
+
function toRequest(req, stream = req) {
|
|
4
|
+
const host = firstHeader(req.headers.host) ?? "localhost";
|
|
5
|
+
const url = `${req.protocol ?? "http"}://${host}${req.originalUrl ?? req.url ?? "/"}`;
|
|
6
|
+
const headers = headersFrom(req.headers);
|
|
7
|
+
const method = req.method ?? "GET";
|
|
8
|
+
if (method === "GET" || method === "HEAD") return new Request(url, {
|
|
9
|
+
method,
|
|
10
|
+
headers
|
|
11
|
+
});
|
|
12
|
+
const parsed = parsedBody(req.body, headers);
|
|
13
|
+
if (parsed !== void 0) return new Request(url, {
|
|
14
|
+
method,
|
|
15
|
+
headers,
|
|
16
|
+
body: parsed
|
|
17
|
+
});
|
|
18
|
+
if (stream === null) return new Request(url, {
|
|
19
|
+
method,
|
|
20
|
+
headers
|
|
21
|
+
});
|
|
22
|
+
const init = {
|
|
23
|
+
method,
|
|
24
|
+
headers,
|
|
25
|
+
body: incomingBody(stream),
|
|
26
|
+
duplex: "half"
|
|
27
|
+
};
|
|
28
|
+
return new Request(url, init);
|
|
29
|
+
}
|
|
30
|
+
function chunkOf(chunk) {
|
|
31
|
+
return typeof chunk === "string" ? Buffer.from(chunk) : new Uint8Array(chunk);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Pull-based with `highWaterMark: 0`: nothing is read from `req` until the
|
|
35
|
+
* Web body is consumed, so a later body parser (multer, `express.json()`)
|
|
36
|
+
* still sees the whole stream.
|
|
37
|
+
*/
|
|
38
|
+
function incomingBody(req) {
|
|
39
|
+
return new ReadableStream({ pull(controller) {
|
|
40
|
+
return new Promise((resolve) => {
|
|
41
|
+
const drain = () => {
|
|
42
|
+
const chunk = req.read();
|
|
43
|
+
if (chunk !== null) {
|
|
44
|
+
controller.enqueue(chunkOf(chunk));
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
if (req.readableEnded) {
|
|
48
|
+
controller.close();
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
return false;
|
|
52
|
+
};
|
|
53
|
+
if (drain()) {
|
|
54
|
+
resolve();
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
const cleanup = () => {
|
|
58
|
+
req.off("readable", onReadable);
|
|
59
|
+
req.off("end", onEnd);
|
|
60
|
+
req.off("error", onError);
|
|
61
|
+
};
|
|
62
|
+
const onReadable = () => {
|
|
63
|
+
if (drain()) {
|
|
64
|
+
cleanup();
|
|
65
|
+
resolve();
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
const onEnd = () => {
|
|
69
|
+
cleanup();
|
|
70
|
+
controller.close();
|
|
71
|
+
resolve();
|
|
72
|
+
};
|
|
73
|
+
const onError = (err) => {
|
|
74
|
+
cleanup();
|
|
75
|
+
controller.error(err);
|
|
76
|
+
resolve();
|
|
77
|
+
};
|
|
78
|
+
req.on("readable", onReadable);
|
|
79
|
+
req.once("end", onEnd);
|
|
80
|
+
req.once("error", onError);
|
|
81
|
+
});
|
|
82
|
+
} }, { highWaterMark: 0 });
|
|
83
|
+
}
|
|
84
|
+
async function sendResponse(res, response) {
|
|
85
|
+
res.statusCode = response.status;
|
|
86
|
+
for (const [key, value] of response.headers.entries()) res.setHeader(key, value);
|
|
87
|
+
const body = Buffer.from(await response.arrayBuffer());
|
|
88
|
+
res.end(body);
|
|
89
|
+
}
|
|
90
|
+
const fromResponse = sendResponse;
|
|
91
|
+
function isServerResponse(value) {
|
|
92
|
+
return typeof value === "object" && value !== null && "setHeader" in value && typeof value.setHeader === "function" && "end" in value;
|
|
93
|
+
}
|
|
94
|
+
//#endregion
|
|
95
|
+
export { toRequest as i, isServerResponse as n, sendResponse as r, fromResponse as t };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { IncomingMessage, ServerResponse } from "node:http";
|
|
2
|
+
//#region src/node/http.d.ts
|
|
3
|
+
type NodeRequest = IncomingMessage & {
|
|
4
|
+
readonly originalUrl?: string;
|
|
5
|
+
readonly protocol?: string;
|
|
6
|
+
readonly body?: unknown;
|
|
7
|
+
};
|
|
8
|
+
declare function toRequest(req: NodeRequest, stream?: IncomingMessage | null): Request;
|
|
9
|
+
declare function sendResponse(res: ServerResponse, response: Response): Promise<void>;
|
|
10
|
+
declare const fromResponse: typeof sendResponse;
|
|
11
|
+
declare function isServerResponse(value: unknown): value is ServerResponse;
|
|
12
|
+
//#endregion
|
|
13
|
+
export { toRequest as a, sendResponse as i, fromResponse as n, isServerResponse as r, NodeRequest as t };
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
//#region src/server/http.ts
|
|
2
|
+
/** Node-style headers (`IncomingHttpHeaders`, Fastify's) as Fetch `Headers`; repeated values stay separate. */
|
|
3
|
+
function headersFrom(source) {
|
|
4
|
+
const headers = new Headers();
|
|
5
|
+
for (const [key, value] of Object.entries(source)) {
|
|
6
|
+
if (typeof value === "string") {
|
|
7
|
+
headers.set(key, value);
|
|
8
|
+
continue;
|
|
9
|
+
}
|
|
10
|
+
for (const item of value ?? []) headers.append(key, item);
|
|
11
|
+
}
|
|
12
|
+
return headers;
|
|
13
|
+
}
|
|
14
|
+
function firstHeader(value) {
|
|
15
|
+
if (typeof value === "string") return value.length > 0 ? value : void 0;
|
|
16
|
+
return value?.[0];
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* A body a framework already parsed, as the text a Fetch `Request` carries.
|
|
20
|
+
* A non-string body is serialised as JSON and, without a `content-type`,
|
|
21
|
+
* labelled `application/json` on `headers`.
|
|
22
|
+
*/
|
|
23
|
+
function parsedBody(body, headers) {
|
|
24
|
+
if (body === void 0) return;
|
|
25
|
+
if (typeof body === "string") return body;
|
|
26
|
+
if (!headers.has("content-type")) headers.set("content-type", "application/json");
|
|
27
|
+
return JSON.stringify(body);
|
|
28
|
+
}
|
|
29
|
+
/** The Fetch `Request` an RPC context carries as `request` or `req`. */
|
|
30
|
+
function requestFromContext(context) {
|
|
31
|
+
if ("request" in context && context.request instanceof Request) return context.request;
|
|
32
|
+
if ("req" in context && context.req instanceof Request) return context.req;
|
|
33
|
+
}
|
|
34
|
+
/** Whether the caller sent credentials, which turns a `401` into a `WWW-Authenticate` challenge. */
|
|
35
|
+
function hasCredentials(request) {
|
|
36
|
+
return request.headers.has("authorization");
|
|
37
|
+
}
|
|
38
|
+
/** The Problem Details `detail` of `cause`, or `fallback` when it has none. */
|
|
39
|
+
function problemMessage(cause, fallback) {
|
|
40
|
+
if (cause !== null && typeof cause === "object" && "detail" in cause && typeof cause.detail === "string" && cause.detail.length > 0) return cause.detail;
|
|
41
|
+
return fallback;
|
|
42
|
+
}
|
|
43
|
+
//#endregion
|
|
44
|
+
export { problemMessage as a, parsedBody as i, hasCredentials as n, requestFromContext as o, headersFrom as r, firstHeader as t };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
//#region src/core/ids.ts
|
|
2
|
+
/**
|
|
3
|
+
* The canonical text of a scope or object id: a non-empty string as is, a
|
|
4
|
+
* finite number or a bigint as its decimal text (a `bigint` key column read
|
|
5
|
+
* through supabase-js arrives as a number), anything else none.
|
|
6
|
+
*/
|
|
7
|
+
function idText(value) {
|
|
8
|
+
if (typeof value === "string") return value === "" ? void 0 : value;
|
|
9
|
+
if (typeof value === "number" && Number.isFinite(value)) return String(value);
|
|
10
|
+
if (typeof value === "bigint") return String(value);
|
|
11
|
+
}
|
|
12
|
+
/** Whether two ids are the same id once both are read as text; a missing id matches nothing. */
|
|
13
|
+
function sameId(left, right) {
|
|
14
|
+
const text = idText(left);
|
|
15
|
+
return text !== void 0 && text === idText(right);
|
|
16
|
+
}
|
|
17
|
+
//#endregion
|
|
18
|
+
export { sameId as n, idText as t };
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { Ft as TokenVerifier, at as DecisionSink, gt as MembershipSource } from "./policy-CFZAr_Al.js";
|
|
2
|
+
import { n as RevocationFeed } from "./revocations-Cy06JNx2.js";
|
|
3
|
+
//#region src/scim/types.d.ts
|
|
4
|
+
declare const SCIM_CONTENT_TYPE = "application/scim+json";
|
|
5
|
+
declare const USER_SCHEMA = "urn:ietf:params:scim:schemas:core:2.0:User";
|
|
6
|
+
declare const GROUP_SCHEMA = "urn:ietf:params:scim:schemas:core:2.0:Group";
|
|
7
|
+
declare const LIST_SCHEMA = "urn:ietf:params:scim:api:messages:2.0:ListResponse";
|
|
8
|
+
declare const ERROR_SCHEMA = "urn:ietf:params:scim:api:messages:2.0:Error";
|
|
9
|
+
declare const PATCH_SCHEMA = "urn:ietf:params:scim:api:messages:2.0:PatchOp";
|
|
10
|
+
declare const ROLES_EXTENSION = "urn:permdock:scim:schemas:extension:roles:1.0";
|
|
11
|
+
type DirectoryMeta = {
|
|
12
|
+
readonly created: string;
|
|
13
|
+
readonly lastModified: string;
|
|
14
|
+
readonly location?: string;
|
|
15
|
+
readonly resourceType?: "User" | "Group";
|
|
16
|
+
};
|
|
17
|
+
type DirectoryEmail = {
|
|
18
|
+
readonly value: string;
|
|
19
|
+
readonly primary?: boolean;
|
|
20
|
+
readonly type?: string;
|
|
21
|
+
};
|
|
22
|
+
type DirectoryUser = {
|
|
23
|
+
readonly id: string;
|
|
24
|
+
readonly externalId?: string;
|
|
25
|
+
readonly userName: string;
|
|
26
|
+
readonly active: boolean;
|
|
27
|
+
readonly emails?: readonly DirectoryEmail[];
|
|
28
|
+
readonly meta: DirectoryMeta;
|
|
29
|
+
};
|
|
30
|
+
type DirectoryGroupMember = {
|
|
31
|
+
readonly value: string;
|
|
32
|
+
};
|
|
33
|
+
type DirectoryGroup = {
|
|
34
|
+
readonly id: string;
|
|
35
|
+
readonly externalId?: string;
|
|
36
|
+
readonly displayName: string;
|
|
37
|
+
readonly members: readonly DirectoryGroupMember[];
|
|
38
|
+
readonly roles?: readonly string[];
|
|
39
|
+
readonly meta: DirectoryMeta;
|
|
40
|
+
};
|
|
41
|
+
type ScimCompareOp = "eq" | "ne" | "co" | "sw";
|
|
42
|
+
type ScimFilter = {
|
|
43
|
+
readonly op: ScimCompareOp;
|
|
44
|
+
readonly attribute: string;
|
|
45
|
+
readonly value: string | boolean;
|
|
46
|
+
} | {
|
|
47
|
+
readonly op: "pr";
|
|
48
|
+
readonly attribute: string;
|
|
49
|
+
} | {
|
|
50
|
+
readonly op: "and" | "or";
|
|
51
|
+
readonly filters: readonly ScimFilter[];
|
|
52
|
+
};
|
|
53
|
+
type ScimPage = {
|
|
54
|
+
readonly startIndex?: number;
|
|
55
|
+
readonly count?: number;
|
|
56
|
+
readonly cursor?: string;
|
|
57
|
+
};
|
|
58
|
+
type ScimPageResult<T> = {
|
|
59
|
+
readonly Resources: readonly T[];
|
|
60
|
+
readonly totalResults: number;
|
|
61
|
+
readonly startIndex?: number;
|
|
62
|
+
readonly itemsPerPage?: number;
|
|
63
|
+
readonly nextCursor?: string;
|
|
64
|
+
};
|
|
65
|
+
type ScimPatchOp = {
|
|
66
|
+
readonly op: "add" | "replace" | "remove";
|
|
67
|
+
readonly path?: string;
|
|
68
|
+
readonly value?: unknown;
|
|
69
|
+
};
|
|
70
|
+
type DirectoryStore = {
|
|
71
|
+
getUser(tenant: string, id: string): Promise<DirectoryUser | null>;
|
|
72
|
+
findUsers(tenant: string, filter: ScimFilter | undefined, page: ScimPage): Promise<ScimPageResult<DirectoryUser>>;
|
|
73
|
+
putUser(tenant: string, user: DirectoryUser): Promise<DirectoryUser>;
|
|
74
|
+
patchUser(tenant: string, id: string, ops: readonly ScimPatchOp[]): Promise<DirectoryUser>;
|
|
75
|
+
deleteUser(tenant: string, id: string): Promise<void>;
|
|
76
|
+
getGroup(tenant: string, id: string): Promise<DirectoryGroup | null>;
|
|
77
|
+
findGroups(tenant: string, filter: ScimFilter | undefined, page: ScimPage): Promise<ScimPageResult<DirectoryGroup>>;
|
|
78
|
+
putGroup(tenant: string, group: DirectoryGroup): Promise<DirectoryGroup>;
|
|
79
|
+
patchGroup(tenant: string, id: string, ops: readonly ScimPatchOp[]): Promise<DirectoryGroup>;
|
|
80
|
+
deleteGroup(tenant: string, id: string): Promise<void>;
|
|
81
|
+
groupsFor(tenant: string, userId: string): Promise<readonly DirectoryGroup[]>;
|
|
82
|
+
};
|
|
83
|
+
type ScimTokenOptions = {
|
|
84
|
+
readonly hash: "sha256";
|
|
85
|
+
readonly lookup: (tenant: string) => string | undefined | Promise<string | undefined>;
|
|
86
|
+
};
|
|
87
|
+
type DirectoryChange = {
|
|
88
|
+
readonly tenant: string;
|
|
89
|
+
readonly userIds: readonly string[];
|
|
90
|
+
/** `session-revoked` when a user was deactivated or deleted; `changed` otherwise. */
|
|
91
|
+
readonly kind: "session-revoked" | "changed";
|
|
92
|
+
};
|
|
93
|
+
type ScimHandlerOptions = {
|
|
94
|
+
readonly store: DirectoryStore;
|
|
95
|
+
readonly tenant: string | ((request: Request) => string | Promise<string>);
|
|
96
|
+
readonly token?: ScimTokenOptions;
|
|
97
|
+
readonly verifier?: TokenVerifier;
|
|
98
|
+
readonly audience?: string;
|
|
99
|
+
readonly groupRoles?: Readonly<Record<string, readonly string[]>>;
|
|
100
|
+
readonly assignable?: readonly string[];
|
|
101
|
+
readonly sink?: DecisionSink;
|
|
102
|
+
readonly onChange?: (change: DirectoryChange) => void | Promise<void>;
|
|
103
|
+
/**
|
|
104
|
+
* Publishes for each affected user's id, `externalId` and `userName`:
|
|
105
|
+
* `session-revoked` when a user is deactivated (`active: false`) or
|
|
106
|
+
* deleted, so open connections end; `changed` otherwise, so they revalidate.
|
|
107
|
+
*/
|
|
108
|
+
readonly revocations?: RevocationFeed;
|
|
109
|
+
readonly onUnknownRole?: (name: string) => void;
|
|
110
|
+
};
|
|
111
|
+
type DirectoryMembershipMatch = "externalId" | "userName" | "either";
|
|
112
|
+
type DirectoryMembershipSourceOptions = {
|
|
113
|
+
readonly match?: DirectoryMembershipMatch;
|
|
114
|
+
readonly groupRoles?: Readonly<Record<string, readonly string[]>>;
|
|
115
|
+
readonly assignable?: readonly string[];
|
|
116
|
+
readonly onUnknownRole?: (name: string) => void;
|
|
117
|
+
};
|
|
118
|
+
declare class DirectoryUniquenessError extends Error {
|
|
119
|
+
override readonly name = "DirectoryUniquenessError";
|
|
120
|
+
readonly code: "uniqueness";
|
|
121
|
+
constructor(message?: string);
|
|
122
|
+
}
|
|
123
|
+
declare class DirectoryNotFoundError extends Error {
|
|
124
|
+
override readonly name = "DirectoryNotFoundError";
|
|
125
|
+
readonly code: "not-found";
|
|
126
|
+
constructor(message?: string);
|
|
127
|
+
}
|
|
128
|
+
//#endregion
|
|
129
|
+
//#region src/scim/auth.d.ts
|
|
130
|
+
type ScimCredential = {
|
|
131
|
+
readonly kind: "token";
|
|
132
|
+
} | {
|
|
133
|
+
readonly kind: "jwt";
|
|
134
|
+
readonly iss?: string;
|
|
135
|
+
};
|
|
136
|
+
type ScimAuthResult = {
|
|
137
|
+
readonly ok: true;
|
|
138
|
+
readonly credential: ScimCredential;
|
|
139
|
+
} | {
|
|
140
|
+
readonly ok: false;
|
|
141
|
+
readonly status: 401 | 403;
|
|
142
|
+
};
|
|
143
|
+
declare function authenticateScim(input: {
|
|
144
|
+
readonly request: Request;
|
|
145
|
+
readonly tenant: string;
|
|
146
|
+
readonly audience?: string;
|
|
147
|
+
readonly token?: ScimTokenOptions;
|
|
148
|
+
readonly verifier?: TokenVerifier;
|
|
149
|
+
}): Promise<ScimAuthResult>;
|
|
150
|
+
declare function sha256Hex(value: string): string;
|
|
151
|
+
//#endregion
|
|
152
|
+
//#region src/scim/discovery.d.ts
|
|
153
|
+
declare function serviceProviderConfig(): Record<string, unknown>;
|
|
154
|
+
declare function resourceTypes(): readonly Record<string, unknown>[];
|
|
155
|
+
declare function schemas(): readonly Record<string, unknown>[];
|
|
156
|
+
//#endregion
|
|
157
|
+
//#region src/scim/filter.d.ts
|
|
158
|
+
declare function parseScimFilter(input: string): ScimFilter | undefined;
|
|
159
|
+
declare function matchFilter(target: DirectoryUser | DirectoryGroup | Record<string, unknown>, filter: ScimFilter | undefined): boolean;
|
|
160
|
+
declare function filterSupported(filter: ScimFilter): boolean;
|
|
161
|
+
//#endregion
|
|
162
|
+
//#region src/scim/handler.d.ts
|
|
163
|
+
declare function scimHandler(options: ScimHandlerOptions): (request: Request) => Promise<Response>;
|
|
164
|
+
//#endregion
|
|
165
|
+
//#region src/scim/route.d.ts
|
|
166
|
+
declare function tenantFromPath(request: Request): string;
|
|
167
|
+
//#endregion
|
|
168
|
+
//#region src/scim/patch.d.ts
|
|
169
|
+
declare function normalizePatchOps(ops: readonly unknown[]): readonly ScimPatchOp[] | undefined;
|
|
170
|
+
//#endregion
|
|
171
|
+
//#region src/scim/source.d.ts
|
|
172
|
+
declare function directoryMembershipSource(store: DirectoryStore, options?: DirectoryMembershipSourceOptions): MembershipSource;
|
|
173
|
+
//#endregion
|
|
174
|
+
//#region src/scim/store.d.ts
|
|
175
|
+
declare function memoryDirectoryStore(): DirectoryStore;
|
|
176
|
+
//#endregion
|
|
177
|
+
export { ScimPageResult as A, LIST_SCHEMA as C, ScimFilter as D, SCIM_CONTENT_TYPE as E, ScimTokenOptions as M, USER_SCHEMA as N, ScimHandlerOptions as O, GROUP_SCHEMA as S, ROLES_EXTENSION as T, DirectoryNotFoundError as _, scimHandler as a, DirectoryUser as b, parseScimFilter as c, serviceProviderConfig as d, authenticateScim as f, DirectoryMembershipSourceOptions as g, DirectoryGroup as h, tenantFromPath as i, ScimPatchOp as j, ScimPage as k, resourceTypes as l, DirectoryChange as m, directoryMembershipSource as n, filterSupported as o, sha256Hex as p, normalizePatchOps as r, matchFilter as s, memoryDirectoryStore as t, schemas as u, DirectoryStore as v, PATCH_SCHEMA as w, ERROR_SCHEMA as x, DirectoryUniquenessError as y };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { C as Policy, Nr as Principal } from "./policy-CFZAr_Al.js";
|
|
2
|
+
import { C as SsfPermDock, w as SsfPermDockOptions } from "./types-9AWO9EGt.js";
|
|
3
|
+
//#region src/ssf/create.d.ts
|
|
4
|
+
declare function createPermDock<TUser, TPrincipal extends Principal = Principal>(policy: Policy<TUser, TPrincipal>, options: SsfPermDockOptions): SsfPermDock;
|
|
5
|
+
//#endregion
|
|
6
|
+
export { createPermDock as t };
|