259
API.md
Archivo normal
259
API.md
Archivo normal
@@ -0,0 +1,259 @@
|
||||
# API Documentation
|
||||
|
||||
## Base URL
|
||||
|
||||
```
|
||||
http://localhost:3000/api
|
||||
```
|
||||
|
||||
## Endpoints
|
||||
|
||||
### 1. Search / Generate Hashes
|
||||
|
||||
**Endpoint**: `POST /api/search`
|
||||
|
||||
**Description**: Search for a hash in the database or generate hashes from plaintext.
|
||||
|
||||
#### Request
|
||||
|
||||
**Headers**:
|
||||
```
|
||||
Content-Type: application/json
|
||||
```
|
||||
|
||||
**Body**:
|
||||
```json
|
||||
{
|
||||
"query": "string" // Required: Hash or plaintext to search/generate
|
||||
}
|
||||
```
|
||||
|
||||
#### Response Examples
|
||||
|
||||
##### Case 1: Hash Found in Database
|
||||
|
||||
**Request**:
|
||||
```json
|
||||
{
|
||||
"query": "5f4dcc3b5aa765d61d8327deb882cf99"
|
||||
}
|
||||
```
|
||||
|
||||
**Response** (200 OK):
|
||||
```json
|
||||
{
|
||||
"found": true,
|
||||
"hashType": "md5",
|
||||
"hash": "5f4dcc3b5aa765d61d8327deb882cf99",
|
||||
"results": [
|
||||
{
|
||||
"plaintext": "password",
|
||||
"hashes": {
|
||||
"md5": "5f4dcc3b5aa765d61d8327deb882cf99",
|
||||
"sha1": "5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8",
|
||||
"sha256": "5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8",
|
||||
"sha512": "b109f3bbbc244eb82441917ed06d618b9008dd09b3befd1b5e07394c706a8bb980b1d7785e5976ec049b46df5f1326af5a2ea6d103fd07c95385ffab0cacbc86"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
##### Case 2: Hash Not Found in Database
|
||||
|
||||
**Request**:
|
||||
```json
|
||||
{
|
||||
"query": "abc123def456789abc123def456789ab"
|
||||
}
|
||||
```
|
||||
|
||||
**Response** (200 OK):
|
||||
```json
|
||||
{
|
||||
"found": false,
|
||||
"hashType": "md5",
|
||||
"hash": "abc123def456789abc123def456789ab",
|
||||
"message": "Hash not found in database"
|
||||
}
|
||||
```
|
||||
|
||||
##### Case 3: Plaintext Input (Hash Generation)
|
||||
|
||||
**Request**:
|
||||
```json
|
||||
{
|
||||
"query": "mypassword"
|
||||
}
|
||||
```
|
||||
|
||||
**Response** (200 OK):
|
||||
```json
|
||||
{
|
||||
"found": true,
|
||||
"isPlaintext": true,
|
||||
"plaintext": "mypassword",
|
||||
"hashes": {
|
||||
"md5": "34819d7beeabb9260a5c854bc85b3e44",
|
||||
"sha1": "91dfd9ddb4198affc5c194cd8ce6d338fde470e2",
|
||||
"sha256": "89e01536ac207279409d4de1e5253e01f4a1769e696db0d6062ca9b8f56767c8",
|
||||
"sha512": "a336f671080fbf4f2a230f313560ddf0d0c12dfcf1741e49e8722a234673037dc493e1c04ce89532b85b8d5c8e7baf1e532c67a89b5c4c8c1e98ba1e14c64e4e"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Note: When plaintext is provided, it is automatically indexed in Elasticsearch for future lookups.
|
||||
|
||||
#### Error Responses
|
||||
|
||||
**400 Bad Request** - Missing or invalid query parameter:
|
||||
```json
|
||||
{
|
||||
"error": "Query parameter is required"
|
||||
}
|
||||
```
|
||||
|
||||
**500 Internal Server Error** - Server or Elasticsearch error:
|
||||
```json
|
||||
{
|
||||
"error": "Internal server error",
|
||||
"details": "Connection refused"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. Health Check
|
||||
|
||||
**Endpoint**: `GET /api/health`
|
||||
|
||||
**Description**: Check the health of the application and Elasticsearch connection.
|
||||
|
||||
#### Request
|
||||
|
||||
No parameters required.
|
||||
|
||||
#### Response
|
||||
|
||||
**Success** (200 OK):
|
||||
```json
|
||||
{
|
||||
"status": "ok",
|
||||
"elasticsearch": {
|
||||
"cluster": "elasticsearch",
|
||||
"status": "green"
|
||||
},
|
||||
"index": {
|
||||
"exists": true,
|
||||
"name": "hasher",
|
||||
"stats": {
|
||||
"documentCount": 1542,
|
||||
"indexSize": 524288
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Elasticsearch cluster status values**:
|
||||
- `green`: All primary and replica shards are active
|
||||
- `yellow`: All primary shards are active, but not all replicas
|
||||
- `red`: Some primary shards are not active
|
||||
|
||||
**Error** (503 Service Unavailable):
|
||||
```json
|
||||
{
|
||||
"status": "error",
|
||||
"error": "Connection refused to Elasticsearch"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Hash Type Detection
|
||||
|
||||
The API automatically detects hash types based on length and format:
|
||||
|
||||
| Hash Type | Length (hex chars) | Pattern |
|
||||
|-----------|-------------------|---------|
|
||||
| MD5 | 32 | `^[a-f0-9]{32}$` |
|
||||
| SHA1 | 40 | `^[a-f0-9]{40}$` |
|
||||
| SHA256 | 64 | `^[a-f0-9]{64}$` |
|
||||
| SHA512 | 128 | `^[a-f0-9]{128}$` |
|
||||
| Bcrypt | 60 | `^\$2[abxy]\$` |
|
||||
|
||||
Hashes are case-insensitive.
|
||||
|
||||
---
|
||||
|
||||
## Usage Examples
|
||||
|
||||
### cURL
|
||||
|
||||
**Search for a hash**:
|
||||
```bash
|
||||
curl -X POST http://localhost:3000/api/search \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"query":"5f4dcc3b5aa765d61d8327deb882cf99"}'
|
||||
```
|
||||
|
||||
**Generate hashes**:
|
||||
```bash
|
||||
curl -X POST http://localhost:3000/api/search \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"query":"password"}'
|
||||
```
|
||||
|
||||
**Health check**:
|
||||
```bash
|
||||
curl http://localhost:3000/api/health
|
||||
```
|
||||
|
||||
### JavaScript (fetch)
|
||||
|
||||
```javascript
|
||||
// Search for a hash
|
||||
const response = await fetch('http://localhost:3000/api/search', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ query: '5f4dcc3b5aa765d61d8327deb882cf99' })
|
||||
});
|
||||
const data = await response.json();
|
||||
console.log(data);
|
||||
```
|
||||
|
||||
### Python (requests)
|
||||
|
||||
```python
|
||||
import requests
|
||||
|
||||
# Search for a hash
|
||||
response = requests.post(
|
||||
'http://localhost:3000/api/search',
|
||||
json={'query': '5f4dcc3b5aa765d61d8327deb882cf99'}
|
||||
)
|
||||
print(response.json())
|
||||
|
||||
# Health check
|
||||
health = requests.get('http://localhost:3000/api/health')
|
||||
print(health.json())
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Rate Limiting
|
||||
|
||||
Currently, there is no rate limiting implemented. For production use, consider implementing rate limiting at the API gateway or application level.
|
||||
|
||||
## CORS
|
||||
|
||||
The API accepts requests from any origin by default. For production deployment, configure CORS appropriately in your Next.js configuration.
|
||||
|
||||
---
|
||||
|
||||
## Notes
|
||||
|
||||
- All timestamps are in ISO 8601 format
|
||||
- The API automatically creates the Elasticsearch index if it doesn't exist
|
||||
- Plaintext searches are automatically indexed for future lookups
|
||||
- Searches are case-insensitive
|
||||
- Hashes must be valid hexadecimal strings
|
||||
Referencia en una nueva incidencia
Block a user