فهرست منبع

docs: Add docs on custom field permissions

Relates to #2671
Michael Bromley 1 سال پیش
والد
کامیت
6778ede482
2فایلهای تغییر یافته به همراه121 افزوده شده و 8 حذف شده
  1. 80 0
      docs/docs/guides/developer-guide/custom-fields/index.md
  2. 41 8
      docs/docs/guides/developer-guide/custom-permissions/index.md

+ 80 - 0
docs/docs/guides/developer-guide/custom-fields/index.md

@@ -261,6 +261,20 @@ console.log(customer.avatar);
 
 
 All custom fields share some common properties:
 All custom fields share some common properties:
 
 
+- [`name`](#name)
+- [`type`](#type)
+- [`list`](#list)
+- [`label`](#label)
+- [`description`](#description)
+- [`public`](#public)
+- [`readonly`](#readonly)
+- [`internal`](#internal)
+- [`defaultValue`](#defaultvalue)
+- [`nullable`](#nullable)
+- [`unique`](#unique)
+- [`validate`](#validate)
+- [`requiresPermission`](#requirespermission)
+
 #### name
 #### name
 
 
 <CustomFieldProperty required={true} type="string"/>
 <CustomFieldProperty required={true} type="string"/>
@@ -577,10 +591,60 @@ const config = {
 };
 };
 ```
 ```
 
 
+#### requiresPermission
+
+<CustomFieldProperty required={false} type="Permission | Permission[] | string | string[]" />
+
+Since v2.2.0, you can restrict access to custom field data by specifying a permission or permissions which are required to read and update the field.
+For instance, you might want to add a particular custom field to the `Product` entity, but you do not want all administrators to be able
+to view or update the field.
+
+In the Admin UI, the custom field will not be displayed if the current administrator lacks the required permission.
+
+In the GraphQL API, if the current user does not have the required permission, then the field will always return `null`. 
+Attempting to set the value of a field for which the user does not have the required permission will cause the mutation to fail
+with an error.
+
+```ts title="src/vendure-config.ts"
+import { Permission } from '@vendure/core';
+
+const config = {
+    // ...
+    customFields: {
+        Product: [
+            {
+                name: 'internalNotes',
+                type: 'text',
+                // highlight-start
+                requiresPermission: Permission.SuperAdmin,
+                // highlight-end
+            },
+            {
+                name: 'shippingType',
+                type: 'string',
+                // highlight-start
+                // You can also use an array of permissions, 
+                // and the user must have at least one of the permissions
+                // to access the field.
+                requiresPermission: [
+                    Permission.SuperAdmin, 
+                    Permission.ReadShippingMethod,
+                ],
+                // highlight-end
+            },
+        ]
+    }
+};
+```
+
 ### Properties for `string` fields
 ### Properties for `string` fields
 
 
 In addition to the common properties, the `string` custom fields have some type-specific properties:
 In addition to the common properties, the `string` custom fields have some type-specific properties:
 
 
+- [`pattern`](#pattern)
+- [`options`](#options)
+- [`length`](#length)
+
 #### pattern
 #### pattern
 
 
 <CustomFieldProperty required={false} type="string" />
 <CustomFieldProperty required={false} type="string" />
@@ -659,6 +723,9 @@ const config = {
 
 
 In addition to the common properties, the `localeString` custom fields have some type-specific properties:
 In addition to the common properties, the `localeString` custom fields have some type-specific properties:
 
 
+- [`pattern`](#pattern-1)
+- [`length`](#length-1)
+
 #### pattern
 #### pattern
 
 
 <CustomFieldProperty required={false} type="string" />
 <CustomFieldProperty required={false} type="string" />
@@ -675,6 +742,10 @@ Same as the `length` property for `string` fields.
 
 
 In addition to the common properties, the `int` & `float` custom fields have some type-specific properties:
 In addition to the common properties, the `int` & `float` custom fields have some type-specific properties:
 
 
+- [`min`](#min)
+- [`max`](#max)
+- [`step`](#step)
+
 #### min
 #### min
 
 
 <CustomFieldProperty required={false} type="number" />
 <CustomFieldProperty required={false} type="number" />
@@ -747,6 +818,10 @@ In addition to the common properties, the `datetime` custom fields have some typ
 The min, max & step properties for datetime fields are intended to be used as described in
 The min, max & step properties for datetime fields are intended to be used as described in
 [the MDN datetime-local docs](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/datetime-local#Additional_attributes)
 [the MDN datetime-local docs](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/datetime-local#Additional_attributes)
 
 
+- [`min`](#min-1)
+- [`max`](#max-1)
+- [`step`](#step-1)
+
 #### min
 #### min
 
 
 <CustomFieldProperty required={false} type="string" />
 <CustomFieldProperty required={false} type="string" />
@@ -801,6 +876,11 @@ The step value. See [the MDN datetime-local docs](https://developer.mozilla.org/
 
 
 In addition to the common properties, the `relation` custom fields have some type-specific properties:
 In addition to the common properties, the `relation` custom fields have some type-specific properties:
 
 
+- [`entity`](#entity)
+- [`eager`](#eager)
+- [`graphQLType`](#graphqltype)
+- [`inverseSide`](#inverseside)
+
 #### entity
 #### entity
 
 
 <CustomFieldProperty required={true} type="VendureEntity" typeLink="/reference/typescript-api/entities/vendure-entity" />
 <CustomFieldProperty required={true} type="VendureEntity" typeLink="/reference/typescript-api/entities/vendure-entity" />

+ 41 - 8
docs/docs/guides/developer-guide/custom-permissions/index.md

@@ -81,7 +81,7 @@ For example, let's imagine we are creating a plugin which adds a new entity call
 ```ts title="src/plugins/product-review/constants.ts"
 ```ts title="src/plugins/product-review/constants.ts"
 import { CrudPermissionDefinition } from '@vendure/core';
 import { CrudPermissionDefinition } from '@vendure/core';
 
 
-export const productReview = new CrudPermissionDefinition('ProductReview');
+export const productReviewPermission = new CrudPermissionDefinition('ProductReview');
 ```
 ```
 
 
 These permissions can then be used in our resolver:
 These permissions can then be used in our resolver:
@@ -89,20 +89,20 @@ These permissions can then be used in our resolver:
 ```ts title="src/plugins/product-review/api/product-review.resolver.ts"
 ```ts title="src/plugins/product-review/api/product-review.resolver.ts"
 import { Mutation, Resolver } from '@nestjs/graphql';
 import { Mutation, Resolver } from '@nestjs/graphql';
 import { Allow, Transaction } from '@vendure/core';
 import { Allow, Transaction } from '@vendure/core';
-import { productReview } from '../constants';
+import { productReviewPermission } from '../constants';
 
 
 @Resolver()
 @Resolver()
 export class ProductReviewResolver {
 export class ProductReviewResolver {
 
 
     // highlight-next-line
     // highlight-next-line
-    @Allow(productReview.Read)
+    @Allow(productReviewPermission.Read)
     @Query()
     @Query()
     productReviews(/* ... */) {
     productReviews(/* ... */) {
         // ...
         // ...
     }
     }
     
     
     // highlight-next-line
     // highlight-next-line
-    @Allow(productReview.Create)
+    @Allow(productReviewPermission.Create)
     @Mutation()
     @Mutation()
     @Transaction()
     @Transaction()
     createProductReview(/* ... */) {
     createProductReview(/* ... */) {
@@ -110,7 +110,7 @@ export class ProductReviewResolver {
     }
     }
     
     
     // highlight-next-line
     // highlight-next-line
-    @Allow(productReview.Update)
+    @Allow(productReviewPermission.Update)
     @Mutation()
     @Mutation()
     @Transaction()
     @Transaction()
     updateProductReview(/* ... */) {
     updateProductReview(/* ... */) {
@@ -118,7 +118,7 @@ export class ProductReviewResolver {
     }
     }
     
     
     // highlight-next-line
     // highlight-next-line
-    @Allow(productReview.Delete)
+    @Allow(productReviewPermission.Delete)
     @Mutation()
     @Mutation()
     @Transaction()
     @Transaction()
     deleteProductReview(/* ... */) {
     deleteProductReview(/* ... */) {
@@ -134,7 +134,7 @@ import gql from 'graphql-tag';
 import { VendurePlugin } from '@vendure/core';
 import { VendurePlugin } from '@vendure/core';
 
 
 import { ProductReviewResolver } from './api/product-review.resolver'
 import { ProductReviewResolver } from './api/product-review.resolver'
-import { productReview } from './constants';
+import { productReviewPermission } from './constants';
 
 
 @VendurePlugin({
 @VendurePlugin({
     adminApiExtensions: {
     adminApiExtensions: {
@@ -145,9 +145,42 @@ import { productReview } from './constants';
     },
     },
     configuration: config => {
     configuration: config => {
         // highlight-next-line
         // highlight-next-line
-        config.authOptions.customPermissions.push(productReview);
+        config.authOptions.customPermissions.push(productReviewPermission);
         return config;
         return config;
     },
     },
 })
 })
 export class ProductReviewPlugin {}
 export class ProductReviewPlugin {}
 ```
 ```
+
+## Custom permissions for custom fields
+
+Since Vendure v2.2.0, it is possible to define custom permissions for custom fields. This is useful when you want to 
+control access to specific custom fields on an entity. For example, imagine a "product reviews" plugin which adds a
+`rating` custom field to the `Product` entity. 
+
+You may want to restrict access to this custom field to only those roles which have permissions on the product review
+plugin.
+
+```ts title="src/plugins/product-review.plugin.ts"
+import { VendurePlugin } from '@vendure/core';
+import { productReviewPermission } from './constants';
+
+@VendurePlugin({
+    configuration: config => {
+        config.authOptions.customPermissions.push(productReviewPermission);
+        
+        config.customFields.Product.push({
+            name: 'rating',
+            type: 'int',
+            // highlight-start
+            requiresPermission: [
+                productReviewPermission.Read, 
+                productReviewPermission.Update,
+            ],
+            // highlight-end
+        });
+        return config;
+    },
+})
+export class ProductReviewPlugin {}
+```