diff --git a/cli.json b/cli.json index 9a3eb59..9d791b8 100644 --- a/cli.json +++ b/cli.json @@ -5,13 +5,13 @@ "commands": [ { "name": "edgeworkers", - "version": "0.5.3", + "version": "1.0.0", "aliases": ["ew", "edgeworkers"], "description": "Manage Akamai EdgeWorkers code bundles." }, { "name": "edgekv", - "version": "0.5.3", + "version": "1.0.0", "aliases": ["ekv", "edgekv"], "description": "Manage Akamai EdgeKV database." } diff --git a/docs/edgekv_cli.md b/docs/edgekv_cli.md index 458cba2..476e4c7 100644 --- a/docs/edgekv_cli.md +++ b/docs/edgekv_cli.md @@ -20,6 +20,8 @@ * [ Delete Item](###delete-item) * [ List Items](###list-items) * [ Create an Access Token](###create-an-access-token) + * [ List Access Tokens](###list-access-tokens) + * [ Retrieve Access Token](###retrieve-access-token) * [ Resources](##resources) * [ Reporting Issues](##reporting-issues) @@ -313,6 +315,28 @@ Example: 2. The token name can be between 1 and 32 characters in length. 3. The expiry date must be at least 1 day in the future and no more than 6 months from the current date. +### List Access Tokens + +List of all tokens for which the user has permission to download. + +Usage: `akamai edgekv list tokens` + +| Option | Description | +| - | - | +| -h, --help | Display information on how to use this EdgeKV command | + +### Retrieve Access Token + +Retrieve an edgeKV access token + +Usage: +`akamai edgekv create token --save_path= --overwrite` + +| Option | Existence | Description | +| - | - | - | +| --save_path | Optional | Path specifying where to save the edgekv_tokens.js token file. We recommend that you save the token file in the same location as the EdgeWorkers code bundle file (.tgz). The EdgeWorkers code bundle is then automatically updated every time this command updates the edgekv_tokens.js token file.If a path is not provided the token value is displayed. This token must be securely stored and manually added to the edgekv_tokens.js token file and EdgeWorkers code bundle. | +| -o, --overwrite | Optional | This option is used in conjunction with the --save_path option to overwrite the value of an existing token with the same name in the edgekv_tokens.js file. | +| -h, --help | Display information on how to use this EdgeKV command | ___ ## Resources diff --git a/package-lock.json b/package-lock.json index e11af28..0a4ccde 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "akamai-edgeworkers-cli", - "version": "0.5.3", + "version": "1.0.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -371,6 +371,11 @@ "mime-types": "^2.1.12" } }, + "from-seconds": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/from-seconds/-/from-seconds-1.0.2.tgz", + "integrity": "sha512-rr8AdsRI+cr+0LRvyr/oPlZOkYt25l2oxffcrc/7g2orlCyMECa3xs0anJJdmrq/m3lwh+WcD7vwuZ5MF9qi5g==" + }, "fs-constants": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", diff --git a/package.json b/package.json index d76fc7c..18aba12 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "akamai-edgeworkers-cli", - "version": "0.5.3", + "version": "1.0.0", "description": "A tool that makes it easier to manage Akamai EdgeWorkers code bundles and EdgeKV databases. Call the EdgeWorkers and EdgeKV API from the command line.", "repository": "https://github.com/akamai/cli-edgeworkers", "scripts": { @@ -23,6 +23,7 @@ "console.table": "0.10.0", "crypto-js": "^4.0.0", "edgegrid": "^3.0.8", + "from-seconds": "^1.0.2", "inquirer": "6.2.0", "jwt-decode": "^3.1.2", "sha256-file": "^1.0.0", diff --git a/src/cli-httpRequest.ts b/src/cli-httpRequest.ts index b294fee..03f4442 100644 --- a/src/cli-httpRequest.ts +++ b/src/cli-httpRequest.ts @@ -44,6 +44,7 @@ export function sendEdgeRequest(pth: string, method: string, body, headers) { try { var errorObj = JSON.parse(body); errorObj["status"] = response.statusCode; + errorObj["traceId"] = response.headers["x-trace-id"]; // adding trace id for debugging purpose reject(cliUtils.toJsonPretty(errorObj)); } catch (ex) { console.error(`got error code: ${response.statusCode} calling ${method} ${path}\n${body}`); diff --git a/src/edgekv/ekv-cli-main.ts b/src/edgekv/ekv-cli-main.ts index 213309a..8e66c1d 100644 --- a/src/edgekv/ekv-cli-main.ts +++ b/src/edgekv/ekv-cli-main.ts @@ -164,6 +164,20 @@ list cliUtils.logAndExit(0, copywrite); }); +list + .command("tokens") + .description("List all tokens for which the user has permission to download.") + .action(async function () { + try { + await kvCliHandler.listTokens(); + } catch (e) { + cliUtils.logAndExit(1, e); + } + }) + .on("--help", function () { + cliUtils.logAndExit(0, copywrite); + }); + const create = program.command('create') .description("Creates a namespace or creates a token") .on("--help", function () { @@ -206,6 +220,25 @@ create cliUtils.logAndExit(0, copywrite); }); +const download = program.command('download') + .alias("dnld") + .description("Download an edgekv token"); + +download + .command("token ") + .description("Download an edgekv token") + .option('--save_path ', 'The path of the bundle where the token will be saved') + .option("-o, --overwrite", "EdgeKV token placed inside the bundle will be overwritten") + .action(async function (tokenName, options) { + try { + await kvCliHandler.retrieveToken(tokenName, options); + } catch (e) { + cliUtils.logAndExit(1, e); + } + }) + .on("--help", function () { + cliUtils.logAndExit(0, copywrite); + }); const show = program.command('show') .description("Check the initialization status of the EdgeKV or Retrieve an EdgeKV namespace. Use show -h to see available options") diff --git a/src/edgekv/ekv-error.ts b/src/edgekv/ekv-error.ts index f0bb925..b5ba2eb 100644 --- a/src/edgekv/ekv-error.ts +++ b/src/edgekv/ekv-error.ts @@ -8,11 +8,13 @@ export function handleError(err) { } catch (e) { return { isError: true, - error_reason: "" + error_reason: "", + traceId: "-" } } let statusCode = err["status"] == undefined ? "" : err["status"]; + let traceIdVal = err["traceId"] == undefined ? "" : err["traceId"]; // this is sent by edgeKV if (err.hasOwnProperty("errors")) { let errors = err["errors"]; @@ -20,7 +22,8 @@ export function handleError(err) { return { isError: true, error_reason: errors[0]["detail"], - status: statusCode + status: statusCode, + traceId: traceIdVal } } } @@ -31,13 +34,15 @@ export function handleError(err) { return { isError: true, error_reason: additionalDetail["detail"], - status: statusCode + status: statusCode, + traceId: traceIdVal } } else { return { isError: true, error_reason: "", - status: statusCode + status: statusCode, + traceId: traceIdVal } } } @@ -46,7 +51,8 @@ export function handleError(err) { return { isError: true, error_reason: errDetail, - status: statusCode + status: statusCode, + traceId: traceIdVal } } } \ No newline at end of file diff --git a/src/edgekv/ekv-handler.ts b/src/edgekv/ekv-handler.ts index 118bfe9..32760be 100644 --- a/src/edgekv/ekv-handler.ts +++ b/src/edgekv/ekv-handler.ts @@ -17,7 +17,7 @@ export async function listNameSpaces(environment: string) { cliUtils.logWithBorder(`The following namespaces are provisioned on the ${environment} environment`); console.table(nsListResp); } else { - response.logError(nameSpaceList, `ERROR: Error while retrieving namespaces. ${nameSpaceList.error_reason}`); + response.logError(nameSpaceList, `ERROR: Error while retrieving namespaces. ${nameSpaceList.error_reason} [TraceId: ${nameSpaceList.traceId}]`); } } @@ -29,7 +29,7 @@ export async function createNamespace(environment: string, nameSpace: string) { cliUtils.logWithBorder(msg); response.logNamespace(nameSpace, createdNamespace); } else { - response.logError(createdNamespace, `ERROR: Error while creating namespace. ${createdNamespace.error_reason}`); + response.logError(createdNamespace, `ERROR: Error while creating namespace. ${createdNamespace.error_reason} [TraceId: ${createdNamespace.traceId}]`); } } @@ -42,12 +42,12 @@ export async function getNameSpace(environment: string, nameSpace: string) { cliUtils.logWithBorder(msg); response.logNamespace(nameSpace, createdNamespace); } else { - response.logError(createdNamespace, `ERROR: Error while retrieving namespace from ${environment} environment. ${createdNamespace.error_reason}`); + response.logError(createdNamespace, `ERROR: Error while retrieving namespace from ${environment} environment. ${createdNamespace.error_reason} [TraceId: ${createdNamespace.traceId}]`); } } export async function initializeEdgeKv() { - let initializedEdgeKv = await cliUtils.spinner(edgekvSvc.initializeEdgeKV(),`Initializing EdgeKV...`); + let initializedEdgeKv = await cliUtils.spinner(edgekvSvc.initializeEdgeKV(), `Initializing EdgeKV...`); if (initializedEdgeKv.body != undefined && !initializedEdgeKv.isError) { let initRespBody = JSON.parse(initializedEdgeKv.body); @@ -74,12 +74,12 @@ export async function initializeEdgeKv() { } response.logInitialize(initRespBody); } else { - response.logError(initializedEdgeKv, `ERROR: EdgeKV Initialization failed. (${initializedEdgeKv.error_reason}).`); + response.logError(initializedEdgeKv, `ERROR: EdgeKV Initialization failed. (${initializedEdgeKv.error_reason}) [${initializedEdgeKv.traceId}]`); } } export async function getInitializationStatus() { - let initializedEdgeKv = await cliUtils.spinner(edgekvSvc.getInitializedEdgeKV(),"Getting Initialization status..."); + let initializedEdgeKv = await cliUtils.spinner(edgekvSvc.getInitializedEdgeKV(), "Getting Initialization status..."); if (initializedEdgeKv.body != undefined && !initializedEdgeKv.isError) { let initRespBody = JSON.parse(initializedEdgeKv.body); @@ -103,7 +103,7 @@ export async function getInitializationStatus() { } response.logInitialize(initRespBody); } else { - response.logError(initializedEdgeKv, `ERROR: EdgeKV Initialization failed. (${initializedEdgeKv.error_reason}).`); + response.logError(initializedEdgeKv, `ERROR: Unable to retrieve EdgeKV status. (${initializedEdgeKv.error_reason}) [TraceId: ${initializedEdgeKv.traceId}]`); } } @@ -127,7 +127,7 @@ export async function writeItemToEdgeKV(environment: string, nameSpace: string, if (createdItem != undefined && !createdItem.isError) { cliUtils.logWithBorder(msg); } else { - response.logError(createdItem, `ERROR: Unable to write item to EdgeKV. ${createdItem.error_reason}`); + response.logError(createdItem, `ERROR: Unable to write item to EdgeKV. ${createdItem.error_reason} [TraceId: ${createdItem.traceId}]`); } } @@ -135,7 +135,7 @@ export async function readItemFromEdgeKV(environment: string, nameSpace: string, ekvhelper.validateNetwork(environment); - let item = await cliUtils.spinner(edgekvSvc.readItem(environment, nameSpace, groupId, itemId),"Reading items from EdgeKV.."); + let item = await cliUtils.spinner(edgekvSvc.readItem(environment, nameSpace, groupId, itemId), "Reading items from EdgeKV.."); if (item != undefined && !item.isError) { let msg = `Item ${itemId} from group ${groupId}, namespace ${nameSpace} and environment ${environment} retrieved successfully.` cliUtils.logWithBorder(msg); @@ -145,7 +145,7 @@ export async function readItemFromEdgeKV(environment: string, nameSpace: string, console.log(item); } } else { - response.logError(item, `ERROR: Unable to read item. ${item.error_reason}`); + response.logError(item, `ERROR: Unable to read item. ${item.error_reason} [TraceId: ${item.traceId}]`); } } @@ -156,13 +156,13 @@ export async function deleteItemFromEdgeKV(environment: string, nameSpace: strin let msg = `Item ${itemId} was successfully marked for deletion from group ${groupId}, namespace ${nameSpace} and environment ${environment}` cliUtils.logWithBorder(msg); } else { - response.logError(deletedItem, `ERROR: Unable to delete item ${itemId} from group ${groupId}, namespace ${nameSpace} and environment ${environment}. ${deletedItem.error_reason}`); + response.logError(deletedItem, `ERROR: Unable to delete item ${itemId} from group ${groupId}, namespace ${nameSpace} and environment ${environment}. ${deletedItem.error_reason} [TraceId: ${deletedItem.traceId}]`); } } export async function listItemsFromGroup(environment: string, nameSpace: string, groupId: string) { ekvhelper.validateNetwork(environment); - let itemsList = await cliUtils.spinner(edgekvSvc.getItemsFromGroup(environment, nameSpace, groupId),`Listing items from namespace ${nameSpace} and group ${groupId}`); + let itemsList = await cliUtils.spinner(edgekvSvc.getItemsFromGroup(environment, nameSpace, groupId), `Listing items from namespace ${nameSpace} and group ${groupId}`); if (itemsList != undefined && !itemsList.isError) { let msg: string = `There are no items for group ${groupId}, namespace ${nameSpace} and environment ${environment}`; @@ -174,24 +174,31 @@ export async function listItemsFromGroup(environment: string, nameSpace: string, console.log(element); }); } else { - response.logError(itemsList, `ERROR: Unable to retrieve items from group. ${itemsList.error_reason}`); + response.logError(itemsList, `ERROR: Unable to retrieve items from group. ${itemsList.error_reason} [TraceId: ${itemsList.traceId}]`); + } +} + +export async function listTokens() { + let tokenList = await cliUtils.spinner(edgekvSvc.getTokenList(), `Fetching token list...`); + let msg = `The following tokens are available for you to download`; + if (tokenList != undefined && !tokenList.isError) { + cliUtils.logWithBorder(msg); + response.logTokenList(tokenList); + cliUtils.log(`You have ${tokenList["tokens"].length} tokens available to download.`) + } else { + response.logError(tokenList, `ERROR: Unable to retrieve edgekv access tokens. ${tokenList.error_reason} [TraceId: ${tokenList.traceId}]`); } } export async function createToken(tokenName: string, options: { save_path?: string, staging?: string, production?: string, ewids?: string, namespace?: string, expiry?: string, overwrite?}) { // convert string to ISO date let expiry = getExpiryDate(options.expiry); - let savePath = options.save_path; + // parse input permissions let permissionList = parseNameSpacePermissions(options.namespace); let envAccess = { "allow": true, "deny": false }; - - if (savePath) { - if (!ekvhelper.checkIfFileExists(savePath)) { - cliUtils.logWithBorder(`ERROR: Unable to create token. save_path provided is invalid or you do not have access permissions. Please provide a valid path.`); - process.exit(1); - } - } + let savePath = options.save_path; + validateSavePath(savePath); if (options.staging == "deny" && options.production == "deny") { cliUtils.logWithBorder(`ERROR: Unable to create token. Either one of staging or production access should be set to "allow". Please provide a valid access permissions.`); @@ -201,22 +208,22 @@ export async function createToken(tokenName: string, options: { save_path?: stri let createdToken = await cliUtils.spinner(edgekvSvc.createEdgeKVToken(tokenName, permissionList, envAccess[options.staging], envAccess[options.production], options.ewids, expiry), "Creating edgekv token ..."); if (createdToken != undefined && !createdToken.isError) { - // decodes the jwt token - let decodedToken = ekvhelper.decodeJWTToken(createdToken["value"]); - let nameSpaceList = ekvhelper.getNameSpaceListFromJWT(decodedToken); - let msg = `Add the token value in edgekv_tokens.js file and place it in your bundle. Use --save_path option to save the token file to your bundle` - if (options.save_path) { - if (ekvhelper.getFileExtension(savePath) != ".tgz") { - ekvhelper.createTokenFileWithoutBundle(options.save_path, options.overwrite, createdToken, decodedToken, nameSpaceList); - } else { - ekvhelper.saveTokenToBundle(options.save_path, options.overwrite, createdToken, decodedToken, nameSpaceList); - } - } else { - cliUtils.logWithBorder(msg); - response.logToken(createdToken["name"], createdToken["value"], decodedToken, nameSpaceList, false); - } + processToken(createdToken, savePath, options.overwrite); + } else { + response.logError(createdToken, `ERROR: Unable to create edgekv token. ${createdToken.error_reason} [TraceId: ${createdToken.traceId}]`); + } +} + +export async function retrieveToken(tokenName: string, options: { save_path?: string, overwrite?}) { + let savePath = options.save_path; + validateSavePath(savePath); + + let retrievedToken = await cliUtils.spinner(edgekvSvc.getSingleToken(tokenName), "Downloading egdekv token..."); + + if (retrievedToken != undefined && !retrievedToken.isError) { + processToken(retrievedToken, savePath, options.overwrite); } else { - response.logError(createdToken, `ERROR: Unable to create edgekv token. ${createdToken.error_reason}`); + response.logError(retrievedToken, `ERROR: Unable to retrieve edgekv token. ${retrievedToken.error_reason} [TraceId: ${retrievedToken.traceId}]`); } } @@ -240,7 +247,7 @@ function getExpiryDate(expiry: string) { function parseNameSpacePermissions(namespace: string) { // list to which all the permissions mapped to namespace will be added - let permissionList = {}; + let permissionList = {}; let allowedPermission = ["r", "w", "d"]; let allowedPermissionErrorMsg = "ERROR: Permissions provided is invalid. Please provide from the following : r,w,d"; namespace.split(",").forEach(val => { @@ -269,4 +276,30 @@ function parseNameSpacePermissions(namespace: string) { permissionList[per[0]] = permissions; }); return permissionList; +} + +function validateSavePath(savePath) { + if (savePath) { + if (!ekvhelper.checkIfFileExists(savePath)) { + cliUtils.logWithBorder(`ERROR: Unable to save token. save_path provided is invalid or you do not have access permissions. Please provide a valid path.`); + process.exit(1); + } + } +} + +function processToken(token, savePath, overwrite) { + // decodes the jwt token + let decodedToken = ekvhelper.decodeJWTToken(token["value"]); + let nameSpaceList = ekvhelper.getNameSpaceListFromJWT(decodedToken); + let msg = `Add the token value in edgekv_tokens.js file and place it in your bundle. Use --save_path option to save the token file to your bundle` + if (savePath) { + if (ekvhelper.getFileExtension(savePath) != ".tgz") { + ekvhelper.createTokenFileWithoutBundle(savePath, overwrite, token, decodedToken, nameSpaceList); + } else { + ekvhelper.saveTokenToBundle(savePath, overwrite, token, decodedToken, nameSpaceList); + } + } else { + cliUtils.logWithBorder(msg); + response.logToken(token["name"], token["value"], decodedToken, nameSpaceList, false); + } } \ No newline at end of file diff --git a/src/edgekv/ekv-helper.ts b/src/edgekv/ekv-helper.ts index d78f350..7be96a9 100644 --- a/src/edgekv/ekv-helper.ts +++ b/src/edgekv/ekv-helper.ts @@ -1,6 +1,7 @@ import * as cliUtils from '../utils/cli-utils'; import jwt_decode from "jwt-decode"; import * as response from './ekv-response'; +import { fromSeconds } from 'from-seconds'; const fs = require('fs'); var path = require('path') @@ -12,21 +13,18 @@ const tkn_export = "\n}\nexport { edgekv_access_tokens };" /** * converts seconds to years, months and days - * @example docs - https://stackoverflow.com/questions/8942895/convert-a-number-of-days-to-days-months-and-years-with-jquery/8943500 * @param seconds */ export function convertRetentionPeriod(seconds) { if (seconds == 0) { return "Indefinite"; } - - let days = Math.floor(seconds / 86400); // converting seconds to days - let y = 365; - let m = 30; - var remainder = days % y; - let remDays = remainder % m; - let year = (days - remainder) / y; - let month = (remainder - remDays) / m; + let convResult = fromSeconds(seconds); + let yearConv = convResult.toYears(); + let year = yearConv["years"]; + let month = yearConv["months"]; + let days = yearConv["days"]; + let totalDays = convResult.toDays()["days"]; let result: string = ""; if (year >= 1) { @@ -35,9 +33,10 @@ export function convertRetentionPeriod(seconds) { if (month >= 1) { result += month + ((month == 1) ? " month " : " months "); } - if (remDays >= 1) { - result += remDays + ((remDays == 1) ? " day" : " days"); + if (days >= 1) { + result += days + ((days == 1) ? " day" : " days"); } + result += " (" + totalDays + "days)"; return result; } @@ -225,9 +224,11 @@ function constructTokenFile(tokenContent) { export function createTokenFileWithoutBundle(savePath, overWrite, createdToken, decodedToken, nameSpaceList) { let msg = `Token in ${savePath}/edgekv_tokens.js was successfully updated.`; - + let tokenFilePath = savePath; // if token file does not exist, create new file - let tokenFilePath = savePath + "/edgekv_tokens.js"; + if (savePath.indexOf("edgekv_tokens.js") == -1) { + tokenFilePath = savePath + "/edgekv_tokens.js"; + } let tokenFileContent = ""; let tokenContent = []; if (!checkIfFileExists(tokenFilePath)) { @@ -336,4 +337,12 @@ function updateTokenContent(tokenContent, nameSpaceList, createdToken, decodedTo } } return tokenContent; +} + +export function getDateDifference(date) { + let Difference_In_Time = date.getTime() - new Date().getTime(); + + // To calculate the no. of days between two dates + let Difference_In_Days = Difference_In_Time / (1000 * 3600 * 24); + return Difference_In_Days; } \ No newline at end of file diff --git a/src/edgekv/ekv-response.ts b/src/edgekv/ekv-response.ts index e97f58a..4cfd479 100644 --- a/src/edgekv/ekv-response.ts +++ b/src/edgekv/ekv-response.ts @@ -1,8 +1,11 @@ import * as ekvhelper from './ekv-helper'; import * as cliUtils from '../utils/cli-utils' -import {ErrorMessage} from './http-error-message'; +import { ErrorMessage } from './http-error-message'; require('console.table'); +const shortMnthNames = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; +const weekday = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; + export function logNamespace(nameSpaceId: string, createdNameSpace) { let retentionPeriod = ekvhelper.convertRetentionPeriod(createdNameSpace["retention_period"]); var createNameSpace = { @@ -10,7 +13,7 @@ export function logNamespace(nameSpaceId: string, createdNameSpace) { RetentionPeriod: retentionPeriod } console.table([createNameSpace]); -} +} export function logInitialize(initializedEdgekv) { let initializeStatus = { @@ -22,6 +25,29 @@ export function logInitialize(initializedEdgekv) { console.table([initializeStatus]); } +export function logTokenList(tokenList) { + let tokens = []; + tokenList["tokens"].forEach(token => { + let parts = token["expiry"].split('-'); + let expiry = new Date(parts[0], parts[1] - 1, parts[2]); + let difference = Math.floor(ekvhelper.getDateDifference(expiry)); + let warning = "-"; + + if (difference >=0 && difference <= 30) { + warning = `Will EXPIRE in less than ${difference} days`; + } else if (difference <= -1) { + warning = `Token already expired`; + } + let tokenContent = { + TokenName: token["name"], + ExpiryDate: `${weekday[expiry.getUTCDay()]},${expiry.getDate()} ${shortMnthNames[expiry.getMonth()]} ${expiry.getFullYear()}`, + Warning: warning + } + tokens.push(tokenContent); + }); + console.table(tokens); +} + /** * todo this needs to be updated when open api releases the beta * @param status @@ -34,59 +60,64 @@ export function logError(errorObj, message) { } } -export function logToken(tokenName: string, tokenValue, decodedToken, nameSpaceList, savePath:boolean) { - const shortMnthNames = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; - let weekday = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; +export function logToken(tokenName: string, tokenValue, decodedToken, nameSpaceList, savePath: boolean) { let expiryDate = ekvhelper.convertTokenDate(decodedToken['exp']); let issueDate = ekvhelper.convertTokenDate(decodedToken['iat']) let env = decodedToken["env"]; let staging = false; let production = false; - env.forEach(function(value) { - if(value === 's') { + env.forEach(function (value) { + if (value === 's') { staging = true; - } else if(value === 'p') { + } else if (value === 'p') { production = true; } }) console.log( - 'Token Name: ', tokenName+'\n' - + 'CpCode used: ', decodedToken["cpc"]+'\n' - + 'Valid for EWIDs: ', decodedToken["ewids"]+'\n' - + 'Valid on Production: ', production+'\n' - + 'Valid on Staging: ', staging+'\n' - + `Expiry date: ${weekday[expiryDate.getDay()]},${expiryDate.getDate()} ${shortMnthNames[expiryDate.getMonth()]} ${expiryDate.getFullYear()}\n` - + `Issue date: ${weekday[issueDate.getDay()]},${issueDate.getDate()} ${shortMnthNames[issueDate.getMonth()]} ${issueDate.getFullYear()}`); + 'Token Name: ', tokenName + '\n' + + 'CpCode used: ', decodedToken["cpc"] + '\n' + + 'Valid for EWIDs: ', decodedToken["ewids"] + '\n' + + 'Valid on Production: ', production + '\n' + + 'Valid on Staging: ', staging + '\n' + + `Issue date: ${weekday[issueDate.getDay()]},${issueDate.getDate()} ${shortMnthNames[issueDate.getMonth()]} ${issueDate.getFullYear()} \n` + + `Expiry date: ${weekday[expiryDate.getDay()]},${expiryDate.getDate()} ${shortMnthNames[expiryDate.getMonth()]} ${expiryDate.getFullYear()}`); + let difference = Math.floor(ekvhelper.getDateDifference(expiryDate)); + if(difference >=0 && difference <= 30) { + console.log(` *** WARNING: Access Token will EXPIRE in less than ${difference} days! ***`); + } else if (difference <= -1) { + console.log(` *** Token already expired ***`); + } + // if save path is not provided print the token value - if(!savePath) { - console.log("value: "+tokenValue); + if (!savePath) { + console.log("value: " + tokenValue); } - + console.log('Namespace Permissions:') for (let ns of nameSpaceList) { let permission = decodedToken[ns]; - let permissionList = []; - permission.forEach(function(value) { - permissionList.push(permissions[value]); - }); - console.log(' '+ ns.substring(ns.indexOf('-')+1)+': [' + permissionList+']'); - } + let permissionList = []; + permission.forEach(function (value) { + permissionList.push(permissions[value]); + }); + console.log(' ' + ns.substring(ns.indexOf('-') + 1) + ': [' + permissionList + ']'); + } } export function getNameSpaceFromToken(decodedToken) { let nameSpaceList = []; - Object.keys(decodedToken).forEach(function(key){ - if(key.includes("namespace-")){ + Object.keys(decodedToken).forEach(function (key) { + if (key.includes("namespace-")) { nameSpaceList.push(key); } }) } enum permissions { -r = "READ", -w = "WRITE", -d = "DELETE" + r = "READ", + w = "WRITE", + d = "DELETE" } diff --git a/src/edgekv/ekv-service.ts b/src/edgekv/ekv-service.ts index 93bb4fb..5dc9071 100644 --- a/src/edgekv/ekv-service.ts +++ b/src/edgekv/ekv-service.ts @@ -55,4 +55,13 @@ export function createEdgeKVToken(tokenName: string, permissionList, allowOnStg: "name": tokenName, "allow_on_production": allowOnProd, "allow_on_staging": allowOnStg, "ewids":ewids ,"expiry": expiry, "namespace_permissions": permissionList }; return httpEdge.postJson(`${EDGEKV_API_BASE}/tokens`, body).then(r => r.body).catch(err => error.handleError(err)); -} \ No newline at end of file +} + +export function getSingleToken(tokenName: string) { + return httpEdge.getJson(`${EDGEKV_API_BASE}/tokens/${tokenName}`).then(r => r.body).catch(err => error.handleError(err)); +} + +export function getTokenList() { + return httpEdge.getJson(`${EDGEKV_API_BASE}/tokens`).then(r => r.body).catch(err => error.handleError(err)); +} +// } \ No newline at end of file diff --git a/src/edgekv/http-error-message.ts b/src/edgekv/http-error-message.ts index 6e6deb2..7ce8ec2 100644 --- a/src/edgekv/http-error-message.ts +++ b/src/edgekv/http-error-message.ts @@ -1,3 +1,5 @@ export enum ErrorMessage { permissionError = "ERROR: Operation could not be performed. The identity is not authorized to manage any context.", + initializeError_403 = "ERROR: EdgeKV Initialization failed (You don't have permission to access that resource.). Please make sure you have the EdgeKV product added to your contract.", + initStatusError_403 = "ERROR: Unable to retrieve EdgeKV status. You don't have permission to access that resource. Please make sure you have the EdgeKV product added to your contract." } \ No newline at end of file