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.12.0 to 1.13.0

lib/authentication/authentication_types.js

36

index.d.ts

@@ -85,2 +85,7 @@ /*

ERR_CONN_CREATE_INVALID_DISABLE_SAML_URL_CHECK = 404051,
ERR_CONN_CREATE_INVALID_CLIENT_REQUEST_MFA_TOKEN = 404052;
ERR_CONN_CREATE_MISSING_HOST = 404053;
ERR_CONN_CREATE_INVALID_HOST = 404054;
ERR_CONN_CREATE_INVALID_PASSCODE_IN_PASSWORD = 404055;
ERR_CONN_CREATE_INVALID_PASSCODE = 404056;

@@ -238,2 +243,8 @@ // 405001

keepAlive?: boolean;
/**
* If the user wants to use their own credential manager for SSO or MFA token caching,
* pass the custom credential manager to this option.
*/
customCredentialManager?: object;
}

@@ -431,3 +442,2 @@

//Connection options Options but not on the web document.
/**

@@ -473,2 +483,18 @@ * Set whether the retry reason is included or not in the retry url.

validateDefaultParameters?: boolean;
/**
* The option to set the location where the token will be saved for the token authentication (MFA and SSO).
* The path must include the folder path only.
*/
credentialCacheDir?: string;
/**
* The option to include the passcode from DUO into the password.
*/
passcodeInPassword?: boolean;
/**
* The option to pass passcode from DUO.
*/
passcode?: string
}

@@ -529,3 +555,3 @@

*/
getQueryStatus(queryId: string): string;
getQueryStatus(queryId: string): Promise<string>;

@@ -535,3 +561,3 @@ /**

*/
getQueryStatusThrowIfError(queryId: string): string;
getQueryStatusThrowIfError(queryId: string): Promise<string>;

@@ -541,3 +567,3 @@ /**

*/
getResultsFromQueryId(options: StatementOption): RowStatement | FileAndStageBindStatement;
getResultsFromQueryId(options: StatementOption): Promise<RowStatement | FileAndStageBindStatement>;

@@ -557,3 +583,3 @@ /**

*/
serialize(): String;
serialize(): string;
}

@@ -560,0 +586,0 @@

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

const mfaAuthenticator = require ('./authentication_types.js').USER_PWD_MFA_AUTHENTICATOR;
/**

@@ -14,17 +16,51 @@ * Creates a default authenticator.

*/
function AuthDefault(password) {
function AuthDefault(connectionConfig) {
const password = connectionConfig.password;
const mfaToken = connectionConfig.mfaToken;
const passcode = connectionConfig.getPasscode();
const isPasscodeInPassword = connectionConfig.getPasscodeInPassword();
/**
* Update JSON body with password.
*
* @param {JSON} body
*
* @returns {null}
*/
* Update JSON body with password or token.
*
* @param {JSON} body
*
* @returns {null}
*/
this.updateBody = function (body) {
body['data']['PASSWORD'] = password;
if (isMFAAuth()) {
setMFASessionParams(body);
}
};
this.authenticate = async function () {};
function isMFAAuth() {
return ( connectionConfig.getAuthenticator() === mfaAuthenticator || mfaToken || passcode || isPasscodeInPassword);
}
function setMFASessionParams(body) {
body['data']['TOKEN'] = mfaToken;
body['data']['AUTHENTICATOR'] = mfaAuthenticator;
if (isPasscodeInPassword) {
body['data']['EXT_AUTHN_DUO_METHOD'] = 'passcode';
body['data']['passcodeInPassword'] = true;
} else if (passcode) {
body['data']['EXT_AUTHN_DUO_METHOD'] = 'passcode';
body['data']['PASSCODE'] = passcode;
} else {
body['data']['EXT_AUTHN_DUO_METHOD'] = 'push';
}
}
this.authenticate = async function () {
return;
};
this.reauthenticate = async function () {
return;
};
}
module.exports = AuthDefault;

40

lib/authentication/authentication.js

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

const Logger = require('../logger');
const AuthMFAToken = require('./auth_mfatoken');
const AuthenticationTypes = require('./authentication_types');
let authenticator;
const authenticationTypes =
{
DEFAULT_AUTHENTICATOR: 'SNOWFLAKE', // default authenticator name
EXTERNAL_BROWSER_AUTHENTICATOR: 'EXTERNALBROWSER',
KEY_PAIR_AUTHENTICATOR: 'SNOWFLAKE_JWT',
OAUTH_AUTHENTICATOR: 'OAUTH',
MFA_TOKEN_AUTHENTICATOR: 'USERNAME_PASSWORD_MFA',
ID_TOKEN_AUTHENTICATOR: 'ID_TOKEN',
};
exports.authenticationTypes = authenticationTypes;
/**

@@ -81,5 +67,5 @@ * Returns the JSON body to be sent when connecting.

let auth;
if (authType === authenticationTypes.DEFAULT_AUTHENTICATOR) {
auth = new AuthDefault(connectionConfig.password);
} else if (authType === authenticationTypes.EXTERNAL_BROWSER_AUTHENTICATOR) {
if (authType === AuthenticationTypes.DEFAULT_AUTHENTICATOR || authType === AuthenticationTypes.USER_PWD_MFA_AUTHENTICATOR) {
auth = new AuthDefault(connectionConfig);
} else if (authType === AuthenticationTypes.EXTERNAL_BROWSER_AUTHENTICATOR) {
if (connectionConfig.getClientStoreTemporaryCredential() && !!connectionConfig.idToken) {

@@ -90,11 +76,5 @@ auth = new AuthIDToken(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) {
} else if (authType === AuthenticationTypes.KEY_PAIR_AUTHENTICATOR) {
auth = new AuthKeypair(connectionConfig);
} else if (authType === authenticationTypes.OAUTH_AUTHENTICATOR) {
} else if (authType === AuthenticationTypes.OAUTH_AUTHENTICATOR) {
auth = new AuthOauth(connectionConfig.getToken());

@@ -106,6 +86,4 @@ } else if (this.isOktaAuth(authType)) {

Logger.getInstance().warn(`No authenticator found for '${authType}'. Using default authenticator as a fallback`);
auth = new AuthDefault(connectionConfig.password);
auth = new AuthDefault(connectionConfig);
}
authenticator = auth;
return auth;

@@ -123,5 +101,1 @@ };

};
exports.getCurrentAuth = function () {
return authenticator;
};

@@ -11,3 +11,3 @@ /*

const Logger = require('../logger');
const { authenticationTypes } = require('../authentication/authentication');
const AuthenticationTypes = require('../authentication/authentication_types');
const Util = require('../util');

@@ -25,3 +25,3 @@

return fixedConfiguration && fixedConfiguration.authenticator &&
fixedConfiguration.authenticator.toUpperCase() === authenticationTypes.OAUTH_AUTHENTICATOR &&
fixedConfiguration.authenticator.toUpperCase() === AuthenticationTypes.OAUTH_AUTHENTICATOR &&
!Util.string.isNotNullOrEmpty(fixedConfiguration.token);

@@ -28,0 +28,0 @@ }

@@ -13,3 +13,3 @@ /*

const GlobalConfig = require('../global_config');
const authenticationTypes = require('../authentication/authentication').authenticationTypes;
const AuthenticationTypes = require('../authentication/authentication_types');
const levenshtein = require('fastest-levenshtein');

@@ -66,2 +66,4 @@ const RowMode = require('./../constants/row_mode');

'credentialCacheDir',
'passcodeInPassword',
'passcode',
];

@@ -169,4 +171,4 @@

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

@@ -185,3 +187,3 @@ Errors.checkArgumentExists(Util.exists(options.username),

if (!Util.exists(options.authenticator) ||
options.authenticator === authenticationTypes.DEFAULT_AUTHENTICATOR) {
options.authenticator === AuthenticationTypes.DEFAULT_AUTHENTICATOR) {
// check for missing password

@@ -281,3 +283,3 @@ Errors.checkArgumentExists(Util.exists(options.password),

if (!Util.exists(authenticator)) {
authenticator = authenticationTypes.DEFAULT_AUTHENTICATOR;
authenticator = AuthenticationTypes.DEFAULT_AUTHENTICATOR;
} else {

@@ -483,11 +485,2 @@ authenticator = authenticator.toUpperCase();

if (validateDefaultParameters) {
for (const [key] of Object.entries(options)) {
if (!DEFAULT_PARAMS.includes(key)) {
const result = levenshtein.closest(key, DEFAULT_PARAMS);
Logger.getInstance().error(`'${key}' is an unknown connection parameter. Did you mean '${result}'?`);
}
}
}
let includeRetryReason = true;

@@ -558,2 +551,28 @@ if (Util.exists(options.includeRetryReason)) {

let passcodeInPassword = false;
if (Util.exists(options.passcodeInPassword)) {
Errors.checkArgumentValid(Util.isBoolean(options.passcodeInPassword),
ErrorCodes.ERR_CONN_CREATE_INVALID_PASSCODE_IN_PASSWORD);
passcodeInPassword = options.passcodeInPassword;
}
let passcode = null;
if (Util.exists(options.passcode)) {
Errors.checkArgumentValid(Util.isString(options.passcode),
ErrorCodes.ERR_CONN_CREATE_INVALID_PASSCODE);
passcode = options.passcode;
}
if (validateDefaultParameters) {
for (const [key] of Object.entries(options)) {
if (!DEFAULT_PARAMS.includes(key)) {
const result = levenshtein.closest(key, DEFAULT_PARAMS);
Logger.getInstance().error(`'${key}' is an unknown connection parameter. Did you mean '${result}'?`);
}
}
}
/**

@@ -864,2 +883,10 @@ * Returns an object that contains information about the proxy hostname, port,

this.getPasscodeInPassword = function () {
return passcodeInPassword;
};
this.getPasscode = function () {
return passcode;
};
// save config options

@@ -866,0 +893,0 @@ this.username = options.username;

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

const Authenticator = require('../authentication/authentication');
const AuthenticationTypes = require('../authentication/authentication_types');
const Logger = require('../logger');

@@ -24,3 +25,2 @@ const { isOktaAuth } = require('../authentication/authentication');

/**

@@ -219,3 +219,3 @@ * Creates a new Connection instance.

// external browser and okta are not compatible with connect() due to their usage of async functions
if (authenticationType === Authenticator.authenticationTypes.EXTERNAL_BROWSER_AUTHENTICATOR ||
if (authenticationType === AuthenticationTypes.EXTERNAL_BROWSER_AUTHENTICATOR ||
isOktaAuth(authenticationType)) {

@@ -227,3 +227,3 @@ throw Errors.createClientError(

// Get authenticator to use
const auth = Authenticator.getAuthenticator(connectionConfig, context.getHttpClient());
const auth = services.sf.getAuthenticator();

@@ -292,7 +292,6 @@ auth.authenticate(connectionConfig.getAuthenticator(),

const self = this;
const authType = Authenticator.authenticationTypes;
if (connectionConfig.getClientStoreTemporaryCredential()) {
const key = Util.buildCredentialCacheKey(connectionConfig.host,
connectionConfig.username, Authenticator.authenticationTypes.ID_TOKEN_AUTHENTICATOR);
connectionConfig.username, AuthenticationTypes.ID_TOKEN_AUTHENTICATOR);
if (GlobalConfig.getCredentialManager() === null) {

@@ -306,3 +305,3 @@ GlobalConfig.setCustomCredentialManager(new JsonCredentialManager(connectionConfig.getCredentialCacheDir()));

const key = Util.buildCredentialCacheKey(connectionConfig.host,
connectionConfig.username, authType.MFA_TOKEN_AUTHENTICATOR);
connectionConfig.username, AuthenticationTypes.USER_PWD_MFA_AUTHENTICATOR);
if (GlobalConfig.getCredentialManager() === null) {

@@ -315,3 +314,3 @@ GlobalConfig.setCustomCredentialManager(new JsonCredentialManager(connectionConfig.getCredentialCacheDir()));

// Get authenticator to use
const auth = Authenticator.getAuthenticator(connectionConfig, context.getHttpClient());
const auth = services.sf.getAuthenticator();

@@ -452,5 +451,5 @@ try {

const queries = queryResponse['data']['queries'];
let status = QueryStatus.code.NO_DATA; // default status
if (queries.length > 0) {
status = queries[0]['status'];
let status = QueryStatus.code.NO_QUERY_DATA; // default status
if ( queries.length > 0) {
status = queries[0]['status'];
}

@@ -480,11 +479,10 @@

this.getQueryStatusThrowIfError = async function (queryId) {
const status = await this.getQueryStatus(queryId);
const response = await getQueryResponse(queryId);
const status = extractQueryStatus(response);
let sqlState = null;
let message, code, sqlState = null;
if (this.isAnError(status) ) {
let message = response['message'] || '';
const code = response['code'] || -1;
if (this.isAnError(status)) {
const response = await getQueryResponse(queryId);
message = response['message'] || '';
code = response['code'] || -1;
if (response['data']) {

@@ -516,6 +514,7 @@ message += response['data']['queries'].length > 0 ? response['data']['queries'][0]['errorMessage'] : '';

while (queryStillExecuting) {
// Check if query is still running and trigger exception if it failed
// Check if query is still running.
// Trigger exception if it failed or there is no query data in the server.
status = await this.getQueryStatusThrowIfError(queryId);
queryStillExecuting = this.isStillRunning(status);
if (!queryStillExecuting) {
if (!queryStillExecuting || status === QueryStatus.code.NO_QUERY_DATA) {
break;

@@ -544,2 +543,7 @@ }

if (QueryStatus.code[status] === QueryStatus.code.NO_QUERY_DATA) {
throw Errors.createClientError(
ErrorCodes.ERR_GET_RESULTS_QUERY_ID_NO_DATA, true, queryId, status);
}
if (QueryStatus.code[status] !== QueryStatus.code.SUCCESS) {

@@ -546,0 +550,0 @@ throw Errors.createClientError(

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

exports[404054] = 'Invalid host. The specified value must be a string.';
exports[404055] = 'Invalid passcodeInPassword. The specified value must be a boolean';
exports[404056] = 'Invalid passcode. The specified value must be a string';

@@ -86,0 +88,0 @@ // 405001

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

code.NO_DATA = 'NO_DATA';
code.NO_QUERY_DATA = 'NO_QUERY_DATA';

@@ -23,0 +24,0 @@ // All running query statuses

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

codes.ERR_CONN_CREATE_INVALID_HOST = 404054;
codes.ERR_CONN_CREATE_INVALID_PASSCODE_IN_PASSWORD = 404055;
codes.ERR_CONN_CREATE_INVALID_PASSCODE = 404056;
// 405001

@@ -343,3 +344,3 @@ codes.ERR_CONN_CONNECT_INVALID_CALLBACK = 405001;

code: errorCode,
data: data,
data: { ...data, queryId: null },
message: message,

@@ -346,0 +347,0 @@ sqlState: sqlState

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

request = axios.request(requestOptions).then(response => {
sanitizeAxiosResponse(response);
if (Util.isFunction(options.callback)) {

@@ -44,2 +45,3 @@ return options.callback(null, normalizeResponse(response), response.data);

}).catch(err => {
sanitizeAxiosError(err);
if (Util.isFunction(options.callback)) {

@@ -81,12 +83,15 @@ if (err.response) { // axios returns error for not 2xx responses - let's unwrap it

HttpClient.prototype.requestAsync = async function (options) {
const requestOptions = prepareRequestOptions.call(this, options);
const response = await axios.request(requestOptions);
if (Util.isString(response['data']) &&
response['headers']['content-type'] === 'application/json') {
response['data'] = JSON.parse(response['data']);
try {
const requestOptions = prepareRequestOptions.call(this, options);
const response = await axios.request(requestOptions);
if (Util.isString(response['data']) &&
response['headers']['content-type'] === 'application/json') {
response['data'] = JSON.parse(response['data']);
}
sanitizeAxiosResponse(response);
return response;
} catch (err) {
sanitizeAxiosError(err);
throw err;
}
return response;
};

@@ -184,2 +189,18 @@

function sanitizeAxiosResponse(response) {
response.request = undefined;
if (response.config) {
response.config.data = undefined;
response.config.headers = undefined;
}
}
function sanitizeAxiosError(error) {
error.request = undefined;
error.config = undefined;
if (error.response) {
sanitizeAxiosResponse(error.response);
}
}
function prepareRequestOptions(options) {

@@ -186,0 +207,0 @@ const headers = normalizeHeaders(options.headers) || {};

@@ -59,5 +59,6 @@ /*

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

@@ -117,2 +118,4 @@ function isRetryableNetworkError(err) {

this.authenticator = Authenticator.getAuthenticator(connectionConfig, httpClient);
// create state objects for all the different states we can be in

@@ -500,2 +503,6 @@ const stateOptions =

this.getAuthenticator = function () {
return this.authenticator;
};
// if we don't have any tokens, start out as pristine

@@ -580,3 +587,3 @@ if (tokenInfo.isEmpty()) {

*/
function sendHttpRequest(requestOptions, httpClient) {
function sendHttpRequest(requestOptions, httpClient, auth) {
const realRequestOptions =

@@ -650,3 +657,2 @@ {

const data = body.data;
const auth = getCurrentAuth();

@@ -656,3 +662,3 @@ if (body.code === GSErrors.code.ID_TOKEN_INVALID && data.authnMethod === 'TOKEN') {

const key = Util.buildCredentialCacheKey(connectionConfig.host,
connectionConfig.username, authenticationTypes.ID_TOKEN_AUTHENTICATOR);
connectionConfig.username, AuthenticationTypes.ID_TOKEN_AUTHENTICATOR);
await GlobalConfig.getCredentialManager().remove(key);

@@ -693,7 +699,9 @@ await auth.reauthenticate(requestOptions.json);

this.snowflakeService = options.snowflakeService;
this.httpClient = options.httpClient;
this.connectionConfig = options.connectionConfig;
this.tokenInfo = options.tokenInfo;
const connectionConfig = options.connectionConfig;
const snowflakeService = options.snowflakeService;
const httpClient = options.httpClient;
const connectionConfig = options.connectionConfig;

@@ -745,3 +753,3 @@ ///////////////////////////////////////////////////////////////////////////

// issue the http request
sendHttpRequest(this.requestOptions, httpClient);
sendHttpRequest(this.requestOptions, httpClient, snowflakeService.getAuthenticator());
};

@@ -1150,3 +1158,3 @@

const key = Util.buildCredentialCacheKey(connectionConfig.host,
connectionConfig.username, authenticationTypes.MFA_TOKEN_AUTHENTICATOR);
connectionConfig.username, AuthenticationTypes.USER_PWD_MFA_AUTHENTICATOR);
await GlobalConfig.getCredentialManager().write(key, body.data.mfaToken);

@@ -1157,3 +1165,3 @@ }

const key = Util.buildCredentialCacheKey(connectionConfig.host,
connectionConfig.username, authenticationTypes.ID_TOKEN_AUTHENTICATOR);
connectionConfig.username, AuthenticationTypes.ID_TOKEN_AUTHENTICATOR);
await GlobalConfig.getCredentialManager().write(key, body.data.idToken);

@@ -1182,3 +1190,3 @@ }

const auth = getCurrentAuth();
const auth = parent.snowflakeService.getAuthenticator();
if (auth instanceof AuthOkta) {

@@ -1185,0 +1193,0 @@ Logger.getInstance().debug('OKTA authentication requires token refresh.');

{
"name": "snowflake-sdk",
"version": "1.12.0",
"version": "1.13.0",
"description": "Node.js driver for Snowflake",

@@ -5,0 +5,0 @@ "dependencies": {

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