- 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>
102 lines
3.0 KiB
JavaScript
102 lines
3.0 KiB
JavaScript
#!/usr/bin/env node
|
|
|
|
const crypto = require('crypto');
|
|
const { spawn } = require('child_process');
|
|
|
|
// Configuration
|
|
const config = {
|
|
DO_ACCESS_KEY: 'DO801MU8BZBB89LLK4FN',
|
|
DO_SECRET_KEY: 'rfKPjampdpUCYhn02XrKg6IWKmqebjg9HQTGxNLzJQY',
|
|
DO_REGION: 'fra1'
|
|
};
|
|
|
|
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 generateSignatureAndTest() {
|
|
const testUrl = 'https://autocollant.fra1.digitaloceanspaces.com/Class_generator/ContentMe/greetings-basic.json';
|
|
const method = 'GET';
|
|
|
|
// Timestamp actuel
|
|
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(`🕐 Génération signature pour: ${timeStamp}`);
|
|
|
|
// Parse URL
|
|
const urlObj = new URL(testUrl);
|
|
const host = urlObj.hostname;
|
|
const canonicalUri = urlObj.pathname;
|
|
|
|
// Headers canoniques
|
|
const canonicalHeaders = `host:${host}\nx-amz-date:${timeStamp}\n`;
|
|
const signedHeaders = 'host;x-amz-date';
|
|
|
|
// Requête canonique
|
|
const payloadHash = sha256('');
|
|
const canonicalRequest = [
|
|
method,
|
|
canonicalUri,
|
|
'', // query string
|
|
canonicalHeaders,
|
|
signedHeaders,
|
|
payloadHash
|
|
].join('\n');
|
|
|
|
// String to sign
|
|
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');
|
|
|
|
// Signature
|
|
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}`;
|
|
|
|
console.log(`🔑 Authorization: ${authorization}`);
|
|
|
|
// Test avec curl
|
|
const curlArgs = [
|
|
'-X', 'GET',
|
|
testUrl,
|
|
'-H', `Authorization: ${authorization}`,
|
|
'-H', `X-Amz-Date: ${timeStamp}`,
|
|
'-H', `X-Amz-Content-Sha256: ${payloadHash}`,
|
|
'-H', 'User-Agent: test-client',
|
|
'-i'
|
|
];
|
|
|
|
console.log('🌐 Test curl...');
|
|
|
|
const curl = spawn('curl', curlArgs);
|
|
|
|
curl.stdout.on('data', (data) => {
|
|
console.log(data.toString());
|
|
});
|
|
|
|
curl.stderr.on('data', (data) => {
|
|
console.error(data.toString());
|
|
});
|
|
|
|
curl.on('close', (code) => {
|
|
console.log(`✅ Curl terminé avec code: ${code}`);
|
|
});
|
|
}
|
|
|
|
generateSignatureAndTest(); |