From 1176cdc368dfac4823d1a593c0413e476bf12532 Mon Sep 17 00:00:00 2001
From: patrick-motsch
Date: Sun, 1 Mar 2026 10:20:09 +0100
Subject: [PATCH] fix(teamsbot): save credentials when form visible without
showCredentialForm state, add debugMode to effective config merge
Made-with: Cursor
---
modules/features/teamsbot/routeFeatureTeamsbot.py | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/modules/features/teamsbot/routeFeatureTeamsbot.py b/modules/features/teamsbot/routeFeatureTeamsbot.py
index 302ef889..660ea279 100644
--- a/modules/features/teamsbot/routeFeatureTeamsbot.py
+++ b/modules/features/teamsbot/routeFeatureTeamsbot.py
@@ -198,6 +198,7 @@ async def startSession(
# Determine effective join mode, bot name, and credentials
joinMode = body.joinMode or TeamsbotJoinMode.ANONYMOUS
+ logger.debug(f"startSession: requested joinMode={body.joinMode}, effective joinMode={joinMode}, userId={userId}, mandateId={mandateId}")
effectiveBotName = body.botName
botAccountEmail = None
botAccountPassword = None
@@ -241,15 +242,18 @@ async def startSession(
# User Account access: load saved MS credentials for the current user
elif joinMode == TeamsbotJoinMode.USER_ACCOUNT:
+ logger.debug(f"USER_ACCOUNT branch entered for userId={userId}, mandateId={mandateId}")
userAccount = interface.getUserAccount(userId, mandateId)
+ logger.debug(f"getUserAccount result: {bool(userAccount)}, keys={list(userAccount.keys()) if userAccount else 'N/A'}")
if userAccount:
botAccountEmail = userAccount.get("email")
encryptedPwd = userAccount.get("encryptedPassword")
+ logger.debug(f"UserAccount email={botAccountEmail}, hasEncryptedPwd={bool(encryptedPwd)}, encPwdPrefix={encryptedPwd[:20] if encryptedPwd else 'N/A'}...")
if botAccountEmail and encryptedPwd:
try:
from modules.shared.configuration import decryptValue
botAccountPassword = decryptValue(encryptedPwd, userId=userId, keyName="userAccountPassword")
- logger.info(f"User account credentials loaded for: {botAccountEmail}")
+ logger.info(f"User account credentials loaded and decrypted for: {botAccountEmail}")
if not effectiveBotName:
effectiveBotName = userAccount.get("displayName")
if not effectiveBotName and "@" in botAccountEmail:
@@ -259,8 +263,10 @@ async def startSession(
logger.warning(f"Could not decrypt user account password: {e}")
botAccountEmail = None
botAccountPassword = None
+ else:
+ logger.warning(f"UserAccount record found but missing email or encryptedPassword")
else:
- logger.warning(f"No saved credentials for user {userId} -- falling back to anonymous join")
+ logger.warning(f"No saved credentials for user {userId}, mandateId={mandateId} -- falling back to anonymous join")
joinMode = TeamsbotJoinMode.ANONYMOUS
else:
@@ -282,6 +288,7 @@ async def startSession(
})
# Start the bot in background — pass credentials separately (not in config)
+ logger.debug(f"startSession FINAL: joinMode={joinMode}, hasEmail={bool(botAccountEmail)}, hasPassword={bool(botAccountPassword)}, botName={effectiveBotName}")
service = TeamsbotService(context.user, mandateId, instanceId, sessionConfig)
asyncio.create_task(
service.joinMeeting(sessionId, cleanMeetingUrl, body.connectionId, gatewayBaseUrl, botAccountEmail, botAccountPassword)
@@ -508,7 +515,8 @@ def _getEffectiveConfig(instanceId: str, userId: str, interface) -> TeamsbotConf
overrides = {}
for field in ["botName", "aiSystemPrompt", "responseMode",
"responseChannel", "transferMode", "language", "voiceId",
- "triggerIntervalSeconds", "triggerCooldownSeconds", "contextWindowSegments"]:
+ "triggerIntervalSeconds", "triggerCooldownSeconds", "contextWindowSegments",
+ "debugMode"]:
value = userSettings.get(field)
if value is not None:
overrides[field] = value