Skip to content
63 linesCodeBlameRaw
1import assert from "node:assert/strict";
2import { test } from "node:test";
3
4import { amzDate, sha256Hex, sign, uriEncode } from "./sigv4.ts";
5
6const EMPTY = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855";
7
8// AWS's SigV4 test suite, `get-vanilla`: the plainest request there is.
9test("signs AWS's get-vanilla test vector", async () => {
10 const signed = await sign({
11 method: "GET",
12 url: "https://example.amazonaws.com/",
13 payload_hash: EMPTY,
14 region: "us-east-1",
15 service: "service",
16 credentials: { access_key_id: "AKIDEXAMPLE", secret_access_key: "wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY" },
17 date: new Date("2015-08-30T12:36:00Z"),
18 });
19 assert.equal(signed.canonical_request, `GET\n/\n\nhost:example.amazonaws.com\nx-amz-date:20150830T123600Z\n\nhost;x-amz-date\n${EMPTY}`);
20 assert.equal(signed.string_to_sign, "AWS4-HMAC-SHA256\n20150830T123600Z\n20150830/us-east-1/service/aws4_request\nbb579772317eb040ac9ed261061d46c1f17a8133879d6129b6e1c25292927e63");
21 assert.equal(signed.signature, "5fa00fa31553b73ebf1942676e86291e8372ff2a2260956d9b8aae1d763fbf31");
22 assert.equal(
23 signed.headers.authorization,
24 "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=5fa00fa31553b73ebf1942676e86291e8372ff2a2260956d9b8aae1d763fbf31",
25 );
26});
27
28// The S3 documentation's worked example: GET Object with a Range header.
29test("signs the S3 GET Object example", async () => {
30 const signed = await sign({
31 method: "GET",
32 url: "https://examplebucket.s3.amazonaws.com/test.txt",
33 headers: { range: "bytes=0-9", "x-amz-content-sha256": EMPTY },
34 payload_hash: EMPTY,
35 region: "us-east-1",
36 service: "s3",
37 credentials: { access_key_id: "AKIAIOSFODNN7EXAMPLE", secret_access_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" },
38 date: new Date("2013-05-24T00:00:00Z"),
39 });
40 assert.equal(signed.signature, "f0e8bdb87c964420e857bd35b5d6ed310bd44f0170aba48dd91039c6036bdb41");
41 assert.match(signed.headers.authorization!, /SignedHeaders=host;range;x-amz-content-sha256;x-amz-date,/);
42});
43
44test("hashes and encodes as SigV4 wants", async () => {
45 assert.equal(await sha256Hex(""), EMPTY);
46 assert.equal(uriEncode("a b/c*~"), "a%20b%2Fc%2A~");
47 assert.equal(amzDate(new Date("2015-08-30T12:36:00.123Z")), "20150830T123600Z");
48});
49
50test("puts the query in order", async () => {
51 const signed = await sign({
52 method: "GET",
53 url: "https://example.amazonaws.com/?Param2=value2&Param1=value1",
54 payload_hash: EMPTY,
55 region: "us-east-1",
56 service: "service",
57 credentials: { access_key_id: "AKIDEXAMPLE", secret_access_key: "wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY" },
58 date: new Date("2015-08-30T12:36:00Z"),
59 });
60 assert.equal(signed.canonical_request.split("\n")[2], "Param1=value1&Param2=value2");
61 // AWS's `get-vanilla-query-order-key-case`.
62 assert.equal(signed.signature, "b97d918cfa904a5beff61c982a1b6f458b799221646efd99d3219ec94cdf2500");
63});