Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

snowflake-sdk

Package Overview
Dependencies
Maintainers
2
Versions
64
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

snowflake-sdk - npm Package Compare versions

Comparing version 1.11.0 to 1.12.0

lib/authentication/auth_idtoken.js

214

index.d.ts

@@ -10,48 +10,4 @@ /*

declare module 'snowflake-sdk' {
export const enum RowMode {
ARRAY = 'array',
OBJECT = 'object',
OBJECT_WITH_RENAMED_DUPLICATED_COLUMNS = 'object_with_renamed_duplicated_columns',
}
export const enum LogLevel {
ERROR = 'ERROR',
WARN = 'WARN',
INFO = 'INFO',
DEBUG = 'DEBUG',
TRACE = 'TRACE',
}
export const enum DataType {
String = 'String',
Boolean = 'Boolean',
Number = 'Number',
Date = 'Date',
JSON = 'JSON',
Buffer = 'Buffer',
}
const enum StatementStatus {
Fetching = "fetching",
Complete = "complete",
}
const enum QueryStatus {
RUNNING = 'RUNNING',
ABORTING = 'ABORTING',
SUCCESS = 'SUCCESS',
FAILED_WITH_ERROR = 'FAILED_WITH_ERROR',
ABORTED = 'ABORTED',
QUEUED = 'QUEUED',
FAILED_WITH_INCIDENT = 'FAILED_WITH_INCIDENT',
DISCONNECTED = 'DISCONNECTED',
RESUMING_WAREHOUSE = 'RESUMING_WAREHOUSE',
// purposeful typo.Is present in QueryDTO.java
QUEUED_REPAIRING_WAREHOUSE = 'QUEUED_REPARING_WAREHOUSE',
RESTARTED = 'RESTARTED',
BLOCKED = 'BLOCKED',
NO_DATA = 'NO_DATA',
}
const enum ErrorCode {
enum ErrorCode {
// 400001

@@ -127,2 +83,5 @@ ERR_INTERNAL_ASSERT_FAILED = 400001,

ERR_CONN_CREATE_INVALID_DISABLE_CONSOLE_LOGIN = 404047,
ERR_CONN_CREATE_INVALID_FORCE_GCP_USE_DOWNSCOPED_CREDENTIAL = 404048,
ERR_CONN_CREATE_INVALID_REPRESENT_NULL_AS_STRING_NULL = 404050,
ERR_CONN_CREATE_INVALID_DISABLE_SAML_URL_CHECK = 404051,

@@ -133,5 +92,5 @@ // 405001

// 405501
ERR_CONN_CONNECT_STATUS_CONNECTING = 405501, // sql state: 08002
ERR_CONN_CONNECT_STATUS_CONNECTED = 405502, // sql state: 08002
ERR_CONN_CONNECT_STATUS_DISCONNECTED = 405503, // sql state: 08002
ERR_CONN_CONNECT_STATUS_CONNECTING = 405501, // sql state= 08002
ERR_CONN_CONNECT_STATUS_CONNECTED = 405502, // sql state= 08002
ERR_CONN_CONNECT_STATUS_DISCONNECTED = 405503, // sql state= 08002
ERR_CONN_CREATE_INVALID_AUTH_CONNECT = 405504,

@@ -148,4 +107,4 @@ ERR_CONN_CONNECT_INVALID_CLIENT_CONFIG = 405505,

// 407001
ERR_CONN_REQUEST_STATUS_PRISTINE = 407001, // sql state: 08003
ERR_CONN_REQUEST_STATUS_DISCONNECTED = 407002, // sql state: 08003
ERR_CONN_REQUEST_STATUS_PRISTINE = 407001, // sql state= 08003
ERR_CONN_REQUEST_STATUS_DISCONNECTED = 407002, // sql state= 08003

@@ -219,3 +178,3 @@ // 408001

ERR_GET_RESULTS_QUERY_ID_NO_DATA = 460002,
ERR_GET_RESULTS_QUERY_ID_NOT_SUCCESS_STATUS = 460003,
ERR_GET_RESULTS_QUERY_ID_NOT_SUCCESS_STATUS = 460003
}

@@ -228,3 +187,9 @@

export type StatementCallback = (err: SnowflakeError | undefined, stmt: RowStatement | FileAndStageBindStatement, rows?: Array<any> | undefined) => void;
export type ConnectionCallback = (err: SnowflakeError | undefined, conn: Connection) => void
export type ConnectionCallback = (err: SnowflakeError | undefined, conn: Connection) => void;
export type RowMode = "object" | "array" | "object_with_renamed_duplicated_columns";
export type LogLevel = "ERROR" | "WARN" | "INFO" | "DEBUG" | "TRACE";
export type DataType = "String" | "Boolean" | "Number" | "Date" | "JSON" | "Buffer";
export type QueryStatus = "RUNNING" | "ABORTING" | "SUCCESS" | "FAILED_WITH_ERROR" | "ABORTED" | "QUEUED" | "FAILED_WITH_INCIDENT" | "DISCONNECTED" | "RESUMING_WAREHOUSE" | "QUEUED_REPARING_WAREHOUSE" | "RESTARTED" | "BLOCKED" | "NO_DATA";
export type StatementStatus = "fetching" | "complete";
type PoolOptions = import('generic-pool').Options;

@@ -234,2 +199,9 @@ type Readable = import('stream').Readable;

export interface XMlParserConfigOption {
ignoreAttributes?: boolean;
alwaysCreateTextNode?: boolean;
attributeNamePrefix?: string;
attributesGroupName?: false | null | string;
}
export interface ConfigureOptions {

@@ -240,9 +212,14 @@ /**

*/
logLevel?: LogLevel | undefined;
logFilePath?: string | undefined;
logLevel?: LogLevel;
logFilePath?: string;
/**
* additionalLogToConsole is a Boolean value that indicates whether to send log messages also to the console when a filePath is specified.
*/
additionalLogToConsole?: boolean | null;
/**
* Check the ocsp checking is off.
*/
insecureConnect?: boolean | undefined;
insecureConnect?: boolean;

@@ -253,3 +230,3 @@ /**

*/
ocspFailOpen?: boolean | undefined;
ocspFailOpen?: boolean;

@@ -263,6 +240,8 @@ /**

xmlParserConfig?: XMlParserConfigOption;
/**
* Specifies whether to enable keep-alive functionality on the socket immediately after receiving a new connection request.
*/
keepAlive?: boolean,
keepAlive?: boolean;
}

@@ -315,2 +294,13 @@

/**
* Specifies the timeout, in milliseconds, for browser activities related to SSO authentication. The default value is 120000 (milliseconds).
*/
browserActionTimeout?: number;
/**
* Specifies the lists of hosts that the driver should connect to directly, bypassing the proxy server (e.g. *.amazonaws.com to bypass Amazon S3 access). For multiple hosts, separate the hostnames with a pipe symbol (|).
* You can also use an asterisk as a wild card. For example: noProxy: "*.amazonaws.com|*.my_company.com"
*/
noProxy?: string;
/**
* Specifies the hostname of an authenticated proxy server.

@@ -321,7 +311,22 @@ */

/**
* Specifies the username used to connect to an authenticated proxy server.
*/
proxyUser?: string;
/**
* Specifies the password for the user specified by proxyUser.
*/
proxyPassword?: string;
/**
* Specifies the port of an authenticated proxy server.
*/
proxyPort?: number;
/**
* Specifies the protocol used to connect to the authenticated proxy server. Use this property to specify the HTTP protocol: http or https.
*/
proxyProtocol?: string;
/**
* Specifies the serviceName.

@@ -367,2 +372,7 @@ */

/**
* Number of milliseconds to keep the connection alive with no response. Default: 90000 (1 minute 30 seconds).
*/
timeout?: number;
/**
* The default security role to use for the session after connecting.

@@ -385,3 +395,3 @@ */

*/
fetchAsString?: DataType[] | undefined;
fetchAsString?: DataType[];

@@ -414,2 +424,23 @@ /**

/**
* The max login timeout value. This value is either 0 or over 300.
*/
retryTimeout?: number;
/**
* The option to skip the SAML URL check in the Okta authentication
*/
disableSamlUrlCheck?: boolean;
/**
* The option to fetch all the null values in the columns as the string null.
*/
representNullAsStringNull?: boolean;
/**
* Number of threads for clients to use to prefetch large result sets. Valid values: 1-10.
*/
resultPrefetch?: number;
//Connection options Options but not on the web document.
/**
* Set whether the retry reason is included or not in the retry url.

@@ -420,11 +451,36 @@ */

/**
* The max login timeout value. This value is either 0 or over 300.
* Number of retries for the login request.
*/
retryTimeout?: number;
sfRetryMaxLoginRetries?: number;
/**
* The option to throw an error on the bind stage if this is enabled.
*/
forceStageBindError?: number;
/**
* The option to disable the query context cache.
*/
disableQueryContextCache?: boolean;
/**
* The option to disable GCS_USE_DOWNSCOPED_CREDENTIAL session parameter
*/
gcsUseDownscopedCredential?: boolean;
/**
* The option to use https request only for the snowflake server if other GCP metadata or configuration is already set on the machine.
* The default value is false.
*/
forceGCPUseDownscopedCredential?: boolean
forceGCPUseDownscopedCredential?: boolean;
/**
* The option to disable the web authentication console login.
*/
disableConsoleLogin?: boolean;
/**
* Turn on the validation function which checks whether all the connection configuration from users are valid or not.
*/
validateDefaultParameters?: boolean;
}

@@ -506,2 +562,7 @@

isAnError(): boolean;
/*
* Returns a serialized version of this connection.
*/
serialize(): String;
}

@@ -511,5 +572,10 @@

sqlText: string;
complete: StatementCallback;
complete?: StatementCallback;
/**
* Enable asynchronous queries by including asyncExec: true in the connection.execute method.
*/
asyncExec?: boolean;
/**
* The requestId is for resubmitting requests.

@@ -547,2 +613,13 @@ * Detailed Information: https://docs.snowflake.com/en/developer-guide/node-js/nodejs-driver-execute.

parameters?: Record<string, any>;
/**
* Returns the rowMode string value ('array', 'object' or 'object_with_renamed_duplicated_columns'). Could be null or undefined.
*/
rowMode?: RowMode;
/**
* Current working directory to use for GET/PUT execution using relative paths from a client location
* that is different from the connector directory.
*/
cwd?: string;
}

@@ -614,6 +691,9 @@

/**
* Cancels this statement if possible.
*/
cancel(callback?: StatementCallback): void;
/**
* Streams the rows in this statement's result. If start and end values are
* specified, only rows in the specified range are streamed.
*
* @param {Object} options
*/

@@ -626,4 +706,2 @@ streamRows(options?: StreamOptions): Readable;

* callback will only be invoked on rows in the specified range.
*
* @param {Object} options
*/

@@ -783,3 +861,3 @@ fetchRows(options?: StreamOptions): Readable;

end?: number;
fetchAsString?: DataType[] | undefined;
fetchAsString?: DataType[];
}

@@ -816,2 +894,2 @@

export function createPool(options: ConnectionOptions, poolOptions?: PoolOptions): Pool<Connection>;
}
}

@@ -14,3 +14,3 @@ /*

const REGEX_SNOWFLAKE_ENDPOINT = /.snowflakecomputing.com$/;
const REGEX_SNOWFLAKE_ENDPOINT = /.snowflakecomputing./;

@@ -17,0 +17,0 @@ const ocspFailOpenWarning =

@@ -20,6 +20,9 @@ /*

*/
function AuthKeypair(privateKey, privateKeyPath, privateKeyPass, cryptomod, jwtmod, filesystem) {
function AuthKeypair(connectionConfig, cryptomod, jwtmod, filesystem) {
const crypto = typeof cryptomod !== 'undefined' ? cryptomod : require('crypto');
const jwt = typeof jwtmod !== 'undefined' ? jwtmod : require('jsonwebtoken');
const fs = typeof filesystem !== 'undefined' ? filesystem : require('fs');
let privateKey = connectionConfig.getPrivateKey();
const privateKeyPath = connectionConfig.getPrivateKeyPath();
const privateKeyPass = connectionConfig.getPrivateKeyPass();

@@ -138,3 +141,3 @@ let jwtToken;

const currentTime = Date.now();
const jwtTokenExp = currentTime + LIFETIME;
const jwtTokenExp = currentTime + (LIFETIME * 1000);

@@ -152,4 +155,13 @@ // Create payload containing jwt token and lifetime span

};
this.reauthenticate = async function (body) {
this.authenticate(connectionConfig.getAuthenticator(),
connectionConfig.getServiceName(),
connectionConfig.account,
connectionConfig.username);
this.updateBody(body);
};
}
module.exports = AuthKeypair;

@@ -54,2 +54,3 @@ /*

body['data']['PROOF_KEY'] = proofKey;
body['data']['AUTHENTICATOR'] = 'EXTERNALBROWSER';
};

@@ -56,0 +57,0 @@

@@ -10,3 +10,5 @@ /*

const AuthOkta = require('./auth_okta');
const AuthIDToken = require('./auth_idtoken');
const Logger = require('../logger');
const AuthMFAToken = require('./auth_mfatoken');

@@ -21,2 +23,4 @@ let authenticator;

OAUTH_AUTHENTICATOR: 'OAUTH',
MFA_TOKEN_AUTHENTICATOR: 'USERNAME_PASSWORD_MFA',
ID_TOKEN_AUTHENTICATOR: 'ID_TOKEN',
};

@@ -81,7 +85,15 @@

} else if (authType === authenticationTypes.EXTERNAL_BROWSER_AUTHENTICATOR) {
auth = new AuthWeb(connectionConfig, httpClient);
if (connectionConfig.getClientStoreTemporaryCredential() && !!connectionConfig.idToken) {
auth = new AuthIDToken(connectionConfig, httpClient);
} else {
auth = new AuthWeb(connectionConfig, httpClient);
}
} else if (authType === authenticationTypes.MFA_TOKEN_AUTHENTICATOR) {
if (connectionConfig.getClientRequestMFAToken() && !!connectionConfig.mfaToken) {
auth = new AuthMFAToken(connectionConfig);
} else {
auth = new AuthDefault(connectionConfig.password);
}
} else if (authType === authenticationTypes.KEY_PAIR_AUTHENTICATOR) {
auth = new AuthKeypair(connectionConfig.getPrivateKey(),
connectionConfig.getPrivateKeyPath(),
connectionConfig.getPrivateKeyPass());
auth = new AuthKeypair(connectionConfig);
} else if (authType === authenticationTypes.OAUTH_AUTHENTICATOR) {

@@ -88,0 +100,0 @@ auth = new AuthOauth(connectionConfig.getToken());

@@ -9,2 +9,3 @@ /*

const Errors = require('../errors');
const path = require('path');
const ErrorCodes = Errors.codes;

@@ -17,2 +18,3 @@ const NativeTypes = require('./result/data_types').NativeTypes;

const DataTypes = require('./result/data_types');
const Logger = require('../logger');
const WAIT_FOR_BROWSER_ACTION_TIMEOUT = 120000;

@@ -58,9 +60,10 @@ const DEFAULT_PARAMS =

'retryTimeout',
'clientRequestMFAToken',
'clientStoreTemporaryCredential',
'disableConsoleLogin',
'forceGCPUseDownscopedCredential',
'disableSamlUrlCheck',
'representNullAsStringNull',
'disableSamlURLCheck'
'disableSamlURLCheck',
'credentialCacheDir',
];
const Logger = require('../logger');

@@ -71,3 +74,6 @@ function consolidateHostAndAccount(options) {

let realRegion = undefined;
const protocol = options.protocol || 'https';
const port = Util.exists(options.port) ? Util.format(':%s', options.port) : '';
if (Util.exists(options.region)) {

@@ -87,24 +93,13 @@ Errors.checkArgumentValid(Util.isCorrectSubdomain(options.region), ErrorCodes.ERR_CONN_CREATE_INVALID_REGION_REGEX);

}
if (!Util.exists(options.host)) {
options.host = Util.constructHostname(realRegion, realAccount);
}
}
if (!Util.isString(options.accessUrl) || !Util.exists(options.accessUrl)) {
if (options.region === 'us-west-2') {
options.region = '';
}
if (Util.exists(options.host)) {
options.accessUrl = Util.format('https://%s', options.host);
} else if (dotPos < 0 && Util.isString(options.region) && options.region.length > 0) {
options.accessUrl = Util.format('https://%s.%s.snowflakecomputing.com', options.account, options.region);
} else {
options.accessUrl = Util.format('https://%s.snowflakecomputing.com', options.account);
}
} else if (!Util.exists(options.account)) {
if (Util.exists(options.accessUrl)) { //accessUrl is set in configuration
try {
const parsedUrl = url.parse(options.accessUrl);
Errors.checkArgumentValid(Util.exists(parsedUrl.hostname), ErrorCodes.ERR_CONN_CREATE_INVALID_ACCESS_URL);
if (!Util.exists(options.host)) {
options.host = parsedUrl.hostname;
}
const dotPos = parsedUrl.hostname.indexOf('.');
if (dotPos > 0) {
if (dotPos > 0 && !Util.exists(options.account)) {
realAccount = parsedUrl.hostname.substring(0, dotPos);

@@ -114,6 +109,21 @@ }

Errors.checkArgumentValid(
false, ErrorCodes.ERR_CONN_CREATE_INVALID_ACCESS_URL);
false, ErrorCodes.ERR_CONN_CREATE_MISSING_ACCOUNT);
}
} else if (Util.exists(options.host)) { //host is set in configuration
options.accessUrl = Util.format('%s://%s%s', protocol, options.host, port);
const dotPos = options.host.indexOf('.');
if (dotPos > 0 && !Util.exists(options.account)) {
realAccount = options.host.substring(0, dotPos);
} else {
realAccount = options.account;
}
} else if (Util.exists(options.account)) { //only account() is set in configuration
if (options.region === 'us-west-2') {
options.region = '';
}
options.host = Util.constructHostname(realRegion, realAccount);
options.accessUrl = Util.format('%s://%s%s', protocol, options.host, port);
}
if (Util.exists(realAccount) && options.accessUrl.endsWith('global.snowflakecomputing.com')) {
if (Util.exists(realAccount) && options.accessUrl.includes('global.snowflakecomputing')) {
const dashPos = realAccount.indexOf('-');

@@ -127,4 +137,7 @@ if (dashPos > 0) {

options.region = realRegion;
// check for missing password
// check for missing accessURL
Errors.checkArgumentExists(Util.exists(options.account), ErrorCodes.ERR_CONN_CREATE_MISSING_ACCOUNT);
// check for missing account
Errors.checkArgumentExists(Util.exists(options.accessUrl), ErrorCodes.ERR_CONN_CREATE_MISSING_ACCESS_URL);
}

@@ -161,4 +174,4 @@

if (!Util.exists(options.authenticator) ||
(options.authenticator !== authenticationTypes.OAUTH_AUTHENTICATOR &&
options.authenticator !== authenticationTypes.EXTERNAL_BROWSER_AUTHENTICATOR)) {
(options.authenticator.toUpperCase() !== authenticationTypes.OAUTH_AUTHENTICATOR &&
options.authenticator.toUpperCase() !== authenticationTypes.EXTERNAL_BROWSER_AUTHENTICATOR)) {
// check for missing username

@@ -304,3 +317,3 @@ Errors.checkArgumentExists(Util.exists(options.username),

const token = options.token;
if (Util.exists(options.token)) {
if (Util.exists(token)) {
Errors.checkArgumentValid(Util.isString(token),

@@ -491,2 +504,10 @@ ErrorCodes.ERR_CONN_CREATE_INVALID_OAUTH_TOKEN);

let clientRequestMFAToken = false;
if (Util.exists(options.clientRequestMFAToken)) {
Errors.checkArgumentValid(Util.isBoolean(options.clientRequestMFAToken),
ErrorCodes.ERR_CONN_CREATE_INVALID_CLIENT_REQUEST_MFA_TOKEN);
clientRequestMFAToken = options.clientRequestMFAToken;
}
let disableConsoleLogin = true;

@@ -515,3 +536,3 @@ if (Util.exists(options.disableConsoleLogin)) {

}
let disableSamlURLCheck = false;

@@ -525,2 +546,19 @@ if (Util.exists(options.disableSamlURLCheck)) {

let clientStoreTemporaryCredential = false;
if (Util.exists(options.clientStoreTemporaryCredential)) {
Errors.checkArgumentValid(Util.isBoolean(options.clientStoreTemporaryCredential),
ErrorCodes.ERR_CONN_CREATE_INVALID_CLIENT_STORE_TEMPORARY_CREDENTIAL);
clientStoreTemporaryCredential = options.clientStoreTemporaryCredential;
}
let credentialCacheDir = null;
if (Util.exists(options.credentialCacheDir)) {
const absolutePath = path.resolve(options.credentialCacheDir);
Errors.checkArgumentValid(Util.validatePath(absolutePath),
ErrorCodes.ERR_CONN_CREATE_INVALID_CREDENTIAL_CACHE_DIR);
credentialCacheDir = absolutePath;
}
/**

@@ -749,3 +787,3 @@ * Returns an object that contains information about the proxy hostname, port,

/**
* Returns the bind threshold
* Returns the bind threshold
*

@@ -808,4 +846,4 @@ * @returns {string}

/**
* Returns whether the SAML URL check is enabled or not.
*
* Returns whether the SAML URL check is enabled or not.
*
* @returns {Boolean}

@@ -817,2 +855,18 @@ */

this.getCredentialCacheDir = function () {
return credentialCacheDir;
};
this.getClientRequestMFAToken = function () {
return clientRequestMFAToken;
};
/**
* Returns whether the auth token saves on the local machine or not.
*
* @returns {Boolean}
*/
this.getClientStoreTemporaryCredential = function () {
return clientStoreTemporaryCredential;
};
// save config options

@@ -819,0 +873,0 @@ this.username = options.username;

@@ -20,4 +20,5 @@ /*

const { init: initEasyLogging } = require('../logger/easy_logging_starter');
const GlobalConfig = require('../global_config');
const JsonCredentialManager = require('../authentication/secure_storage/json_credential_manager');
const PRIVATELINK_URL_SUFFIX = '.privatelink.snowflakecomputing.com';

@@ -165,3 +166,3 @@ /**

this.setupOcspPrivateLink = function (host) {
process.env.SF_OCSP_RESPONSE_CACHE_SERVER_URL = `http://ocsp.${host}/ocsp_response_cache.json`;
process.env.SF_OCSP_RESPONSE_CACHE_SERVER_URL = Util.createOcspResponseCacheServerUrl(host);
};

@@ -188,2 +189,4 @@

this.determineConnectionDomain = () => connectionConfig.accessUrl && connectionConfig.accessUrl.includes('snowflakecomputing.cn') ? 'CHINA' : 'GLOBAL';
/**

@@ -197,2 +200,4 @@ * Establishes a connection if we aren't in a fatal state.

this.connect = function (callback) {
const connectionDomain = this.determineConnectionDomain();
Logger.getInstance().info(`Connecting to ${connectionDomain} Snowflake domain`);
// invalid callback

@@ -203,3 +208,3 @@ Errors.checkArgumentValid(

if (connectionConfig.host.endsWith(PRIVATELINK_URL_SUFFIX)) {
if (Util.exists(connectionConfig.host) && Util.isPrivateLink(connectionConfig.host)) {
this.setupOcspPrivateLink(connectionConfig.host);

@@ -271,2 +276,5 @@ }

this.connectAsync = async function (callback) {
const connectingDomain = this.determineConnectionDomain();
Logger.getInstance().info(`Connecting to ${connectingDomain} Snowflake domain`);
// invalid callback

@@ -277,3 +285,3 @@ Errors.checkArgumentValid(

if (connectionConfig.host.endsWith(PRIVATELINK_URL_SUFFIX)) {
if (Util.isPrivateLink(connectionConfig.host)) {
this.setupOcspPrivateLink(connectionConfig.host);

@@ -285,4 +293,24 @@ }

// callback
const self = this;
const authType = Authenticator.authenticationTypes;
if (connectionConfig.getClientStoreTemporaryCredential()) {
const key = Util.buildCredentialCacheKey(connectionConfig.host,
connectionConfig.username, Authenticator.authenticationTypes.ID_TOKEN_AUTHENTICATOR);
if (GlobalConfig.getCredentialManager() === null) {
GlobalConfig.setCustomCredentialManager(new JsonCredentialManager(connectionConfig.getCredentialCacheDir()));
}
connectionConfig.idToken = await GlobalConfig.getCredentialManager().read(key);
}
if (connectionConfig.getClientRequestMFAToken()) {
const key = Util.buildCredentialCacheKey(connectionConfig.host,
connectionConfig.username, authType.MFA_TOKEN_AUTHENTICATOR);
if (GlobalConfig.getCredentialManager() === null) {
GlobalConfig.setCustomCredentialManager(new JsonCredentialManager(connectionConfig.getCredentialCacheDir()));
}
connectionConfig.mfaToken = await GlobalConfig.getCredentialManager().read(key);
}
// Get authenticator to use

@@ -301,25 +329,24 @@ const auth = Authenticator.getAuthenticator(connectionConfig, context.getHttpClient());

connectionConfig.account,
connectionConfig.username)
.then(() => {
// JSON for connection
const body = Authenticator.formAuthJSON(connectionConfig.getAuthenticator(),
connectionConfig.account,
connectionConfig.username,
connectionConfig.getClientType(),
connectionConfig.getClientVersion(),
connectionConfig.getClientEnvironment());
connectionConfig.username);
// JSON for connection
const body = Authenticator.formAuthJSON(connectionConfig.getAuthenticator(),
connectionConfig.account,
connectionConfig.username,
connectionConfig.getClientType(),
connectionConfig.getClientVersion(),
connectionConfig.getClientEnvironment());
// Update JSON body with the authentication values
auth.updateBody(body);
// Update JSON body with the authentication values
auth.updateBody(body);
// Request connection
services.sf.connect({
callback: connectCallback(self, callback),
json: body
});
});
// Request connection
services.sf.connect({
callback: connectCallback(self, callback),
json: body,
});
} catch (authErr) {
callback(authErr);
}
// return the connection to facilitate chaining

@@ -326,0 +353,0 @@ return this;

@@ -185,2 +185,6 @@ /*

}
const cwd = statementOptions.cwd;
if (Util.exists(cwd)) {
Errors.checkArgumentValid(Util.isString(cwd), ErrorCodes.ERR_CONN_FETCH_RESULT_INVALID_CWD);
}

@@ -201,2 +205,3 @@ // validate non-user-specified arguments

statementContext.rowMode = statementOptions.rowMode;
statementContext.cwd = statementOptions.cwd;

@@ -380,2 +385,6 @@ // set the statement type

if (Util.exists(statementOptions.cwd)) {
statementContext.cwd = statementOptions.cwd;
}
// validate non-user-specified arguments

@@ -382,0 +391,0 @@ Errors.assertInternal(Util.isObject(services));

@@ -26,2 +26,3 @@ /*

exports[403006] = 'Invalid keep alive value. The specified value must be a boolean.';
exports[403007] = 'Invalid custom credential manager value. The specified value must be an object, and it should have three methods: write, read, remove';

@@ -76,5 +77,10 @@ // 404001

exports[404047] = 'Invalid disableConsoleLogin. The specified value must be a boolean';
exports[404048] = 'Invalid disableGCPTokenUpload. The specified value must be a boolean';
exports[404048] = 'Invalid forceGCPUseDownscopedCredential. The specified value must be a boolean';
exports[404049] = 'Invalid clientStoreTemporaryCredential. The specified value must be a boolean.';
exports[404050] = 'Invalid representNullAsStringNull. The specified value must be a boolean';
exports[404051] = 'Invalid disableSamlURLCheck. The specified value must be a boolean';
exports[404052] = 'Invalid clientRequestMFAToken. The specified value must be a boolean.';
exports[404053] = 'A host must be specified.';
exports[404054] = 'Invalid host. The specified value must be a string.';

@@ -132,2 +138,3 @@ // 405001

exports[410008] = 'Invalid fetchAsString type: %s. The supported types are: String, Boolean, Number, Date, Buffer, and JSON.';
exports[410009] = 'Invalid cwd (current working directory) type: %s. The specified value must be a string.';

@@ -134,0 +141,0 @@ // 411001

@@ -12,3 +12,4 @@ /*

code.MASTER_TOKEN_EXPIRED = '390114';
code.ID_TOKEN_INVALID = '390195';
exports.code = code;

@@ -16,2 +16,3 @@ /*

const GlobalConfig = require('./global_config');
const { loadConnectionConfiguration } = require('./configuration/connection_configuration');

@@ -67,2 +68,12 @@ /**

if (connectionOptions == null) {
try {
connectionOptions = loadConnectionConfiguration();
} catch ( error ) {
Logger.getInstance().debug(`Problem during reading connection configuration from file: ${error.message}`);
Errors.checkArgumentExists(Util.exists(connectionOptions),
ErrorCodes.ERR_CONN_CREATE_MISSING_OPTIONS);
}
}
const validateCredentials = !config && (connectionOptions && !connectionOptions.sessionToken);

@@ -211,2 +222,10 @@ const connectionConfig =

}
const customCredentialManager = options.customCredentialManager;
if (Util.exists(customCredentialManager)) {
Errors.checkArgumentValid(Util.isObject(customCredentialManager),
ErrorCodes.ERR_GLOBAL_CONFIGURE_INVALID_CUSTOM_CREDENTIAL_MANAGER);
GlobalConfig.setCustomCredentialManager(customCredentialManager);
}
}

@@ -213,0 +232,0 @@ };

@@ -31,2 +31,3 @@ /*

codes.ERR_GLOBAL_CONFIGURE_INVALID_KEEP_ALIVE = 403006;
codes.ERR_GLOBAL_CONFIGURE_INVALID_CUSTOM_CREDENTIAL_MANAGER = 403007;

@@ -82,5 +83,10 @@ // 404001

codes.ERR_CONN_CREATE_INVALID_FORCE_GCP_USE_DOWNSCOPED_CREDENTIAL = 404048;
codes.ERR_CONN_CREATE_INVALID_CLIENT_STORE_TEMPORARY_CREDENTIAL = 404049;
codes.ERR_CONN_CREATE_INVALID_REPRESENT_NULL_AS_STRING_NULL = 404050;
codes.ERR_CONN_CREATE_INVALID_DISABLE_SAML_URL_CHECK = 404051;
codes.ERR_CONN_CREATE_INVALID_CLIENT_REQUEST_MFA_TOKEN = 404052;
codes.ERR_CONN_CREATE_MISSING_HOST = 404053;
codes.ERR_CONN_CREATE_INVALID_HOST = 404054;
// 405001

@@ -137,2 +143,3 @@ codes.ERR_CONN_CONNECT_INVALID_CALLBACK = 405001;

codes.ERR_CONN_FETCH_RESULT_INVALID_FETCH_AS_STRING_VALUES = 410008;
codes.ERR_CONN_FETCH_RESULT_INVALID_CWD = 410009;

@@ -139,0 +146,0 @@ // 411001

@@ -10,4 +10,2 @@ /*

const Logger = require('../logger');
const AES_CBC = 'aes-128-cbc';
const AES_ECB = 'aes-128-ecb';
const AES_BLOCK_SIZE = 128;

@@ -37,2 +35,10 @@ const blockSize = parseInt(AES_BLOCK_SIZE / 8); // in bytes

function aesCbc(keySizeInBytes) {
return `aes-${keySizeInBytes * 8}-cbc`;
}
function aesEcb(keySizeInBytes) {
return `aes-${keySizeInBytes * 8}-ecb`;
}
exports.EncryptionMetadata = EncryptionMetadata;

@@ -141,6 +147,6 @@

const ivData = getSecureRandom(blockSize);
const fileKey = getSecureRandom(blockSize);
const fileKey = getSecureRandom(keySize);
// Create cipher with file key, AES CBC, and iv data
let cipher = crypto.createCipheriv(AES_CBC, fileKey, ivData);
let cipher = crypto.createCipheriv(aesCbc(keySize), fileKey, ivData);
const encrypted = cipher.update(fileStream);

@@ -151,3 +157,3 @@ const final = cipher.final();

// Create key cipher with decoded key and AES ECB
cipher = crypto.createCipheriv(AES_ECB, decodedKey, null);
cipher = crypto.createCipheriv(aesEcb(keySize), decodedKey, null);

@@ -194,6 +200,6 @@ // Encrypt with file key

const ivData = getSecureRandom(blockSize);
const fileKey = getSecureRandom(blockSize);
const fileKey = getSecureRandom(keySize);
// Create cipher with file key, AES CBC, and iv data
let cipher = crypto.createCipheriv(AES_CBC, fileKey, ivData);
let cipher = crypto.createCipheriv(aesCbc(keySize), fileKey, ivData);

@@ -222,3 +228,3 @@ // Create temp file

// Create key cipher with decoded key and AES ECB
cipher = crypto.createCipheriv(AES_ECB, decodedKey, null);
cipher = crypto.createCipheriv(aesEcb(keySize), decodedKey, null);

@@ -270,2 +276,3 @@ // Encrypt with file key

const decodedKey = Buffer.from(encryptionMaterial[QUERY_STAGE_MASTER_KEY], BASE64);
const keySize = decodedKey.length;

@@ -291,3 +298,3 @@ // Get key bytes and iv bytes from base64 encoded value

// Create key decipher with decoded key and AES ECB
let decipher = crypto.createDecipheriv(AES_ECB, decodedKey, null);
let decipher = crypto.createDecipheriv(aesEcb(keySize), decodedKey, null);
const fileKey = Buffer.concat([

@@ -299,3 +306,3 @@ decipher.update(keyBytes),

// Create decipher with file key, iv bytes, and AES CBC
decipher = crypto.createDecipheriv(AES_CBC, fileKey, ivBytes);
decipher = crypto.createDecipheriv(aesCbc(keySize), fileKey, ivBytes);

@@ -302,0 +309,0 @@ await new Promise(function (resolve) {

@@ -67,2 +67,3 @@ /*

const command = context.sqlText;
const cwd = context.cwd;

@@ -604,3 +605,11 @@ let commandType;

// Get root directory of file path
const root = path.dirname(src);
let root = path.dirname(src);
// If cwd exists and root is relative . then replace with context's cwd
// Used for VS Code extension where extension cwd differs from user workspace dir
if (cwd && !path.isAbsolute(src)) {
const absolutePath = path.resolve(cwd, src);
root = path.dirname(absolutePath);
}
let dir;

@@ -671,2 +680,10 @@

localLocation = expandTilde(data['localLocation']);
// If cwd exists and root is relative . then replace with context's cwd
// Used for VS Code extension where extension cwd differs from user workspace dir
if (cwd && !path.isAbsolute(localLocation)) {
const absolutePath = path.resolve(cwd, localLocation);
localLocation = absolutePath;
}
const dir = fs.statSync(localLocation);

@@ -673,0 +690,0 @@ if (!dir.isDirectory()) {

@@ -6,3 +6,3 @@ /*

const crypto = require('crypto');
const fs = require('fs');
const fs = require('fs');
const path = require('path');

@@ -13,2 +13,3 @@ const struct = require('python-struct');

const glob = require('glob');
const Logger = require('../logger');

@@ -149,2 +150,27 @@ const resultStatus = {

function validateOnlyUserReadWritePermission(filePath) {
if (os.platform() === 'win32') {
return;
}
fs.accessSync(filePath, fs.constants.F_OK);
const mode = (fs.statSync(filePath)).mode;
const permission = (mode & 0o00777 | 0o600);
//This should be 600 permission, which means the file permission has not been changed by others.
if (permission === 0o600) {
Logger.getInstance().debug(`Validated that the user has only read and write permission for file: ${filePath}, Permission: ${permission}`);
} else {
throw new Error(`File permissions different than read/write for user. File: ${filePath}`);
}
}
function generateChecksum(str, algorithm, encoding) {
return crypto
.createHash(algorithm || 'sha256')
.update(str, 'utf8')
.digest(encoding || 'hex')
.substring(0, 32);
}
exports.getMatchingFilePaths = getMatchingFilePaths;
exports.validateOnlyUserReadWritePermission = validateOnlyUserReadWritePermission;
exports.generateChecksum = generateChecksum;

@@ -8,5 +8,5 @@ /*

const mkdirp = require('mkdirp');
const Errors = require('./errors');
const ErrorCodes = Errors.codes;
const Util = require('./util');
const Errors = require('./errors');
const Logger = require('./logger');

@@ -260,2 +260,14 @@ const { XMLParser, XMLValidator } = require('fast-xml-parser');

let credentialManager = null;
exports.setCustomCredentialManager = function (customCredentialManager) {
Errors.checkArgumentValid(Util.checkValidCustomCredentialManager(customCredentialManager),
ErrorCodes.ERR_GLOBAL_CONFIGURE_INVALID_CUSTOM_CREDENTIAL_MANAGER);
credentialManager = customCredentialManager;
Logger.getInstance().info('Custom credential manager is set by a user.');
};
exports.getCredentialManager = function () {
return credentialManager;
};

@@ -27,4 +27,7 @@ /*

* @param {Number} capacity Maximum capacity of the cache.
* @param {Number} sessionId Session for which the cache is created.
*/
function QueryContextCache(capacity) {
function QueryContextCache(capacity, sessionId) {
Logger.getInstance().debug(`Creating new QueryContextCache with capacity ${capacity} for session ${sessionId}`);
this.sessionId = sessionId;
this.capacity = capacity;

@@ -45,2 +48,3 @@ this.idMap = new Map(); // Map for id and QCC

this.sortTreeSet();
Logger.getInstance().trace(`QCC session ${this.sessionId} - Added QCE: ${JSON.stringify(qce)}`);
};

@@ -57,2 +61,3 @@

this.treeSet.delete(qce);
Logger.getInstance().trace(`QCC session ${this.sessionId} - Removed QCE: ${JSON.stringify(qce)}`);
};

@@ -63,3 +68,3 @@

* and add a new element received.
*{
*
* @param {Object} oldQCE an element exist in the cache

@@ -74,2 +79,4 @@ * @param {Object} newQCE a new element just received.

this.addQCE(newQCE);
Logger.getInstance().debug(`QCC session ${this.sessionId} - Replaced QCE: ${JSON.stringify(oldQCE)} with ${JSON.stringify(newQCE)}`);
};

@@ -88,3 +95,5 @@

QueryContextCache.prototype.merge = function (newQCE) {
Logger.getInstance().debug(`QCC session ${this.sessionId} - Merging QCE: ${JSON.stringify(newQCE)}`);
if (this.idMap.has(newQCE.id)) {
Logger.getInstance().debug(`QCC session ${this.sessionId} - Element id ${newQCE.id} found in cache`);

@@ -94,4 +103,5 @@ // ID found in the cache

if (newQCE.timestamp > qce.timestamp) {
Logger.getInstance().trace(`QCC session ${this.sessionId} - New element is more recent. Current timestamp: ${qce.timestamp}, new timestamp: ${newQCE.timestamp}`);
if (qce.priority === newQCE.priority) {
Logger.getInstance().trace(`QCC session ${this.sessionId} - Element priority (${qce.priority}) is the same`);
// Same priority, overwrite new data at same place

@@ -101,3 +111,3 @@ qce.timestamp = newQCE.timestamp;

} else {
Logger.getInstance().trace(`QCC session ${this.sessionId} - Element priority changed. Current priority: ${qce.priority}, new priority: ${newQCE.priority}`);
// Change in priority

@@ -107,8 +117,10 @@ this.replaceQCE(qce, newQCE);

} else if (newQCE.timestamp === qce.timestamp && qce.priority !== newQCE.priority) {
Logger.getInstance().trace(`QCC session ${this.sessionId} - Element timestamp is the same, but priority changes. Current priority: ${qce.priority}, new priority: ${newQCE.priority}`);
// Same read timestamp but change in priority
this.replaceQCE(qce, newQCE);
} else {
Logger.getInstance().trace(`QCC session ${this.sessionId} - Element is the same. Doing nothing.`);
}
} else {
Logger.getInstance().trace(`QCC session ${this.sessionId} - New element`);
// new id

@@ -120,6 +132,7 @@ if (this.priorityMap.has(newQCE.priority)) {

Logger.getInstance().trace(`QCC session ${this.sessionId} - Element with the same priority found: ${JSON.stringify(qce)}. Replacing with new element: ${JSON.stringify(newQCE)}`);
// Replace with new data
this.replaceQCE(qce, newQCE);
} else {
Logger.getInstance().debug(`QCC session ${this.sessionId} - Adding new element to the cache: ${JSON.stringify(newQCE)}`);
// new priority

@@ -137,4 +150,4 @@ // Add new element in the cache

QueryContextCache.prototype.checkCacheCapacity = function () {
Logger.getInstance().debug(
`checkCacheCapacity() called. treeSet size ${this.treeSet.size} cache capacity ${this.capacity}` );
Logger.getInstance().trace(
`QCC session ${this.sessionId} - checkCacheCapacity() called. treeSet size ${this.treeSet.size}, cache capacity ${this.capacity}`);

@@ -146,5 +159,4 @@ // remove elements based on priority

}
Logger.getInstance().debug(
`checkCacheCapacity() returns. treeSet size ${this.treeSet.size} cache capacity ${this.capacity}`,
);
Logger.getInstance().trace(
`QCC session ${this.sessionId} - checkCacheCapacity() returns. treeSet size ${this.treeSet.size}, cache capacity ${this.capacity}`);
};

@@ -154,7 +166,7 @@

QueryContextCache.prototype.clearCache = function () {
Logger.getInstance().debug('clearCache() called');
Logger.getInstance().trace(`QCC session ${this.sessionId} - clearCache() called`);
this.idMap.clear();
this.priorityMap.clear();
this.treeSet.clear();
Logger.getInstance().debug(`clearCache() returns. Number of entries in cache now ${this.treeSet.size}`,);
Logger.getInstance().trace(`QCC session ${this.sessionId} - clearCache() returns. Number of entries in cache now ${this.treeSet.size}`);
};

@@ -171,7 +183,7 @@

const stringifyData = JSON.stringify(data);
Logger.getInstance().debug(`deserializeQueryContext() called: data from server: ${stringifyData}`);
Logger.getInstance().debug(`QCC session ${this.sessionId} - deserializeQueryContext() called: data from server: ${stringifyData}`);
if (!data || stringifyData === '{}' || data.entries === null) {
this.clearCache();
Logger.getInstance().debug('deserializeQueryContext() returns');
Logger.getInstance().trace(`QCC session ${this.sessionId} - deserializeQueryContext() returns`);
this.logCacheEntries();

@@ -212,3 +224,3 @@ return;

Logger.getInstance().warn(
'deserializeQueryContextJson: deserializeQueryContextElement meets mismatch field type. Clear the QueryContextCache.');
`QCC session ${this.sessionId} - deserializeQueryContextJson: deserializeQueryContextElement meets mismatch field type. Clear the QueryContextCache.`);
this.clearCache();

@@ -221,3 +233,3 @@ return;

} catch (e) {
Logger.getInstance().debug(`deserializeQueryContextJson: Exception = ${e.getMessage}`, );
Logger.getInstance().debug(`QCC session ${this.sessionId} - deserializeQueryContextJson: Exception = ${e.getMessage}`);

@@ -240,5 +252,5 @@ // Not rethrowing. clear the cache as incomplete merge can lead to unexpected behavior.

entry.context = null;
Logger.getInstance().debug('deserializeQueryContextElement `context` field is empty');
Logger.getInstance().debug(`QCC session ${this.sessionId} - deserializeQueryContextElement \`context\` field is empty`);
} else {
Logger.getInstance().warn('deserializeQueryContextElement: `context` field is not String type');
Logger.getInstance().warn(`QCC session ${this.sessionId} - deserializeQueryContextElement: \`context\` field is not String type`);
return null;

@@ -251,8 +263,7 @@ }

QueryContextCache.prototype.logCacheEntries = function () {
this.treeSet.forEach(function (elem) {
Logger.getInstance().debug(
`Cache Entry: id: ${elem.id} timestamp: ${elem.timestamp} priority: ${elem.priority}`,
);
});
`QCC session ${this.sessionId} - Cache Entry: id: ${elem.id} timestamp: ${elem.timestamp} priority: ${elem.priority}`);
}, this);
};

@@ -289,2 +300,1 @@

module.exports = QueryContextCache;

@@ -58,4 +58,6 @@ /*

const Logger = require('../logger');
const { getCurrentAuth } = require('../authentication/authentication');
const GlobalConfig = require('../global_config');
const { authenticationTypes, getCurrentAuth } = require('../authentication/authentication');
const AuthOkta = require('../authentication/auth_okta');
const AuthKeypair = require('../authentication/auth_keypair');

@@ -157,2 +159,18 @@ function isRetryableNetworkError(err) {

/**
* Set the session id for the current SnowflakeService
* @param sessionId
*/
this.setSessionId = function (sessionId) {
this.sessionId = sessionId;
};
/**
* Get the session id.
* @returns {number}
*/
this.getSessionId = function () {
return this.sessionId;
};
/**
* Transitions to the Pristine state.

@@ -522,3 +540,5 @@ *

if (!connectionConfig.getDisableQueryContextCache()){
this.qcc = new QueryContextCache(size);
this.qcc = new QueryContextCache(size, this.getSessionId());
} else {
Logger.getInstance().debug(`QueryContextCache initialization skipped as it is disabled for connection with sessionId: ${this.sessionId}`);
}

@@ -629,2 +649,13 @@ };

const data = body.data;
const auth = getCurrentAuth();
if (body.code === GSErrors.code.ID_TOKEN_INVALID && data.authnMethod === 'TOKEN') {
Logger.getInstance().debug('ID Token being used has expired. Reauthenticating');
const key = Util.buildCredentialCacheKey(connectionConfig.host,
connectionConfig.username, authenticationTypes.ID_TOKEN_AUTHENTICATOR);
await GlobalConfig.getCredentialManager().remove(key);
await auth.reauthenticate(requestOptions.json);
return httpClient.request(realRequestOptions);
}
err = Errors.createOperationFailedError(

@@ -1070,3 +1101,13 @@ body.code, data, body.message,

}
if (Util.exists(this.connectionConfig.getClientRequestMFAToken())) {
sessionParameters.SESSION_PARAMETERS.CLIENT_REQUEST_MFA_TOKEN =
this.connectionConfig.getClientRequestMFAToken();
}
if (Util.exists(this.connectionConfig.getClientStoreTemporaryCredential())) {
sessionParameters.SESSION_PARAMETERS.CLIENT_STORE_TEMPORARY_CREDENTIAL =
this.connectionConfig.getClientStoreTemporaryCredential();
}
Util.apply(json.data, clientInfo);

@@ -1086,3 +1127,3 @@ Util.apply(json.data, sessionParameters);

const parent = this;
const requestCallback = function (err, body) {
const requestCallback = async function (err, body) {
// clear credential-related information

@@ -1095,2 +1136,5 @@ connectionConfig.clearCredentials();

Errors.assertInternal(Util.exists(body.data));
parent.snowflakeService.setSessionId(body.data.sessionId);
Logger.getInstance().debug(`New session with id ${parent.snowflakeService.getSessionId()} initialized`);

@@ -1103,2 +1147,14 @@ // update the parameters

if (connectionConfig.getClientRequestMFAToken() && body.data.mfaToken) {
const key = Util.buildCredentialCacheKey(connectionConfig.host,
connectionConfig.username, authenticationTypes.MFA_TOKEN_AUTHENTICATOR);
await GlobalConfig.getCredentialManager().write(key, body.data.mfaToken);
}
if (connectionConfig.getClientStoreTemporaryCredential() && body.data.idToken) {
const key = Util.buildCredentialCacheKey(connectionConfig.host,
connectionConfig.username, authenticationTypes.ID_TOKEN_AUTHENTICATOR);
await GlobalConfig.getCredentialManager().write(key, body.data.idToken);
}
// we're now connected

@@ -1120,3 +1176,3 @@ parent.snowflakeService.transitionToConnected();

if (sleep <= 0) {
Logger.getInstance().debug('Reached out to the Login Timeout');
Logger.getInstance().debug('Reached out to the max Login Timeout');
parent.snowflakeService.transitionToDisconnected();

@@ -1140,2 +1196,6 @@ }

} else {
if (auth instanceof AuthKeypair) {
Logger.getInstance().debug('AuthKeyPair authentication requires token refresh.');
await auth.reauthenticate(context.options.json);
}
setTimeout(sendRequest, sleep * 1000);

@@ -1594,2 +1654,2 @@ return;

};
}
}

@@ -8,2 +8,6 @@ /*

const os = require('os');
const Logger = require('./logger');
const fs = require('fs');
const Errors = require('./errors');
const ErrorCodes = Errors.codes;

@@ -516,3 +520,3 @@ /**

if (region === 'us-west-2') {
region = '';
host = account + '.snowflakecomputing.com';
} else if (region != null) {

@@ -522,3 +526,8 @@ if (account.indexOf('.') > 0) {

}
host = account + '.' + region + '.snowflakecomputing.com';
if (region.startsWith('cn-') || region.startsWith('CN-')) {
host = account + '.' + region + '.snowflakecomputing.cn';
} else {
host = account + '.' + region + '.snowflakecomputing.com';
}
} else {

@@ -531,2 +540,20 @@ host = account + '.snowflakecomputing.com';

/**
* Returns true if host indicates private link
*
* @returns {boolean}
*/
exports.isPrivateLink = function (host) {
Errors.checkArgumentExists(this.exists(host), ErrorCodes.ERR_CONN_CREATE_MISSING_HOST);
return host.toLowerCase().includes('privatelink.snowflakecomputing.');
};
/**
* Returns true if host indicates private link
*
* @returns {boolean}
*/
exports.createOcspResponseCacheServerUrl = function (host) {
return `http://ocsp.${host}/ocsp_response_cache.json`;
};
/**
* Returns if command is a PUT command

@@ -594,3 +621,3 @@ *

exports.isCorrectSubdomain = function (value) {
const subdomainRegex = RegExp(/^\w([\w.-]+\w|)$/i);
const subdomainRegex = RegExp(/^\w+([.-]\w+)*$/i);
return subdomainRegex.test(value);

@@ -659,3 +686,35 @@ };

exports.buildCredentialCacheKey = function (host, username, credType) {
if (!host || !username || !credType) {
Logger.getInstance().debug('Cannot build the credential cache key because one of host, username, and credType is null');
return null;
}
return `{${host.toUpperCase()}}:{${username.toUpperCase()}}:{SF_NODE_JS_DRIVER}:{${credType.toUpperCase()}}`;
};
/**
*
* @param {Object} customCredentialManager
* @returns
*/
exports.checkValidCustomCredentialManager = function (customCredentialManager) {
if ( typeof customCredentialManager !== 'object') {
return false;
}
const requireMethods = ['write', 'read', 'remove'];
for (const method of requireMethods) {
if (!Object.hasOwnProperty.call(customCredentialManager, method) || typeof customCredentialManager[method] !== 'function') {
return false;
}
}
return true;
};
exports.checkParametersDefined = function (...parameters) {
return parameters.every((element) => element !== undefined && element !== null);
};
/**
* remove http:// or https:// from the input, e.g. used with proxy URL

@@ -669,2 +728,34 @@ * @param input

exports.buildCredentialCacheKey = function (host, username, credType) {
if (!host || !username || !credType) {
Logger.getInstance().debug('Cannot build the credential cache key because one of host, username, and credType is null');
return null;
}
return `{${host.toUpperCase()}}:{${username.toUpperCase()}}:{SF_NODE_JS_DRIVER}:{${credType.toUpperCase()}}`;
};
/**
*
* @param {Object} customCredentialManager
* @returns
*/
exports.checkValidCustomCredentialManager = function (customCredentialManager) {
if ( typeof customCredentialManager !== 'object') {
return false;
}
const requireMethods = ['write', 'read', 'remove'];
for (const method of requireMethods) {
if (!Object.hasOwnProperty.call(customCredentialManager, method) || typeof customCredentialManager[method] !== 'function') {
return false;
}
}
return true;
};
exports.checkParametersDefined = function (...parameters) {
return parameters.every((element) => element !== undefined && element !== null);
};
exports.shouldPerformGCPBucket = function (accessToken) {

@@ -714,1 +805,11 @@ return !!accessToken && process.env.SNOWFLAKE_FORCE_GCP_USE_DOWNSCOPED_CREDENTIAL !== 'true';

};
exports.validatePath = function (dir) {
try {
const stat = fs.statSync(dir);
return stat.isDirectory();
} catch {
Logger.getInstance().error('The path location is invalid. Please check this location is accessible or existing');
return false;
}
};
{
"name": "snowflake-sdk",
"version": "1.11.0",
"version": "1.12.0",
"description": "Node.js driver for Snowflake",

@@ -8,3 +8,3 @@ "dependencies": {

"@aws-sdk/node-http-handler": "^3.374.0",
"@azure/storage-blob": "^12.11.0",
"@azure/storage-blob": "12.18.x",
"@google-cloud/storage": "^7.7.0",

@@ -34,2 +34,3 @@ "@techteamer/ocsp": "1.0.1",

"simple-lru-cache": "^0.0.2",
"toml": "^3.0.0",
"uuid": "^8.3.2",

@@ -36,0 +37,0 @@ "winston": "^3.1.0"

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc