const test = require("node:test");
const assert = require("node:assert/strict");
const path = require("node:path");
const s3 = require(
path.join(
__dirname,
"..", "..", "..", "..", "..", "..",
"roles", "test-e2e-playwright", "files", "personas", "utils", "s3.js",
),
);
const ACCESS_KEY = "AKIAIOSFODNN7EXAMPLE";
const SECRET_KEY = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY";
const REGION = "us-east-1";
const STAMP = new Date(Date.UTC(2013, 4, 24, 0, 0, 0));
const VECTORS = [
{
method: "GET",
host: "seaweedfs:8333",
path: "/",
query: null,
payload: "",
signature: "741e224559611fe6adfe50315e98fec09bdb9a52da21c86b77ee676d98e00dd1",
},
{
method: "GET",
host: "seaweedfs:8333",
path: "/matrix",
query: { "list-type": "2", "max-keys": "1" },
payload: "",
signature: "eee845a1bf4fa9439b3e9a3fe61ab440e0560036caacb71cc871c079fd4ad7b5",
},
{
method: "PUT",
host: "seaweedfs:8333",
path: "/infinito-engine-check-abc",
query: null,
payload: "",
signature: "53e844ed6b237bdf9329204161e0c80a0f699c4032b4862f5ce4cb52ec737464",
},
{
method: "DELETE",
host: "127.0.0.1:8085",
path: "/bucket/infinito-engine-check/xyz",
query: null,
payload: "",
signature: "fb4f99e695b2c37135b9b2a92ebcb5436c6deabd9bd6e876cd6b5d4eae00b0b0",
},
{
method: "GET",
host: "host.example:8333",
path: "/b/k",
query: { a: "1", B: "2", c: "x y" },
payload: "body",
signature: "6cf8880d3c0baa47750aa5b0736a2b10459546b2f583643689200c01e067e8ec",
},
];
function signatureOf(vector) {
const headers = s3.sign({
method: vector.method,
host: vector.host,
path: vector.path,
region: REGION,
accessKey: ACCESS_KEY,
secretKey: SECRET_KEY,
query: vector.query,
payload: vector.payload,
now: STAMP,
});
return headers.Authorization.split("Signature=")[1];
}
test("signatures match the reference implementation", () => {
for (const vector of VECTORS) {
assert.equal(signatureOf(vector), vector.signature, `${vector.method} ${vector.path}`);
}
});
test("the node signer agrees with the python engine probe", () => {
const fs = require("node:fs");
const pinned = path.join(
__dirname,
"..", "..", "..", "..", "..", "..",
"tests", "unit", "python", "roles", "web-svc-seaweedfs", "test_sigv4.py",
);
const python = fs.readFileSync(pinned, "utf8");
for (const vector of VECTORS) {
assert.ok(
python.includes(vector.signature),
`${vector.signature} must also be pinned in test_sigv4.py so the two signers cannot drift apart`,
);
}
});
test("a changed secret changes the signature", () => {
const headers = s3.sign({
method: "GET",
host: "seaweedfs:8333",
path: "/",
region: REGION,
accessKey: ACCESS_KEY,
secretKey: `${SECRET_KEY}x`,
payload: "",
now: STAMP,
});
assert.ok(!headers.Authorization.includes(VECTORS[0].signature));
});
test("a space encodes as %20, not +", () => {
assert.equal(s3.canonicalQuery({ c: "x y" }), "c=x%20y");
});
test("the secret never reaches the returned headers", () => {
const headers = s3.sign({
method: "GET",
host: "seaweedfs:8333",
path: "/",
region: REGION,
accessKey: ACCESS_KEY,
secretKey: SECRET_KEY,
payload: "",
now: STAMP,
});
assert.ok(!Object.values(headers).join("").includes(SECRET_KEY));
});
test("a truncated listing reports its continuation token", () => {
const xml = [
"",
"a/1"e1"2026-01-01T00:00:00Z",
"b/2"e2"2026-01-02T00:00:00Z",
"true",
"tok-42",
"",
].join("");
const { objects, next } = s3.parseListing(xml);
assert.deepEqual([...objects.keys()], ["a/1", "b/2"]);
assert.notEqual(objects.get("a/1"), objects.get("b/2"));
assert.equal(next, "tok-42");
});
test("a complete listing reports no continuation", () => {
const xml =
"onlyfalse";
const { objects, next } = s3.parseListing(xml);
assert.deepEqual([...objects.keys()], ["only"]);
assert.equal(next, "");
});
test("an empty listing yields no objects", () => {
const { objects, next } = s3.parseListing(
"false",
);
assert.equal(objects.size, 0);
assert.equal(next, "");
});