diff --git a/backend/onyx/auth/schemas.py b/backend/onyx/auth/schemas.py index 88a8f6111..6a589a0d6 100644 --- a/backend/onyx/auth/schemas.py +++ b/backend/onyx/auth/schemas.py @@ -42,6 +42,10 @@ class UserCreate(schemas.BaseUserCreate): tenant_id: str | None = None +class UserUpdateWithRole(schemas.BaseUserUpdate): + role: UserRole + + class UserUpdate(schemas.BaseUserUpdate): """ Role updates are not allowed through the user update endpoint for security reasons diff --git a/backend/onyx/auth/users.py b/backend/onyx/auth/users.py index db79ed29a..0d8fa5474 100644 --- a/backend/onyx/auth/users.py +++ b/backend/onyx/auth/users.py @@ -57,7 +57,7 @@ from onyx.auth.invited_users import get_invited_users from onyx.auth.schemas import AuthBackend from onyx.auth.schemas import UserCreate from onyx.auth.schemas import UserRole -from onyx.auth.schemas import UserUpdate +from onyx.auth.schemas import UserUpdateWithRole from onyx.configs.app_configs import AUTH_BACKEND from onyx.configs.app_configs import AUTH_COOKIE_EXPIRE_TIME_SECONDS from onyx.configs.app_configs import AUTH_TYPE @@ -216,7 +216,6 @@ class UserManager(UUIDIDMixin, BaseUserManager[User, uuid.UUID]): reset_password_token_secret = USER_AUTH_SECRET verification_token_secret = USER_AUTH_SECRET verification_token_lifetime_seconds = AUTH_COOKIE_EXPIRE_TIME_SECONDS - user_db: SQLAlchemyUserDatabase[User, uuid.UUID] async def create( @@ -246,10 +245,8 @@ class UserManager(UUIDIDMixin, BaseUserManager[User, uuid.UUID]): referral_source=referral_source, request=request, ) - async with get_async_session_with_tenant(tenant_id) as db_session: token = CURRENT_TENANT_ID_CONTEXTVAR.set(tenant_id) - verify_email_is_invited(user_create.email) verify_email_domain(user_create.email) if MULTI_TENANT: @@ -268,16 +265,16 @@ class UserManager(UUIDIDMixin, BaseUserManager[User, uuid.UUID]): user_create.role = UserRole.ADMIN else: user_create.role = UserRole.BASIC - try: user = await super().create(user_create, safe=safe, request=request) # type: ignore except exceptions.UserAlreadyExists: user = await self.get_by_email(user_create.email) # Handle case where user has used product outside of web and is now creating an account through web if not user.role.is_web_login() and user_create.role.is_web_login(): - user_update = UserUpdate( + user_update = UserUpdateWithRole( password=user_create.password, is_verified=user_create.is_verified, + role=user_create.role, ) user = await self.update(user_update, user) else: @@ -285,7 +282,6 @@ class UserManager(UUIDIDMixin, BaseUserManager[User, uuid.UUID]): finally: CURRENT_TENANT_ID_CONTEXTVAR.reset(token) - return user async def validate_password(self, password: str, _: schemas.UC | models.UP) -> None: diff --git a/web/src/app/chat/input/ChatInputBar.tsx b/web/src/app/chat/input/ChatInputBar.tsx index 405831f23..490e5bda8 100644 --- a/web/src/app/chat/input/ChatInputBar.tsx +++ b/web/src/app/chat/input/ChatInputBar.tsx @@ -534,7 +534,7 @@ export function ChatInputBar({ filterManager.selectedDocumentSets.length > 0 || filterManager.selectedTags.length > 0 || filterManager.selectedSources.length > 0) && ( -
+
{filterManager.selectedTags && filterManager.selectedTags.map((tag, index) => ( diff --git a/web/src/app/ee/admin/groups/[groupId]/AddMemberForm.tsx b/web/src/app/ee/admin/groups/[groupId]/AddMemberForm.tsx index fd8e5064f..b63a80c00 100644 --- a/web/src/app/ee/admin/groups/[groupId]/AddMemberForm.tsx +++ b/web/src/app/ee/admin/groups/[groupId]/AddMemberForm.tsx @@ -21,8 +21,12 @@ export const AddMemberForm: React.FC = ({ const [selectedUserIds, setSelectedUserIds] = useState([]); return ( - onClose()}> -
+ onClose()} + > +
)}
-
- {children} -
+ {children}
); diff --git a/web/src/components/UserDropdown.tsx b/web/src/components/UserDropdown.tsx index 4d456d673..bc565980f 100644 --- a/web/src/components/UserDropdown.tsx +++ b/web/src/components/UserDropdown.tsx @@ -160,7 +160,7 @@ export function UserDropdown({ {user && user.email ? user.email[0].toUpperCase() : "A"}
{notifications && notifications.length > 0 && ( -
+
)}
} diff --git a/web/src/components/context/ChatContext.tsx b/web/src/components/context/ChatContext.tsx index b053850fa..621d79783 100644 --- a/web/src/components/context/ChatContext.tsx +++ b/web/src/components/context/ChatContext.tsx @@ -11,6 +11,8 @@ import { import { ChatSession, InputPrompt } from "@/app/chat/interfaces"; import { LLMProviderDescriptor } from "@/app/admin/configuration/llm/interfaces"; import { Folder } from "@/app/chat/folders/interfaces"; +import { useSearchParams } from "next/navigation"; +import { useRouter } from "next/navigation"; interface ChatContextProps { chatSessions: ChatSession[]; @@ -49,6 +51,8 @@ export const ChatProvider: React.FC<{ >; children: React.ReactNode; }> = ({ value, children }) => { + const router = useRouter(); + const searchParams = useSearchParams(); const [inputPrompts, setInputPrompts] = useState(value?.inputPrompts || []); const [chatSessions, setChatSessions] = useState(value?.chatSessions || []); const [folders, setFolders] = useState(value?.folders || []); @@ -70,6 +74,16 @@ export const ChatProvider: React.FC<{ if (!response.ok) throw new Error("Failed to fetch chat sessions"); const { sessions } = await response.json(); setChatSessions(sessions); + + const currentSessionId = searchParams.get("chatId"); + if ( + currentSessionId && + !sessions.some( + (session: ChatSession) => session.id === currentSessionId + ) + ) { + router.replace("/chat"); + } } catch (error) { console.error("Error refreshing chat sessions:", error); }