fix: preserve Teams return URL during auth login - skip goto when already on login page, poll for redirect completion
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
325de1c9ae
commit
4b6adaad8d
2 changed files with 59 additions and 24 deletions
|
|
@ -36,11 +36,21 @@ export class AuthProcedure {
|
||||||
try {
|
try {
|
||||||
this._logger.info(`Authenticating as ${email}...`);
|
this._logger.info(`Authenticating as ${email}...`);
|
||||||
|
|
||||||
// Navigate to Microsoft login
|
// Only navigate to login page if not already there.
|
||||||
await this._page.goto(_LOGIN_URL, {
|
// When called after clicking "Sign in" on Teams pre-join page,
|
||||||
waitUntil: 'domcontentloaded',
|
// the browser is already on login.microsoftonline.com WITH a return URL
|
||||||
timeout: 30000,
|
// embedded by Teams. Navigating again would destroy that return URL!
|
||||||
});
|
const currentUrl = this._page.url();
|
||||||
|
if (!currentUrl.includes('login.microsoftonline.com')) {
|
||||||
|
this._logger.info('Not on login page yet, navigating to Microsoft login...');
|
||||||
|
await this._page.goto(_LOGIN_URL, {
|
||||||
|
waitUntil: 'domcontentloaded',
|
||||||
|
timeout: 30000,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this._logger.info('Already on Microsoft login page - skipping navigation to preserve return URL');
|
||||||
|
await this._page.waitForLoadState('domcontentloaded', { timeout: 15000 });
|
||||||
|
}
|
||||||
|
|
||||||
// Wait for email input
|
// Wait for email input
|
||||||
const emailInput = await this._page.waitForSelector(
|
const emailInput = await this._page.waitForSelector(
|
||||||
|
|
|
||||||
|
|
@ -214,32 +214,57 @@ export class BotOrchestrator {
|
||||||
if (authSuccess) {
|
if (authSuccess) {
|
||||||
this._logger.info('Authentication via "Sign in" link succeeded');
|
this._logger.info('Authentication via "Sign in" link succeeded');
|
||||||
|
|
||||||
// After login, Teams does a redirect chain automatically:
|
// After login, the redirect chain goes automatically:
|
||||||
// Login → M365 → Teams v2 → Pre-Join page (/v2/)
|
// login.microsoftonline.com → teams.microsoft.com/v2/?meetingjoin=true#/meet/...
|
||||||
// Do NOT navigate anywhere. Just wait for the redirect chain to complete
|
// The return URL is embedded by Teams when clicking "Sign in".
|
||||||
// and for the "Join now" button to appear on the Teams v2 pre-join page.
|
// We just wait for the redirect to complete.
|
||||||
this._logger.info('Waiting for Teams to redirect to authenticated pre-join page...');
|
this._logger.info('Waiting for redirect chain to leave login.microsoftonline.com...');
|
||||||
|
|
||||||
// Wait for the #prejoin-join-button to appear (up to 30 seconds)
|
// Step 1: Wait for URL to leave login.microsoftonline.com (poll up to 45s)
|
||||||
// This button only exists on the Teams v2 authenticated pre-join page
|
const maxWaitMs = 45000;
|
||||||
|
const pollIntervalMs = 1000;
|
||||||
|
const startTime = Date.now();
|
||||||
|
let leftLoginPage = false;
|
||||||
|
|
||||||
|
while (Date.now() - startTime < maxWaitMs) {
|
||||||
|
const currentUrl = this._page!.url();
|
||||||
|
if (!currentUrl.includes('login.microsoftonline.com')) {
|
||||||
|
this._logger.info(`Left login page after ${Date.now() - startTime}ms. URL: ${currentUrl.substring(0, 100)}`);
|
||||||
|
leftLoginPage = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
await this._page!.waitForTimeout(pollIntervalMs);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!leftLoginPage) {
|
||||||
|
const stuckUrl = this._page!.url();
|
||||||
|
this._logger.warn(`Still on login page after ${maxWaitMs}ms. URL: ${stuckUrl.substring(0, 100)}`);
|
||||||
|
// Try navigating to meeting URL as fallback (auth cookies should be set)
|
||||||
|
this._logger.info('Fallback: navigating to meeting URL with auth cookies...');
|
||||||
|
await this._page!.goto(this._meetingUrl, { waitUntil: 'domcontentloaded', timeout: 30000 });
|
||||||
|
await this._joinProcedure!.handleLauncherIfPresent();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 2: Wait for the pre-join page to fully load
|
||||||
|
// The #prejoin-join-button appears on the Teams v2 authenticated pre-join page
|
||||||
const joinButtonSelector = '#prejoin-join-button, button[data-tid="prejoin-join-button"]';
|
const joinButtonSelector = '#prejoin-join-button, button[data-tid="prejoin-join-button"]';
|
||||||
try {
|
try {
|
||||||
await this._page!.waitForSelector(joinButtonSelector, { timeout: 30000, state: 'visible' });
|
await this._page!.waitForSelector(joinButtonSelector, { timeout: 30000, state: 'visible' });
|
||||||
const currentUrl = this._page!.url();
|
const finalUrl = this._page!.url();
|
||||||
this._logger.info(`Arrived at authenticated pre-join page: ${currentUrl.substring(0, 80)}`);
|
this._logger.info(`On authenticated pre-join page: ${finalUrl.substring(0, 100)}`);
|
||||||
} catch {
|
} catch {
|
||||||
const currentUrl = this._page!.url();
|
const finalUrl = this._page!.url();
|
||||||
const pageContent = await this._page!.evaluate(() => document.body?.innerText?.substring(0, 300) || '');
|
const pageContent = await this._page!.evaluate(() => document.body?.innerText?.substring(0, 300) || '');
|
||||||
this._logger.warn(`Join button not found after auth redirect. URL: ${currentUrl.substring(0, 80)}`);
|
this._logger.warn(`Join button not found. URL: ${finalUrl.substring(0, 100)}`);
|
||||||
this._logger.warn(`Page content: ${pageContent.substring(0, 200)}`);
|
this._logger.warn(`Page content: ${pageContent.substring(0, 200)}`);
|
||||||
}
|
|
||||||
|
|
||||||
// Verify we're on the authenticated pre-join page
|
// If we ended up somewhere unexpected, try meeting URL as last resort
|
||||||
const pageText = await this._page!.evaluate(() => document.body?.innerText?.substring(0, 500) || '');
|
if (!finalUrl.includes('teams.microsoft.com')) {
|
||||||
if (pageText.includes('Join now')) {
|
this._logger.info('Not on Teams - navigating to meeting URL as last resort...');
|
||||||
this._logger.info('On authenticated pre-join page with "Join now" button');
|
await this._page!.goto(this._meetingUrl, { waitUntil: 'domcontentloaded', timeout: 30000 });
|
||||||
} else {
|
await this._joinProcedure!.handleLauncherIfPresent();
|
||||||
this._logger.warn(`Post-auth page content: ${pageText.substring(0, 300)}`);
|
await this._page!.waitForTimeout(5000);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this._logger.warn('Authentication via "Sign in" failed - continuing as anonymous');
|
this._logger.warn('Authentication via "Sign in" failed - continuing as anonymous');
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue