permdock 0.17.0 → 0.18.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/dist/a2a/index.d.ts +4 -4
- package/dist/a2a/index.js +3 -3
- package/dist/{adoption-scan-Ci0xiJ3T.js → adoption-scan-CxExBYSJ.js} +1 -1
- package/dist/agent/index.d.ts +2 -2
- package/dist/agent/index.js +1 -1
- package/dist/ai-sdk/index.d.ts +3 -3
- package/dist/ai-sdk/index.js +3 -3
- package/dist/{approval-normalize-4KxMRdJC.js → approval-normalize-CUjgSsOl.js} +1 -1
- package/dist/{approval-policies-9VagPixq.d.ts → approval-policies-oNnckT12.d.ts} +1 -1
- package/dist/{approval-prompt-BSh-yxbH.d.ts → approval-prompt-Bg7gDSqd.d.ts} +1 -1
- package/dist/approvals/index.d.ts +3 -3
- package/dist/approvals/index.js +3 -3
- package/dist/{approvals-DdFcTncq.js → approvals-DGId_hgJ.js} +2 -2
- package/dist/{approvers-CNtl4Vc5.js → approvers-BaNwKYgd.js} +1 -3
- package/dist/{arazzo-_zUmT8ZT.js → arazzo--riLuGY0.js} +2 -2
- package/dist/{arazzo-7kbeh1yi.js → arazzo-CEDbb-uM.js} +1 -1
- package/dist/astro/index.d.ts +4 -4
- package/dist/astro/index.js +2 -2
- package/dist/{audience-jRO819i3.js → audience-B4YR9UpV.js} +1 -1
- package/dist/authzen/index.d.ts +5 -5
- package/dist/authzen/index.js +2 -2
- package/dist/{automation-DCWuVKtd.d.ts → automation-Bfa_wD1h.d.ts} +1 -1
- package/dist/better-auth/index.d.ts +1 -1
- package/dist/better-auth/index.js +1 -1
- package/dist/better-supabase/index.d.ts +153 -91
- package/dist/better-supabase/index.js +332 -62
- package/dist/{bind-BJFeLX1V.js → bind-B4pMH9bm.js} +4 -4
- package/dist/{bind-DjFNX0Pq.d.ts → bind-DR6ku3A9.d.ts} +7 -7
- package/dist/{build-instance-lye7oEqf.js → build-instance-BFMFQdE_.js} +1 -1
- package/dist/{capability-BzjWdKmP.d.ts → capability-BZ_veK9o.d.ts} +1 -1
- package/dist/{casbin-DFzk_so3.js → casbin-DCQHkkyj.js} +1 -1
- package/dist/{casbin-C3O_O9nu.js → casbin-bKC1FpEx.js} +1 -1
- package/dist/catalog/index.d.ts +4 -4
- package/dist/catalog/index.js +5 -5
- package/dist/catalog-Caqhbdix.js +1 -0
- package/dist/{catalog-DGDd_ww1.js → catalog-D1fw8qif.js} +2 -2
- package/dist/{catalog-operations-DVI5QO5R.js → catalog-operations-BD22drQf.js} +2 -2
- package/dist/{catalog-DJJIkR9P.js → catalog-zzNuR3sY.js} +1 -1
- package/dist/{challenge-M_ghKJnT.js → challenge-B2O2OLEk.js} +1 -1
- package/dist/chat/index.d.ts +1 -1
- package/dist/chat/index.js +2 -2
- package/dist/chat-sdk/index.d.ts +3 -3
- package/dist/claude-agent/index.d.ts +3 -3
- package/dist/claude-agent/index.js +2 -2
- package/dist/clerk/index.d.ts +2 -2
- package/dist/cli/bin.js +1 -1
- package/dist/cli/index.d.ts +4 -4
- package/dist/cli/index.js +2 -2
- package/dist/client-CH7vzSAY.d.ts +32 -0
- package/dist/cloud/index.d.ts +8 -8
- package/dist/cloud/index.js +1 -1
- package/dist/{cloud-DYqzmh5i.js → cloud-C0vXBmLG.js} +2 -2
- package/dist/{codemod-DqB9klYI.js → codemod-C-L0w-u7.js} +2 -2
- package/dist/{codemod-DNGMGqBS.js → codemod-eYI1FbeJ.js} +1 -1
- package/dist/{collect-C44RrKCI.js → collect-CU85z6Ta.js} +2 -2
- package/dist/{collect-HfJXl8Tr.js → collect-D878zLDP.js} +1 -1
- package/dist/collect-KCtOigxx.js +1 -0
- package/dist/compile/index.d.ts +1 -1
- package/dist/{compile-BxiwRotu.d.ts → compile-DBm0ub4p.d.ts} +2 -2
- package/dist/{completion-pwVjJlek.js → completion-Dauc6pVT.js} +1 -1
- package/dist/{config-DnfH6_eT.js → config-DWp2PucY.js} +1 -1
- package/dist/{config-report-C1jl7Na-.js → config-report-DKpFm5ID.js} +2 -2
- package/dist/convex/index.d.ts +4 -4
- package/dist/convex/index.js +2 -2
- package/dist/{core-W5f4Rjt0.js → core-B8sLve3z.js} +3 -3
- package/dist/{core-0iYZ5HUx.d.ts → core-D87h2kpR.d.ts} +2 -2
- package/dist/{create-jCPwPWXf.js → create-3A7J9KRR.js} +4 -4
- package/dist/{create-DrHUmKvG.d.ts → create-BrQXL-Wt.d.ts} +6 -6
- package/dist/{create-bzQlBzG4.d.ts → create-BzwjZuRS.d.ts} +7 -7
- package/dist/{create-gqtDb1nU.js → create-C-tm3KIF.js} +3 -3
- package/dist/{create-DNN3OtsO.d.ts → create-CtoT1lIQ.d.ts} +4 -4
- package/dist/delivery/index.d.ts +4 -4
- package/dist/delivery/index.js +1 -1
- package/dist/{denied-text-DyzWwxEB.d.ts → denied-text-DlIxt8fh.d.ts} +1 -1
- package/dist/{describe-nalX_HHE.d.ts → describe-BKtC_8PG.d.ts} +1 -1
- package/dist/{describe-CogP1loh.js → describe-BZAlPHxT.js} +1 -1
- package/dist/{diff-BTsLiW59.js → diff-BnNHqtHj.js} +4 -4
- package/dist/{diff-CcxYooMu.js → diff-CBCzOTWM.js} +1 -1
- package/dist/{doctor-DS-9ApID.js → doctor-CkYKCuX7.js} +55 -17
- package/dist/{doctor-BNRhJegR.js → doctor-xUpR5rXg.js} +2 -2
- package/dist/drizzle/index.d.ts +3 -3
- package/dist/elysia/index.d.ts +4 -4
- package/dist/elysia/index.js +3 -3
- package/dist/{errors-Dc9FdamT.d.ts → errors-TpzkEKgJ.d.ts} +1 -1
- package/dist/{evaluate-CsjXeLRo.js → evaluate-Czbj7thS.js} +2 -2
- package/dist/{evaluations-BasA9zXp.d.ts → evaluations-CisTTURl.d.ts} +3 -3
- package/dist/{evaluations-DG40eSJa.js → evaluations-h3KoJAPa.js} +1 -1
- package/dist/eve/index.d.ts +4 -4
- package/dist/eve/index.js +3 -3
- package/dist/express/index.d.ts +4 -4
- package/dist/express/index.js +3 -3
- package/dist/fastify/index.d.ts +4 -4
- package/dist/fastify/index.js +3 -3
- package/dist/{fetch-adapter-BgqpOOpd.d.ts → fetch-adapter-BdmfnbJM.d.ts} +2 -2
- package/dist/{fetch-adapter-UZOW0PRC.js → fetch-adapter-DH-NJPbL.js} +2 -2
- package/dist/{fixtures-0VTW5oNq.js → fixtures-Cemqurt8.js} +8 -2
- package/dist/{gen-CNCzG4sB.js → gen-BEIN-DRM.js} +1 -1
- package/dist/{gen-DnpZwQPo.js → gen-mf-MRwVr.js} +3 -3
- package/dist/h3/index.d.ts +4 -4
- package/dist/h3/index.js +3 -3
- package/dist/{helpers-DNnZffrI.js → helpers-DmqGy63f.js} +21 -13
- package/dist/hono/index.d.ts +4 -4
- package/dist/hono/index.js +3 -3
- package/dist/{hosted-DxRLLiFU.d.ts → hosted-BFNXwcjd.d.ts} +1 -1
- package/dist/{hosted-tPZnyjQS.js → hosted-waouw2V-.js} +3 -3
- package/dist/{import-BYVbSKx0.js → import-DObwEota.js} +1 -1
- package/dist/{index-z44pfWar.d.ts → index-BhnOOnp9.d.ts} +2 -2
- package/dist/{index-DFwUOkvt.d.ts → index-CVGio3cH.d.ts} +4 -4
- package/dist/{index-CXXUFWtG.d.ts → index-CdMOd-GY.d.ts} +4 -4
- package/dist/{index-Bt-UoBWu.d.ts → index-CdUTE6qd.d.ts} +8 -8
- package/dist/{index-CZ5mixHO.d.ts → index-Dfv9Toct.d.ts} +1 -1
- package/dist/{index-DtGtDzjb.d.ts → index-rFp6X_QP.d.ts} +4 -4
- package/dist/index.d.ts +17 -17
- package/dist/index.js +15 -13
- package/dist/{init-YSDySeMy.js → init-CNJ8lLjo.js} +1 -1
- package/dist/{init-Dr1qAStu.js → init-DS3PEsCG.js} +3 -3
- package/dist/{instance-options-BOCRxEFb.d.ts → instance-options-2sFGSdsf.d.ts} +1 -1
- package/dist/{instance-snapshot-BgOGtyCy.js → instance-snapshot-BWa71my8.js} +2 -2
- package/dist/jwt/index.d.ts +4 -4
- package/dist/{kernel-CDDU93dI.js → kernel-30Z2zM_d.js} +6 -6
- package/dist/kysely/index.d.ts +3 -3
- package/dist/{login-CXgEKLaW.js → login-BgK5Jloo.js} +1 -1
- package/dist/{login-DEVXDTX8.js → login-DUVzBLh7.js} +3 -3
- package/dist/{manifest-BXTbHNIV.js → manifest-BdzBobNK.js} +1 -1
- package/dist/{manifest-schema-DQkBK2Mr.js → manifest-schema-CsFsYLF-.js} +1 -1
- package/dist/{manifest-Dij1U0hx.js → manifest-wclLWBVH.js} +35 -35
- package/dist/{map-error-B_f3C5cs.js → map-error-BH16Ah8P.js} +1 -1
- package/dist/mcp/index.d.ts +8 -8
- package/dist/mcp/index.js +5 -5
- package/dist/nest/index.d.ts +4 -4
- package/dist/nest/index.js +3 -3
- package/dist/next/index.d.ts +23 -10
- package/dist/next/index.js +29 -9
- package/dist/next/plugin.d.ts +1 -1
- package/dist/next/plugin.js +1 -1
- package/dist/node/index.d.ts +4 -4
- package/dist/node/index.js +2 -2
- package/dist/openai/index.d.ts +4 -4
- package/dist/openai/index.js +3 -3
- package/dist/openapi/index.d.ts +2 -2
- package/dist/{openapi-D3wkvOoU.js → openapi-C4gFqeRz.js} +2 -2
- package/dist/{openapi-GM-kTdkq.js → openapi-zMEB9qxn.js} +2 -2
- package/dist/{operation-findings-CXtFzlKJ.js → operation-findings-CVwJHEu_.js} +1 -1
- package/dist/operation-risks-BKOcTv8J.js +13 -0
- package/dist/operations-Bm9HFecz.js +89 -0
- package/dist/orpc/index.d.ts +5 -5
- package/dist/orpc/index.js +3 -3
- package/dist/otel/index.d.ts +3 -3
- package/dist/{output-DhTpe8v1.js → output-BFWLER4r.js} +1 -1
- package/dist/{ownership-moSRhxl_.js → ownership-D-mIt-w0.js} +1 -1
- package/dist/{parse-local-manifest-DEiCF4ah.js → parse-local-manifest-CxcSMQgl.js} +2 -2
- package/dist/{parse-local-manifest-BgTYdR3q.d.ts → parse-local-manifest-DvjTQNuO.d.ts} +1 -1
- package/dist/pdp/index.d.ts +3 -3
- package/dist/pdp/index.js +1 -1
- package/dist/{permdock-DdzMv5-F.js → permdock-D-_WrdKu.js} +18 -8
- package/dist/{permdock-DUWZEOLR.d.ts → permdock-ffY4CMd9.d.ts} +20 -7
- package/dist/{permissions-CvpPtz5O.js → permissions-B3ggI88M.js} +2 -2
- package/dist/{permissions-CVXmRILq.js → permissions-BaoLxy66.js} +1 -13
- package/dist/{policy-CTNl7pvN.d.ts → policy-BtKSApSt.d.ts} +1 -1
- package/dist/{policy-DxQyHKPB.js → policy-cV_wwPb8.js} +2 -2
- package/dist/{policy-from-catalog-DVa1faOr.js → policy-from-catalog-B68hGC0S.js} +6 -6
- package/dist/{policy-types-IRJVABmm.d.ts → policy-types-D-GwfQTc.d.ts} +9 -0
- package/dist/{postgrest-B_cEDd4e.d.ts → postgrest-D84p5dbA.d.ts} +1 -1
- package/dist/{powersync-C0nsyULQ.js → powersync-9PYOE1wt.js} +150 -13
- package/dist/{powersync-BZxw_v-A.js → powersync-DStC_g0B.js} +2 -2
- package/dist/powersync-xNRlC4jN.js +1 -0
- package/dist/prisma/index.d.ts +2 -2
- package/dist/{protected-action-qowj6nxN.js → protected-action-B40tU3yP.js} +2 -2
- package/dist/{protected-action-D3S9U4nc.d.ts → protected-action-Ds_EUY8B.d.ts} +5 -5
- package/dist/{protected-action-B6n6w7Rl.js → protected-action-OpOxtTsN.js} +1 -1
- package/dist/{provider-CjAu39fJ.d.ts → provider-OtnIiFWm.d.ts} +1 -1
- package/dist/{pull-DVoZ0V9_.js → pull-DLP4I1Kl.js} +2 -2
- package/dist/pull-UBjDnf4b.js +1 -0
- package/dist/{push-eJl1Tvqm.js → push-BSb8j1EW.js} +3 -3
- package/dist/{pushed-policy-DMXAOmEW.js → pushed-policy-BecMsTtM.js} +1 -1
- package/dist/{pushed-policy-CUQuvlS3.d.ts → pushed-policy-Ck3FZcoy.d.ts} +1 -1
- package/dist/react/index.d.ts +6 -6
- package/dist/react/index.js +3 -3
- package/dist/react/provider-client.d.ts +1 -1
- package/dist/react-native/index.d.ts +103 -38
- package/dist/react-native/index.js +194 -35
- package/dist/{replay-Dc3d8LhG.d.ts → replay-E5X9E1lC.d.ts} +1 -1
- package/dist/{request-context-Ch052blg.js → request-context-DM6_jY1n.js} +1 -1
- package/dist/resend/index.d.ts +4 -4
- package/dist/{resolve-names-1nCei24V.js → resolve-names-CBl4r4_r.js} +1 -1
- package/dist/{rls-ClJRblnR.js → rls-DGBL-jDY.js} +10 -10
- package/dist/{rls-BVzoZCn3.js → rls-pAHGYgTb.js} +1 -1
- package/dist/{role-builder-BrmOcXch.js → role-builder-CMW4wWzn.js} +1 -1
- package/dist/{rpc-BOu3FD6X.js → rpc-KwX_Jcxz.js} +1 -1
- package/dist/{run-CnCaTjWX.js → run-B7lv3NuK.js} +2 -2
- package/dist/run-UPbacxPg.js +1 -0
- package/dist/{run-ticket-C6lXvHM_.d.ts → run-ticket-DPaD27_r.d.ts} +2 -2
- package/dist/{runtime-CBXkOcg9.js → runtime-rf0ZuyF3.js} +1 -1
- package/dist/{saas-BqM9mJkk.js → saas-B8H1MsQ3.js} +4 -4
- package/dist/{scan-CepUXrFt.js → scan-0r3OZqqK.js} +1 -1
- package/dist/{schema-9_NDz8fx.js → schema-B_9tXrbG.js} +1 -1
- package/dist/scim/index.d.ts +1 -1
- package/dist/server/index.d.ts +10 -10
- package/dist/server/index.js +3 -3
- package/dist/{server-types-Bw-lWqzR.d.ts → server-types-3OnXjZ2D.d.ts} +8 -8
- package/dist/{sink-DUzt0e4B.d.ts → sink-ogbVkyeo.d.ts} +2 -2
- package/dist/{skills-BUuH-QFt.js → skills-B4MPRxQd.js} +1 -1
- package/dist/{skills-a4N6Y2Xm.js → skills-C9sTD70r.js} +1 -1
- package/dist/{snapshot-cache-Dbk-Gnij.d.ts → snapshot-cache-B4YvlGG_.d.ts} +1 -1
- package/dist/solid/index.d.ts +5 -5
- package/dist/solid/index.js +3 -3
- package/dist/solid-start/index.d.ts +4 -4
- package/dist/solid-start/index.js +3 -3
- package/dist/{sources-CXY05xtB.d.ts → sources-xdQShLDU.d.ts} +1 -1
- package/dist/{src-nYNBfmgq.js → src-Brzq_0in.js} +21 -104
- package/dist/ssf/index.d.ts +3 -3
- package/dist/ssf/index.js +1 -1
- package/dist/{standard-webhooks-BFeEpjxy.d.ts → standard-webhooks-BfPaZ6T1.d.ts} +2 -2
- package/dist/{store-g5ctUrOI.d.ts → store-DYeB-_U3.d.ts} +4 -4
- package/dist/{store-XgBMbfDy.js → store-DmVqy74I.js} +2 -2
- package/dist/{stores-53_kOwPi.js → stores-BYFopOm1.js} +2 -2
- package/dist/{stores-BtdN3eDO.d.ts → stores-EPul_8MN.d.ts} +5 -5
- package/dist/{stream-BMJg56jU.d.ts → stream-W2RuUYly.d.ts} +1 -1
- package/dist/supabase/client.d.ts +2 -31
- package/dist/supabase/index.d.ts +5 -5
- package/dist/supabase/index.js +3 -3
- package/dist/supabase/middleware.d.ts +5 -5
- package/dist/supabase/middleware.js +4 -4
- package/dist/{supabase-C8cNzp4i.js → supabase-BiViJpQ4.js} +1 -1
- package/dist/{supabase-C6FyUeSh.js → supabase-CogTyJH2.js} +2 -2
- package/dist/supabase-hook-BN46IrVI.js +1 -0
- package/dist/{supabase-hook-Cj85nccs.js → supabase-hook-DX38Hj8h.js} +238 -23
- package/dist/{supautils-BP_5WAIc.js → supautils-BGf6zRvM.js} +6 -6
- package/dist/svelte/index.d.ts +5 -5
- package/dist/svelte/index.js +5 -5
- package/dist/svelte/runtime.d.ts +3 -3
- package/dist/svelte/runtime.js +2 -2
- package/dist/svelte/source.d.ts +5 -5
- package/dist/svelte/source.js +3 -3
- package/dist/sveltekit/index.d.ts +4 -4
- package/dist/sveltekit/index.js +2 -2
- package/dist/{tables-BsGE6HBR.js → tables-BfOk0ymL.js} +1 -1
- package/dist/tanstack-start/index.d.ts +4 -4
- package/dist/tanstack-start/index.js +2 -2
- package/dist/terminal/index.d.ts +5 -5
- package/dist/terminal/index.js +3 -3
- package/dist/testing/core.d.ts +1 -1
- package/dist/testing/core.js +1 -1
- package/dist/testing/fixtures/index.js +1 -1
- package/dist/testing/index.d.ts +22 -22
- package/dist/testing/index.js +15 -15
- package/dist/testing/saas/index.d.ts +3 -3
- package/dist/testing/saas/index.js +2 -2
- package/dist/testing/saas/permissions.js +1 -1
- package/dist/{tool-refusal-C1UlhU0V.js → tool-refusal-D4spOJ7I.js} +1 -1
- package/dist/trpc/index.d.ts +5 -5
- package/dist/trpc/index.js +3 -3
- package/dist/{type-helpers-C_OnZW8c.d.ts → type-helpers-i1EJ3Eb1.d.ts} +1 -1
- package/dist/{types-CAAN7evk.d.ts → types-3Y8UpFkF.d.ts} +17 -1
- package/dist/{types-B3BOcI0J.d.ts → types-B8qUkGja.d.ts} +2 -2
- package/dist/{types-UfpcY575.d.ts → types-CCEeSCMB.d.ts} +3 -3
- package/dist/{types-AOP5HQku.d.ts → types-CDVXR6YD.d.ts} +1 -1
- package/dist/{types-CJC1aaoJ.d.ts → types-Ck1KOfug.d.ts} +2 -2
- package/dist/{types-BvBbkAu1.d.ts → types-CqcsNCaN.d.ts} +1 -1
- package/dist/{types-CA-A33Q5.d.ts → types-D-JO7lh8.d.ts} +4 -4
- package/dist/{types-DVZNTkU0.d.ts → types-D19MK4t-.d.ts} +3 -3
- package/dist/{types-Sj1U8HMm.d.ts → types-DGf_cpKF.d.ts} +2 -2
- package/dist/{types-e82uzrTn.d.ts → types-DmbfLu2p.d.ts} +4 -4
- package/dist/{types-D29K5ZNP.d.ts → types-o1vu6Ks3.d.ts} +4 -4
- package/dist/unplugin/index.d.ts +1 -1
- package/dist/unplugin/index.js +1 -1
- package/dist/usage-Cl5eb-e1.js +1 -0
- package/dist/{usage-COsGLht5.js → usage-DC0UKe6C.js} +3 -3
- package/dist/{usage-CqcMeQgX.js → usage-DYtRVkcN.js} +1 -1
- package/dist/{validation-error-DpvsBwZJ.d.ts → validation-error-Dx8PipbO.d.ts} +1 -1
- package/dist/{verify-C8G8D5mk.js → verify-Bpj0hauG.js} +8 -8
- package/dist/{version-cache-9Vq5QVFC.d.ts → version-cache-DzNKWiI6.d.ts} +1 -1
- package/dist/{views-TrZYlDnM.js → views-MWmJ6Y4P.js} +1 -1
- package/dist/vue/index.d.ts +5 -5
- package/dist/vue/index.js +3 -3
- package/dist/{waiter-C2cXXLFZ.d.ts → waiter-NK_UuZbb.d.ts} +2 -2
- package/dist/{watch-DXRDBSCu.js → watch-CBHADqBH.js} +1 -1
- package/dist/watch-OYwAPCzx.js +1 -0
- package/dist/webmcp/index.d.ts +1 -1
- package/dist/webmcp/index.js +1 -1
- package/dist/{who-can-BY5d3HPw.js → who-can-KhVWMxtf.js} +1 -1
- package/dist/workflow/index.d.ts +3 -3
- package/dist/workflow/index.js +2 -2
- package/dist/workflow-sdk/index.d.ts +4 -4
- package/dist/{wrap-DpZAbxuD.d.ts → wrap-BHGA-SMM.d.ts} +2 -2
- package/package.json +1 -1
- package/schemas/supabase-manifest-v1.json +1 -1
- package/skills/permdock-approvals/references/stores-and-resume.md +1 -1
- package/skills/permdock-wire/references/adapters.md +3 -1
- package/dist/catalog-BpnjesqX.js +0 -1
- package/dist/collect-CAibhmCi.js +0 -1
- package/dist/powersync-Cqzx25dI.js +0 -1
- package/dist/pull-CUVdB04v.js +0 -1
- package/dist/run-D9N6V5WQ.js +0 -1
- package/dist/supabase-hook-CPBX4dy5.js +0 -1
- package/dist/usage-D1cpHO7p.js +0 -1
- package/dist/watch-DnymTAfe.js +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { r as isRecord, t as compact } from "../compact-CAf557ZB.js";
|
|
2
2
|
import { n as freezeDeep } from "../freeze-jjan0lCv.js";
|
|
3
|
-
import { a as flattenApprovers, o as holder, r as approverLeaves } from "../approvers-
|
|
3
|
+
import { a as flattenApprovers, i as approverManagerKey, o as holder, r as approverLeaves } from "../approvers-BaNwKYgd.js";
|
|
4
4
|
import { t as loadPrincipal } from "../principal-source-C6N60GtM.js";
|
|
5
5
|
import { a as isId, r as idList } from "../expiry-6XByK0dm.js";
|
|
6
6
|
import { c as listPermissions, n as findPermission, o as isPermission } from "../permission-registry-B8tYxPIt.js";
|
|
@@ -10,27 +10,30 @@ import { r as sha256Digest } from "../sha256-C-4WXKIu.js";
|
|
|
10
10
|
import { t as decideSupportSession } from "../support-session-BsmPCbz8.js";
|
|
11
11
|
import { d as scopeList } from "../scopes-BSdYaGHs.js";
|
|
12
12
|
import { o as flattenGrantee } from "../grantee-Dke-9rd1.js";
|
|
13
|
-
import { n as asApprover } from "../approval-normalize-
|
|
13
|
+
import { n as asApprover } from "../approval-normalize-CUjgSsOl.js";
|
|
14
|
+
import { n as isOperationEffect } from "../operations-Bm9HFecz.js";
|
|
14
15
|
import { r as isSubject, t as anonymousSubject } from "../subject-C7RddW0G.js";
|
|
15
|
-
import { I as decisionTenant } from "../evaluate-
|
|
16
|
-
import { _ as claimsFirst } from "../instance-snapshot-
|
|
16
|
+
import { I as decisionTenant } from "../evaluate-Czbj7thS.js";
|
|
17
|
+
import { _ as claimsFirst } from "../instance-snapshot-BWa71my8.js";
|
|
17
18
|
import { a as permissionStates } from "../checks-fyDOhcz0.js";
|
|
18
|
-
import { a as delegatedScopeMap, s as scopesReaching } from "../permdock-
|
|
19
|
+
import { a as delegatedScopeMap, s as scopesReaching } from "../permdock-D-_WrdKu.js";
|
|
20
|
+
import { s as ApprovalError } from "../types-CcUXciSj.js";
|
|
21
|
+
import { t as applyApprovalVerdict } from "../store-DmVqy74I.js";
|
|
19
22
|
import { i as linkPolicyViolation, n as capabilityOf, r as capabilitySubject } from "../capability-zN6T9fxe.js";
|
|
20
23
|
import { r as credentialSubject, s as parseCredential } from "../credential-B3Hj4puZ.js";
|
|
21
|
-
import { s as resumeDecision } from "../helpers-
|
|
24
|
+
import { h as managerKeys, s as resumeDecision } from "../helpers-DmqGy63f.js";
|
|
22
25
|
import { t as AccessReviewError } from "../errors-BDUwg2qC.js";
|
|
23
26
|
import { t as parseApprovalRequest } from "../parse-request-DOBVaeiQ.js";
|
|
24
27
|
import { n as parseApprovalHeader } from "../approval-header-8QV6MU4H.js";
|
|
25
28
|
import { i as snapshotTag } from "../snapshot-cache-B66h7FBK.js";
|
|
26
|
-
import { t as buildInstance } from "../build-instance-
|
|
29
|
+
import { t as buildInstance } from "../build-instance-BFMFQdE_.js";
|
|
27
30
|
import { n as NO_GRANT } from "../decision-CaG5_eNJ.js";
|
|
28
31
|
import { t as policyRowConditionKeys } from "../row-conditions-BAGHOmVq.js";
|
|
29
|
-
import { n as subscribersFor } from "../audience-
|
|
32
|
+
import { n as subscribersFor } from "../audience-B4YR9UpV.js";
|
|
30
33
|
import { i as qualifySqlTable, l as sqlIdent, s as quoteSqlLiteral } from "../sql-0WjxIp9g.js";
|
|
31
34
|
import { o as junctionMembershipSource } from "../sources-C4vkzZJV.js";
|
|
32
35
|
import { c as subjectFromSupabaseSession, t as callRpc } from "../postgrest-BrjrckDG.js";
|
|
33
|
-
import { n as parseSupabaseManifest, t as hasTokenHook } from "../manifest-
|
|
36
|
+
import { n as parseSupabaseManifest, t as hasTokenHook } from "../manifest-BdzBobNK.js";
|
|
34
37
|
import { t as parseCatalog } from "../parse-UTC-sDrt.js";
|
|
35
38
|
import { n as activeTenantMismatch, t as activeOrganizationFrom } from "../active-tenant-DVee32-T.js";
|
|
36
39
|
import { AsyncResult, dbError } from "better-supabase";
|
|
@@ -201,14 +204,15 @@ async function unwrap(result, call) {
|
|
|
201
204
|
return awaited.data;
|
|
202
205
|
}
|
|
203
206
|
/** Every block record carrying a PermDock request, newest first, capped. */
|
|
204
|
-
async function scan(approvals, found) {
|
|
207
|
+
async function scan(approvals, found, tenantless) {
|
|
205
208
|
const out = [];
|
|
206
209
|
let before;
|
|
207
210
|
for (let scanned = 0; scanned < MAX_SCANNED; scanned += PAGE) {
|
|
208
211
|
const page = await unwrap(approvals.list({
|
|
209
212
|
status: null,
|
|
210
213
|
pageSize: PAGE,
|
|
211
|
-
...before === void 0 ? {} : { before }
|
|
214
|
+
...before === void 0 ? {} : { before },
|
|
215
|
+
...tenantless ? { tenantless } : {}
|
|
212
216
|
}), "list");
|
|
213
217
|
for (const record of page) {
|
|
214
218
|
const request = requestOf(record);
|
|
@@ -240,14 +244,23 @@ function matchesQuery(request, query) {
|
|
|
240
244
|
* block's own approve and reject flow. `create` files the request on the
|
|
241
245
|
* resource under the permission's action, with the PermDock request in
|
|
242
246
|
* `payload.permdock` and its `fingerprint`. `get`, `getById` and `list` read
|
|
243
|
-
* the block's latest 2,000 requests in the block's tenant
|
|
244
|
-
*
|
|
245
|
-
* `
|
|
246
|
-
*
|
|
247
|
+
* the block's latest 2,000 requests in the block's tenant, and with
|
|
248
|
+
* `tenantless` the latest 2,000 without one. `consume` calls the block's
|
|
249
|
+
* `consume`, which refuses a second use and another fingerprint. `resolve`
|
|
250
|
+
* checks the verdict against the PermDock request, then calls the block's
|
|
251
|
+
* `approve` or `reject` with `decidedBy` set to the approver, so a service-role
|
|
252
|
+
* client records the user who decided; without `approve` and `reject` on the
|
|
253
|
+
* client it throws. `expire` answers 0, since the block expires requests
|
|
247
254
|
* itself.
|
|
248
255
|
*/
|
|
249
|
-
function blockApprovalStore(approvals) {
|
|
250
|
-
const
|
|
256
|
+
function blockApprovalStore(approvals, options = {}) {
|
|
257
|
+
const tenantless = options.tenantless === true;
|
|
258
|
+
const scanAll = async (found) => {
|
|
259
|
+
const inTenant = await scan(approvals, found, false);
|
|
260
|
+
if (!tenantless || inTenant.some(found)) return inTenant;
|
|
261
|
+
return [...inTenant, ...await scan(approvals, found, true)];
|
|
262
|
+
};
|
|
263
|
+
const byToken = async (token) => (await scanAll(({ request }) => request.token === token)).find(({ request }) => request.token === token);
|
|
251
264
|
return Object.freeze({
|
|
252
265
|
name: "better-supabase-approvals",
|
|
253
266
|
async create(request) {
|
|
@@ -258,23 +271,32 @@ function blockApprovalStore(approvals) {
|
|
|
258
271
|
action: actionOf(request.permission),
|
|
259
272
|
reason: request.detail,
|
|
260
273
|
payload: { permdock: request },
|
|
261
|
-
fingerprint: request.fingerprint
|
|
274
|
+
fingerprint: request.fingerprint,
|
|
275
|
+
tenantless: tenantless && decisionTenant(request.subject, request.membership) === void 0 ? true : void 0
|
|
262
276
|
})), "request");
|
|
263
277
|
},
|
|
264
278
|
async get(token) {
|
|
265
279
|
return (await byToken(token))?.request ?? null;
|
|
266
280
|
},
|
|
267
281
|
async getById(id) {
|
|
268
|
-
return (await
|
|
282
|
+
return (await scanAll(({ request }) => request.id === id)).find(({ request }) => request.id === id)?.request ?? null;
|
|
269
283
|
},
|
|
270
|
-
resolve() {
|
|
271
|
-
|
|
284
|
+
async resolve(token, verdict) {
|
|
285
|
+
const decide = verdict.status === "approved" ? approvals.approve : approvals.reject;
|
|
286
|
+
if (decide === void 0) throw new Error("PermDock: blockApprovalStore resolves only with the approvals block's approve and reject on the client");
|
|
287
|
+
const found = await byToken(token);
|
|
288
|
+
if (found === void 0) throw new ApprovalError("approval-not-found", "approval was not found");
|
|
289
|
+
applyApprovalVerdict(found.request, verdict);
|
|
290
|
+
const by = verdict.by.principal?.id;
|
|
291
|
+
const next = requestOf(await unwrap(decide(found.record.id, verdict.note, compact({ decidedBy: by })), verdict.status === "approved" ? "approve" : "reject"));
|
|
292
|
+
if (next === null) throw new ApprovalError("approval-not-found", "approval was not found");
|
|
293
|
+
return next;
|
|
272
294
|
},
|
|
273
295
|
async list(query) {
|
|
274
296
|
const limit = Math.min(Math.max(query.limit ?? 50, 1), 200);
|
|
275
297
|
const offset = query.cursor === void 0 ? 0 : Number(query.cursor);
|
|
276
298
|
if (!Number.isSafeInteger(offset) || offset < 0) return { items: [] };
|
|
277
|
-
const all = (await
|
|
299
|
+
const all = (await scanAll(() => false)).map(({ request }) => request).filter((request) => matchesQuery(request, query)).toReversed().toSorted((a, b) => Date.parse(a.createdAt) - Date.parse(b.createdAt));
|
|
278
300
|
const items = all.slice(offset, offset + limit);
|
|
279
301
|
return offset + limit < all.length ? {
|
|
280
302
|
items,
|
|
@@ -336,41 +358,243 @@ function stageApprovers(approvers, roleScope) {
|
|
|
336
358
|
of: leaves
|
|
337
359
|
};
|
|
338
360
|
}
|
|
339
|
-
function
|
|
361
|
+
function quorumOf(step) {
|
|
362
|
+
if (step.required !== "all") return step.required;
|
|
363
|
+
const { users = [], permission, role, team, manager } = step.approvers;
|
|
364
|
+
if (users.length === 0 || permission !== void 0 || role !== void 0 || team !== void 0 || manager === true) throw new TypeError("PermDock: an approval policy step with required \"all\" needs users and no other approvers, since the block counts other holders when a request is filed");
|
|
365
|
+
return users.length;
|
|
366
|
+
}
|
|
367
|
+
const NUMERIC = /^-?\d+(?:\.\d+)?$/u;
|
|
368
|
+
function isScalar(value) {
|
|
369
|
+
return typeof value === "string" || typeof value === "number" || typeof value === "boolean";
|
|
370
|
+
}
|
|
371
|
+
function variants(value) {
|
|
372
|
+
if (typeof value === "string" && NUMERIC.test(value)) return [value, Number(value)];
|
|
373
|
+
return typeof value === "number" ? [value, String(value)] : [value];
|
|
374
|
+
}
|
|
375
|
+
function numberOf(value) {
|
|
376
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
377
|
+
return typeof value === "string" && NUMERIC.test(value) ? Number(value) : void 0;
|
|
378
|
+
}
|
|
379
|
+
const ORDER = {
|
|
380
|
+
gt: "gt",
|
|
381
|
+
gte: "gte",
|
|
382
|
+
lt: "lt",
|
|
383
|
+
lte: "lte"
|
|
384
|
+
};
|
|
385
|
+
function ruleCondition(field, operator, value) {
|
|
386
|
+
const list = Array.isArray(value) && value.every(isScalar) ? value : [];
|
|
387
|
+
const contains = (item) => ({
|
|
388
|
+
op: "contains",
|
|
389
|
+
field,
|
|
390
|
+
value: item
|
|
391
|
+
});
|
|
392
|
+
switch (operator) {
|
|
393
|
+
case "": return true;
|
|
394
|
+
case "is":
|
|
395
|
+
case "eq": return isScalar(value) ? {
|
|
396
|
+
op: "or",
|
|
397
|
+
conditions: variants(value).map((item) => ({
|
|
398
|
+
op: "eq",
|
|
399
|
+
field,
|
|
400
|
+
value: item
|
|
401
|
+
}))
|
|
402
|
+
} : void 0;
|
|
403
|
+
case "is_not":
|
|
404
|
+
case "neq": return isScalar(value) ? {
|
|
405
|
+
op: "and",
|
|
406
|
+
conditions: variants(value).map((item) => ({
|
|
407
|
+
op: "ne",
|
|
408
|
+
field,
|
|
409
|
+
value: item
|
|
410
|
+
}))
|
|
411
|
+
} : void 0;
|
|
412
|
+
case "gt":
|
|
413
|
+
case "gte":
|
|
414
|
+
case "lt":
|
|
415
|
+
case "lte": {
|
|
416
|
+
const bound = numberOf(value);
|
|
417
|
+
return bound === void 0 ? void 0 : {
|
|
418
|
+
op: ORDER[operator],
|
|
419
|
+
field,
|
|
420
|
+
value: bound
|
|
421
|
+
};
|
|
422
|
+
}
|
|
423
|
+
case "between":
|
|
424
|
+
case "not_between": {
|
|
425
|
+
const [low, high] = Array.isArray(value) ? value.map(numberOf) : [void 0, void 0];
|
|
426
|
+
if (low === void 0 || high === void 0) return;
|
|
427
|
+
const between = {
|
|
428
|
+
op: "and",
|
|
429
|
+
conditions: [{
|
|
430
|
+
op: "gte",
|
|
431
|
+
field,
|
|
432
|
+
value: low
|
|
433
|
+
}, {
|
|
434
|
+
op: "lte",
|
|
435
|
+
field,
|
|
436
|
+
value: high
|
|
437
|
+
}]
|
|
438
|
+
};
|
|
439
|
+
return operator === "between" ? between : {
|
|
440
|
+
op: "not",
|
|
441
|
+
condition: between
|
|
442
|
+
};
|
|
443
|
+
}
|
|
444
|
+
case "is_any_of":
|
|
445
|
+
case "is_none_of": return list.length === 0 ? void 0 : {
|
|
446
|
+
op: operator === "is_any_of" ? "in" : "notIn",
|
|
447
|
+
field,
|
|
448
|
+
value: list.flatMap(variants)
|
|
449
|
+
};
|
|
450
|
+
case "contains": return typeof value === "string" ? contains(value) : void 0;
|
|
451
|
+
case "not_contains": return typeof value === "string" ? {
|
|
452
|
+
op: "not",
|
|
453
|
+
condition: contains(value)
|
|
454
|
+
} : void 0;
|
|
455
|
+
case "has_any_of":
|
|
456
|
+
case "has_all_of":
|
|
457
|
+
case "has_none_of": {
|
|
458
|
+
if (list.length === 0) return;
|
|
459
|
+
const each = list.map(contains);
|
|
460
|
+
if (operator === "has_all_of") return {
|
|
461
|
+
op: "and",
|
|
462
|
+
conditions: each
|
|
463
|
+
};
|
|
464
|
+
const any = {
|
|
465
|
+
op: "or",
|
|
466
|
+
conditions: each
|
|
467
|
+
};
|
|
468
|
+
return operator === "has_any_of" ? any : {
|
|
469
|
+
op: "not",
|
|
470
|
+
condition: any
|
|
471
|
+
};
|
|
472
|
+
}
|
|
473
|
+
case "empty": return {
|
|
474
|
+
op: "isNull",
|
|
475
|
+
field,
|
|
476
|
+
value: true
|
|
477
|
+
};
|
|
478
|
+
case "not_empty": return {
|
|
479
|
+
op: "isNull",
|
|
480
|
+
field,
|
|
481
|
+
value: false
|
|
482
|
+
};
|
|
483
|
+
default: return;
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
function treeCondition(node) {
|
|
487
|
+
if (!isRecord(node)) return;
|
|
488
|
+
let condition;
|
|
489
|
+
if (node["type"] === "group") {
|
|
490
|
+
const rules = node["rules"];
|
|
491
|
+
const combinator = node["combinator"];
|
|
492
|
+
if (!Array.isArray(rules) || combinator !== "and" && combinator !== "or") return;
|
|
493
|
+
const parts = [];
|
|
494
|
+
for (const rule of rules) {
|
|
495
|
+
const part = treeCondition(rule);
|
|
496
|
+
if (part === void 0) return;
|
|
497
|
+
if (part === true) {
|
|
498
|
+
if (combinator === "or") return true;
|
|
499
|
+
continue;
|
|
500
|
+
}
|
|
501
|
+
parts.push(part);
|
|
502
|
+
}
|
|
503
|
+
condition = parts.length === 0 ? true : {
|
|
504
|
+
op: combinator,
|
|
505
|
+
conditions: parts
|
|
506
|
+
};
|
|
507
|
+
} else if (node["type"] === "rule") {
|
|
508
|
+
const path = node["path"];
|
|
509
|
+
const operator = node["operator"];
|
|
510
|
+
if (!Array.isArray(path) || path.length !== 1 || typeof path[0] !== "string" || typeof operator !== "string") return;
|
|
511
|
+
condition = ruleCondition(path[0], operator, node["value"]);
|
|
512
|
+
}
|
|
513
|
+
if (node["negated"] !== true || condition === void 0) return condition;
|
|
514
|
+
return condition === true ? void 0 : {
|
|
515
|
+
op: "not",
|
|
516
|
+
condition
|
|
517
|
+
};
|
|
518
|
+
}
|
|
519
|
+
function effectsOf(effect, options) {
|
|
520
|
+
if (effect === void 0) return;
|
|
521
|
+
const mapped = options.effects !== void 0 && Object.hasOwn(options.effects, effect) ? options.effects[effect] : void 0;
|
|
522
|
+
if (mapped !== void 0) return mapped.length === 0 ? void 0 : mapped;
|
|
523
|
+
return isOperationEffect(effect) ? [effect] : void 0;
|
|
524
|
+
}
|
|
525
|
+
function keysOf(entry, permissions) {
|
|
526
|
+
if (permissions === void 0) throw new TypeError("PermDock: an approval policy for every subject type or action needs blockApprovalPolicySource's permissions, or an effect PermDock knows");
|
|
527
|
+
return listPermissions(permissions).map((permission) => permission.key).filter((key) => {
|
|
528
|
+
const dot = key.lastIndexOf(".");
|
|
529
|
+
return dot > 0 && (entry.subjectType === "*" || key.slice(0, dot) === entry.subjectType) && (entry.action === "*" || key.slice(dot + 1) === entry.action);
|
|
530
|
+
});
|
|
531
|
+
}
|
|
532
|
+
function policiesOf(entry, options) {
|
|
533
|
+
const roleScope = options.roleScope ?? "tenant";
|
|
340
534
|
const approval = compact({
|
|
341
535
|
stages: entry.steps.length === 0 ? void 0 : entry.steps.map((step) => ({
|
|
342
536
|
by: stageApprovers(step.approvers, roleScope),
|
|
343
|
-
quorum: step
|
|
537
|
+
quorum: quorumOf(step)
|
|
344
538
|
})),
|
|
345
539
|
combine: entry.steps.length > 1 ? "sequential" : void 0,
|
|
346
540
|
mode: entry.mode === "confirm" && entry.selfApproval ? "confirm" : void 0,
|
|
347
541
|
ttl: entry.expiresIn === void 0 ? void 0 : intervalSeconds(entry.expiresIn)
|
|
348
542
|
});
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
tenant: entry.organizationId,
|
|
543
|
+
const tree = entry.conditions === void 0 || entry.conditions === null ? true : treeCondition(entry.conditions);
|
|
544
|
+
const shared = compact({
|
|
545
|
+
tenant: entry.organizationId ?? void 0,
|
|
546
|
+
check: tree === true || tree === void 0 ? void 0 : tree,
|
|
352
547
|
approval
|
|
353
|
-
};
|
|
548
|
+
});
|
|
549
|
+
if (!(entry.subjectType === "*" || entry.action === "*")) return [{
|
|
550
|
+
...shared,
|
|
551
|
+
permission: `${entry.subjectType}.${entry.action}`
|
|
552
|
+
}];
|
|
553
|
+
const effects = effectsOf(entry.effect, options);
|
|
554
|
+
if (effects !== void 0) return [{
|
|
555
|
+
...shared,
|
|
556
|
+
effects
|
|
557
|
+
}];
|
|
558
|
+
return keysOf(entry, options.permissions).map((permission) => ({
|
|
559
|
+
...shared,
|
|
560
|
+
permission
|
|
561
|
+
}));
|
|
562
|
+
}
|
|
563
|
+
function enabledIn(tenants) {
|
|
564
|
+
return (entry) => isRecord(entry) && entry["enabled"] === true && (entry["organizationId"] === null || typeof entry["organizationId"] === "string" && tenants.includes(entry["organizationId"]));
|
|
565
|
+
}
|
|
566
|
+
async function listed(approvals, platform) {
|
|
567
|
+
const entries = await unwrap(approvals.listPolicies(platform ? {
|
|
568
|
+
pageSize: 200,
|
|
569
|
+
platform
|
|
570
|
+
} : { pageSize: 200 }), "listPolicies");
|
|
571
|
+
if (!Array.isArray(entries)) throw new TypeError("PermDock: listPolicies answered no list");
|
|
572
|
+
return entries.map((entry) => entry);
|
|
354
573
|
}
|
|
355
574
|
/**
|
|
356
|
-
* An `ApprovalPolicySource` over the approvals block's tenant policies,
|
|
357
|
-
*
|
|
358
|
-
* the
|
|
359
|
-
*
|
|
360
|
-
*
|
|
361
|
-
*
|
|
362
|
-
*
|
|
363
|
-
*
|
|
364
|
-
*
|
|
575
|
+
* An `ApprovalPolicySource` over the approvals block's tenant policies, and
|
|
576
|
+
* with `platform` its platform policies, so a PermDock decision asks for
|
|
577
|
+
* approval wherever the block would. A policy keys the permission
|
|
578
|
+
* `<subjectType>.<action>`; a platform policy has no tenant. Its steps become
|
|
579
|
+
* sequential stages whose approvers are any of the step's permission, role,
|
|
580
|
+
* users and manager; `required: "all"` over users needs each of them. `confirm`
|
|
581
|
+
* with `selfApproval` lets the principal approve; `expiresIn` caps the
|
|
582
|
+
* request's `ttl`. `conditions` become a `check` over the call's input, or the
|
|
583
|
+
* row without one; a tree PermDock cannot express is dropped, so the policy
|
|
584
|
+
* applies to every call: stricter, never looser. A `*` subject type or action
|
|
585
|
+
* with an effect PermDock knows matches every operation with that effect, and
|
|
586
|
+
* without one expands over `permissions`. A concrete policy's `effect` is
|
|
587
|
+
* ignored, so it applies to every call of its permission. A step with only a
|
|
588
|
+
* `team` approver, `required: "all"` over anything but users, an interval it
|
|
589
|
+
* cannot read or a failed read makes the source fail, and every call an allow
|
|
590
|
+
* would grant denies.
|
|
365
591
|
*/
|
|
366
592
|
function blockApprovalPolicySource(approvals, options = {}) {
|
|
367
|
-
const roleScope = options.roleScope ?? "tenant";
|
|
368
593
|
return Object.freeze({
|
|
369
594
|
name: "better-supabase-approvals",
|
|
370
595
|
async approvalPoliciesFor(query) {
|
|
371
|
-
const
|
|
372
|
-
|
|
373
|
-
return entries.filter((entry) => isRecord(entry) && entry["enabled"] === true && typeof entry["organizationId"] === "string" && query.tenants.includes(entry["organizationId"])).map((entry) => policyOf(entry, roleScope));
|
|
596
|
+
const [own, platform] = await Promise.all([listed(approvals, false), options.platform === true ? listed(approvals, true) : []]);
|
|
597
|
+
return [...platform, ...own].filter(enabledIn(query.tenants)).flatMap((entry) => policiesOf(entry, options));
|
|
374
598
|
}
|
|
375
599
|
});
|
|
376
600
|
}
|
|
@@ -562,6 +786,15 @@ function subjectFromBetterSupabase(session, options = {}) {
|
|
|
562
786
|
}
|
|
563
787
|
//#endregion
|
|
564
788
|
//#region src/better-supabase/permdock-for.ts
|
|
789
|
+
/** The options a `permdockFor` resolver already holds. */
|
|
790
|
+
const RESOLVER_OWNS = [
|
|
791
|
+
"subject",
|
|
792
|
+
"memberships",
|
|
793
|
+
"version",
|
|
794
|
+
"versions",
|
|
795
|
+
"instances",
|
|
796
|
+
"options"
|
|
797
|
+
];
|
|
565
798
|
function isResult(source) {
|
|
566
799
|
return isRecord(source) && Object.hasOwn(source, "session") && Object.hasOwn(source, "authzVersion") && !Object.hasOwn(source, "kind");
|
|
567
800
|
}
|
|
@@ -601,7 +834,7 @@ function permdockResolver(options) {
|
|
|
601
834
|
byCache.set(versions, created);
|
|
602
835
|
return created;
|
|
603
836
|
};
|
|
604
|
-
|
|
837
|
+
const resolve = async (source, query, runtimeVersions) => {
|
|
605
838
|
const result = isResult(source) ? source : void 0;
|
|
606
839
|
const signedOut = result?.sessionActive === false;
|
|
607
840
|
const user = subjectOf(source, result, signedOut, options.subject);
|
|
@@ -622,6 +855,22 @@ function permdockResolver(options) {
|
|
|
622
855
|
});
|
|
623
856
|
return permdock;
|
|
624
857
|
};
|
|
858
|
+
const sources = (versions) => sourcesFor(versions ?? options.versions);
|
|
859
|
+
return Object.freeze(Object.assign(resolve, { sources }));
|
|
860
|
+
}
|
|
861
|
+
/**
|
|
862
|
+
* The resolver an adapter builds instances with: the app's `permdockFor`, or
|
|
863
|
+
* one built from the adapter's own options. `permdockFor` with any option it
|
|
864
|
+
* already holds throws a `TypeError`, since two sources of the same option
|
|
865
|
+
* would disagree.
|
|
866
|
+
*/
|
|
867
|
+
function resolverOf(options, adapter) {
|
|
868
|
+
const shared = options.permdockFor;
|
|
869
|
+
if (shared === void 0) return permdockResolver(options);
|
|
870
|
+
const clash = RESOLVER_OWNS.find((key) => options[key] !== void 0);
|
|
871
|
+
if (clash !== void 0) throw new TypeError(`PermDock: ${adapter} takes ${clash} from permdockFor; pass it to permdockFor instead`);
|
|
872
|
+
const resolve = (source, query, versions) => shared(source, query, versions);
|
|
873
|
+
return Object.freeze(Object.assign(resolve, { sources: shared.sources }));
|
|
625
874
|
}
|
|
626
875
|
/**
|
|
627
876
|
* One resolver for every instance of the app: `permdockFor(await
|
|
@@ -629,11 +878,15 @@ function permdockResolver(options) {
|
|
|
629
878
|
* bsb.getAccess(...))`. A bootstrap or access result passes its `authzVersion`
|
|
630
879
|
* as `version.known`, so the instance reads no version, and a `sessionActive:
|
|
631
880
|
* false` bootstrap is anonymous. With `instances`, a subject at an unchanged
|
|
632
|
-
* version reuses its instance across requests.
|
|
881
|
+
* version reuses its instance across requests. Pass the same resolver to
|
|
882
|
+
* `authorizer({ permdockFor })`, `authorizationHooks({ permdockFor })` and,
|
|
883
|
+
* through `permdockFor.sources()`, to every other adapter's options, so they
|
|
884
|
+
* share one instance per subject and version.
|
|
633
885
|
*/
|
|
634
886
|
function permdockFor(options) {
|
|
635
887
|
const resolve = permdockResolver(options);
|
|
636
|
-
|
|
888
|
+
const call = (source, query, versions) => resolve(source, typeof query === "string" || query === null ? { tenant: query } : query ?? {}, versions);
|
|
889
|
+
return Object.freeze(Object.assign(call, { sources: resolve.sources }));
|
|
637
890
|
}
|
|
638
891
|
/**
|
|
639
892
|
* One `{ allowed, outcome, reason? }` per named check for `input`, from one
|
|
@@ -785,22 +1038,22 @@ function grants$1(permdock, key) {
|
|
|
785
1038
|
return permission !== void 0 && permdock.decide(permission, void 0).outcome === "granted";
|
|
786
1039
|
}
|
|
787
1040
|
/**
|
|
788
|
-
* A list matches when every entry does, `anyOf` when one does;
|
|
789
|
-
* match nobody, as in SQL.
|
|
1041
|
+
* A list matches when every entry does, `anyOf` when one does; `manager` when
|
|
1042
|
+
* its key is in `managed`; other leaves match nobody, as in SQL.
|
|
790
1043
|
*/
|
|
791
|
-
function matches(approvers, userId, permdock) {
|
|
1044
|
+
function matches(approvers, userId, permdock, managed) {
|
|
792
1045
|
const items = flattenApprovers(approvers);
|
|
793
1046
|
return items.length > 0 && items.every((item) => {
|
|
794
1047
|
switch (item.kind) {
|
|
795
1048
|
case "user": return item.id === userId;
|
|
796
1049
|
case "permission": return grants$1(permdock, item.permission);
|
|
797
|
-
case "any-of": return item.of.some((entry) => matches(entry, userId, permdock));
|
|
1050
|
+
case "any-of": return item.of.some((entry) => matches(entry, userId, permdock, managed));
|
|
1051
|
+
case "manager": return managed.has(approverManagerKey(item));
|
|
798
1052
|
case "actor":
|
|
799
1053
|
case "anyone":
|
|
800
1054
|
case "assurance":
|
|
801
1055
|
case "authenticated":
|
|
802
1056
|
case "inherit":
|
|
803
|
-
case "manager":
|
|
804
1057
|
case "plan":
|
|
805
1058
|
case "relation":
|
|
806
1059
|
case "role": return false;
|
|
@@ -822,12 +1075,12 @@ function matches(approvers, userId, permdock) {
|
|
|
822
1075
|
*/
|
|
823
1076
|
function authorizationHooks(options) {
|
|
824
1077
|
const { policy } = options;
|
|
825
|
-
const resolve =
|
|
1078
|
+
const resolve = resolverOf(options, "authorizationHooks");
|
|
826
1079
|
const instance = async (claims, tenant) => {
|
|
827
1080
|
const permdock = await resolve({
|
|
828
1081
|
kind: "user",
|
|
829
1082
|
claims
|
|
830
|
-
}, tenant);
|
|
1083
|
+
}, { tenant: tenant ?? null });
|
|
831
1084
|
if (permdock.subject.principal === null) return null;
|
|
832
1085
|
return tenant === null || tenant === void 0 || permdock.subject.principal.tenant === tenant ? permdock : null;
|
|
833
1086
|
};
|
|
@@ -875,7 +1128,10 @@ function authorizationHooks(options) {
|
|
|
875
1128
|
const given = approvers[request.kind];
|
|
876
1129
|
if (given === void 0 || approver.claims["sub"] !== approver.userId) return false;
|
|
877
1130
|
const permdock = await instance(approver.claims, request.tenant);
|
|
878
|
-
|
|
1131
|
+
if (permdock === null) return false;
|
|
1132
|
+
const wanted = asApprover(given);
|
|
1133
|
+
const managed = request.requester === void 0 ? [] : await managerKeys(approverLeaves(wanted), request.requester, approver.userId, compact({ relations: resolve.sources().relations }));
|
|
1134
|
+
return matches(wanted, approver.userId, permdock, new Set(managed));
|
|
879
1135
|
} catch {
|
|
880
1136
|
return false;
|
|
881
1137
|
}
|
|
@@ -937,6 +1193,8 @@ function authorizationHooks(options) {
|
|
|
937
1193
|
//#region src/better-supabase/approvers.ts
|
|
938
1194
|
/** `rls.approvals`' approver check, executable by `authenticated`. */
|
|
939
1195
|
const IS_APPROVER = "permdock_is_approver";
|
|
1196
|
+
/** The manager walk `rls.approvals.managers` writes. */
|
|
1197
|
+
const MANAGES = "permdock_manages";
|
|
940
1198
|
/**
|
|
941
1199
|
* The resource a cover's `resources` names for a request kind: `job` for
|
|
942
1200
|
* `job.update`, else the kind.
|
|
@@ -948,14 +1206,20 @@ function resourceOf(kind) {
|
|
|
948
1206
|
/**
|
|
949
1207
|
* better-supabase's `isApprover` template: one `case` over `{kind}` whose
|
|
950
1208
|
* branches call `permdock_is_approver` with the kind's approvers as JSON. A
|
|
951
|
-
* kind with no branch is `false`.
|
|
952
|
-
*
|
|
1209
|
+
* kind with no branch is `false`. With `requestApprovers`, every call is the
|
|
1210
|
+
* five-argument form, which also gets better-supabase's `{approvers}`, the
|
|
1211
|
+
* request's current approvers. Only `user`, `holder` and `anyOf` approvers, and
|
|
1212
|
+
* `manager` with `rls.approvals.managers`, match in SQL; other leaves are
|
|
1213
|
+
* reported and match nobody.
|
|
953
1214
|
*/
|
|
954
1215
|
function isApproverTemplate(input) {
|
|
955
1216
|
const problems = [];
|
|
956
1217
|
if (!input.listed) return { problems: [`approvers needs ${input.schema}.${IS_APPROVER}, which \`permdock rls generate\` writes with rls.approvals. Run it, then \`permdock supabase inspect --out\`.`] };
|
|
957
1218
|
const fn = `${sqlIdent(input.schema)}.${sqlIdent(IS_APPROVER)}`;
|
|
958
1219
|
const keys = input.catalog === void 0 ? void 0 : new Set(input.catalog.permissions.map((permission) => permission.key));
|
|
1220
|
+
const current = input.requestApprovers === true;
|
|
1221
|
+
if (current && input.covers !== true) return { problems: [`requestApprovers needs the five-argument ${IS_APPROVER}, which \`permdock rls generate\` writes with rls.approvals.delegations or rls.approvals.managers. Set one, run it, then \`permdock supabase inspect --out\`.`] };
|
|
1222
|
+
const passed = current ? ", ({approvers})::jsonb" : "";
|
|
959
1223
|
const branches = [];
|
|
960
1224
|
for (const [kind, given] of Object.entries(input.approvers)) {
|
|
961
1225
|
if (kind === "") {
|
|
@@ -963,24 +1227,28 @@ function isApproverTemplate(input) {
|
|
|
963
1227
|
continue;
|
|
964
1228
|
}
|
|
965
1229
|
const approvers = asApprover(given);
|
|
1230
|
+
const managers = input.managers === true && input.covers === true;
|
|
966
1231
|
for (const leaf of approverLeaves(approvers)) {
|
|
967
1232
|
if (leaf.kind === "user") continue;
|
|
968
|
-
if (leaf.kind
|
|
1233
|
+
if (leaf.kind === "manager") {
|
|
1234
|
+
if (!managers) problems.push(`The ${kind} approvers name a manager approver, which ${IS_APPROVER} checks only with rls.approvals.managers, so it matches nobody. Set rls.approvals.managers, run \`permdock rls generate\`, then \`permdock supabase inspect --out\`.`);
|
|
1235
|
+
} else if (leaf.kind !== "permission") problems.push(`The ${kind} approvers name a ${leaf.kind} approver, which ${IS_APPROVER} cannot check in SQL, so it matches nobody. Use user(), holder(), manager() or anyOf().`);
|
|
969
1236
|
else if (keys !== void 0 && !keys.has(leaf.permission)) problems.push(`The ${kind} approver permission ${leaf.permission} is not in the catalog. Run \`permdock catalog\` after adding it to the policy.`);
|
|
970
1237
|
}
|
|
971
1238
|
const json = `${quoteSqlLiteral(JSON.stringify(approvers))}::jsonb`;
|
|
972
|
-
branches.push(input.covers === true ? `when ${quoteSqlLiteral(kind)} then ${fn}(${json}, ({tenant})::text, ({requester})::text, ${quoteSqlLiteral(resourceOf(kind))})` : `when ${quoteSqlLiteral(kind)} then ${fn}(${json}, ({tenant})::text)`);
|
|
1239
|
+
branches.push(input.covers === true ? `when ${quoteSqlLiteral(kind)} then ${fn}(${json}, ({tenant})::text, ({requester})::text, ${quoteSqlLiteral(resourceOf(kind))}${passed})` : `when ${quoteSqlLiteral(kind)} then ${fn}(${json}, ({tenant})::text)`);
|
|
973
1240
|
}
|
|
974
|
-
if (branches.length === 0) {
|
|
1241
|
+
if (branches.length === 0 && !current) {
|
|
975
1242
|
problems.push("approvers names no kind, so isApprover is not set.");
|
|
976
1243
|
return { problems };
|
|
977
1244
|
}
|
|
978
1245
|
if (!input.rootTenant) problems.push(`The tenant scope "${input.tenantScope}" is not a root scope, and ${IS_APPROVER} checks holder() approvers at the root scope, so they match nobody.`);
|
|
1246
|
+
const otherwise = current ? `${fn}(null::jsonb, ({tenant})::text, ({requester})::text, split_part({kind}, '.', 1)${passed})` : "false";
|
|
979
1247
|
return {
|
|
980
|
-
template: `case {kind} ${branches.join(" ")} else
|
|
1248
|
+
template: branches.length === 0 ? otherwise : `case {kind} ${branches.join(" ")} else ${otherwise} end`,
|
|
981
1249
|
requires: {
|
|
982
1250
|
function: fn,
|
|
983
|
-
args: input.covers === true ? "jsonb, text, text, text" : "jsonb, text",
|
|
1251
|
+
args: current ? "jsonb, text, text, text, jsonb" : input.covers === true ? "jsonb, text, text, text" : "jsonb, text",
|
|
984
1252
|
role: "postgres"
|
|
985
1253
|
},
|
|
986
1254
|
problems
|
|
@@ -1392,12 +1660,14 @@ function authorizationProvider(options) {
|
|
|
1392
1660
|
...options.approvers
|
|
1393
1661
|
};
|
|
1394
1662
|
let isApprover;
|
|
1395
|
-
if (approvers !== void 0) {
|
|
1663
|
+
if (approvers !== void 0 || options.requestApprovers === true) {
|
|
1396
1664
|
const built = isApproverTemplate({
|
|
1397
|
-
approvers,
|
|
1665
|
+
approvers: approvers ?? {},
|
|
1666
|
+
requestApprovers: options.requestApprovers === true,
|
|
1398
1667
|
schema: rls.schema,
|
|
1399
1668
|
listed: helpers.has(IS_APPROVER),
|
|
1400
1669
|
covers: /\bp_requester\b/u.test(helpers.get("permdock_is_approver")?.args ?? ""),
|
|
1670
|
+
managers: helpers.has(MANAGES),
|
|
1401
1671
|
tenantScope,
|
|
1402
1672
|
rootTenant,
|
|
1403
1673
|
catalog
|
|
@@ -1586,7 +1856,7 @@ function authorizer(options) {
|
|
|
1586
1856
|
if (batch) return "read";
|
|
1587
1857
|
return isPermission(request.action) && READ_ACTIONS.has(request.action.action) ? "read" : "write";
|
|
1588
1858
|
};
|
|
1589
|
-
const resolve =
|
|
1859
|
+
const resolve = resolverOf(options, "authorizer");
|
|
1590
1860
|
const instanceFor = (claims, tenant, intent, runtime) => resolve(claims === void 0 ? null : {
|
|
1591
1861
|
kind: "user",
|
|
1592
1862
|
claims
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { t as compact } from "./compact-CAf557ZB.js";
|
|
2
|
-
import { l as withApp } from "./permdock-
|
|
2
|
+
import { l as withApp } from "./permdock-D-_WrdKu.js";
|
|
3
3
|
import { t as composeWraps } from "./wrap-C5PWzgkq.js";
|
|
4
|
-
import { r as instanceOptions } from "./build-instance-
|
|
5
|
-
import { f as invalidSignatureResponse } from "./evaluations-
|
|
4
|
+
import { r as instanceOptions } from "./build-instance-BFMFQdE_.js";
|
|
5
|
+
import { f as invalidSignatureResponse } from "./evaluations-h3KoJAPa.js";
|
|
6
6
|
import { n as tenantScope } from "./adapter-context-OHikyRqV.js";
|
|
7
|
-
import { t as createPermDock } from "./create-
|
|
7
|
+
import { t as createPermDock } from "./create-3A7J9KRR.js";
|
|
8
8
|
//#region src/server/bind.ts
|
|
9
9
|
/**
|
|
10
10
|
* The server kernel with the subject and actor callbacks reading the context
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { Z as Intent, yr as Subject } from "./policy-types-
|
|
2
|
-
import { m as ApprovalStore } from "./types-
|
|
3
|
-
import { t as InstanceOptions } from "./instance-options-
|
|
1
|
+
import { Z as Intent, yr as Subject } from "./policy-types-D-GwfQTc.js";
|
|
2
|
+
import { m as ApprovalStore } from "./types-CqcsNCaN.js";
|
|
3
|
+
import { t as InstanceOptions } from "./instance-options-2sFGSdsf.js";
|
|
4
4
|
import { t as RequestContext } from "./request-context-C2_1lchh.js";
|
|
5
|
-
import { n as PermDockWrap } from "./wrap-
|
|
6
|
-
import { o as OtelWrap } from "./types-
|
|
7
|
-
import { r as PdpFactory } from "./types-
|
|
8
|
-
import { S as TenantOption, _ as WebBotAuthVerifier, t as DeniedResponse } from "./server-types-
|
|
5
|
+
import { n as PermDockWrap } from "./wrap-BHGA-SMM.js";
|
|
6
|
+
import { o as OtelWrap } from "./types-DGf_cpKF.js";
|
|
7
|
+
import { r as PdpFactory } from "./types-B8qUkGja.js";
|
|
8
|
+
import { S as TenantOption, _ as WebBotAuthVerifier, t as DeniedResponse } from "./server-types-3OnXjZ2D.js";
|
|
9
9
|
//#region src/server/bind.d.ts
|
|
10
10
|
/**
|
|
11
11
|
* The options of every framework adapter; `TContext` is what its callbacks
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Kt as Instant, _r as Principal, gt as TokenSigner } from "./policy-types-
|
|
1
|
+
import { Kt as Instant, _r as Principal, gt as TokenSigner } from "./policy-types-D-GwfQTc.js";
|
|
2
2
|
import { f as PermissionTree, u as Permission } from "./permission-types-CAY-GU7e.js";
|
|
3
3
|
//#region src/core/capability.d.ts
|
|
4
4
|
/**
|