From 22ae30d6ef067629e25f0ecc4822fd4bc03b0882 Mon Sep 17 00:00:00 2001
From: ValueOn AG
Date: Tue, 17 Feb 2026 00:48:32 +0100
Subject: [PATCH] fix: login at microsoftonline.com BEFORE navigating to /v2/
meeting URL
Co-authored-by: Cursor
---
src/bot/authTestProcedure.ts | 60 +++++++++++++++++-------------------
1 file changed, 29 insertions(+), 31 deletions(-)
diff --git a/src/bot/authTestProcedure.ts b/src/bot/authTestProcedure.ts
index 5933ae9..fb768dd 100644
--- a/src/bot/authTestProcedure.ts
+++ b/src/bot/authTestProcedure.ts
@@ -167,48 +167,46 @@ async function _runVariant(
let authSuccess: boolean | null = null;
if (variant.id === 'headfulDirect') {
- // Variant 6: Navigate directly to /v2/ URL, bypassing launcher.html entirely
+ // Strategy: Login at Microsoft FIRST, then navigate to /v2/ meeting URL.
+ // The /v2/ "Sign in" button leads to a guest-code flow, NOT Microsoft login.
+ // So we must authenticate before navigating to the meeting.
+
+ if (botAccountEmail && botAccountPassword) {
+ authAttempted = true;
+ _log('info', `Step 1: Authenticating at login.microsoftonline.com as ${botAccountEmail}`);
+
+ // Navigate to Microsoft login directly
+ const authProcedure = new AuthProcedure(page, logger);
+ authSuccess = await authProcedure.authenticateWithMicrosoft(botAccountEmail, botAccountPassword, false);
+ _log(authSuccess ? 'info' : 'warn', `Auth result: ${authSuccess ? 'success' : 'failed'}`);
+
+ if (authSuccess) {
+ // Wait for auth to fully settle (cookies, redirects)
+ await page.waitForTimeout(3000);
+ _log('info', `After auth, URL: ${page.url().substring(0, 120)}`);
+ }
+ } else {
+ _log('info', 'No credentials provided — skipping auth');
+ }
+
+ // Step 2: Navigate to /v2/ meeting URL (with or without auth cookies)
const directUrl = _buildDirectV2Url(meetingUrl);
- _log('info', `Direct /v2/ navigation: ${directUrl.substring(0, 120)}`);
+ _log('info', `Step 2: Direct /v2/ navigation: ${directUrl.substring(0, 120)}`);
await page.goto(directUrl, {
waitUntil: 'domcontentloaded',
timeout: 30000,
});
- // Wait for initial page load
- await page.waitForTimeout(5000);
+ // Wait for page to settle
+ await page.waitForTimeout(8000);
const currentUrl = page.url();
- _log('info', `After initial load: ${currentUrl.substring(0, 120)}`);
+ _log('info', `After meeting load: ${currentUrl.substring(0, 120)}`);
if (currentUrl.includes('light-meetings')) {
- _log('warn', 'Teams redirected /v2/ to light-meetings');
+ _log('warn', 'Teams redirected /v2/ to light-meetings (even after auth)');
} else if (currentUrl.includes('/v2/')) {
- _log('info', '/v2/ page loaded — checking for Sign-in link');
-
- // If we have credentials, attempt auth on the /v2/ page
- if (botAccountEmail && botAccountPassword) {
- authAttempted = true;
- _log('info', `Attempting auth as ${botAccountEmail}`);
-
- // Look for Sign-in link on the /v2/ pre-join page
- const signInClicked = await _clickSignInLink(page, _log);
-
- if (signInClicked) {
- // Use AuthProcedure for the hybrid flow (inline modal → MS login → password)
- authSuccess = await _attemptAuth(page, botAccountEmail, botAccountPassword);
- _log(authSuccess ? 'info' : 'warn', `Auth result: ${authSuccess ? 'success' : 'failed'}`);
-
- // Wait for page to settle after auth
- await page.waitForTimeout(5000);
- _log('info', `After auth, URL: ${page.url().substring(0, 120)}`);
- } else {
- _log('warn', 'No Sign-in link found on /v2/ page');
- authSuccess = false;
- }
- } else {
- _log('info', 'No credentials provided — skipping auth');
- }
+ _log('info', '/v2/ page loaded after auth!');
}
} else {
// Standard flow: resolve URL, navigate, click launcher