#!/usr/bin/env node const crypto = require('crypto'); const fetch = (...args) => import('node-fetch').then(({default: fetch}) => fetch(...args)); // Ta configuration const config = { DO_ACCESS_KEY: 'DO801MU8BZBB89LLK4FN', DO_SECRET_KEY: 'rfKPjampdpUCYhn02XrKg6IWKmqebjg9HQTGxNLzJQY', DO_REGION: 'fra1', DO_ENDPOINT: 'https://autocollant.fra1.digitaloceanspaces.com', DO_CONTENT_PATH: 'Class_generator/ContentMe' }; function sha256(message) { return crypto.createHash('sha256').update(message, 'utf8').digest('hex'); } function hmacSha256(key, message) { return crypto.createHmac('sha256', key).update(message, 'utf8').digest(); } async function generateAWSSignature(method, url) { const now = new Date(); const dateStamp = now.toISOString().slice(0, 10).replace(/-/g, ''); const timeStamp = now.toISOString().slice(0, 19).replace(/[-:]/g, '') + 'Z'; const urlObj = new URL(url); const host = urlObj.hostname; const canonicalUri = urlObj.pathname; const canonicalQueryString = urlObj.search ? urlObj.search.slice(1) : ''; const canonicalHeaders = `host:${host}\nx-amz-date:${timeStamp}\n`; const signedHeaders = 'host;x-amz-date'; const payloadHash = method === 'GET' ? sha256('') : 'UNSIGNED-PAYLOAD'; const canonicalRequest = [ method, canonicalUri, canonicalQueryString, canonicalHeaders, signedHeaders, payloadHash ].join('\n'); const algorithm = 'AWS4-HMAC-SHA256'; const credentialScope = `${dateStamp}/${config.DO_REGION}/s3/aws4_request`; const canonicalRequestHash = sha256(canonicalRequest); const stringToSign = [ algorithm, timeStamp, credentialScope, canonicalRequestHash ].join('\n'); const kDate = hmacSha256('AWS4' + config.DO_SECRET_KEY, dateStamp); const kRegion = hmacSha256(kDate, config.DO_REGION); const kService = hmacSha256(kRegion, 's3'); const kSigning = hmacSha256(kService, 'aws4_request'); const signature = hmacSha256(kSigning, stringToSign).toString('hex'); const authorization = `${algorithm} Credential=${config.DO_ACCESS_KEY}/${credentialScope}, SignedHeaders=${signedHeaders}, Signature=${signature}`; return { 'Authorization': authorization, 'X-Amz-Date': timeStamp, 'X-Amz-Content-Sha256': payloadHash }; } async function testDigitalOceanFetch() { console.log('🚀 Test DigitalOcean avec node-fetch\n'); const testUrl = `${config.DO_ENDPOINT}/${config.DO_CONTENT_PATH}/english-class-demo.json`; console.log(`🎯 URL: ${testUrl}`); try { const headers = await generateAWSSignature('GET', testUrl); console.log('🔐 Headers générés:', JSON.stringify(headers, null, 2)); console.log('\n🌐 Requête fetch...'); const response = await fetch(testUrl, { method: 'GET', headers: headers }); console.log(`📡 Status: ${response.status} ${response.statusText}`); console.log(`📝 Headers response:`, Object.fromEntries(response.headers.entries())); if (response.ok) { const content = await response.text(); console.log(`✅ SUCCÈS ! Contenu (${content.length} chars):`); console.log(content.substring(0, 500) + '...'); } else { const errorText = await response.text(); console.log(`❌ Erreur: ${errorText}`); } } catch (error) { console.error(`💥 Erreur fetch: ${error.message}`); console.error(error.stack); } } // Lancer le test testDigitalOceanFetch();