"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getAwsCredentials = getAwsCredentials;
exports.getAwsRegion = getAwsRegion;
exports.getStsHostname = getStsHostname;
exports.getAwsAttestationToken = getAwsAttestationToken;
const credential_provider_node_1 = require("@aws-sdk/credential-provider-node");
const client_sts_1 = require("@aws-sdk/client-sts");
const ec2_metadata_service_1 = require("@aws-sdk/ec2-metadata-service");
const protocol_http_1 = require("@smithy/protocol-http");
const signature_v4_1 = require("@smithy/signature-v4");
const sha256_js_1 = require("@aws-crypto/sha256-js");
const logger_1 = __importDefault(require("../../logger"));
async function getAwsCredentials(region, impersonationPath = []) {
    (0, logger_1.default)().debug('Getting AWS credentials from default provider');
    let credentials = await (0, credential_provider_node_1.defaultProvider)()();
    for (const roleArn of impersonationPath) {
        (0, logger_1.default)().debug(`Getting AWS credentials from impersonation role: ${roleArn}`);
        const stsClient = new client_sts_1.STSClient({
            credentials,
            region,
        });
        const command = new client_sts_1.AssumeRoleCommand({
            RoleArn: roleArn,
            RoleSessionName: 'identity-federation-session',
        });
        const { Credentials } = await stsClient.send(command);
        if (Credentials?.AccessKeyId && Credentials?.SecretAccessKey) {
            credentials = {
                accessKeyId: Credentials.AccessKeyId,
                secretAccessKey: Credentials.SecretAccessKey,
                sessionToken: Credentials.SessionToken,
            };
        }
        else {
            throw new Error(`Failed to get credentials from impersonation role ${roleArn}`);
        }
    }
    return credentials;
}
async function getAwsRegion() {
    if (process.env.AWS_REGION) {
        (0, logger_1.default)().debug('Getting AWS region from AWS_REGION');
        return process.env.AWS_REGION; // Lambda
    }
    else {
        (0, logger_1.default)().debug('Getting AWS region from EC2 metadata service');
        return new ec2_metadata_service_1.MetadataService().request('/latest/meta-data/placement/region', {}); // EC2
    }
}
function getStsHostname(region) {
    const domain = region.startsWith('cn-') ? 'amazonaws.com.cn' : 'amazonaws.com';
    return `sts.${region}.${domain}`;
}
async function getAwsAttestationToken(impersonationPath) {
    const region = await getAwsRegion();
    const credentials = await getAwsCredentials(region, impersonationPath);
    const stsHostname = getStsHostname(region);
    const request = new protocol_http_1.HttpRequest({
        method: 'POST',
        protocol: 'https',
        hostname: stsHostname,
        path: '/',
        headers: {
            host: stsHostname,
            'x-snowflake-audience': 'snowflakecomputing.com',
        },
        query: {
            Action: 'GetCallerIdentity',
            Version: '2011-06-15',
        },
    });
    const signedRequest = await new signature_v4_1.SignatureV4({
        credentials,
        applyChecksum: false,
        region,
        service: 'sts',
        sha256: sha256_js_1.Sha256,
    }).sign(request);
    const token = {
        url: `https://${stsHostname}/?Action=GetCallerIdentity&Version=2011-06-15`,
        method: 'POST',
        headers: signedRequest.headers,
    };
    return btoa(JSON.stringify(token));
}
//# sourceMappingURL=attestation_aws.js.map