Safely apply content filtering
Safely apply content filtering
The best way to ensure that your indexed content is seen only by the intended users is to enforce content security when configuring your Salesforce source. The Users Following System Permissions source configuration option replicates the security model of your Salesforce organization, which means that users only see the content that they’re allowed to see in Salesforce when obtaining search results from a Coveo index.
However, you may face situations where you have to configure your source to be accessible to Everyone. This is typically the case when you index Salesforce Knowledge Base (KB) records that are based on data categories as Coveo can’t replicate this security model (see Limitations).
Leading practice
When using the Salesforce Sharing for Lightning Knowledge security model, Coveo automatically supports permissions set on Online, Draft, and Archived articles. |
This article provides the leading practices to safely filter content from a source whose content is accessible to Everyone in a Salesforce Community.
Configure query filters
Filter rules allow you to enter hidden query expressions to be added to all queries going through a given query pipeline.
They’re typically used to add a field-based expression to the constant query expression (cq
).
You apply the @objectType=="Solution"
query filter to the pipeline to which the traffic of your public support portal is directed.
As a result, the @objectType=="Solution"
query expression is added to any query sent via this support portal.
Therefore, if a user types Speedbit watch wristband
in the searchbox, the items returned are those that match these keywords and whose objectType
has the Solution
value.
Items matching these keywords but having a different objectType
value aren’t returned in the user’s search results.
Filters, by themselves, don’t prevent the exposure of filtered content. We strongly advise against creating a source whose content is accessible to everyone and using a pipeline filter to exclude sensitive information. In the following cases, sensitive content from a source whose content is accessible to everyone could be exposed:
|
To learn how to configure query pipeline filter rules, see Manage filter rules.
Note
You can enforce a filter expression directly in the search token. See Configure the Search Token for instructions. |
Use the proper query pipeline routing mechanism
The most recommended and flexible query pipeline routing mechanism is condition-based routing.
In this scenario, search requests are authenticated with a search token that contains a searchHub
parameter, and each query pipeline except the default one has a distinct query pipeline condition based on a specific search hub value such as Search Hub is Community Search or Search Hub is Agent Panel.
When using this routing mechanism, you ensure that search requests are routed according to the search interface from which they originate.
You should always use positive operators (for example, |
Configure the search token
When using query filters to secure content, the safest way to enforce content security is to authenticate user queries using a search token that’s generated server side.
For instance, when using this approach, you can enforce a search hub value in the search token, which will make every authenticated request originating from the desired component use the specified search hub. Because this configuration is stored server side and encrypted in the search token, it can’t be modified by users or client-side code.
The procedure to generate a custom search token differs depending on the origin of the authenticated request:
Configure the search token for a Community Search component
Since the Coveo for Salesforce (v4.23) release, you can enforce a search hub in the search token that authenticates queries originating from a Coveo Lightning Community Search component by using the Search Hub option in the Advanced Server-Side Configuration panel.
Note
Setting a search hub using the Search Hub option of the Advanced Server-Side Configuration will override any search hub value set when building the page. |
Doing so prevents you from having to create an Apex class to generate a custom search token.
If you choose this approach to enforce a search hub in your search token, you can skip to step 5.
Step 1: Create an Apex class to generate the search token
-
In Salesforce, access the Developer Console.
-
In the Developer Console, create a new Apex class ( File > New > Apex Class).
-
In the new Apex class, enter the following template:
public with sharing class <MY_APEX_CLASS> { // Annotate the method so that it's accessible from the Lightning component @AuraEnabled public static string getToken() { // Generate a token using the Globals Class provided by Coveo. // See the Globals Class documentation: https://docs.coveo.com/en/1075/coveo-for-salesforce/globals-class Map<String, Object> endpoint = CoveoV2.Globals.getEndpointData(); endpoint.put('token', CoveoV2.Globals.generateSearchToken()); return JSON.serialize(endpoint); } }
Where you replace
<MY_APEX_CLASS>
with the name you chose for your Apex class. -
In the
getToken()
class, enter your code to create the custom search token. Modify that code to at least include thesearchHub
in your token generation steps.For content security reasons, don’t specify a search hub value as a parameter of the
getToken()
class (for example,getToken(String searchHub
)).Examplepublic with sharing class <MY_APEX_CLASS> { // Annotate the method so that it's accessible from the Lightning component @AuraEnabled public static string getToken() { // Generate a token using the Globals Class provided by Coveo. // See the Globals Class documentation: https://docs.coveo.com/en/1075/coveo-for-salesforce/globals-class Map<String, Object> endpoint = CoveoV2.Globals.getEndpointData(); endpoint.put('token', CoveoV2.Globals.generateSearchToken(new Map<String, Object> { 'searchHub' => '<MY_SEARCH_HUB>' })); return JSON.serialize(endpoint); } }
Where you replace
<MY_SEARCH_HUB>
with the name of the search hub to enforce in the search token.Note that you can specify other parameters in the search token, such as query filters or a query pipeline.
See Globals Class for instructions.
-
Save the Apex class.
Note
While you can use the Advanced Server-Side Configuration panel to add configurations to the search token, this panel doesn’t let you enforce a specific query pipeline in the search token. |
Step 2: Create the custom Lightning endpoint handler
Now that you’ve created your Apex class, you must create a custom Lightning endpoint handler to reference your Apex class in your Lightning component.
-
In the Developer Console, create a Lightning component.
-
In the component
.cmp
, add the following code:<aura:component controller="<MY_APEX_CLASS>" > <!-- GET THE ENDPOINT INITIALIZATION DATA --> <aura:method name="getEndpoint" action="{!c.getTokenAction}" access="global"> <aura:attribute name="name" type="String" /> </aura:method> <!-- RENEW THE ENDPOINT ACCESS TOKEN --> <aura:method name="renewAccessToken" action="{!c.getTokenAction}" access="global"> <aura:attribute name="name" type="String" /> </aura:method> </aura:component>
Where you replace
<MY_APEX_CLASS>
with the name of the Apex class you created in previous step. -
In the
controller.js
file, enter the following code:({ getTokenAction: function(component, event, helper) { const getTokenAction = component.get('c.getToken'); var getTokenPromise = new Promise(function (resolve, reject) { getTokenAction.setCallback(this, function (response) { if (response.getState() === 'SUCCESS') { var responseData = response.getReturnValue(); resolve(JSON.parse(responseData)); } else if (response.getState() === 'ERROR') { reject(Error('Error generating token')); } }); }); $A.enqueueAction(getTokenAction); return getTokenPromise; } });
-
Save the file.
Your custom Lightning endpoint handler is now ready.
Note
In our simple example, since there’s no difference between the generation and the renewal of a token, we call the same |
Step 3: Reference the custom Lightning endpoint handler in a Community Search component
Now that you’ve created your Apex class to generate a custom search token and a custom Lightning endpoint handler, you must reference the custom Lightning endpoint handler in a Community Search component.
Note
The following procedure assumes that you have wrapped a default Coveo Lightning component to create a custom Lightning component. See Integrate Coveo components in a custom Lightning component for your Experience Cloud site for instructions. |
-
In Salesforce, access an existing custom Lightning component, or create a new one.
-
In the component
.cmp
, ensure that your component references the custom Lightning endpoint handler you created in the last step. For example, the component.cmp
should look like the following:<aura:component implements='forceCommunity:availableForAllPageTypes'> <aura:attribute name="endpointHandler" type="Aura.Component[]" access="global"> <c:<MY_CUSTOM_ENDPOINT_HANDLER>></c:<MY_CUSTOM_ENDPOINT_HANDLER>> </aura:attribute> <CoveoV2:CommunitySearch endpointHandler="{!v.endpointHandler}"/> </aura:component>
Where you replace
<MY_CUSTOM_ENDPOINT_HANDLER>
with the name of the custom endpoint handler you created in the last step. -
Save the Lightning component.
Step 4: Ensure your Community Search component generates the search token server side
Now that your custom Community Search component references your custom code to generate a search token, make sure that your component uses your code to generate the search token server side.
-
In the Experience cloud site where your custom Lightning component is integrated, access the Preview mode.
-
Access the Advanced Server-Side Configuration panel for the component that must use the custom search token:
With Coveo for Salesforce v3.25+ With Coveo for Salesforce V3 At the upper-right corner of the component, click the cogwheel icon, and then select Advanced Configuration.
At the upper-left corner of the component, click the cogwheel icon, and then select Advanced Lightning Configuration.
-
In the Advanced Server-Side Configuration panel that opens, click the Bypass above settings to rather generate the search token from a custom Apex class checkbox to use your Apex class to generate the search token for this component.
Step 5: Validate the search token
Now that you’re enforcing configurations in a search token that’s generated server side, you should validate that the search token enforces the proper parameters to ensure that your content filtering is secure.
See Ensure that authentication enforces search hub values for instructions.
Configure the search token for a Community Search Box component
The Community Search Box component inherits its search token configuration from the Community Search component if they share the same name
.
Therefore, if you specified a search hub value in the Search Hub option of the Advanced Server-Side Configuration panel of the Community Search component, you don’t need to create an Apex class to generate a custom search token, and you can skip to step 5.
Step 1: Create an Apex class to generate the search token
-
In Salesforce, access the Developer Console.
-
In the Developer Console, create a new Apex class ( File > New > Apex Class).
-
In the new Apex class, enter the following template:
public with sharing class <MY_APEX_CLASS> { // Annotate the method so that it's accessible from the Lightning component @AuraEnabled public static string getToken() { // Generate a token using the Globals Class provided by Coveo. // See the Globals Class documentation: https://docs.coveo.com/en/1075/coveo-for-salesforce/globals-class Map<String, Object> endpoint = CoveoV2.Globals.getEndpointData(); endpoint.put('token', CoveoV2.Globals.generateSearchToken()); return JSON.serialize(endpoint); } }
Where you replace
<MY_APEX_CLASS>
with the name you chose for your Apex class. -
In the
getToken()
class, enter your code to create the custom search token. Modify that code to at least include thesearchHub
in your token generation steps.For content security reasons, don’t specify a search hub value as a parameter of the
getToken()
class (for example,getToken(String searchHub
)).Examplepublic with sharing class <MY_APEX_CLASS> { // Annotate the method so that it's accessible from the Lightning component @AuraEnabled public static string getToken() { // Generate a token using the Globals Class provided by Coveo. // See the Globals Class documentation: https://docs.coveo.com/en/1075/coveo-for-salesforce/globals-class Map<String, Object> endpoint = CoveoV2.Globals.getEndpointData(); endpoint.put('token', CoveoV2.Globals.generateSearchToken(new Map<String, Object> { 'searchHub' => '<MY_SEARCH_HUB>' })); return JSON.serialize(endpoint); } }
Where you replace
<MY_SEARCH_HUB>
with the name of the search hub to enforce in the search token.Note that you can specify other parameters in the search token, such as query filters or a query pipeline.
See Globals Class for instructions.
-
Save the Apex class.
Step 2: Create the custom Lightning endpoint handler
Now that you’ve created your Apex class, you must create a custom Lightning endpoint handler to reference your Apex class in your Lightning component.
-
In the Developer Console, create a Lightning component.
-
In the component
.cmp
, add the following code:<aura:component controller="<MY_APEX_CLASS>" > <!-- GET THE ENDPOINT INITIALIZATION DATA --> <aura:method name="getEndpoint" action="{!c.getTokenAction}" access="global"> <aura:attribute name="name" type="String" /> </aura:method> <!-- RENEW THE ENDPOINT ACCESS TOKEN --> <aura:method name="renewAccessToken" action="{!c.getTokenAction}" access="global"> <aura:attribute name="name" type="String" /> </aura:method> </aura:component>
Where you replace
<MY_APEX_CLASS>
with the name of the Apex class you created in previous step. -
In the
controller.js
file, enter the following code:({ getTokenAction: function(component, event, helper) { const getTokenAction = component.get('c.getToken'); var getTokenPromise = new Promise(function (resolve, reject) { getTokenAction.setCallback(this, function (response) { if (response.getState() === 'SUCCESS') { var responseData = response.getReturnValue(); resolve(JSON.parse(responseData)); } else if (response.getState() === 'ERROR') { reject(Error('Error generating token')); } }); }); $A.enqueueAction(getTokenAction); return getTokenPromise; } });
-
Save the file.
Your custom Lightning endpoint handler is now ready.
Note
In our simple example, since there’s no difference between the generation and the renewal of a token, we call the same |
Step 3: Reference the custom Lightning endpoint handler in a Community Search Box component
Now that you’ve created your Apex class to generate a custom search token and a custom Lightning endpoint handler, you must reference the custom Lightning endpoint handler in a Community Search Box component.
Note
The following procedure assumes that you have wrapped a default Coveo Lightning component to create a custom Lightning component. See Integrate Coveo components in a custom Lightning component for your Experience Cloud site for instructions. |
-
In Salesforce, access an existing custom Lightning component, or create a new one.
-
In the component
.cmp
, ensure that your component references the custom Lightning endpoint handler you created in the last step. For example, the component.cmp
should look like the following:<aura:component implements='forceCommunity:searchInterface'> <aura:attribute name="endpointHandler" type="Aura.Component[]" access="global"> <c:<MY_CUSTOM_ENDPOINT_HANDLER>></c:<MY_CUSTOM_ENDPOINT_HANDLER>> </aura:attribute> <CoveoV2:CommunitySearchBox endpointHandler="{!v.endpointHandler}"/> </aura:component>
Where you replace
<MY_CUSTOM_ENDPOINT_HANDLER>
with the name of the custom endpoint handler you created in the last step. -
Save the Lightning component.
Step 4: Ensure your Community Search Box component generates the search token server side
The Community Search Box component inherits its configuration from the Community Search component if they share the same name
.
Therefore, any change made to the Advanced Server-Side Configuration panel, such as activating the Bypass above settings to rather generate the search token from a custom Apex class option will be replicated in your Community Search Box component’s configuration.
Step 5: Validate the search token
Now that you’re enforcing configurations in a search token that’s generated server side, you should validate that the search token enforces the proper parameters to ensure that your content filtering is secure.
To do so, you should inspect the search token that appears in the request headers of a POST
request made against a Coveo query suggest endpoint (for example, search/v2/querySuggest
).
See Ensure that authentication enforces search hub values for instructions.
Configure the search token for a Case Deflection component
Since the Coveo for Salesforce (v4.23) release, you can enforce a search hub in the search token that authenticates queries originating from a Coveo Lightning Case Deflection component by using the Search Hub option in the Advanced Server-Side Configuration panel.
Note
Setting a search hub using the Search Hub option of the Advanced Server-Side Configuration will override any search hub value set when building the page. |
Doing so prevents you from having to create an Apex class to generate a custom search token.
If you choose this approach to enforce a search hub in your search token, you can skip to step 5.
Step 1: Create an Apex class to generate the search token
-
In Salesforce, access the Developer Console.
-
In the Developer Console, create a new Apex class ( File > New > Apex Class).
-
In the new Apex class, enter the following template:
public with sharing class <MY_APEX_CLASS> { // Annotate the method so that it's accessible from the Lightning component @AuraEnabled public static string getToken() { // Generate a token using the Globals Class provided by Coveo. // See the Globals Class documentation: https://docs.coveo.com/en/1075/coveo-for-salesforce/globals-class Map<String, Object> endpoint = CoveoV2.Globals.getEndpointData(); endpoint.put('token', CoveoV2.Globals.generateSearchToken()); return JSON.serialize(endpoint); } }
Where you replace
<MY_APEX_CLASS>
with the name you chose for your Apex class. -
In the
getToken()
class, enter your code to create the custom search token. Modify that code to at least include thesearchHub
in your token generation steps.For content security reasons, don’t specify a search hub value as a parameter of the
getToken()
class (for example,getToken(String searchHub
)).Examplepublic with sharing class <MY_APEX_CLASS> { // Annotate the method so that it's accessible from the Lightning component @AuraEnabled public static string getToken() { // Generate a token using the Globals Class provided by Coveo. // See the Globals Class documentation: https://docs.coveo.com/en/1075/coveo-for-salesforce/globals-class Map<String, Object> endpoint = CoveoV2.Globals.getEndpointData(); endpoint.put('token', CoveoV2.Globals.generateSearchToken(new Map<String, Object> { 'searchHub' => '<MY_SEARCH_HUB>' })); return JSON.serialize(endpoint); } }
Where you replace
<MY_SEARCH_HUB>
with the name of the search hub to enforce in the search token.Note that you can specify other parameters in the search token, such as query filters or a query pipeline.
See Globals Class for instructions.
-
Save the Apex class.
Note
While you can use the Advanced Server-Side Configuration panel to add configurations to the search token, this panel doesn’t let you enforce a specific query pipeline in the search token. |
Step 2: Create the custom Lightning endpoint handler
Now that you’ve created your Apex class, you must create a custom Lightning endpoint handler to reference your Apex class in your Lightning component.
-
In the Developer Console, create a Lightning component.
-
In the component
.cmp
, add the following code:<aura:component controller="<MY_APEX_CLASS>" > <!-- GET THE ENDPOINT INITIALIZATION DATA --> <aura:method name="getEndpoint" action="{!c.getTokenAction}" access="global"> <aura:attribute name="name" type="String" /> </aura:method> <!-- RENEW THE ENDPOINT ACCESS TOKEN --> <aura:method name="renewAccessToken" action="{!c.getTokenAction}" access="global"> <aura:attribute name="name" type="String" /> </aura:method> </aura:component>
Where you replace
<MY_APEX_CLASS>
with the name of the Apex class you created in previous step. -
In the
controller.js
file, enter the following code:({ getTokenAction: function(component, event, helper) { const getTokenAction = component.get('c.getToken'); var getTokenPromise = new Promise(function (resolve, reject) { getTokenAction.setCallback(this, function (response) { if (response.getState() === 'SUCCESS') { var responseData = response.getReturnValue(); resolve(JSON.parse(responseData)); } else if (response.getState() === 'ERROR') { reject(Error('Error generating token')); } }); }); $A.enqueueAction(getTokenAction); return getTokenPromise; } });
-
Save the file.
Your custom Lightning endpoint handler is now ready.
Note
In our simple example, since there’s no difference between the generation and the renewal of a token, we call the same |
Step 3: Reference the custom Lightning endpoint handler in a Case Deflection component
Now that you’ve created your Apex class to generate a custom search token and a custom Lightning endpoint handler, you must reference the custom Lightning endpoint handler in a Case Deflection component.
Note
The following procedure assumes that you have wrapped a default Coveo Lightning component to create a custom Lightning component. See Integrate Coveo components in a custom Lightning component for your Experience Cloud site for instructions. |
-
In Salesforce, access an existing custom Lightning component, or create a new one.
-
In the component
.cmp
, ensure that your component references the custom Lightning endpoint handler you created in the last step. For example, the component.cmp
should look like the following:<aura:component implements='forceCommunity:availableForAllPageTypes'> <aura:attribute name="endpointHandler" type="Aura.Component[]" access="global"> <c:<MY_CUSTOM_ENDPOINT_HANDLER>></c:<MY_CUSTOM_ENDPOINT_HANDLER>> </aura:attribute> <CoveoV2:CaseDeflection endpointHandler="{!v.endpointHandler}"/> </aura:component>
Where you replace
<MY_CUSTOM_ENDPOINT_HANDLER>
with the name of the custom endpoint handler you created in the last step. -
Save the Lightning component.
Step 4: Ensure your Case Deflection component generates the search token server side
Now that your custom Case Deflection component references your custom code to generate a search token, make sure that your component uses your code to generate the search token server side.
-
In the Experience cloud site where your custom Lightning component is integrated, access the Preview mode.
-
Access the Advanced Server-Side Configuration panel for the component that must use the custom search token:
With Coveo for Salesforce v3.25+ With Coveo for Salesforce V3 At the upper-right corner of the component, click the cogwheel icon, and then select Advanced Configuration.
At the upper-left corner of the component, click the cogwheel icon, and then select Advanced Lightning Configuration.
-
In the Advanced Server-Side Configuration panel that opens, click the Bypass above settings to rather generate the search token from a custom Apex class checkbox to use your Apex class to generate the search token for this component.
Step 5: Validate the search token
Now that you’re enforcing configurations in a search token that’s generated server side, you should validate that the search token enforces the proper parameters to ensure that your content filtering is secure.
See Ensure that authentication enforces search hub values for instructions.
Configure the search token for a Page View Tracker component
The Page View Tracker component inherits its search token configuration from the Community Search component if they share the same name
.
Therefore, if you specified a search hub value in the Search Hub option of the Advanced Server-Side Configuration panel of the Community Search component, you don’t need to create an Apex class to generate a custom search token, and you can skip to step 4.
Step 1: Create an Apex class to generate the search token
-
In Salesforce, access the Developer Console.
-
In the Developer Console, create a new Apex class ( File > New > Apex Class).
-
In the new Apex class, enter the following template:
public with sharing class <MY_APEX_CLASS> { // Annotate the method so that it's accessible from the Lightning component @AuraEnabled public static string getToken() { // Generate a token using the Globals Class provided by Coveo. // See the Globals Class documentation: https://docs.coveo.com/en/1075/coveo-for-salesforce/globals-class Map<String, Object> endpoint = CoveoV2.Globals.getEndpointData(); endpoint.put('token', CoveoV2.Globals.generateSearchToken()); return JSON.serialize(endpoint); } }
Where you replace
<MY_APEX_CLASS>
with the name you chose for your Apex class. -
In the
getToken()
class, enter your code to create the custom search token. Modify that code to at least include thesearchHub
in your token generation steps.For content security reasons, don’t specify a search hub value as a parameter of the
getToken()
class (for example,getToken(String searchHub
)).Examplepublic with sharing class <MY_APEX_CLASS> { // Annotate the method so that it's accessible from the Lightning component @AuraEnabled public static string getToken() { // Generate a token using the Globals Class provided by Coveo. // See the Globals Class documentation: https://docs.coveo.com/en/1075/coveo-for-salesforce/globals-class Map<String, Object> endpoint = CoveoV2.Globals.getEndpointData(); endpoint.put('token', CoveoV2.Globals.generateSearchToken(new Map<String, Object> { 'searchHub' => '<MY_SEARCH_HUB>' })); return JSON.serialize(endpoint); } }
Where you replace
<MY_SEARCH_HUB>
with the name of the search hub to enforce in the search token.Note that you can specify other parameters in the search token, such as query filters or a query pipeline.
See Globals Class for instructions.
-
Save the Apex class.
Step 2: Configure the component to reference the Apex class
Now that you’ve created your Apex class, you must configure the Page View Tracker component to reference your Apex class.
Note
The following procedure assumes that you have wrapped a default Coveo Lightning component to create a custom Lightning component. See Integrate Coveo components in a custom Lightning component for your Experience Cloud site for instructions. |
-
In Salesforce, access an existing custom Page View Tracking Lightning component, or create a new one.
-
In the component
.cmp
, ensure that your component references the Apex class you created in the last step. For example, the component.cmp
should look like the following:<aura:component implements="forceCommunity:availableForAllPageTypes,force:hasRecordId,force:hasSObjectName" access="global" controller="<MY_APEX_CLASS>"> <CoveoV2:PageViewTracker GetSearchToken="{!c.generateSearchToken}" contentIdValue="{!v.recordId}" name="{!v.name}" /> </aura:component>
Where you replace
<MY_APEX_CLASS>
with the name you chose for your Apex class in previous step. -
In the
controller.js
file, enter the following code:({ generateSearchToken: function(component, event, helper) { var deferred = event.getParam('deferred'); var action = component.get('c.getToken'); action.setCallback(this, function(response) { if (response.getState() == 'SUCCESS') { deferred.resolve({ searchToken: response.getReturnValue() }) } }); $A.enqueueAction(action); } })
-
Save the component.
Your custom Page View Tracker component is now ready.
Step 3: Ensure your Page View Tracker component generates the search token server side
The Page View Tracker component inherits its configuration from the Community Search component if they share the same name
.
Therefore, any change made to the Advanced Server-Side Configuration panel, such as activating the Bypass above settings to rather generate the search token from a custom Apex class option will be replicated in your Page View Tracker component’s configuration.
Step 4: Validate the search token
Now that you’re enforcing configurations in a search token that’s generated server side, you should validate that the search token enforces the proper parameters to ensure that your content filtering is secure.
To do so, you should inspect the search token that appears in the request headers of a POST
request made against the Coveo Usage Analytics Write API (for example, /rest/ua/v15/analytics/
).
See Ensure that authentication enforces search hub values for instructions.
Configure the search token for a Recommendations component
The Recommendations component inherits its search token configuration from the Community Search component if they share the same name
.
Therefore, if you specified a search hub value in the Search Hub option of the Advanced Server-Side Configuration panel of the Community Search component, you don’t need to create an Apex class to generate a custom search token, and you can skip to step 5.
Step 1: Create an Apex class to generate the search token
-
In Salesforce, access the Developer Console.
-
In the Developer Console, create a new Apex class ( File > New > Apex Class).
-
In the new Apex class, enter the following template:
public with sharing class <MY_APEX_CLASS> { // Annotate the method so that it's accessible from the Lightning component @AuraEnabled public static string getToken() { // Generate a token using the Globals Class provided by Coveo. // See the Globals Class documentation: https://docs.coveo.com/en/1075/coveo-for-salesforce/globals-class Map<String, Object> endpoint = CoveoV2.Globals.getEndpointData(); endpoint.put('token', CoveoV2.Globals.generateSearchToken()); return JSON.serialize(endpoint); } }
Where you replace
<MY_APEX_CLASS>
with the name you chose for your Apex class. -
In the
getToken()
class, enter your code to create the custom search token. Modify that code to at least include thesearchHub
in your token generation steps.For content security reasons, don’t specify a search hub value as a parameter of the
getToken()
class (for example,getToken(String searchHub
)).Examplepublic with sharing class <MY_APEX_CLASS> { // Annotate the method so that it's accessible from the Lightning component @AuraEnabled public static string getToken() { // Generate a token using the Globals Class provided by Coveo. // See the Globals Class documentation: https://docs.coveo.com/en/1075/coveo-for-salesforce/globals-class Map<String, Object> endpoint = CoveoV2.Globals.getEndpointData(); endpoint.put('token', CoveoV2.Globals.generateSearchToken(new Map<String, Object> { 'searchHub' => '<MY_SEARCH_HUB>' })); return JSON.serialize(endpoint); } }
Where you replace
<MY_SEARCH_HUB>
with the name of the search hub to enforce in the search token.Note that you can specify other parameters in the search token, such as query filters or a query pipeline.
See Globals Class for instructions.
-
Save the Apex class.
Step 2: Create the custom Lightning endpoint handler
Now that you’ve created your Apex class, you must create a custom Lightning endpoint handler to reference your Apex class in your Lightning component.
-
In the Developer Console, create a Lightning component.
-
In the component
.cmp
, add the following code:<aura:component controller="<MY_APEX_CLASS>" > <!-- GET THE ENDPOINT INITIALIZATION DATA --> <aura:method name="getEndpoint" action="{!c.getTokenAction}" access="global"> <aura:attribute name="name" type="String" /> </aura:method> <!-- RENEW THE ENDPOINT ACCESS TOKEN --> <aura:method name="renewAccessToken" action="{!c.getTokenAction}" access="global"> <aura:attribute name="name" type="String" /> </aura:method> </aura:component>
Where you replace
<MY_APEX_CLASS>
with the name of the Apex class you created in previous step. -
In the
controller.js
file, enter the following code:({ getTokenAction: function(component, event, helper) { const getTokenAction = component.get('c.getToken'); var getTokenPromise = new Promise(function (resolve, reject) { getTokenAction.setCallback(this, function (response) { if (response.getState() === 'SUCCESS') { var responseData = response.getReturnValue(); resolve(JSON.parse(responseData)); } else if (response.getState() === 'ERROR') { reject(Error('Error generating token')); } }); }); $A.enqueueAction(getTokenAction); return getTokenPromise; } });
-
Save the file.
Your custom Lightning endpoint handler is now ready.
Note
In our simple example, since there’s no difference between the generation and the renewal of a token, we call the same |
Step 3: Reference the custom Lightning endpoint handler in a Recommendations component
Now that you’ve created your Apex class to generate a custom search token and a custom Lightning endpoint handler, you must reference the custom Lightning endpoint handler in a Recommendations component.
Note
The following procedure assumes that you’ve created a custom Coveo Recommendations component as the default Coveo for Salesforce Recommendation Lightning Web component doesn’t support custom search tokens. See Creating Your Custom Component for instructions on how to create a custom Recommendations component. |
-
In Salesforce, access an existing custom Lightning component, or create a new one.
-
In the component
.cmp
, ensure that your component references the custom Lightning endpoint handler you created in the last step. For example, the component.cmp
should look like the following:<aura:component implements='forceCommunity:availableForAllPageTypes' access="global"> <aura:attribute name="endpointHandler" type="Aura.Component[]" access="global"> <c:<MY_CUSTOM_ENDPOINT_HANDLER>></c:<MY_CUSTOM_ENDPOINT_HANDLER>> </aura:attribute> <aura:attribute name="title" type="String" access="global" /> <aura:attribute name="debug" type="Boolean" default="false" access="global" /> <aura:attribute name="recommendationsContext" type="String" access="global" /> <div> <article> <header> <h2> {!v.title} </h2> </header> <CoveoV2:SearchUI endpointHandler="{!v.endpointHandler}" name="<VISUALFORCE_COMPONENT_NAME>" debug="{!v.debug}" aura:id="coveoRecommendations" /> </article> </div> </aura:component>
Where you replace
<MY_CUSTOM_ENDPOINT_HANDLER>
with the name of the custom endpoint handler you created in the last step and<VISUALFORCE_COMPONENT_NAME>
with the name of the Visualforce component that contains the JavaScript configuration for your custom Recommendations component (see Leveraging JavaScript Search Framework Components for more information). -
Save the Lightning component.
Step 4: Ensure your Recommendations component generates the search token server side
The Recommendations component inherits its configuration from the Community Search component if they share the same name
.
Therefore, any change made to the Advanced Server-Side Configuration panel, such as activating the Bypass above settings to rather generate the search token from a custom Apex class option will be replicated in your Recommendations component’s configuration.
Step 5: Validate the search token
Now that you’re enforcing configurations in a search token that’s generated server side, you should validate that the search token enforces the proper parameters to ensure that your content filtering is secure.
-
Access the Salesforce Community where your custom Coveo Lightning Recommendations component is integrated.
-
Access the Preview mode.
-
Open the Debug panel for the custom Coveo Lightning Recommendations component, and then select the Enable query debug option.
-
Search for the Pipeline parameter, and verify whether the associated value represents the query pipeline to which queries must be directed.
Configure the search token for a Quantic search interface
Step 1: Modify your token provider
In most Quantic implementations, you will have installed and configured the Coveo for Salesforce package, and you will have used it to implement your search token provider.
If that’s the case, enforcing a target search hub requires minimal configuration of this search token provider.
Hardcode the target search hub when calling the generateSearchToken
function:
global with sharing class CoveoTokenProvider implements ITokenProvider {
@AuraEnabled(continuation=true cacheable=false)
global static String getHeadlessConfiguration() {
Map<String, Object> coveoEndpointData = CoveoV2.Globals.getEndpointData();
String searchToken = CoveoV2.Globals.generateSearchToken(new Map<String, Object> {
'searchHub' => '<TARGET_VALUE>'
});
Map<String, String> headlessConfiguration = new Map<String, String>();
headlessConfiguration.put('organizationId', (String) coveoEndpointData.get('organization'));
headlessConfiguration.put('accessToken', searchToken);
headlessConfiguration.put('platformUrl', (String) coveoEndpointData.get('clientUri'));
return JSON.serialize(headlessConfiguration);
}
}
Where you replace <TARGET_VALUE>
by the target search hub value.
The reason why it’s important to hardcode the target search hub value in your backend function (for example, |
If you haven’t installed the Coveo for Salesforce package, or you have decided to implement your own custom token provider for some other reason, we can’t make precise recommendations about what to do, but be sure not to expose an argument that would allow users to modify the search hub value set in the token.
Note
In a Quantic search interface, while search tokens can enforce a search hub in search requests, you should also set your
Where you replace |
Step 2: Validate the search token
Now that you’re enforcing configurations in a search token that’s generated server side, you should validate that the search token enforces the proper parameters to ensure that your content filtering is secure.
See Ensure that authentication enforces search hub values for instructions.