@sixb/core 0.1.12 → 0.1.14
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/actions/index.d.ts +2 -2
- package/dist/actions/index.d.ts.map +1 -1
- package/dist/actions/index.js +28 -26
- package/dist/actions/index.js.map +1 -1
- package/dist/actions/read-facade.d.ts +14 -16
- package/dist/actions/read-facade.d.ts.map +1 -1
- package/dist/actions/request.d.ts.map +1 -1
- package/dist/actions/run-dispatch.d.ts +2 -0
- package/dist/actions/run-dispatch.d.ts.map +1 -1
- package/dist/actions/types/context.d.ts +18 -31
- package/dist/actions/types/context.d.ts.map +1 -1
- package/dist/actions/types/params.d.ts +2 -1
- package/dist/actions/types/params.d.ts.map +1 -1
- package/dist/actions/worker.js +1 -1
- package/dist/agents/index.js +41 -39
- package/dist/agents/index.js.map +1 -1
- package/dist/agents/streams/index.js +2 -2
- package/dist/agents/streams/internal.js +2 -2
- package/dist/assert-never.d.ts +6 -0
- package/dist/assert-never.d.ts.map +1 -0
- package/dist/auth/client-address.d.ts +3 -0
- package/dist/auth/client-address.d.ts.map +1 -0
- package/dist/auth/csrf.d.ts +5 -1
- package/dist/auth/csrf.d.ts.map +1 -1
- package/dist/auth/errors.d.ts +12 -0
- package/dist/auth/errors.d.ts.map +1 -1
- package/dist/auth/index.d.ts +4 -3
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +16 -8
- package/dist/auth/index.js.map +1 -1
- package/dist/auth/runtime.d.ts +58 -41
- package/dist/auth/runtime.d.ts.map +1 -1
- package/dist/auth/session-cache.d.ts +10 -3
- package/dist/auth/session-cache.d.ts.map +1 -1
- package/dist/auth/sessions.d.ts +12 -0
- package/dist/auth/sessions.d.ts.map +1 -1
- package/dist/auth/strategy.d.ts +2 -0
- package/dist/auth/strategy.d.ts.map +1 -1
- package/dist/auth/strategy.js +4 -2
- package/dist/auth/strategy.js.map +1 -1
- package/dist/auth/types.d.ts +16 -15
- package/dist/auth/types.d.ts.map +1 -1
- package/dist/authorization/index.js +3 -3
- package/dist/bootstrap/index.d.ts +1 -1
- package/dist/bootstrap/index.d.ts.map +1 -1
- package/dist/bootstrap/index.js +45 -43
- package/dist/bootstrap/index.js.map +1 -1
- package/dist/bootstrap/ontology-type-manifest.d.ts +8 -0
- package/dist/bootstrap/ontology-type-manifest.d.ts.map +1 -1
- package/dist/{chunk-m7cx05vp.js → chunk-00pfcqh4.js} +126 -59
- package/dist/{chunk-m7cx05vp.js.map → chunk-00pfcqh4.js.map} +13 -12
- package/dist/{chunk-nzsy3xrp.js → chunk-16jenmzw.js} +69 -44
- package/dist/{chunk-nzsy3xrp.js.map → chunk-16jenmzw.js.map} +7 -7
- package/dist/{chunk-y3ev53cq.js → chunk-2fv8sajb.js} +2 -2
- package/dist/{chunk-q5gz3g2j.js → chunk-2jntasmh.js} +13 -16
- package/dist/{chunk-q5gz3g2j.js.map → chunk-2jntasmh.js.map} +3 -3
- package/dist/chunk-3a338wrp.js +191 -0
- package/dist/chunk-3a338wrp.js.map +11 -0
- package/dist/{chunk-ybhz3j9g.js → chunk-3fpgxpsq.js} +104 -148
- package/dist/{chunk-ybhz3j9g.js.map → chunk-3fpgxpsq.js.map} +7 -8
- package/dist/{chunk-eyjzgav0.js → chunk-3nx8vj5a.js} +6 -4
- package/dist/chunk-3nx8vj5a.js.map +12 -0
- package/dist/{chunk-5tetw4hn.js → chunk-4tnrzqqh.js} +1 -1
- package/dist/{chunk-3ghw2t5q.js → chunk-4ypbe95r.js} +10 -16
- package/dist/chunk-4ypbe95r.js.map +10 -0
- package/dist/{chunk-2cxv584m.js → chunk-6rzb1g6h.js} +358 -248
- package/dist/chunk-6rzb1g6h.js.map +44 -0
- package/dist/{chunk-7zgecwy1.js → chunk-6x0pqh32.js} +12 -1
- package/dist/{chunk-7zgecwy1.js.map → chunk-6x0pqh32.js.map} +3 -3
- package/dist/{chunk-6ma8dvzc.js → chunk-728fp090.js} +49 -42
- package/dist/chunk-728fp090.js.map +15 -0
- package/dist/chunk-96yw3pwd.js.map +2 -2
- package/dist/{chunk-4k53sm9e.js → chunk-a0073121.js} +59 -59
- package/dist/{chunk-4k53sm9e.js.map → chunk-a0073121.js.map} +5 -5
- package/dist/{chunk-y1ahv8b7.js → chunk-bdhfn0ww.js} +1 -1
- package/dist/{chunk-kept9cdd.js → chunk-bxx3ms5t.js} +1 -1
- package/dist/{chunk-xtfryrfb.js → chunk-cbn96bve.js} +2 -2
- package/dist/{chunk-vsg0g7h9.js → chunk-d8yes9yx.js} +304 -45
- package/dist/chunk-d8yes9yx.js.map +20 -0
- package/dist/{chunk-vpxss818.js → chunk-drz59ve0.js} +9 -8
- package/dist/chunk-drz59ve0.js.map +10 -0
- package/dist/{chunk-7c2g3sz9.js → chunk-dsfw1bdr.js} +5 -5
- package/dist/{chunk-7c2g3sz9.js.map → chunk-dsfw1bdr.js.map} +1 -1
- package/dist/{chunk-qm535afa.js → chunk-dv4ct8mp.js} +66 -24
- package/dist/chunk-dv4ct8mp.js.map +15 -0
- package/dist/{chunk-t7dzd1tm.js → chunk-e2c5yxfe.js} +2 -2
- package/dist/{chunk-p6r1ex7t.js → chunk-ffwvdgk1.js} +5 -13
- package/dist/chunk-ffwvdgk1.js.map +10 -0
- package/dist/{chunk-tg4g4zh0.js → chunk-gct3m1da.js} +9 -9
- package/dist/{chunk-tg4g4zh0.js.map → chunk-gct3m1da.js.map} +3 -3
- package/dist/chunk-h89wz928.js +42 -0
- package/dist/chunk-h89wz928.js.map +10 -0
- package/dist/{chunk-b768c93y.js → chunk-hj0n3c2p.js} +83 -28
- package/dist/{chunk-b768c93y.js.map → chunk-hj0n3c2p.js.map} +5 -5
- package/dist/{chunk-hkw8rykk.js → chunk-ht4a7mjg.js} +74 -4
- package/dist/chunk-ht4a7mjg.js.map +15 -0
- package/dist/{chunk-7qnvhtcd.js → chunk-hxgj4kzd.js} +17 -17
- package/dist/{chunk-7qnvhtcd.js.map → chunk-hxgj4kzd.js.map} +5 -5
- package/dist/{chunk-bg2bs62d.js → chunk-jfdggg1p.js} +5 -5
- package/dist/{chunk-f06sf7rr.js → chunk-k4kkp58d.js} +18 -5
- package/dist/chunk-k4kkp58d.js.map +11 -0
- package/dist/{chunk-e1f1sqba.js → chunk-kxea54yg.js} +3 -3
- package/dist/{chunk-2h63nrde.js → chunk-ky7zpbtt.js} +5 -7
- package/dist/{chunk-2h63nrde.js.map → chunk-ky7zpbtt.js.map} +3 -4
- package/dist/chunk-m4ehq95f.js +9 -0
- package/dist/chunk-m4ehq95f.js.map +10 -0
- package/dist/{chunk-0mza4xb2.js → chunk-m8zkvep1.js} +2 -2
- package/dist/{chunk-xn686q2e.js → chunk-ma1mhh7w.js} +75 -57
- package/dist/{chunk-xn686q2e.js.map → chunk-ma1mhh7w.js.map} +3 -3
- package/dist/{chunk-yxb4c62x.js → chunk-mr60an99.js} +3 -2
- package/dist/{chunk-yxb4c62x.js.map → chunk-mr60an99.js.map} +3 -3
- package/dist/{chunk-g50nxqs5.js → chunk-pvgpckm1.js} +63 -20
- package/dist/chunk-pvgpckm1.js.map +20 -0
- package/dist/{chunk-jjwhy3rs.js → chunk-q2xghyft.js} +5 -5
- package/dist/chunk-rdghfsss.js.map +2 -2
- package/dist/{chunk-bbaa1fet.js → chunk-rzcjp5m2.js} +7 -3
- package/dist/chunk-rzcjp5m2.js.map +25 -0
- package/dist/{chunk-hzw7yv5g.js → chunk-rzkr70gr.js} +5 -1
- package/dist/{chunk-hzw7yv5g.js.map → chunk-rzkr70gr.js.map} +3 -3
- package/dist/{chunk-axndsymr.js → chunk-tw03bsmb.js} +2 -2
- package/dist/{chunk-axndsymr.js.map → chunk-tw03bsmb.js.map} +3 -3
- package/dist/{chunk-y0v18c2j.js → chunk-vef6qa14.js} +2 -2
- package/dist/{chunk-gzt6v1ja.js → chunk-vn3yh259.js} +1 -1
- package/dist/{chunk-sfypc7mk.js → chunk-wn7mznxc.js} +4 -4
- package/dist/{chunk-r5zythxp.js → chunk-wnxabtn4.js} +7 -7
- package/dist/{chunk-4ph94nhd.js → chunk-ww185kt6.js} +2 -2
- package/dist/{chunk-3h7ctayx.js → chunk-xgptywp0.js} +4 -3
- package/dist/chunk-xgptywp0.js.map +11 -0
- package/dist/{chunk-gswwr35f.js → chunk-y487ywrv.js} +4 -4
- package/dist/{chunk-bet1rb9h.js → chunk-y6vnvayj.js} +1 -1
- package/dist/{chunk-x9tmx3fc.js → chunk-ypj2wqtj.js} +3 -6
- package/dist/{chunk-x9tmx3fc.js.map → chunk-ypj2wqtj.js.map} +4 -4
- package/dist/{chunk-3bnt2wna.js → chunk-yvf2jqj8.js} +1 -1
- package/dist/{chunk-g2gezsg5.js → chunk-z9h698s8.js} +1 -1
- package/dist/{chunk-wjffn5m4.js → chunk-zdkcdshk.js} +3 -36
- package/dist/{chunk-wjffn5m4.js.map → chunk-zdkcdshk.js.map} +3 -4
- package/dist/{chunk-bfjv1adk.js → chunk-znw0zvy4.js} +1 -1
- package/dist/edits/types.d.ts +19 -19
- package/dist/edits/types.d.ts.map +1 -1
- package/dist/error-reporting/internal.js +3 -3
- package/dist/errors/catalog.d.ts +4 -0
- package/dist/errors/catalog.d.ts.map +1 -1
- package/dist/errors/internal.js +1 -1
- package/dist/events/envelope.d.ts +0 -12
- package/dist/events/envelope.d.ts.map +1 -1
- package/dist/events/index.d.ts +1 -1
- package/dist/events/index.d.ts.map +1 -1
- package/dist/events/index.js +3 -3
- package/dist/events/service.d.ts +1 -2
- package/dist/events/service.d.ts.map +1 -1
- package/dist/events/toStoredEvent.d.ts +1 -2
- package/dist/events/toStoredEvent.d.ts.map +1 -1
- package/dist/events/types/index.d.ts +2 -1
- package/dist/events/types/index.d.ts.map +1 -1
- package/dist/execution/agent.d.ts +1 -2
- package/dist/execution/agent.d.ts.map +1 -1
- package/dist/execution/agent.js +39 -37
- package/dist/execution/agent.js.map +1 -1
- package/dist/execution/authorized-object-reader.d.ts.map +1 -1
- package/dist/execution/primitive.d.ts +1 -2
- package/dist/execution/primitive.d.ts.map +1 -1
- package/dist/execution/primitive.js +38 -36
- package/dist/execution/primitive.js.map +3 -3
- package/dist/execution/request.d.ts +1 -2
- package/dist/execution/request.d.ts.map +1 -1
- package/dist/execution/request.js +39 -37
- package/dist/execution/request.js.map +3 -3
- package/dist/index.d.ts +6 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +56 -50
- package/dist/index.js.map +1 -1
- package/dist/maintenance/ontology-maintenance.d.ts +11 -1
- package/dist/maintenance/ontology-maintenance.d.ts.map +1 -1
- package/dist/materialization/errors.d.ts +3 -1
- package/dist/materialization/errors.d.ts.map +1 -1
- package/dist/materialization/events.d.ts +27 -2
- package/dist/materialization/events.d.ts.map +1 -1
- package/dist/materializer/edits/commit.d.ts.map +1 -1
- package/dist/materializer/edits/operations.d.ts +2 -1
- package/dist/materializer/edits/operations.d.ts.map +1 -1
- package/dist/materializer/edits/plan.d.ts +2 -2
- package/dist/materializer/edits/plan.d.ts.map +1 -1
- package/dist/materializer/edits/user-refs.d.ts +30 -0
- package/dist/materializer/edits/user-refs.d.ts.map +1 -0
- package/dist/materializer/effective/build-events.d.ts +2 -2
- package/dist/materializer/effective/build-events.d.ts.map +1 -1
- package/dist/materializer/execution/scope.d.ts +11 -3
- package/dist/materializer/execution/scope.d.ts.map +1 -1
- package/dist/materializer/index.js +23 -21
- package/dist/materializer/index.js.map +1 -1
- package/dist/materializer/projections/replacement-plan.d.ts +2 -0
- package/dist/materializer/projections/replacement-plan.d.ts.map +1 -1
- package/dist/materializer/telemetry/plan.d.ts +2 -2
- package/dist/materializer/telemetry/plan.d.ts.map +1 -1
- package/dist/models/execution/index.js +23 -21
- package/dist/models/execution/index.js.map +1 -1
- package/dist/models/index.js +1 -1
- package/dist/objects/execution.d.ts +21 -27
- package/dist/objects/execution.d.ts.map +1 -1
- package/dist/objects/index.js +28 -26
- package/dist/objects/index.js.map +1 -1
- package/dist/objects/query/executor.d.ts.map +1 -1
- package/dist/objects/query/index.js +27 -25
- package/dist/objects/query/index.js.map +1 -1
- package/dist/objects/query/ir.d.ts +8 -1
- package/dist/objects/query/ir.d.ts.map +1 -1
- package/dist/objects/query/scalar-values.d.ts.map +1 -1
- package/dist/objects/query/validate.d.ts.map +1 -1
- package/dist/objects/sdk/object-handle.d.ts +1 -2
- package/dist/objects/sdk/object-handle.d.ts.map +1 -1
- package/dist/objects/sdk/object-set.d.ts +2 -3
- package/dist/objects/sdk/object-set.d.ts.map +1 -1
- package/dist/objects/sdk/query-builder.d.ts +8 -10
- package/dist/objects/sdk/query-builder.d.ts.map +1 -1
- package/dist/objects/sdk/telemetry-channel.d.ts +1 -2
- package/dist/objects/sdk/telemetry-channel.d.ts.map +1 -1
- package/dist/objects/sdk/where.d.ts +2 -3
- package/dist/objects/sdk/where.d.ts.map +1 -1
- package/dist/ontology/builders.d.ts +11 -10
- package/dist/ontology/builders.d.ts.map +1 -1
- package/dist/ontology/index.d.ts +4 -2
- package/dist/ontology/index.d.ts.map +1 -1
- package/dist/ontology/index.js +6 -4
- package/dist/ontology/index.js.map +1 -1
- package/dist/ontology/inference/index.d.ts +34 -22
- package/dist/ontology/inference/index.d.ts.map +1 -1
- package/dist/ontology/internal.d.ts +1 -0
- package/dist/ontology/internal.d.ts.map +1 -1
- package/dist/ontology/internal.js +9 -7
- package/dist/ontology/internal.js.map +1 -1
- package/dist/ontology/primitives.d.ts +38 -0
- package/dist/ontology/primitives.d.ts.map +1 -0
- package/dist/ontology/query-capabilities.d.ts +38 -0
- package/dist/ontology/query-capabilities.d.ts.map +1 -0
- package/dist/ontology/refs.d.ts +23 -2
- package/dist/ontology/refs.d.ts.map +1 -1
- package/dist/ontology/registered.d.ts +16 -0
- package/dist/ontology/registered.d.ts.map +1 -0
- package/dist/ontology/registry.d.ts.map +1 -1
- package/dist/ontology/tokens.d.ts +35 -1
- package/dist/ontology/tokens.d.ts.map +1 -1
- package/dist/ontology/types.d.ts +18 -4
- package/dist/ontology/types.d.ts.map +1 -1
- package/dist/ontology/user-ref.d.ts +35 -0
- package/dist/ontology/user-ref.d.ts.map +1 -0
- package/dist/ontology/validation/definition.d.ts.map +1 -1
- package/dist/ontology/validation/index.d.ts +1 -1
- package/dist/ontology/validation/index.d.ts.map +1 -1
- package/dist/ontology/validation/normalize.d.ts.map +1 -1
- package/dist/ontology/validation/properties.d.ts +6 -1
- package/dist/ontology/validation/properties.d.ts.map +1 -1
- package/dist/ontology/validation/query.d.ts.map +1 -1
- package/dist/ontology/validation/schema.d.ts.map +1 -1
- package/dist/pipelines/index.js +26 -24
- package/dist/pipelines/index.js.map +1 -1
- package/dist/predicates/types.d.ts +53 -3
- package/dist/predicates/types.d.ts.map +1 -1
- package/dist/projections/builders.d.ts +19 -1
- package/dist/projections/builders.d.ts.map +1 -1
- package/dist/projections/internal.js +23 -21
- package/dist/projections/internal.js.map +1 -1
- package/dist/projections/validation.d.ts.map +1 -1
- package/dist/query.js +2 -2
- package/dist/queues/in-memory.d.ts +1 -1
- package/dist/queues/in-memory.d.ts.map +1 -1
- package/dist/runtime/create.d.ts +1 -1
- package/dist/runtime/create.d.ts.map +1 -1
- package/dist/runtime/host.d.ts +5 -5
- package/dist/runtime/host.d.ts.map +1 -1
- package/dist/runtime/index.d.ts +1 -1
- package/dist/runtime/index.d.ts.map +1 -1
- package/dist/runtime/internal.js +27 -25
- package/dist/runtime/internal.js.map +1 -1
- package/dist/runtime/sixb.d.ts +5 -5
- package/dist/runtime/sixb.d.ts.map +1 -1
- package/dist/runtime/types.d.ts +171 -188
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/sandboxes/index.js +5 -5
- package/dist/sandboxes/sandbox.d.ts +4 -1
- package/dist/sandboxes/sandbox.d.ts.map +1 -1
- package/dist/shared/params/types.d.ts +4 -3
- package/dist/shared/params/types.d.ts.map +1 -1
- package/dist/shared/params/user-refs.d.ts +19 -0
- package/dist/shared/params/user-refs.d.ts.map +1 -0
- package/dist/shares/compiler.d.ts.map +1 -1
- package/dist/shares/internal.js +24 -22
- package/dist/shares/internal.js.map +2 -2
- package/dist/storage/action-runs/failure.js +2 -2
- package/dist/storage/action-runs/types.d.ts +1 -1
- package/dist/storage/action-runs/types.d.ts.map +1 -1
- package/dist/storage/agents/provider.js +1 -1
- package/dist/storage/ai-limits/enforcement.js +2 -2
- package/dist/storage/auth/errors.d.ts +1 -1
- package/dist/storage/auth/errors.d.ts.map +1 -1
- package/dist/storage/auth/in-memory/access-tokens.d.ts.map +1 -1
- package/dist/storage/auth/in-memory/auth-storage.d.ts +2 -1
- package/dist/storage/auth/in-memory/auth-storage.d.ts.map +1 -1
- package/dist/storage/auth/in-memory/device-authorizations.d.ts.map +1 -1
- package/dist/storage/auth/in-memory/sessions.d.ts +8 -1
- package/dist/storage/auth/in-memory/sessions.d.ts.map +1 -1
- package/dist/storage/auth/in-memory/shared.d.ts.map +1 -1
- package/dist/storage/auth/index.d.ts +1 -1
- package/dist/storage/auth/index.d.ts.map +1 -1
- package/dist/storage/auth/types.d.ts +77 -20
- package/dist/storage/auth/types.d.ts.map +1 -1
- package/dist/storage/connector-connections/provider.js +1 -1
- package/dist/storage/executions/provider.js +1 -1
- package/dist/storage/file-upload-sessions/in-memory.d.ts +9 -18
- package/dist/storage/file-upload-sessions/in-memory.d.ts.map +1 -1
- package/dist/storage/file-upload-sessions/index.d.ts +1 -1
- package/dist/storage/file-upload-sessions/index.d.ts.map +1 -1
- package/dist/storage/file-upload-sessions/provider.d.ts +52 -0
- package/dist/storage/file-upload-sessions/provider.d.ts.map +1 -0
- package/dist/storage/file-upload-sessions/provider.js +24 -0
- package/dist/storage/file-upload-sessions/provider.js.map +9 -0
- package/dist/storage/file-upload-sessions/types.d.ts +19 -1
- package/dist/storage/file-upload-sessions/types.d.ts.map +1 -1
- package/dist/storage/file-upload-sessions/utils.d.ts +8 -2
- package/dist/storage/file-upload-sessions/utils.d.ts.map +1 -1
- package/dist/storage/index.d.ts +3 -3
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/index.js +29 -25
- package/dist/storage/index.js.map +1 -1
- package/dist/storage/internal.js +11 -9
- package/dist/storage/internal.js.map +1 -1
- package/dist/storage/objects/in-memory/query.d.ts.map +1 -1
- package/dist/storage/ontology/commits.d.ts +6 -2
- package/dist/storage/ontology/commits.d.ts.map +1 -1
- package/dist/storage/ontology/in-memory/materializations.d.ts.map +1 -1
- package/dist/storage/ontology/provider-work.d.ts.map +1 -1
- package/dist/storage/ontology/provider.d.ts +14 -1
- package/dist/storage/ontology/provider.d.ts.map +1 -1
- package/dist/storage/ontology/provider.js +8 -2
- package/dist/storage/ontology/provider.js.map +1 -1
- package/dist/storage/operation-scope.d.ts.map +1 -1
- package/dist/storage/operation-scope.js +1 -1
- package/dist/storage/projection-runs/provider.js +2 -2
- package/dist/storage/types.d.ts +1 -1
- package/dist/storage/types.d.ts.map +1 -1
- package/dist/storage/workflow-interventions/index.d.ts +1 -1
- package/dist/storage/workflow-interventions/index.d.ts.map +1 -1
- package/dist/storage/workflow-interventions/types.d.ts +5 -8
- package/dist/storage/workflow-interventions/types.d.ts.map +1 -1
- package/dist/storage/workflow-runs/provider.js +8 -8
- package/dist/syncs/index.js +27 -25
- package/dist/syncs/index.js.map +1 -1
- package/dist/testing/action-execution.d.ts +4 -0
- package/dist/testing/action-execution.d.ts.map +1 -1
- package/dist/testing/auth-storage-contract.d.ts.map +1 -1
- package/dist/testing/execution.d.ts +1 -2
- package/dist/testing/execution.d.ts.map +1 -1
- package/dist/testing/file-upload-session-storage-contract.d.ts +12 -0
- package/dist/testing/file-upload-session-storage-contract.d.ts.map +1 -0
- package/dist/testing/index.d.ts +2 -0
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +2035 -1358
- package/dist/testing/index.js.map +15 -13
- package/dist/testing/materializer-storage-contract.d.ts.map +1 -1
- package/dist/testing/object-query-contract.d.ts.map +1 -1
- package/dist/testing/ontology-contract-fixture.d.ts +8 -0
- package/dist/testing/ontology-contract-fixture.d.ts.map +1 -1
- package/dist/testing/ontology-storage-contract.d.ts.map +1 -1
- package/dist/testing/sandboxes-contract.d.ts.map +1 -1
- package/dist/testing/workflow-intervention-storage-contract.d.ts +8 -0
- package/dist/testing/workflow-intervention-storage-contract.d.ts.map +1 -0
- package/dist/webhooks/internal.js +24 -22
- package/dist/webhooks/internal.js.map +2 -2
- package/dist/webhooks/types.d.ts +2 -2
- package/dist/webhooks/types.d.ts.map +1 -1
- package/dist/workers/index.js +1 -1
- package/dist/workflows/index.js +42 -40
- package/dist/workflows/index.js.map +1 -1
- package/dist/workflows/run-dispatch.d.ts.map +1 -1
- package/dist/workflows/types.d.ts +2 -2
- package/dist/workflows/types.d.ts.map +1 -1
- package/package.json +7 -1
- package/src/actions/index.ts +0 -3
- package/src/actions/read-facade.ts +102 -62
- package/src/actions/request.ts +13 -0
- package/src/actions/run-dispatch.ts +3 -0
- package/src/actions/types/context.ts +17 -65
- package/src/actions/types/params.ts +2 -1
- package/src/agents/authority.ts +1 -1
- package/src/assert-never.ts +7 -0
- package/src/auth/client-address.ts +12 -0
- package/src/auth/csrf.ts +14 -5
- package/src/auth/errors.ts +23 -0
- package/src/auth/index.ts +4 -3
- package/src/auth/runtime.ts +353 -297
- package/src/auth/session-cache.ts +18 -6
- package/src/auth/sessions.ts +30 -0
- package/src/auth/strategy.ts +2 -0
- package/src/auth/types.ts +15 -17
- package/src/bootstrap/index.ts +1 -0
- package/src/bootstrap/ontology-type-manifest.ts +112 -60
- package/src/edits/types.ts +47 -63
- package/src/errors/catalog.ts +4 -0
- package/src/events/envelope.ts +0 -13
- package/src/events/index.ts +1 -1
- package/src/events/service.ts +1 -11
- package/src/events/toStoredEvent.ts +1 -3
- package/src/events/types/index.ts +1 -1
- package/src/execution/agent.ts +1 -2
- package/src/execution/authorized-object-reader.ts +5 -7
- package/src/execution/primitive.ts +1 -2
- package/src/execution/request.ts +1 -2
- package/src/index.ts +8 -7
- package/src/maintenance/ontology-maintenance.ts +77 -1
- package/src/materialization/errors.ts +2 -0
- package/src/materialization/events.ts +27 -2
- package/src/materializer/README.md +2 -0
- package/src/materializer/edits/commit.ts +21 -12
- package/src/materializer/edits/operations.ts +32 -4
- package/src/materializer/edits/plan.ts +4 -5
- package/src/materializer/edits/user-refs.ts +115 -0
- package/src/materializer/effective/build-events.ts +4 -5
- package/src/materializer/execution/scope.ts +40 -7
- package/src/materializer/projections/replace.ts +2 -0
- package/src/materializer/projections/replacement-plan.ts +4 -0
- package/src/materializer/telemetry/append.ts +4 -12
- package/src/materializer/telemetry/plan.ts +4 -5
- package/src/objects/execution.ts +33 -62
- package/src/objects/query/executor.ts +12 -3
- package/src/objects/query/ir.ts +7 -0
- package/src/objects/query/planner.ts +1 -0
- package/src/objects/query/scalar-values.ts +19 -0
- package/src/objects/query/validate.ts +55 -44
- package/src/objects/sdk/object-handle.ts +8 -8
- package/src/objects/sdk/object-set.ts +8 -15
- package/src/objects/sdk/query-builder.ts +59 -71
- package/src/objects/sdk/telemetry-channel.ts +6 -7
- package/src/objects/sdk/where.ts +6 -13
- package/src/ontology/builders.ts +15 -11
- package/src/ontology/index.ts +4 -0
- package/src/ontology/inference/index.ts +56 -36
- package/src/ontology/internal.ts +1 -0
- package/src/ontology/json-schema.ts +12 -0
- package/src/ontology/primitives.ts +91 -0
- package/src/ontology/query-capabilities.ts +136 -0
- package/src/ontology/refs.ts +33 -6
- package/src/ontology/registered.ts +22 -0
- package/src/ontology/registry.ts +6 -3
- package/src/ontology/tokens.ts +41 -2
- package/src/ontology/types.ts +19 -3
- package/src/ontology/user-ref.ts +120 -0
- package/src/ontology/validation/definition.ts +2 -13
- package/src/ontology/validation/index.ts +1 -0
- package/src/ontology/validation/normalize.ts +39 -3
- package/src/ontology/validation/properties.ts +95 -19
- package/src/ontology/validation/query.ts +11 -42
- package/src/ontology/validation/schema.ts +16 -0
- package/src/predicates/types.ts +43 -33
- package/src/projections/builders.ts +24 -3
- package/src/projections/validation.ts +15 -1
- package/src/runtime/create.ts +2 -2
- package/src/runtime/host.ts +10 -12
- package/src/runtime/index.ts +3 -2
- package/src/runtime/sixb.ts +13 -23
- package/src/runtime/types.ts +277 -479
- package/src/sandboxes/sandbox.ts +4 -1
- package/src/shared/params/types.ts +4 -3
- package/src/shared/params/user-refs.ts +48 -0
- package/src/shares/compiler.ts +6 -16
- package/src/storage/action-runs/types.ts +1 -0
- package/src/storage/auth/errors.ts +0 -1
- package/src/storage/auth/in-memory/access-tokens.ts +5 -2
- package/src/storage/auth/in-memory/auth-storage.ts +49 -73
- package/src/storage/auth/in-memory/device-authorizations.ts +0 -2
- package/src/storage/auth/in-memory/sessions.ts +69 -1
- package/src/storage/auth/in-memory/shared.ts +13 -7
- package/src/storage/auth/index.ts +2 -1
- package/src/storage/auth/types.ts +72 -20
- package/src/storage/executions/validation.ts +1 -1
- package/src/storage/file-upload-sessions/in-memory.ts +64 -113
- package/src/storage/file-upload-sessions/index.ts +1 -0
- package/src/storage/file-upload-sessions/provider.ts +258 -0
- package/src/storage/file-upload-sessions/types.ts +20 -1
- package/src/storage/file-upload-sessions/utils.ts +25 -9
- package/src/storage/index.ts +3 -2
- package/src/storage/objects/in-memory/query.ts +13 -3
- package/src/storage/ontology/commits.ts +6 -2
- package/src/storage/ontology/in-memory/materializations.ts +6 -34
- package/src/storage/ontology/provider-header-validation.ts +57 -0
- package/src/storage/ontology/provider-work.ts +15 -3
- package/src/storage/ontology/provider.ts +59 -1
- package/src/storage/operation-scope.ts +1 -0
- package/src/storage/types.ts +0 -1
- package/src/storage/workflow-interventions/index.ts +0 -1
- package/src/storage/workflow-interventions/types.ts +5 -9
- package/src/testing/action-execution.ts +13 -3
- package/src/testing/auth-storage-contract.ts +253 -192
- package/src/testing/execution-storage-contract.ts +1 -2
- package/src/testing/execution.ts +4 -7
- package/src/testing/file-upload-session-storage-contract.ts +335 -0
- package/src/testing/index.ts +8 -0
- package/src/testing/materializer-storage-contract.ts +86 -4
- package/src/testing/object-query-contract.ts +121 -2
- package/src/testing/ontology-contract-fixture.ts +23 -3
- package/src/testing/ontology-storage-contract.ts +58 -0
- package/src/testing/sandboxes-contract.ts +27 -0
- package/src/testing/workflow-intervention-storage-contract.ts +203 -0
- package/src/webhooks/types.ts +2 -2
- package/src/workflows/run-dispatch.ts +12 -1
- package/src/workflows/snapshot.ts +16 -7
- package/src/workflows/types.ts +2 -2
- package/dist/chunk-2cxv584m.js.map +0 -43
- package/dist/chunk-3ghw2t5q.js.map +0 -10
- package/dist/chunk-3h7ctayx.js.map +0 -11
- package/dist/chunk-6ma8dvzc.js.map +0 -15
- package/dist/chunk-bbaa1fet.js.map +0 -25
- package/dist/chunk-eyjzgav0.js.map +0 -12
- package/dist/chunk-f06sf7rr.js.map +0 -11
- package/dist/chunk-g50nxqs5.js.map +0 -18
- package/dist/chunk-hkw8rykk.js.map +0 -15
- package/dist/chunk-p6r1ex7t.js.map +0 -10
- package/dist/chunk-qm535afa.js.map +0 -15
- package/dist/chunk-vpxss818.js.map +0 -10
- package/dist/chunk-vsg0g7h9.js.map +0 -17
- /package/dist/{chunk-y3ev53cq.js.map → chunk-2fv8sajb.js.map} +0 -0
- /package/dist/{chunk-5tetw4hn.js.map → chunk-4tnrzqqh.js.map} +0 -0
- /package/dist/{chunk-y1ahv8b7.js.map → chunk-bdhfn0ww.js.map} +0 -0
- /package/dist/{chunk-kept9cdd.js.map → chunk-bxx3ms5t.js.map} +0 -0
- /package/dist/{chunk-xtfryrfb.js.map → chunk-cbn96bve.js.map} +0 -0
- /package/dist/{chunk-t7dzd1tm.js.map → chunk-e2c5yxfe.js.map} +0 -0
- /package/dist/{chunk-bg2bs62d.js.map → chunk-jfdggg1p.js.map} +0 -0
- /package/dist/{chunk-e1f1sqba.js.map → chunk-kxea54yg.js.map} +0 -0
- /package/dist/{chunk-0mza4xb2.js.map → chunk-m8zkvep1.js.map} +0 -0
- /package/dist/{chunk-jjwhy3rs.js.map → chunk-q2xghyft.js.map} +0 -0
- /package/dist/{chunk-y0v18c2j.js.map → chunk-vef6qa14.js.map} +0 -0
- /package/dist/{chunk-gzt6v1ja.js.map → chunk-vn3yh259.js.map} +0 -0
- /package/dist/{chunk-sfypc7mk.js.map → chunk-wn7mznxc.js.map} +0 -0
- /package/dist/{chunk-r5zythxp.js.map → chunk-wnxabtn4.js.map} +0 -0
- /package/dist/{chunk-4ph94nhd.js.map → chunk-ww185kt6.js.map} +0 -0
- /package/dist/{chunk-gswwr35f.js.map → chunk-y487ywrv.js.map} +0 -0
- /package/dist/{chunk-bet1rb9h.js.map → chunk-y6vnvayj.js.map} +0 -0
- /package/dist/{chunk-3bnt2wna.js.map → chunk-yvf2jqj8.js.map} +0 -0
- /package/dist/{chunk-g2gezsg5.js.map → chunk-z9h698s8.js.map} +0 -0
- /package/dist/{chunk-bfjv1adk.js.map → chunk-znw0zvy4.js.map} +0 -0
|
@@ -5,23 +5,23 @@ import {
|
|
|
5
5
|
canAccessApplication2,
|
|
6
6
|
resolveRoleGrants2,
|
|
7
7
|
resolveAuthorizationContext2
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-rzcjp5m2.js";
|
|
9
9
|
import {
|
|
10
10
|
AuthRuntimeError2,
|
|
11
|
+
DEFAULT_AUTH_SESSION_AUDIENCE2,
|
|
11
12
|
resolveAuthSessionAudience2,
|
|
12
13
|
resolveAuthCookieOptionsForAudience,
|
|
13
14
|
getCookie2,
|
|
14
15
|
resolveAuthConfig2,
|
|
15
16
|
resolveInvitationExpiresAt,
|
|
16
|
-
sanitizeReturnTo,
|
|
17
17
|
assertNonEmpty3,
|
|
18
18
|
normalizePagination,
|
|
19
19
|
isInvitationDeliveryAuthStrategy2
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-2jntasmh.js";
|
|
21
21
|
import {
|
|
22
22
|
normalizeParams,
|
|
23
23
|
coerceParamsToTyped
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-2fv8sajb.js";
|
|
25
25
|
import {
|
|
26
26
|
snapshotLinkPathSelection
|
|
27
27
|
} from "./chunk-t6f3tdnr.js";
|
|
@@ -109,6 +109,14 @@ function accessTokenKindFromLabel(label) {
|
|
|
109
109
|
}
|
|
110
110
|
return null;
|
|
111
111
|
}
|
|
112
|
+
// src/auth/client-address.ts
|
|
113
|
+
var clientAddresses = new WeakMap;
|
|
114
|
+
function setRequestClientAddress2(request, address) {
|
|
115
|
+
clientAddresses.set(request, address);
|
|
116
|
+
}
|
|
117
|
+
function getRequestClientAddress2(request) {
|
|
118
|
+
return clientAddresses.get(request);
|
|
119
|
+
}
|
|
112
120
|
// src/auth/csrf.ts
|
|
113
121
|
import { randomBytes as randomBytes2, timingSafeEqual } from "crypto";
|
|
114
122
|
var CSRF_HEADER_NAME2 = "x-sixb-csrf";
|
|
@@ -123,12 +131,17 @@ function verifyDoubleSubmitCsrf2(request, options) {
|
|
|
123
131
|
if (isCsrfExemptMethod2(request.method)) {
|
|
124
132
|
return true;
|
|
125
133
|
}
|
|
134
|
+
return verifyCsrfToken2(request, {
|
|
135
|
+
cookieName: options.cookieName,
|
|
136
|
+
token: request.headers.get(CSRF_HEADER_NAME2)
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
function verifyCsrfToken2(request, options) {
|
|
126
140
|
const cookieValue = getCookie2(request, options.cookieName);
|
|
127
|
-
|
|
128
|
-
if (!cookieValue || !headerValue) {
|
|
141
|
+
if (!cookieValue || !options.token) {
|
|
129
142
|
return false;
|
|
130
143
|
}
|
|
131
|
-
return safeEqual(cookieValue,
|
|
144
|
+
return safeEqual(cookieValue, options.token);
|
|
132
145
|
}
|
|
133
146
|
function safeEqual(left, right) {
|
|
134
147
|
const leftBytes = Buffer.from(left);
|
|
@@ -1366,7 +1379,12 @@ function createSessionRecord(state, input) {
|
|
|
1366
1379
|
expiresAt: cloneDate(input.expiresAt),
|
|
1367
1380
|
absoluteExpiresAt: input.absoluteExpiresAt ? cloneDate(input.absoluteExpiresAt) : undefined,
|
|
1368
1381
|
userAgent: input.userAgent,
|
|
1369
|
-
ipAddress: input.ipAddress
|
|
1382
|
+
ipAddress: input.ipAddress,
|
|
1383
|
+
bearer: input.bearer ? {
|
|
1384
|
+
clientName: assertNonEmpty4(input.bearer.clientName, "Session client name"),
|
|
1385
|
+
accessExpiresAt: cloneDate(input.bearer.accessExpiresAt),
|
|
1386
|
+
refreshTokenHash: assertNonEmpty4(input.bearer.refreshTokenHash, "Refresh token hash")
|
|
1387
|
+
} : undefined
|
|
1370
1388
|
};
|
|
1371
1389
|
state.sessions.set(sessionKey(projectId, id), cloneRecord(session));
|
|
1372
1390
|
return session;
|
|
@@ -1420,10 +1438,10 @@ function createAccessTokenRecord(state, input) {
|
|
|
1420
1438
|
const id = assertNonEmpty4(input.id, "Access token id");
|
|
1421
1439
|
const projectId = assertNonEmpty4(input.projectId, "Project id");
|
|
1422
1440
|
const name = assertNonEmpty4(input.name, "Access token name");
|
|
1423
|
-
const subjectId = assertNonEmpty4(input.
|
|
1441
|
+
const subjectId = assertNonEmpty4(input.subject.id, "Access token subject id");
|
|
1424
1442
|
const tokenHash = assertNonEmpty4(input.tokenHash, "Access token hash");
|
|
1425
|
-
assertAccessTokenSubject(input.kind, input.
|
|
1426
|
-
assertAccessTokenSubjectExists(state, projectId, input.
|
|
1443
|
+
assertAccessTokenSubject(input.kind, input.subject.type);
|
|
1444
|
+
assertAccessTokenSubjectExists(state, projectId, input.subject.type, subjectId);
|
|
1427
1445
|
const key = accessTokenKey(projectId, id);
|
|
1428
1446
|
if (state.accessTokens.has(key)) {
|
|
1429
1447
|
throw new AuthStorageError2("duplicate_access_token", `[Sixb] Access token '${id}' already exists for project '${projectId}'.`);
|
|
@@ -1433,8 +1451,7 @@ function createAccessTokenRecord(state, input) {
|
|
|
1433
1451
|
projectId,
|
|
1434
1452
|
name,
|
|
1435
1453
|
kind: input.kind,
|
|
1436
|
-
|
|
1437
|
-
subjectId,
|
|
1454
|
+
subject: { type: input.subject.type, id: subjectId },
|
|
1438
1455
|
tokenHash,
|
|
1439
1456
|
groupIds: normalizeOptionalGroupIds(input.groupIds),
|
|
1440
1457
|
createdByPrincipal: input.createdByPrincipal,
|
|
@@ -1556,7 +1573,7 @@ class InMemoryAuthAccessTokenStore {
|
|
|
1556
1573
|
async list(input) {
|
|
1557
1574
|
const order = input.order ?? "asc";
|
|
1558
1575
|
const offset = input.offset ?? 0;
|
|
1559
|
-
const rows = [...this.state.accessTokens.values()].filter((token) => token.projectId === input.projectId).filter((token) => input.kind === undefined || token.kind === input.kind).filter((token) => input.
|
|
1576
|
+
const rows = [...this.state.accessTokens.values()].filter((token) => token.projectId === input.projectId).filter((token) => input.kind === undefined || token.kind === input.kind).filter((token) => input.subject === undefined || token.subject.type === input.subject.type && token.subject.id === input.subject.id).filter((token) => input.includeRevoked || !token.revokedAt).sort((a, b) => compareByCreatedAt(a, b, order));
|
|
1560
1577
|
const page = rows.slice(offset, input.limit === undefined ? undefined : offset + input.limit);
|
|
1561
1578
|
return {
|
|
1562
1579
|
accessTokens: page.map(cloneRecord),
|
|
@@ -1632,8 +1649,6 @@ class InMemoryAuthDeviceAuthorizationStore {
|
|
|
1632
1649
|
deviceCodeHash: assertNonEmpty4(input.deviceCodeHash, "Device code hash"),
|
|
1633
1650
|
userCode: assertNonEmpty4(input.userCode, "User code"),
|
|
1634
1651
|
clientName: assertNonEmpty4(input.clientName, "Client name"),
|
|
1635
|
-
tokenName: assertNonEmpty4(input.tokenName, "Token name"),
|
|
1636
|
-
tokenExpiresAt: new Date(input.tokenExpiresAt),
|
|
1637
1652
|
status: "pending",
|
|
1638
1653
|
createdAt: new Date(input.createdAt),
|
|
1639
1654
|
expiresAt: new Date(input.expiresAt)
|
|
@@ -2080,15 +2095,54 @@ class InMemoryAuthSessionStore {
|
|
|
2080
2095
|
}
|
|
2081
2096
|
async findValidByTokenHash(params) {
|
|
2082
2097
|
const session = this.state.sessions.get(sessionKey(params.projectId, params.id));
|
|
2083
|
-
if (!session || session.audience !== params.audience || session.tokenHash !== params.tokenHash || !isActiveSession(session, params.now)) {
|
|
2098
|
+
if (!session || session.bearer || session.audience !== params.audience || session.tokenHash !== params.tokenHash || !isActiveSession(session, params.now)) {
|
|
2084
2099
|
return null;
|
|
2085
2100
|
}
|
|
2086
2101
|
return cloneRecord(session);
|
|
2087
2102
|
}
|
|
2103
|
+
async findValidByAccessTokenHash(params) {
|
|
2104
|
+
const session = this.state.sessions.get(sessionKey(params.projectId, params.id));
|
|
2105
|
+
if (!session?.bearer || session.tokenHash !== params.tokenHash || session.bearer.accessExpiresAt <= params.now || !isActiveSession(session, params.now)) {
|
|
2106
|
+
return null;
|
|
2107
|
+
}
|
|
2108
|
+
return cloneRecord(session);
|
|
2109
|
+
}
|
|
2110
|
+
async rotateRefreshToken(params) {
|
|
2111
|
+
const key = sessionKey(params.projectId, params.id);
|
|
2112
|
+
const session = this.state.sessions.get(key);
|
|
2113
|
+
if (!session?.bearer || !isActiveSession(session, params.now)) {
|
|
2114
|
+
return { status: "invalid" };
|
|
2115
|
+
}
|
|
2116
|
+
const { bearer } = session;
|
|
2117
|
+
const replacedRecently = bearer.previousRefreshTokenHash === params.refreshTokenHash && bearer.refreshedAt !== undefined && params.now.getTime() - bearer.refreshedAt.getTime() <= params.reuseGraceMs;
|
|
2118
|
+
if (bearer.refreshTokenHash !== params.refreshTokenHash && !replacedRecently) {
|
|
2119
|
+
if (bearer.previousRefreshTokenHash !== params.refreshTokenHash) {
|
|
2120
|
+
return { status: "invalid" };
|
|
2121
|
+
}
|
|
2122
|
+
this.state.sessions.set(key, cloneRecord({ ...session, revokedAt: cloneDate(params.now) }));
|
|
2123
|
+
return { status: "reused" };
|
|
2124
|
+
}
|
|
2125
|
+
const requestedExpiresAt = session.absoluteExpiresAt ? new Date(Math.min(params.next.expiresAt.getTime(), session.absoluteExpiresAt.getTime())) : params.next.expiresAt;
|
|
2126
|
+
const next = {
|
|
2127
|
+
...session,
|
|
2128
|
+
tokenHash: params.next.tokenHash,
|
|
2129
|
+
expiresAt: new Date(Math.max(session.expiresAt.getTime(), requestedExpiresAt.getTime())),
|
|
2130
|
+
lastSeenAt: cloneDate(params.now),
|
|
2131
|
+
bearer: {
|
|
2132
|
+
clientName: bearer.clientName,
|
|
2133
|
+
accessExpiresAt: cloneDate(params.next.accessExpiresAt),
|
|
2134
|
+
refreshTokenHash: params.next.refreshTokenHash,
|
|
2135
|
+
previousRefreshTokenHash: bearer.refreshTokenHash,
|
|
2136
|
+
refreshedAt: cloneDate(params.now)
|
|
2137
|
+
}
|
|
2138
|
+
};
|
|
2139
|
+
this.state.sessions.set(key, cloneRecord(next));
|
|
2140
|
+
return { status: "rotated", session: cloneRecord(next) };
|
|
2141
|
+
}
|
|
2088
2142
|
async renewIfValid(params) {
|
|
2089
2143
|
const key = sessionKey(params.projectId, params.id);
|
|
2090
2144
|
const session = this.state.sessions.get(key);
|
|
2091
|
-
if (!session || session.audience !== params.audience || session.tokenHash !== params.tokenHash || !isActiveSession(session, params.now)) {
|
|
2145
|
+
if (!session || session.bearer || session.audience !== params.audience || session.tokenHash !== params.tokenHash || !isActiveSession(session, params.now)) {
|
|
2092
2146
|
return null;
|
|
2093
2147
|
}
|
|
2094
2148
|
const requestedExpiresAt = session.absoluteExpiresAt ? new Date(Math.min(params.expiresAt.getTime(), session.absoluteExpiresAt.getTime())) : params.expiresAt;
|
|
@@ -2274,17 +2328,17 @@ class InMemoryAuthStorage2 {
|
|
|
2274
2328
|
if (authorization.status !== "approved" || !authorization.approvedUserId || !authorization.approvedSessionId || authorization.expiresAt <= input.completedAt) {
|
|
2275
2329
|
throw new AuthStorageError2("invalid_device_authorization", "[Sixb] Device authorization is invalid.");
|
|
2276
2330
|
}
|
|
2277
|
-
if (input.
|
|
2278
|
-
throw new AuthStorageError2("invalid_device_authorization", "[Sixb] Device
|
|
2331
|
+
if (input.session.projectId !== input.projectId || input.session.userId !== authorization.approvedUserId) {
|
|
2332
|
+
throw new AuthStorageError2("invalid_device_authorization", "[Sixb] Device session is invalid.");
|
|
2279
2333
|
}
|
|
2280
|
-
const
|
|
2334
|
+
const session = createSessionRecord(this.state, input.session);
|
|
2281
2335
|
const consumed = {
|
|
2282
2336
|
...authorization,
|
|
2283
2337
|
status: "consumed",
|
|
2284
2338
|
consumedAt: new Date(input.completedAt)
|
|
2285
2339
|
};
|
|
2286
2340
|
this.state.deviceAuthorizations.set(key, cloneRecord(consumed));
|
|
2287
|
-
return { authorization: cloneRecord(consumed),
|
|
2341
|
+
return { authorization: cloneRecord(consumed), session: cloneRecord(session) };
|
|
2288
2342
|
}
|
|
2289
2343
|
async completeMagicLinkSignIn(input) {
|
|
2290
2344
|
const projectId = assertNonEmpty4(input.projectId, "Project id");
|
|
@@ -2321,15 +2375,6 @@ class InMemoryAuthStorage2 {
|
|
|
2321
2375
|
});
|
|
2322
2376
|
throw new AuthStorageError2("user_creation_not_allowed", `[Sixb] Magic link '${input.magicLinkId}' cannot create a user for project '${projectId}'.`);
|
|
2323
2377
|
}
|
|
2324
|
-
if (shouldCreateUser && !activeInvitation && input.allowUserCreationWithoutInvitation && input.requireNoActiveUsersForUserCreation && hasActiveUsers(this.state, projectId)) {
|
|
2325
|
-
consumeMagicLinkRecord(this.state, {
|
|
2326
|
-
projectId,
|
|
2327
|
-
id: input.magicLinkId,
|
|
2328
|
-
tokenHash: input.tokenHash,
|
|
2329
|
-
consumedAt: completedAt
|
|
2330
|
-
});
|
|
2331
|
-
throw new AuthStorageError2("user_creation_not_allowed", `[Sixb] Magic link '${input.magicLinkId}' cannot create a user for project '${projectId}'.`);
|
|
2332
|
-
}
|
|
2333
2378
|
validateCompleteSessionInput(this.state, projectId, input.session);
|
|
2334
2379
|
assertSignInSessionAudience(projectId, input.session.audience, magicLink.audience);
|
|
2335
2380
|
let newUserId;
|
|
@@ -2365,8 +2410,9 @@ class InMemoryAuthStorage2 {
|
|
|
2365
2410
|
projectId,
|
|
2366
2411
|
user
|
|
2367
2412
|
});
|
|
2368
|
-
const memberships = this.
|
|
2413
|
+
const memberships = this.applyGroups({
|
|
2369
2414
|
completedAt,
|
|
2415
|
+
source: "manual",
|
|
2370
2416
|
groupIds: manualGroupIds,
|
|
2371
2417
|
projectId,
|
|
2372
2418
|
userId: user.id,
|
|
@@ -2410,26 +2456,14 @@ class InMemoryAuthStorage2 {
|
|
|
2410
2456
|
this.consumeOidcAttempt(input, completedAt, projectId);
|
|
2411
2457
|
throw new AuthStorageError2("missing_user", `[Sixb] User '${identity.userId}' not found for linked OIDC identity.`);
|
|
2412
2458
|
}
|
|
2413
|
-
if (!identity && user && (!input.autoLinkByVerifiedEmail || !input.emailVerified)) {
|
|
2414
|
-
this.consumeOidcAttempt(input, completedAt, projectId);
|
|
2415
|
-
throw new AuthStorageError2("email_link_not_allowed", `[Sixb] OIDC identity cannot auto-link to user '${user.id}' for project '${projectId}'.`);
|
|
2416
|
-
}
|
|
2417
2459
|
if (user?.status === "suspended") {
|
|
2418
2460
|
this.consumeOidcAttempt(input, completedAt, projectId);
|
|
2419
2461
|
throw new AuthStorageError2("suspended_user", `[Sixb] User '${user.id}' is suspended for project '${projectId}'.`);
|
|
2420
2462
|
}
|
|
2421
|
-
if (shouldCreateUser && !input.emailVerified) {
|
|
2422
|
-
this.consumeOidcAttempt(input, completedAt, projectId);
|
|
2423
|
-
throw new AuthStorageError2("user_creation_not_allowed", `[Sixb] OIDC authorization attempt '${input.oidcAuthorizationAttemptId}' cannot create a user for project '${projectId}'.`);
|
|
2424
|
-
}
|
|
2425
2463
|
if (shouldCreateUser && !activeInvitation && !input.allowUserCreationWithoutInvitation) {
|
|
2426
2464
|
this.consumeOidcAttempt(input, completedAt, projectId);
|
|
2427
2465
|
throw new AuthStorageError2("user_creation_not_allowed", `[Sixb] OIDC authorization attempt '${input.oidcAuthorizationAttemptId}' cannot create a user for project '${projectId}'.`);
|
|
2428
2466
|
}
|
|
2429
|
-
if (shouldCreateUser && !activeInvitation && input.allowUserCreationWithoutInvitation && input.requireNoActiveUsersForUserCreation && hasActiveUsers(this.state, projectId)) {
|
|
2430
|
-
this.consumeOidcAttempt(input, completedAt, projectId);
|
|
2431
|
-
throw new AuthStorageError2("user_creation_not_allowed", `[Sixb] OIDC authorization attempt '${input.oidcAuthorizationAttemptId}' cannot create a user for project '${projectId}'.`);
|
|
2432
|
-
}
|
|
2433
2467
|
validateCompleteSessionInput(this.state, projectId, input.session);
|
|
2434
2468
|
assertSignInSessionAudience(projectId, input.session.audience, attempt.audience);
|
|
2435
2469
|
let newUserId;
|
|
@@ -2459,12 +2493,19 @@ class InMemoryAuthStorage2 {
|
|
|
2459
2493
|
projectId,
|
|
2460
2494
|
user
|
|
2461
2495
|
});
|
|
2462
|
-
const memberships = this.
|
|
2496
|
+
const memberships = this.syncDirectoryGroups({
|
|
2463
2497
|
completedAt,
|
|
2464
|
-
groupIds:
|
|
2498
|
+
groupIds: input.directoryGroupIds,
|
|
2465
2499
|
projectId,
|
|
2466
2500
|
userId: user.id,
|
|
2467
|
-
existing:
|
|
2501
|
+
existing: this.applyGroups({
|
|
2502
|
+
completedAt,
|
|
2503
|
+
source: "manual",
|
|
2504
|
+
groupIds: manualGroupIds,
|
|
2505
|
+
projectId,
|
|
2506
|
+
userId: user.id,
|
|
2507
|
+
existing: invitation.memberships
|
|
2508
|
+
})
|
|
2468
2509
|
});
|
|
2469
2510
|
const nextIdentity = {
|
|
2470
2511
|
projectId,
|
|
@@ -2525,19 +2566,30 @@ class InMemoryAuthStorage2 {
|
|
|
2525
2566
|
}));
|
|
2526
2567
|
return { invitation, memberships };
|
|
2527
2568
|
}
|
|
2528
|
-
|
|
2569
|
+
applyGroups(input) {
|
|
2529
2570
|
const memberships = [...input.existing];
|
|
2530
2571
|
for (const groupId of input.groupIds) {
|
|
2531
2572
|
memberships.push(upsertGroupMembershipRecord(this.state, {
|
|
2532
2573
|
projectId: input.projectId,
|
|
2533
2574
|
userId: input.userId,
|
|
2534
2575
|
groupId,
|
|
2535
|
-
source:
|
|
2576
|
+
source: input.source,
|
|
2536
2577
|
createdAt: input.completedAt
|
|
2537
2578
|
}));
|
|
2538
2579
|
}
|
|
2539
2580
|
return memberships;
|
|
2540
2581
|
}
|
|
2582
|
+
syncDirectoryGroups(input) {
|
|
2583
|
+
if (!input.groupIds) {
|
|
2584
|
+
return input.existing;
|
|
2585
|
+
}
|
|
2586
|
+
const groupIds = normalizeGroupIds(input.groupIds);
|
|
2587
|
+
const stale = [...this.state.groupMemberships.values()].filter((membership) => membership.projectId === input.projectId && membership.userId === input.userId && membership.source === "directory" && !groupIds.includes(membership.groupId));
|
|
2588
|
+
for (const membership of stale) {
|
|
2589
|
+
removeGroupMembershipRecord(this.state, membership);
|
|
2590
|
+
}
|
|
2591
|
+
return this.applyGroups({ ...input, groupIds, source: "directory" });
|
|
2592
|
+
}
|
|
2541
2593
|
createSignInSession(input) {
|
|
2542
2594
|
return createSessionRecord(this.state, {
|
|
2543
2595
|
id: input.session.id,
|
|
@@ -2568,14 +2620,6 @@ function restoreMap(target, snapshot) {
|
|
|
2568
2620
|
target.set(key, value);
|
|
2569
2621
|
}
|
|
2570
2622
|
}
|
|
2571
|
-
function hasActiveUsers(state, projectId) {
|
|
2572
|
-
for (const user of state.users.values()) {
|
|
2573
|
-
if (user.projectId === projectId && user.status === "active") {
|
|
2574
|
-
return true;
|
|
2575
|
-
}
|
|
2576
|
-
}
|
|
2577
|
-
return false;
|
|
2578
|
-
}
|
|
2579
2623
|
function assertSignInSessionAudience(projectId, sessionAudience, storedAudience) {
|
|
2580
2624
|
if (sessionAudience === storedAudience) {
|
|
2581
2625
|
return;
|
|
@@ -2596,20 +2640,22 @@ class SessionCache {
|
|
|
2596
2640
|
if (!entry) {
|
|
2597
2641
|
return;
|
|
2598
2642
|
}
|
|
2599
|
-
if (entry.expiresAtMs <= input.nowMs || entry.tokenHash !== input.tokenHash || entry.audience !== input.audience) {
|
|
2643
|
+
if (entry.expiresAtMs <= input.nowMs || entry.tokenHash !== input.tokenHash || entry.transport !== input.transport || input.audience !== undefined && entry.audience !== input.audience) {
|
|
2600
2644
|
this.entries.delete(input.sessionId);
|
|
2601
2645
|
return;
|
|
2602
2646
|
}
|
|
2603
2647
|
return entry.session;
|
|
2604
2648
|
}
|
|
2605
2649
|
set(input) {
|
|
2606
|
-
const
|
|
2650
|
+
const bearer = input.session.session.bearer;
|
|
2651
|
+
const expiresAtMs = Math.min(input.nowMs + this.ttlMs, input.sessionExpiresAtMs, input.sessionAbsoluteExpiresAtMs ?? Number.POSITIVE_INFINITY, bearer?.accessExpiresAt.getTime() ?? Number.POSITIVE_INFINITY);
|
|
2607
2652
|
if (expiresAtMs <= input.nowMs) {
|
|
2608
2653
|
return;
|
|
2609
2654
|
}
|
|
2610
2655
|
this.entries.delete(input.sessionId);
|
|
2611
2656
|
this.entries.set(input.sessionId, {
|
|
2612
2657
|
tokenHash: input.tokenHash,
|
|
2658
|
+
transport: bearer ? "bearer" : "cookie",
|
|
2613
2659
|
audience: input.audience,
|
|
2614
2660
|
session: input.session,
|
|
2615
2661
|
expiresAtMs
|
|
@@ -2672,10 +2718,27 @@ function createSessionCredential2(sessionId = `ses_${randomUUID2()}`) {
|
|
|
2672
2718
|
cookieValue: formatSessionCookieValue2(sessionId, sessionSecret)
|
|
2673
2719
|
};
|
|
2674
2720
|
}
|
|
2721
|
+
var SESSION_ACCESS_TOKEN_PREFIX = "sixb_at_";
|
|
2722
|
+
var SESSION_REFRESH_TOKEN_PREFIX = "sixb_rt_";
|
|
2723
|
+
function createBearerSessionTokens(sessionId) {
|
|
2724
|
+
const accessSecret = generateSessionSecret2();
|
|
2725
|
+
const refreshSecret = generateSessionSecret2();
|
|
2726
|
+
return {
|
|
2727
|
+
accessToken: `${SESSION_ACCESS_TOKEN_PREFIX}${formatSessionCookieValue2(sessionId, accessSecret)}`,
|
|
2728
|
+
refreshToken: `${SESSION_REFRESH_TOKEN_PREFIX}${formatSessionCookieValue2(sessionId, refreshSecret)}`,
|
|
2729
|
+
tokenHash: hashSessionSecret2(accessSecret),
|
|
2730
|
+
refreshTokenHash: hashSessionSecret2(refreshSecret)
|
|
2731
|
+
};
|
|
2732
|
+
}
|
|
2733
|
+
function parseBearerSessionToken(prefix, value) {
|
|
2734
|
+
return value.startsWith(prefix) ? parseSessionCookieValue2(value.slice(prefix.length)) : null;
|
|
2735
|
+
}
|
|
2675
2736
|
|
|
2676
2737
|
// src/auth/runtime.ts
|
|
2677
2738
|
var SESSION_TOUCH_INTERVAL_MS = 60000;
|
|
2678
2739
|
var ACCESS_TOKEN_TOUCH_INTERVAL_MS = 60000;
|
|
2740
|
+
var BEARER_ACCESS_TOKEN_TTL_MS = 15 * 60000;
|
|
2741
|
+
var REFRESH_REUSE_GRACE_MS = 60000;
|
|
2679
2742
|
|
|
2680
2743
|
class AuthRuntime2 {
|
|
2681
2744
|
projectId;
|
|
@@ -2730,19 +2793,17 @@ class AuthRuntime2 {
|
|
|
2730
2793
|
return { authenticated: false, reason: "auth_disabled" };
|
|
2731
2794
|
}
|
|
2732
2795
|
const audience = resolveAuthSessionAudience2(options.audience);
|
|
2733
|
-
|
|
2734
|
-
if (credentialSource !== "session") {
|
|
2735
|
-
const authorizationHeader = request.headers.get("authorization");
|
|
2796
|
+
if (options.credentialSource === "any") {
|
|
2736
2797
|
const tokenValue = getBearerAccessTokenValue2(request);
|
|
2798
|
+
if (tokenValue?.startsWith(SESSION_ACCESS_TOKEN_PREFIX)) {
|
|
2799
|
+
return this.resolveBearerSession(tokenValue);
|
|
2800
|
+
}
|
|
2737
2801
|
if (tokenValue) {
|
|
2738
2802
|
return this.resolveAccessTokenSession(request, tokenValue);
|
|
2739
2803
|
}
|
|
2740
|
-
if (
|
|
2804
|
+
if (request.headers.get("authorization")) {
|
|
2741
2805
|
return { authenticated: false, reason: "invalid_access_token" };
|
|
2742
2806
|
}
|
|
2743
|
-
if (credentialSource === "accessToken") {
|
|
2744
|
-
return { authenticated: false, reason: "missing_access_token" };
|
|
2745
|
-
}
|
|
2746
2807
|
}
|
|
2747
2808
|
return this.resolveCookieSession(request, audience, options.sessionActivity);
|
|
2748
2809
|
}
|
|
@@ -2761,6 +2822,7 @@ class AuthRuntime2 {
|
|
|
2761
2822
|
const cached = this.sessionCache?.get({
|
|
2762
2823
|
sessionId: parts.sessionId,
|
|
2763
2824
|
tokenHash,
|
|
2825
|
+
transport: "cookie",
|
|
2764
2826
|
audience,
|
|
2765
2827
|
nowMs
|
|
2766
2828
|
});
|
|
@@ -2799,41 +2861,109 @@ class AuthRuntime2 {
|
|
|
2799
2861
|
session = renewed;
|
|
2800
2862
|
sessionRenewed = true;
|
|
2801
2863
|
}
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
id: session.userId
|
|
2805
|
-
});
|
|
2806
|
-
if (!user) {
|
|
2807
|
-
return { authenticated: false, reason: "missing_user" };
|
|
2864
|
+
if (!sessionRenewed) {
|
|
2865
|
+
await this.touchSessionLastSeen(storage, session, now);
|
|
2808
2866
|
}
|
|
2809
|
-
|
|
2810
|
-
|
|
2867
|
+
const result = await this.authenticateSession(storage, session, tokenHash, now);
|
|
2868
|
+
return result.authenticated && sessionRenewed ? { ...result, sessionRenewed: true } : result;
|
|
2869
|
+
}
|
|
2870
|
+
async resolveBearerSession(tokenValue) {
|
|
2871
|
+
const parts = parseBearerSessionToken(SESSION_ACCESS_TOKEN_PREFIX, tokenValue);
|
|
2872
|
+
if (!parts) {
|
|
2873
|
+
return { authenticated: false, reason: "invalid_access_token" };
|
|
2811
2874
|
}
|
|
2812
|
-
const
|
|
2875
|
+
const tokenHash = hashSessionSecret2(parts.sessionSecret);
|
|
2876
|
+
const now = new Date;
|
|
2877
|
+
const cached = this.sessionCache?.get({
|
|
2878
|
+
sessionId: parts.sessionId,
|
|
2879
|
+
tokenHash,
|
|
2880
|
+
transport: "bearer",
|
|
2881
|
+
nowMs: now.getTime()
|
|
2882
|
+
});
|
|
2883
|
+
if (cached) {
|
|
2884
|
+
return cached;
|
|
2885
|
+
}
|
|
2886
|
+
const storage = this.requireAuthStorage();
|
|
2887
|
+
const session = await storage.sessions.findValidByAccessTokenHash({
|
|
2813
2888
|
projectId: this.projectId,
|
|
2814
|
-
|
|
2889
|
+
id: parts.sessionId,
|
|
2890
|
+
tokenHash,
|
|
2891
|
+
now
|
|
2815
2892
|
});
|
|
2816
|
-
if (!
|
|
2817
|
-
|
|
2893
|
+
if (!session) {
|
|
2894
|
+
return { authenticated: false, reason: "invalid_access_token" };
|
|
2895
|
+
}
|
|
2896
|
+
await this.touchSessionLastSeen(storage, session, now);
|
|
2897
|
+
return this.authenticateSession(storage, session, tokenHash, now);
|
|
2898
|
+
}
|
|
2899
|
+
async authenticateSession(storage, session, tokenHash, now) {
|
|
2900
|
+
const member = await this.loadActiveUser(storage, session.userId);
|
|
2901
|
+
if (!member.authenticated) {
|
|
2902
|
+
return member;
|
|
2818
2903
|
}
|
|
2819
2904
|
const result = {
|
|
2820
2905
|
authenticated: true,
|
|
2821
2906
|
credentialSource: "session",
|
|
2822
|
-
principal: { type: "user", id: user.id },
|
|
2823
|
-
user,
|
|
2907
|
+
principal: { type: "user", id: member.user.id },
|
|
2908
|
+
user: member.user,
|
|
2824
2909
|
session,
|
|
2825
|
-
groupIds:
|
|
2910
|
+
groupIds: member.groupIds
|
|
2826
2911
|
};
|
|
2827
2912
|
this.sessionCache?.set({
|
|
2828
|
-
sessionId:
|
|
2913
|
+
sessionId: session.id,
|
|
2829
2914
|
tokenHash,
|
|
2830
|
-
audience,
|
|
2915
|
+
audience: session.audience,
|
|
2831
2916
|
session: result,
|
|
2832
|
-
nowMs,
|
|
2917
|
+
nowMs: now.getTime(),
|
|
2833
2918
|
sessionExpiresAtMs: session.expiresAt.getTime(),
|
|
2834
2919
|
sessionAbsoluteExpiresAtMs: session.absoluteExpiresAt?.getTime()
|
|
2835
2920
|
});
|
|
2836
|
-
return
|
|
2921
|
+
return result;
|
|
2922
|
+
}
|
|
2923
|
+
prepareBearerSession(input) {
|
|
2924
|
+
const sessionId = `ses_${randomUUID3()}`;
|
|
2925
|
+
const tokens = createBearerSessionTokens(sessionId);
|
|
2926
|
+
return {
|
|
2927
|
+
tokens,
|
|
2928
|
+
session: {
|
|
2929
|
+
id: sessionId,
|
|
2930
|
+
projectId: this.projectId,
|
|
2931
|
+
userId: input.userId,
|
|
2932
|
+
strategyId: "device",
|
|
2933
|
+
audience: DEFAULT_AUTH_SESSION_AUDIENCE2,
|
|
2934
|
+
tokenHash: tokens.tokenHash,
|
|
2935
|
+
createdAt: input.now,
|
|
2936
|
+
...this.createSessionDeadlines(input.now),
|
|
2937
|
+
bearer: {
|
|
2938
|
+
clientName: input.clientName,
|
|
2939
|
+
accessExpiresAt: new Date(input.now.getTime() + BEARER_ACCESS_TOKEN_TTL_MS),
|
|
2940
|
+
refreshTokenHash: tokens.refreshTokenHash
|
|
2941
|
+
}
|
|
2942
|
+
}
|
|
2943
|
+
};
|
|
2944
|
+
}
|
|
2945
|
+
async refreshSession(refreshToken) {
|
|
2946
|
+
const parts = parseBearerSessionToken(SESSION_REFRESH_TOKEN_PREFIX, refreshToken);
|
|
2947
|
+
if (!parts || !this.isEnabled()) {
|
|
2948
|
+
return null;
|
|
2949
|
+
}
|
|
2950
|
+
const now = new Date;
|
|
2951
|
+
const tokens = createBearerSessionTokens(parts.sessionId);
|
|
2952
|
+
const result = await this.requireAuthStorage().sessions.rotateRefreshToken({
|
|
2953
|
+
projectId: this.projectId,
|
|
2954
|
+
id: parts.sessionId,
|
|
2955
|
+
refreshTokenHash: hashSessionSecret2(parts.sessionSecret),
|
|
2956
|
+
now,
|
|
2957
|
+
reuseGraceMs: REFRESH_REUSE_GRACE_MS,
|
|
2958
|
+
next: {
|
|
2959
|
+
tokenHash: tokens.tokenHash,
|
|
2960
|
+
accessExpiresAt: new Date(now.getTime() + BEARER_ACCESS_TOKEN_TTL_MS),
|
|
2961
|
+
refreshTokenHash: tokens.refreshTokenHash,
|
|
2962
|
+
expiresAt: new Date(now.getTime() + this.config.session.idleTimeoutMs)
|
|
2963
|
+
}
|
|
2964
|
+
});
|
|
2965
|
+
this.sessionCache?.invalidate(parts.sessionId);
|
|
2966
|
+
return result.status === "rotated" ? { tokens, session: result.session } : null;
|
|
2837
2967
|
}
|
|
2838
2968
|
canRenewSession(session, nowMs) {
|
|
2839
2969
|
if (session.expiresAt.getTime() - nowMs > this.config.session.renewalWindowMs) {
|
|
@@ -2863,33 +2993,23 @@ class AuthRuntime2 {
|
|
|
2863
2993
|
return { authenticated: false, reason: "invalid_access_token" };
|
|
2864
2994
|
}
|
|
2865
2995
|
await this.touchAccessTokenLastUsed(storage, accessToken, request, now);
|
|
2866
|
-
if (accessToken.
|
|
2867
|
-
const
|
|
2868
|
-
|
|
2869
|
-
|
|
2870
|
-
});
|
|
2871
|
-
if (!user) {
|
|
2872
|
-
return { authenticated: false, reason: "missing_user" };
|
|
2873
|
-
}
|
|
2874
|
-
if (user.status === "suspended") {
|
|
2875
|
-
return { authenticated: false, reason: "suspended_user" };
|
|
2996
|
+
if (accessToken.subject.type === "user") {
|
|
2997
|
+
const member = await this.loadActiveUser(storage, accessToken.subject.id);
|
|
2998
|
+
if (!member.authenticated) {
|
|
2999
|
+
return member;
|
|
2876
3000
|
}
|
|
2877
|
-
const memberships = await storage.groupMemberships.listForUser({
|
|
2878
|
-
projectId: this.projectId,
|
|
2879
|
-
userId: user.id
|
|
2880
|
-
});
|
|
2881
3001
|
return {
|
|
2882
3002
|
authenticated: true,
|
|
2883
3003
|
credentialSource: "accessToken",
|
|
2884
|
-
principal: { type: "user", id: user.id },
|
|
2885
|
-
user,
|
|
3004
|
+
principal: { type: "user", id: member.user.id },
|
|
3005
|
+
user: member.user,
|
|
2886
3006
|
accessToken,
|
|
2887
|
-
groupIds: constrainTokenGroupIds(
|
|
3007
|
+
groupIds: constrainTokenGroupIds(member.groupIds, accessToken)
|
|
2888
3008
|
};
|
|
2889
3009
|
}
|
|
2890
3010
|
const serviceAccount = await storage.serviceAccounts.getById({
|
|
2891
3011
|
projectId: this.projectId,
|
|
2892
|
-
id: accessToken.
|
|
3012
|
+
id: accessToken.subject.id
|
|
2893
3013
|
});
|
|
2894
3014
|
if (!serviceAccount) {
|
|
2895
3015
|
return { authenticated: false, reason: "missing_service_account" };
|
|
@@ -2910,8 +3030,23 @@ class AuthRuntime2 {
|
|
|
2910
3030
|
groupIds: constrainTokenGroupIds(memberships.map((membership) => membership.groupId), accessToken)
|
|
2911
3031
|
};
|
|
2912
3032
|
}
|
|
2913
|
-
|
|
2914
|
-
this.
|
|
3033
|
+
async loadActiveUser(storage, userId) {
|
|
3034
|
+
const user = await storage.users.getById({ projectId: this.projectId, id: userId });
|
|
3035
|
+
if (!user) {
|
|
3036
|
+
return { authenticated: false, reason: "missing_user" };
|
|
3037
|
+
}
|
|
3038
|
+
if (user.status === "suspended") {
|
|
3039
|
+
return { authenticated: false, reason: "suspended_user" };
|
|
3040
|
+
}
|
|
3041
|
+
const memberships = await storage.groupMemberships.listForUser({
|
|
3042
|
+
projectId: this.projectId,
|
|
3043
|
+
userId
|
|
3044
|
+
});
|
|
3045
|
+
return {
|
|
3046
|
+
authenticated: true,
|
|
3047
|
+
user,
|
|
3048
|
+
groupIds: memberships.map((membership) => membership.groupId)
|
|
3049
|
+
};
|
|
2915
3050
|
}
|
|
2916
3051
|
async touchSessionLastSeen(storage, session, now) {
|
|
2917
3052
|
const lastSeen = session.lastSeenAt?.getTime() ?? 0;
|
|
@@ -2933,76 +3068,33 @@ class AuthRuntime2 {
|
|
|
2933
3068
|
id: accessToken.id,
|
|
2934
3069
|
lastUsedAt: now,
|
|
2935
3070
|
userAgent: request.headers.get("user-agent")?.trim() || undefined,
|
|
2936
|
-
ipAddress:
|
|
3071
|
+
ipAddress: getRequestClientAddress2(request)
|
|
2937
3072
|
});
|
|
2938
3073
|
} catch {}
|
|
2939
3074
|
}
|
|
2940
|
-
async requirePrincipal(request, options = {}) {
|
|
2941
|
-
const session = await this.getSession(request, options);
|
|
2942
|
-
if (!session.authenticated) {
|
|
2943
|
-
throw new AuthRuntimeError2("authentication_required", "[Sixb] Authentication is required.");
|
|
2944
|
-
}
|
|
2945
|
-
return session.principal;
|
|
2946
|
-
}
|
|
2947
|
-
async requireUser(request, options = {}) {
|
|
2948
|
-
const session = await this.getSession(request, { ...options, credentialSource: "session" });
|
|
2949
|
-
if (!session.authenticated) {
|
|
2950
|
-
throw new AuthRuntimeError2("authentication_required", "[Sixb] Authentication is required.");
|
|
2951
|
-
}
|
|
2952
|
-
return session;
|
|
2953
|
-
}
|
|
2954
|
-
async requireUserRequest(request, options = {}) {
|
|
2955
|
-
const session = await this.getSession(request, { ...options, credentialSource: "any" });
|
|
2956
|
-
if (!session.authenticated) {
|
|
2957
|
-
throw new AuthRuntimeError2("authentication_required", "[Sixb] Authentication is required.");
|
|
2958
|
-
}
|
|
2959
|
-
if (!isAuthenticatedUserRequestSession(session)) {
|
|
2960
|
-
throw new AuthRuntimeError2("authorization_denied", "[Sixb] User authentication is required.");
|
|
2961
|
-
}
|
|
2962
|
-
return session;
|
|
2963
|
-
}
|
|
2964
|
-
async createSecurityContext(request, options = {}) {
|
|
2965
|
-
const session = await this.requireUser(request, options);
|
|
2966
|
-
return {
|
|
2967
|
-
principal: session.principal,
|
|
2968
|
-
sessionId: session.session.id,
|
|
2969
|
-
projectId: this.projectId,
|
|
2970
|
-
correlationId: resolveCorrelationId(request)
|
|
2971
|
-
};
|
|
2972
|
-
}
|
|
2973
|
-
async createAuthorizationContext(request, options = {}) {
|
|
2974
|
-
const session = await this.getSession(request, options);
|
|
2975
|
-
if (!session.authenticated) {
|
|
2976
|
-
throw new AuthRuntimeError2("authentication_required", "[Sixb] Authentication is required.");
|
|
2977
|
-
}
|
|
2978
|
-
return this.contextFromSession(session);
|
|
2979
|
-
}
|
|
2980
3075
|
contextFromSession(session) {
|
|
2981
3076
|
return resolveAuthorizationContext2({
|
|
2982
3077
|
principal: session.principal,
|
|
2983
|
-
sessionId: session
|
|
3078
|
+
sessionId: callerSessionId(session),
|
|
2984
3079
|
groupIds: session.groupIds,
|
|
2985
3080
|
roles: this.security.listResolvedRoles()
|
|
2986
3081
|
});
|
|
2987
3082
|
}
|
|
2988
|
-
async listPersonalAccessTokens(
|
|
2989
|
-
const session = await this.requireUserRequest(request, options);
|
|
3083
|
+
async listPersonalAccessTokens(caller) {
|
|
2990
3084
|
const storage = this.requireAuthStorage();
|
|
2991
3085
|
const result = await storage.accessTokens.list({
|
|
2992
3086
|
projectId: this.projectId,
|
|
2993
3087
|
kind: "personal",
|
|
2994
|
-
|
|
2995
|
-
subjectId: session.user.id,
|
|
3088
|
+
subject: { type: "user", id: caller.user.id },
|
|
2996
3089
|
includeRevoked: true,
|
|
2997
3090
|
order: "desc",
|
|
2998
3091
|
limit: 100
|
|
2999
3092
|
});
|
|
3000
3093
|
return { accessTokens: result.accessTokens };
|
|
3001
3094
|
}
|
|
3002
|
-
async createPersonalAccessToken(
|
|
3003
|
-
const session = await this.requireUserRequest(request, options);
|
|
3095
|
+
async createPersonalAccessToken(caller, input) {
|
|
3004
3096
|
const storage = this.requireAuthStorage();
|
|
3005
|
-
const groupIds = constrainRequestedGroupIds(input.groupIds,
|
|
3097
|
+
const groupIds = constrainRequestedGroupIds(input.groupIds, caller.groupIds, {
|
|
3006
3098
|
subject: "personal access token"
|
|
3007
3099
|
});
|
|
3008
3100
|
const credential = createAccessTokenCredential2("personal");
|
|
@@ -3011,25 +3103,23 @@ class AuthRuntime2 {
|
|
|
3011
3103
|
projectId: this.projectId,
|
|
3012
3104
|
name: input.name,
|
|
3013
3105
|
kind: "personal",
|
|
3014
|
-
|
|
3015
|
-
subjectId: session.user.id,
|
|
3106
|
+
subject: { type: "user", id: caller.user.id },
|
|
3016
3107
|
tokenHash: credential.tokenHash,
|
|
3017
3108
|
groupIds,
|
|
3018
|
-
createdByPrincipal:
|
|
3019
|
-
createdBySessionId:
|
|
3109
|
+
createdByPrincipal: caller.principal,
|
|
3110
|
+
createdBySessionId: callerSessionId(caller),
|
|
3020
3111
|
createdAt: new Date,
|
|
3021
3112
|
expiresAt: input.expiresAt
|
|
3022
3113
|
});
|
|
3023
3114
|
return { accessToken, tokenValue: credential.tokenValue };
|
|
3024
3115
|
}
|
|
3025
|
-
async revokePersonalAccessToken(
|
|
3026
|
-
const session = await this.requireUserRequest(request, options);
|
|
3116
|
+
async revokePersonalAccessToken(caller, input) {
|
|
3027
3117
|
const storage = this.requireAuthStorage();
|
|
3028
3118
|
const token = await storage.accessTokens.getById({
|
|
3029
3119
|
projectId: this.projectId,
|
|
3030
3120
|
id: input.tokenId
|
|
3031
3121
|
});
|
|
3032
|
-
if (!token || token.kind !== "personal" || token.
|
|
3122
|
+
if (!token || token.kind !== "personal" || token.subject.type !== "user" || token.subject.id !== caller.user.id) {
|
|
3033
3123
|
throw missingAccessTokenError(input.tokenId, this.projectId);
|
|
3034
3124
|
}
|
|
3035
3125
|
const accessToken = await storage.accessTokens.revoke({
|
|
@@ -3039,8 +3129,7 @@ class AuthRuntime2 {
|
|
|
3039
3129
|
});
|
|
3040
3130
|
return { accessToken };
|
|
3041
3131
|
}
|
|
3042
|
-
async listServiceAccounts(
|
|
3043
|
-
const session = await this.requireUserRequest(request, options);
|
|
3132
|
+
async listServiceAccounts(caller) {
|
|
3044
3133
|
const storage = this.requireAuthStorage();
|
|
3045
3134
|
const result = await storage.serviceAccounts.list({
|
|
3046
3135
|
projectId: this.projectId,
|
|
@@ -3052,13 +3141,12 @@ class AuthRuntime2 {
|
|
|
3052
3141
|
groupIds: await this.listServiceAccountGroupIds(storage, serviceAccount.id)
|
|
3053
3142
|
})));
|
|
3054
3143
|
return {
|
|
3055
|
-
serviceAccounts: withGroups.filter(({ groupIds }) => callerCanManageServiceAccount(
|
|
3144
|
+
serviceAccounts: withGroups.filter(({ groupIds }) => callerCanManageServiceAccount(caller.groupIds, groupIds))
|
|
3056
3145
|
};
|
|
3057
3146
|
}
|
|
3058
|
-
async createServiceAccount(
|
|
3059
|
-
const session = await this.requireUserRequest(request, options);
|
|
3147
|
+
async createServiceAccount(caller, input) {
|
|
3060
3148
|
const storage = this.requireAuthStorage();
|
|
3061
|
-
const groupIds = constrainRequestedGroupIds(input.groupIds,
|
|
3149
|
+
const groupIds = constrainRequestedGroupIds(input.groupIds, caller.groupIds, {
|
|
3062
3150
|
subject: "service account"
|
|
3063
3151
|
}) ?? [];
|
|
3064
3152
|
const now = new Date;
|
|
@@ -3067,8 +3155,8 @@ class AuthRuntime2 {
|
|
|
3067
3155
|
projectId: this.projectId,
|
|
3068
3156
|
name: input.name,
|
|
3069
3157
|
description: input.description,
|
|
3070
|
-
createdByPrincipal:
|
|
3071
|
-
createdBySessionId:
|
|
3158
|
+
createdByPrincipal: caller.principal,
|
|
3159
|
+
createdBySessionId: callerSessionId(caller),
|
|
3072
3160
|
createdAt: now,
|
|
3073
3161
|
updatedAt: now
|
|
3074
3162
|
});
|
|
@@ -3084,10 +3172,9 @@ class AuthRuntime2 {
|
|
|
3084
3172
|
}
|
|
3085
3173
|
return { serviceAccount, groupMemberships };
|
|
3086
3174
|
}
|
|
3087
|
-
async disableServiceAccount(
|
|
3088
|
-
const session = await this.requireUserRequest(request, options);
|
|
3175
|
+
async disableServiceAccount(caller, input) {
|
|
3089
3176
|
const storage = this.requireAuthStorage();
|
|
3090
|
-
const { serviceAccount, groupIds } = await this.requireManageableServiceAccount(storage,
|
|
3177
|
+
const { serviceAccount, groupIds } = await this.requireManageableServiceAccount(storage, caller.groupIds, input.serviceAccountId);
|
|
3091
3178
|
const updated = await storage.serviceAccounts.update({
|
|
3092
3179
|
projectId: this.projectId,
|
|
3093
3180
|
id: serviceAccount.id,
|
|
@@ -3096,25 +3183,22 @@ class AuthRuntime2 {
|
|
|
3096
3183
|
});
|
|
3097
3184
|
return { serviceAccount: updated, groupIds };
|
|
3098
3185
|
}
|
|
3099
|
-
async listServiceAccountAccessTokens(
|
|
3100
|
-
const session = await this.requireUserRequest(request, options);
|
|
3186
|
+
async listServiceAccountAccessTokens(caller, input) {
|
|
3101
3187
|
const storage = this.requireAuthStorage();
|
|
3102
|
-
const { serviceAccount } = await this.requireManageableServiceAccount(storage,
|
|
3188
|
+
const { serviceAccount } = await this.requireManageableServiceAccount(storage, caller.groupIds, input.serviceAccountId);
|
|
3103
3189
|
const result = await storage.accessTokens.list({
|
|
3104
3190
|
projectId: this.projectId,
|
|
3105
3191
|
kind: "serviceAccount",
|
|
3106
|
-
|
|
3107
|
-
subjectId: serviceAccount.id,
|
|
3192
|
+
subject: { type: "serviceAccount", id: serviceAccount.id },
|
|
3108
3193
|
includeRevoked: true,
|
|
3109
3194
|
order: "desc",
|
|
3110
3195
|
limit: 100
|
|
3111
3196
|
});
|
|
3112
3197
|
return { serviceAccount, accessTokens: result.accessTokens };
|
|
3113
3198
|
}
|
|
3114
|
-
async createServiceAccountAccessToken(
|
|
3115
|
-
const session = await this.requireUserRequest(request, options);
|
|
3199
|
+
async createServiceAccountAccessToken(caller, input) {
|
|
3116
3200
|
const storage = this.requireAuthStorage();
|
|
3117
|
-
const { serviceAccount, groupIds: serviceAccountGroupIds } = await this.requireManageableServiceAccount(storage,
|
|
3201
|
+
const { serviceAccount, groupIds: serviceAccountGroupIds } = await this.requireManageableServiceAccount(storage, caller.groupIds, input.serviceAccountId);
|
|
3118
3202
|
if (serviceAccount.status === "suspended") {
|
|
3119
3203
|
throw new AuthStorageError2("suspended_service_account", `[Sixb] Service account '${input.serviceAccountId}' is suspended for project '${this.projectId}'.`);
|
|
3120
3204
|
}
|
|
@@ -3127,26 +3211,24 @@ class AuthRuntime2 {
|
|
|
3127
3211
|
projectId: this.projectId,
|
|
3128
3212
|
name: input.name,
|
|
3129
3213
|
kind: "serviceAccount",
|
|
3130
|
-
|
|
3131
|
-
subjectId: serviceAccount.id,
|
|
3214
|
+
subject: { type: "serviceAccount", id: serviceAccount.id },
|
|
3132
3215
|
tokenHash: credential.tokenHash,
|
|
3133
3216
|
groupIds,
|
|
3134
|
-
createdByPrincipal:
|
|
3135
|
-
createdBySessionId:
|
|
3217
|
+
createdByPrincipal: caller.principal,
|
|
3218
|
+
createdBySessionId: callerSessionId(caller),
|
|
3136
3219
|
createdAt: new Date,
|
|
3137
3220
|
expiresAt: input.expiresAt
|
|
3138
3221
|
});
|
|
3139
3222
|
return { accessToken, tokenValue: credential.tokenValue, serviceAccount };
|
|
3140
3223
|
}
|
|
3141
|
-
async revokeServiceAccountAccessToken(
|
|
3142
|
-
const session = await this.requireUserRequest(request, options);
|
|
3224
|
+
async revokeServiceAccountAccessToken(caller, input) {
|
|
3143
3225
|
const storage = this.requireAuthStorage();
|
|
3144
|
-
const { serviceAccount } = await this.requireManageableServiceAccount(storage,
|
|
3226
|
+
const { serviceAccount } = await this.requireManageableServiceAccount(storage, caller.groupIds, input.serviceAccountId);
|
|
3145
3227
|
const token = await storage.accessTokens.getById({
|
|
3146
3228
|
projectId: this.projectId,
|
|
3147
3229
|
id: input.tokenId
|
|
3148
3230
|
});
|
|
3149
|
-
if (!token || token.kind !== "serviceAccount" || token.
|
|
3231
|
+
if (!token || token.kind !== "serviceAccount" || token.subject.type !== "serviceAccount" || token.subject.id !== serviceAccount.id) {
|
|
3150
3232
|
throw missingAccessTokenError(input.tokenId, this.projectId);
|
|
3151
3233
|
}
|
|
3152
3234
|
const accessToken = await storage.accessTokens.revoke({
|
|
@@ -3174,9 +3256,8 @@ class AuthRuntime2 {
|
|
|
3174
3256
|
});
|
|
3175
3257
|
return memberships.map((membership) => membership.groupId);
|
|
3176
3258
|
}
|
|
3177
|
-
async getInvitationOptions(
|
|
3178
|
-
const
|
|
3179
|
-
const scope = this.resolveMembershipPolicyScopeForUser(session.groupIds);
|
|
3259
|
+
async getInvitationOptions(caller) {
|
|
3260
|
+
const scope = this.resolveMembershipPolicyScopeForUser(caller.groupIds);
|
|
3180
3261
|
const inviteScope = scope.operations.invite;
|
|
3181
3262
|
const groups = this.scopedGroupOptions(inviteScope.groupIds);
|
|
3182
3263
|
const hasInviteMembershipPolicy = inviteScope.policyIds.length > 0;
|
|
@@ -3193,32 +3274,31 @@ class AuthRuntime2 {
|
|
|
3193
3274
|
getMembershipCapabilities(input) {
|
|
3194
3275
|
return membershipCapabilities(this.resolveMembershipPolicyScopeForUser(groupIdsOf(input.callerGroups)));
|
|
3195
3276
|
}
|
|
3196
|
-
async getMembershipOptions(
|
|
3197
|
-
const
|
|
3198
|
-
const scope = this.resolveMembershipPolicyScopeForUser(session.groupIds);
|
|
3277
|
+
async getMembershipOptions(caller) {
|
|
3278
|
+
const scope = this.resolveMembershipPolicyScopeForUser(caller.groupIds);
|
|
3199
3279
|
return {
|
|
3200
3280
|
groups: this.scopedGroupOptions(scope.operations.assignGroups.groupIds),
|
|
3201
3281
|
capabilities: membershipCapabilities(scope).holds
|
|
3202
3282
|
};
|
|
3203
3283
|
}
|
|
3204
|
-
async listMembers(
|
|
3205
|
-
const session = await this.requireUser(request, options);
|
|
3284
|
+
async listMembers(caller, input = {}) {
|
|
3206
3285
|
const storage = this.requireAuthStorage();
|
|
3207
|
-
const scope = this.resolveMembershipPolicyScopeForUser(
|
|
3286
|
+
const scope = this.resolveMembershipPolicyScopeForUser(caller.groupIds);
|
|
3208
3287
|
const { limit, offset } = normalizePagination(input);
|
|
3209
3288
|
const result = await storage.users.list({ projectId: this.projectId, order: input.order });
|
|
3210
3289
|
const members = [];
|
|
3211
3290
|
for (const user of result.users) {
|
|
3212
|
-
const groupIds = (await storage.groupMemberships.listForUser({ projectId: this.projectId, userId: user.id }))
|
|
3291
|
+
const { groupIds, managedGroupIds } = memberGroups(await storage.groupMemberships.listForUser({ projectId: this.projectId, userId: user.id }));
|
|
3213
3292
|
const canAssignGroups = canPerformMembershipOperation(scope, "assignGroups", groupIds);
|
|
3214
3293
|
const canSuspendScope = canPerformMembershipOperation(scope, "suspend", groupIds);
|
|
3215
3294
|
if (!canAssignGroups && !canSuspendScope) {
|
|
3216
3295
|
continue;
|
|
3217
3296
|
}
|
|
3218
|
-
const isSelf = user.id ===
|
|
3297
|
+
const isSelf = user.id === caller.user.id;
|
|
3219
3298
|
members.push({
|
|
3220
3299
|
user,
|
|
3221
3300
|
groupIds,
|
|
3301
|
+
managedGroupIds,
|
|
3222
3302
|
capabilities: {
|
|
3223
3303
|
assignGroups: canAssignGroups,
|
|
3224
3304
|
suspend: canSuspendScope && !isSelf && user.status === "active",
|
|
@@ -3229,12 +3309,15 @@ class AuthRuntime2 {
|
|
|
3229
3309
|
const page = paginate(members, { limit, offset });
|
|
3230
3310
|
return { members: page.page, hasMore: page.hasMore, total: page.total };
|
|
3231
3311
|
}
|
|
3232
|
-
async updateMemberGroups(
|
|
3233
|
-
const session = await this.requireUser(request, options);
|
|
3312
|
+
async updateMemberGroups(caller, input) {
|
|
3234
3313
|
const storage = this.requireAuthStorage();
|
|
3235
|
-
const scope = this.resolveMembershipPolicyScopeForUser(
|
|
3314
|
+
const scope = this.resolveMembershipPolicyScopeForUser(caller.groupIds);
|
|
3236
3315
|
const userId = assertNonEmpty3(input.userId, "User id");
|
|
3237
|
-
const {
|
|
3316
|
+
const {
|
|
3317
|
+
user,
|
|
3318
|
+
groupIds: currentGroupIds,
|
|
3319
|
+
managedGroupIds: currentManagedGroupIds
|
|
3320
|
+
} = await this.requireManageableMember(storage, scope, "assignGroups", userId);
|
|
3238
3321
|
const requestedGroupIds = this.resolveMemberGroupIds(input.groupIds);
|
|
3239
3322
|
const missing = missingMembershipGroupIds(scope, "assignGroups", requestedGroupIds);
|
|
3240
3323
|
if (missing.length > 0) {
|
|
@@ -3244,7 +3327,11 @@ class AuthRuntime2 {
|
|
|
3244
3327
|
const requested = new Set(requestedGroupIds);
|
|
3245
3328
|
const additions = requestedGroupIds.filter((groupId) => !current.has(groupId));
|
|
3246
3329
|
const removals = currentGroupIds.filter((groupId) => !requested.has(groupId));
|
|
3247
|
-
|
|
3330
|
+
const managedRemovals = removals.filter((groupId) => currentManagedGroupIds.includes(groupId));
|
|
3331
|
+
if (managedRemovals.length > 0) {
|
|
3332
|
+
throw new AuthRuntimeError2("invalid_auth_input", `[Sixb] Group(s) ${managedRemovals.join(", ")} are managed by the identity provider. Change them there; they sync at the user's next sign-in.`);
|
|
3333
|
+
}
|
|
3334
|
+
if (user.id === caller.user.id && removals.length > 0) {
|
|
3248
3335
|
throw new AuthRuntimeError2("authorization_denied", "[Sixb] The current user cannot remove their own groups.");
|
|
3249
3336
|
}
|
|
3250
3337
|
const now = new Date;
|
|
@@ -3264,17 +3351,16 @@ class AuthRuntime2 {
|
|
|
3264
3351
|
groupId
|
|
3265
3352
|
});
|
|
3266
3353
|
}
|
|
3267
|
-
this.
|
|
3268
|
-
const groupIds = (await storage.groupMemberships.listForUser({ projectId: this.projectId, userId: user.id }))
|
|
3269
|
-
return { user, groupIds };
|
|
3354
|
+
this.sessionCache?.invalidateUser(user.id);
|
|
3355
|
+
const { groupIds, managedGroupIds } = memberGroups(await storage.groupMemberships.listForUser({ projectId: this.projectId, userId: user.id }));
|
|
3356
|
+
return { user, groupIds, managedGroupIds };
|
|
3270
3357
|
}
|
|
3271
|
-
async suspendMember(
|
|
3272
|
-
const session = await this.requireUser(request, options);
|
|
3358
|
+
async suspendMember(caller, input) {
|
|
3273
3359
|
const storage = this.requireAuthStorage();
|
|
3274
|
-
const scope = this.resolveMembershipPolicyScopeForUser(
|
|
3360
|
+
const scope = this.resolveMembershipPolicyScopeForUser(caller.groupIds);
|
|
3275
3361
|
const userId = assertNonEmpty3(input.userId, "User id");
|
|
3276
|
-
const { user, groupIds } = await this.requireManageableMember(storage, scope, "suspend", userId);
|
|
3277
|
-
if (user.id ===
|
|
3362
|
+
const { user, groupIds, managedGroupIds } = await this.requireManageableMember(storage, scope, "suspend", userId);
|
|
3363
|
+
if (user.id === caller.user.id) {
|
|
3278
3364
|
throw new AuthRuntimeError2("authorization_denied", "[Sixb] The current user cannot suspend themselves.");
|
|
3279
3365
|
}
|
|
3280
3366
|
const suspended = await storage.suspendUserAndRevokeSessions({
|
|
@@ -3282,25 +3368,53 @@ class AuthRuntime2 {
|
|
|
3282
3368
|
userId: user.id,
|
|
3283
3369
|
suspendedAt: new Date
|
|
3284
3370
|
});
|
|
3285
|
-
this.
|
|
3286
|
-
return { user: suspended, groupIds };
|
|
3371
|
+
this.sessionCache?.invalidateUser(user.id);
|
|
3372
|
+
return { user: suspended, groupIds, managedGroupIds };
|
|
3287
3373
|
}
|
|
3288
|
-
async reactivateMember(
|
|
3289
|
-
const session = await this.requireUser(request, options);
|
|
3374
|
+
async reactivateMember(caller, input) {
|
|
3290
3375
|
const storage = this.requireAuthStorage();
|
|
3291
|
-
const scope = this.resolveMembershipPolicyScopeForUser(
|
|
3376
|
+
const scope = this.resolveMembershipPolicyScopeForUser(caller.groupIds);
|
|
3292
3377
|
const userId = assertNonEmpty3(input.userId, "User id");
|
|
3293
|
-
const { user, groupIds } = await this.requireManageableMember(storage, scope, "suspend", userId);
|
|
3378
|
+
const { user, groupIds, managedGroupIds } = await this.requireManageableMember(storage, scope, "suspend", userId);
|
|
3294
3379
|
const reactivated = await storage.users.updateStatus({
|
|
3295
3380
|
projectId: this.projectId,
|
|
3296
3381
|
id: user.id,
|
|
3297
3382
|
status: "active",
|
|
3298
3383
|
updatedAt: new Date
|
|
3299
3384
|
});
|
|
3300
|
-
return { user: reactivated, groupIds };
|
|
3385
|
+
return { user: reactivated, groupIds, managedGroupIds };
|
|
3386
|
+
}
|
|
3387
|
+
async listSessions(caller) {
|
|
3388
|
+
return this.requireAuthStorage().sessions.listActiveByUserId({
|
|
3389
|
+
projectId: this.projectId,
|
|
3390
|
+
userId: caller.user.id,
|
|
3391
|
+
now: new Date
|
|
3392
|
+
});
|
|
3393
|
+
}
|
|
3394
|
+
async revokeSession(caller, sessionId) {
|
|
3395
|
+
const storage = this.requireAuthStorage();
|
|
3396
|
+
const session = await storage.sessions.getById({ projectId: this.projectId, id: sessionId });
|
|
3397
|
+
if (!session || session.userId !== caller.user.id) {
|
|
3398
|
+
return false;
|
|
3399
|
+
}
|
|
3400
|
+
await storage.sessions.revoke({
|
|
3401
|
+
projectId: this.projectId,
|
|
3402
|
+
id: sessionId,
|
|
3403
|
+
revokedAt: new Date
|
|
3404
|
+
});
|
|
3405
|
+
this.sessionCache?.invalidate(sessionId);
|
|
3406
|
+
return true;
|
|
3301
3407
|
}
|
|
3302
|
-
|
|
3303
|
-
this.
|
|
3408
|
+
async revokeAllSessions(caller) {
|
|
3409
|
+
const revoked = await this.requireAuthStorage().sessions.revokeActiveForUser({
|
|
3410
|
+
projectId: this.projectId,
|
|
3411
|
+
userId: caller.user.id,
|
|
3412
|
+
revokedAt: new Date
|
|
3413
|
+
});
|
|
3414
|
+
for (const session of revoked) {
|
|
3415
|
+
this.sessionCache?.invalidate(session.id);
|
|
3416
|
+
}
|
|
3417
|
+
return revoked.length;
|
|
3304
3418
|
}
|
|
3305
3419
|
scopedGroupOptions(groupIds) {
|
|
3306
3420
|
return this.security.listGroups().filter((group) => groupIds.has(group.id)).map((group) => ({
|
|
@@ -3311,11 +3425,11 @@ class AuthRuntime2 {
|
|
|
3311
3425
|
}
|
|
3312
3426
|
async requireManageableMember(storage, scope, operation, userId) {
|
|
3313
3427
|
const user = await storage.users.getById({ projectId: this.projectId, id: userId });
|
|
3314
|
-
const groupIds = user ?
|
|
3428
|
+
const { groupIds, managedGroupIds } = memberGroups(user ? await storage.groupMemberships.listForUser({ projectId: this.projectId, userId }) : []);
|
|
3315
3429
|
if (!user || !canPerformMembershipOperation(scope, operation, groupIds)) {
|
|
3316
3430
|
throw new AuthStorageError2("missing_user", `[Sixb] User '${userId}' not found for project '${this.projectId}'.`);
|
|
3317
3431
|
}
|
|
3318
|
-
return { user, groupIds };
|
|
3432
|
+
return { user, groupIds, managedGroupIds };
|
|
3319
3433
|
}
|
|
3320
3434
|
resolveMemberGroupIds(input) {
|
|
3321
3435
|
const groupIds = [...new Set(input.map((groupId) => assertNonEmpty3(groupId, "Group id")))];
|
|
@@ -3326,26 +3440,24 @@ class AuthRuntime2 {
|
|
|
3326
3440
|
}
|
|
3327
3441
|
return groupIds;
|
|
3328
3442
|
}
|
|
3329
|
-
async invite(
|
|
3330
|
-
const session = await this.requireUser(request, options);
|
|
3443
|
+
async invite(caller, input, destination) {
|
|
3331
3444
|
const authStorage = this.requireAuthStorage();
|
|
3332
3445
|
const now = new Date;
|
|
3333
3446
|
const groupIds = this.resolveInviteGroupIds(input);
|
|
3334
|
-
this.assertCanManageInvitationGroups(
|
|
3447
|
+
this.assertCanManageInvitationGroups(caller.groupIds, groupIds);
|
|
3335
3448
|
const strategy = this.getStrategy();
|
|
3336
3449
|
if (!isInvitationDeliveryAuthStrategy2(strategy)) {
|
|
3337
3450
|
throw new AuthRuntimeError2("invalid_auth_config", "[Sixb] The active auth strategy does not support invitations.");
|
|
3338
3451
|
}
|
|
3339
3452
|
await this.assertCanInviteRecipient(strategy, authStorage, input.email, now);
|
|
3340
|
-
|
|
3341
|
-
this.assertInvitationApplicationAccess(groupIds, deliveryAudience);
|
|
3453
|
+
this.assertInvitationApplicationAccess(groupIds, destination.audience);
|
|
3342
3454
|
const invitation = await authStorage.invitations.createOrUpdateActive({
|
|
3343
3455
|
id: `inv_${randomUUID3()}`,
|
|
3344
3456
|
projectId: this.projectId,
|
|
3345
3457
|
email: input.email,
|
|
3346
3458
|
groupIds,
|
|
3347
|
-
createdByPrincipal:
|
|
3348
|
-
createdBySessionId:
|
|
3459
|
+
createdByPrincipal: caller.principal,
|
|
3460
|
+
createdBySessionId: callerSessionId(caller),
|
|
3349
3461
|
createdAt: now,
|
|
3350
3462
|
updatedAt: now,
|
|
3351
3463
|
expiresAt: resolveInvitationExpiresAt(input.expiresAt, now)
|
|
@@ -3356,9 +3468,9 @@ class AuthRuntime2 {
|
|
|
3356
3468
|
projectId: this.projectId,
|
|
3357
3469
|
authStorage,
|
|
3358
3470
|
invitation,
|
|
3359
|
-
audience:
|
|
3360
|
-
returnTo:
|
|
3361
|
-
requestOrigin:
|
|
3471
|
+
audience: destination.audience,
|
|
3472
|
+
returnTo: destination.returnTo,
|
|
3473
|
+
requestOrigin: destination.requestOrigin,
|
|
3362
3474
|
revealLink: input.revealLink,
|
|
3363
3475
|
now
|
|
3364
3476
|
});
|
|
@@ -3379,8 +3491,7 @@ class AuthRuntime2 {
|
|
|
3379
3491
|
}
|
|
3380
3492
|
return { invitation, delivery };
|
|
3381
3493
|
}
|
|
3382
|
-
async listInvitations(
|
|
3383
|
-
const session = await this.requireUser(request, options);
|
|
3494
|
+
async listInvitations(caller, input = {}) {
|
|
3384
3495
|
const authStorage = this.requireAuthStorage();
|
|
3385
3496
|
const { limit, offset } = normalizePagination(input);
|
|
3386
3497
|
const result = await authStorage.invitations.list({
|
|
@@ -3389,7 +3500,7 @@ class AuthRuntime2 {
|
|
|
3389
3500
|
statuses: input.statuses,
|
|
3390
3501
|
order: input.order
|
|
3391
3502
|
});
|
|
3392
|
-
const scope = this.resolveMembershipPolicyScopeForUser(
|
|
3503
|
+
const scope = this.resolveMembershipPolicyScopeForUser(caller.groupIds);
|
|
3393
3504
|
const manageable = result.invitations.filter((invitation) => canPerformMembershipOperation(scope, "invite", invitation.groupIds));
|
|
3394
3505
|
const page = paginate(manageable, { limit, offset });
|
|
3395
3506
|
return {
|
|
@@ -3398,8 +3509,7 @@ class AuthRuntime2 {
|
|
|
3398
3509
|
total: page.total
|
|
3399
3510
|
};
|
|
3400
3511
|
}
|
|
3401
|
-
async revokeInvitation(
|
|
3402
|
-
const session = await this.requireUser(request, options);
|
|
3512
|
+
async revokeInvitation(caller, input) {
|
|
3403
3513
|
const authStorage = this.requireAuthStorage();
|
|
3404
3514
|
const invitationId = assertNonEmpty3(input.invitationId, "Invitation id");
|
|
3405
3515
|
const invitation = await authStorage.invitations.getById({
|
|
@@ -3409,7 +3519,7 @@ class AuthRuntime2 {
|
|
|
3409
3519
|
if (!invitation) {
|
|
3410
3520
|
throw new AuthStorageError2("missing_invitation", `[Sixb] Invitation '${invitationId}' not found for project '${this.projectId}'.`);
|
|
3411
3521
|
}
|
|
3412
|
-
this.assertCanManageInvitationGroups(
|
|
3522
|
+
this.assertCanManageInvitationGroups(caller.groupIds, invitation.groupIds);
|
|
3413
3523
|
if (invitation.status !== "pending") {
|
|
3414
3524
|
throw new AuthRuntimeError2("invalid_auth_input", `[Sixb] Invitation '${invitationId}' is already ${invitation.status} and cannot be revoked.`);
|
|
3415
3525
|
}
|
|
@@ -3506,14 +3616,14 @@ class AuthRuntime2 {
|
|
|
3506
3616
|
throw new AuthRuntimeError2("authorization_denied", `[Sixb] The current user is not allowed to create or manage invitations for group(s): ${missing.join(", ")}.`);
|
|
3507
3617
|
}
|
|
3508
3618
|
}
|
|
3509
|
-
function
|
|
3510
|
-
return
|
|
3511
|
-
|
|
3512
|
-
|
|
3513
|
-
|
|
3619
|
+
function memberGroups(memberships) {
|
|
3620
|
+
return {
|
|
3621
|
+
groupIds: memberships.map((membership) => membership.groupId),
|
|
3622
|
+
managedGroupIds: memberships.filter((membership) => membership.source === "directory").map((membership) => membership.groupId)
|
|
3623
|
+
};
|
|
3514
3624
|
}
|
|
3515
|
-
function
|
|
3516
|
-
return
|
|
3625
|
+
function callerSessionId(caller) {
|
|
3626
|
+
return caller.credentialSource === "session" ? caller.session.id : undefined;
|
|
3517
3627
|
}
|
|
3518
3628
|
function constrainTokenGroupIds(principalGroupIds, accessToken) {
|
|
3519
3629
|
if (accessToken.groupIds === undefined) {
|
|
@@ -3589,6 +3699,6 @@ var SYSTEM_PRINCIPAL2 = { type: "system", id: "system" };
|
|
|
3589
3699
|
function principalsEqual2(left, right) {
|
|
3590
3700
|
return left.type === right.type && left.id === right.id;
|
|
3591
3701
|
}
|
|
3592
|
-
export { ActionDefinitionError2, ActionEditCommitError2, missingActionMutationMessage, effectsWithoutEditsMessage, assertNonEmpty2, isActionDefinition2, isGlobalActionDefinition2, isObjectActionDefinition2, normalizeActionParams, coerceActionParamsToTyped2, validateActionSubject, resolveObjectActionSubject, PERSONAL_ACCESS_TOKEN_PREFIX2, SERVICE_ACCOUNT_ACCESS_TOKEN_PREFIX2, generateAccessTokenSecret2, hashAccessTokenSecret2, formatAccessTokenValue2, parseAccessTokenValue2, getBearerAccessTokenValue2, createAccessTokenCredential2, CSRF_HEADER_NAME2, generateCsrfToken2, isCsrfExemptMethod2, verifyDoubleSubmitCsrf2, applications2, SecurityValidationError2, isGroupDefinition, isMembershipPolicyDefinition, isRoleDefinition, defineGroup2, defineRole2, defineMembershipPolicy2, every2, ShareDefinitionError2, defineShare2, isShareDefinition, snapshotShareDefinition, can2, SecurityRegistry, AuthStorageError2, MAX_PENDING_DEVICE_AUTHORIZATIONS2, paginate, InMemoryAuthStorage2, generateSessionSecret2, hashSessionSecret2, formatSessionCookieValue2, parseSessionCookieValue2, createSessionCredential2, AuthRuntime2, SYSTEM_PRINCIPAL2, principalsEqual2 };
|
|
3702
|
+
export { ActionDefinitionError2, ActionEditCommitError2, missingActionMutationMessage, effectsWithoutEditsMessage, assertNonEmpty2, isActionDefinition2, isGlobalActionDefinition2, isObjectActionDefinition2, normalizeActionParams, coerceActionParamsToTyped2, validateActionSubject, resolveObjectActionSubject, PERSONAL_ACCESS_TOKEN_PREFIX2, SERVICE_ACCOUNT_ACCESS_TOKEN_PREFIX2, generateAccessTokenSecret2, hashAccessTokenSecret2, formatAccessTokenValue2, parseAccessTokenValue2, getBearerAccessTokenValue2, createAccessTokenCredential2, setRequestClientAddress2, getRequestClientAddress2, CSRF_HEADER_NAME2, generateCsrfToken2, isCsrfExemptMethod2, verifyDoubleSubmitCsrf2, verifyCsrfToken2, applications2, SecurityValidationError2, isGroupDefinition, isMembershipPolicyDefinition, isRoleDefinition, defineGroup2, defineRole2, defineMembershipPolicy2, every2, ShareDefinitionError2, defineShare2, isShareDefinition, snapshotShareDefinition, can2, SecurityRegistry, AuthStorageError2, MAX_PENDING_DEVICE_AUTHORIZATIONS2, paginate, InMemoryAuthStorage2, generateSessionSecret2, hashSessionSecret2, formatSessionCookieValue2, parseSessionCookieValue2, createSessionCredential2, AuthRuntime2, SYSTEM_PRINCIPAL2, principalsEqual2 };
|
|
3593
3703
|
|
|
3594
|
-
//# debugId=
|
|
3704
|
+
//# debugId=73464FD9FDE5971364756E2164756E21
|