Very minor auth standardization (#4400)

This commit is contained in:
pablonyx 2025-04-01 11:46:49 -07:00 committed by Weves
parent 7491cdd0f0
commit 2a87837ce1
24 changed files with 4330 additions and 7904 deletions

View File

@ -36,9 +36,6 @@ from onyx.utils.logger import setup_logger
logger = setup_logger() logger = setup_logger()
router = APIRouter(prefix="/auth/saml") router = APIRouter(prefix="/auth/saml")
# Define non-authenticated user roles that should be re-created during SAML login
NON_AUTHENTICATED_ROLES = {UserRole.SLACK_USER, UserRole.EXT_PERM_USER}
async def upsert_saml_user(email: str) -> User: async def upsert_saml_user(email: str) -> User:
logger.debug(f"Attempting to upsert SAML user with email: {email}") logger.debug(f"Attempting to upsert SAML user with email: {email}")
@ -54,7 +51,7 @@ async def upsert_saml_user(email: str) -> User:
try: try:
user = await user_manager.get_by_email(email) user = await user_manager.get_by_email(email)
# If user has a non-authenticated role, treat as non-existent # If user has a non-authenticated role, treat as non-existent
if user.role in NON_AUTHENTICATED_ROLES: if not user.role.is_web_login():
raise exceptions.UserNotExists() raise exceptions.UserNotExists()
return user return user
except exceptions.UserNotExists: except exceptions.UserNotExists:

View File

@ -42,7 +42,6 @@ ENV NEXT_PUBLIC_DISABLE_STREAMING=${NEXT_PUBLIC_DISABLE_STREAMING}
ARG NEXT_PUBLIC_NEW_CHAT_DIRECTS_TO_SAME_PERSONA ARG NEXT_PUBLIC_NEW_CHAT_DIRECTS_TO_SAME_PERSONA
ENV NEXT_PUBLIC_NEW_CHAT_DIRECTS_TO_SAME_PERSONA=${NEXT_PUBLIC_NEW_CHAT_DIRECTS_TO_SAME_PERSONA} ENV NEXT_PUBLIC_NEW_CHAT_DIRECTS_TO_SAME_PERSONA=${NEXT_PUBLIC_NEW_CHAT_DIRECTS_TO_SAME_PERSONA}
# allow user to specify custom feedback options
ARG NEXT_PUBLIC_POSITIVE_PREDEFINED_FEEDBACK_OPTIONS ARG NEXT_PUBLIC_POSITIVE_PREDEFINED_FEEDBACK_OPTIONS
ENV NEXT_PUBLIC_POSITIVE_PREDEFINED_FEEDBACK_OPTIONS=${NEXT_PUBLIC_POSITIVE_PREDEFINED_FEEDBACK_OPTIONS} ENV NEXT_PUBLIC_POSITIVE_PREDEFINED_FEEDBACK_OPTIONS=${NEXT_PUBLIC_POSITIVE_PREDEFINED_FEEDBACK_OPTIONS}

12090
web/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -93,11 +93,12 @@
}, },
"devDependencies": { "devDependencies": {
"@chromatic-com/playwright": "^0.10.2", "@chromatic-com/playwright": "^0.10.2",
"@playwright/test": "^1.39.0",
"@tailwindcss/typography": "^0.5.10", "@tailwindcss/typography": "^0.5.10",
"@types/chrome": "^0.0.287", "@types/chrome": "^0.0.287",
"@types/jest": "^29.5.14", "@types/jest": "^29.5.14",
"chromatic": "^11.25.2", "chromatic": "^11.25.2",
"eslint": "^8.48.0", "eslint": "^8.57.1",
"eslint-config-next": "^14.1.0", "eslint-config-next": "^14.1.0",
"jest": "^29.7.0", "jest": "^29.7.0",
"prettier": "2.8.8", "prettier": "2.8.8",

View File

@ -17,7 +17,7 @@ export default function PostHogPageView(): null {
// Track pageviews // Track pageviews
if (pathname) { if (pathname) {
let url = window.origin + pathname; let url = window.origin + pathname;
if (searchParams.toString()) { if (searchParams?.toString()) {
url = url + `?${searchParams.toString()}`; url = url + `?${searchParams.toString()}`;
} }
posthog.capture("$pageview", { posthog.capture("$pageview", {

View File

@ -149,7 +149,7 @@ export function AssistantEditor({
const { refreshAssistants, isImageGenerationAvailable } = useAssistants(); const { refreshAssistants, isImageGenerationAvailable } = useAssistants();
const router = useRouter(); const router = useRouter();
const searchParams = useSearchParams(); const searchParams = useSearchParams();
const isAdminPage = searchParams.get("admin") === "true"; const isAdminPage = searchParams?.get("admin") === "true";
const { popup, setPopup } = usePopup(); const { popup, setPopup } = usePopup();
const { labels, refreshLabels, createLabel, updateLabel, deleteLabel } = const { labels, refreshLabels, createLabel, updateLabel, deleteLabel } =
@ -469,8 +469,14 @@ export function AssistantEditor({
description: Yup.string().required( description: Yup.string().required(
"Must provide a description for the Assistant" "Must provide a description for the Assistant"
), ),
system_prompt: Yup.string(), system_prompt: Yup.string().max(
task_prompt: Yup.string(), 8000,
"Instructions must be less than 8000 characters"
),
task_prompt: Yup.string().max(
8000,
"Reminders must be less than 8000 characters"
),
is_public: Yup.boolean().required(), is_public: Yup.boolean().required(),
document_set_ids: Yup.array().of(Yup.number()), document_set_ids: Yup.array().of(Yup.number()),
num_chunks: Yup.number().nullable(), num_chunks: Yup.number().nullable(),

View File

@ -26,8 +26,8 @@ export default function OAuthCallbackPage() {
); );
// Extract query parameters // Extract query parameters
const code = searchParams.get("code"); const code = searchParams?.get("code");
const state = searchParams.get("state"); const state = searchParams?.get("state");
const pathname = usePathname(); const pathname = usePathname();
const connector = pathname?.split("/")[3]; const connector = pathname?.split("/")[3];

View File

@ -4,7 +4,6 @@ import { useEffect, useState } from "react";
import { usePathname, useRouter, useSearchParams } from "next/navigation"; import { usePathname, useRouter, useSearchParams } from "next/navigation";
import { AdminPageTitle } from "@/components/admin/Title"; import { AdminPageTitle } from "@/components/admin/Title";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import Title from "@/components/ui/title";
import { KeyIcon } from "@/components/icons/icons"; import { KeyIcon } from "@/components/icons/icons";
import { getSourceMetadata, isValidSource } from "@/lib/sources"; import { getSourceMetadata, isValidSource } from "@/lib/sources";
import { ConfluenceAccessibleResource, ValidSources } from "@/lib/types"; import { ConfluenceAccessibleResource, ValidSources } from "@/lib/types";
@ -74,7 +73,7 @@ export default function OAuthFinalizePage() {
>([]); >([]);
// Extract query parameters // Extract query parameters
const credentialParam = searchParams.get("credential"); const credentialParam = searchParams?.get("credential");
const credential = credentialParam ? parseInt(credentialParam, 10) : NaN; const credential = credentialParam ? parseInt(credentialParam, 10) : NaN;
const pathname = usePathname(); const pathname = usePathname();
const connector = pathname?.split("/")[3]; const connector = pathname?.split("/")[3];
@ -85,7 +84,7 @@ export default function OAuthFinalizePage() {
// connector (url segment)= "google-drive" // connector (url segment)= "google-drive"
// sourceType (for looking up metadata) = "google_drive" // sourceType (for looking up metadata) = "google_drive"
if (isNaN(credential)) { if (isNaN(credential) || !connector) {
setStatusMessage("Improperly formed OAuth finalization request."); setStatusMessage("Improperly formed OAuth finalization request.");
setStatusDetails("Invalid or missing credential id."); setStatusDetails("Invalid or missing credential id.");
setIsError(true); setIsError(true);

View File

@ -23,8 +23,8 @@ const ResetPasswordPage: React.FC = () => {
const { popup, setPopup } = usePopup(); const { popup, setPopup } = usePopup();
const [isWorking, setIsWorking] = useState(false); const [isWorking, setIsWorking] = useState(false);
const searchParams = useSearchParams(); const searchParams = useSearchParams();
const token = searchParams.get("token"); const token = searchParams?.get("token");
const tenantId = searchParams.get(TENANT_ID_COOKIE_NAME); const tenantId = searchParams?.get(TENANT_ID_COOKIE_NAME);
// Keep search param same name as cookie for simplicity // Keep search param same name as cookie for simplicity
useEffect(() => { useEffect(() => {

View File

@ -15,9 +15,9 @@ export function Verify({ user }: { user: User | null }) {
const [error, setError] = useState(""); const [error, setError] = useState("");
const verify = useCallback(async () => { const verify = useCallback(async () => {
const token = searchParams.get("token"); const token = searchParams?.get("token");
const firstUser = const firstUser =
searchParams.get("first_user") && NEXT_PUBLIC_CLOUD_ENABLED; searchParams?.get("first_user") && NEXT_PUBLIC_CLOUD_ENABLED;
if (!token) { if (!token) {
setError( setError(
"Missing verification token. Try requesting a new verification email." "Missing verification token. Try requesting a new verification email."

View File

@ -196,7 +196,9 @@ export function ChatPage({
setCurrentMessageFiles, setCurrentMessageFiles,
} = useDocumentsContext(); } = useDocumentsContext();
const defaultAssistantIdRaw = searchParams.get(SEARCH_PARAM_NAMES.PERSONA_ID); const defaultAssistantIdRaw = searchParams?.get(
SEARCH_PARAM_NAMES.PERSONA_ID
);
const defaultAssistantId = defaultAssistantIdRaw const defaultAssistantId = defaultAssistantIdRaw
? parseInt(defaultAssistantIdRaw) ? parseInt(defaultAssistantIdRaw)
: undefined; : undefined;
@ -252,8 +254,8 @@ export function ChatPage({
); );
const { user, isAdmin } = useUser(); const { user, isAdmin } = useUser();
const slackChatId = searchParams.get("slackChatId"); const slackChatId = searchParams?.get("slackChatId");
const existingChatIdRaw = searchParams.get("chatId"); const existingChatIdRaw = searchParams?.get("chatId");
const [showHistorySidebar, setShowHistorySidebar] = useState(false); const [showHistorySidebar, setShowHistorySidebar] = useState(false);
@ -275,7 +277,7 @@ export function ChatPage({
const processSearchParamsAndSubmitMessage = (searchParamsString: string) => { const processSearchParamsAndSubmitMessage = (searchParamsString: string) => {
const newSearchParams = new URLSearchParams(searchParamsString); const newSearchParams = new URLSearchParams(searchParamsString);
const message = newSearchParams.get("user-prompt"); const message = newSearchParams?.get("user-prompt");
filterManager.buildFiltersFromQueryString( filterManager.buildFiltersFromQueryString(
newSearchParams.toString(), newSearchParams.toString(),
@ -284,7 +286,7 @@ export function ChatPage({
tags tags
); );
const fileDescriptorString = newSearchParams.get(SEARCH_PARAM_NAMES.FILES); const fileDescriptorString = newSearchParams?.get(SEARCH_PARAM_NAMES.FILES);
const overrideFileDescriptors: FileDescriptor[] = fileDescriptorString const overrideFileDescriptors: FileDescriptor[] = fileDescriptorString
? JSON.parse(decodeURIComponent(fileDescriptorString)) ? JSON.parse(decodeURIComponent(fileDescriptorString))
: []; : [];
@ -324,7 +326,7 @@ export function ChatPage({
: undefined : undefined
); );
// Gather default temperature settings // Gather default temperature settings
const search_param_temperature = searchParams.get( const search_param_temperature = searchParams?.get(
SEARCH_PARAM_NAMES.TEMPERATURE SEARCH_PARAM_NAMES.TEMPERATURE
); );
@ -551,7 +553,7 @@ export function ChatPage({
if ( if (
newMessageHistory.length === 1 && newMessageHistory.length === 1 &&
!submitOnLoadPerformed.current && !submitOnLoadPerformed.current &&
searchParams.get(SEARCH_PARAM_NAMES.SEEDED) === "true" searchParams?.get(SEARCH_PARAM_NAMES.SEEDED) === "true"
) { ) {
submitOnLoadPerformed.current = true; submitOnLoadPerformed.current = true;
const seededMessage = newMessageHistory[0].message; const seededMessage = newMessageHistory[0].message;
@ -572,11 +574,11 @@ export function ChatPage({
initialSessionFetch(); initialSessionFetch();
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, [existingChatSessionId, searchParams.get(SEARCH_PARAM_NAMES.PERSONA_ID)]); }, [existingChatSessionId, searchParams?.get(SEARCH_PARAM_NAMES.PERSONA_ID)]);
useEffect(() => { useEffect(() => {
const userFolderId = searchParams.get(SEARCH_PARAM_NAMES.USER_FOLDER_ID); const userFolderId = searchParams?.get(SEARCH_PARAM_NAMES.USER_FOLDER_ID);
const allMyDocuments = searchParams.get( const allMyDocuments = searchParams?.get(
SEARCH_PARAM_NAMES.ALL_MY_DOCUMENTS SEARCH_PARAM_NAMES.ALL_MY_DOCUMENTS
); );
@ -599,14 +601,14 @@ export function ChatPage({
} }
}, [ }, [
userFolders, userFolders,
searchParams.get(SEARCH_PARAM_NAMES.USER_FOLDER_ID), searchParams?.get(SEARCH_PARAM_NAMES.USER_FOLDER_ID),
searchParams.get(SEARCH_PARAM_NAMES.ALL_MY_DOCUMENTS), searchParams?.get(SEARCH_PARAM_NAMES.ALL_MY_DOCUMENTS),
addSelectedFolder, addSelectedFolder,
clearSelectedItems, clearSelectedItems,
]); ]);
const [message, setMessage] = useState( const [message, setMessage] = useState(
searchParams.get(SEARCH_PARAM_NAMES.USER_PROMPT) || "" searchParams?.get(SEARCH_PARAM_NAMES.USER_PROMPT) || ""
); );
const [completeMessageDetail, setCompleteMessageDetail] = useState< const [completeMessageDetail, setCompleteMessageDetail] = useState<
@ -1048,7 +1050,7 @@ export function ChatPage({
// Equivalent to `loadNewPageLogic` // Equivalent to `loadNewPageLogic`
useEffect(() => { useEffect(() => {
if (searchParams.get(SEARCH_PARAM_NAMES.SEND_ON_LOAD)) { if (searchParams?.get(SEARCH_PARAM_NAMES.SEND_ON_LOAD)) {
processSearchParamsAndSubmitMessage(searchParams.toString()); processSearchParamsAndSubmitMessage(searchParams.toString());
} }
}, [searchParams, router]); }, [searchParams, router]);
@ -1231,7 +1233,7 @@ export function ChatPage({
const isNewSession = chatSessionIdRef.current === null; const isNewSession = chatSessionIdRef.current === null;
const searchParamBasedChatSessionName = const searchParamBasedChatSessionName =
searchParams.get(SEARCH_PARAM_NAMES.TITLE) || null; searchParams?.get(SEARCH_PARAM_NAMES.TITLE) || null;
if (isNewSession) { if (isNewSession) {
currChatSessionId = await createChatSession( currChatSessionId = await createChatSession(
@ -1409,11 +1411,11 @@ export function ChatPage({
modelVersion: modelVersion:
modelOverride?.modelName || modelOverride?.modelName ||
llmManager.currentLlm.modelName || llmManager.currentLlm.modelName ||
searchParams.get(SEARCH_PARAM_NAMES.MODEL_VERSION) || searchParams?.get(SEARCH_PARAM_NAMES.MODEL_VERSION) ||
undefined, undefined,
temperature: llmManager.temperature || undefined, temperature: llmManager.temperature || undefined,
systemPromptOverride: systemPromptOverride:
searchParams.get(SEARCH_PARAM_NAMES.SYSTEM_PROMPT) || undefined, searchParams?.get(SEARCH_PARAM_NAMES.SYSTEM_PROMPT) || undefined,
useExistingUserMessage: isSeededChat, useExistingUserMessage: isSeededChat,
useLanggraph: useLanggraph:
settings?.settings.pro_search_enabled && settings?.settings.pro_search_enabled &&

View File

@ -668,7 +668,7 @@ const PARAMS_TO_SKIP = [
]; ];
export function buildChatUrl( export function buildChatUrl(
existingSearchParams: ReadonlyURLSearchParams, existingSearchParams: ReadonlyURLSearchParams | null,
chatSessionId: string | null, chatSessionId: string | null,
personaId: number | null, personaId: number | null,
search?: boolean search?: boolean
@ -685,7 +685,7 @@ export function buildChatUrl(
finalSearchParams.push(`${SEARCH_PARAM_NAMES.PERSONA_ID}=${personaId}`); finalSearchParams.push(`${SEARCH_PARAM_NAMES.PERSONA_ID}=${personaId}`);
} }
existingSearchParams.forEach((value, key) => { existingSearchParams?.forEach((value, key) => {
if (!PARAMS_TO_SKIP.includes(key)) { if (!PARAMS_TO_SKIP.includes(key)) {
finalSearchParams.push(`${key}=${value}`); finalSearchParams.push(`${key}=${value}`);
} }
@ -719,7 +719,7 @@ export async function uploadFilesForChat(
return [responseJson.files as FileDescriptor[], null]; return [responseJson.files as FileDescriptor[], null];
} }
export async function useScrollonStream({ export function useScrollonStream({
chatState, chatState,
scrollableDivRef, scrollableDivRef,
scrollDist, scrollDist,
@ -817,5 +817,5 @@ export async function useScrollonStream({
}); });
} }
} }
}, [chatState, distance, scrollDist, scrollableDivRef]); }, [chatState, distance, scrollDist, scrollableDivRef, enableAutoScroll]);
} }

View File

@ -23,8 +23,10 @@ export const SEARCH_PARAM_NAMES = {
SEND_ON_LOAD: "send-on-load", SEND_ON_LOAD: "send-on-load",
}; };
export function shouldSubmitOnLoad(searchParams: ReadonlyURLSearchParams) { export function shouldSubmitOnLoad(
const rawSubmitOnLoad = searchParams.get(SEARCH_PARAM_NAMES.SUBMIT_ON_LOAD); searchParams: ReadonlyURLSearchParams | null
) {
const rawSubmitOnLoad = searchParams?.get(SEARCH_PARAM_NAMES.SUBMIT_ON_LOAD);
if (rawSubmitOnLoad === "true" || rawSubmitOnLoad === "1") { if (rawSubmitOnLoad === "true" || rawSubmitOnLoad === "1") {
return true; return true;
} }

View File

@ -104,7 +104,7 @@ export function UserDropdown({
// Construct the current URL // Construct the current URL
const currentUrl = `${pathname}${ const currentUrl = `${pathname}${
searchParams.toString() ? `?${searchParams.toString()}` : "" searchParams?.toString() ? `?${searchParams.toString()}` : ""
}`; }`;
// Encode the current URL to use as a redirect parameter // Encode the current URL to use as a redirect parameter

View File

@ -59,8 +59,8 @@ export function ClientLayout({
const { llmProviders } = useChatContext(); const { llmProviders } = useChatContext();
const { popup, setPopup } = usePopup(); const { popup, setPopup } = usePopup();
if ( if (
pathname.startsWith("/admin/connectors") || (pathname && pathname.startsWith("/admin/connectors")) ||
pathname.startsWith("/admin/embeddings") (pathname && pathname.startsWith("/admin/embeddings"))
) { ) {
return <>{children}</>; return <>{children}</>;
} }

View File

@ -76,7 +76,7 @@ export const ChatProvider: React.FC<{
const { sessions } = await response.json(); const { sessions } = await response.json();
setChatSessions(sessions); setChatSessions(sessions);
const currentSessionId = searchParams.get("chatId"); const currentSessionId = searchParams?.get("chatId");
if ( if (
currentSessionId && currentSessionId &&
!sessions.some( !sessions.some(

View File

@ -34,7 +34,7 @@ export const EmbeddingFormProvider: React.FC<{
const pathname = usePathname(); const pathname = usePathname();
// Initialize formStep based on the URL parameter // Initialize formStep based on the URL parameter
const initialStep = parseInt(searchParams.get("step") || "0", 10); const initialStep = parseInt(searchParams?.get("step") || "0", 10);
const [formStep, setFormStep] = useState(initialStep); const [formStep, setFormStep] = useState(initialStep);
const [formValues, setFormValues] = useState<Record<string, any>>({}); const [formValues, setFormValues] = useState<Record<string, any>>({});
@ -56,8 +56,10 @@ export const EmbeddingFormProvider: React.FC<{
useEffect(() => { useEffect(() => {
// Update URL when formStep changes // Update URL when formStep changes
const updatedSearchParams = new URLSearchParams(searchParams.toString()); const updatedSearchParams = new URLSearchParams(
const existingStep = updatedSearchParams.get("step"); searchParams?.toString() || ""
);
const existingStep = updatedSearchParams?.get("step");
updatedSearchParams.set("step", formStep.toString()); updatedSearchParams.set("step", formStep.toString());
const newUrl = `${pathname}?${updatedSearchParams.toString()}`; const newUrl = `${pathname}?${updatedSearchParams.toString()}`;
@ -70,7 +72,7 @@ export const EmbeddingFormProvider: React.FC<{
// Update formStep when URL changes // Update formStep when URL changes
useEffect(() => { useEffect(() => {
const stepFromUrl = parseInt(searchParams.get("step") || "0", 10); const stepFromUrl = parseInt(searchParams?.get("step") || "0", 10);
if (stepFromUrl !== formStep) { if (stepFromUrl !== formStep) {
setFormStep(stepFromUrl); setFormStep(stepFromUrl);
} }

View File

@ -34,7 +34,7 @@ export const FormProvider: React.FC<{
const pathname = usePathname(); const pathname = usePathname();
// Initialize formStep based on the URL parameter // Initialize formStep based on the URL parameter
const initialStep = parseInt(searchParams.get("step") || "0", 10); const initialStep = parseInt(searchParams?.get("step") || "0", 10);
const [formStep, setFormStep] = useState(initialStep); const [formStep, setFormStep] = useState(initialStep);
const [formValues, setFormValues] = useState<Record<string, any>>({}); const [formValues, setFormValues] = useState<Record<string, any>>({});
@ -56,8 +56,10 @@ export const FormProvider: React.FC<{
useEffect(() => { useEffect(() => {
// Update URL when formStep changes // Update URL when formStep changes
const updatedSearchParams = new URLSearchParams(searchParams.toString()); const updatedSearchParams = new URLSearchParams(
const existingStep = updatedSearchParams.get("step"); searchParams?.toString() || ""
);
const existingStep = updatedSearchParams?.get("step");
updatedSearchParams.set("step", formStep.toString()); updatedSearchParams.set("step", formStep.toString());
const newUrl = `${pathname}?${updatedSearchParams.toString()}`; const newUrl = `${pathname}?${updatedSearchParams.toString()}`;
@ -69,7 +71,7 @@ export const FormProvider: React.FC<{
}, [formStep, router, pathname, searchParams]); }, [formStep, router, pathname, searchParams]);
useEffect(() => { useEffect(() => {
const stepFromUrl = parseInt(searchParams.get("step") || "0", 10); const stepFromUrl = parseInt(searchParams?.get("step") || "0", 10);
if (stepFromUrl !== formStep) { if (stepFromUrl !== formStep) {
setFormStep(stepFromUrl); setFormStep(stepFromUrl);
} }

View File

@ -35,7 +35,7 @@ export const HealthCheckBanner = () => {
useEffect(() => { useEffect(() => {
if (userError && userError.status === 403) { if (userError && userError.status === 403) {
logout().then(() => { logout().then(() => {
if (!pathname.includes("/auth")) { if (!pathname?.includes("/auth")) {
setShowLoggedOutModal(true); setShowLoggedOutModal(true);
} }
}); });
@ -61,7 +61,7 @@ export const HealthCheckBanner = () => {
expirationTimeoutRef.current = setTimeout(() => { expirationTimeoutRef.current = setTimeout(() => {
setExpired(true); setExpired(true);
if (!pathname.includes("/auth")) { if (!pathname?.includes("/auth")) {
setShowLoggedOutModal(true); setShowLoggedOutModal(true);
} }
}, timeUntilExpire); }, timeUntilExpire);
@ -205,7 +205,7 @@ export const HealthCheckBanner = () => {
} }
if (error instanceof RedirectError || expired) { if (error instanceof RedirectError || expired) {
if (!pathname.includes("/auth")) { if (!pathname?.includes("/auth")) {
setShowLoggedOutModal(true); setShowLoggedOutModal(true);
} }
return null; return null;

View File

@ -19,12 +19,12 @@ function setWelcomeFlowComplete() {
Cookies.set(COMPLETED_WELCOME_FLOW_COOKIE, "true", { expires: 365 }); Cookies.set(COMPLETED_WELCOME_FLOW_COOKIE, "true", { expires: 365 });
} }
export function _CompletedWelcomeFlowDummyComponent() { export function CompletedWelcomeFlowDummyComponent() {
setWelcomeFlowComplete(); setWelcomeFlowComplete();
return null; return null;
} }
export function _WelcomeModal({ user }: { user: User | null }) { export function WelcomeModal({ user }: { user: User | null }) {
const router = useRouter(); const router = useRouter();
const [providerOptions, setProviderOptions] = useState< const [providerOptions, setProviderOptions] = useState<

View File

@ -1,6 +1,6 @@
import { import {
_CompletedWelcomeFlowDummyComponent, CompletedWelcomeFlowDummyComponent,
_WelcomeModal, WelcomeModal as WelcomeModalComponent,
} from "./WelcomeModal"; } from "./WelcomeModal";
import { COMPLETED_WELCOME_FLOW_COOKIE } from "./constants"; import { COMPLETED_WELCOME_FLOW_COOKIE } from "./constants";
import { User } from "@/lib/types"; import { User } from "@/lib/types";
@ -24,8 +24,8 @@ export function WelcomeModal({
}) { }) {
const hasCompletedWelcomeFlow = hasCompletedWelcomeFlowSS(requestCookies); const hasCompletedWelcomeFlow = hasCompletedWelcomeFlowSS(requestCookies);
if (hasCompletedWelcomeFlow) { if (hasCompletedWelcomeFlow) {
return <_CompletedWelcomeFlowDummyComponent />; return <CompletedWelcomeFlowDummyComponent />;
} }
return <_WelcomeModal user={user} />; return <WelcomeModalComponent user={user} />;
} }

View File

@ -31,13 +31,13 @@ export function NewTeamModal() {
const { setPopup } = usePopup(); const { setPopup } = usePopup();
useEffect(() => { useEffect(() => {
const hasNewTeamParam = searchParams.has("new_team"); const hasNewTeamParam = searchParams?.has("new_team");
if (hasNewTeamParam) { if (hasNewTeamParam) {
setShowNewTeamModal(true); setShowNewTeamModal(true);
fetchTenantInfo(); fetchTenantInfo();
// Remove the new_team parameter from the URL without page reload // Remove the new_team parameter from the URL without page reload
const newParams = new URLSearchParams(searchParams.toString()); const newParams = new URLSearchParams(searchParams?.toString() || "");
newParams.delete("new_team"); newParams.delete("new_team");
const newUrl = const newUrl =
window.location.pathname + window.location.pathname +

View File

@ -16,7 +16,7 @@ export const usePopupFromQuery = (messages: PopupMessages) => {
const searchParams = new URLSearchParams(window.location.search); const searchParams = new URLSearchParams(window.location.search);
// Get the value for search param with key "message" // Get the value for search param with key "message"
const messageValue = searchParams.get("message"); const messageValue = searchParams?.get("message");
// Check if any key from messages object is present in search params // Check if any key from messages object is present in search params
if (messageValue && messageValue in messages) { if (messageValue && messageValue in messages) {

View File

@ -148,7 +148,7 @@ function usePaginatedFetch<T extends PaginatedType>({
// Updates the URL with the current page number // Updates the URL with the current page number
const updatePageUrl = useCallback( const updatePageUrl = useCallback(
(page: number) => { (page: number) => {
if (currentPath) { if (currentPath && searchParams) {
const params = new URLSearchParams(searchParams); const params = new URLSearchParams(searchParams);
params.set("page", page.toString()); params.set("page", page.toString());
router.replace(`${currentPath}?${params.toString()}`, { router.replace(`${currentPath}?${params.toString()}`, {