Class_generator/test-aws-signature.js
StillHammer fe7153d28b Fix compatibility system and improve UX
- Add intelligent content-game compatibility system with visual badges
- Fix Adventure Reader to work with Dragon's Pearl content structure
- Implement multi-column games grid for faster navigation
- Add pronunciation display for Chinese vocabulary and sentences
- Fix navigation breadcrumb to show proper hierarchy (Home > Levels > Content)
- Add back buttons to all navigation pages
- Improve JSONContentLoader to preserve story structure
- Add comprehensive debugging and diagnostic tools

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-18 19:29:21 +08:00

147 lines
4.8 KiB
JavaScript

#!/usr/bin/env node
// Test de signature AWS pour DigitalOcean Spaces
const crypto = require('crypto');
// Configuration avec ta clé read-only
const config = {
DO_ACCESS_KEY: 'DO801XTYPE968NZGAQM3',
DO_SECRET_KEY: 'rfKPjampdpUCYhn02XrKg6IWKmqebjg9HQTGxNLzJQY',
DO_REGION: 'fra1',
DO_ENDPOINT: 'https://autocollant.fra1.digitaloceanspaces.com',
DO_CONTENT_PATH: 'Class_generator/ContentMe'
};
// Fonction de hash SHA256
function sha256(message) {
return crypto.createHash('sha256').update(message, 'utf8').digest('hex');
}
// Fonction HMAC SHA256
function hmacSha256(key, message) {
return crypto.createHmac('sha256', key).update(message, 'utf8').digest();
}
// Génération de la signature AWS V4
async function generateAWSSignature(method, url) {
const accessKey = config.DO_ACCESS_KEY;
const secretKey = config.DO_SECRET_KEY;
const region = config.DO_REGION;
const service = 's3';
const now = new Date();
const dateStamp = now.toISOString().slice(0, 10).replace(/-/g, '');
const timeStamp = now.toISOString().slice(0, 19).replace(/[-:]/g, '') + 'Z';
console.log(`🕐 Timestamp: ${timeStamp}`);
console.log(`📅 Date: ${dateStamp}`);
// Parse URL
const urlObj = new URL(url);
const host = urlObj.hostname;
const canonicalUri = urlObj.pathname || '/';
const canonicalQueryString = urlObj.search ? urlObj.search.slice(1) : '';
console.log(`🌐 Host: ${host}`);
console.log(`📍 URI: ${canonicalUri}`);
console.log(`❓ Query: ${canonicalQueryString}`);
// Canonical headers
const canonicalHeaders = `host:${host}\nx-amz-date:${timeStamp}\n`;
const signedHeaders = 'host;x-amz-date';
console.log(`📝 Canonical headers:\n${canonicalHeaders}`);
// Create canonical request
const payloadHash = method === 'GET' ? sha256('') : 'UNSIGNED-PAYLOAD';
const canonicalRequest = [
method,
canonicalUri,
canonicalQueryString,
canonicalHeaders,
signedHeaders,
payloadHash
].join('\n');
console.log(`📋 Canonical request:\n${canonicalRequest}`);
console.log(`🔢 Payload hash: ${payloadHash}`);
// Create string to sign
const algorithm = 'AWS4-HMAC-SHA256';
const credentialScope = `${dateStamp}/${region}/${service}/aws4_request`;
const canonicalRequestHash = sha256(canonicalRequest);
const stringToSign = [
algorithm,
timeStamp,
credentialScope,
canonicalRequestHash
].join('\n');
console.log(`🔐 String to sign:\n${stringToSign}`);
console.log(`🔗 Canonical request hash: ${canonicalRequestHash}`);
// Calculate signature
const kDate = hmacSha256('AWS4' + secretKey, dateStamp);
const kRegion = hmacSha256(kDate, region);
const kService = hmacSha256(kRegion, service);
const kSigning = hmacSha256(kService, 'aws4_request');
const signature = hmacSha256(kSigning, stringToSign).toString('hex');
console.log(`✍️ Signature: ${signature}`);
// Create authorization header
const authorization = `${algorithm} Credential=${accessKey}/${credentialScope}, SignedHeaders=${signedHeaders}, Signature=${signature}`;
console.log(`🔑 Authorization: ${authorization}`);
return {
'Authorization': authorization,
'X-Amz-Date': timeStamp,
'X-Amz-Content-Sha256': payloadHash
};
}
// Test avec fetch
async function testDigitalOceanAccess() {
console.log('🚀 Test d\'accès DigitalOcean Spaces avec signature AWS\n');
const testUrl = `${config.DO_ENDPOINT}/${config.DO_CONTENT_PATH}/greetings-basic.json`;
console.log(`🎯 URL de test: ${testUrl}\n`);
try {
const headers = await generateAWSSignature('GET', testUrl);
console.log('\n📦 Headers finaux:');
console.log(JSON.stringify(headers, null, 2));
// Test avec node-fetch si disponible
try {
const fetch = require('node-fetch');
console.log('\n🌐 Test avec node-fetch...');
const response = await fetch(testUrl, {
method: 'GET',
headers: headers
});
console.log(`📡 Status: ${response.status} ${response.statusText}`);
if (response.ok) {
const content = await response.text();
console.log(`✅ Succès ! Contenu (${content.length} chars): ${content.substring(0, 200)}...`);
} else {
const errorText = await response.text();
console.log(`❌ Erreur: ${errorText}`);
}
} catch (fetchError) {
console.log('⚠️ node-fetch non disponible, test signature seulement');
console.log('✅ Signature générée avec succès !');
}
} catch (error) {
console.error(`❌ Erreur: ${error.message}`);
}
}
// Lancer le test
testDigitalOceanAccess();