All files index.js

97.14% Statements 34/35
92.31% Branches 12/13
100% Functions 7/7
97.14% Lines 34/35

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 911x 1x 1x 1x 1x 1x 1x 1x   1x 1x     4x 4x         4x 4x           4x       4x 4x 4x   4x                         4x   4x       4x 4x 4x 4x 4x 4x   4x   4x                   4x         4x 4x         3x       3x      
const AWS = require('aws-sdk');
const Promise = require("bluebird");
const crypto = require("crypto-js");
const { SHA256, HmacSHA256 } = crypto;
const { Hex, Base64, Utf8 } = crypto.enc;
const dayjs = require('dayjs');
const utc = require('dayjs/plugin/utc')
dayjs.extend(utc)
 
module.exports = class EKSToken {
    static _config = new AWS.Config();
 
    static preInspection() {
        return Promise.fromCallback((cb) => {
            this._config.getCredentials(cb);
        });
    }
 
    static renew(clusterName = 'eks-cluster', expires = '60', formatTime) {
        return this.preInspection().then((resolve) => {
            const [accessKeyId, secretAccessKey, sessionToken, region] = [
                this._config.credentials.accessKeyId,
                this._config.credentials.secretAccessKey,
                this._config.credentials.sessionToken,
                this._config.region
            ];
            Iif (!accessKeyId || !secretAccessKey || !region) {
                throw new Error('Lose the accessKeyId, secretAccessKey or region');
            }
            // YYYYMMDD'T'HHMMSS'Z'
            const fullDate = formatTime || dayjs.utc().format('YYYYMMDDTHHmmss[Z]');
            const subDate = fullDate.substring(0, 8);
            const tokenHeader = sessionToken ? `X-Amz-Security-Token=${encodeURIComponent(sessionToken)}&` : '';
            const canonicalRequest =
                'GET' + '\n' +
                '/' + '\n' +
                'Action=GetCallerIdentity&' +
                'Version=2011-06-15&' +
                'X-Amz-Algorithm=AWS4-HMAC-SHA256&' +
                `X-Amz-Credential=${accessKeyId}%2F${subDate}%2F${region}%2Fsts%2Faws4_request&` +
                `X-Amz-Date=${fullDate}&` +
                `X-Amz-Expires=${expires}&` +
                tokenHeader +
                `X-Amz-SignedHeaders=host%3Bx-k8s-aws-id` + '\n' +
                `host:sts.${region}.amazonaws.com\nx-k8s-aws-id:${clusterName}\n` + '\n' +
                'host;x-k8s-aws-id' + '\n' +
                'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855';
            const hashedCanonicalRequest = Hex.stringify(SHA256(canonicalRequest));
            const stringToSign =
                'AWS4-HMAC-SHA256' + '\n' +
                fullDate + '\n' +
                `${subDate}/${region}/sts/aws4_request` + '\n' +
                hashedCanonicalRequest;
            const signingKey = ((key, dateStamp, regionName, serviceName) => {
                var kDate = HmacSHA256(dateStamp, "AWS4" + key);
                var kRegion = HmacSHA256(regionName, kDate);
                var kService = HmacSHA256(serviceName, kRegion);
                var kSigning = HmacSHA256("aws4_request", kService);
                return kSigning;
            })(secretAccessKey, subDate, region, 'sts');
            const signature = Hex.stringify(HmacSHA256(stringToSign, signingKey));
            const presignedURL =
                `https://sts.${region}.amazonaws.com/?` +
                'Action=GetCallerIdentity&' +
                'Version=2011-06-15&' +
                'X-Amz-Algorithm=AWS4-HMAC-SHA256&' +
                `X-Amz-Credential=${accessKeyId}%2F${subDate}%2F${region}%2Fsts%2Faws4_request&` +
                `X-Amz-Date=${fullDate}&` +
                `X-Amz-Expires=${expires}&` +
                tokenHeader +
                'X-Amz-SignedHeaders=host%3Bx-k8s-aws-id&' +
                `X-Amz-Signature=${signature}`;
            const base64Encoding = Base64.stringify(Utf8.parse(presignedURL))
                // for url safe
                .replace(/\+/g, '-') // Convert '+' to '-'
                .replace(/\//g, '_') // Convert '/' to '_'
                .replace(/=+$/, ''); // Remove ending '='
            const eksToken = 'k8s-aws-v1.' + base64Encoding;
            return eksToken;
        })
    }
 
    static get config() {
        return this._config;
    }
 
    static set config(option) {
        option && this._config.update(option);
    }
}