Access Control Logic (ACL) — the rules and reasoning that determine who is allowed to access which resources and under what conditions.
When registering a model, you can specify if the model is owned by a user:
const models: Models = {
car: {
name: 'car',
schema: sCar,
// Model is owned by a user
isOwned: true,
}
};This will automatically add an ownerId field to the model table, and enforce ACL rules so only the owner of a car can read or modify it.
If you have added an authenticator to the app, the isOwned property will default to true for all models.
In JS20 ACL is automatically built in. This means - if your model is marked as isOwned: true, the framework will always append where ownerId === user.id to any queries. To modify an owned item, the endpoint must be marked as isLoggedIn: true as well.
You can now create endpoints that write & read models. These endpoints automatically enforce ACL rules based on whether the user is logged in.
app.addEndpoint({
path: '/cars',
method: 'POST',
inputSchema: sCar,
outputSchema: Schema.withInstance(sCar),
//Only logged in users can create cars
isLoggedIn: true,
run: async (system, input) => {
// ownerId automatically set to user.id
return system.models.car.create(input);
}
});We can safely forward the provided user input. JS20 will take care of everything. Under the hood, it does:
/*
Before running action:
1. Make sure user is logged in (because isLoggedIn: true)
2. Validate all input by the inputSchema
*/
run: async (system, input) => {
/*
When calling car.create():
3. Safely sanitize the input so no illegal chars
4. Create a new database item with the current user as owner
5. Fetch the newly created item
6. Validate & sanitize data by the outputSchema and ensure user has the right to access it
7. Return the newly created item
*/
return system.models.car.create(input);
}We can also call other read/write operations:
system.models.car.getById(id);
system.models.car.updateById(id, data);
system.models.car.deleteById(id);