@datacamp/learn-vm-scripts 1.13.6 → 1.13.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +21 -6
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -285,6 +285,7 @@ var resetChrome = async ({ userDataDir }) => {
|
|
|
285
285
|
var USERNAME_SELECTOR = 'input[autocomplete="username"]';
|
|
286
286
|
var PASSWORD_SELECTOR = 'input[autocomplete="current-password"]';
|
|
287
287
|
var OTP_SELECTOR = 'input[autocomplete="one-time-code"]';
|
|
288
|
+
var SELECTOR_TIMEOUT = 7500;
|
|
288
289
|
async function loginToSnowflake({
|
|
289
290
|
url,
|
|
290
291
|
username,
|
|
@@ -294,7 +295,7 @@ async function loginToSnowflake({
|
|
|
294
295
|
}) {
|
|
295
296
|
logger.log("Navigating to Snowflake login page...");
|
|
296
297
|
await page.goto(ensureHttps(url));
|
|
297
|
-
await page.waitForSelector(USERNAME_SELECTOR);
|
|
298
|
+
await page.waitForSelector(USERNAME_SELECTOR, { timeout: SELECTOR_TIMEOUT });
|
|
298
299
|
const usernameField = await page.$(USERNAME_SELECTOR);
|
|
299
300
|
if (!usernameField) {
|
|
300
301
|
throw new Error("Username field not found");
|
|
@@ -302,7 +303,7 @@ async function loginToSnowflake({
|
|
|
302
303
|
await usernameField.click({ clickCount: 3 });
|
|
303
304
|
await page.keyboard.press("Backspace");
|
|
304
305
|
await page.type(USERNAME_SELECTOR, username);
|
|
305
|
-
await page.waitForSelector(PASSWORD_SELECTOR);
|
|
306
|
+
await page.waitForSelector(PASSWORD_SELECTOR, { timeout: SELECTOR_TIMEOUT });
|
|
306
307
|
const passwordField = await page.$(PASSWORD_SELECTOR);
|
|
307
308
|
if (!passwordField) {
|
|
308
309
|
throw new Error("Password field not found");
|
|
@@ -310,7 +311,9 @@ async function loginToSnowflake({
|
|
|
310
311
|
await passwordField.click({ clickCount: 3 });
|
|
311
312
|
await page.keyboard.press("Backspace");
|
|
312
313
|
await page.type(PASSWORD_SELECTOR, password);
|
|
313
|
-
await page.waitForSelector("button:not([disabled])"
|
|
314
|
+
await page.waitForSelector("button:not([disabled])", {
|
|
315
|
+
timeout: SELECTOR_TIMEOUT
|
|
316
|
+
});
|
|
314
317
|
const buttons = await page.$$("button:not([disabled])");
|
|
315
318
|
let signInButtonHandle;
|
|
316
319
|
for (const btn of buttons) {
|
|
@@ -329,9 +332,21 @@ async function loginToSnowflake({
|
|
|
329
332
|
await signInButtonHandle.click();
|
|
330
333
|
if (otp != null) {
|
|
331
334
|
logger.log("Handling Snowflake OTP challenge...");
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
+
const MFA_LOCK_TEXT = "no valid Multi-Factor Authentication (MFA) methods are available";
|
|
336
|
+
const result = await Promise.race([
|
|
337
|
+
page.waitForSelector(OTP_SELECTOR, { timeout: SELECTOR_TIMEOUT }).then(() => "otp"),
|
|
338
|
+
page.waitForFunction(
|
|
339
|
+
`document.body.innerText.includes('${MFA_LOCK_TEXT}')`,
|
|
340
|
+
{
|
|
341
|
+
timeout: SELECTOR_TIMEOUT
|
|
342
|
+
}
|
|
343
|
+
).then(() => "mfa_locked")
|
|
344
|
+
]);
|
|
345
|
+
if (result === "mfa_locked") {
|
|
346
|
+
throw new Error(
|
|
347
|
+
"Snowflake account is temporarily locked due to no valid MFA methods available"
|
|
348
|
+
);
|
|
349
|
+
}
|
|
335
350
|
const otpField = await page.$(OTP_SELECTOR);
|
|
336
351
|
if (!otpField) {
|
|
337
352
|
throw new Error("OTP field not found");
|
package/package.json
CHANGED