---
description: Some more checks to ensure that users can do only what they're allowed to.
---

# More authorization checks

To finish the topic of authorization, let's just add some more checks. Specifically:

* A <mark style="color:blue;">`user`</mark> can receive an <mark style="color:blue;">`update()`</mark>, <mark style="color:blue;">`remove()`</mark> or <mark style="color:blue;">`recover()`</mark> only from himself
* An <mark style="color:blue;">`order`</mark> can be paid only by the <mark style="color:blue;">`user`</mark> who owns it
* A regular <mark style="color:blue;">`user`</mark> can only **soft** delete his account

First, go to the <mark style="color:blue;">`UsersController`</mark> and, in the three aforementioned routes, extract the <mark style="color:blue;">`user`</mark> from the <mark style="color:blue;">`request`</mark> and pass it along to the service method. Remember to also add this parameter to the namesake methods in the service.

```typescript
@User() user: RequestUser,
```

{% hint style="info" %}
You may call it <mark style="color:blue;">`currentUser`</mark> in the service, to prevent a name collision.
{% endhint %}

Now, before going to the service, let's create the file <mark style="color:purple;">auth</mark>/<mark style="color:purple;">util</mark>/<mark style="color:purple;">authorization.util</mark>. Here, we'll create a function to compare the <mark style="color:blue;">`id`</mark> of the current <mark style="color:blue;">`user`</mark> with a required <mark style="color:blue;">`id`</mark>. If they're not the same, access will be denied. The purpose of this function is to verify if a <mark style="color:blue;">`user`</mark> is acting on himself or on something which he owns.

```typescript
export const compareUserId = (userId: number, requiredId: number) => {
  if (userId !== requiredId) {
    throw new ForbiddenException('Forbidden resource');
  }
};
```

Then, in the <mark style="color:blue;">`UsersService`</mark>, at the start of those three methods, we'll simply check if the <mark style="color:blue;">`user`</mark> is an <mark style="color:blue;">`ADMIN`</mark>, in which case he should have unrestricted access. If not, we then compare his <mark style="color:blue;">`id`</mark>.

```typescript
if (currentUser.role !== Role.ADMIN) {
  compareUserId(currentUser.id, id);
}
```

In the case of making a <mark style="color:blue;">`payment`</mark>, we have to check if the <mark style="color:blue;">`order`</mark> is owned by the <mark style="color:blue;">`user`</mark> who is paying for it. In the <mark style="color:blue;">`payOrder()`</mark> route in the <mark style="color:blue;">`PaymentsController`</mark>, we shall perform the same step done just above. That is, to extract the <mark style="color:blue;">`user`</mark> from the <mark style="color:blue;">`request`</mark> and pass it along to the method call below, and also add this parameter to the method in the service.

In the <mark style="color:blue;">`PaymentsService`</mark>, when fetching the <mark style="color:blue;">`order`</mark>, also bring its <mark style="color:blue;">`customer`</mark> in the <mark style="color:blue;">`relations`</mark> to be able to make the comparison. Then, make it after checking if the <mark style="color:blue;">`order`</mark> exists.

```typescript
compareUserId(currentUser.id, order.customer.id);
```

Finally, let's enforce that a regular <mark style="color:blue;">`user`</mark> can only **soft** delete his account. In the <mark style="color:blue;">`remove()`</mark> method in the <mark style="color:blue;">`UsersService`</mark>, we already check if the <mark style="color:blue;">`user`</mark> is not an <mark style="color:blue;">`ADMIN`</mark>. There, after comparing his <mark style="color:blue;">`id`</mark>, check the deletion type.

```typescript
if (!soft) {
  throw new ForbiddenException('Forbidden resource');
}
```

<mark style="color:green;">**Commit**</mark> - Validating user authorization inside service

The main content of this module has been concluded. We'll now just see a last feature and a fix.
