top of page

Tech Insights

Securing Your Site: Custom Content Collections and the Wix Data API

Thu Jun 02 2022

2.gif
Blank_Canvas_on_Transparent_Background.p

Share

  • Twitter
  • Black LinkedIn Icon
  • Facebook

Security best practices with code examples to consider when using the content manager with a focus on custom collections and the Wix Data AP

Made by Wix Apps come with out-of-the-box content collections that feature certain security measures within the default collection settings. These include PII encryption and Velo API settings that require each user to log into your site before they’re allowed to perform certain actions. At times, you may find that your business needs require a custom collection that uses the Velo JavaScript editor and the Wix Data API, which allows you to interact with your custom collection. But does this guarantee that your site is secure? What happens then you may ask? Am I secure?


There are certain security measures to be aware of when you create custom collections with the Wix Data API, which ensure that your site is as secure as possible. In this article, we will implement a custom collection and explore various options available which help secure access to your code and data.


To get in a security mindset it is important to ask yourself who exactly needs access to your code, and who should be able to interact with the collections on your Wix site or execute functions in your code. You should limit access to only those users who need to be able to perform actions such as inserting a new row of data, modifying a value, or deleting data. You also want to create layers of security by taking into account each of your site’s resources separately and considering the security of your site as a whole. For example, it’s often valuable to set security permissions at the page level and at the content collection level. It’s also important to limit function execution within your code, so that only specific users can call certain functions. Web module (.jsw) functions, for example, should only be invoked from a site members page, since it doesn’t make sense to allow other users to invoke it.


Let’s explore how to secure a custom content collection with a short example. We’ll build a simple form that allows site members to post comments to one of our web pages. Users who are not site members will be able to view the comments, but not be able to contribute posts. Doing this will give us a better understanding of the security features available when using custom content collections.


How to Secure my Custom Content Collection


To get started with our example, we first need to create a custom comment page. In this instance, we are also using the Wix Members Area app to help us distinguish valid site members from those that don’t yet have an account. If you’re not familiar with the Wix Members Area and login page, you can visit the Members Area example for additional guidance.


Example:


Building a comment form for site members that site visitors can also see.


Prerequisites: A Wix site with the Wix Members Area and Content Manager added. This tutorial assumes you have a basic knowledge of the Wix editor environment and familiarity with JavaScript.


First, you will want to create a new page on your site with a title like comments. Add a repeater element and give the repeater an ID of #commentsRepeater. Next, attach a text field to the repeater and give it the name #commentsText. Below the repeater, add an input field with an ID of #inputComment and add a button below the repeater called #submitComment. Finally, add a text field with your error message with an ID of #errorMsg and set it to be hidden on default. Once you’ve completed all these steps, your page should look similar to our example:

Next, create a dataset to connect to your repeater element. To do this, click on your repeater and the connector button at the end of the list. It’s worth noting that the dataset does not provide security features by default and is primarily considered a UI element that interacts with your collection.

Then click create dataset and create a new dataset and under collection, create a new comments collection if you have not done so already.

Within the content manager select your new Comments collection and you should see an option to add an email field and a comment field. In the properties field for email, be sure to toggle on the “Personally Identifiable Information” switch. This is the first manual security action we are taking. PII can include everything from a user’s email address, phone number, credit card information, and any other information that could be harmful if it landed in the wrong hands. Protecting this information is your responsibility as a developer, so be sure to design your site with security and user privacy in mind. Read more about PII and best practices when working with this type of data.

Once your collection is configured, be sure to add a test comment so you can see that your repeater is populating as expected while you work. Once you’re finished, click publish to activate your new collection and make it available for use in the code.


If you have not done so already, turn on dev mode. This can be done by clicking the “Dev Mode” button in the menu bar in the top left corner of the page.Next, open the page code for your comments page. Only site members should be able to post comments, so first import currentMember.

import { currentMember } from 'wix-members';

In the onReady function that is present in the Velo editor by default, define what should happen when a user enters some text and clicks your submit button.

$w('#submitComment').onClick( async () => {
    let toInsert = {}
  
    const comment = $w('#inputComment').value;
    const member = await currentMember.getMember()

    if(member){
      const email = member.loginEmail
      console.log(email)
      toInsert = {"email": email, "comment": comment}
    }
  
    if (toInsert.email){
      await insertComment(toInsert)
    } else {
      console.log("logged out")
      $w('#errorMsg').show()
    }
  
  })
});

Code Notes: In the function above, you can see that we have created a new object to hold a user’s email. Our function also performs a check to see whether or not the user is a member of our site before allowing them to insert a new comment.


Next, let’s add the insertComment function which will be called when a logged-in member submits a comment.

function insertComment(toInsert){
   wixData.insert("Comments", toInsert).then((result) =>{
      console.log(`Success: ${JSON.stringify(result)}`)
   }).catch((error) =>{
      console.log(`Error: ${JSON.stringify(error)}`)
   })
}

Code Notes: Inside of our insertComment function, the comment from the user input is passed into the function, which adds it to the comments collection through the Wix Data API.


This code may look adequate on the surface, but we still have more work to do. While the email field is marked as PII in the database, and now only members may insert comments, our site still isn’t quite secure enough. In the next section, I’ll explain why there are still more security features we should consider and discuss the implications for our code thus far.


Permissions for Content Collections


Wix provides a number of preset permissions options for your collections. Take a look at the following table, which illustrates each preset permission option and shows which actions each permission setting allows.

Preset / Permission

Read

Create

Update

Delete

Site Content

Anyone

Admin

Admin

Admin

Form Submission

Admin

Anyone

Admin

Admin

Member-Generated Content

Anyone

Site member

Site member author

Site member author

Member-Only Content

Site member

Admin

Admin

Admin

Member-Only Form Submission

Admin

Site member

Admin

Admin

Private Data

Admin

Admin

Admin

Admin

Custom

n/a

n/a

n/a

n/a

Applying this to our example, none of the presets will work because the email field should only be able to be accessed by an admin, but the comments data must be interactive for logged in members and visible to logged out site visitors.


In this case, we want to open the databases section in our editor, which lives on the left-hand side of the navigation. From there, click on the ellipsis then edit settings.

In the pop up window, click on the tab labeled “Additional Settings.”Then choose “Custom Use” from the dropdown to set permissions.

Click on the “Set Custom Permissions” button and set the options to match this image below.

Admins should be the only users with access to the private email field in our collection. However, setting read permissions to admin prevents our site visitors from reading the comments on our site, which is not exactly what we had in mind for our design. We have a few options for handling this scenario, and while either will work, you should choose the solution that works best for your use-case. Option One: Move the emails field in your collection to a new table of their own, one that’s completely protected by security restrictions, and leave the comments in a table that allows anyone to read the data. Option Two, which we will walk through together below, involves using the Wix Data API to query the database collection and deciding which data we want to return on the front-end of our site.


Protecting Wix Data Queries in Backend Code


Until now, we have used a single dataset to populate the repeated element. Due to the current collection permissions, site visitors and members can no longer see comments unless they are a site administrator.


To adjust our Wix Data query to populate our repeater, we will first need to right click on the dataset and delete it. One important note: Datasets are a UI feature that allows quick connections to data in elements like repeaters. However, they do not provide any level of security to the data in the collection itself. Even if you are not exposing data through the dataset, the permissions set at the collection level drive the security of that collection.


Next, click on the code block icon ({ }) in the top left-hand corner of the navigation and create a back-end jsw file called callData.jsw. Back-end files are not exposed to the front-end, but are callable from the front end through exported functions so security is important to handle here as well.

In the callData.jsw file, place the following code:

import wixData from'wix-data';

const options = {
   "suppressAuth":true
}

exportasyncfunctiongetData(){
   try {
      let results = await wixData.query("Comments").find(options);
      if(results.totalCount > 0){
         const filteredResults = results.items.map(item => {
            const {comment, _id} = item
            return {comment, _id}
         })
         return filteredResults
      }
   } catch(err) {
      console.log(err)
   }
}

Code Notes: In the code block above, using suppressAuth allows us to override the collection permissions when using a Wix Data query so that users who are not administrators can interact with the otherwise protected collection. Security is provided manually in the results that are being returned from the function. By utilizing the object destructuring expression in JavaScript, we are filtering the results to ensure that they only ever return the comments data to the front end. This gives us the added security we want and means that no matter how this function is triggered, it will only ever return the data specified by our query. If we were to update our collection with new columns containing sensitive data or PII in the future, our query would still only ever return the comments data to the front-end.


Now that our back-end function is ready, there are a few adjustments we need to make to front-end code. Open the Velo code editor for our comments page and add the import statement to allow us to call our back-end function.

import { getData } from 'backend/callData'

Next, add the following code just inside the onReady function.


$w.onReady(async function () {
//updates for more secure version getting filtered comments from backend and populate the repeater

$w('#commentsRepeater').data = []
const results = await getData();

$w('#commentsRepeater').data = results
$w('#commentsRepeater').onItemReady(($item, itemData,index) => {
   $item("#commentsText").text = itemData.comment;
})

Code Notes: In this code block, you’ll see that we’re assigning an empty array to our repeater field . From there, we’re await(ing) (remember this is an asynchronous function!) the results of our getData call to the back-end. Once the data is returned, the array is connected to the repeater, meaning that you can now populate all comments in the repeater text element using the onItemReady function.


Things to Remember on Your Own Projects


Working through this simple example will give you a better grasp of the security features available when using the Wix Data API on your Velo sites and help you get into a security mindset. Remember to ask yourself the following questions:

  • Who should be allowed to access this data?

  • Is there any sensitive data or PII that must be protected?

  • Am I returning only the minimum amount of data needed to my UI?

  • Am I using Wix Data collection queries in back-end files so that the code is not available on the front end?

  • Have I set permissions at the page and collection levels to only allow users I know to perform certain actions?

  • Am I using Wix Apps such as the members area and API when possible to ensure the highest levels of security in my collections?

Custom collections permissions and the Wix Data API are powerful tools that allow you to build beautiful sites. But knowing best practices can help ensure that your sites are not only beautiful, but also incredibly secure.


If you have questions about your particular security scenario that are not answered here, please reach out to our customer care experts.

Blank_Canvas_on_Transparent_Background.p

0

get certified.png

Related Posts

View All

1.png

CORVID LIBARY

Unified Database Management

Unified Database Management

Jun 18, 2018   8min

1.png

CORVID LIBARY

Unified Database Management

Unified Database Management

Jun 18, 2018   8min

1.png

CORVID LIBARY

Unified Database Management

Unified Database Management

Jun 18, 2018   8min

bottom of page