# Validating file signature

Before ending this section and going to the actual file logic, let's just make a final improvement to validation. Even though we are validating a file's extension, someone may create a malicious file and manually alter its extension, and our system would accept it. Obviously this is not interesting at all. We may mitigate this problem by also validating the **file signature** (also known as **magic number** or **magic bytes**), which corresponds to a file's first bytes, identifying its type. They remain unchanged even if the extension is manually altered, for example.

To begin, let's install the library [magic-bytes](https://www.npmjs.com/package/magic-bytes.js), which allows to obtain a file's signature.

```sh
yarn add magic-bytes.js
```

What we'll do now is to create a new, custom <mark style="color:blue;">`FileValidator`</mark>. This time, it will be created from scratch. So, begin by creating the file <mark style="color:purple;">validators</mark>/<mark style="color:purple;">file-signature.validator</mark>. Here, we should create a class that extends the <mark style="color:blue;">`FileValidator`</mark>. We then get this class signature:

```typescript
export class FileSignatureValidator extends FileValidator {}
```

First, let's implement the method that generates the error message.

```typescript
buildErrorMessage() {
  return 'Validation failed (file type does not match file signature)';
}
```

Then, import the **magic-bytes** library like the following (requires manual importing):

```typescript
import magicBytes from 'magic-bytes.js';
```

Now, implement the <mark style="color:blue;">`isValid()`</mark> method. Here, we perform these steps:

* The <mark style="color:blue;">`fileSignatures`</mark> are obtained from the file's <mark style="color:blue;">`buffer`</mark> (More than one signature may be present, that's why an array is returned)
* It is checked if any signature is obtained, as some file types <mark style="color:red;">don't</mark> have one, such as .**txt** files
* It is verified if the file's signature matches its extension

```typescript
isValid(file: File) {
  const fileSignatures = magicBytes(file.buffer).map((file) => file.mime);
  if (!fileSignatures.length) return false;

  const isMatch = fileSignatures.includes(file.mimetype);
  if (!isMatch) return false;

  return true;
}
```

We have concluded our validator. Go back to the <mark style="color:blue;">`createFileValidators()`</mark> function and include it in its return.

```typescript
new FileSignatureValidator()
```

However, notice that it requires an options object, even if no options will be used. This is due to the <mark style="color:blue;">`FileValidator`</mark> constructor. To avoid instantiating it like this, we may go back to the <mark style="color:purple;">file-signature.validator</mark> file and define a constructor with no parameters that simply calls the constructor of the superclass while passing this empty options object.

```typescript
constructor() {
  super({});
}
```

Excellent, now if the file's extension is accepted, its signature will also be checked to determine if it matches the extension.

<mark style="color:green;">**Commit**</mark> - Validating file signature
