@vizamodo/aws-sts-core 0.1.28 → 0.1.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/sigv4/headers.js +17 -14
- package/dist/sts/issue.js +5 -10
- package/package.json +1 -1
package/dist/sigv4/headers.js
CHANGED
|
@@ -11,26 +11,29 @@
|
|
|
11
11
|
* This function is PURE and side‑effect free.
|
|
12
12
|
*/
|
|
13
13
|
export function canonicalizeHeaders(headers) {
|
|
14
|
-
const
|
|
15
|
-
for (const [
|
|
16
|
-
if (
|
|
14
|
+
const map = new Map();
|
|
15
|
+
for (const [rawName, rawValue] of Object.entries(headers)) {
|
|
16
|
+
if (rawValue === undefined)
|
|
17
17
|
continue;
|
|
18
|
-
const name =
|
|
18
|
+
const name = rawName.toLowerCase().trim();
|
|
19
19
|
if (!name)
|
|
20
20
|
continue;
|
|
21
|
-
|
|
22
|
-
// - trim
|
|
23
|
-
// - collapse multiple spaces into one
|
|
24
|
-
const cleanedValue = value
|
|
21
|
+
const value = rawValue
|
|
25
22
|
.trim()
|
|
26
|
-
.replace(
|
|
27
|
-
|
|
23
|
+
.replace(/[ \t]+/g, " ");
|
|
24
|
+
if (!map.has(name)) {
|
|
25
|
+
map.set(name, []);
|
|
26
|
+
}
|
|
27
|
+
map.get(name).push(value);
|
|
28
28
|
}
|
|
29
|
-
const
|
|
30
|
-
const canonicalHeaders =
|
|
31
|
-
.map((name) =>
|
|
29
|
+
const sortedNames = Array.from(map.keys()).sort();
|
|
30
|
+
const canonicalHeaders = sortedNames
|
|
31
|
+
.map((name) => {
|
|
32
|
+
const combined = map.get(name).join(",");
|
|
33
|
+
return `${name}:${combined}\n`;
|
|
34
|
+
})
|
|
32
35
|
.join("");
|
|
33
|
-
const signedHeaders =
|
|
36
|
+
const signedHeaders = sortedNames.join(";");
|
|
34
37
|
return {
|
|
35
38
|
canonicalHeaders,
|
|
36
39
|
signedHeaders,
|
package/dist/sts/issue.js
CHANGED
|
@@ -53,16 +53,17 @@ export async function issueAwsCredentials(input) {
|
|
|
53
53
|
const amzDate = now.toISOString().replace(/\.\d{3}Z$/, "Z").replace(/[:-]/g, "");
|
|
54
54
|
const dateStamp = amzDate.slice(0, 8);
|
|
55
55
|
const service = "rolesanywhere";
|
|
56
|
-
// 3. Chuẩn bị Body &
|
|
56
|
+
// 3. Chuẩn bị Body & Cert (base64-encoded DER, không marker, không xuống dòng)
|
|
57
57
|
const body = JSON.stringify({ trustAnchorArn, profileArn, roleArn, durationSeconds: sessionTtl });
|
|
58
58
|
const payloadHash = await sha256Hex(body);
|
|
59
|
-
|
|
59
|
+
// AWS Roles Anywhere requires base64-encoded DER (NO PEM markers, NO newlines)
|
|
60
|
+
const normalizedCert = certBase64.replace(/\s+/g, "");
|
|
60
61
|
// 4. Tính toán Signature (CẦN Host trong Canonical Request)
|
|
61
62
|
const baseHeaders = {
|
|
62
63
|
"content-type": "application/json",
|
|
63
64
|
"host": host,
|
|
64
65
|
"x-amz-date": amzDate,
|
|
65
|
-
"x-amz-x509-chain":
|
|
66
|
+
"x-amz-x509-chain": normalizedCert,
|
|
66
67
|
};
|
|
67
68
|
const { canonicalHeaders, signedHeaders } = canonicalizeHeaders(baseHeaders);
|
|
68
69
|
const credentialScope = `${dateStamp}/${region}/${service}/aws4_request`;
|
|
@@ -85,7 +86,7 @@ export async function issueAwsCredentials(input) {
|
|
|
85
86
|
const finalHeaders = new Headers({
|
|
86
87
|
"Content-Type": "application/json",
|
|
87
88
|
"X-Amz-Date": amzDate,
|
|
88
|
-
"X-Amz-X509-Chain":
|
|
89
|
+
"X-Amz-X509-Chain": normalizedCert,
|
|
89
90
|
"Authorization": `AWS4-X509-ECDSA-SHA256 Credential=${roleArn}/${credentialScope}, SignedHeaders=${signedHeaders}, Signature=${signatureHex}`
|
|
90
91
|
});
|
|
91
92
|
// 6. Execution (fetch)
|
|
@@ -121,12 +122,6 @@ export async function issueAwsCredentials(input) {
|
|
|
121
122
|
}
|
|
122
123
|
}
|
|
123
124
|
// ---- helpers ----
|
|
124
|
-
function toPemCertificate(base64) {
|
|
125
|
-
// Loại bỏ mọi khoảng trắng/xuống dòng trong base64
|
|
126
|
-
const normalized = base64.replace(/\s+/g, "");
|
|
127
|
-
// AWS Roles Anywhere Header: Không được dùng xuống dòng \n
|
|
128
|
-
return `-----BEGIN CERTIFICATE-----${normalized}-----END CERTIFICATE-----`;
|
|
129
|
-
}
|
|
130
125
|
async function sha256Hex(input) {
|
|
131
126
|
const data = new TextEncoder().encode(input);
|
|
132
127
|
const hash = await crypto.subtle.digest("SHA-256", data);
|