Skip to main content

Custom Access Function

Custom Access Function allows more granular control on how the data in the endpoints is accessed. These functions are set up on the Project Dashboard and are executed on the server side for every request to the endpoint with this functionality enabled.

Why these functions are important

When is comes to accessing the data without a Custom Access Function, RESTED_DEV offers Secure endpoints, and Additional data options, these can be enabled on the Project Dashboard and the access control to the data is done on the server side. This already gives a good level of security, but the control to check who is accessing the data is limited, and used incorrecly could expose the data of the endpoint.

Custom Access Functions come in to help with more complex use cases and give more control to the administrator of a Project.

Let's start with an example of a typical use case to understand better this functionality.

Example - Chat application

Let's imagine you are building a Chat application that allows users to have private conversations with each other. When user1 send a message to user2, that message should only be available for those 2 users.

With Secure Endpoints and Custom Data Options only, this would not be possible. If user3 would try to request data from the endpoint containing messages (without JSONata filtering), all messages would be sent to the client - even though the client application can filter out the records, a more curious user could inspect the request and check the messages there.

For these use cases, the basic usage or the RESTED_DEV endpoints is not enough.

How Custom Access Functions solve this issue?

You can check who is requesting the message and decide whether or not that user can receive it. You do this by checking uniqueIds (and other data), and match it against the requested data, or even data from other endpoints.

You can easily implement role based access using this function.

Some important notes

  • The function is written in JavaScript as a IIFE function
  • To enable this function in an endpoint the funtion must be saved first in the Project configuration
  • When this function is enabled for an endpoint, all other checks are ignored, you have full control to check who can access the data - be aware, if used incorrectly you can open the endpoint to authenticathed and non-authenticathed users.

Example of a function

In the context of a chat application, in the following function we are checking if the user accessing the data can receive access it. We do this by checking if their uniqueId is equal to fromUserId or toUserId.

Remember that this depends on how your data is structured. RESTED_DEV gives you the flexibility to structure the data in any way, so you need to write your function accordingly.

//GET|roles|rolesVar
//GET|messages|messagesVar

(function myCustomAccessFunction() {
// global vars:
// console.log('The data contained in accessed endpoint:', ACCESSED_DATA)
// console.log('The current signed in user:', SIGNED_IN_USER)
// console.log("Name of the accessed endpoint:", THIS_ENDPOINT_NAME);
// ...and more

// we can control the access to each endpoint in the project
// in this example, we just want to control access to the messages endpoint
if (THIS_ENDPOINT_NAME !== "messages") {
return true;
}

if (THIS_ENDPOINT_IS_SECURE && !SIGNED_IN_USER) {
throw new Error("This endpoint requires an authenticathed user");
}

// since we are sending messages, we allow the auth users to post anything
if (REQUEST_METHOD === "POST") {
// we could do other checks here
console.log("NEW_DATA_TO_PERSIST", NEW_DATA_TO_PERSIST);
return true;
}

// here we control which messages the user has access to
if (REQUEST_METHOD === "GET") {
// we could do other checks here

// we are gonna filter the record ids the logged in user has access to
const accessedData = Array.isArray(ACCESSED_DATA)
? ACCESSED_DATA
: [ACCESSED_DATA];

return accessedData
.filter((record) => {
const userUniqueId = SIGNED_IN_USER.uniqueId;
if (
record.data.fromUserId === userUniqueId ||
record.data.toUserId === userUniqueId
) {
return true;
}
})
.map((record) => record.uniqueId);
}
})();

The function must be written as a IIFE function and from within the function you will have access to enviroment variables.

Environment variables

VariableDescription
SIGNED_IN_USERIf there's a user signed in, this variable will contain their data.
ACCESSED_DATAContains the accessed data. This data is not avaialable for POST requests.
THIS_ENDPOINT_NAMEName of the endpoint. Currently you can only set one function per project, if you want to use it in multiple endpoints you can use this variable to conditionaly make checks to the data.
NEW_DATA_TO_PERSISTContains the data to be persisted/updated. Only available for POST and PUT requests.
THIS_ENDPOINT_IS_SECUREBoolean where the accessed endpoint is secured.
REQUEST_METHODType of request: GET, POST, PUT, DELETE

Accessing data from other endpoints

In some cases, like role based access, you might need to access data from other endoints.

To do so, before you define a function, you need to include the following string (like we did in the example above):

//GET|roles|rolesVar

The string is divided in 3 parts, delimited by the pipe "|" symbol:

//GET|name_of_the_endpoint|name_of_the_variable
name_of_the_endpointName of the endpoint you want to get data from. The endpoint needs to exist in the Project.
name_of_the_variableThe data will be requested will be available as an environment variable that can be accessed from within the function.
note

You can get the data from multiple endpoints but we recomend not doing so as it will impact the response times of the request to the endpoint.

Return values

The function is expected to return certain values:

Return valueDescription
Boolean - trueAllow access to the data/endpoint.
Boolean - falseDeny access to the data/endpoint.
Array of uniqueIdsList of uniqueIds from the accessed data. The endpoint will only return records that match the ids.

Debbugging

To debug the data, you need to enable debug mode for your endpoint. This can be done on the Dashboard, directly in the endpoint.

When enabled, the endpoint will return as well the output of anything logged within the function.

The structure of the response changes.

danger

Be mindful when enabling debugging mode for a production endpoint: -The response format changes, if your application is not handling that it could cause problems; -Data logged in the function could be exposed to the user;