4NK_vault/docs/sdk-documentation.md
4NK Dev fcb15afb88 Initial commit: 4NK Vault API with quantum-resistant encryption
- API server with ChaCha20-Poly1305 encryption
- TypeScript SDK client with full functionality
- Complete documentation in docs/
- Environment variable processing with composite variables
- HTTPS-only API on port 6666
- Storage structure for configuration files
- Tests and examples included

Features:
- Quantum-resistant encryption (ChaCha20-Poly1305)
- Variable substitution from .env files
- Comprehensive TypeScript SDK
- Full API documentation and specifications
- Deployment guides and security model
2025-09-29 21:02:18 +00:00

636 lines
14 KiB
Markdown

# SDK Client TypeScript - Documentation complète
## Vue d'ensemble
Le SDK Client TypeScript pour l'API Vault 4NK fournit une interface type-safe et moderne pour interagir avec l'API de stockage sécurisé. Il inclut le déchiffrement côté client, la gestion d'erreurs avancée, et des utilitaires cryptographiques.
## Installation
### NPM
```bash
npm install @4nk/vault-sdk
```
### Depuis les sources
```bash
git clone https://git.4nkweb.com/4nk/vault-sdk.git
cd vault-sdk
npm install
npm run build
```
## Configuration
### Importation de base
```typescript
import { VaultClient, createVaultClient, VaultCrypto } from '@4nk/vault-sdk';
```
### Création d'un client
#### Méthode simple
```typescript
const client = createVaultClient(
'https://vault.4nkweb.com:6666',
'quantum_resistant_demo_key_32byt'
);
```
#### Méthode avancée
```typescript
const client = new VaultClient(
{
baseUrl: 'https://vault.4nkweb.com:6666',
verifySsl: false, // Pour les certificats auto-signés
timeout: 15000, // 15 secondes
},
'quantum_resistant_demo_key_32byt'
);
```
## API Reference
### Classe VaultClient
#### Constructeur
```typescript
constructor(config: VaultConfig, decryptionKey: string)
```
**Paramètres** :
- `config` : Configuration du client
- `decryptionKey` : Clé de déchiffrement (32 bytes exactement)
**Configuration** :
```typescript
interface VaultConfig {
baseUrl: string; // URL de base de l'API
verifySsl?: boolean; // Validation SSL (défaut: true)
timeout?: number; // Timeout en ms (défaut: 30000)
}
```
#### Méthodes
##### `getFile(env: string, filePath: string): Promise<VaultFile>`
Récupère et déchiffre un fichier depuis l'API.
**Paramètres** :
- `env` : Environnement (ex: "dev", "prod")
- `filePath` : Chemin du fichier relatif
**Retour** :
```typescript
interface VaultFile {
content: string; // Contenu déchiffré
filename: string; // Nom du fichier
size: number; // Taille en caractères
encrypted: boolean; // Était chiffré
algorithm?: string; // Algorithme utilisé
}
```
**Exemple** :
```typescript
try {
const file = await client.getFile('dev', 'bitcoin/bitcoin.conf');
console.log(`Fichier: ${file.filename}`);
console.log(`Taille: ${file.size} caractères`);
console.log(`Contenu: ${file.content}`);
} catch (error) {
console.error('Erreur:', error.message);
}
```
##### `getFiles(requests: FileRequest[]): Promise<VaultFile[]>`
Récupère plusieurs fichiers en parallèle.
**Paramètres** :
```typescript
interface FileRequest {
env: string;
filePath: string;
}
```
**Exemple** :
```typescript
const files = await client.getFiles([
{ env: 'dev', filePath: 'bitcoin/bitcoin.conf' },
{ env: 'dev', filePath: 'tor/torrc' },
{ env: 'dev', filePath: 'sdk_relay/sdk_relay.conf' }
]);
files.forEach(file => {
console.log(`${file.filename}: ${file.size} caractères`);
});
```
##### `health(): Promise<VaultHealth>`
Vérifie l'état de santé de l'API.
**Retour** :
```typescript
interface VaultHealth {
status: string; // "healthy" ou "unhealthy"
service: string; // Nom du service
encryption: string; // Type de chiffrement
algorithm: string; // Algorithme utilisé
}
```
**Exemple** :
```typescript
const health = await client.health();
console.log(`Statut: ${health.status}`);
console.log(`Chiffrement: ${health.encryption}`);
```
##### `info(): Promise<VaultInfo>`
Récupère les informations sur l'API.
**Retour** :
```typescript
interface VaultInfo {
name: string; // Nom de l'API
version: string; // Version
domain: string; // Domaine
port: number; // Port
protocol: string; // Protocole
encryption: string; // Type de chiffrement
endpoints: Record<string, string>; // Endpoints disponibles
}
```
**Exemple** :
```typescript
const info = await client.info();
console.log(`API: ${info.name} v${info.version}`);
console.log(`Domaine: ${info.domain}:${info.port}`);
```
##### `ping(): Promise<boolean>`
Teste la connectivité à l'API.
**Retour** : `true` si connecté, `false` sinon
**Exemple** :
```typescript
const isConnected = await client.ping();
if (isConnected) {
console.log('✅ API accessible');
} else {
console.log('❌ API inaccessible');
}
```
##### `searchFiles(env: string, pattern?: RegExp): Promise<string[]>`
Recherche des fichiers par pattern (non implémenté côté serveur).
**Note** : Cette méthode retourne toujours un tableau vide car l'endpoint de recherche n'est pas encore implémenté côté serveur.
### Classe VaultCrypto
Utilitaires pour la gestion des clés de chiffrement.
#### `generateKey(): string`
Génère une clé de déchiffrement aléatoire de 32 bytes.
**Retour** : Clé de 32 caractères UTF-8
**Exemple** :
```typescript
const randomKey = VaultCrypto.generateKey();
console.log(`Clé générée: ${randomKey.substring(0, 10)}...`);
```
#### `hashToKey(password: string): string`
Dérive une clé de 32 bytes depuis un mot de passe.
**Paramètres** :
- `password` : Mot de passe source
**Retour** : Clé de 32 bytes dérivée avec SHA-256
**Exemple** :
```typescript
const password = 'mon-mot-de-passe-secret';
const derivedKey = VaultCrypto.hashToKey(password);
console.log(`Clé dérivée: ${derivedKey.substring(0, 10)}...`);
```
#### `validateKey(key: string): boolean`
Vérifie qu'une clé fait exactement 32 bytes.
**Paramètres** :
- `key` : Clé à valider
**Retour** : `true` si la clé est valide, `false` sinon
**Exemple** :
```typescript
const key = 'quantum_resistant_demo_key_32byt';
const isValid = VaultCrypto.validateKey(key);
console.log(`Clé valide: ${isValid}`);
```
## Gestion d'erreurs
### Classes d'erreurs
#### VaultApiError
Erreurs liées aux requêtes HTTP vers l'API.
```typescript
class VaultApiError extends Error {
constructor(
message: string,
public statusCode?: number,
public endpoint?: string
);
}
```
**Propriétés** :
- `message` : Message d'erreur
- `statusCode` : Code HTTP d'erreur
- `endpoint` : Endpoint qui a échoué
**Exemple** :
```typescript
try {
await client.getFile('dev', 'fichier-inexistant.conf');
} catch (error) {
if (error instanceof VaultApiError) {
console.error(`Erreur API: ${error.message}`);
console.error(`Code: ${error.statusCode}`);
console.error(`Endpoint: ${error.endpoint}`);
}
}
```
#### VaultDecryptionError
Erreurs liées au déchiffrement des fichiers.
```typescript
class VaultDecryptionError extends Error {
constructor(message: string);
}
```
**Exemple** :
```typescript
try {
const file = await client.getFile('dev', 'config.conf');
} catch (error) {
if (error instanceof VaultDecryptionError) {
console.error(`Erreur de déchiffrement: ${error.message}`);
}
}
```
### Gestion d'erreurs complète
```typescript
async function handleFileRequest(env: string, filePath: string) {
try {
const file = await client.getFile(env, filePath);
return file;
} catch (error) {
if (error instanceof VaultApiError) {
switch (error.statusCode) {
case 404:
console.error(`Fichier non trouvé: ${filePath}`);
break;
case 403:
console.error(`Accès non autorisé: ${filePath}`);
break;
case 500:
console.error(`Erreur serveur pour: ${filePath}`);
break;
default:
console.error(`Erreur API: ${error.message}`);
}
} else if (error instanceof VaultDecryptionError) {
console.error(`Erreur de déchiffrement: ${error.message}`);
} else {
console.error(`Erreur inconnue: ${error.message}`);
}
throw error;
}
}
```
## Exemples d'utilisation
### Exemple basique
```typescript
import { createVaultClient } from '@4nk/vault-sdk';
async function basicExample() {
// Création du client
const client = createVaultClient(
'https://vault.4nkweb.com:6666',
'quantum_resistant_demo_key_32byt'
);
// Test de connectivité
const isConnected = await client.ping();
if (!isConnected) {
throw new Error('Impossible de se connecter à l\'API');
}
// Récupération d'un fichier
const file = await client.getFile('dev', 'bitcoin/bitcoin.conf');
console.log(`Fichier: ${file.filename}`);
console.log(`Taille: ${file.size} caractères`);
console.log(`Contenu: ${file.content.substring(0, 100)}...`);
}
```
### Exemple avancé avec gestion d'erreurs
```typescript
import { VaultClient, VaultApiError, VaultDecryptionError } from '@4nk/vault-sdk';
async function advancedExample() {
const client = new VaultClient(
{
baseUrl: 'https://vault.4nkweb.com:6666',
timeout: 10000,
},
'quantum_resistant_demo_key_32byt'
);
// Informations sur l'API
try {
const info = await client.info();
console.log(`API: ${info.name} v${info.version}`);
} catch (error) {
console.error('Erreur info:', error.message);
}
// Récupération de plusieurs fichiers
const requests = [
{ env: 'dev', filePath: 'bitcoin/bitcoin.conf' },
{ env: 'dev', filePath: 'tor/torrc' },
{ env: 'dev', filePath: 'sdk_relay/sdk_relay.conf' }
];
try {
const files = await client.getFiles(requests);
console.log(`${files.length} fichiers récupérés`);
files.forEach((file, index) => {
console.log(`${index + 1}. ${file.filename}: ${file.size} chars`);
});
} catch (error) {
if (error instanceof VaultApiError) {
console.error(`Erreur API: ${error.statusCode} - ${error.message}`);
} else if (error instanceof VaultDecryptionError) {
console.error(`Erreur de déchiffrement: ${error.message}`);
}
}
}
```
### Exemple avec retry automatique
```typescript
async function retryOperation<T>(
operation: () => Promise<T>,
maxRetries: number = 3,
delay: number = 1000
): Promise<T> {
let lastError: Error;
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
return await operation();
} catch (error) {
lastError = error as Error;
console.log(`Tentative ${attempt}/${maxRetries} échouée: ${lastError.message}`);
if (attempt < maxRetries) {
await new Promise(resolve => setTimeout(resolve, delay));
}
}
}
throw lastError!;
}
// Utilisation
const file = await retryOperation(
() => client.getFile('dev', 'bitcoin/bitcoin.conf'),
3,
500
);
```
## Configuration TypeScript
### tsconfig.json recommandé
```json
{
"compilerOptions": {
"target": "ES2020",
"module": "commonjs",
"lib": ["ES2020", "DOM"],
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"declaration": true,
"sourceMap": true
}
}
```
### Types personnalisés
```typescript
// Extension des types existants
interface CustomVaultFile extends VaultFile {
metadata?: {
lastModified: Date;
checksum: string;
};
}
// Types pour vos applications
interface ConfigFile {
environment: string;
services: string[];
variables: Record<string, string>;
}
```
## Tests
### Tests unitaires avec Jest
```typescript
import { VaultClient, VaultCrypto } from '@4nk/vault-sdk';
describe('VaultClient', () => {
let client: VaultClient;
beforeEach(() => {
client = new VaultClient(
{ baseUrl: 'https://vault.4nkweb.com:6666' },
'quantum_resistant_demo_key_32byt'
);
});
it('devrait récupérer un fichier', async () => {
const file = await client.getFile('dev', 'bitcoin/bitcoin.conf');
expect(file).toBeDefined();
expect(file.filename).toBe('bitcoin.conf');
expect(file.content).toBeTruthy();
});
it('devrait gérer les erreurs 404', async () => {
await expect(client.getFile('dev', 'fichier-inexistant.conf'))
.rejects
.toThrow('Fichier non trouvé');
});
});
```
### Tests d'intégration
```typescript
describe('Intégration API', () => {
it('devrait fonctionner end-to-end', async () => {
const client = createVaultClient(
'https://vault.4nkweb.com:6666',
'quantum_resistant_demo_key_32byt'
);
// Test de santé
const health = await client.health();
expect(health.status).toBe('healthy');
// Test de fichier
const file = await client.getFile('dev', 'bitcoin/bitcoin.conf');
expect(file.content).toContain('bitcoin');
});
});
```
## Performance et optimisation
### Récupération parallèle
```typescript
// ✅ Bon : Récupération parallèle
const files = await client.getFiles(requests);
// ❌ Mauvais : Récupération séquentielle
const files = [];
for (const request of requests) {
const file = await client.getFile(request.env, request.filePath);
files.push(file);
}
```
### Cache local
```typescript
class CachedVaultClient extends VaultClient {
private cache = new Map<string, VaultFile>();
async getFile(env: string, filePath: string): Promise<VaultFile> {
const key = `${env}/${filePath}`;
if (this.cache.has(key)) {
return this.cache.get(key)!;
}
const file = await super.getFile(env, filePath);
this.cache.set(key, file);
return file;
}
}
```
## Dépannage
### Problèmes courants
#### Erreur de clé de déchiffrement
```
Error: La clé de déchiffrement doit faire exactement 32 bytes
```
**Solution** : Vérifiez que votre clé fait exactement 32 caractères UTF-8.
#### Erreur de connectivité
```
Error: fetch failed
```
**Solutions** :
- Vérifiez que l'API est démarrée
- Vérifiez l'URL de base
- Désactivez la validation SSL si nécessaire (`verifySsl: false`)
#### Erreur de déchiffrement
```
VaultDecryptionError: Erreur de déchiffrement
```
**Solutions** :
- Vérifiez que la clé correspond à celle utilisée côté serveur
- Vérifiez que le fichier n'est pas corrompu
### Debug
```typescript
// Activation des logs détaillés
const client = new VaultClient(
{
baseUrl: 'https://vault.4nkweb.com:6666',
timeout: 30000
},
'quantum_resistant_demo_key_32byt'
);
// Test de connectivité
const isConnected = await client.ping();
console.log('Connecté:', isConnected);
// Test d'information
try {
const info = await client.info();
console.log('Info API:', info);
} catch (error) {
console.error('Erreur info:', error);
}
```
## Support
- **Documentation** : [docs/README.md](README.md)
- **API Specification** : [docs/api-specification.md](api-specification.md)
- **Issues** : [Git Issues](https://git.4nkweb.com/4nk/vault-sdk/issues)
- **Email** : sdk-support@4nkweb.com
---
**Version SDK** : 1.0.0
**Compatibilité API** : 1.0.0+