> For the complete documentation index, see [llms.txt](https://adamite.gitbook.io/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://adamite.gitbook.io/docs/server/database/securing-your-data/securing-read-operations.md).

# Securing read operations

To secure a read operation, you'll want to add a `read` rule.

```javascript
module.exports = {
  "default": {
    "projects": {
      "read": () => {
        return true;
      }
    }
  }
};
```

{% hint style="info" %}
Whether you're reading a collection of documents or an individual document, each document will be passed through the read rule, allowing you to return `true` or `false`. This allows you to granularly filter documents out of a collection.&#x20;
{% endhint %}

## Verify that the user is logged in

You may only want to allow logged in users to read certain documents from the database. Context information is passed to the `read` rule which can be inspected to determine login state.

```javascript
module.exports = {
  "default": {
    "projects": {
      "read": (req) => {
        const { isLoggedIn } = req.client.auth;
        return !!isLoggedIn;
      }
    }
  }
};
```

## Verify ownership of a document

Once you verify a user is logged in, you may also only want to allow them to read documents that belong to them. In addition to seeing the logged in user's information, you can see a snapshot of the document that is being read.

```javascript
module.exports = {
  "default": {
    "projects": {
      "read": (req, res) => {
        const { isLoggedIn, data } = req.client.auth;
        
        return (
          !!isLoggedIn &&
          data.id === res.data.owner
        );
      }
    }
  }
};
```

## Alter the data returned to the client

You may want to allow anyone to read a document, but only allow certain users to see privileged information on the document. For example, everyone can view a user's profile, but only that user can read their email address on the document.

```javascript
module.exports = {
  "default": {
    "users": {
      "read": (req, res) => {
        const { isLoggedIn, data } = req.client.auth;
        
        if (!isLoggedIn) {
          return false;
        }
        
        if (data.id !== res.data.owner) {
          delete res.data.email; // redact `email` property
        }
        
        return true;
      }
    }
  }
};
```

## Access other data to validate an operation

In some cases, you may need to access other data in the database in order to validate an operation. Within the `rules.js` file, you can use the Adamite SDK to query data just like you would on your client.

```javascript
const adamite = require("@adamite/sdk").default;

module.exports = {
  "default": {
    "projects": {
      "read": async (req, res) => {
        const { isLoggedIn, data } = req.client.auth;
        
        if (!isLoggedIn) {
          throw new Error("Not logged in.");
        }
        
        const matchingOrganizations =
          await adamite()
            .database()
            .collection("organizations")
            .where("members", "array-includes", data.id)
            .get();
        
        if (matchingOrganizations.docs.length === 0) {
          throw new Error("User does not belong to any organizations.");
        }
        
        const matchingOrganizationIds = matchingOrganizations.docs.map((o) => {
          return o.id;
        });
        
        const projectOrganizationId = res.data.organization;
                
        if (!matchingOrganizationIds.includes(projectOrganizationId)) {
          throw new Error("User is not a member of project's organization.");
        }
        
        return true;
      }
    }
  }
};
```
