UNPKG

@azure/data-tables

Version:
131 lines 5.94 kB
// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. import { fromAccountConnectionString, getAccountConnectionString, } from "./accountConnectionString.js"; const DevelopmentConnectionString = "DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;TableEndpoint=http://127.0.0.1:10002/devstoreaccount1"; /** * This function parses a connection string into a set of * parameters to pass to be passed to TableClientService, * depending on the connection string type these parameter would * contain: * - Account Connection String: A pipeline to sign the request with a SharedKey * - SAS Connection String: Attach a SAS token to the storage account url for authentication * @param connectionString - Connection string to parse * @param options - TableService client options */ export function getClientParamsFromConnectionString(connectionString, options = {}) { if (connectionString.toLowerCase().indexOf("usedevelopmentstorage=true") !== -1) { connectionString = DevelopmentConnectionString; options.allowInsecureConnection = true; } const extractedCreds = extractConnectionStringParts(connectionString); if (extractedCreds.kind === "AccountConnString") { return fromAccountConnectionString(extractedCreds, options); } else if (extractedCreds.kind === "SASConnString") { return { url: `${extractedCreds.url}?${extractedCreds.accountSas}`, options, }; } else { throw new Error("Connection string must be either an Account connection string or a SAS connection string"); } } /** * Extracts the parts of an Storage account connection string. * * @param connectionString - Connection string. * @returns String key value pairs of the storage account's url and credentials. */ export function extractConnectionStringParts(connectionString) { // Matching TableEndpoint in the Account connection string let tableEndpoint = getValueInConnString(connectionString, "TableEndpoint"); // Slicing off '/' at the end if exists // (The methods that use `extractConnectionStringParts` expect the url to not have `/` at the end) tableEndpoint = tableEndpoint.endsWith("/") ? tableEndpoint.slice(0, -1) : tableEndpoint; if (isAccountConnectionString(connectionString)) { return getAccountConnectionString(getValueInConnString(connectionString, "AccountName"), getValueInConnString(connectionString, "AccountKey"), getValueInConnString(connectionString, "DefaultEndpointsProtocol"), getValueInConnString(connectionString, "EndpointSuffix"), tableEndpoint); } else { return getSASConnectionString(connectionString, tableEndpoint); } } /** * Checks whether a connection string is an Account Connection string or not */ function isAccountConnectionString(connectionString) { const lowercaseConnectionString = connectionString.toLowerCase(); return (lowercaseConnectionString.search("defaultendpointsprotocol=") !== -1 && lowercaseConnectionString.search("accountkey=") !== -1); } function getSASConnectionString(connectionString, tableEndpoint) { const accountName = getAccountNameFromUrl(tableEndpoint); const accountSas = getValueInConnString(connectionString, "SharedAccessSignature"); if (!tableEndpoint) { throw new Error("Invalid TableEndpoint in the provided SAS Connection String"); } else if (!accountSas) { throw new Error("Invalid SharedAccessSignature in the provided SAS Connection String"); } else if (!accountName) { throw new Error("Invalid AccountName in the provided SAS Connection String"); } return { kind: "SASConnString", url: tableEndpoint, accountName, accountSas }; } function getValueInConnString(connectionString, argument) { const searchKey = argument.toLowerCase(); const elements = connectionString.split(";").filter((e) => Boolean(e)); for (const element of elements) { const trimmedElement = element.trim(); const [elementKey, value] = getValuePair(trimmedElement); const key = elementKey.toLowerCase(); if (key === searchKey) { return value; } } return ""; } function getValuePair(kvp) { // If the string is not in kvp format <key>=<valye> return an empty array if (!kvp || kvp.indexOf("=") === -1) { return []; } // Get the substring before the first '=' const key = kvp.substr(0, kvp.indexOf("=")); // Get the substring after the first '=' const value = kvp.substr(kvp.indexOf("=") + 1); return [key, value]; } /** * Extracts account name from the url * @param url - URL to extract the account name from * @returns The account name */ function getAccountNameFromUrl(url) { if (!url) { return url; } const parsedUrl = new URL(url); let accountName; const host = parsedUrl.host || ""; const path = parsedUrl.pathname || ""; const hostParts = host.split("."); const pathParts = path.split("/"); if (hostParts.length >= 1 && hostParts[1] === "table") { // `${defaultEndpointsProtocol}://${accountName}.table.${endpointSuffix}`; // Slicing off '/' at the end if exists url = url.endsWith("/") ? url.slice(0, -1) : url; accountName = host.split(".")[0]; } else if (pathParts.length >= 1) { // IPv4/IPv6 address hosts... Example - http://192.0.0.10:10001/devstoreaccount1/ // Single word domain without a [dot] in the endpoint... Example - http://localhost:10001/devstoreaccount1/ // .getPath() -> /devstoreaccount1/ accountName = pathParts[1]; } else { throw new Error("Unable to extract accountName with provided information."); } return accountName; } //# sourceMappingURL=connectionString.js.map