"use strict";
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", { value: true });
exports.tablesNamedKeyCredentialPolicyName = void 0;
exports.tablesNamedKeyCredentialPolicy = tablesNamedKeyCredentialPolicy;
exports.getAuthorizationHeader = getAuthorizationHeader;
const constants_js_1 = require("./utils/constants.js");
const computeHMACSHA256_js_1 = require("./utils/computeHMACSHA256.js");
/**
 * The programmatic identifier of the tablesNamedKeyCredentialPolicy.
 */
exports.tablesNamedKeyCredentialPolicyName = "tablesNamedKeyCredentialPolicy";
/**
 * tablesNamedKeyCredentialPolicy is a policy used to sign HTTP request with a shared key.
 */
function tablesNamedKeyCredentialPolicy(credential) {
    function signRequest(request) {
        const headerValue = getAuthorizationHeader(request, credential);
        request.headers.set(constants_js_1.HeaderConstants.AUTHORIZATION, headerValue);
    }
    return {
        name: exports.tablesNamedKeyCredentialPolicyName,
        async sendRequest(request, next) {
            signRequest(request);
            return next(request);
        },
    };
}
function getAuthorizationHeader(request, credential) {
    if (!request.headers.has(constants_js_1.HeaderConstants.X_MS_DATE)) {
        request.headers.set(constants_js_1.HeaderConstants.X_MS_DATE, new Date().toUTCString());
    }
    if (request.body && typeof request.body === "string" && request.body.length > 0) {
        request.headers.set(constants_js_1.HeaderConstants.CONTENT_LENGTH, Buffer.byteLength(request.body));
    }
    // If x-ms-date is present, use it otherwise date
    const dateHeader = getHeaderValueToSign(request, constants_js_1.HeaderConstants.X_MS_DATE);
    if (!dateHeader) {
        throw new Error("Failed to sign request: x-ms-date or date header must be present");
    }
    const stringToSign = [
        dateHeader,
        getCanonicalizedResourceString(request, credential),
    ].join("\n");
    const signature = (0, computeHMACSHA256_js_1.computeHMACSHA256)(stringToSign, credential.key);
    return `SharedKeyLite ${credential.name}:${signature}`;
}
function getHeaderValueToSign(request, headerName) {
    const value = request.headers.get(headerName);
    if (!value) {
        return "";
    }
    return value;
}
function getCanonicalizedResourceString(request, credential) {
    // https://learn.microsoft.com/rest/api/storageservices/authorize-with-shared-key#shared-key-lite-and-table-service-format-for-2009-09-19-and-later
    const url = new URL(request.url);
    const path = url.pathname || "/";
    let canonicalizedResourceString = "/" + credential.name + path;
    // The query string should include the question mark and the comp parameter (for example, ?comp=metadata). No other parameters should be included on the query string.
    const comp = url.searchParams.get("comp");
    if (comp) {
        canonicalizedResourceString = `${canonicalizedResourceString}?comp=${comp}`;
    }
    return canonicalizedResourceString;
}
//# sourceMappingURL=tablesNamedCredentialPolicy.js.map