# NG Error Tracker

**NG Error Tracker** is an Angular package that securely captures and sends error logs to a configurable endpoint. It encrypts logs before sending, avoids duplicates, and temporarily stores logs in `localStorage` if the connection is unavailable.

## 📌 Features

- 🚀 **Automatic error capturing** in Angular
- 🔐 **AES-256-GCM + RSA-OAEP-SHA-256 encryption** of logs before sending
- 🔄 **Prevents duplicates** and reduces log spam
- 💾 **Local storage** of logs when offline, auto-retries later
- ⏳ **Batch sending every 30 seconds** if new errors arrive
- 🔍 **User action tracking** before an error occurs

---

## 📦 Installation

```sh
npm install ng-error-tracker
```

---

## 🚀 Usage in Angular

### 1️⃣ **Import and Configure in `main.ts`**

```typescript
import { HTTP_INTERCEPTORS, provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';
import { provideErrorTracker, ErrorLoggerInterceptor } from 'ng-error-tracker';

bootstrapApplication(AppComponent, {
  providers: [
    provideHttpClient(withInterceptorsFromDi()),
    
    { provide: HTTP_INTERCEPTORS, useClass: ErrorLoggerInterceptor, multi: true },
    provideErrorTracker({
      enableLogging: true,
      apiUrl: 'https://my-api-logs.com/errors',
      apiKey: 'abcdef-12345',
      publicKeyUrl: 'https://my-api-logs.com/public-key',
      appName: 'MyApp',
      appEnv: 'production',
      appBuildId: 'abcdef123456'
    }),
  ],
});
```

### 2️⃣ **Capture Custom Errors**

If you want to manually capture errors:

```typescript
import { ErrorLoggerService } from 'ng-error-tracker';

constructor(private errorLogger: ErrorLoggerService) {}

try {
  throw new Error('Testing error');
} catch (error) {
  this.errorLogger.handleError(error);
}
```

---

## 🔑 Configuration Parameters

Below is a refined parameters table that clearly explains when a public key is required, which RSA format is expected (DER), and other details for an AES-256-GCM + RSA-OAEP-SHA-256 encryption scenario. In short, **AES-256-GCM** handles large data, and **RSA-OAEP-SHA-256** secures the AES key. You must provide a public key if you want encryption.

| Option            | Description                                                                                                                                                                                                                                                                                                                                      | Required                                                   |
|-------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------|
| **enableLogging** | Enables or disables logging (boolean).                                                                                                                                                                                                                                                                                                           | **Yes**                                                    |
| **apiUrl**        | Endpoint where the logs are sent.                                                                                                                                                                                                                                                                                                                | **Yes**                                                    |
| **apiKey**        | Authentication key for the API.                                                                                                                                                                                                                                                                                                                  | **No**                                                     |
| **publicKey**     | RSA public key (BASE64(DER format)) to encrypt logs. If this is not provided, you must specify `publicKeyUrl`.                                                                                                                                                                                                                                   | **No**<br>(**Required** if `publicKeyUrl` is not provided) |
| **publicKeyUrl**  | URL returning your RSA public key in BASE64(DER format). The library fetches it to encrypt logs. If omitted, you must directly supply `publicKey`.                                                                                                                                                                                               | **No**                                                     |
| **appName**       | Name of the application generating the logs.                                                                                                                                                                                                                                                                                                     | **Yes**                                                    |
| **appEnv**        | Environment or build configuration (e.g., dev, staging, prod).                                                                                                                                                                                                                                                                                   | **Yes**                                                    |
| **appBuildId**    | Unique build identifier for the application. If not provided, the library will attempt to generate it automatically using a hash of application main file. In web environments, it will fetch main file and extract portions of its content for hashing. If none of these methods succeed, a default value of `'unknown-build-id'` will be used. | **No (Auto-generated if omitted)**                         |
## Notes

1. **AES-256-GCM + RSA-OAEP-SHA-256**:  
   The library encrypts large logs with **AES-256-GCM** to avoid the “Message too long for RSA” limitation.  
   It then encrypts the AES key itself using an **RSA public key** (via Web Crypto API).

2. **DER Format**:  
   The RSA public key must be a DER encoding.

3. **`publicKey` vs `publicKeyUrl`**:
- If you already have the public key as a string, use `publicKey`.
- If you prefer to host the key at an endpoint, specify `publicKeyUrl`.
- You **must** provide at least one if you want encryption.

4. **If Neither is Provided**:  
   Encryption will not happen (unless your code enforces it). However, the library can still log errors in plaintext. Ensure you handle that scenario according to your security requirements.
---

## 🔒 Security and Privacy

- Removes sensitive data such as emails, IDs, and phone numbers before sending logs.
- Logs are encrypted via **AES-256-GCM + RSA-OAEP-SHA-256** before being sent to the API.

---

## ❓ FAQs

**🔹 What if the logging API is unavailable?**  
➡️ The logs are stored in `localStorage` and resent when the app restarts or upon navigation.

**🔹 How do I disable log capturing?**  
➡️ Set `enableLogging: false` in the initialization provider.

**🔹 Can I send logs manually?**  
➡️ Yes, just call `this.errorLogger.handleError(error)` from anywhere in your code.

---

## 📝 License

This project is licensed under the **MIT** License. See the `LICENSE` file for more information.

---

🚀 **Developed by Dyango Rodríguez** | 💡 *Contributions and improvements welcome.*

