@appsemble/utils 0.29.10 → 0.30.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 +3 -3
- package/api/components/parameters/$own.d.ts +2 -0
- package/api/components/parameters/$own.js +7 -0
- package/api/components/parameters/appMemberId.d.ts +2 -0
- package/api/components/parameters/appMemberId.js +8 -0
- package/api/components/parameters/groupId.d.ts +2 -0
- package/api/components/parameters/groupId.js +8 -0
- package/api/components/parameters/groupMemberId.d.ts +2 -0
- package/api/components/parameters/groupMemberId.js +8 -0
- package/api/components/parameters/index.d.ts +17 -13
- package/api/components/parameters/index.js +17 -13
- package/api/components/parameters/organizationId.d.ts +9 -2
- package/api/components/parameters/organizationId.js +1 -1
- package/api/components/parameters/roles.js +12 -6
- package/api/components/parameters/seed.d.ts +2 -0
- package/api/components/parameters/seed.js +9 -0
- package/api/components/parameters/selectedGroupId.d.ts +2 -0
- package/api/components/parameters/selectedGroupId.js +7 -0
- package/api/components/parameters/serviceSecretId.d.ts +2 -0
- package/api/components/parameters/{appServiceId.js → serviceSecretId.js} +3 -3
- package/api/components/requestBodies/oauth2Consent.js +1 -5
- package/api/components/requestBodies/user.js +1 -1
- package/api/components/schemas/ActionDefinition.js +14 -11
- package/api/components/schemas/AppAccount.js +7 -24
- package/api/components/schemas/AppDefinition.js +3 -15
- package/api/components/schemas/AppMember.d.ts +2 -0
- package/api/components/schemas/AppMember.js +26 -0
- package/api/components/schemas/AppMemberCurrentPatchActionDefinition.d.ts +1 -0
- package/api/components/schemas/AppMemberCurrentPatchActionDefinition.js +30 -0
- package/api/components/schemas/AppMemberDeleteActionDefinition.d.ts +1 -0
- package/api/components/schemas/AppMemberDeleteActionDefinition.js +20 -0
- package/api/components/schemas/AppMemberInfo.d.ts +2 -0
- package/api/components/schemas/AppMemberInfo.js +48 -0
- package/api/components/schemas/AppMemberInviteActionDefinition.d.ts +1 -0
- package/api/components/schemas/AppMemberInviteActionDefinition.js +24 -0
- package/api/components/schemas/AppMemberLoginActionDefinition.d.ts +1 -0
- package/api/components/schemas/AppMemberLoginActionDefinition.js +24 -0
- package/api/components/schemas/AppMemberLogoutActionDefinition.d.ts +1 -0
- package/api/components/schemas/AppMemberLogoutActionDefinition.js +14 -0
- package/api/components/schemas/AppMemberPropertiesPatchActionDefinition.d.ts +1 -0
- package/api/components/schemas/AppMemberPropertiesPatchActionDefinition.js +26 -0
- package/api/components/schemas/AppMemberPropertyDefinition.d.ts +2 -0
- package/api/components/schemas/{UserPropertyDefinition.js → AppMemberPropertyDefinition.js} +5 -5
- package/api/components/schemas/AppMemberQueryActionDefinition.d.ts +1 -0
- package/api/components/schemas/AppMemberQueryActionDefinition.js +20 -0
- package/api/components/schemas/AppMemberRegisterActionDefinition.d.ts +1 -0
- package/api/components/schemas/AppMemberRegisterActionDefinition.js +43 -0
- package/api/components/schemas/AppMemberRoleUpdateActionDefinition.d.ts +1 -0
- package/api/components/schemas/AppMemberRoleUpdateActionDefinition.js +27 -0
- package/api/components/schemas/AppMembersDefinition.d.ts +2 -0
- package/api/components/schemas/AppMembersDefinition.js +17 -0
- package/api/components/schemas/GroupMember.d.ts +2 -0
- package/api/components/schemas/GroupMember.js +19 -0
- package/api/components/schemas/GroupMemberDeleteActionDefinition.d.ts +1 -0
- package/api/components/schemas/{TeamMembersActionDefinition.js → GroupMemberDeleteActionDefinition.js} +5 -5
- package/api/components/schemas/GroupMemberInviteActionDefinition.d.ts +1 -0
- package/api/components/schemas/{TeamInviteActionDefinition.js → GroupMemberInviteActionDefinition.js} +5 -6
- package/api/components/schemas/GroupMemberQueryActionDefinition.d.ts +1 -0
- package/api/components/schemas/GroupMemberQueryActionDefinition.js +18 -0
- package/api/components/schemas/GroupMemberRoleUpdateActionDefinition.d.ts +1 -0
- package/api/components/schemas/GroupMemberRoleUpdateActionDefinition.js +22 -0
- package/api/components/schemas/GroupQueryActionDefinition.d.ts +1 -0
- package/api/components/schemas/{UserLogoutActionDefinition.js → GroupQueryActionDefinition.js} +4 -4
- package/api/components/schemas/OrganizationMember.js +2 -2
- package/api/components/schemas/ResourceCountActionDefinition.js +4 -0
- package/api/components/schemas/ResourceCreateActionDefinition.js +1 -1
- package/api/components/schemas/ResourceDefinition.js +0 -22
- package/api/components/schemas/ResourceQueryActionDefinition.js +4 -0
- package/api/components/schemas/SecurityDefaultDefinition.js +1 -1
- package/api/components/schemas/SecurityDefinition.js +2 -6
- package/api/components/schemas/SecurityGuestDefinition.d.ts +2 -0
- package/api/components/schemas/SecurityGuestDefinition.js +26 -0
- package/api/components/schemas/SecurityRoleDefinition.js +7 -0
- package/api/components/schemas/User.js +2 -22
- package/api/components/schemas/UserInfo.d.ts +2 -0
- package/api/components/schemas/UserInfo.js +42 -0
- package/api/components/schemas/index.d.ts +22 -15
- package/api/components/schemas/index.js +22 -15
- package/api/components/securitySchemes/app.js +6 -6
- package/api/components/securitySchemes/cli.js +3 -3
- package/api/paths/app-collections/appCollectionId/apps/appId/pinned.d.ts +2 -0
- package/api/paths/app-collections/appCollectionId/apps/appId/pinned.js +70 -0
- package/api/paths/app-collections/appCollectionId/apps/appId.d.ts +2 -0
- package/api/paths/app-collections/appCollectionId/apps/appId.js +34 -0
- package/api/paths/app-collections/appCollectionId/apps.d.ts +2 -0
- package/api/paths/app-collections/appCollectionId/apps.js +93 -0
- package/api/paths/app-collections/appCollectionId/expert/profileImage.d.ts +2 -0
- package/api/paths/app-collections/appCollectionId/expert/profileImage.js +31 -0
- package/api/paths/app-collections/appCollectionId/headerImage.d.ts +2 -0
- package/api/paths/app-collections/appCollectionId/headerImage.js +31 -0
- package/api/paths/app-collections/appCollectionId.d.ts +2 -0
- package/api/paths/app-collections/appCollectionId.js +102 -0
- package/api/paths/app-invites/token/respond.d.ts +2 -0
- package/api/paths/app-invites/token/respond.js +51 -0
- package/api/paths/app-invites/token.d.ts +2 -0
- package/api/paths/app-invites/token.js +23 -0
- package/api/paths/app-members/appMemberId/picture.d.ts +2 -0
- package/api/paths/app-members/appMemberId/picture.js +30 -0
- package/api/paths/app-members/appMemberId/properties.d.ts +2 -0
- package/api/paths/app-members/appMemberId/properties.js +48 -0
- package/api/paths/app-members/appMemberId/role.d.ts +2 -0
- package/api/paths/app-members/appMemberId/role.js +46 -0
- package/api/paths/app-members/appMemberId.d.ts +2 -0
- package/api/paths/app-members/appMemberId.js +24 -0
- package/api/paths/appCollections.d.ts +1 -1
- package/api/paths/appCollections.js +12 -454
- package/api/paths/appTemplates.d.ts +2 -0
- package/api/paths/appTemplates.js +94 -0
- package/api/paths/apps/appId/actions/path.d.ts +2 -0
- package/api/paths/{action.js → apps/appId/actions/path.js} +18 -20
- package/api/paths/apps/appId/assets/assetId.d.ts +2 -0
- package/api/paths/apps/appId/assets/assetId.js +38 -0
- package/api/paths/apps/appId/assets/count.d.ts +2 -0
- package/api/paths/apps/appId/assets/count.js +22 -0
- package/api/paths/apps/appId/assets.d.ts +2 -0
- package/api/paths/apps/appId/assets.js +96 -0
- package/api/paths/apps/appId/auth/email/login.d.ts +2 -0
- package/api/paths/apps/appId/auth/email/login.js +10 -0
- package/api/paths/apps/appId/auth/email/register.d.ts +2 -0
- package/api/paths/apps/appId/auth/email/register.js +52 -0
- package/api/paths/apps/appId/auth/email/requestResetPassword.d.ts +2 -0
- package/api/paths/apps/appId/auth/email/requestResetPassword.js +31 -0
- package/api/paths/apps/appId/auth/email/resendVerification.d.ts +2 -0
- package/api/paths/apps/appId/auth/email/resendVerification.js +32 -0
- package/api/paths/apps/appId/auth/email/resetPassword.d.ts +2 -0
- package/api/paths/apps/appId/auth/email/resetPassword.js +34 -0
- package/api/paths/apps/appId/auth/email/verify.d.ts +2 -0
- package/api/paths/apps/appId/auth/email/verify.js +31 -0
- package/api/paths/apps/appId/broadcast.d.ts +2 -0
- package/api/paths/apps/appId/broadcast.js +36 -0
- package/api/paths/apps/appId/demo-groups.d.ts +2 -0
- package/api/paths/apps/appId/demo-groups.js +29 -0
- package/api/paths/apps/appId/demo-members.d.ts +2 -0
- package/api/paths/apps/appId/demo-members.js +27 -0
- package/api/paths/apps/appId/email.d.ts +2 -0
- package/api/paths/apps/appId/email.js +48 -0
- package/api/paths/apps/appId/export.d.ts +2 -0
- package/api/paths/apps/appId/export.js +41 -0
- package/api/paths/apps/appId/groups.d.ts +2 -0
- package/api/paths/apps/appId/groups.js +79 -0
- package/api/paths/apps/appId/icon.d.ts +2 -0
- package/api/paths/apps/appId/icon.js +31 -0
- package/api/paths/apps/appId/invites.d.ts +2 -0
- package/api/paths/apps/appId/invites.js +79 -0
- package/api/paths/apps/appId/lock.d.ts +2 -0
- package/api/paths/apps/appId/lock.js +35 -0
- package/api/paths/apps/appId/maskableIcon.d.ts +2 -0
- package/api/paths/apps/appId/maskableIcon.js +15 -0
- package/api/paths/apps/appId/members/current/groups.d.ts +2 -0
- package/api/paths/apps/appId/members/current/groups.js +30 -0
- package/api/paths/apps/appId/members/current/link.d.ts +2 -0
- package/api/paths/apps/appId/members/current/link.js +41 -0
- package/api/paths/apps/appId/members/current.d.ts +2 -0
- package/api/paths/apps/appId/members/current.js +111 -0
- package/api/paths/apps/appId/members.d.ts +2 -0
- package/api/paths/apps/appId/members.js +29 -0
- package/api/paths/apps/appId/messages/language.d.ts +2 -0
- package/api/paths/apps/appId/messages/language.js +47 -0
- package/api/paths/apps/appId/messages.d.ts +2 -0
- package/api/paths/apps/appId/messages.js +72 -0
- package/api/paths/apps/appId/quotas/emails.d.ts +2 -0
- package/api/paths/apps/appId/quotas/emails.js +36 -0
- package/api/paths/apps/appId/ratings.d.ts +2 -0
- package/api/paths/apps/appId/ratings.js +58 -0
- package/api/paths/apps/appId/readmes/readmeId.d.ts +2 -0
- package/api/paths/apps/appId/readmes/readmeId.js +17 -0
- package/api/paths/apps/appId/reseed.d.ts +2 -0
- package/api/paths/apps/appId/reseed.js +12 -0
- package/api/paths/apps/appId/resources/resourceType/count.d.ts +2 -0
- package/api/paths/apps/appId/resources/resourceType/count.js +30 -0
- package/api/paths/apps/appId/resources/resourceType/resourceId/subscriptions.d.ts +2 -0
- package/api/paths/apps/appId/resources/resourceType/resourceId/subscriptions.js +31 -0
- package/api/paths/apps/appId/resources/resourceType/resourceId.d.ts +2 -0
- package/api/paths/apps/appId/resources/resourceType/resourceId.js +74 -0
- package/api/paths/apps/appId/resources/resourceType/subscriptions.d.ts +2 -0
- package/api/paths/apps/appId/resources/resourceType/subscriptions.js +26 -0
- package/api/paths/apps/appId/resources/resourceType.d.ts +2 -0
- package/api/paths/apps/appId/resources/resourceType.js +171 -0
- package/api/paths/apps/appId/resources/versions.d.ts +2 -0
- package/api/paths/apps/appId/resources/versions.js +29 -0
- package/api/paths/apps/appId/resources.d.ts +2 -0
- package/api/paths/apps/appId/resources.js +15 -0
- package/api/paths/apps/appId/saml/secretId/acs.d.ts +2 -0
- package/api/paths/apps/appId/saml/secretId/acs.js +35 -0
- package/api/paths/apps/appId/saml/secretId/authn.d.ts +2 -0
- package/api/paths/apps/appId/saml/secretId/authn.js +37 -0
- package/api/paths/apps/appId/saml/secretId/metadata.d.ts +2 -0
- package/api/paths/apps/appId/saml/secretId/metadata.js +21 -0
- package/api/paths/apps/appId/scim/resource-types/resourceTypeId.d.ts +2 -0
- package/api/paths/apps/appId/scim/resource-types/resourceTypeId.js +25 -0
- package/api/paths/apps/appId/scim/resource-types.d.ts +2 -0
- package/api/paths/apps/appId/scim/resource-types.js +22 -0
- package/api/paths/apps/appId/scim/schemas/schemaId.d.ts +2 -0
- package/api/paths/apps/appId/scim/schemas/schemaId.js +24 -0
- package/api/paths/apps/appId/scim/schemas.d.ts +2 -0
- package/api/paths/apps/appId/scim/schemas.js +21 -0
- package/api/paths/apps/appId/scim/service-provider-config.d.ts +2 -0
- package/api/paths/apps/appId/scim/service-provider-config.js +22 -0
- package/api/paths/apps/appId/scim/users/userId.d.ts +2 -0
- package/api/paths/apps/appId/scim/users/userId.js +92 -0
- package/api/paths/apps/appId/scim/users.d.ts +2 -0
- package/api/paths/apps/appId/scim/users.js +58 -0
- package/api/paths/apps/appId/screenshots/screenshotId.d.ts +2 -0
- package/api/paths/apps/appId/screenshots/screenshotId.js +28 -0
- package/api/paths/apps/appId/screenshots.d.ts +2 -0
- package/api/paths/apps/appId/screenshots.js +55 -0
- package/api/paths/apps/appId/secrets/oauth2/secretId/verify.d.ts +2 -0
- package/api/paths/apps/appId/secrets/oauth2/secretId/verify.js +47 -0
- package/api/paths/apps/appId/secrets/oauth2/secretId.d.ts +2 -0
- package/api/paths/apps/appId/secrets/oauth2/secretId.js +60 -0
- package/api/paths/apps/appId/secrets/oauth2.d.ts +2 -0
- package/api/paths/apps/appId/secrets/oauth2.js +54 -0
- package/api/paths/apps/appId/secrets/saml/secretId.d.ts +2 -0
- package/api/paths/apps/appId/secrets/saml/secretId.js +39 -0
- package/api/paths/apps/appId/secrets/saml.d.ts +2 -0
- package/api/paths/apps/appId/secrets/saml.js +54 -0
- package/api/paths/apps/appId/secrets/scim.d.ts +2 -0
- package/api/paths/apps/appId/secrets/scim.js +43 -0
- package/api/paths/apps/appId/secrets/service/secretId.d.ts +2 -0
- package/api/paths/apps/appId/secrets/service/secretId.js +39 -0
- package/api/paths/apps/appId/secrets/service.d.ts +2 -0
- package/api/paths/apps/appId/secrets/service.js +54 -0
- package/api/paths/apps/appId/secrets/ssl.d.ts +2 -0
- package/api/paths/apps/appId/secrets/ssl.js +37 -0
- package/api/paths/apps/appId/snapshots/snapshotId.d.ts +2 -0
- package/api/paths/apps/appId/snapshots/snapshotId.js +47 -0
- package/api/paths/apps/appId/snapshots.d.ts +2 -0
- package/api/paths/apps/appId/snapshots.js +40 -0
- package/api/paths/apps/appId/style/block/organizationId/blockId.d.ts +2 -0
- package/api/paths/apps/appId/style/block/organizationId/blockId.js +53 -0
- package/api/paths/apps/appId/style/core.d.ts +2 -0
- package/api/paths/apps/appId/style/core.js +17 -0
- package/api/paths/apps/appId/style/shared.d.ts +2 -0
- package/api/paths/apps/appId/style/shared.js +17 -0
- package/api/paths/apps/appId/subscriptions.d.ts +2 -0
- package/api/paths/apps/appId/subscriptions.js +91 -0
- package/api/paths/apps/appId/variables/variableId.d.ts +2 -0
- package/api/paths/apps/appId/variables/variableId.js +39 -0
- package/api/paths/apps/appId/variables.d.ts +2 -0
- package/api/paths/apps/appId/variables.js +53 -0
- package/api/paths/apps/appId.d.ts +2 -0
- package/api/paths/apps/appId.js +175 -0
- package/api/paths/apps.d.ts +1 -1
- package/api/paths/apps.js +95 -1518
- package/api/paths/auth/email/login.d.ts +2 -0
- package/api/paths/auth/email/login.js +10 -0
- package/api/paths/auth/email/register.d.ts +2 -0
- package/api/paths/auth/email/register.js +45 -0
- package/api/paths/auth/email/requestResetPassword.d.ts +2 -0
- package/api/paths/auth/email/requestResetPassword.js +30 -0
- package/api/paths/auth/email/resendVerification.d.ts +2 -0
- package/api/paths/auth/email/resendVerification.js +31 -0
- package/api/paths/auth/email/resetPassword.d.ts +2 -0
- package/api/paths/auth/email/resetPassword.js +33 -0
- package/api/paths/auth/email/verify.d.ts +2 -0
- package/api/paths/auth/email/verify.js +30 -0
- package/api/paths/auth/oauth2/authorizations/connect.d.ts +2 -0
- package/api/paths/auth/oauth2/authorizations/connect.js +45 -0
- package/api/paths/auth/oauth2/authorizations/register.d.ts +2 -0
- package/api/paths/auth/oauth2/authorizations/register.js +32 -0
- package/api/paths/auth/refreshToken.d.ts +2 -0
- package/api/paths/auth/refreshToken.js +26 -0
- package/api/paths/blocks/organizationId/blockId/versions/list.d.ts +2 -0
- package/api/paths/blocks/organizationId/blockId/versions/list.js +27 -0
- package/api/paths/blocks/organizationId/blockId/versions/version/asset.d.ts +2 -0
- package/api/paths/blocks/organizationId/blockId/versions/version/asset.js +24 -0
- package/api/paths/blocks/organizationId/blockId/versions/version/icon.d.ts +2 -0
- package/api/paths/blocks/organizationId/blockId/versions/version/icon.js +18 -0
- package/api/paths/blocks/organizationId/blockId/versions/version/messages/language.d.ts +2 -0
- package/api/paths/blocks/organizationId/blockId/versions/version/messages/language.js +37 -0
- package/api/paths/blocks/organizationId/blockId/versions/version.d.ts +2 -0
- package/api/paths/blocks/organizationId/blockId/versions/version.js +29 -0
- package/api/paths/blocks/organizationId/blockId/versions.d.ts +2 -0
- package/api/paths/blocks/organizationId/blockId/versions.js +27 -0
- package/api/paths/blocks/organizationId/blockId.d.ts +2 -0
- package/api/paths/blocks/organizationId/blockId.js +18 -0
- package/api/paths/blocks/versions/blockVersion.js +21 -0
- package/api/paths/blocks.d.ts +1 -1
- package/api/paths/blocks.js +29 -204
- package/api/paths/containerLogs.d.ts +1 -1
- package/api/paths/containerLogs.js +28 -30
- package/api/paths/group-invites/token/respond.d.ts +2 -0
- package/api/paths/group-invites/token/respond.js +42 -0
- package/api/paths/group-invites/token.d.ts +2 -0
- package/api/paths/group-invites/token.js +23 -0
- package/api/paths/group-members/groupMemberId/role.d.ts +2 -0
- package/api/paths/group-members/groupMemberId/role.js +40 -0
- package/api/paths/group-members/groupMemberId.d.ts +2 -0
- package/api/paths/group-members/groupMemberId.js +34 -0
- package/api/paths/groups/groupId/invites.d.ts +2 -0
- package/api/paths/groups/groupId/invites.js +87 -0
- package/api/paths/groups/groupId/members.d.ts +2 -0
- package/api/paths/groups/groupId/members.js +34 -0
- package/api/paths/groups/groupId.d.ts +2 -0
- package/api/paths/groups/groupId.js +86 -0
- package/api/paths/health.d.ts +1 -1
- package/api/paths/health.js +12 -66
- package/api/paths/index.d.ts +145 -136
- package/api/paths/index.js +294 -58
- package/api/paths/messages/language.d.ts +2 -0
- package/api/paths/messages/language.js +21 -0
- package/api/paths/messages.d.ts +2 -0
- package/api/paths/messages.js +26 -0
- package/api/paths/organization-invites/token/respond.d.ts +2 -0
- package/api/paths/organization-invites/token/respond.js +42 -0
- package/api/paths/organization-invites/token.d.ts +2 -0
- package/api/paths/organization-invites/token.js +23 -0
- package/api/paths/organizations/organizationId/appCollections.d.ts +2 -0
- package/api/paths/organizations/organizationId/appCollections.js +76 -0
- package/api/paths/organizations/organizationId/apps/import.d.ts +2 -0
- package/api/paths/organizations/organizationId/apps/import.js +26 -0
- package/api/paths/organizations/organizationId/apps.d.ts +2 -0
- package/api/paths/organizations/organizationId/apps.js +33 -0
- package/api/paths/organizations/organizationId/blocks.d.ts +2 -0
- package/api/paths/organizations/organizationId/blocks.js +25 -0
- package/api/paths/organizations/organizationId/icon.d.ts +2 -0
- package/api/paths/organizations/organizationId/icon.js +14 -0
- package/api/paths/organizations/organizationId/invites/resend.d.ts +2 -0
- package/api/paths/organizations/organizationId/invites/resend.js +32 -0
- package/api/paths/organizations/organizationId/invites.d.ts +2 -0
- package/api/paths/organizations/organizationId/invites.js +108 -0
- package/api/paths/organizations/organizationId/members/memberId/role.d.ts +2 -0
- package/api/paths/organizations/organizationId/members/memberId/role.js +50 -0
- package/api/paths/organizations/organizationId/members/memberId.d.ts +2 -0
- package/api/paths/organizations/organizationId/members/memberId.js +25 -0
- package/api/paths/organizations/organizationId/members.d.ts +2 -0
- package/api/paths/organizations/organizationId/members.js +25 -0
- package/api/paths/organizations/organizationId.d.ts +2 -0
- package/api/paths/organizations/organizationId.js +67 -0
- package/api/paths/organizations.d.ts +1 -1
- package/api/paths/organizations.js +46 -452
- package/api/paths/ssl.d.ts +2 -0
- package/api/paths/ssl.js +31 -0
- package/api/paths/timezones.d.ts +2 -0
- package/api/paths/timezones.js +23 -0
- package/api/paths/trainingBlocks/trainingBlockId.d.ts +2 -0
- package/api/paths/trainingBlocks/trainingBlockId.js +41 -0
- package/api/paths/trainings/trainingId/blocks.d.ts +2 -0
- package/api/paths/trainings/trainingId/blocks.js +51 -0
- package/api/paths/trainings/trainingId/users/current.d.ts +2 -0
- package/api/paths/trainings/trainingId/users/current.js +62 -0
- package/api/paths/trainings/trainingId/users.d.ts +2 -0
- package/api/paths/trainings/trainingId/users.js +25 -0
- package/api/paths/trainings/trainingId.d.ts +2 -0
- package/api/paths/trainings/trainingId.js +85 -0
- package/api/paths/trainings.d.ts +1 -1
- package/api/paths/trainings.js +26 -287
- package/api/paths/users/current/apps/accounts.d.ts +2 -0
- package/api/paths/users/current/apps/accounts.js +24 -0
- package/api/paths/users/current/apps/appId/account.d.ts +2 -0
- package/api/paths/users/current/apps/appId/account.js +65 -0
- package/api/paths/users/current/apps.d.ts +2 -0
- package/api/paths/users/current/apps.js +32 -0
- package/api/paths/users/current/auth/oauth2/apps/appId/consent/agree.d.ts +2 -0
- package/api/paths/users/current/auth/oauth2/apps/appId/consent/agree.js +12 -0
- package/api/paths/users/current/auth/oauth2/apps/appId/consent/verify.d.ts +2 -0
- package/api/paths/users/current/auth/oauth2/apps/appId/consent/verify.js +12 -0
- package/api/paths/users/current/auth/oauth2/authorizations.d.ts +2 -0
- package/api/paths/users/current/auth/oauth2/authorizations.js +43 -0
- package/api/paths/users/current/auth/oauth2/clientCredentials/clientId.d.ts +2 -0
- package/api/paths/users/current/auth/oauth2/clientCredentials/clientId.js +23 -0
- package/api/paths/users/current/auth/oauth2/clientCredentials.d.ts +2 -0
- package/api/paths/users/current/auth/oauth2/clientCredentials.js +53 -0
- package/api/paths/users/current/emails.d.ts +2 -0
- package/api/paths/users/current/emails.js +73 -0
- package/api/paths/users/current/organizations.d.ts +2 -0
- package/api/paths/users/current/organizations.js +29 -0
- package/api/paths/users/current/unsubscribe.d.ts +2 -0
- package/api/paths/users/current/unsubscribe.js +29 -0
- package/api/paths/users/current.d.ts +2 -0
- package/api/paths/users/current.js +43 -0
- package/api/paths/users/subscribed.d.ts +2 -0
- package/api/paths/users/subscribed.js +12 -0
- package/api/tags/index.d.ts +2 -1
- package/api/tags/index.js +170 -8
- package/appMembers.d.ts +1 -0
- package/appMembers.js +9 -0
- package/authorization.d.ts +12 -0
- package/authorization.js +171 -0
- package/constants/index.d.ts +0 -2
- package/constants/index.js +0 -2
- package/constants/scopes.d.ts +1 -1
- package/constants/scopes.js +2 -2
- package/examples.js +13 -14
- package/index.d.ts +2 -2
- package/index.js +2 -2
- package/package.json +2 -2
- package/reference-schemas/remappers/data.js +23 -38
- package/remap.d.ts +3 -7
- package/remap.js +1 -2
- package/remap.test.js +8 -9
- package/validation.js +396 -83
- package/validation.test.js +1039 -230
- package/api/components/parameters/$team.d.ts +0 -2
- package/api/components/parameters/$team.js +0 -8
- package/api/components/parameters/appServiceId.d.ts +0 -2
- package/api/components/parameters/memberEmail.d.ts +0 -2
- package/api/components/parameters/memberEmail.js +0 -8
- package/api/components/schemas/TeamInviteActionDefinition.d.ts +0 -1
- package/api/components/schemas/TeamJoinActionDefinition.d.ts +0 -1
- package/api/components/schemas/TeamJoinActionDefinition.js +0 -14
- package/api/components/schemas/TeamListActionDefinition.d.ts +0 -1
- package/api/components/schemas/TeamListActionDefinition.js +0 -14
- package/api/components/schemas/TeamMembersActionDefinition.d.ts +0 -1
- package/api/components/schemas/TeamsDefinition.d.ts +0 -2
- package/api/components/schemas/TeamsDefinition.js +0 -28
- package/api/components/schemas/UserCreateActionDefinition.d.ts +0 -1
- package/api/components/schemas/UserCreateActionDefinition.js +0 -33
- package/api/components/schemas/UserLoginActionDefinition.d.ts +0 -1
- package/api/components/schemas/UserLoginActionDefinition.js +0 -22
- package/api/components/schemas/UserLogoutActionDefinition.d.ts +0 -1
- package/api/components/schemas/UserPropertyDefinition.d.ts +0 -2
- package/api/components/schemas/UserQueryActionDefinition.d.ts +0 -1
- package/api/components/schemas/UserQueryActionDefinition.js +0 -20
- package/api/components/schemas/UserRegisterActionDefinition.d.ts +0 -1
- package/api/components/schemas/UserRegisterActionDefinition.js +0 -37
- package/api/components/schemas/UserRemoveActionDefinition.d.ts +0 -1
- package/api/components/schemas/UserRemoveActionDefinition.js +0 -20
- package/api/components/schemas/UserUpdateActionDefinition.d.ts +0 -1
- package/api/components/schemas/UserUpdateActionDefinition.js +0 -36
- package/api/components/schemas/UsersDefinition.d.ts +0 -2
- package/api/components/schemas/UsersDefinition.js +0 -17
- package/api/paths/appMessages.d.ts +0 -2
- package/api/paths/appMessages.js +0 -120
- package/api/paths/appOAuth2Secrets.d.ts +0 -2
- package/api/paths/appOAuth2Secrets.js +0 -161
- package/api/paths/appQuotas.d.ts +0 -2
- package/api/paths/appQuotas.js +0 -38
- package/api/paths/appSSLSecrets.d.ts +0 -2
- package/api/paths/appSSLSecrets.js +0 -39
- package/api/paths/appSamlSecrets.d.ts +0 -2
- package/api/paths/appSamlSecrets.js +0 -94
- package/api/paths/appScimEndpoints.d.ts +0 -2
- package/api/paths/appScimEndpoints.js +0 -260
- package/api/paths/appScimSecrets.d.ts +0 -2
- package/api/paths/appScimSecrets.js +0 -45
- package/api/paths/appServiceSecrets.d.ts +0 -2
- package/api/paths/appServiceSecrets.js +0 -94
- package/api/paths/appVariables.d.ts +0 -2
- package/api/paths/appVariables.js +0 -93
- package/api/paths/appsembleMessages.d.ts +0 -2
- package/api/paths/appsembleMessages.js +0 -48
- package/api/paths/assets.d.ts +0 -2
- package/api/paths/assets.js +0 -213
- package/api/paths/emails.d.ts +0 -2
- package/api/paths/emails.js +0 -167
- package/api/paths/invite.d.ts +0 -2
- package/api/paths/invite.js +0 -25
- package/api/paths/oauth2ClientCredentials.d.ts +0 -2
- package/api/paths/oauth2ClientCredentials.js +0 -77
- package/api/paths/oauth2Login.d.ts +0 -2
- package/api/paths/oauth2Login.js +0 -119
- package/api/paths/oauth2Provider.d.ts +0 -2
- package/api/paths/oauth2Provider.js +0 -75
- package/api/paths/resourceHistory.d.ts +0 -2
- package/api/paths/resourceHistory.js +0 -31
- package/api/paths/resources.d.ts +0 -2
- package/api/paths/resources.js +0 -395
- package/api/paths/saml.d.ts +0 -2
- package/api/paths/saml.js +0 -126
- package/api/paths/templates.d.ts +0 -2
- package/api/paths/templates.js +0 -96
- package/api/paths/user.d.ts +0 -2
- package/api/paths/user.js +0 -649
- package/api/tags/app.d.ts +0 -2
- package/api/tags/app.js +0 -5
- package/api/tags/appMember.d.ts +0 -2
- package/api/tags/appMember.js +0 -5
- package/api/tags/asset.d.ts +0 -2
- package/api/tags/asset.js +0 -5
- package/api/tags/auth.d.ts +0 -2
- package/api/tags/auth.js +0 -5
- package/api/tags/language.d.ts +0 -2
- package/api/tags/language.js +0 -5
- package/api/tags/organization.d.ts +0 -2
- package/api/tags/organization.js +0 -5
- package/api/tags/resource.d.ts +0 -2
- package/api/tags/resource.js +0 -5
- package/api/tags/template.d.ts +0 -2
- package/api/tags/template.js +0 -5
- package/api/tags/user.d.ts +0 -2
- package/api/tags/user.js +0 -5
- package/appSecurity.d.ts +0 -9
- package/appSecurity.js +0 -41
- package/appSecurity.test.d.ts +0 -1
- package/appSecurity.test.js +0 -114
- package/checkAppRole.d.ts +0 -11
- package/checkAppRole.js +0 -34
- package/constants/Permission.d.ts +0 -114
- package/constants/Permission.js +0 -116
- package/constants/roles.d.ts +0 -16
- package/constants/roles.js +0 -58
- /package/api/paths/{action.d.ts → blocks/versions/blockVersion.d.ts} +0 -0
package/validation.test.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { predefinedAppRoles, } from '@appsemble/types';
|
|
1
2
|
import { ValidationError } from 'jsonschema';
|
|
2
3
|
import { describe, expect, it } from 'vitest';
|
|
3
4
|
import { validateAppDefinition } from './validation.js';
|
|
@@ -885,15 +886,6 @@ describe('validateAppDefinition', () => {
|
|
|
885
886
|
]),
|
|
886
887
|
]);
|
|
887
888
|
});
|
|
888
|
-
it('should validate the top level default roles exist', async () => {
|
|
889
|
-
const app = createTestApp();
|
|
890
|
-
app.roles = ['Unknown'];
|
|
891
|
-
const result = await validateAppDefinition(app, () => []);
|
|
892
|
-
expect(result.valid).toBe(false);
|
|
893
|
-
expect(result.errors).toStrictEqual([
|
|
894
|
-
new ValidationError('does not exist in this app’s roles', 'Unknown', undefined, ['roles', 0]),
|
|
895
|
-
]);
|
|
896
|
-
});
|
|
897
889
|
it('should validate resource types against reserved keywords', async () => {
|
|
898
890
|
const app = {
|
|
899
891
|
name: 'Test app',
|
|
@@ -984,92 +976,23 @@ describe('validateAppDefinition', () => {
|
|
|
984
976
|
new ValidationError('is a reserved keyword', { type: 'object', properties: { name: { type: 'string' } } }, undefined, ['resources', 'expires']),
|
|
985
977
|
]);
|
|
986
978
|
});
|
|
987
|
-
it('should validate
|
|
988
|
-
const app = createTestApp();
|
|
989
|
-
app.resources.person.roles = ['Unknown'];
|
|
990
|
-
const result = await validateAppDefinition(app, () => []);
|
|
991
|
-
expect(result.valid).toBe(false);
|
|
992
|
-
expect(result.errors).toStrictEqual([
|
|
993
|
-
new ValidationError('does not exist in this app’s roles', 'Unknown', undefined, [
|
|
994
|
-
'resources',
|
|
995
|
-
'person',
|
|
996
|
-
'roles',
|
|
997
|
-
0,
|
|
998
|
-
]),
|
|
999
|
-
]);
|
|
1000
|
-
});
|
|
1001
|
-
it('should validate the resource action roles', async () => {
|
|
1002
|
-
const app = createTestApp();
|
|
1003
|
-
app.resources.person.count = { roles: ['Unknown'] };
|
|
1004
|
-
app.resources.person.create = { roles: ['Unknown'] };
|
|
1005
|
-
app.resources.person.delete = { roles: ['Unknown'] };
|
|
1006
|
-
app.resources.person.get = { roles: ['Unknown'] };
|
|
1007
|
-
app.resources.person.query = { roles: ['Unknown'] };
|
|
1008
|
-
app.resources.person.update = { roles: ['Unknown'] };
|
|
1009
|
-
const result = await validateAppDefinition(app, () => []);
|
|
1010
|
-
expect(result.valid).toBe(false);
|
|
1011
|
-
expect(result.errors).toStrictEqual([
|
|
1012
|
-
new ValidationError('does not exist in this app’s roles', 'Unknown', undefined, [
|
|
1013
|
-
'resources',
|
|
1014
|
-
'person',
|
|
1015
|
-
'count',
|
|
1016
|
-
'roles',
|
|
1017
|
-
0,
|
|
1018
|
-
]),
|
|
1019
|
-
new ValidationError('does not exist in this app’s roles', 'Unknown', undefined, [
|
|
1020
|
-
'resources',
|
|
1021
|
-
'person',
|
|
1022
|
-
'create',
|
|
1023
|
-
'roles',
|
|
1024
|
-
0,
|
|
1025
|
-
]),
|
|
1026
|
-
new ValidationError('does not exist in this app’s roles', 'Unknown', undefined, [
|
|
1027
|
-
'resources',
|
|
1028
|
-
'person',
|
|
1029
|
-
'delete',
|
|
1030
|
-
'roles',
|
|
1031
|
-
0,
|
|
1032
|
-
]),
|
|
1033
|
-
new ValidationError('does not exist in this app’s roles', 'Unknown', undefined, [
|
|
1034
|
-
'resources',
|
|
1035
|
-
'person',
|
|
1036
|
-
'get',
|
|
1037
|
-
'roles',
|
|
1038
|
-
0,
|
|
1039
|
-
]),
|
|
1040
|
-
new ValidationError('does not exist in this app’s roles', 'Unknown', undefined, [
|
|
1041
|
-
'resources',
|
|
1042
|
-
'person',
|
|
1043
|
-
'query',
|
|
1044
|
-
'roles',
|
|
1045
|
-
0,
|
|
1046
|
-
]),
|
|
1047
|
-
new ValidationError('does not exist in this app’s roles', 'Unknown', undefined, [
|
|
1048
|
-
'resources',
|
|
1049
|
-
'person',
|
|
1050
|
-
'update',
|
|
1051
|
-
'roles',
|
|
1052
|
-
0,
|
|
1053
|
-
]),
|
|
1054
|
-
]);
|
|
1055
|
-
});
|
|
1056
|
-
it('should validate user properties for type or enum', async () => {
|
|
1057
|
-
const app = { ...createTestApp(), users: { properties: { foo: { schema: {} } } } };
|
|
979
|
+
it('should validate app member properties for type or enum', async () => {
|
|
980
|
+
const app = { ...createTestApp(), members: { properties: { foo: { schema: {} } } } };
|
|
1058
981
|
const result = await validateAppDefinition(app, () => []);
|
|
1059
982
|
expect(result.valid).toBe(false);
|
|
1060
983
|
expect(result.errors).toStrictEqual([
|
|
1061
984
|
new ValidationError('must define type or enum', {}, undefined, [
|
|
1062
|
-
'
|
|
985
|
+
'members',
|
|
1063
986
|
'properties',
|
|
1064
987
|
'foo',
|
|
1065
988
|
'schema',
|
|
1066
989
|
]),
|
|
1067
990
|
]);
|
|
1068
991
|
});
|
|
1069
|
-
it('should validate
|
|
992
|
+
it('should validate app member properties for resource references', async () => {
|
|
1070
993
|
const app = {
|
|
1071
994
|
...createTestApp(),
|
|
1072
|
-
|
|
995
|
+
members: {
|
|
1073
996
|
properties: {
|
|
1074
997
|
foo: {
|
|
1075
998
|
schema: { type: 'integer' },
|
|
@@ -1084,7 +1007,7 @@ describe('validateAppDefinition', () => {
|
|
|
1084
1007
|
expect(result.valid).toBe(false);
|
|
1085
1008
|
expect(result.errors).toStrictEqual([
|
|
1086
1009
|
new ValidationError('refers to a resource that doesn’t exist', 'tasks', undefined, [
|
|
1087
|
-
'
|
|
1010
|
+
'members',
|
|
1088
1011
|
'properties',
|
|
1089
1012
|
'foo',
|
|
1090
1013
|
'reference',
|
|
@@ -1269,27 +1192,6 @@ describe('validateAppDefinition', () => {
|
|
|
1269
1192
|
]),
|
|
1270
1193
|
]);
|
|
1271
1194
|
});
|
|
1272
|
-
it('should allow the $author role for resource actions', async () => {
|
|
1273
|
-
const app = createTestApp();
|
|
1274
|
-
app.resources.person.roles = ['$author'];
|
|
1275
|
-
app.resources.person.count = { roles: ['$author'] };
|
|
1276
|
-
app.resources.person.create = { roles: ['$author'] };
|
|
1277
|
-
app.resources.person.delete = { roles: ['$author'] };
|
|
1278
|
-
app.resources.person.get = { roles: ['$author'] };
|
|
1279
|
-
app.resources.person.query = { roles: ['$author'] };
|
|
1280
|
-
app.resources.person.update = { roles: ['$author'] };
|
|
1281
|
-
const result = await validateAppDefinition(app, () => []);
|
|
1282
|
-
expect(result.valid).toBe(false);
|
|
1283
|
-
expect(result.errors).toStrictEqual([
|
|
1284
|
-
new ValidationError('does not exist in this app’s roles', '$author', undefined, [
|
|
1285
|
-
'resources',
|
|
1286
|
-
'person',
|
|
1287
|
-
'create',
|
|
1288
|
-
'roles',
|
|
1289
|
-
0,
|
|
1290
|
-
]),
|
|
1291
|
-
]);
|
|
1292
|
-
});
|
|
1293
1195
|
it('should validate page roles', async () => {
|
|
1294
1196
|
const app = createTestApp();
|
|
1295
1197
|
app.pages[0].roles = ['Unknown'];
|
|
@@ -1351,17 +1253,17 @@ describe('validateAppDefinition', () => {
|
|
|
1351
1253
|
const result = await validateAppDefinition(app, () => []);
|
|
1352
1254
|
expect(result.valid).toBe(false);
|
|
1353
1255
|
expect(result.errors).toStrictEqual([
|
|
1354
|
-
new ValidationError('
|
|
1256
|
+
new ValidationError('cyclically inherits itself', { inherits: ['B'] }, undefined, [
|
|
1355
1257
|
'security',
|
|
1356
1258
|
'roles',
|
|
1357
1259
|
'A',
|
|
1358
1260
|
]),
|
|
1359
|
-
new ValidationError('
|
|
1261
|
+
new ValidationError('cyclically inherits itself', { inherits: ['C'] }, undefined, [
|
|
1360
1262
|
'security',
|
|
1361
1263
|
'roles',
|
|
1362
1264
|
'B',
|
|
1363
1265
|
]),
|
|
1364
|
-
new ValidationError('
|
|
1266
|
+
new ValidationError('cyclically inherits itself', { inherits: ['E', 'A'] }, undefined, [
|
|
1365
1267
|
'security',
|
|
1366
1268
|
'roles',
|
|
1367
1269
|
'C',
|
|
@@ -1665,14 +1567,14 @@ describe('validateAppDefinition', () => {
|
|
|
1665
1567
|
expect(result.valid).toBe(true);
|
|
1666
1568
|
expect(result.errors).toStrictEqual([]);
|
|
1667
1569
|
});
|
|
1668
|
-
it('should report an error if
|
|
1570
|
+
it('should report an error if app member actions are used without a security definition', async () => {
|
|
1669
1571
|
const { security, ...app } = createTestApp();
|
|
1670
1572
|
app.pages[0].blocks.push({
|
|
1671
1573
|
type: 'test',
|
|
1672
1574
|
version: '1.2.3',
|
|
1673
1575
|
actions: {
|
|
1674
1576
|
onWhatever: {
|
|
1675
|
-
type: '
|
|
1577
|
+
type: 'app.member.login',
|
|
1676
1578
|
email: 'example@example.com',
|
|
1677
1579
|
password: 'password',
|
|
1678
1580
|
},
|
|
@@ -1683,10 +1585,10 @@ describe('validateAppDefinition', () => {
|
|
|
1683
1585
|
version: '1.2.3',
|
|
1684
1586
|
actions: {
|
|
1685
1587
|
onWhatever: {
|
|
1686
|
-
type: '
|
|
1588
|
+
type: 'app.member.register',
|
|
1687
1589
|
email: 'example@example.com',
|
|
1688
1590
|
password: 'password',
|
|
1689
|
-
|
|
1591
|
+
name: 'Test User',
|
|
1690
1592
|
},
|
|
1691
1593
|
},
|
|
1692
1594
|
});
|
|
@@ -1695,9 +1597,7 @@ describe('validateAppDefinition', () => {
|
|
|
1695
1597
|
version: '1.2.3',
|
|
1696
1598
|
actions: {
|
|
1697
1599
|
onWhatever: {
|
|
1698
|
-
type: '
|
|
1699
|
-
currentEmail: 'example@example.com',
|
|
1700
|
-
password: 'password',
|
|
1600
|
+
type: 'app.member.current.patch',
|
|
1701
1601
|
},
|
|
1702
1602
|
},
|
|
1703
1603
|
});
|
|
@@ -1714,9 +1614,9 @@ describe('validateAppDefinition', () => {
|
|
|
1714
1614
|
]);
|
|
1715
1615
|
expect(result.valid).toBe(false);
|
|
1716
1616
|
expect(result.errors).toStrictEqual([
|
|
1717
|
-
new ValidationError('refers to
|
|
1718
|
-
new ValidationError('refers to
|
|
1719
|
-
new ValidationError('refers to
|
|
1617
|
+
new ValidationError('refers to an app member action but the app doesn’t have a security definition', 'app.member.login', undefined, ['pages', 0, 'blocks', 0, 'actions', 'onWhatever', 'type']),
|
|
1618
|
+
new ValidationError('refers to an app member action but the app doesn’t have a security definition', 'app.member.register', undefined, ['pages', 0, 'blocks', 1, 'actions', 'onWhatever', 'type']),
|
|
1619
|
+
new ValidationError('refers to an app member action but the app doesn’t have a security definition', 'app.member.current.patch', undefined, ['pages', 0, 'blocks', 2, 'actions', 'onWhatever', 'type']),
|
|
1720
1620
|
]);
|
|
1721
1621
|
});
|
|
1722
1622
|
it('should report an error if flow actions are used on a non-flow page', async () => {
|
|
@@ -1905,53 +1805,7 @@ describe('validateAppDefinition', () => {
|
|
|
1905
1805
|
it('should report an error if a user register action on a block adds unsupported user properties', async () => {
|
|
1906
1806
|
const app = {
|
|
1907
1807
|
...createTestApp(),
|
|
1908
|
-
|
|
1909
|
-
properties: {
|
|
1910
|
-
foo: {
|
|
1911
|
-
schema: {
|
|
1912
|
-
type: 'string',
|
|
1913
|
-
},
|
|
1914
|
-
},
|
|
1915
|
-
},
|
|
1916
|
-
},
|
|
1917
|
-
};
|
|
1918
|
-
app.pages[0].blocks.push({
|
|
1919
|
-
type: 'test',
|
|
1920
|
-
version: '1.2.3',
|
|
1921
|
-
actions: {
|
|
1922
|
-
onWhatever: {
|
|
1923
|
-
type: 'user.register',
|
|
1924
|
-
displayName: 'name',
|
|
1925
|
-
email: 'email@example.com',
|
|
1926
|
-
password: 'password',
|
|
1927
|
-
properties: {
|
|
1928
|
-
'object.from': {
|
|
1929
|
-
bar: 'baz',
|
|
1930
|
-
},
|
|
1931
|
-
},
|
|
1932
|
-
},
|
|
1933
|
-
},
|
|
1934
|
-
});
|
|
1935
|
-
const result = await validateAppDefinition(app, () => [
|
|
1936
|
-
{
|
|
1937
|
-
name: '@appsemble/test',
|
|
1938
|
-
version: '1.2.3',
|
|
1939
|
-
files: [],
|
|
1940
|
-
languages: [],
|
|
1941
|
-
actions: {
|
|
1942
|
-
onWhatever: {},
|
|
1943
|
-
},
|
|
1944
|
-
},
|
|
1945
|
-
]);
|
|
1946
|
-
expect(result.valid).toBe(false);
|
|
1947
|
-
expect(result.errors).toStrictEqual([
|
|
1948
|
-
new ValidationError('contains a property that doesn’t exist in users.properties', 'user.register', undefined, ['pages', 0, 'blocks', 0, 'actions', 'onWhatever', 'properties']),
|
|
1949
|
-
]);
|
|
1950
|
-
});
|
|
1951
|
-
it('should report an error if a user create action on a block adds unsupported user properties', async () => {
|
|
1952
|
-
const app = {
|
|
1953
|
-
...createTestApp(),
|
|
1954
|
-
users: {
|
|
1808
|
+
members: {
|
|
1955
1809
|
properties: {
|
|
1956
1810
|
foo: {
|
|
1957
1811
|
schema: {
|
|
@@ -1966,11 +1820,10 @@ describe('validateAppDefinition', () => {
|
|
|
1966
1820
|
version: '1.2.3',
|
|
1967
1821
|
actions: {
|
|
1968
1822
|
onWhatever: {
|
|
1969
|
-
type: '
|
|
1823
|
+
type: 'app.member.register',
|
|
1970
1824
|
name: 'name',
|
|
1971
1825
|
email: 'email@example.com',
|
|
1972
1826
|
password: 'password',
|
|
1973
|
-
role: 'role',
|
|
1974
1827
|
properties: {
|
|
1975
1828
|
'object.from': {
|
|
1976
1829
|
bar: 'baz',
|
|
@@ -1992,13 +1845,13 @@ describe('validateAppDefinition', () => {
|
|
|
1992
1845
|
]);
|
|
1993
1846
|
expect(result.valid).toBe(false);
|
|
1994
1847
|
expect(result.errors).toStrictEqual([
|
|
1995
|
-
new ValidationError('contains a property that doesn’t exist in
|
|
1848
|
+
new ValidationError('contains a property that doesn’t exist in app member properties', 'app.member.register', undefined, ['pages', 0, 'blocks', 0, 'actions', 'onWhatever', 'properties']),
|
|
1996
1849
|
]);
|
|
1997
1850
|
});
|
|
1998
|
-
it('should report an error if a
|
|
1851
|
+
it('should report an error if a app member update action on a block adds unsupported app member properties', async () => {
|
|
1999
1852
|
const app = {
|
|
2000
1853
|
...createTestApp(),
|
|
2001
|
-
|
|
1854
|
+
members: {
|
|
2002
1855
|
properties: {
|
|
2003
1856
|
foo: {
|
|
2004
1857
|
schema: {
|
|
@@ -2013,12 +1866,8 @@ describe('validateAppDefinition', () => {
|
|
|
2013
1866
|
version: '1.2.3',
|
|
2014
1867
|
actions: {
|
|
2015
1868
|
onWhatever: {
|
|
2016
|
-
type: '
|
|
1869
|
+
type: 'app.member.current.patch',
|
|
2017
1870
|
name: 'name',
|
|
2018
|
-
currentEmail: 'email@example.com',
|
|
2019
|
-
newEmail: 'new-email@example.com',
|
|
2020
|
-
password: 'password',
|
|
2021
|
-
role: 'role',
|
|
2022
1871
|
properties: {
|
|
2023
1872
|
'object.from': {
|
|
2024
1873
|
bar: 'baz',
|
|
@@ -2040,7 +1889,7 @@ describe('validateAppDefinition', () => {
|
|
|
2040
1889
|
]);
|
|
2041
1890
|
expect(result.valid).toBe(false);
|
|
2042
1891
|
expect(result.errors).toStrictEqual([
|
|
2043
|
-
new ValidationError('contains a property that doesn’t exist in
|
|
1892
|
+
new ValidationError('contains a property that doesn’t exist in app member properties', 'app.member.current.patch', undefined, ['pages', 0, 'blocks', 0, 'actions', 'onWhatever', 'properties']),
|
|
2044
1893
|
]);
|
|
2045
1894
|
});
|
|
2046
1895
|
it('should report an error if a resource action on a block refers to a non-existent resource', async () => {
|
|
@@ -2104,7 +1953,7 @@ describe('validateAppDefinition', () => {
|
|
|
2104
1953
|
]),
|
|
2105
1954
|
]);
|
|
2106
1955
|
});
|
|
2107
|
-
it('should report an error if a resource action on a block
|
|
1956
|
+
it('should report an error if a resource action on a block is accessible by no roles in the app', async () => {
|
|
2108
1957
|
const app = createTestApp();
|
|
2109
1958
|
app.pages[0].blocks.push({
|
|
2110
1959
|
type: 'test',
|
|
@@ -2129,10 +1978,10 @@ describe('validateAppDefinition', () => {
|
|
|
2129
1978
|
]);
|
|
2130
1979
|
expect(result.valid).toBe(false);
|
|
2131
1980
|
expect(result.errors).toStrictEqual([
|
|
2132
|
-
new ValidationError('
|
|
1981
|
+
new ValidationError('there is no-one in the app, who has permissions to use this action', 'resource.get', undefined, ['pages', 0, 'blocks', 0, 'actions', 'onWhatever', 'resource']),
|
|
2133
1982
|
]);
|
|
2134
1983
|
});
|
|
2135
|
-
it('should report an error if a resource action on the controller
|
|
1984
|
+
it('should report an error if a resource action on the controller is accessible by no roles in the app', async () => {
|
|
2136
1985
|
const app = createTestApp();
|
|
2137
1986
|
app.controller = {
|
|
2138
1987
|
actions: {
|
|
@@ -2149,57 +1998,7 @@ describe('validateAppDefinition', () => {
|
|
|
2149
1998
|
});
|
|
2150
1999
|
expect(result.valid).toBe(false);
|
|
2151
2000
|
expect(result.errors).toStrictEqual([
|
|
2152
|
-
new ValidationError('
|
|
2153
|
-
]);
|
|
2154
|
-
});
|
|
2155
|
-
it('should report an error if a resource action on a block refers is private action without a security definition', async () => {
|
|
2156
|
-
const { security, ...app } = createTestApp();
|
|
2157
|
-
app.resources.person.roles = [];
|
|
2158
|
-
app.pages[0].blocks.push({
|
|
2159
|
-
type: 'test',
|
|
2160
|
-
version: '1.2.3',
|
|
2161
|
-
actions: {
|
|
2162
|
-
onWhatever: {
|
|
2163
|
-
type: 'resource.get',
|
|
2164
|
-
resource: 'person',
|
|
2165
|
-
},
|
|
2166
|
-
},
|
|
2167
|
-
});
|
|
2168
|
-
const result = await validateAppDefinition(app, () => [
|
|
2169
|
-
{
|
|
2170
|
-
name: '@appsemble/test',
|
|
2171
|
-
version: '1.2.3',
|
|
2172
|
-
files: [],
|
|
2173
|
-
languages: [],
|
|
2174
|
-
actions: {
|
|
2175
|
-
onWhatever: {},
|
|
2176
|
-
},
|
|
2177
|
-
},
|
|
2178
|
-
]);
|
|
2179
|
-
expect(result.valid).toBe(false);
|
|
2180
|
-
expect(result.errors).toStrictEqual([
|
|
2181
|
-
new ValidationError('refers to a resource action that is accessible when logged in, but the app has no security definitions', 'resource.get', undefined, ['pages', 0, 'blocks', 0, 'actions', 'onWhatever', 'resource']),
|
|
2182
|
-
]);
|
|
2183
|
-
});
|
|
2184
|
-
it('should report an error if a resource action on the controller refers is private action without a security definition', async () => {
|
|
2185
|
-
const { security, ...app } = createTestApp();
|
|
2186
|
-
app.resources.person.roles = [];
|
|
2187
|
-
app.controller = {
|
|
2188
|
-
actions: {
|
|
2189
|
-
onWhatever: {
|
|
2190
|
-
type: 'resource.get',
|
|
2191
|
-
resource: 'person',
|
|
2192
|
-
},
|
|
2193
|
-
},
|
|
2194
|
-
};
|
|
2195
|
-
const result = await validateAppDefinition(app, () => [], {
|
|
2196
|
-
actions: {
|
|
2197
|
-
onWhatever: {},
|
|
2198
|
-
},
|
|
2199
|
-
});
|
|
2200
|
-
expect(result.valid).toBe(false);
|
|
2201
|
-
expect(result.errors).toStrictEqual([
|
|
2202
|
-
new ValidationError('refers to a resource action that is accessible when logged in, but the app has no security definitions', 'resource.get', undefined, ['controller', 'actions', 'onWhatever', 'resource']),
|
|
2001
|
+
new ValidationError('there is no-one in the app, who has permissions to use this action', 'resource.get', undefined, ['controller', 'actions', 'onWhatever', 'resource']),
|
|
2203
2002
|
]);
|
|
2204
2003
|
});
|
|
2205
2004
|
it('should ignore if an app is null', async () => {
|
|
@@ -2302,5 +2101,1015 @@ describe('validateAppDefinition', () => {
|
|
|
2302
2101
|
}, undefined, ['pages', 0, 'blocks', 0, 'actions', 'onClick', 'type']),
|
|
2303
2102
|
]);
|
|
2304
2103
|
});
|
|
2104
|
+
it('should validate security definition', async () => {
|
|
2105
|
+
const { security, ...app } = createTestApp();
|
|
2106
|
+
app.security = {};
|
|
2107
|
+
const result = await validateAppDefinition(app, () => []);
|
|
2108
|
+
expect(result.valid).toBe(false);
|
|
2109
|
+
expect(result.errors).toStrictEqual([
|
|
2110
|
+
new ValidationError('invalid security definition. Must define either guest or roles and default', app, undefined, ['security']),
|
|
2111
|
+
]);
|
|
2112
|
+
});
|
|
2113
|
+
it('should report an error on duplicate guest permissions', async () => {
|
|
2114
|
+
const app = createTestApp();
|
|
2115
|
+
app.security = {
|
|
2116
|
+
guest: {
|
|
2117
|
+
permissions: ['$group:query', '$group:query'],
|
|
2118
|
+
},
|
|
2119
|
+
};
|
|
2120
|
+
const result = await validateAppDefinition(app, () => []);
|
|
2121
|
+
expect(result.valid).toBe(false);
|
|
2122
|
+
expect(result.errors).toStrictEqual([
|
|
2123
|
+
new ValidationError('duplicate permission declaration', app, undefined, [
|
|
2124
|
+
'security',
|
|
2125
|
+
'guest',
|
|
2126
|
+
'permissions',
|
|
2127
|
+
1,
|
|
2128
|
+
]),
|
|
2129
|
+
]);
|
|
2130
|
+
});
|
|
2131
|
+
it('should report an error when a guest resource permission references a non existing resource', async () => {
|
|
2132
|
+
const app = createTestApp();
|
|
2133
|
+
app.security = {
|
|
2134
|
+
guest: {
|
|
2135
|
+
permissions: ['$resource:unknown:query'],
|
|
2136
|
+
},
|
|
2137
|
+
};
|
|
2138
|
+
const result = await validateAppDefinition(app, () => []);
|
|
2139
|
+
expect(result.valid).toBe(false);
|
|
2140
|
+
expect(result.errors).toStrictEqual([
|
|
2141
|
+
new ValidationError("resource unknown does not exist in the app's resources definition", app, undefined, ['security', 'guest', 'permissions', 0]),
|
|
2142
|
+
]);
|
|
2143
|
+
});
|
|
2144
|
+
it('should report an error when a guest resource permission for a specific resource is declared and there is already a resource permission with scope all declared', async () => {
|
|
2145
|
+
const app = createTestApp();
|
|
2146
|
+
app.security = {
|
|
2147
|
+
guest: {
|
|
2148
|
+
permissions: ['$resource:person:query', '$resource:all:query'],
|
|
2149
|
+
},
|
|
2150
|
+
};
|
|
2151
|
+
const result = await validateAppDefinition(app, () => []);
|
|
2152
|
+
expect(result.valid).toBe(false);
|
|
2153
|
+
expect(result.errors).toStrictEqual([
|
|
2154
|
+
new ValidationError('redundant permission. A permission for the query resource action with scope all is already declared', app, undefined, ['security', 'guest', 'permissions', 0]),
|
|
2155
|
+
]);
|
|
2156
|
+
});
|
|
2157
|
+
it('should report an error when a guest resource view permission with scope all is declared and there is a resource that does not define the view', async () => {
|
|
2158
|
+
const app = createTestApp();
|
|
2159
|
+
app.security = {
|
|
2160
|
+
guest: {
|
|
2161
|
+
permissions: ['$resource:all:query:public'],
|
|
2162
|
+
},
|
|
2163
|
+
};
|
|
2164
|
+
app.resources = {
|
|
2165
|
+
person: {
|
|
2166
|
+
schema: {
|
|
2167
|
+
type: 'object',
|
|
2168
|
+
properties: {
|
|
2169
|
+
name: { type: 'string' },
|
|
2170
|
+
},
|
|
2171
|
+
},
|
|
2172
|
+
views: {
|
|
2173
|
+
public: {
|
|
2174
|
+
remap: 'log.info',
|
|
2175
|
+
},
|
|
2176
|
+
},
|
|
2177
|
+
},
|
|
2178
|
+
note: {
|
|
2179
|
+
schema: {
|
|
2180
|
+
type: 'object',
|
|
2181
|
+
properties: {
|
|
2182
|
+
name: { type: 'string' },
|
|
2183
|
+
},
|
|
2184
|
+
},
|
|
2185
|
+
},
|
|
2186
|
+
};
|
|
2187
|
+
const result = await validateAppDefinition(app, () => []);
|
|
2188
|
+
expect(result.valid).toBe(false);
|
|
2189
|
+
expect(result.errors).toStrictEqual([
|
|
2190
|
+
new ValidationError('resource note is missing a definition for the public view', app, undefined, ['security', 'guest', 'permissions', 0]),
|
|
2191
|
+
]);
|
|
2192
|
+
});
|
|
2193
|
+
it('should report an error when a guest resource view permission is declared for a resource that does not define the view', async () => {
|
|
2194
|
+
const app = createTestApp();
|
|
2195
|
+
app.security = {
|
|
2196
|
+
guest: {
|
|
2197
|
+
permissions: ['$resource:person:query:public'],
|
|
2198
|
+
},
|
|
2199
|
+
};
|
|
2200
|
+
app.resources = {
|
|
2201
|
+
person: {
|
|
2202
|
+
schema: {
|
|
2203
|
+
type: 'object',
|
|
2204
|
+
properties: {
|
|
2205
|
+
name: { type: 'string' },
|
|
2206
|
+
},
|
|
2207
|
+
},
|
|
2208
|
+
},
|
|
2209
|
+
};
|
|
2210
|
+
const result = await validateAppDefinition(app, () => []);
|
|
2211
|
+
expect(result.valid).toBe(false);
|
|
2212
|
+
expect(result.errors).toStrictEqual([
|
|
2213
|
+
new ValidationError('resource person is missing a definition for the public view', app, undefined, ['security', 'guest', 'permissions', 0]),
|
|
2214
|
+
]);
|
|
2215
|
+
});
|
|
2216
|
+
it('should report an error when a guest resource view permission redeclares a view permission for an already declared resource action view permission', async () => {
|
|
2217
|
+
const app = createTestApp();
|
|
2218
|
+
app.security = {
|
|
2219
|
+
guest: {
|
|
2220
|
+
permissions: ['$resource:person:query:public', '$resource:person:query:private'],
|
|
2221
|
+
},
|
|
2222
|
+
};
|
|
2223
|
+
app.resources = {
|
|
2224
|
+
person: {
|
|
2225
|
+
schema: {
|
|
2226
|
+
type: 'object',
|
|
2227
|
+
properties: {
|
|
2228
|
+
name: { type: 'string' },
|
|
2229
|
+
},
|
|
2230
|
+
},
|
|
2231
|
+
views: {
|
|
2232
|
+
public: {
|
|
2233
|
+
remap: 'log.info',
|
|
2234
|
+
},
|
|
2235
|
+
private: {
|
|
2236
|
+
remap: 'log.info',
|
|
2237
|
+
},
|
|
2238
|
+
},
|
|
2239
|
+
},
|
|
2240
|
+
};
|
|
2241
|
+
const result = await validateAppDefinition(app, () => []);
|
|
2242
|
+
expect(result.valid).toBe(false);
|
|
2243
|
+
expect(result.errors).toStrictEqual([
|
|
2244
|
+
new ValidationError('a view permission for the query action on resource person is already declared', app, undefined, ['security', 'guest', 'permissions', 0]),
|
|
2245
|
+
]);
|
|
2246
|
+
});
|
|
2247
|
+
it('should report an error when a guest resource view permission redeclares a view permission for an already declared resource action view permission with scope all', async () => {
|
|
2248
|
+
const app = createTestApp();
|
|
2249
|
+
app.security = {
|
|
2250
|
+
guest: {
|
|
2251
|
+
permissions: ['$resource:person:query:public', '$resource:all:query:private'],
|
|
2252
|
+
},
|
|
2253
|
+
};
|
|
2254
|
+
app.resources = {
|
|
2255
|
+
person: {
|
|
2256
|
+
schema: {
|
|
2257
|
+
type: 'object',
|
|
2258
|
+
properties: {
|
|
2259
|
+
name: { type: 'string' },
|
|
2260
|
+
},
|
|
2261
|
+
},
|
|
2262
|
+
views: {
|
|
2263
|
+
public: {
|
|
2264
|
+
remap: 'log.info',
|
|
2265
|
+
},
|
|
2266
|
+
private: {
|
|
2267
|
+
remap: 'log.info',
|
|
2268
|
+
},
|
|
2269
|
+
},
|
|
2270
|
+
},
|
|
2271
|
+
};
|
|
2272
|
+
const result = await validateAppDefinition(app, () => []);
|
|
2273
|
+
expect(result.valid).toBe(false);
|
|
2274
|
+
expect(result.errors).toStrictEqual([
|
|
2275
|
+
new ValidationError('a view permission for the query action with scope all is already declared', app, undefined, ['security', 'guest', 'permissions', 0]),
|
|
2276
|
+
]);
|
|
2277
|
+
});
|
|
2278
|
+
it('should report an error when a guest resource view permission is declared for a specific view and there is already a permission for the same resource action without a specific view', async () => {
|
|
2279
|
+
const app = createTestApp();
|
|
2280
|
+
app.security = {
|
|
2281
|
+
guest: {
|
|
2282
|
+
permissions: ['$resource:person:query:public', '$resource:person:query'],
|
|
2283
|
+
},
|
|
2284
|
+
};
|
|
2285
|
+
app.resources = {
|
|
2286
|
+
person: {
|
|
2287
|
+
schema: {
|
|
2288
|
+
type: 'object',
|
|
2289
|
+
properties: {
|
|
2290
|
+
name: { type: 'string' },
|
|
2291
|
+
},
|
|
2292
|
+
},
|
|
2293
|
+
views: {
|
|
2294
|
+
public: {
|
|
2295
|
+
remap: 'log.info',
|
|
2296
|
+
},
|
|
2297
|
+
},
|
|
2298
|
+
},
|
|
2299
|
+
};
|
|
2300
|
+
const result = await validateAppDefinition(app, () => []);
|
|
2301
|
+
expect(result.valid).toBe(false);
|
|
2302
|
+
expect(result.errors).toStrictEqual([
|
|
2303
|
+
new ValidationError('redundant permission. A permission for the query action on resource person without a specific view is already declared', app, undefined, ['security', 'guest', 'permissions', 0]),
|
|
2304
|
+
]);
|
|
2305
|
+
});
|
|
2306
|
+
it('should report an error when a guest resource view permission is declared for a specific view and there is already a permission for the same resource action with scope all without a specific view', async () => {
|
|
2307
|
+
const app = createTestApp();
|
|
2308
|
+
app.security = {
|
|
2309
|
+
guest: {
|
|
2310
|
+
permissions: ['$resource:person:query:public', '$resource:all:query'],
|
|
2311
|
+
},
|
|
2312
|
+
};
|
|
2313
|
+
app.resources = {
|
|
2314
|
+
person: {
|
|
2315
|
+
schema: {
|
|
2316
|
+
type: 'object',
|
|
2317
|
+
properties: {
|
|
2318
|
+
name: { type: 'string' },
|
|
2319
|
+
},
|
|
2320
|
+
},
|
|
2321
|
+
views: {
|
|
2322
|
+
public: {
|
|
2323
|
+
remap: 'log.info',
|
|
2324
|
+
},
|
|
2325
|
+
},
|
|
2326
|
+
},
|
|
2327
|
+
};
|
|
2328
|
+
const result = await validateAppDefinition(app, () => []);
|
|
2329
|
+
expect(result.valid).toBe(false);
|
|
2330
|
+
expect(result.errors).toStrictEqual([
|
|
2331
|
+
new ValidationError('redundant permission. A permission for the query resource action with scope all without a specific view is already declared', app, undefined, ['security', 'guest', 'permissions', 0]),
|
|
2332
|
+
]);
|
|
2333
|
+
});
|
|
2334
|
+
it('should report an error when a guest resource view permission is declared for a specific view and there is already a permission for the same resource action with scope all with the same view', async () => {
|
|
2335
|
+
const app = createTestApp();
|
|
2336
|
+
app.security = {
|
|
2337
|
+
guest: {
|
|
2338
|
+
permissions: ['$resource:person:query:public', '$resource:all:query:public'],
|
|
2339
|
+
},
|
|
2340
|
+
};
|
|
2341
|
+
app.resources = {
|
|
2342
|
+
person: {
|
|
2343
|
+
schema: {
|
|
2344
|
+
type: 'object',
|
|
2345
|
+
properties: {
|
|
2346
|
+
name: { type: 'string' },
|
|
2347
|
+
},
|
|
2348
|
+
},
|
|
2349
|
+
views: {
|
|
2350
|
+
public: {
|
|
2351
|
+
remap: 'log.info',
|
|
2352
|
+
},
|
|
2353
|
+
},
|
|
2354
|
+
},
|
|
2355
|
+
};
|
|
2356
|
+
const result = await validateAppDefinition(app, () => []);
|
|
2357
|
+
expect(result.valid).toBe(false);
|
|
2358
|
+
expect(result.errors).toStrictEqual([
|
|
2359
|
+
new ValidationError('redundant permission. A permission for the query resource action with scope all for this view is already declared', app, undefined, ['security', 'guest', 'permissions', 0]),
|
|
2360
|
+
]);
|
|
2361
|
+
});
|
|
2362
|
+
it('should report an error on duplicate role permissions', async () => {
|
|
2363
|
+
const app = createTestApp();
|
|
2364
|
+
app.security = {
|
|
2365
|
+
default: {
|
|
2366
|
+
role: 'test',
|
|
2367
|
+
},
|
|
2368
|
+
roles: {
|
|
2369
|
+
test: {
|
|
2370
|
+
permissions: ['$group:query', '$group:query'],
|
|
2371
|
+
},
|
|
2372
|
+
},
|
|
2373
|
+
};
|
|
2374
|
+
const result = await validateAppDefinition(app, () => []);
|
|
2375
|
+
expect(result.valid).toBe(false);
|
|
2376
|
+
expect(result.errors).toStrictEqual([
|
|
2377
|
+
new ValidationError('duplicate permission declaration', app, undefined, [
|
|
2378
|
+
'security',
|
|
2379
|
+
'roles',
|
|
2380
|
+
'test',
|
|
2381
|
+
'permissions',
|
|
2382
|
+
1,
|
|
2383
|
+
]),
|
|
2384
|
+
]);
|
|
2385
|
+
});
|
|
2386
|
+
it('should report an error if a role redeclares an inherited permission', async () => {
|
|
2387
|
+
const app = createTestApp();
|
|
2388
|
+
app.security = {
|
|
2389
|
+
default: {
|
|
2390
|
+
role: 'test',
|
|
2391
|
+
},
|
|
2392
|
+
roles: {
|
|
2393
|
+
inherited: {
|
|
2394
|
+
permissions: ['$group:query'],
|
|
2395
|
+
},
|
|
2396
|
+
test: {
|
|
2397
|
+
permissions: ['$group:query'],
|
|
2398
|
+
inherits: ['inherited'],
|
|
2399
|
+
},
|
|
2400
|
+
},
|
|
2401
|
+
};
|
|
2402
|
+
const result = await validateAppDefinition(app, () => []);
|
|
2403
|
+
expect(result.valid).toBe(false);
|
|
2404
|
+
expect(result.errors).toStrictEqual([
|
|
2405
|
+
new ValidationError('permission is already inherited from another role', app, undefined, [
|
|
2406
|
+
'security',
|
|
2407
|
+
'roles',
|
|
2408
|
+
'test',
|
|
2409
|
+
'permissions',
|
|
2410
|
+
0,
|
|
2411
|
+
]),
|
|
2412
|
+
]);
|
|
2413
|
+
});
|
|
2414
|
+
it('should report an error when a role resource permission references a non existing resource', async () => {
|
|
2415
|
+
const app = createTestApp();
|
|
2416
|
+
app.security = {
|
|
2417
|
+
default: {
|
|
2418
|
+
role: 'test',
|
|
2419
|
+
},
|
|
2420
|
+
roles: {
|
|
2421
|
+
test: {
|
|
2422
|
+
permissions: ['$resource:unknown:query'],
|
|
2423
|
+
},
|
|
2424
|
+
},
|
|
2425
|
+
};
|
|
2426
|
+
const result = await validateAppDefinition(app, () => []);
|
|
2427
|
+
expect(result.valid).toBe(false);
|
|
2428
|
+
expect(result.errors).toStrictEqual([
|
|
2429
|
+
new ValidationError("resource unknown does not exist in the app's resources definition", app, undefined, ['security', 'roles', 'test', 'permissions', 0]),
|
|
2430
|
+
]);
|
|
2431
|
+
});
|
|
2432
|
+
it('should report an error when a role resource permission for a specific resource is declared and there is already a resource permission with scope all declared', async () => {
|
|
2433
|
+
const app = createTestApp();
|
|
2434
|
+
app.security = {
|
|
2435
|
+
default: {
|
|
2436
|
+
role: 'test',
|
|
2437
|
+
},
|
|
2438
|
+
roles: {
|
|
2439
|
+
test: {
|
|
2440
|
+
permissions: ['$resource:person:query', '$resource:all:query'],
|
|
2441
|
+
},
|
|
2442
|
+
},
|
|
2443
|
+
};
|
|
2444
|
+
const result = await validateAppDefinition(app, () => []);
|
|
2445
|
+
expect(result.valid).toBe(false);
|
|
2446
|
+
expect(result.errors).toStrictEqual([
|
|
2447
|
+
new ValidationError('redundant permission. A permission for the query resource action with scope all is already declared', app, undefined, ['security', 'roles', 'test', 'permissions', 0]),
|
|
2448
|
+
]);
|
|
2449
|
+
});
|
|
2450
|
+
it('should report an error when a role resource permission for a specific resource is declared and there is already an inherited resource permission with scope all', async () => {
|
|
2451
|
+
const app = createTestApp();
|
|
2452
|
+
app.security = {
|
|
2453
|
+
default: {
|
|
2454
|
+
role: 'test',
|
|
2455
|
+
},
|
|
2456
|
+
roles: {
|
|
2457
|
+
inherited: {
|
|
2458
|
+
permissions: ['$resource:all:query'],
|
|
2459
|
+
},
|
|
2460
|
+
test: {
|
|
2461
|
+
permissions: ['$resource:person:query'],
|
|
2462
|
+
inherits: ['inherited'],
|
|
2463
|
+
},
|
|
2464
|
+
},
|
|
2465
|
+
};
|
|
2466
|
+
const result = await validateAppDefinition(app, () => []);
|
|
2467
|
+
expect(result.valid).toBe(false);
|
|
2468
|
+
expect(result.errors).toStrictEqual([
|
|
2469
|
+
new ValidationError('redundant permission. A permission for the query resource action with scope all is already inherited from another role', app, undefined, ['security', 'roles', 'test', 'permissions', 0]),
|
|
2470
|
+
]);
|
|
2471
|
+
});
|
|
2472
|
+
it('should report an error when a role resource view permission with scope all is declared and there is a resource that does not define the view', async () => {
|
|
2473
|
+
const app = createTestApp();
|
|
2474
|
+
app.security = {
|
|
2475
|
+
default: {
|
|
2476
|
+
role: 'test',
|
|
2477
|
+
},
|
|
2478
|
+
roles: {
|
|
2479
|
+
test: {
|
|
2480
|
+
permissions: ['$resource:all:query:public'],
|
|
2481
|
+
},
|
|
2482
|
+
},
|
|
2483
|
+
};
|
|
2484
|
+
app.resources = {
|
|
2485
|
+
person: {
|
|
2486
|
+
schema: {
|
|
2487
|
+
type: 'object',
|
|
2488
|
+
properties: {
|
|
2489
|
+
name: { type: 'string' },
|
|
2490
|
+
},
|
|
2491
|
+
},
|
|
2492
|
+
},
|
|
2493
|
+
};
|
|
2494
|
+
const result = await validateAppDefinition(app, () => []);
|
|
2495
|
+
expect(result.valid).toBe(false);
|
|
2496
|
+
expect(result.errors).toStrictEqual([
|
|
2497
|
+
new ValidationError('resource person is missing a definition for the public view', app, undefined, ['security', 'roles', 'test', 'permissions', 0]),
|
|
2498
|
+
]);
|
|
2499
|
+
});
|
|
2500
|
+
it('should report an error when a role resource view permission is declared for a resource that does not define the view', async () => {
|
|
2501
|
+
const app = createTestApp();
|
|
2502
|
+
app.security = {
|
|
2503
|
+
default: {
|
|
2504
|
+
role: 'test',
|
|
2505
|
+
},
|
|
2506
|
+
roles: {
|
|
2507
|
+
test: {
|
|
2508
|
+
permissions: ['$resource:person:query:public'],
|
|
2509
|
+
},
|
|
2510
|
+
},
|
|
2511
|
+
};
|
|
2512
|
+
app.resources = {
|
|
2513
|
+
person: {
|
|
2514
|
+
schema: {
|
|
2515
|
+
type: 'object',
|
|
2516
|
+
properties: {
|
|
2517
|
+
name: { type: 'string' },
|
|
2518
|
+
},
|
|
2519
|
+
},
|
|
2520
|
+
},
|
|
2521
|
+
};
|
|
2522
|
+
const result = await validateAppDefinition(app, () => []);
|
|
2523
|
+
expect(result.valid).toBe(false);
|
|
2524
|
+
expect(result.errors).toStrictEqual([
|
|
2525
|
+
new ValidationError('resource person is missing a definition for the public view', app, undefined, ['security', 'roles', 'test', 'permissions', 0]),
|
|
2526
|
+
]);
|
|
2527
|
+
});
|
|
2528
|
+
it('should report an error when a role resource view permission redeclares a view permission for an already declared resource action view permission', async () => {
|
|
2529
|
+
const app = createTestApp();
|
|
2530
|
+
app.security = {
|
|
2531
|
+
default: {
|
|
2532
|
+
role: 'test',
|
|
2533
|
+
},
|
|
2534
|
+
roles: {
|
|
2535
|
+
test: {
|
|
2536
|
+
permissions: ['$resource:person:query:public', '$resource:person:query:private'],
|
|
2537
|
+
},
|
|
2538
|
+
},
|
|
2539
|
+
};
|
|
2540
|
+
app.resources = {
|
|
2541
|
+
person: {
|
|
2542
|
+
schema: {
|
|
2543
|
+
type: 'object',
|
|
2544
|
+
properties: {
|
|
2545
|
+
name: { type: 'string' },
|
|
2546
|
+
},
|
|
2547
|
+
},
|
|
2548
|
+
views: {
|
|
2549
|
+
public: {
|
|
2550
|
+
remap: 'log.info',
|
|
2551
|
+
},
|
|
2552
|
+
private: {
|
|
2553
|
+
remap: 'log.info',
|
|
2554
|
+
},
|
|
2555
|
+
},
|
|
2556
|
+
},
|
|
2557
|
+
};
|
|
2558
|
+
const result = await validateAppDefinition(app, () => []);
|
|
2559
|
+
expect(result.valid).toBe(false);
|
|
2560
|
+
expect(result.errors).toStrictEqual([
|
|
2561
|
+
new ValidationError('a view permission for the query action on resource person is already declared', app, undefined, ['security', 'roles', 'test', 'permissions', 0]),
|
|
2562
|
+
]);
|
|
2563
|
+
});
|
|
2564
|
+
it('should report an error when a role resource view permission redeclares a view permission for an already declared resource action view permission with scope all', async () => {
|
|
2565
|
+
const app = createTestApp();
|
|
2566
|
+
app.security = {
|
|
2567
|
+
default: {
|
|
2568
|
+
role: 'test',
|
|
2569
|
+
},
|
|
2570
|
+
roles: {
|
|
2571
|
+
test: {
|
|
2572
|
+
permissions: ['$resource:person:query:public', '$resource:all:query:private'],
|
|
2573
|
+
},
|
|
2574
|
+
},
|
|
2575
|
+
};
|
|
2576
|
+
app.resources = {
|
|
2577
|
+
person: {
|
|
2578
|
+
schema: {
|
|
2579
|
+
type: 'object',
|
|
2580
|
+
properties: {
|
|
2581
|
+
name: { type: 'string' },
|
|
2582
|
+
},
|
|
2583
|
+
},
|
|
2584
|
+
views: {
|
|
2585
|
+
public: {
|
|
2586
|
+
remap: 'log.info',
|
|
2587
|
+
},
|
|
2588
|
+
private: {
|
|
2589
|
+
remap: 'log.info',
|
|
2590
|
+
},
|
|
2591
|
+
},
|
|
2592
|
+
},
|
|
2593
|
+
};
|
|
2594
|
+
const result = await validateAppDefinition(app, () => []);
|
|
2595
|
+
expect(result.valid).toBe(false);
|
|
2596
|
+
expect(result.errors).toStrictEqual([
|
|
2597
|
+
new ValidationError('a view permission for the query action with scope all is already declared', app, undefined, ['security', 'roles', 'test', 'permissions', 0]),
|
|
2598
|
+
]);
|
|
2599
|
+
});
|
|
2600
|
+
it('should report an error when a role resource view permission is declared for a specific view and there is already a permission for the same resource action without a specific view', async () => {
|
|
2601
|
+
const app = createTestApp();
|
|
2602
|
+
app.security = {
|
|
2603
|
+
default: {
|
|
2604
|
+
role: 'test',
|
|
2605
|
+
},
|
|
2606
|
+
roles: {
|
|
2607
|
+
test: {
|
|
2608
|
+
permissions: ['$resource:person:query:public', '$resource:person:query'],
|
|
2609
|
+
},
|
|
2610
|
+
},
|
|
2611
|
+
};
|
|
2612
|
+
app.resources = {
|
|
2613
|
+
person: {
|
|
2614
|
+
schema: {
|
|
2615
|
+
type: 'object',
|
|
2616
|
+
properties: {
|
|
2617
|
+
name: { type: 'string' },
|
|
2618
|
+
},
|
|
2619
|
+
},
|
|
2620
|
+
views: {
|
|
2621
|
+
public: {
|
|
2622
|
+
remap: 'log.info',
|
|
2623
|
+
},
|
|
2624
|
+
},
|
|
2625
|
+
},
|
|
2626
|
+
};
|
|
2627
|
+
const result = await validateAppDefinition(app, () => []);
|
|
2628
|
+
expect(result.valid).toBe(false);
|
|
2629
|
+
expect(result.errors).toStrictEqual([
|
|
2630
|
+
new ValidationError('redundant permission. A permission for the query action on resource person without a specific view is already declared', app, undefined, ['security', 'roles', 'test', 'permissions', 0]),
|
|
2631
|
+
]);
|
|
2632
|
+
});
|
|
2633
|
+
it('should report an error when a role resource view permission is declared for a specific view and there is already a permission for the same resource action with scope all without a specific view', async () => {
|
|
2634
|
+
const app = createTestApp();
|
|
2635
|
+
app.security = {
|
|
2636
|
+
default: {
|
|
2637
|
+
role: 'test',
|
|
2638
|
+
},
|
|
2639
|
+
roles: {
|
|
2640
|
+
test: {
|
|
2641
|
+
permissions: ['$resource:person:query:public', '$resource:all:query'],
|
|
2642
|
+
},
|
|
2643
|
+
},
|
|
2644
|
+
};
|
|
2645
|
+
app.resources = {
|
|
2646
|
+
person: {
|
|
2647
|
+
schema: {
|
|
2648
|
+
type: 'object',
|
|
2649
|
+
properties: {
|
|
2650
|
+
name: { type: 'string' },
|
|
2651
|
+
},
|
|
2652
|
+
},
|
|
2653
|
+
views: {
|
|
2654
|
+
public: {
|
|
2655
|
+
remap: 'log.info',
|
|
2656
|
+
},
|
|
2657
|
+
},
|
|
2658
|
+
},
|
|
2659
|
+
};
|
|
2660
|
+
const result = await validateAppDefinition(app, () => []);
|
|
2661
|
+
expect(result.valid).toBe(false);
|
|
2662
|
+
expect(result.errors).toStrictEqual([
|
|
2663
|
+
new ValidationError('redundant permission. A permission for the query resource action with scope all without a specific view is already declared', app, undefined, ['security', 'roles', 'test', 'permissions', 0]),
|
|
2664
|
+
]);
|
|
2665
|
+
});
|
|
2666
|
+
it('should report an error when a role resource view permission is declared for a specific view and there is already a permission for the same resource action with scope all with the same view', async () => {
|
|
2667
|
+
const app = createTestApp();
|
|
2668
|
+
app.security = {
|
|
2669
|
+
default: {
|
|
2670
|
+
role: 'test',
|
|
2671
|
+
},
|
|
2672
|
+
roles: {
|
|
2673
|
+
test: {
|
|
2674
|
+
permissions: ['$resource:person:query:public', '$resource:all:query:public'],
|
|
2675
|
+
},
|
|
2676
|
+
},
|
|
2677
|
+
};
|
|
2678
|
+
app.resources = {
|
|
2679
|
+
person: {
|
|
2680
|
+
schema: {
|
|
2681
|
+
type: 'object',
|
|
2682
|
+
properties: {
|
|
2683
|
+
name: { type: 'string' },
|
|
2684
|
+
},
|
|
2685
|
+
},
|
|
2686
|
+
views: {
|
|
2687
|
+
public: {
|
|
2688
|
+
remap: 'log.info',
|
|
2689
|
+
},
|
|
2690
|
+
},
|
|
2691
|
+
},
|
|
2692
|
+
};
|
|
2693
|
+
const result = await validateAppDefinition(app, () => []);
|
|
2694
|
+
expect(result.valid).toBe(false);
|
|
2695
|
+
expect(result.errors).toStrictEqual([
|
|
2696
|
+
new ValidationError('redundant permission. A permission for the query resource action with scope all for this view is already declared', app, undefined, ['security', 'roles', 'test', 'permissions', 0]),
|
|
2697
|
+
]);
|
|
2698
|
+
});
|
|
2699
|
+
it('should report an error when a role resource view permission redeclares a view permission for an already inherited resource action view permission', async () => {
|
|
2700
|
+
const app = createTestApp();
|
|
2701
|
+
app.security = {
|
|
2702
|
+
default: {
|
|
2703
|
+
role: 'test',
|
|
2704
|
+
},
|
|
2705
|
+
roles: {
|
|
2706
|
+
inherited: {
|
|
2707
|
+
permissions: ['$resource:person:query:private'],
|
|
2708
|
+
},
|
|
2709
|
+
test: {
|
|
2710
|
+
permissions: ['$resource:person:query:public'],
|
|
2711
|
+
inherits: ['inherited'],
|
|
2712
|
+
},
|
|
2713
|
+
},
|
|
2714
|
+
};
|
|
2715
|
+
app.resources = {
|
|
2716
|
+
person: {
|
|
2717
|
+
schema: {
|
|
2718
|
+
type: 'object',
|
|
2719
|
+
properties: {
|
|
2720
|
+
name: { type: 'string' },
|
|
2721
|
+
},
|
|
2722
|
+
},
|
|
2723
|
+
views: {
|
|
2724
|
+
public: {
|
|
2725
|
+
remap: 'log.info',
|
|
2726
|
+
},
|
|
2727
|
+
private: {
|
|
2728
|
+
remap: 'log.info',
|
|
2729
|
+
},
|
|
2730
|
+
},
|
|
2731
|
+
},
|
|
2732
|
+
};
|
|
2733
|
+
const result = await validateAppDefinition(app, () => []);
|
|
2734
|
+
expect(result.valid).toBe(false);
|
|
2735
|
+
expect(result.errors).toStrictEqual([
|
|
2736
|
+
new ValidationError('a view permission for the query action on resource person is already inherited from another role', app, undefined, ['security', 'roles', 'test', 'permissions', 0]),
|
|
2737
|
+
]);
|
|
2738
|
+
});
|
|
2739
|
+
it('should report an error when a role resource view permission redeclares a view permission for an already inherited resource action view permission with scope all', async () => {
|
|
2740
|
+
const app = createTestApp();
|
|
2741
|
+
app.security = {
|
|
2742
|
+
default: {
|
|
2743
|
+
role: 'test',
|
|
2744
|
+
},
|
|
2745
|
+
roles: {
|
|
2746
|
+
inherited: {
|
|
2747
|
+
permissions: ['$resource:all:query:private'],
|
|
2748
|
+
},
|
|
2749
|
+
test: {
|
|
2750
|
+
permissions: ['$resource:person:query:public'],
|
|
2751
|
+
inherits: ['inherited'],
|
|
2752
|
+
},
|
|
2753
|
+
},
|
|
2754
|
+
};
|
|
2755
|
+
app.resources = {
|
|
2756
|
+
person: {
|
|
2757
|
+
schema: {
|
|
2758
|
+
type: 'object',
|
|
2759
|
+
properties: {
|
|
2760
|
+
name: { type: 'string' },
|
|
2761
|
+
},
|
|
2762
|
+
},
|
|
2763
|
+
views: {
|
|
2764
|
+
public: {
|
|
2765
|
+
remap: 'log.info',
|
|
2766
|
+
},
|
|
2767
|
+
private: {
|
|
2768
|
+
remap: 'log.info',
|
|
2769
|
+
},
|
|
2770
|
+
},
|
|
2771
|
+
},
|
|
2772
|
+
};
|
|
2773
|
+
const result = await validateAppDefinition(app, () => []);
|
|
2774
|
+
expect(result.valid).toBe(false);
|
|
2775
|
+
expect(result.errors).toStrictEqual([
|
|
2776
|
+
new ValidationError('a view permission for the query action with scope all is already inherited from another role', app, undefined, ['security', 'roles', 'test', 'permissions', 0]),
|
|
2777
|
+
]);
|
|
2778
|
+
});
|
|
2779
|
+
it('should report an error when a role resource view permission is declared for a specific view and there is already an inherited permission for the same resource action without a specific view', async () => {
|
|
2780
|
+
const app = createTestApp();
|
|
2781
|
+
app.security = {
|
|
2782
|
+
default: {
|
|
2783
|
+
role: 'test',
|
|
2784
|
+
},
|
|
2785
|
+
roles: {
|
|
2786
|
+
inherited: {
|
|
2787
|
+
permissions: ['$resource:person:query'],
|
|
2788
|
+
},
|
|
2789
|
+
test: {
|
|
2790
|
+
permissions: ['$resource:person:query:public'],
|
|
2791
|
+
inherits: ['inherited'],
|
|
2792
|
+
},
|
|
2793
|
+
},
|
|
2794
|
+
};
|
|
2795
|
+
app.resources = {
|
|
2796
|
+
person: {
|
|
2797
|
+
schema: {
|
|
2798
|
+
type: 'object',
|
|
2799
|
+
properties: {
|
|
2800
|
+
name: { type: 'string' },
|
|
2801
|
+
},
|
|
2802
|
+
},
|
|
2803
|
+
views: {
|
|
2804
|
+
public: {
|
|
2805
|
+
remap: 'log.info',
|
|
2806
|
+
},
|
|
2807
|
+
},
|
|
2808
|
+
},
|
|
2809
|
+
};
|
|
2810
|
+
const result = await validateAppDefinition(app, () => []);
|
|
2811
|
+
expect(result.valid).toBe(false);
|
|
2812
|
+
expect(result.errors).toStrictEqual([
|
|
2813
|
+
new ValidationError('redundant permission. A permission for the query action on resource person without a specific view is already inherited from another role', app, undefined, ['security', 'roles', 'test', 'permissions', 0]),
|
|
2814
|
+
]);
|
|
2815
|
+
});
|
|
2816
|
+
it('should report an error when a role resource view permission is declared for a specific view and there is already an inherited permission for the same resource action with scope all without a specific view', async () => {
|
|
2817
|
+
const app = createTestApp();
|
|
2818
|
+
app.security = {
|
|
2819
|
+
default: {
|
|
2820
|
+
role: 'test',
|
|
2821
|
+
},
|
|
2822
|
+
roles: {
|
|
2823
|
+
inherited: {
|
|
2824
|
+
permissions: ['$resource:all:query'],
|
|
2825
|
+
},
|
|
2826
|
+
test: {
|
|
2827
|
+
permissions: ['$resource:person:query:public'],
|
|
2828
|
+
inherits: ['inherited'],
|
|
2829
|
+
},
|
|
2830
|
+
},
|
|
2831
|
+
};
|
|
2832
|
+
app.resources = {
|
|
2833
|
+
person: {
|
|
2834
|
+
schema: {
|
|
2835
|
+
type: 'object',
|
|
2836
|
+
properties: {
|
|
2837
|
+
name: { type: 'string' },
|
|
2838
|
+
},
|
|
2839
|
+
},
|
|
2840
|
+
views: {
|
|
2841
|
+
public: {
|
|
2842
|
+
remap: 'log.info',
|
|
2843
|
+
},
|
|
2844
|
+
},
|
|
2845
|
+
},
|
|
2846
|
+
};
|
|
2847
|
+
const result = await validateAppDefinition(app, () => []);
|
|
2848
|
+
expect(result.valid).toBe(false);
|
|
2849
|
+
expect(result.errors).toStrictEqual([
|
|
2850
|
+
new ValidationError('redundant permission. A permission for the query resource action with scope all without a specific view is already inherited from another role', app, undefined, ['security', 'roles', 'test', 'permissions', 0]),
|
|
2851
|
+
]);
|
|
2852
|
+
});
|
|
2853
|
+
it('a should report an error when a role resource view permission is declared for a specific view and there is already a permission for the same resource action with scope all with the same view', async () => {
|
|
2854
|
+
const app = createTestApp();
|
|
2855
|
+
app.security = {
|
|
2856
|
+
default: {
|
|
2857
|
+
role: 'test',
|
|
2858
|
+
},
|
|
2859
|
+
roles: {
|
|
2860
|
+
inherited: {
|
|
2861
|
+
permissions: ['$resource:all:query:public'],
|
|
2862
|
+
},
|
|
2863
|
+
test: {
|
|
2864
|
+
permissions: ['$resource:person:query:public'],
|
|
2865
|
+
inherits: ['inherited'],
|
|
2866
|
+
},
|
|
2867
|
+
},
|
|
2868
|
+
};
|
|
2869
|
+
app.resources = {
|
|
2870
|
+
person: {
|
|
2871
|
+
schema: {
|
|
2872
|
+
type: 'object',
|
|
2873
|
+
properties: {
|
|
2874
|
+
name: { type: 'string' },
|
|
2875
|
+
},
|
|
2876
|
+
},
|
|
2877
|
+
views: {
|
|
2878
|
+
public: {
|
|
2879
|
+
remap: 'log.info',
|
|
2880
|
+
},
|
|
2881
|
+
},
|
|
2882
|
+
},
|
|
2883
|
+
};
|
|
2884
|
+
const result = await validateAppDefinition(app, () => []);
|
|
2885
|
+
expect(result.valid).toBe(false);
|
|
2886
|
+
expect(result.errors).toStrictEqual([
|
|
2887
|
+
new ValidationError('redundant permission. A permission for the query resource action with scope all for this view is already inherited from another role', app, undefined, ['security', 'roles', 'test', 'permissions', 0]),
|
|
2888
|
+
]);
|
|
2889
|
+
});
|
|
2890
|
+
it('should report an error when an own resource permission references a resource that does not exist', async () => {
|
|
2891
|
+
const app = createTestApp();
|
|
2892
|
+
app.security = {
|
|
2893
|
+
default: {
|
|
2894
|
+
role: 'test',
|
|
2895
|
+
},
|
|
2896
|
+
roles: {
|
|
2897
|
+
test: {
|
|
2898
|
+
permissions: ['$resource:unknown:own:get'],
|
|
2899
|
+
},
|
|
2900
|
+
},
|
|
2901
|
+
};
|
|
2902
|
+
const result = await validateAppDefinition(app, () => []);
|
|
2903
|
+
expect(result.valid).toBe(false);
|
|
2904
|
+
expect(result.errors).toStrictEqual([
|
|
2905
|
+
new ValidationError("resource unknown does not exist in the app's resources definition", app, undefined, ['security', 'roles', 'test', 'permissions', 0]),
|
|
2906
|
+
]);
|
|
2907
|
+
});
|
|
2908
|
+
it('should report an error when an own resource permission is declared and there is already a generic resource permission for that action on that resource', async () => {
|
|
2909
|
+
const app = createTestApp();
|
|
2910
|
+
app.security = {
|
|
2911
|
+
default: {
|
|
2912
|
+
role: 'test',
|
|
2913
|
+
},
|
|
2914
|
+
roles: {
|
|
2915
|
+
test: {
|
|
2916
|
+
permissions: ['$resource:person:own:get', '$resource:person:get'],
|
|
2917
|
+
},
|
|
2918
|
+
},
|
|
2919
|
+
};
|
|
2920
|
+
const result = await validateAppDefinition(app, () => []);
|
|
2921
|
+
expect(result.valid).toBe(false);
|
|
2922
|
+
expect(result.errors).toStrictEqual([
|
|
2923
|
+
new ValidationError('redundant permission. A permission for the get resource action on resource person is already declared', app, undefined, ['security', 'roles', 'test', 'permissions', 0]),
|
|
2924
|
+
]);
|
|
2925
|
+
});
|
|
2926
|
+
it('should report an error when an own resource permission is declared and there is already a generic resource permission with scope all for that action', async () => {
|
|
2927
|
+
const app = createTestApp();
|
|
2928
|
+
app.security = {
|
|
2929
|
+
default: {
|
|
2930
|
+
role: 'test',
|
|
2931
|
+
},
|
|
2932
|
+
roles: {
|
|
2933
|
+
test: {
|
|
2934
|
+
permissions: ['$resource:person:own:get', '$resource:all:get'],
|
|
2935
|
+
},
|
|
2936
|
+
},
|
|
2937
|
+
};
|
|
2938
|
+
const result = await validateAppDefinition(app, () => []);
|
|
2939
|
+
expect(result.valid).toBe(false);
|
|
2940
|
+
expect(result.errors).toStrictEqual([
|
|
2941
|
+
new ValidationError('redundant permission. A permission for the get resource action with scope all is already declared', app, undefined, ['security', 'roles', 'test', 'permissions', 0]),
|
|
2942
|
+
]);
|
|
2943
|
+
});
|
|
2944
|
+
it('should report an error when an own resource permission is declared and there is already an own resource permission with scope all for that action', async () => {
|
|
2945
|
+
const app = createTestApp();
|
|
2946
|
+
app.security = {
|
|
2947
|
+
default: {
|
|
2948
|
+
role: 'test',
|
|
2949
|
+
},
|
|
2950
|
+
roles: {
|
|
2951
|
+
test: {
|
|
2952
|
+
permissions: ['$resource:person:own:get', '$resource:all:own:get'],
|
|
2953
|
+
},
|
|
2954
|
+
},
|
|
2955
|
+
};
|
|
2956
|
+
const result = await validateAppDefinition(app, () => []);
|
|
2957
|
+
expect(result.valid).toBe(false);
|
|
2958
|
+
expect(result.errors).toStrictEqual([
|
|
2959
|
+
new ValidationError('redundant permission. An own permission for the get resource action with scope all is already declared', app, undefined, ['security', 'roles', 'test', 'permissions', 0]),
|
|
2960
|
+
]);
|
|
2961
|
+
});
|
|
2962
|
+
it('should report an error when an own resource permission is declared and there is already an inherited generic resource permission for that action on that resource', async () => {
|
|
2963
|
+
const app = createTestApp();
|
|
2964
|
+
app.security = {
|
|
2965
|
+
default: {
|
|
2966
|
+
role: 'test',
|
|
2967
|
+
},
|
|
2968
|
+
roles: {
|
|
2969
|
+
inherited: {
|
|
2970
|
+
permissions: ['$resource:person:get'],
|
|
2971
|
+
},
|
|
2972
|
+
test: {
|
|
2973
|
+
permissions: ['$resource:person:own:get'],
|
|
2974
|
+
inherits: ['inherited'],
|
|
2975
|
+
},
|
|
2976
|
+
},
|
|
2977
|
+
};
|
|
2978
|
+
const result = await validateAppDefinition(app, () => []);
|
|
2979
|
+
expect(result.valid).toBe(false);
|
|
2980
|
+
expect(result.errors).toStrictEqual([
|
|
2981
|
+
new ValidationError('redundant permission. A permission for the get resource action on resource person is already inherited from another role', app, undefined, ['security', 'roles', 'test', 'permissions', 0]),
|
|
2982
|
+
]);
|
|
2983
|
+
});
|
|
2984
|
+
it('should report an error when an own resource permission is declared and there is already an inherited generic resource permission with scope all for that action', async () => {
|
|
2985
|
+
const app = createTestApp();
|
|
2986
|
+
app.security = {
|
|
2987
|
+
default: {
|
|
2988
|
+
role: 'test',
|
|
2989
|
+
},
|
|
2990
|
+
roles: {
|
|
2991
|
+
inherited: {
|
|
2992
|
+
permissions: ['$resource:all:get'],
|
|
2993
|
+
},
|
|
2994
|
+
test: {
|
|
2995
|
+
permissions: ['$resource:person:own:get'],
|
|
2996
|
+
inherits: ['inherited'],
|
|
2997
|
+
},
|
|
2998
|
+
},
|
|
2999
|
+
};
|
|
3000
|
+
const result = await validateAppDefinition(app, () => []);
|
|
3001
|
+
expect(result.valid).toBe(false);
|
|
3002
|
+
expect(result.errors).toStrictEqual([
|
|
3003
|
+
new ValidationError('redundant permission. A permission for the get resource action with scope all is already inherited from another role', app, undefined, ['security', 'roles', 'test', 'permissions', 0]),
|
|
3004
|
+
]);
|
|
3005
|
+
});
|
|
3006
|
+
it('should report an error when an own resource permission is declared and there is already an inherited own resource permission with scope all for that action', async () => {
|
|
3007
|
+
const app = createTestApp();
|
|
3008
|
+
app.security = {
|
|
3009
|
+
default: {
|
|
3010
|
+
role: 'test',
|
|
3011
|
+
},
|
|
3012
|
+
roles: {
|
|
3013
|
+
inherited: {
|
|
3014
|
+
permissions: ['$resource:all:own:get'],
|
|
3015
|
+
},
|
|
3016
|
+
test: {
|
|
3017
|
+
permissions: ['$resource:person:own:get'],
|
|
3018
|
+
inherits: ['inherited'],
|
|
3019
|
+
},
|
|
3020
|
+
},
|
|
3021
|
+
};
|
|
3022
|
+
const result = await validateAppDefinition(app, () => []);
|
|
3023
|
+
expect(result.valid).toBe(false);
|
|
3024
|
+
expect(result.errors).toStrictEqual([
|
|
3025
|
+
new ValidationError('redundant permission. An own permission for the get resource action with scope all is already inherited from another role', app, undefined, ['security', 'roles', 'test', 'permissions', 0]),
|
|
3026
|
+
]);
|
|
3027
|
+
});
|
|
3028
|
+
it('should not allow overwriting predefined roles', async () => {
|
|
3029
|
+
const app = createTestApp();
|
|
3030
|
+
app.security = {
|
|
3031
|
+
default: {
|
|
3032
|
+
role: 'Member',
|
|
3033
|
+
},
|
|
3034
|
+
roles: {
|
|
3035
|
+
Member: {},
|
|
3036
|
+
MembersManager: {},
|
|
3037
|
+
GroupMembersManager: {},
|
|
3038
|
+
GroupsManager: {},
|
|
3039
|
+
ResourcesManager: {},
|
|
3040
|
+
Owner: {},
|
|
3041
|
+
},
|
|
3042
|
+
};
|
|
3043
|
+
const result = await validateAppDefinition(app, () => []);
|
|
3044
|
+
expect(result.valid).toBe(false);
|
|
3045
|
+
expect(result.errors).toStrictEqual(predefinedAppRoles.map((role) => new ValidationError(`not allowed to overwrite role ${role}`, app, undefined, [
|
|
3046
|
+
'security',
|
|
3047
|
+
'roles',
|
|
3048
|
+
role,
|
|
3049
|
+
])));
|
|
3050
|
+
});
|
|
3051
|
+
it('should throw an error on invalid role permissions', async () => {
|
|
3052
|
+
const app = createTestApp();
|
|
3053
|
+
app.security = {
|
|
3054
|
+
default: {
|
|
3055
|
+
role: 'test',
|
|
3056
|
+
},
|
|
3057
|
+
roles: {
|
|
3058
|
+
test: {
|
|
3059
|
+
permissions: ['$resource:person:modify'],
|
|
3060
|
+
},
|
|
3061
|
+
},
|
|
3062
|
+
};
|
|
3063
|
+
const result = await validateAppDefinition(app, () => []);
|
|
3064
|
+
expect(result.valid).toBe(false);
|
|
3065
|
+
expect(result.errors).toStrictEqual([
|
|
3066
|
+
new ValidationError('invalid permission', app, undefined, [
|
|
3067
|
+
'security',
|
|
3068
|
+
'roles',
|
|
3069
|
+
'test',
|
|
3070
|
+
'permissions',
|
|
3071
|
+
0,
|
|
3072
|
+
]),
|
|
3073
|
+
]);
|
|
3074
|
+
});
|
|
3075
|
+
it('should throw an error on invalid guest permissions', async () => {
|
|
3076
|
+
const app = createTestApp();
|
|
3077
|
+
app.security = {
|
|
3078
|
+
guest: {
|
|
3079
|
+
permissions: ['$resource:person:own:modify'],
|
|
3080
|
+
},
|
|
3081
|
+
};
|
|
3082
|
+
const result = await validateAppDefinition(app, () => []);
|
|
3083
|
+
expect(result.valid).toBe(false);
|
|
3084
|
+
expect(result.errors).toStrictEqual([
|
|
3085
|
+
new ValidationError('invalid permission', app, undefined, [
|
|
3086
|
+
'security',
|
|
3087
|
+
'guest',
|
|
3088
|
+
'permissions',
|
|
3089
|
+
0,
|
|
3090
|
+
]),
|
|
3091
|
+
]);
|
|
3092
|
+
});
|
|
3093
|
+
it('should throw an error on invalid guest inherited permissions', async () => {
|
|
3094
|
+
const app = createTestApp();
|
|
3095
|
+
app.security = {
|
|
3096
|
+
guest: {
|
|
3097
|
+
inherits: ['test'],
|
|
3098
|
+
},
|
|
3099
|
+
default: {
|
|
3100
|
+
role: 'test',
|
|
3101
|
+
},
|
|
3102
|
+
roles: {
|
|
3103
|
+
test: {
|
|
3104
|
+
permissions: ['$resource:person:own:get'],
|
|
3105
|
+
},
|
|
3106
|
+
},
|
|
3107
|
+
};
|
|
3108
|
+
const result = await validateAppDefinition(app, () => []);
|
|
3109
|
+
expect(result.valid).toBe(false);
|
|
3110
|
+
expect(result.errors).toStrictEqual([
|
|
3111
|
+
new ValidationError('invalid security definition. Guest cannot inherit roles that contain own resource permissions', app, undefined, ['security', 'guest', 'inherits']),
|
|
3112
|
+
]);
|
|
3113
|
+
});
|
|
2305
3114
|
});
|
|
2306
3115
|
//# sourceMappingURL=validation.test.js.map
|