crooked-wire-41853
04/03/2025, 12:26 PMapiRequest(endpoint, method = 'GET', params = {}, body = '', apikey, secret) {
const baseUrl = `${get(this, 'app.proxyEndpoint')}/${this.exoscaleApi}`;
const url = `${baseUrl}/${endpoint}`;
const expires = Math.floor(Date.now() / 1000) + 600; // Expiration time (10 minutes from now)
// Sort query params alphabetically
const sortedParams = Object.keys(params).sort();
const queryString = new URLSearchParams(params).toString();
const queryValues = sortedParams.map((key) => params[key]).join('');
// Ensure body is properly formatted
const requestBody = body ? JSON.stringify(body) : '';
const apiPath = `/v2/${endpoint}`;
// Construct the message to sign (avoiding extra newlines)
const messageParts = [
`${method} ${apiPath}`, // Correct request path (excluding proxy)
requestBody || '', // Ensure empty string instead of null/undefined
queryValues || '', // Ensure empty string if no query params
'', // No signed headers for now
expires.toString(), // Expiration timestamp
];
const message = messageParts.join('\n');
console.log("Message to sign:", JSON.stringify(message, null, 2));
// Convert secret key to Uint8Array
const secretKey = new TextEncoder().encode(secret);
const messageData = new TextEncoder().encode(message);
console.log("secret and messagedata encoded:", secretKey, messageData);
// Compute HMAC using Web Crypto API
return crypto.subtle.importKey(
"raw",
secretKey,
{ name: "HMAC", hash: { name: "SHA-256" } },
false,
["sign"]
).then((cryptoKey) => {
return crypto.subtle.sign("HMAC", cryptoKey, messageData);
}).then((signatureBuffer) => {
// Convert ArrayBuffer to Base64
const signatureArray = new Uint8Array(signatureBuffer);
const signature = btoa(String.fromCharCode(...signatureArray));
// Build the Authorization header
let authorizationHeader = `EXO2-HMAC-SHA256 credential=${apikey},expires=${expires},signature=${signature}`;
if (sortedParams.length > 0) {
authorizationHeader = `EXO2-HMAC-SHA256 credential=${apikey},signed-query-args=${sortedParams.join(';')},expires=${expires},signature=${signature}`;
}
console.log("Final Authorization Header:", authorizationHeader);
// Construct request options
const options = {
url: queryString ? `${url}?${queryString}` : url, // Include query if exists
method,
dataType: 'json',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
Authorization: authorizationHeader,
},
data: method === 'POST' ? requestBody : undefined,
};
console.log("Final AJAX Request:", JSON.stringify(options, null, 2));
console.log(this.app, this.session, this.intl);
return ajaxPromise(options, true);
}).then((response) => {
return response;
}).catch((err) => {
console.error('API Request Error:', err);
throw err;
});
}
Did I miss something in my header or so?
I still got {"type":"error","status":"401","message":"Unauthorized 401: must authenticate"}