@ddd-ts-kit/auth 0.0.0-stage → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +834 -2
- package/dist/abac/attribute-policy.d.ts +13 -0
- package/dist/abac/attribute-policy.d.ts.map +1 -0
- package/dist/abac/attribute-policy.js +10 -0
- package/dist/abac/attribute-policy.js.map +1 -0
- package/dist/abac/condition.d.ts +6 -0
- package/dist/abac/condition.d.ts.map +1 -0
- package/dist/abac/condition.js +10 -0
- package/dist/abac/condition.js.map +1 -0
- package/dist/abac/policy-based-authorizer.d.ts +23 -0
- package/dist/abac/policy-based-authorizer.d.ts.map +1 -0
- package/dist/abac/policy-based-authorizer.js +39 -0
- package/dist/abac/policy-based-authorizer.js.map +1 -0
- package/dist/abac/policy-input.d.ts +17 -0
- package/dist/abac/policy-input.d.ts.map +1 -0
- package/dist/abac/policy-input.js +2 -0
- package/dist/abac/policy-input.js.map +1 -0
- package/dist/abac/resource-attribute-values.d.ts +3 -0
- package/dist/abac/resource-attribute-values.d.ts.map +1 -0
- package/dist/abac/resource-attribute-values.js +2 -0
- package/dist/abac/resource-attribute-values.js.map +1 -0
- package/dist/abac/resource-attributes.d.ts +8 -0
- package/dist/abac/resource-attributes.d.ts.map +1 -0
- package/dist/abac/resource-attributes.js +5 -0
- package/dist/abac/resource-attributes.js.map +1 -0
- package/dist/authentication/actor-of.d.ts +7 -0
- package/dist/authentication/actor-of.d.ts.map +1 -0
- package/dist/authentication/actor-of.js +9 -0
- package/dist/authentication/actor-of.js.map +1 -0
- package/dist/authentication/authenticator.d.ts +11 -0
- package/dist/authentication/authenticator.d.ts.map +1 -0
- package/dist/authentication/authenticator.js +9 -0
- package/dist/authentication/authenticator.js.map +1 -0
- package/dist/authentication/bearer-credential.d.ts +7 -0
- package/dist/authentication/bearer-credential.d.ts.map +1 -0
- package/dist/authentication/bearer-credential.js +19 -0
- package/dist/authentication/bearer-credential.js.map +1 -0
- package/dist/authentication/header-values.d.ts +2 -0
- package/dist/authentication/header-values.d.ts.map +1 -0
- package/dist/authentication/header-values.js +2 -0
- package/dist/authentication/header-values.js.map +1 -0
- package/dist/authentication/in-actor-context.d.ts +15 -0
- package/dist/authentication/in-actor-context.d.ts.map +1 -0
- package/dist/authentication/in-actor-context.js +11 -0
- package/dist/authentication/in-actor-context.js.map +1 -0
- package/dist/authentication/principal-resolver.d.ts +10 -0
- package/dist/authentication/principal-resolver.d.ts.map +1 -0
- package/dist/authentication/principal-resolver.js +25 -0
- package/dist/authentication/principal-resolver.js.map +1 -0
- package/dist/authentication/resolve-session.d.ts +9 -0
- package/dist/authentication/resolve-session.d.ts.map +1 -0
- package/dist/authentication/resolve-session.js +12 -0
- package/dist/authentication/resolve-session.js.map +1 -0
- package/dist/authentication/session-authenticator.d.ts +13 -0
- package/dist/authentication/session-authenticator.d.ts.map +1 -0
- package/dist/authentication/session-authenticator.js +11 -0
- package/dist/authentication/session-authenticator.js.map +1 -0
- package/dist/authentication/session-of.d.ts +9 -0
- package/dist/authentication/session-of.d.ts.map +1 -0
- package/dist/authentication/session-of.js +27 -0
- package/dist/authentication/session-of.js.map +1 -0
- package/dist/authorization/access-scope.d.ts +16 -0
- package/dist/authorization/access-scope.d.ts.map +1 -0
- package/dist/authorization/access-scope.js +2 -0
- package/dist/authorization/access-scope.js.map +1 -0
- package/dist/authorization/access.d.ts +17 -0
- package/dist/authorization/access.d.ts.map +1 -0
- package/dist/authorization/access.js +8 -0
- package/dist/authorization/access.js.map +1 -0
- package/dist/authorization/authorization-context.d.ts +3 -0
- package/dist/authorization/authorization-context.d.ts.map +1 -0
- package/dist/authorization/authorization-context.js +2 -0
- package/dist/authorization/authorization-context.js.map +1 -0
- package/dist/authorization/authorizer.d.ts +15 -0
- package/dist/authorization/authorizer.d.ts.map +1 -0
- package/dist/authorization/authorizer.js +8 -0
- package/dist/authorization/authorizer.js.map +1 -0
- package/dist/authorization/check-request.d.ts +11 -0
- package/dist/authorization/check-request.d.ts.map +1 -0
- package/dist/authorization/check-request.js +2 -0
- package/dist/authorization/check-request.js.map +1 -0
- package/dist/authorization/decision-record-of.d.ts +7 -0
- package/dist/authorization/decision-record-of.d.ts.map +1 -0
- package/dist/authorization/decision-record-of.js +11 -0
- package/dist/authorization/decision-record-of.js.map +1 -0
- package/dist/authorization/decision-record.d.ts +15 -0
- package/dist/authorization/decision-record.d.ts.map +1 -0
- package/dist/authorization/decision-record.js +2 -0
- package/dist/authorization/decision-record.js.map +1 -0
- package/dist/authorization/decision.d.ts +10 -0
- package/dist/authorization/decision.d.ts.map +1 -0
- package/dist/authorization/decision.js +5 -0
- package/dist/authorization/decision.js.map +1 -0
- package/dist/authorization/denial-reason.d.ts +14 -0
- package/dist/authorization/denial-reason.d.ts.map +1 -0
- package/dist/authorization/denial-reason.js +14 -0
- package/dist/authorization/denial-reason.js.map +1 -0
- package/dist/authorization/is-resource-ref.d.ts +4 -0
- package/dist/authorization/is-resource-ref.d.ts.map +1 -0
- package/dist/authorization/is-resource-ref.js +11 -0
- package/dist/authorization/is-resource-ref.js.map +1 -0
- package/dist/authorization/list-request.d.ts +8 -0
- package/dist/authorization/list-request.d.ts.map +1 -0
- package/dist/authorization/list-request.js +2 -0
- package/dist/authorization/list-request.js.map +1 -0
- package/dist/authorization/on-decision.d.ts +3 -0
- package/dist/authorization/on-decision.d.ts.map +1 -0
- package/dist/authorization/on-decision.js +2 -0
- package/dist/authorization/on-decision.js.map +1 -0
- package/dist/authorization/resource-ref.d.ts +6 -0
- package/dist/authorization/resource-ref.d.ts.map +1 -0
- package/dist/authorization/resource-ref.js +2 -0
- package/dist/authorization/resource-ref.js.map +1 -0
- package/dist/di/authorization-map-of.d.ts +5 -0
- package/dist/di/authorization-map-of.d.ts.map +1 -0
- package/dist/di/authorization-map-of.js +30 -0
- package/dist/di/authorization-map-of.js.map +1 -0
- package/dist/di/authorization-module.d.ts +24 -0
- package/dist/di/authorization-module.d.ts.map +1 -0
- package/dist/di/authorization-module.js +75 -0
- package/dist/di/authorization-module.js.map +1 -0
- package/dist/di.d.ts +7 -0
- package/dist/di.d.ts.map +1 -0
- package/dist/di.js +7 -0
- package/dist/di.js.map +1 -0
- package/dist/errors/authorization-setup-error.d.ts +5 -0
- package/dist/errors/authorization-setup-error.d.ts.map +1 -0
- package/dist/errors/authorization-setup-error.js +8 -0
- package/dist/errors/authorization-setup-error.js.map +1 -0
- package/dist/errors/forbidden-error.d.ts +14 -0
- package/dist/errors/forbidden-error.d.ts.map +1 -0
- package/dist/errors/forbidden-error.js +18 -0
- package/dist/errors/forbidden-error.js.map +1 -0
- package/dist/errors/invalid-credential-error.d.ts +8 -0
- package/dist/errors/invalid-credential-error.d.ts.map +1 -0
- package/dist/errors/invalid-credential-error.js +12 -0
- package/dist/errors/invalid-credential-error.js.map +1 -0
- package/dist/errors/listing-not-supported-error.d.ts +5 -0
- package/dist/errors/listing-not-supported-error.d.ts.map +1 -0
- package/dist/errors/listing-not-supported-error.js +8 -0
- package/dist/errors/listing-not-supported-error.js.map +1 -0
- package/dist/errors/missing-actor-error.d.ts +6 -0
- package/dist/errors/missing-actor-error.d.ts.map +1 -0
- package/dist/errors/missing-actor-error.js +8 -0
- package/dist/errors/missing-actor-error.js.map +1 -0
- package/dist/errors/unauthenticated-error.d.ts +12 -0
- package/dist/errors/unauthenticated-error.d.ts.map +1 -0
- package/dist/errors/unauthenticated-error.js +14 -0
- package/dist/errors/unauthenticated-error.js.map +1 -0
- package/dist/errors/undeclared-use-case-error.d.ts +9 -0
- package/dist/errors/undeclared-use-case-error.d.ts.map +1 -0
- package/dist/errors/undeclared-use-case-error.js +11 -0
- package/dist/errors/undeclared-use-case-error.js.map +1 -0
- package/dist/index.d.ts +51 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +36 -0
- package/dist/index.js.map +1 -0
- package/dist/jwt/claims.d.ts +3 -0
- package/dist/jwt/claims.d.ts.map +1 -0
- package/dist/jwt/claims.js +2 -0
- package/dist/jwt/claims.js.map +1 -0
- package/dist/jwt/is-service-account.d.ts +3 -0
- package/dist/jwt/is-service-account.d.ts.map +1 -0
- package/dist/jwt/is-service-account.js +7 -0
- package/dist/jwt/is-service-account.js.map +1 -0
- package/dist/jwt/jwt-authenticator.d.ts +45 -0
- package/dist/jwt/jwt-authenticator.d.ts.map +1 -0
- package/dist/jwt/jwt-authenticator.js +109 -0
- package/dist/jwt/jwt-authenticator.js.map +1 -0
- package/dist/jwt/keycloak-actor-of.d.ts +6 -0
- package/dist/jwt/keycloak-actor-of.d.ts.map +1 -0
- package/dist/jwt/keycloak-actor-of.js +56 -0
- package/dist/jwt/keycloak-actor-of.js.map +1 -0
- package/dist/jwt/keycloak-authentication-method.d.ts +5 -0
- package/dist/jwt/keycloak-authentication-method.d.ts.map +1 -0
- package/dist/jwt/keycloak-authentication-method.js +6 -0
- package/dist/jwt/keycloak-authentication-method.js.map +1 -0
- package/dist/jwt/keycloak-authenticator.d.ts +23 -0
- package/dist/jwt/keycloak-authenticator.d.ts.map +1 -0
- package/dist/jwt/keycloak-authenticator.js +25 -0
- package/dist/jwt/keycloak-authenticator.js.map +1 -0
- package/dist/jwt/keycloak-claim-options.d.ts +9 -0
- package/dist/jwt/keycloak-claim-options.d.ts.map +1 -0
- package/dist/jwt/keycloak-claim-options.js +2 -0
- package/dist/jwt/keycloak-claim-options.js.map +1 -0
- package/dist/jwt/session-of-claims.d.ts +13 -0
- package/dist/jwt/session-of-claims.d.ts.map +1 -0
- package/dist/jwt/session-of-claims.js +71 -0
- package/dist/jwt/session-of-claims.js.map +1 -0
- package/dist/jwt/without-trailing-slashes.d.ts +3 -0
- package/dist/jwt/without-trailing-slashes.d.ts.map +1 -0
- package/dist/jwt/without-trailing-slashes.js +9 -0
- package/dist/jwt/without-trailing-slashes.js.map +1 -0
- package/dist/jwt.d.ts +3 -0
- package/dist/jwt.d.ts.map +1 -0
- package/dist/jwt.js +3 -0
- package/dist/jwt.js.map +1 -0
- package/dist/permissions/define-permissions.d.ts +13 -0
- package/dist/permissions/define-permissions.d.ts.map +1 -0
- package/dist/permissions/define-permissions.js +23 -0
- package/dist/permissions/define-permissions.js.map +1 -0
- package/dist/permissions/grant-covers.d.ts +3 -0
- package/dist/permissions/grant-covers.d.ts.map +1 -0
- package/dist/permissions/grant-covers.js +5 -0
- package/dist/permissions/grant-covers.js.map +1 -0
- package/dist/permissions/grant-pattern.d.ts +5 -0
- package/dist/permissions/grant-pattern.d.ts.map +1 -0
- package/dist/permissions/grant-pattern.js +12 -0
- package/dist/permissions/grant-pattern.js.map +1 -0
- package/dist/permissions/grant.d.ts +4 -0
- package/dist/permissions/grant.d.ts.map +1 -0
- package/dist/permissions/grant.js +2 -0
- package/dist/permissions/grant.js.map +1 -0
- package/dist/permissions/is-permission.d.ts +3 -0
- package/dist/permissions/is-permission.d.ts.map +1 -0
- package/dist/permissions/is-permission.js +10 -0
- package/dist/permissions/is-permission.js.map +1 -0
- package/dist/permissions/permission-registry.d.ts +12 -0
- package/dist/permissions/permission-registry.d.ts.map +1 -0
- package/dist/permissions/permission-registry.js +31 -0
- package/dist/permissions/permission-registry.js.map +1 -0
- package/dist/permissions/permission.d.ts +9 -0
- package/dist/permissions/permission.d.ts.map +1 -0
- package/dist/permissions/permission.js +2 -0
- package/dist/permissions/permission.js.map +1 -0
- package/dist/policies/define-policy.d.ts +4 -0
- package/dist/policies/define-policy.d.ts.map +1 -0
- package/dist/policies/define-policy.js +10 -0
- package/dist/policies/define-policy.js.map +1 -0
- package/dist/policies/policy-access.d.ts +32 -0
- package/dist/policies/policy-access.d.ts.map +1 -0
- package/dist/policies/policy-access.js +78 -0
- package/dist/policies/policy-access.js.map +1 -0
- package/dist/policies/policy-context.d.ts +5 -0
- package/dist/policies/policy-context.d.ts.map +1 -0
- package/dist/policies/policy-context.js +2 -0
- package/dist/policies/policy-context.js.map +1 -0
- package/dist/policies/policy.d.ts +18 -0
- package/dist/policies/policy.d.ts.map +1 -0
- package/dist/policies/policy.js +2 -0
- package/dist/policies/policy.js.map +1 -0
- package/dist/rbac/role-based-authorizer.d.ts +35 -0
- package/dist/rbac/role-based-authorizer.d.ts.map +1 -0
- package/dist/rbac/role-based-authorizer.js +68 -0
- package/dist/rbac/role-based-authorizer.js.map +1 -0
- package/dist/rbac/tenant-of-context.d.ts +4 -0
- package/dist/rbac/tenant-of-context.d.ts.map +1 -0
- package/dist/rbac/tenant-of-context.js +6 -0
- package/dist/rbac/tenant-of-context.js.map +1 -0
- package/dist/rebac/define-schema.d.ts +8 -0
- package/dist/rebac/define-schema.d.ts.map +1 -0
- package/dist/rebac/define-schema.js +99 -0
- package/dist/rebac/define-schema.js.map +1 -0
- package/dist/rebac/evaluation.d.ts +31 -0
- package/dist/rebac/evaluation.d.ts.map +1 -0
- package/dist/rebac/evaluation.js +94 -0
- package/dist/rebac/evaluation.js.map +1 -0
- package/dist/rebac/expand-node.d.ts +13 -0
- package/dist/rebac/expand-node.d.ts.map +1 -0
- package/dist/rebac/expand-node.js +2 -0
- package/dist/rebac/expand-node.js.map +1 -0
- package/dist/rebac/in-memory-relation-tuple-store.d.ts +12 -0
- package/dist/rebac/in-memory-relation-tuple-store.d.ts.map +1 -0
- package/dist/rebac/in-memory-relation-tuple-store.js +25 -0
- package/dist/rebac/in-memory-relation-tuple-store.js.map +1 -0
- package/dist/rebac/invalid-tuple-error.d.ts +5 -0
- package/dist/rebac/invalid-tuple-error.d.ts.map +1 -0
- package/dist/rebac/invalid-tuple-error.js +8 -0
- package/dist/rebac/invalid-tuple-error.js.map +1 -0
- package/dist/rebac/object-of.d.ts +3 -0
- package/dist/rebac/object-of.d.ts.map +1 -0
- package/dist/rebac/object-of.js +4 -0
- package/dist/rebac/object-of.js.map +1 -0
- package/dist/rebac/parse-object.d.ts +3 -0
- package/dist/rebac/parse-object.d.ts.map +1 -0
- package/dist/rebac/parse-object.js +10 -0
- package/dist/rebac/parse-object.js.map +1 -0
- package/dist/rebac/parse-subject.d.ts +3 -0
- package/dist/rebac/parse-subject.d.ts.map +1 -0
- package/dist/rebac/parse-subject.js +11 -0
- package/dist/rebac/parse-subject.js.map +1 -0
- package/dist/rebac/permission-mapping.d.ts +3 -0
- package/dist/rebac/permission-mapping.d.ts.map +1 -0
- package/dist/rebac/permission-mapping.js +2 -0
- package/dist/rebac/permission-mapping.js.map +1 -0
- package/dist/rebac/relation-based-authorizer.d.ts +45 -0
- package/dist/rebac/relation-based-authorizer.d.ts.map +1 -0
- package/dist/rebac/relation-based-authorizer.js +113 -0
- package/dist/rebac/relation-based-authorizer.js.map +1 -0
- package/dist/rebac/relation-tuple-store.d.ts +16 -0
- package/dist/rebac/relation-tuple-store.d.ts.map +1 -0
- package/dist/rebac/relation-tuple-store.js +8 -0
- package/dist/rebac/relation-tuple-store.js.map +1 -0
- package/dist/rebac/relation-tuple.d.ts +12 -0
- package/dist/rebac/relation-tuple.d.ts.map +1 -0
- package/dist/rebac/relation-tuple.js +2 -0
- package/dist/rebac/relation-tuple.js.map +1 -0
- package/dist/rebac/resolution.d.ts +9 -0
- package/dist/rebac/resolution.d.ts.map +1 -0
- package/dist/rebac/resolution.js +2 -0
- package/dist/rebac/resolution.js.map +1 -0
- package/dist/rebac/reverse-expansion-limit-error.d.ts +5 -0
- package/dist/rebac/reverse-expansion-limit-error.d.ts.map +1 -0
- package/dist/rebac/reverse-expansion-limit-error.js +8 -0
- package/dist/rebac/reverse-expansion-limit-error.js.map +1 -0
- package/dist/rebac/rewrite.d.ts +24 -0
- package/dist/rebac/rewrite.d.ts.map +1 -0
- package/dist/rebac/rewrite.js +15 -0
- package/dist/rebac/rewrite.js.map +1 -0
- package/dist/rebac/schema-checked-tuple-store.d.ts +14 -0
- package/dist/rebac/schema-checked-tuple-store.d.ts.map +1 -0
- package/dist/rebac/schema-checked-tuple-store.js +25 -0
- package/dist/rebac/schema-checked-tuple-store.js.map +1 -0
- package/dist/rebac/schema-definition.d.ts +3 -0
- package/dist/rebac/schema-definition.d.ts.map +1 -0
- package/dist/rebac/schema-definition.js +2 -0
- package/dist/rebac/schema-definition.js.map +1 -0
- package/dist/rebac/schema-error.d.ts +5 -0
- package/dist/rebac/schema-error.d.ts.map +1 -0
- package/dist/rebac/schema-error.js +8 -0
- package/dist/rebac/schema-error.js.map +1 -0
- package/dist/rebac/schema.d.ts +18 -0
- package/dist/rebac/schema.d.ts.map +1 -0
- package/dist/rebac/schema.js +49 -0
- package/dist/rebac/schema.js.map +1 -0
- package/dist/rebac/subject-ref.d.ts +6 -0
- package/dist/rebac/subject-ref.d.ts.map +1 -0
- package/dist/rebac/subject-ref.js +2 -0
- package/dist/rebac/subject-ref.js.map +1 -0
- package/dist/rebac/tuple-key.d.ts +3 -0
- package/dist/rebac/tuple-key.d.ts.map +1 -0
- package/dist/rebac/tuple-key.js +4 -0
- package/dist/rebac/tuple-key.js.map +1 -0
- package/dist/rebac/type-definition.d.ts +7 -0
- package/dist/rebac/type-definition.d.ts.map +1 -0
- package/dist/rebac/type-definition.js +2 -0
- package/dist/rebac/type-definition.js.map +1 -0
- package/dist/rebac.d.ts +22 -0
- package/dist/rebac.d.ts.map +1 -0
- package/dist/rebac.js +15 -0
- package/dist/rebac.js.map +1 -0
- package/dist/testing/actor-builder.d.ts +21 -0
- package/dist/testing/actor-builder.d.ts.map +1 -0
- package/dist/testing/actor-builder.js +26 -0
- package/dist/testing/actor-builder.js.map +1 -0
- package/dist/testing/allow-all.d.ts +9 -0
- package/dist/testing/allow-all.d.ts.map +1 -0
- package/dist/testing/allow-all.js +11 -0
- package/dist/testing/allow-all.js.map +1 -0
- package/dist/testing/an-actor.d.ts +4 -0
- package/dist/testing/an-actor.d.ts.map +1 -0
- package/dist/testing/an-actor.js +7 -0
- package/dist/testing/an-actor.js.map +1 -0
- package/dist/testing/authorizer-contract.d.ts +18 -0
- package/dist/testing/authorizer-contract.d.ts.map +1 -0
- package/dist/testing/authorizer-contract.js +102 -0
- package/dist/testing/authorizer-contract.js.map +1 -0
- package/dist/testing/deny-all.d.ts +10 -0
- package/dist/testing/deny-all.d.ts.map +1 -0
- package/dist/testing/deny-all.js +14 -0
- package/dist/testing/deny-all.js.map +1 -0
- package/dist/testing/fake-authenticator.d.ts +13 -0
- package/dist/testing/fake-authenticator.d.ts.map +1 -0
- package/dist/testing/fake-authenticator.js +26 -0
- package/dist/testing/fake-authenticator.js.map +1 -0
- package/dist/testing/recording-authorizer.d.ts +15 -0
- package/dist/testing/recording-authorizer.d.ts.map +1 -0
- package/dist/testing/recording-authorizer.js +19 -0
- package/dist/testing/recording-authorizer.js.map +1 -0
- package/dist/testing/relation-tuple-store-contract.d.ts +10 -0
- package/dist/testing/relation-tuple-store-contract.d.ts.map +1 -0
- package/dist/testing/relation-tuple-store-contract.js +68 -0
- package/dist/testing/relation-tuple-store-contract.js.map +1 -0
- package/dist/testing.d.ts +9 -0
- package/dist/testing.d.ts.map +1 -0
- package/dist/testing.js +9 -0
- package/dist/testing.js.map +1 -0
- package/dist/use-cases/authorization-map.d.ts +18 -0
- package/dist/use-cases/authorization-map.d.ts.map +1 -0
- package/dist/use-cases/authorization-map.js +32 -0
- package/dist/use-cases/authorization-map.js.map +1 -0
- package/dist/use-cases/authorization-middleware.d.ts +17 -0
- package/dist/use-cases/authorization-middleware.d.ts.map +1 -0
- package/dist/use-cases/authorization-middleware.js +49 -0
- package/dist/use-cases/authorization-middleware.js.map +1 -0
- package/dist/use-cases/public-use-case.d.ts +5 -0
- package/dist/use-cases/public-use-case.d.ts.map +1 -0
- package/dist/use-cases/public-use-case.js +5 -0
- package/dist/use-cases/public-use-case.js.map +1 -0
- package/dist/use-cases/requires.d.ts +17 -0
- package/dist/use-cases/requires.d.ts.map +1 -0
- package/dist/use-cases/requires.js +14 -0
- package/dist/use-cases/requires.js.map +1 -0
- package/dist/use-cases/use-case-declaration.d.ts +17 -0
- package/dist/use-cases/use-case-declaration.d.ts.map +1 -0
- package/dist/use-cases/use-case-declaration.js +2 -0
- package/dist/use-cases/use-case-declaration.js.map +1 -0
- package/package.json +67 -4
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Builder, sequence } from '@ddd-ts-kit/testing';
|
|
2
|
+
/** By default a user without tenant, role or attribute, with an id of its own: `actor-1`, `actor-2`... */
|
|
3
|
+
export class ActorBuilder extends Builder {
|
|
4
|
+
named(id) {
|
|
5
|
+
return this.with('id', id);
|
|
6
|
+
}
|
|
7
|
+
ofTenant(tenantId) {
|
|
8
|
+
return this.with('tenantId', tenantId);
|
|
9
|
+
}
|
|
10
|
+
withRole(...roles) {
|
|
11
|
+
return this.adding('roles', ...roles);
|
|
12
|
+
}
|
|
13
|
+
withAttributes(attributes) {
|
|
14
|
+
return this.with('attributes', attributes);
|
|
15
|
+
}
|
|
16
|
+
asService() {
|
|
17
|
+
return this.with('type', 'service');
|
|
18
|
+
}
|
|
19
|
+
defaults() {
|
|
20
|
+
return { id: sequence('actor'), type: 'user', tenantId: undefined, roles: [], attributes: {} };
|
|
21
|
+
}
|
|
22
|
+
construct({ tenantId, ...actor }) {
|
|
23
|
+
return tenantId === undefined ? actor : { ...actor, tenantId };
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=actor-builder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"actor-builder.js","sourceRoot":"","sources":["../../src/testing/actor-builder.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAiB,MAAM,qBAAqB,CAAC;AAUvE,0GAA0G;AAC1G,MAAM,OAAO,YAAa,SAAQ,OAA0B;IAC1D,KAAK,CAAC,EAAU;QACd,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IAC7B,CAAC;IAED,QAAQ,CAAC,QAAgB;QACvB,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IACzC,CAAC;IAED,QAAQ,CAAC,GAAG,KAAwB;QAClC,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG,KAAK,CAAC,CAAC;IACxC,CAAC;IAED,cAAc,CAAC,UAAoD;QACjE,OAAO,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;IAC7C,CAAC;IAED,SAAS;QACP,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACtC,CAAC;IAES,QAAQ;QAChB,OAAO,EAAE,EAAE,EAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;IACjG,CAAC;IAES,SAAS,CAAC,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAc;QACpD,OAAO,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,KAAK,EAAE,QAAQ,EAAE,CAAC;IACjE,CAAC;CACF"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { AccessScope } from '../authorization/access-scope.js';
|
|
2
|
+
import type { Authorizer } from '../authorization/authorizer.js';
|
|
3
|
+
import { type Decision } from '../authorization/decision.js';
|
|
4
|
+
/** For the specs that are not about rights: everything is granted to everybody. */
|
|
5
|
+
export declare class AllowAll implements Authorizer {
|
|
6
|
+
check(): Promise<Decision>;
|
|
7
|
+
listAccessible(): Promise<AccessScope>;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=allow-all.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"allow-all.d.ts","sourceRoot":"","sources":["../../src/testing/allow-all.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AACpE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EAAW,KAAK,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAEtE,mFAAmF;AACnF,qBAAa,QAAS,YAAW,UAAU;IACnC,KAAK,IAAI,OAAO,CAAC,QAAQ,CAAC,CAE/B;IAEK,cAAc,IAAI,OAAO,CAAC,WAAW,CAAC,CAE3C;CACF"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ALLOWED } from '../authorization/decision.js';
|
|
2
|
+
/** For the specs that are not about rights: everything is granted to everybody. */
|
|
3
|
+
export class AllowAll {
|
|
4
|
+
async check() {
|
|
5
|
+
return ALLOWED;
|
|
6
|
+
}
|
|
7
|
+
async listAccessible() {
|
|
8
|
+
return { kind: 'all' };
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=allow-all.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"allow-all.js","sourceRoot":"","sources":["../../src/testing/allow-all.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAiB,MAAM,8BAA8B,CAAC;AAEtE,mFAAmF;AACnF,MAAM,OAAO,QAAQ;IACnB,KAAK,CAAC,KAAK;QACT,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,cAAc;QAClB,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;IACzB,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"an-actor.d.ts","sourceRoot":"","sources":["../../src/testing/an-actor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAIlD,+EAA+E;AAC/E,wBAAgB,OAAO,IAAI,YAAY,CAEtC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"an-actor.js","sourceRoot":"","sources":["../../src/testing/an-actor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,MAAM,OAAO,GAAG,IAAI,YAAY,EAAE,CAAC;AAEnC,+EAA+E;AAC/E,MAAM,UAAU,OAAO;IACrB,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type Awaitable, type ContractRunner } from '@ddd-ts-kit/testing/contracts';
|
|
2
|
+
import type { Authorizer } from '../authorization/authorizer.js';
|
|
3
|
+
import type { CheckRequest } from '../authorization/check-request.js';
|
|
4
|
+
export interface AuthorizerFixture {
|
|
5
|
+
readonly authorizer: Authorizer;
|
|
6
|
+
/** A request the authorizer was set up to allow, by a specific grant rather than a wildcard. */
|
|
7
|
+
readonly granted: CheckRequest;
|
|
8
|
+
/** A request about the same kind of thing that it was set up to refuse. */
|
|
9
|
+
readonly refused: CheckRequest;
|
|
10
|
+
}
|
|
11
|
+
export interface AuthorizerContractOptions {
|
|
12
|
+
readonly name: string;
|
|
13
|
+
/** A fresh authorizer with its two requests; called before each test. */
|
|
14
|
+
create(): Awaitable<AuthorizerFixture>;
|
|
15
|
+
}
|
|
16
|
+
/** What every authorization model guarantees to the middleware and the handlers. */
|
|
17
|
+
export declare function authorizerContract(runner: ContractRunner, options: AuthorizerContractOptions): void;
|
|
18
|
+
//# sourceMappingURL=authorizer-contract.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authorizer-contract.d.ts","sourceRoot":"","sources":["../../src/testing/authorizer-contract.ts"],"names":[],"mappings":"AACA,OAAO,EAAiB,KAAK,SAAS,EAAE,KAAK,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAEnG,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AAItE,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,gGAAgG;IAChG,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC;IAC/B,2EAA2E;IAC3E,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC;CAChC;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,yEAAyE;IACzE,MAAM,IAAI,SAAS,CAAC,iBAAiB,CAAC,CAAC;CACxC;AAED,oFAAoF;AACpF,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,cAAc,EAAE,OAAO,EAAE,yBAAyB,GAAG,IAAI,CAEnG"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { anonymousActor } from '@ddd-ts-kit/kernel';
|
|
2
|
+
import { ContractSuite } from '@ddd-ts-kit/testing/contracts';
|
|
3
|
+
/** What every authorization model guarantees to the middleware and the handlers. */
|
|
4
|
+
export function authorizerContract(runner, options) {
|
|
5
|
+
new AuthorizerSuite(runner, () => options.create()).describe(`${options.name} (authorizer contract)`);
|
|
6
|
+
}
|
|
7
|
+
const NEVER_GRANTED = {
|
|
8
|
+
id: 'contract:never.granted',
|
|
9
|
+
context: 'contract',
|
|
10
|
+
name: 'never.granted',
|
|
11
|
+
description: 'A permission no fixture grants',
|
|
12
|
+
};
|
|
13
|
+
const REASON_CODE = /^[A-Za-z][A-Za-z0-9_.:-]*$/;
|
|
14
|
+
class AuthorizerSuite extends ContractSuite {
|
|
15
|
+
tests() {
|
|
16
|
+
this.allowsWhatWasGranted();
|
|
17
|
+
this.refusesWithAStableReason();
|
|
18
|
+
this.deniesByDefault();
|
|
19
|
+
this.listsWhatItAllows();
|
|
20
|
+
}
|
|
21
|
+
allowsWhatWasGranted() {
|
|
22
|
+
this.it('allows what was granted, each time it is asked', async () => {
|
|
23
|
+
const { authorizer, granted } = this.subject;
|
|
24
|
+
this.expect(await authorizer.check(granted)).toEqual({ allowed: true });
|
|
25
|
+
this.expect(await authorizer.check(granted)).toEqual({ allowed: true });
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
refusesWithAStableReason() {
|
|
29
|
+
this.it('refuses what was not granted with a machine code, the same each time', async () => {
|
|
30
|
+
const { authorizer, refused } = this.subject;
|
|
31
|
+
const first = await authorizer.check(refused);
|
|
32
|
+
const second = await authorizer.check(refused);
|
|
33
|
+
this.expect(first.allowed).toBe(false);
|
|
34
|
+
this.expect(REASON_CODE.test(reasonOf(first))).toBe(true);
|
|
35
|
+
this.expect(second).toEqual(first);
|
|
36
|
+
});
|
|
37
|
+
this.it('never quotes the actor or the resource in the reason', async () => {
|
|
38
|
+
const { authorizer, refused } = this.subject;
|
|
39
|
+
const reason = reasonOf(await authorizer.check(refused));
|
|
40
|
+
this.expect(reason.includes(refused.actor.id)).toBe(false);
|
|
41
|
+
this.expect(refused.resource !== undefined && reason.includes(refused.resource.id)).toBe(false);
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
deniesByDefault() {
|
|
45
|
+
this.it('refuses the anonymous actor, even what somebody else was granted', async () => {
|
|
46
|
+
const { authorizer, granted } = this.subject;
|
|
47
|
+
const decision = await authorizer.check({ ...granted, actor: anonymousActor() });
|
|
48
|
+
this.expect(decision.allowed).toBe(false);
|
|
49
|
+
});
|
|
50
|
+
this.it('refuses a permission nobody was granted', async () => {
|
|
51
|
+
const { authorizer, granted } = this.subject;
|
|
52
|
+
const decision = await authorizer.check({ ...granted, permission: NEVER_GRANTED });
|
|
53
|
+
this.expect(decision.allowed).toBe(false);
|
|
54
|
+
});
|
|
55
|
+
this.it('leaves the request as it was', async () => {
|
|
56
|
+
const { authorizer, granted } = this.subject;
|
|
57
|
+
const before = structuredClone(granted);
|
|
58
|
+
await authorizer.check(granted);
|
|
59
|
+
this.expect(granted).toEqual(before);
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
listsWhatItAllows() {
|
|
63
|
+
this.it('lists nothing for the anonymous actor', async () => {
|
|
64
|
+
const { granted } = this.subject;
|
|
65
|
+
const scope = await this.scopeOf({ ...granted, actor: anonymousActor() });
|
|
66
|
+
this.expect(scope === undefined || covers(scope, granted.resource?.id ?? 'any') === 'no').toBe(true);
|
|
67
|
+
});
|
|
68
|
+
this.it('lists what a check allows and not what it refuses', async () => {
|
|
69
|
+
const { granted, refused } = this.subject;
|
|
70
|
+
const allowed = await this.scopeOf(granted);
|
|
71
|
+
const denied = await this.scopeOf(refused);
|
|
72
|
+
this.expect(allowed === undefined || covers(allowed, granted.resource?.id) !== 'no').toBe(true);
|
|
73
|
+
this.expect(denied === undefined || covers(denied, refused.resource?.id) !== 'yes').toBe(true);
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
/** `undefined` when the model cannot enumerate or the request names no resource type. */
|
|
77
|
+
async scopeOf({ actor, permission, resource }) {
|
|
78
|
+
const { authorizer } = this.subject;
|
|
79
|
+
const resourceType = resource?.type ?? this.subject.granted.resource?.type;
|
|
80
|
+
if (resourceType === undefined) {
|
|
81
|
+
return undefined;
|
|
82
|
+
}
|
|
83
|
+
return authorizer.listAccessible?.({ actor, permission, resourceType });
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
function reasonOf(decision) {
|
|
87
|
+
return decision.allowed ? '' : decision.reason;
|
|
88
|
+
}
|
|
89
|
+
/** A filter is for the read port to apply: nothing here can tell what it covers. */
|
|
90
|
+
function covers(scope, id) {
|
|
91
|
+
if (scope.kind === 'all') {
|
|
92
|
+
return 'yes';
|
|
93
|
+
}
|
|
94
|
+
if (scope.kind === 'none') {
|
|
95
|
+
return 'no';
|
|
96
|
+
}
|
|
97
|
+
if (scope.kind === 'filter' || id === undefined) {
|
|
98
|
+
return 'unknown';
|
|
99
|
+
}
|
|
100
|
+
return scope.ids.includes(id) ? 'yes' : 'no';
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=authorizer-contract.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authorizer-contract.js","sourceRoot":"","sources":["../../src/testing/authorizer-contract.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { AccessScope } from '../authorization/access-scope.js';
|
|
2
|
+
import type { Authorizer } from '../authorization/authorizer.js';
|
|
3
|
+
import { type Decision } from '../authorization/decision.js';
|
|
4
|
+
export declare class DenyAll implements Authorizer {
|
|
5
|
+
private readonly reason;
|
|
6
|
+
constructor(reason?: string);
|
|
7
|
+
check(): Promise<Decision>;
|
|
8
|
+
listAccessible(): Promise<AccessScope>;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=deny-all.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deny-all.d.ts","sourceRoot":"","sources":["../../src/testing/deny-all.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AACpE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EAAQ,KAAK,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAEnE,qBAAa,OAAQ,YAAW,UAAU;IAC5B,OAAO,CAAC,QAAQ,CAAC,MAAM;IAAnC,YAA6B,MAAM,SAAmB,EAAI;IAEpD,KAAK,IAAI,OAAO,CAAC,QAAQ,CAAC,CAE/B;IAEK,cAAc,IAAI,OAAO,CAAC,WAAW,CAAC,CAE3C;CACF"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { deny } from '../authorization/decision.js';
|
|
2
|
+
export class DenyAll {
|
|
3
|
+
reason;
|
|
4
|
+
constructor(reason = 'DENIED_BY_TEST') {
|
|
5
|
+
this.reason = reason;
|
|
6
|
+
}
|
|
7
|
+
async check() {
|
|
8
|
+
return deny(this.reason);
|
|
9
|
+
}
|
|
10
|
+
async listAccessible() {
|
|
11
|
+
return { kind: 'none' };
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=deny-all.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deny-all.js","sourceRoot":"","sources":["../../src/testing/deny-all.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,IAAI,EAAiB,MAAM,8BAA8B,CAAC;AAEnE,MAAM,OAAO,OAAO;IACW,MAAM;IAAnC,YAA6B,MAAM,GAAG,gBAAgB;sBAAzB,MAAM;IAAsB,CAAC;IAE1D,KAAK,CAAC,KAAK;QACT,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC3B,CAAC;IAED,KAAK,CAAC,cAAc;QAClB,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAC1B,CAAC;CACF"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Actor, Session } from '@ddd-ts-kit/kernel';
|
|
2
|
+
import type { SessionAuthenticator } from '../authentication/session-authenticator.js';
|
|
3
|
+
/**
|
|
4
|
+
* Knows a few credentials by heart, each standing for an actor or for a whole session:
|
|
5
|
+
* `new FakeAuthenticator({ 'token-of-ada': ada, 'token-of-support': aSession().of(bob).build() })`.
|
|
6
|
+
*/
|
|
7
|
+
export declare class FakeAuthenticator implements SessionAuthenticator {
|
|
8
|
+
private readonly principals;
|
|
9
|
+
constructor(principals: Readonly<Record<string, Actor | Session>>);
|
|
10
|
+
authenticate(credential: string | undefined): Promise<Actor>;
|
|
11
|
+
authenticateSession(credential: string | undefined): Promise<Session>;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=fake-authenticator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fake-authenticator.d.ts","sourceRoot":"","sources":["../../src/testing/fake-authenticator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4CAA4C,CAAC;AAIvF;;;GAGG;AACH,qBAAa,iBAAkB,YAAW,oBAAoB;IAChD,OAAO,CAAC,QAAQ,CAAC,UAAU;IAAvC,YAA6B,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,GAAG,OAAO,CAAC,CAAC,EAAI;IAEhF,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,CAEjE;IAEK,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,CAY1E;CACF"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { sessionOf } from '../authentication/session-of.js';
|
|
2
|
+
import { InvalidCredentialError } from '../errors/invalid-credential-error.js';
|
|
3
|
+
/**
|
|
4
|
+
* Knows a few credentials by heart, each standing for an actor or for a whole session:
|
|
5
|
+
* `new FakeAuthenticator({ 'token-of-ada': ada, 'token-of-support': aSession().of(bob).build() })`.
|
|
6
|
+
*/
|
|
7
|
+
export class FakeAuthenticator {
|
|
8
|
+
principals;
|
|
9
|
+
constructor(principals) {
|
|
10
|
+
this.principals = principals;
|
|
11
|
+
}
|
|
12
|
+
async authenticate(credential) {
|
|
13
|
+
return (await this.authenticateSession(credential)).actor;
|
|
14
|
+
}
|
|
15
|
+
async authenticateSession(credential) {
|
|
16
|
+
if (credential === undefined) {
|
|
17
|
+
return sessionOf(undefined);
|
|
18
|
+
}
|
|
19
|
+
const principal = this.principals[credential];
|
|
20
|
+
if (principal === undefined) {
|
|
21
|
+
throw new InvalidCredentialError('UNKNOWN_CREDENTIAL');
|
|
22
|
+
}
|
|
23
|
+
return sessionOf(principal);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=fake-authenticator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fake-authenticator.js","sourceRoot":"","sources":["../../src/testing/fake-authenticator.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAC;AAC5D,OAAO,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAC;AAE/E;;;GAGG;AACH,MAAM,OAAO,iBAAiB;IACC,UAAU;IAAvC,YAA6B,UAAqD;0BAArD,UAAU;IAA8C,CAAC;IAEtF,KAAK,CAAC,YAAY,CAAC,UAA8B;QAC/C,OAAO,CAAC,MAAM,IAAI,CAAC,mBAAmB,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC;IAC5D,CAAC;IAED,KAAK,CAAC,mBAAmB,CAAC,UAA8B;QACtD,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;YAC7B,OAAO,SAAS,CAAC,SAAS,CAAC,CAAC;QAC9B,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;QAE9C,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;YAC5B,MAAM,IAAI,sBAAsB,CAAC,oBAAoB,CAAC,CAAC;QACzD,CAAC;QAED,OAAO,SAAS,CAAC,SAAS,CAAC,CAAC;IAC9B,CAAC;CACF"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { AccessScope } from '../authorization/access-scope.js';
|
|
2
|
+
import type { Authorizer } from '../authorization/authorizer.js';
|
|
3
|
+
import type { CheckRequest } from '../authorization/check-request.js';
|
|
4
|
+
import type { Decision } from '../authorization/decision.js';
|
|
5
|
+
import type { ListRequest } from '../authorization/list-request.js';
|
|
6
|
+
/** Keeps what it was asked, as data, and answers what the wrapped authorizer answers. */
|
|
7
|
+
export declare class RecordingAuthorizer implements Authorizer {
|
|
8
|
+
private readonly answering;
|
|
9
|
+
readonly checks: CheckRequest[];
|
|
10
|
+
readonly listings: ListRequest[];
|
|
11
|
+
constructor(answering?: Authorizer);
|
|
12
|
+
check(request: CheckRequest): Promise<Decision>;
|
|
13
|
+
listAccessible(request: ListRequest): Promise<AccessScope>;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=recording-authorizer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recording-authorizer.d.ts","sourceRoot":"","sources":["../../src/testing/recording-authorizer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AACpE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAGpE,yFAAyF;AACzF,qBAAa,mBAAoB,YAAW,UAAU;IAKxC,OAAO,CAAC,QAAQ,CAAC,SAAS;IAJtC,QAAQ,CAAC,MAAM,EAAE,YAAY,EAAE,CAAM;IAErC,QAAQ,CAAC,QAAQ,EAAE,WAAW,EAAE,CAAM;IAEtC,YAA6B,SAAS,GAAE,UAA2B,EAAI;IAEjE,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,QAAQ,CAAC,CAIpD;IAEK,cAAc,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,CAI/D;CACF"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { AllowAll } from './allow-all.js';
|
|
2
|
+
/** Keeps what it was asked, as data, and answers what the wrapped authorizer answers. */
|
|
3
|
+
export class RecordingAuthorizer {
|
|
4
|
+
answering;
|
|
5
|
+
checks = [];
|
|
6
|
+
listings = [];
|
|
7
|
+
constructor(answering = new AllowAll()) {
|
|
8
|
+
this.answering = answering;
|
|
9
|
+
}
|
|
10
|
+
async check(request) {
|
|
11
|
+
this.checks.push(request);
|
|
12
|
+
return this.answering.check(request);
|
|
13
|
+
}
|
|
14
|
+
async listAccessible(request) {
|
|
15
|
+
this.listings.push(request);
|
|
16
|
+
return (await this.answering.listAccessible?.(request)) ?? { kind: 'none' };
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=recording-authorizer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recording-authorizer.js","sourceRoot":"","sources":["../../src/testing/recording-authorizer.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE1C,yFAAyF;AACzF,MAAM,OAAO,mBAAmB;IAKD,SAAS;IAJ7B,MAAM,GAAmB,EAAE,CAAC;IAE5B,QAAQ,GAAkB,EAAE,CAAC;IAEtC,YAA6B,SAAS,GAAe,IAAI,QAAQ,EAAE;yBAAtC,SAAS;IAAgC,CAAC;IAEvE,KAAK,CAAC,KAAK,CAAC,OAAqB;QAC/B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAE1B,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACvC,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,OAAoB;QACvC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAE5B,OAAO,CAAC,MAAM,IAAI,CAAC,SAAS,CAAC,cAAc,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAC9E,CAAC;CACF"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type Awaitable, type ContractRunner } from '@ddd-ts-kit/testing/contracts';
|
|
2
|
+
import type { RelationTupleStore } from '../rebac/relation-tuple-store.js';
|
|
3
|
+
export interface RelationTupleStoreContractOptions {
|
|
4
|
+
readonly name: string;
|
|
5
|
+
/** A fresh, empty store; called before each test. */
|
|
6
|
+
create(): Awaitable<RelationTupleStore>;
|
|
7
|
+
}
|
|
8
|
+
/** What every relation tuple store, in memory or in a database, guarantees to the authorizer. */
|
|
9
|
+
export declare function relationTupleStoreContract(runner: ContractRunner, options: RelationTupleStoreContractOptions): void;
|
|
10
|
+
//# sourceMappingURL=relation-tuple-store-contract.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relation-tuple-store-contract.d.ts","sourceRoot":"","sources":["../../src/testing/relation-tuple-store-contract.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,SAAS,EAAE,KAAK,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAEnG,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AAG3E,MAAM,WAAW,iCAAiC;IAChD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,qDAAqD;IACrD,MAAM,IAAI,SAAS,CAAC,kBAAkB,CAAC,CAAC;CACzC;AAED,iGAAiG;AACjG,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,cAAc,EAAE,OAAO,EAAE,iCAAiC,GAAG,IAAI,CAEnH"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { ContractSuite } from '@ddd-ts-kit/testing/contracts';
|
|
2
|
+
import { tupleKey } from '../rebac/tuple-key.js';
|
|
3
|
+
/** What every relation tuple store, in memory or in a database, guarantees to the authorizer. */
|
|
4
|
+
export function relationTupleStoreContract(runner, options) {
|
|
5
|
+
new TupleStoreSuite(runner, () => options.create()).describe(`${options.name} (relation tuple store contract)`);
|
|
6
|
+
}
|
|
7
|
+
const adaEdits = { object: 'document:1', relation: 'editor', subject: 'user:ada' };
|
|
8
|
+
const adaViews = { object: 'document:1', relation: 'viewer', subject: 'user:ada' };
|
|
9
|
+
const adamEdits = { object: 'document:1', relation: 'editor', subject: 'user:adam' };
|
|
10
|
+
const teamEdits = { object: 'document:1', relation: 'editor', subject: 'group:eng#member' };
|
|
11
|
+
const adaEditsAnother = { object: 'document:10', relation: 'editor', subject: 'user:ada' };
|
|
12
|
+
const filedUnderTeam = { object: 'document:1', relation: 'parent', subject: 'group:eng' };
|
|
13
|
+
class TupleStoreSuite extends ContractSuite {
|
|
14
|
+
tests() {
|
|
15
|
+
this.readsByObjectAndRelation();
|
|
16
|
+
this.readsBySubject();
|
|
17
|
+
this.writesOnce();
|
|
18
|
+
this.deletes();
|
|
19
|
+
}
|
|
20
|
+
readsByObjectAndRelation() {
|
|
21
|
+
this.it('reads what was written, by object and relation', async () => {
|
|
22
|
+
await this.subject.write([adaEdits, teamEdits]);
|
|
23
|
+
this.expect(sorted(await this.subject.readByObject('document:1', 'editor'))).toEqual(sorted([adaEdits, teamEdits]));
|
|
24
|
+
});
|
|
25
|
+
this.it('keeps objects and relations apart', async () => {
|
|
26
|
+
await this.subject.write([adaEdits, adaViews, adaEditsAnother]);
|
|
27
|
+
this.expect(await this.subject.readByObject('document:1', 'viewer')).toEqual([adaViews]);
|
|
28
|
+
this.expect(await this.subject.readByObject('document:10', 'editor')).toEqual([adaEditsAnother]);
|
|
29
|
+
this.expect(await this.subject.readByObject('document:2', 'editor')).toEqual([]);
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
readsBySubject() {
|
|
33
|
+
this.it('reads by subject across objects and relations', async () => {
|
|
34
|
+
await this.subject.write([adaEdits, adaViews, adaEditsAnother, adamEdits]);
|
|
35
|
+
this.expect(sorted(await this.subject.readBySubject('user:ada'))).toEqual(sorted([adaEdits, adaViews, adaEditsAnother]));
|
|
36
|
+
});
|
|
37
|
+
this.it('matches the subject exactly, a userset being another subject than its object', async () => {
|
|
38
|
+
await this.subject.write([adamEdits, teamEdits, filedUnderTeam]);
|
|
39
|
+
this.expect(await this.subject.readBySubject('user:ada')).toEqual([]);
|
|
40
|
+
this.expect(await this.subject.readBySubject('group:eng#member')).toEqual([teamEdits]);
|
|
41
|
+
this.expect(await this.subject.readBySubject('group:eng')).toEqual([filedUnderTeam]);
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
writesOnce() {
|
|
45
|
+
this.it('stores a tuple written twice once', async () => {
|
|
46
|
+
await this.subject.write([adaEdits]);
|
|
47
|
+
await this.subject.write([adaEdits, adaEdits]);
|
|
48
|
+
this.expect(await this.subject.readByObject('document:1', 'editor')).toEqual([adaEdits]);
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
deletes() {
|
|
52
|
+
this.it('deletes the given tuples and no other', async () => {
|
|
53
|
+
await this.subject.write([adaEdits, adamEdits, adaViews]);
|
|
54
|
+
await this.subject.delete([adaEdits]);
|
|
55
|
+
this.expect(await this.subject.readByObject('document:1', 'editor')).toEqual([adamEdits]);
|
|
56
|
+
this.expect(await this.subject.readBySubject('user:ada')).toEqual([adaViews]);
|
|
57
|
+
});
|
|
58
|
+
this.it('accepts the deletion of a tuple that is not there', async () => {
|
|
59
|
+
await this.subject.write([adaEdits]);
|
|
60
|
+
await this.subject.delete([adamEdits]);
|
|
61
|
+
this.expect(await this.subject.readByObject('document:1', 'editor')).toEqual([adaEdits]);
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
function sorted(tuples) {
|
|
66
|
+
return [...tuples].sort((left, right) => tupleKey(left).localeCompare(tupleKey(right)));
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=relation-tuple-store-contract.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relation-tuple-store-contract.js","sourceRoot":"","sources":["../../src/testing/relation-tuple-store-contract.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { ActorBuilder } from './testing/actor-builder.js';
|
|
2
|
+
export { AllowAll } from './testing/allow-all.js';
|
|
3
|
+
export { anActor } from './testing/an-actor.js';
|
|
4
|
+
export { authorizerContract, type AuthorizerContractOptions, type AuthorizerFixture, } from './testing/authorizer-contract.js';
|
|
5
|
+
export { DenyAll } from './testing/deny-all.js';
|
|
6
|
+
export { FakeAuthenticator } from './testing/fake-authenticator.js';
|
|
7
|
+
export { RecordingAuthorizer } from './testing/recording-authorizer.js';
|
|
8
|
+
export { relationTupleStoreContract, type RelationTupleStoreContractOptions, } from './testing/relation-tuple-store-contract.js';
|
|
9
|
+
//# sourceMappingURL=testing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAChD,OAAO,EACL,kBAAkB,EAClB,KAAK,yBAAyB,EAC9B,KAAK,iBAAiB,GACvB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,EACL,0BAA0B,EAC1B,KAAK,iCAAiC,GACvC,MAAM,4CAA4C,CAAC"}
|
package/dist/testing.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { ActorBuilder } from './testing/actor-builder.js';
|
|
2
|
+
export { AllowAll } from './testing/allow-all.js';
|
|
3
|
+
export { anActor } from './testing/an-actor.js';
|
|
4
|
+
export { authorizerContract, } from './testing/authorizer-contract.js';
|
|
5
|
+
export { DenyAll } from './testing/deny-all.js';
|
|
6
|
+
export { FakeAuthenticator } from './testing/fake-authenticator.js';
|
|
7
|
+
export { RecordingAuthorizer } from './testing/recording-authorizer.js';
|
|
8
|
+
export { relationTupleStoreContract, } from './testing/relation-tuple-store-contract.js';
|
|
9
|
+
//# sourceMappingURL=testing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"testing.js","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAChD,OAAO,EACL,kBAAkB,GAGnB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,EACL,0BAA0B,GAE3B,MAAM,4CAA4C,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Message } from '@ddd-ts-kit/kernel';
|
|
2
|
+
import type { UseCaseDeclaration } from './use-case-declaration.js';
|
|
3
|
+
/**
|
|
4
|
+
* What each command and query requires. A message absent from it is refused: deny by default.
|
|
5
|
+
* A value, not a port: the authorization module builds it from what the use cases declared
|
|
6
|
+
* and binds it under this class.
|
|
7
|
+
*/
|
|
8
|
+
export declare class AuthorizationMap {
|
|
9
|
+
static readonly tokenKey = "auth.AuthorizationMap";
|
|
10
|
+
private readonly byType;
|
|
11
|
+
static of(...declarations: readonly UseCaseDeclaration[]): AuthorizationMap;
|
|
12
|
+
constructor(declarations?: readonly UseCaseDeclaration[]);
|
|
13
|
+
find(message: Message): UseCaseDeclaration | undefined;
|
|
14
|
+
declarations(): readonly UseCaseDeclaration[];
|
|
15
|
+
/** The maps of several contexts as one, for the composition root. */
|
|
16
|
+
merge(...others: readonly AuthorizationMap[]): AuthorizationMap;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=authorization-map.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authorization-map.d.ts","sourceRoot":"","sources":["../../src/use-cases/authorization-map.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAElD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAEpE;;;;GAIG;AACH,qBAAa,gBAAgB;IAC3B,MAAM,CAAC,QAAQ,CAAC,QAAQ,2BAA2B;IAEnD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA0C;IAEjE,MAAM,CAAC,EAAE,CAAC,GAAG,YAAY,EAAE,SAAS,kBAAkB,EAAE,GAAG,gBAAgB,CAE1E;IAED,YAAY,YAAY,GAAE,SAAS,kBAAkB,EAAO,EAQ3D;IAED,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,kBAAkB,GAAG,SAAS,CAErD;IAED,YAAY,IAAI,SAAS,kBAAkB,EAAE,CAE5C;IAED,qEAAqE;IACrE,KAAK,CAAC,GAAG,MAAM,EAAE,SAAS,gBAAgB,EAAE,GAAG,gBAAgB,CAE9D;CACF"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { AuthorizationSetupError } from '../errors/authorization-setup-error.js';
|
|
2
|
+
/**
|
|
3
|
+
* What each command and query requires. A message absent from it is refused: deny by default.
|
|
4
|
+
* A value, not a port: the authorization module builds it from what the use cases declared
|
|
5
|
+
* and binds it under this class.
|
|
6
|
+
*/
|
|
7
|
+
export class AuthorizationMap {
|
|
8
|
+
static tokenKey = 'auth.AuthorizationMap';
|
|
9
|
+
byType = new Map();
|
|
10
|
+
static of(...declarations) {
|
|
11
|
+
return new AuthorizationMap(declarations);
|
|
12
|
+
}
|
|
13
|
+
constructor(declarations = []) {
|
|
14
|
+
for (const declaration of declarations) {
|
|
15
|
+
if (this.byType.has(declaration.type)) {
|
|
16
|
+
throw new AuthorizationSetupError(`The access to ${declaration.type.name} is declared twice.`);
|
|
17
|
+
}
|
|
18
|
+
this.byType.set(declaration.type, declaration);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
find(message) {
|
|
22
|
+
return this.byType.get(message.constructor);
|
|
23
|
+
}
|
|
24
|
+
declarations() {
|
|
25
|
+
return [...this.byType.values()];
|
|
26
|
+
}
|
|
27
|
+
/** The maps of several contexts as one, for the composition root. */
|
|
28
|
+
merge(...others) {
|
|
29
|
+
return new AuthorizationMap([this, ...others].flatMap((map) => map.declarations()));
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=authorization-map.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authorization-map.js","sourceRoot":"","sources":["../../src/use-cases/authorization-map.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,uBAAuB,EAAE,MAAM,wCAAwC,CAAC;AAGjF;;;;GAIG;AACH,MAAM,OAAO,gBAAgB;IAC3B,MAAM,CAAU,QAAQ,GAAG,uBAAuB,CAAC;IAElC,MAAM,GAAG,IAAI,GAAG,EAA+B,CAAC;IAEjE,MAAM,CAAC,EAAE,CAAC,GAAG,YAA2C;QACtD,OAAO,IAAI,gBAAgB,CAAC,YAAY,CAAC,CAAC;IAC5C,CAAC;IAED,YAAY,YAAY,GAAkC,EAAE;QAC1D,KAAK,MAAM,WAAW,IAAI,YAAY,EAAE,CAAC;YACvC,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;gBACtC,MAAM,IAAI,uBAAuB,CAAC,iBAAiB,WAAW,CAAC,IAAI,CAAC,IAAI,qBAAqB,CAAC,CAAC;YACjG,CAAC;YAED,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QACjD,CAAC;IACH,CAAC;IAED,IAAI,CAAC,OAAgB;QACnB,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IAC9C,CAAC;IAED,YAAY;QACV,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;IACnC,CAAC;IAED,qEAAqE;IACrE,KAAK,CAAC,GAAG,MAAmC;QAC1C,OAAO,IAAI,gBAAgB,CAAC,CAAC,IAAI,EAAE,GAAG,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC;IACtF,CAAC;CACF"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type BusMiddleware } from '@ddd-ts-kit/kernel';
|
|
2
|
+
import type { Authorizer } from '../authorization/authorizer.js';
|
|
3
|
+
import type { OnDecision } from '../authorization/on-decision.js';
|
|
4
|
+
import type { AuthorizationMap } from './authorization-map.js';
|
|
5
|
+
export interface AuthorizationMiddlewareOptions {
|
|
6
|
+
readonly authorizer: Authorizer;
|
|
7
|
+
readonly map: AuthorizationMap;
|
|
8
|
+
/** The audit hook: called once per protected message, whether allowed or refused. */
|
|
9
|
+
readonly onDecision?: OnDecision;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Asks the authorizer before any handler runs. Deny by default: a message the map does not
|
|
13
|
+
* know is refused with `UndeclaredUseCaseError`. Install it before the unit of work, so a
|
|
14
|
+
* refused command opens no transaction.
|
|
15
|
+
*/
|
|
16
|
+
export declare function authorizationMiddleware(options: AuthorizationMiddlewareOptions): BusMiddleware;
|
|
17
|
+
//# sourceMappingURL=authorization-middleware.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authorization-middleware.d.ts","sourceRoot":"","sources":["../../src/use-cases/authorization-middleware.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0B,KAAK,aAAa,EAAkC,MAAM,oBAAoB,CAAC;AAChH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAKjE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAKlE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAG/D,MAAM,WAAW,8BAA8B;IAC7C,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,QAAQ,CAAC,GAAG,EAAE,gBAAgB,CAAC;IAC/B,qFAAqF;IACrF,QAAQ,CAAC,UAAU,CAAC,EAAE,UAAU,CAAC;CAClC;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,8BAA8B,GAAG,aAAa,CAc9F"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { isActored, isAnonymous } from '@ddd-ts-kit/kernel';
|
|
2
|
+
import { deny } from '../authorization/decision.js';
|
|
3
|
+
import { decisionRecordOf } from '../authorization/decision-record-of.js';
|
|
4
|
+
import { DenialReason } from '../authorization/denial-reason.js';
|
|
5
|
+
import { ForbiddenError } from '../errors/forbidden-error.js';
|
|
6
|
+
import { MissingActorError } from '../errors/missing-actor-error.js';
|
|
7
|
+
import { UnauthenticatedError } from '../errors/unauthenticated-error.js';
|
|
8
|
+
import { UndeclaredUseCaseError } from '../errors/undeclared-use-case-error.js';
|
|
9
|
+
/**
|
|
10
|
+
* Asks the authorizer before any handler runs. Deny by default: a message the map does not
|
|
11
|
+
* know is refused with `UndeclaredUseCaseError`. Install it before the unit of work, so a
|
|
12
|
+
* refused command opens no transaction.
|
|
13
|
+
*/
|
|
14
|
+
export function authorizationMiddleware(options) {
|
|
15
|
+
return async (message, next, info) => {
|
|
16
|
+
const declaration = options.map.find(message);
|
|
17
|
+
if (declaration === undefined) {
|
|
18
|
+
throw new UndeclaredUseCaseError(info);
|
|
19
|
+
}
|
|
20
|
+
if (declaration.access === 'protected') {
|
|
21
|
+
await assertAllowed(options, declaration, { message, info });
|
|
22
|
+
}
|
|
23
|
+
return next();
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
async function assertAllowed({ authorizer, onDecision }, declaration, { message, info }) {
|
|
27
|
+
const request = requestOf(declaration, message, info);
|
|
28
|
+
const anonymous = isAnonymous(request.actor);
|
|
29
|
+
const decision = anonymous ? deny(DenialReason.anonymous) : await authorizer.check(request);
|
|
30
|
+
await onDecision?.(decisionRecordOf(request, decision, info));
|
|
31
|
+
if (decision.allowed) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
throw anonymous ? new UnauthenticatedError() : new ForbiddenError(request.permission.id, decision.reason);
|
|
35
|
+
}
|
|
36
|
+
function requestOf(declaration, message, info) {
|
|
37
|
+
if (!isActored(message)) {
|
|
38
|
+
throw new MissingActorError(info);
|
|
39
|
+
}
|
|
40
|
+
const resource = declaration.resourceOf(message);
|
|
41
|
+
const context = declaration.contextOf(message);
|
|
42
|
+
return {
|
|
43
|
+
actor: message.actor,
|
|
44
|
+
permission: declaration.permission,
|
|
45
|
+
...(resource === undefined ? {} : { resource }),
|
|
46
|
+
...(context === undefined ? {} : { context }),
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=authorization-middleware.js.map
|